systemd/agent-watcher.service: --user unit with on-failure restart, ProtectSystem=strict, ProtectHome=read-write, NoNewPrivileges=yes, PrivateTmp=yes. JSON logs to journald. Survives reboot via 'loginctl enable-linger'. examples/collector.yaml: working starter config for both sources with inline comments, per-route examples, and the spec §3.1.2 schema for drop files. install.sh: idempotent installer following the agent-ping pattern. Builds the binary, installs it + the unit, drops the example config if absent, reloads systemd, enables, and (unless --no-start) starts the service. Adds drop-folder lifecycle artifacts (*.tmp, .dead-letter/) to workspace .stignore so they don't replicate during processing. Skips Syncthing-related steps gracefully when ~/Nyx/workspace is not present. INSTALL.md: prerequisites, install, configure, verify (drop-file + webhook end-to-end probes), survive-logout, uninstall, troubleshooting table. README.md: rewritten to reflect actual status — v0 working with 43 tests, packaging ready, Layer 2 in progress on Bob's side. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
114 lines
3.9 KiB
Bash
Executable file
114 lines
3.9 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# install.sh — set up the agent-watcher Collector on this machine.
|
|
#
|
|
# Usage:
|
|
# ./install.sh # build + install + enable + start
|
|
# ./install.sh --no-start # everything but `systemctl start`
|
|
#
|
|
# What it does:
|
|
# 1. Builds the agent-watcher binary (requires Go 1.22+).
|
|
# 2. Installs to ~/.local/bin/agent-watcher.
|
|
# 3. Drops the systemd --user unit into ~/.config/systemd/user/.
|
|
# 4. Drops a starter ~/.config/agent-watcher/collector.yaml if missing
|
|
# (copies examples/collector.yaml; you edit it before first start).
|
|
# 5. Reloads systemd, enables, and (unless --no-start) starts the unit.
|
|
# 6. Adds drop-folder lifecycle patterns to the workspace .stignore so
|
|
# drop files do not Syncthing-replicate during local processing.
|
|
#
|
|
# Per CLAUDE.md rule #2, this is intended to be run by a human. The
|
|
# Collector itself, like agent-ping, never invokes this script.
|
|
#
|
|
# Layer 2 (MCP Watcher) has its own install path — different language,
|
|
# different runtime, different unit. See its README when it lands.
|
|
|
|
set -euo pipefail
|
|
|
|
NO_START=0
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--no-start) NO_START=1 ;;
|
|
*) echo "unknown arg: $arg" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
BIN_DIR="$HOME/.local/bin"
|
|
CONF_DIR="$HOME/.config/agent-watcher"
|
|
UNIT_DIR="$HOME/.config/systemd/user"
|
|
WORKSPACE="$HOME/Nyx/workspace"
|
|
STIGNORE="$WORKSPACE/.stignore"
|
|
|
|
echo "agent-watcher install"
|
|
echo "repo: $REPO_DIR"
|
|
echo
|
|
|
|
# 1. Check Go
|
|
echo "[1/6] checking Go toolchain"
|
|
if ! command -v go >/dev/null 2>&1; then
|
|
echo " ERROR: 'go' not found. Install Go 1.22+ first." >&2
|
|
echo " e.g. sudo apt install golang-go" >&2
|
|
exit 1
|
|
fi
|
|
GO_VERSION=$(go version | awk '{print $3}')
|
|
echo " $GO_VERSION"
|
|
|
|
# 2. Build
|
|
echo "[2/6] building agent-watcher binary"
|
|
mkdir -p "$BIN_DIR"
|
|
( cd "$REPO_DIR" && go build -o "$BIN_DIR/agent-watcher" ./cmd/agent-watcher )
|
|
echo " installed: $BIN_DIR/agent-watcher"
|
|
|
|
# 3. systemd unit
|
|
echo "[3/6] installing systemd --user unit"
|
|
mkdir -p "$UNIT_DIR"
|
|
install -m 0644 "$REPO_DIR/systemd/agent-watcher.service" "$UNIT_DIR/agent-watcher.service"
|
|
echo " installed: $UNIT_DIR/agent-watcher.service"
|
|
|
|
# 4. Config skeleton
|
|
echo "[4/6] config skeleton"
|
|
mkdir -p "$CONF_DIR"
|
|
if [ -f "$CONF_DIR/collector.yaml" ]; then
|
|
echo " $CONF_DIR/collector.yaml exists — leaving as-is"
|
|
else
|
|
install -m 0644 "$REPO_DIR/examples/collector.yaml" "$CONF_DIR/collector.yaml"
|
|
echo " installed example: $CONF_DIR/collector.yaml — EDIT BEFORE START"
|
|
fi
|
|
|
|
# 5. .stignore — drop folder is replicated, but lifecycle artifacts shouldn't be
|
|
echo "[5/6] .stignore (drop-folder lifecycle artifacts are local-only)"
|
|
if [ -d "$WORKSPACE" ]; then
|
|
touch "$STIGNORE"
|
|
for pattern in "incoming/.dead-letter/" "incoming/*.json.tmp"; do
|
|
if ! grep -qxF "$pattern" "$STIGNORE"; then
|
|
echo "$pattern" >> "$STIGNORE"
|
|
echo " added: $pattern"
|
|
fi
|
|
done
|
|
else
|
|
echo " $WORKSPACE not present — skipping (Syncthing not set up here)"
|
|
fi
|
|
|
|
# 6. systemd reload + enable + (optionally) start
|
|
echo "[6/6] systemd reload + enable"
|
|
systemctl --user daemon-reload
|
|
systemctl --user enable agent-watcher.service >/dev/null
|
|
echo " enabled at user login (loginctl enable-linger required to run when logged out)"
|
|
|
|
if [ "$NO_START" -eq 0 ]; then
|
|
echo " starting…"
|
|
systemctl --user restart agent-watcher.service
|
|
sleep 1
|
|
systemctl --user status agent-watcher.service --no-pager -n 5 || true
|
|
else
|
|
echo " --no-start: not starting; run 'systemctl --user start agent-watcher' when ready"
|
|
fi
|
|
|
|
echo
|
|
echo "installation complete."
|
|
echo
|
|
echo "next steps:"
|
|
echo " 1. EDIT $CONF_DIR/collector.yaml to suit this host."
|
|
echo " 2. systemctl --user restart agent-watcher (after edits)."
|
|
echo " 3. journalctl --user -u agent-watcher -f (watch logs)."
|
|
echo " 4. curl http://127.0.0.1:18790/health (sanity check)."
|
|
echo " 5. To survive logout: loginctl enable-linger \$USER"
|