systemd-deployed daemon that drives the semprini-core stack-support agent headless via Claude Code, monitors health via Uptime Kuma, applies safe upgrades, and escalates to the operator over Matrix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
44 lines
1.5 KiB
Bash
Executable File
44 lines
1.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# install.sh — install & enable the semprini-maintainer systemd service.
|
|
#
|
|
# Run from this directory. Requires sudo for the systemd parts.
|
|
set -euo pipefail
|
|
|
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
UNIT="semprini-maintainer.service"
|
|
DEST="/etc/systemd/system/$UNIT"
|
|
|
|
echo "→ Pre-flight checks"
|
|
command -v docker >/dev/null || { echo "ERROR: docker not found"; exit 1; }
|
|
command -v python3 >/dev/null || { echo "ERROR: python3 not found"; exit 1; }
|
|
|
|
CLAUDE_BIN="$(python3 -c "import json;print(json.load(open('$DIR/config.json'))['claude_bin'])" 2>/dev/null || echo /home/paul/.local/bin/claude)"
|
|
[ -x "$CLAUDE_BIN" ] || echo "WARN: claude binary not executable at $CLAUDE_BIN"
|
|
|
|
if [ ! -f "$DIR/config.json" ]; then
|
|
echo "ERROR: config.json missing. Run:"
|
|
echo " cp $DIR/config.example.json $DIR/config.json"
|
|
echo " $DIR/register-matrix-bot.sh"
|
|
exit 1
|
|
fi
|
|
|
|
TOKEN="$(python3 -c "import json;print(json.load(open('$DIR/config.json'))['matrix']['access_token'])")"
|
|
case "$TOKEN" in
|
|
""|FILLED_BY_*) echo "ERROR: Matrix not provisioned. Run register-matrix-bot.sh first."; exit 1;;
|
|
esac
|
|
|
|
echo "→ Syntax-checking maintainer.py"
|
|
python3 -m py_compile "$DIR/maintainer.py"
|
|
|
|
echo "→ Installing $UNIT"
|
|
sudo cp "$DIR/$UNIT" "$DEST"
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable "$UNIT"
|
|
sudo systemctl restart "$UNIT"
|
|
|
|
echo
|
|
echo "✓ Installed and started."
|
|
echo " Logs: journalctl -u $UNIT -f"
|
|
echo " Status: systemctl status $UNIT"
|
|
echo " Stop: sudo systemctl stop $UNIT"
|