From a2d4f9d86d99d6d3179a52922f1fedbea6f1600b Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 1 Apr 2026 11:45:23 -0600 Subject: [PATCH] v1.2 --- deploy-courseware.sh | 5 +-- destroy-courseware.sh | 3 +- labctl | 12 ++++-- scripts/service_manager.sh | 80 +++++++++++++++++++++++++++++++++----- 4 files changed, 82 insertions(+), 18 deletions(-) mode change 100644 => 100755 deploy-courseware.sh mode change 100644 => 100755 destroy-courseware.sh mode change 100644 => 100755 labctl mode change 100644 => 100755 scripts/service_manager.sh diff --git a/deploy-courseware.sh b/deploy-courseware.sh old mode 100644 new mode 100755 index 12490c2..c00893e --- a/deploy-courseware.sh +++ b/deploy-courseware.sh @@ -3,6 +3,5 @@ set -euo pipefail ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -"$ROOT_DIR/labctl" up -"$ROOT_DIR/labctl" urls - +bash "$ROOT_DIR/labctl" up +bash "$ROOT_DIR/labctl" urls diff --git a/destroy-courseware.sh b/destroy-courseware.sh old mode 100644 new mode 100755 index 10ce64a..dc93da7 --- a/destroy-courseware.sh +++ b/destroy-courseware.sh @@ -3,5 +3,4 @@ set -euo pipefail ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -"$ROOT_DIR/labctl" down - +bash "$ROOT_DIR/labctl" down diff --git a/labctl b/labctl old mode 100644 new mode 100755 index 8851500..f27b63b --- a/labctl +++ b/labctl @@ -7,6 +7,12 @@ ANSIBLE_PYTHON="$ANSIBLE_VENV/bin/python" ANSIBLE_PLAYBOOK="$ANSIBLE_VENV/bin/ansible-playbook" export ANSIBLE_CONFIG="$ROOT_DIR/ansible/ansible.cfg" +run_project_script() { + local script_path=$1 + shift || true + bash "$script_path" "$@" +} + usage() { cat <<'EOF' Usage: @@ -501,10 +507,10 @@ main() { up) confirm_installation run_playbook up.yml - "$ROOT_DIR/scripts/service_manager.sh" start all + run_project_script "$ROOT_DIR/scripts/service_manager.sh" start all ;; down) - "$ROOT_DIR/scripts/service_manager.sh" stop all || true + run_project_script "$ROOT_DIR/scripts/service_manager.sh" stop all || true run_playbook down.yml ;; preflight) @@ -519,7 +525,7 @@ main() { handle_assets_command "$@" ;; start|stop|status|urls|open|logs) - exec "$ROOT_DIR/scripts/service_manager.sh" "$cmd" "$@" + exec bash "$ROOT_DIR/scripts/service_manager.sh" "$cmd" "$@" ;; ""|-h|--help|help) usage diff --git a/scripts/service_manager.sh b/scripts/service_manager.sh old mode 100644 new mode 100755 index bb8cf00..1f5dd55 --- a/scripts/service_manager.sh +++ b/scripts/service_manager.sh @@ -91,6 +91,45 @@ service_ready() { esac } +service_listener_pids() { + local service=$1 + local port + + port=$(service_port "$service") || return 0 + ss -ltnp "( sport = :$port )" 2>/dev/null \ + | grep -o 'pid=[0-9]\+' \ + | cut -d= -f2 \ + | sort -u +} + +kill_pid_tree() { + local signal=$1 + local pid=$2 + + if [[ ! "$pid" =~ ^[0-9]+$ ]]; then + return 0 + fi + + kill "-$signal" -- "-$pid" >/dev/null 2>&1 || true + pkill "-$signal" -P "$pid" >/dev/null 2>&1 || true + kill "-$signal" "$pid" >/dev/null 2>&1 || true +} + +terminate_service_processes() { + local service=$1 + local signal=$2 + local pid=${3:-} + local listener_pid + + if [ -n "$pid" ]; then + kill_pid_tree "$signal" "$pid" + fi + + while IFS= read -r listener_pid; do + kill_pid_tree "$signal" "$listener_pid" + done < <(service_listener_pids "$service") +} + start_one() { local service=$1 local cmd @@ -184,26 +223,47 @@ start_one() { stop_one() { local service=$1 local pid_file + local pid="" + local attempt pid_file=$(service_pid_file "$service") - if [ ! -f "$pid_file" ]; then + if [ -f "$pid_file" ]; then + pid=$(cat "$pid_file") + fi + + if [ -z "$pid" ] && ! service_ready "$service"; then echo "$service not running" return 0 fi - local pid - pid=$(cat "$pid_file") - if kill -0 "$pid" >/dev/null 2>&1; then - kill "$pid" >/dev/null 2>&1 || true - sleep 2 - if kill -0 "$pid" >/dev/null 2>&1; then - kill -9 "$pid" >/dev/null 2>&1 || true + terminate_service_processes "$service" TERM "$pid" + + for attempt in $(seq 1 20); do + if ! has_live_pid "$service" && ! service_ready "$service"; then + rm -f "$pid_file" + echo "stopped $service" + return 0 fi - fi + + sleep 1 + done + + terminate_service_processes "$service" KILL "$pid" + + for attempt in $(seq 1 5); do + if ! has_live_pid "$service" && ! service_ready "$service"; then + rm -f "$pid_file" + echo "stopped $service" + return 0 + fi + + sleep 1 + done rm -f "$pid_file" - echo "stopped $service" + echo "failed to stop $service cleanly" >&2 + exit 1 } status_one() {