74 lines
2.6 KiB
Bash
74 lines
2.6 KiB
Bash
#!/usr/bin/env bash
|
|||
|
|
# Stop the task manager board.
|
||
|
|
#
|
||
|
|
# ./.task-manager/stop.sh # refuses while agents are running
|
||
|
|
# ./.task-manager/stop.sh --force # stop anyway (agents keep running,
|
||
|
|
# # but the board loses their endings:
|
||
|
|
# # no auto-move, no PR, no decline)
|
||
|
|
#
|
||
|
|
# Only ever stops OUR board: the process is identified by asking the port's
|
||
|
|
# /api/state for its tasks root — a foreign process on the port is left alone.
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
TM="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
|
|
ENV_FILE="$TM/manager/local/.env"
|
||
|
|
FORCE="${1:-}"
|
||
|
|
|
||
|
|
port="${BOARD_PORT:-}"
|
||
|
|
if [ -z "$port" ] && [ -f "$ENV_FILE" ]; then
|
||
|
|
port="$(sed -n 's/^[[:space:]]*BOARD_PORT[[:space:]]*=[[:space:]]*//p' "$ENV_FILE" | tail -1 | tr -d "'\"")"
|
||
|
|
fi
|
||
|
|
port="${port:-26071}"
|
||
|
|
|
||
|
|
# One probe answers both questions: is this our board, and are agents running?
|
||
|
|
probe="$(python3 -c '
|
||
|
|
import json, sys, urllib.request
|
||
|
|
import urllib.error
|
||
|
|
try:
|
||
|
|
with urllib.request.urlopen("http://127.0.0.1:%s/api/state" % sys.argv[1], timeout=2) as r:
|
||
|
|
data = json.load(r)
|
||
|
|
except urllib.error.HTTPError:
|
||
|
|
print("foreign"); sys.exit(0) # something HTTP answered, but not our API
|
||
|
|
except Exception:
|
||
|
|
print("none"); sys.exit(0)
|
||
|
|
if data.get("board", {}).get("root") != sys.argv[2]:
|
||
|
|
print("foreign"); sys.exit(0)
|
||
|
|
running = [a for a in data.get("agents", []) if a.get("status") == "running"]
|
||
|
|
print("ours " + ",".join(
|
||
|
|
"%s on %s" % (a.get("name") or "an agent", a.get("task", "?")) for a in running))
|
||
|
|
' "$port" "$TM/tasks")"
|
||
|
|
|
||
|
|
case "$probe" in
|
||
|
|
none)
|
||
|
|
if lsof -ti tcp:"$port" >/dev/null 2>&1; then
|
||
|
|
echo "Port $port is occupied by something that isn't this project's board — leaving it alone." >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
echo "Nothing answering on port $port — the board is not running."
|
||
|
|
exit 0;;
|
||
|
|
foreign)
|
||
|
|
echo "Port $port is serving something that is not this project's board — leaving it alone." >&2
|
||
|
|
exit 1;;
|
||
|
|
esac
|
||
|
|
|
||
|
|
agents="${probe#ours }"
|
||
|
|
if [ -n "$agents" ] && [ "$FORCE" != "--force" ]; then
|
||
|
|
echo "Agents are still working: $agents"
|
||
|
|
echo "Stopping now would lose their endings (auto-move, PR, decline handling)."
|
||
|
|
echo "Wait for them, hold them from the board, or run: ./.task-manager/stop.sh --force"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
pids="$(lsof -ti tcp:"$port" 2>/dev/null || true)"
|
||
|
|
if [ -z "$pids" ]; then
|
||
|
|
echo "Board answered but no local process found on port $port — nothing to do."
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
kill $pids
|
||
|
|
for _ in 1 2 3 4 5 6 7 8 9 10; do
|
||
|
|
sleep 0.3
|
||
|
|
lsof -ti tcp:"$port" >/dev/null 2>&1 || { echo "Board stopped."; exit 0; }
|
||
|
|
done
|
||
|
|
echo "Still up after SIGTERM — you may need: kill -9 $pids" >&2
|
||
|
|
exit 1
|