2018-12-19 22:55:23 +01:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
##############################################################################
|
|
|
|
# This script allows you to easily manage Platypush instances through Python #
|
|
|
|
# virtual environment. You can build environments from a config.yaml file #
|
|
|
|
# and automatically managed the required dependencies, as well as start, #
|
|
|
|
# stop and remove them #
|
|
|
|
# #
|
2021-09-16 17:53:40 +02:00
|
|
|
# @author: Fabio Manganiello <fabio@platypush.tech> #
|
2018-12-19 22:55:23 +01:00
|
|
|
# @licence: MIT #
|
|
|
|
##############################################################################
|
|
|
|
|
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
workdir="$HOME/.local/share/platypush/venv"
|
2018-12-19 22:55:23 +01:00
|
|
|
|
|
|
|
function build {
|
|
|
|
cfgfile=
|
|
|
|
|
|
|
|
while getopts ':c:' opt; do
|
2019-12-01 22:27:54 +01:00
|
|
|
case ${opt} in
|
2018-12-19 22:55:23 +01:00
|
|
|
c)
|
|
|
|
cfgfile=$OPTARG;;
|
|
|
|
\?)
|
|
|
|
echo "Invalid option: -$OPTARG" >&2
|
|
|
|
exit 1;;
|
|
|
|
:)
|
|
|
|
echo "Option -$OPTARG requires the path to a Platypush configuration file" >&2
|
|
|
|
exit 1;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
2019-12-01 22:27:54 +01:00
|
|
|
if [[ -z "$cfgfile" ]]; then
|
2018-12-19 22:55:23 +01:00
|
|
|
echo "Usage: $0 build -c <path-to-platypush-config-file>" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "Parsing configuration file"
|
2021-09-16 17:53:40 +02:00
|
|
|
pip_cmd=
|
|
|
|
pkg_cmd=
|
2018-12-20 00:08:46 +01:00
|
|
|
includes=()
|
2021-09-16 17:53:40 +02:00
|
|
|
cmd_exec=()
|
2018-12-19 22:55:23 +01:00
|
|
|
|
|
|
|
while read -r line; do
|
2021-09-16 17:53:40 +02:00
|
|
|
if echo "$line" | grep -E "^pip:\s*"; then
|
|
|
|
pip_cmd="$(echo "$line" | sed -r -e 's/^pip:\s*(.*)'/\\1/)"
|
|
|
|
elif echo "$line" | grep -E "^packages:\s*"; then
|
|
|
|
pkg_cmd="$(echo "$line" | sed -r -e 's/^packages:\s*(.*)'/\\1/)"
|
|
|
|
elif echo "$line" | grep -E "^exec:\s*"; then
|
|
|
|
cmd_exec+=("$(echo "$line" | sed -r -e 's/^exec:\s*(.*)'/\\1/)")
|
|
|
|
elif echo "$line" | grep -E "^include:\s*"; then
|
|
|
|
includes+=("$(echo "$line" | sed -r -e 's/^include:\s*(.*)'/\\1/)")
|
|
|
|
elif echo "$line" | grep -E "^device_id:\s*"; then
|
|
|
|
device_id="$(echo "$line" | sed -r -e 's/^device_id:\s*(.*)'/\\1/)"
|
|
|
|
fi
|
|
|
|
done <<< "$(python <<EOF
|
2018-12-19 22:55:23 +01:00
|
|
|
from platypush.config import Config
|
2021-09-16 17:53:40 +02:00
|
|
|
from platypush.utils.manifest import get_install_commands_from_conf
|
2018-12-19 22:55:23 +01:00
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
deps = get_install_commands_from_conf('$(realpath "${cfgfile}")')
|
|
|
|
print(f'device_id: {Config.get("device_id")}')
|
2018-12-20 00:08:46 +01:00
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
if deps.get('pip'):
|
|
|
|
print(f'pip: {deps["pip"]}')
|
2018-12-20 00:08:46 +01:00
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
if deps.get('packages'):
|
|
|
|
print(f'packages: {deps["packages"]}')
|
2018-12-19 22:55:23 +01:00
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
for cmd in deps.get('exec', []):
|
|
|
|
print(f'exec: {cmd}')
|
2018-12-19 22:55:23 +01:00
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
for include in Config._included_files:
|
|
|
|
print(f'include: {include}')
|
2018-12-19 22:55:23 +01:00
|
|
|
EOF
|
2021-09-16 17:53:40 +02:00
|
|
|
)"
|
2018-12-19 22:55:23 +01:00
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
envdir="${workdir}/${device_id}"
|
|
|
|
etcdir="${envdir}/etc/platypush"
|
2018-12-19 22:55:23 +01:00
|
|
|
|
|
|
|
echo "Preparing virtual environment for device $device_id"
|
2018-12-20 00:08:46 +01:00
|
|
|
mkdir -p "$envdir"
|
|
|
|
mkdir -p "$etcdir"
|
2021-09-16 17:53:40 +02:00
|
|
|
srcdir=$(dirname "$cfgfile")
|
2018-12-20 00:08:46 +01:00
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
for ((i=0; i < ${#includes[@]}; i++)); do
|
|
|
|
incdir=$(dirname "${includes[$i]}")
|
|
|
|
incdir=$(realpath --relative-to="$srcdir" "$incdir")
|
2018-12-20 00:08:46 +01:00
|
|
|
destdir="$etcdir/$incdir"
|
|
|
|
mkdir -p "$destdir"
|
|
|
|
cp "${includes[$i]}" "$destdir"
|
|
|
|
done
|
|
|
|
|
|
|
|
cp "$cfgfile" "$etcdir/config.yaml"
|
2021-09-16 17:53:40 +02:00
|
|
|
cfgfile="${etcdir}/config.yaml"
|
2018-12-19 22:55:23 +01:00
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
python3 -m venv "${envdir}"
|
|
|
|
cd "${envdir}" || exit 1
|
|
|
|
source "${envdir}/bin/activate"
|
2018-12-19 22:55:23 +01:00
|
|
|
|
|
|
|
echo "Installing required dependencies"
|
2021-09-16 17:53:40 +02:00
|
|
|
# shellcheck disable=SC2086
|
|
|
|
[ -n "${pkg_cmd}" ] && sudo ${pkg_cmd}
|
|
|
|
[ -n "${pip_cmd}" ] && ${pip_cmd}
|
2018-12-19 22:55:23 +01:00
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
for ((i=0; i < ${#cmd_exec[@]}; i++)); do
|
|
|
|
${cmd_exec[$i]}
|
2018-12-19 22:55:23 +01:00
|
|
|
done
|
|
|
|
|
2021-01-23 15:03:43 +01:00
|
|
|
pip install --upgrade git+https://git.platypush.tech/platypush/platypush.git
|
2018-12-19 22:55:23 +01:00
|
|
|
echo "Platypush virtual environment prepared under $envdir"
|
|
|
|
}
|
|
|
|
|
|
|
|
function start {
|
2019-12-01 22:27:54 +01:00
|
|
|
if [[ -z "$1" ]]; then
|
2018-12-19 22:55:23 +01:00
|
|
|
echo "Usage: $0 start <env-name>" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
env=$1
|
2021-09-16 17:53:40 +02:00
|
|
|
envdir="${workdir}/${env}"
|
|
|
|
rundir="${envdir}/var/run"
|
|
|
|
pidfile="${rundir}/platypush.pid"
|
|
|
|
cfgfile="${envdir}/etc/platypush/config.yaml"
|
2018-12-19 22:55:23 +01:00
|
|
|
|
2019-12-01 22:27:54 +01:00
|
|
|
if [[ ! -d "$envdir" ]]; then
|
2018-12-19 22:55:23 +01:00
|
|
|
echo "No such directory: $envdir" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
mkdir -p "${rundir}"
|
2018-12-19 22:55:23 +01:00
|
|
|
|
|
|
|
if [[ -f "$pidfile" ]]; then
|
2021-09-16 17:53:40 +02:00
|
|
|
if pgrep -F "${pidfile}"; then
|
|
|
|
echo "Another instance (PID $(cat "${pidfile}")) is running, please stop that instance first"
|
2018-12-19 22:55:23 +01:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
echo "A PID file was found but the process does not seem to be running, starting anyway"
|
2018-12-19 22:55:23 +01:00
|
|
|
rm -f "$pidfile"
|
|
|
|
fi
|
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
python3 -m venv "${envdir}"
|
|
|
|
cd "${envdir}" || exit 1
|
2018-12-19 22:55:23 +01:00
|
|
|
source bin/activate
|
2021-09-16 23:28:00 +02:00
|
|
|
bin/platypush -c "$cfgfile" -P "$pidfile" &
|
2021-09-16 17:53:40 +02:00
|
|
|
start_time=$(date +'%s')
|
2018-12-19 22:55:23 +01:00
|
|
|
timeout=30
|
|
|
|
|
|
|
|
while :; do
|
|
|
|
[[ -f "$pidfile" ]] && break
|
2021-09-16 17:53:40 +02:00
|
|
|
now=$(date +'%s')
|
|
|
|
elapsed=$(( now-start_time ))
|
|
|
|
if (( elapsed >= timeout )); then
|
|
|
|
echo "Platypush instance '$env' did not start within $timeout seconds" >&2
|
2018-12-19 22:55:23 +01:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo -n '.'
|
|
|
|
sleep 1
|
|
|
|
done
|
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
pid=$(cat "$pidfile")
|
2018-12-19 22:55:23 +01:00
|
|
|
echo
|
2021-09-16 23:28:00 +02:00
|
|
|
echo "Platypush environment $env started with PID $pid"
|
|
|
|
wait "${pid}"
|
|
|
|
echo "Platypush environment $env terminated"
|
2018-12-19 22:55:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function stop {
|
2019-12-01 22:27:54 +01:00
|
|
|
if [[ -z "$1" ]]; then
|
2018-12-19 22:55:23 +01:00
|
|
|
echo "Usage: $0 stop <env-name>" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
env=$1
|
2021-09-16 17:53:40 +02:00
|
|
|
envdir="${workdir}/${env}"
|
|
|
|
rundir="${envdir}/var/run"
|
|
|
|
pidfile="${rundir}/platypush.pid"
|
2018-12-19 22:55:23 +01:00
|
|
|
|
2019-12-01 22:27:54 +01:00
|
|
|
if [[ ! -d "$envdir" ]]; then
|
2018-12-19 22:55:23 +01:00
|
|
|
echo "No such directory: $envdir" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [[ ! -f "$pidfile" ]]; then
|
2021-09-16 17:53:40 +02:00
|
|
|
echo "No pidfile found for instance \"${env}\""
|
2018-12-19 22:55:23 +01:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
pid=$(cat "$pidfile")
|
|
|
|
pids="$pid $(ps --no-headers -o pid= --ppid "$pid")"
|
|
|
|
# shellcheck disable=SC2086
|
2019-12-01 22:27:54 +01:00
|
|
|
kill -9 ${pids}
|
2018-12-19 22:55:23 +01:00
|
|
|
rm -f "$pidfile"
|
|
|
|
echo "Instance '$env' with PID $pid stopped"
|
|
|
|
}
|
|
|
|
|
|
|
|
function rme {
|
2019-12-01 22:27:54 +01:00
|
|
|
if [[ -z "$1" ]]; then
|
2018-12-19 22:55:23 +01:00
|
|
|
echo "Usage: $0 rm <env-name>" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
envdir="${workdir}/$1"
|
|
|
|
rundir="${envdir}/var/run"
|
|
|
|
pidfile="${rundir}/platypush.pid"
|
2018-12-19 22:55:23 +01:00
|
|
|
|
2019-12-01 22:27:54 +01:00
|
|
|
if [[ ! -d "$envdir" ]]; then
|
2018-12-19 22:55:23 +01:00
|
|
|
echo "No such directory: $envdir" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [[ -f "$pidfile" ]]; then
|
2021-09-16 17:53:40 +02:00
|
|
|
if pgrep -F "${pidfile}"; then
|
|
|
|
echo "Another instance (PID $(cat "$pidfile")) is running, please stop that instance first"
|
2018-12-19 22:55:23 +01:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
echo "A PID file was found but the process does not seem to be running, removing anyway"
|
2018-12-19 22:55:23 +01:00
|
|
|
fi
|
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
echo "WARNING: This operation will permanently remove the Platypush environment $1"
|
|
|
|
echo -n "Are you sure you want to continue? (y/N) "
|
|
|
|
IFS= read -r answer
|
|
|
|
echo "$answer" | grep -E '^[yY]' >/dev/null || exit 0
|
2018-12-19 22:55:23 +01:00
|
|
|
rm -rf "$envdir"
|
|
|
|
echo "$envdir removed"
|
|
|
|
}
|
|
|
|
|
|
|
|
function usage {
|
|
|
|
echo "Usage: $0 <build|start|stop|rm> [options]" >&2
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
|
|
|
if (( $# < 1 )); then
|
|
|
|
usage
|
|
|
|
fi
|
|
|
|
|
|
|
|
action=$1
|
|
|
|
shift
|
2021-09-16 17:53:40 +02:00
|
|
|
mkdir -p "${workdir}"
|
2018-12-19 22:55:23 +01:00
|
|
|
|
2021-09-16 17:53:40 +02:00
|
|
|
# shellcheck disable=SC2048,SC2086
|
2019-12-01 22:27:54 +01:00
|
|
|
case ${action} in
|
2021-09-16 17:53:40 +02:00
|
|
|
'build') build $*;;
|
2018-12-19 22:55:23 +01:00
|
|
|
'start') start $*;;
|
|
|
|
'stop') stop $*;;
|
|
|
|
'rm') rme $*;;
|
|
|
|
*) usage;;
|
|
|
|
esac
|