#!/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 # # # # @author: Fabio Manganiello # # @licence: MIT # ############################################################################## workdir="$HOME/.local/share/platypush/venv" function build { cfgfile= while getopts ':c:' opt; do case ${opt} in 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 if [[ -z "$cfgfile" ]]; then echo "Usage: $0 build -c " >&2 exit 1 fi echo "Parsing configuration file" pip_cmd= pkg_cmd= includes=() cmd_exec=() while read -r line; do 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 <" >&2 exit 1 fi env=$1 envdir="${workdir}/${env}" rundir="${envdir}/var/run" pidfile="${rundir}/platypush.pid" cfgfile="${envdir}/etc/platypush/config.yaml" if [[ ! -d "$envdir" ]]; then echo "No such directory: $envdir" >&2 exit 1 fi mkdir -p "${rundir}" if [[ -f "$pidfile" ]]; then if pgrep -F "${pidfile}"; then echo "Another instance (PID $(cat "${pidfile}")) is running, please stop that instance first" exit 1 fi echo "A PID file was found but the process does not seem to be running, starting anyway" rm -f "$pidfile" fi python3 -m venv "${envdir}" cd "${envdir}" || exit 1 source bin/activate bin/platypush -c "$cfgfile" -P "$pidfile" & start_time=$(date +'%s') timeout=30 while :; do [[ -f "$pidfile" ]] && break now=$(date +'%s') elapsed=$(( now-start_time )) if (( elapsed >= timeout )); then echo "Platypush instance '$env' did not start within $timeout seconds" >&2 exit 1 fi echo -n '.' sleep 1 done pid=$(cat "$pidfile") echo echo "Platypush environment $env started with PID $pid" wait "${pid}" echo "Platypush environment $env terminated" } function stop { if [[ -z "$1" ]]; then echo "Usage: $0 stop " >&2 exit 1 fi env=$1 envdir="${workdir}/${env}" rundir="${envdir}/var/run" pidfile="${rundir}/platypush.pid" if [[ ! -d "$envdir" ]]; then echo "No such directory: $envdir" >&2 exit 1 fi if [[ ! -f "$pidfile" ]]; then echo "No pidfile found for instance \"${env}\"" exit 1 fi pid=$(cat "$pidfile") pids="$pid $(ps --no-headers -o pid= --ppid "$pid")" # shellcheck disable=SC2086 kill -9 ${pids} rm -f "$pidfile" echo "Instance '$env' with PID $pid stopped" } function rme { if [[ -z "$1" ]]; then echo "Usage: $0 rm " >&2 exit 1 fi envdir="${workdir}/$1" rundir="${envdir}/var/run" pidfile="${rundir}/platypush.pid" if [[ ! -d "$envdir" ]]; then echo "No such directory: $envdir" >&2 exit 1 fi if [[ -f "$pidfile" ]]; then if pgrep -F "${pidfile}"; then echo "Another instance (PID $(cat "$pidfile")) is running, please stop that instance first" exit 1 fi echo "A PID file was found but the process does not seem to be running, removing anyway" fi 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 rm -rf "$envdir" echo "$envdir removed" } function usage { echo "Usage: $0 [options]" >&2 exit 1 } if (( $# < 1 )); then usage fi action=$1 shift mkdir -p "${workdir}" # shellcheck disable=SC2048,SC2086 case ${action} in 'build') build $*;; 'start') start $*;; 'stop') stop $*;; 'rm') rme $*;; *) usage;; esac