Stop the containers instead of claiming success (#380)
docker-compose.yml has no 'pid: host', so each container has its own PID namespace and pkill on the host matches nothing inside them. The script then printed "All services gracefully stopped" while mavend, its llama-server and the rest were still running. Now it checks for running compose containers first and stops them with docker compose. If it cannot ask docker and finds nothing to kill on the host, or anything survives the kill, it says so and exits non-zero instead of claiming success. The bare-metal path is unchanged apart from verifying the SIGKILL actually worked, and no longer risks killing the shell it was launched from. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CGeSZxh1DCtRxmFVSYVGvJ
This commit is contained in:
+74
-3
@@ -1,8 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
# Unified script to stop all Maven services.
|
||||
# Usage: ./kill-maven.sh
|
||||
# - Graceful SIGTERM is attempted first.
|
||||
# - If any process lingers, force with SIGKILL.
|
||||
# - Docker deploy: `docker compose stop` (see why below).
|
||||
# - Bare-metal / dev run: graceful SIGTERM first, SIGKILL if anything lingers.
|
||||
# Exits non-zero if it cannot confirm everything is stopped. It must never say
|
||||
# "stopped" unless it checked.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -24,6 +26,69 @@ else
|
||||
LLM='llama-server.*\.gguf'
|
||||
fi
|
||||
|
||||
COMPOSE_FILE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/docker-compose.yml"
|
||||
|
||||
# --- containerised deploy ------------------------------------------------
|
||||
# docker-compose.yml does not set `pid: host`, so each container has its own
|
||||
# PID namespace: pkill on the host sees nothing inside them. This script used
|
||||
# to print "all stopped" while every daemon was still happily running. Stop the
|
||||
# containers through compose instead — that actually reaches them.
|
||||
#
|
||||
# running_containers prints the ids of the project's running containers, or
|
||||
# nothing. Empty output plus a non-zero return means "could not ask docker",
|
||||
# which is different from "nothing is running" and is handled below.
|
||||
running_containers() {
|
||||
docker compose -f "$COMPOSE_FILE" ps -q --status running 2>/dev/null
|
||||
}
|
||||
|
||||
DOCKER_OK=0
|
||||
CONTAINERS=""
|
||||
if command -v docker >/dev/null 2>&1 && [ -f "$COMPOSE_FILE" ]; then
|
||||
if CONTAINERS="$(running_containers)"; then
|
||||
DOCKER_OK=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$DOCKER_OK" = 1 ] && [ -n "$CONTAINERS" ]; then
|
||||
echo "--- Maven is running in containers: stopping via docker compose ---"
|
||||
if ! docker compose -f "$COMPOSE_FILE" stop; then
|
||||
echo "ERROR: 'docker compose stop' failed. Containers may still be running." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "--- Verifying containers are gone ---"
|
||||
LEFT="$(running_containers || true)"
|
||||
if [ -n "$LEFT" ]; then
|
||||
echo "ERROR: containers still running after stop:" >&2
|
||||
docker compose -f "$COMPOSE_FILE" ps >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
echo "All containers stopped."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# --- bare-metal / dev run -----------------------------------------------
|
||||
# pgrep -f matches whole command lines, so a shell that merely mentions
|
||||
# "mavend" (this script's own parent, for one) shows up. Drop ourselves and our
|
||||
# parent, otherwise the SIGKILL sweep can take out the terminal you ran this in.
|
||||
host_pids() {
|
||||
pgrep -f "$PAT|$LLM" | grep -v -e "^$$\$" -e "^$PPID\$" | paste -sd, - || true
|
||||
}
|
||||
HOST_PIDS=$(host_pids)
|
||||
|
||||
if [ -z "$HOST_PIDS" ]; then
|
||||
# Nothing to kill on the host and no running containers. Either Maven is
|
||||
# already down, or it is somewhere this script cannot see (another PID
|
||||
# namespace, another user, docker unreachable). We cannot tell the
|
||||
# difference, so refuse to claim success.
|
||||
echo "ERROR: found no Maven processes on this host and no running containers." >&2
|
||||
if [ "$DOCKER_OK" != 1 ]; then
|
||||
echo " Could not ask docker either — if this is the container deploy," >&2
|
||||
echo " run: docker compose -f $COMPOSE_FILE stop" >&2
|
||||
fi
|
||||
echo " Nothing was stopped. Check by hand before assuming Maven is down." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "--- Sending graceful SIGTERM to Maven services ---"
|
||||
pkill -TERM -f "$PAT" || true
|
||||
# mavend's Pdeathsig SIGKILLs its llama-server on exit, but sweep strays too
|
||||
@@ -32,11 +97,17 @@ pkill -TERM -f "$LLM" || true
|
||||
|
||||
echo "--- Verifying processes are gone ---"
|
||||
sleep 1
|
||||
PIDS=$(pgrep -d ',' -f "$PAT|$LLM") || PIDS=""
|
||||
PIDS=$(host_pids)
|
||||
if [ -n "$PIDS" ]; then
|
||||
echo "Warning: some processes still alive. PIDs: $PIDS"
|
||||
echo "--- Force killing with SIGKILL ---"
|
||||
echo "$PIDS" | tr ',' '\n' | xargs -r kill -9
|
||||
sleep 1
|
||||
LEFT=$(host_pids)
|
||||
if [ -n "$LEFT" ]; then
|
||||
echo "ERROR: still alive after SIGKILL. PIDs: $LEFT" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Done (SIGKILL)."
|
||||
else
|
||||
echo "All services gracefully stopped."
|
||||
|
||||
Reference in New Issue
Block a user