7468806bad
Lightweight stdlib-only Python agent runs on each monitored host, collects CPU / memory / disk / load / uptime from /proc every 30s, and POSTs signed payloads to the Roundtable ingest endpoint. One-line curl-pipe installer creates a hardened systemd unit; admin UI manages host registrations with rotate / revoke. - agent.py: 370 LoC single-file daemon, ring buffer + exponential backoff - ingest route: bearer-token auth, metric expansion into plugin_metrics - install.sh.j2: systemd unit with NoNewPrivileges / ProtectSystem / ProtectHome - settings UI: add host / rotate token / delete registration (admin-only) - dashboard widgets: fleet-glance table + per-host history chart - stale-agent scheduler: 60s log warning for agents past 180s silence Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
82 lines
3.0 KiB
Django/Jinja
82 lines
3.0 KiB
Django/Jinja
#!/bin/sh
|
|
# Roundtable host agent installer
|
|
# Generated for: {{ host_name }} ({{ host_address }})
|
|
# Roundtable URL: {{ url }}
|
|
set -e
|
|
|
|
ROUNDTABLE_URL="{{ url }}"
|
|
AGENT_TOKEN="{{ token }}"
|
|
AGENT_VERSION="{{ agent_version }}"
|
|
|
|
AGENT_USER="roundtable-agent"
|
|
AGENT_DIR="/usr/local/lib/roundtable-agent"
|
|
CONF_FILE="/etc/roundtable-agent.conf"
|
|
UNIT_FILE="/etc/systemd/system/roundtable-agent.service"
|
|
|
|
# ── preflight ────────────────────────────────────────────────────────────────
|
|
[ "$(id -u)" = "0" ] || { echo "must run as root (use sudo)"; exit 1; }
|
|
command -v systemctl >/dev/null 2>&1 || { echo "systemd not found — unsupported init system"; exit 1; }
|
|
command -v python3 >/dev/null 2>&1 || { echo "python3 not found — install python3 first"; exit 1; }
|
|
|
|
# Handle --uninstall
|
|
if [ "${1:-}" = "--uninstall" ]; then
|
|
systemctl disable --now roundtable-agent.service 2>/dev/null || true
|
|
rm -f "$UNIT_FILE" "$CONF_FILE"
|
|
rm -rf "$AGENT_DIR"
|
|
systemctl daemon-reload
|
|
# keep the system user — removing it risks orphaned files elsewhere
|
|
echo "uninstalled"
|
|
exit 0
|
|
fi
|
|
|
|
# ── create system user ───────────────────────────────────────────────────────
|
|
if ! id "$AGENT_USER" >/dev/null 2>&1; then
|
|
useradd --system --no-create-home --shell /usr/sbin/nologin "$AGENT_USER"
|
|
fi
|
|
|
|
# ── drop the agent file ──────────────────────────────────────────────────────
|
|
mkdir -p "$AGENT_DIR"
|
|
curl -sSL "${ROUNDTABLE_URL}/plugins/host_agent/agent.py" -o "$AGENT_DIR/agent.py"
|
|
chmod 0755 "$AGENT_DIR/agent.py"
|
|
chown root:root "$AGENT_DIR/agent.py"
|
|
|
|
# ── write config ─────────────────────────────────────────────────────────────
|
|
cat > "$CONF_FILE" <<EOF
|
|
url = $ROUNDTABLE_URL
|
|
token = $AGENT_TOKEN
|
|
interval_seconds = 30
|
|
EOF
|
|
chown "root:$AGENT_USER" "$CONF_FILE"
|
|
chmod 0640 "$CONF_FILE"
|
|
|
|
# ── write systemd unit ───────────────────────────────────────────────────────
|
|
cat > "$UNIT_FILE" <<EOF
|
|
[Unit]
|
|
Description=Roundtable host agent
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=$AGENT_USER
|
|
ExecStart=/usr/bin/python3 $AGENT_DIR/agent.py
|
|
Restart=on-failure
|
|
RestartSec=10
|
|
NoNewPrivileges=yes
|
|
ProtectSystem=strict
|
|
ProtectHome=yes
|
|
PrivateTmp=yes
|
|
ReadOnlyPaths=/proc /sys
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
systemctl daemon-reload
|
|
systemctl enable --now roundtable-agent.service
|
|
|
|
echo
|
|
echo "Roundtable host agent $AGENT_VERSION installed and running."
|
|
echo "Check status: systemctl status roundtable-agent"
|
|
echo "Logs: journalctl -u roundtable-agent -f"
|