mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-10-28 15:51:26 +00:00
feat(nodes): SSH bootstrap + housekeeping — install script, bundled binaries, auto-prune (#50)
* feat(nodes): SSH bootstrap + housekeeping — install script, bundled binaries, auto-prune
- `containr nodes add <user@host>` mints an enroll token, SSHes once,
runs the install script remotely; --print emits the one-liner
- Public /api/agents/install.sh + /api/agents/download/{platform};
agent binaries built into the image under /agents
- Agent-side `prune` (bounded docker system prune, volumes opt-in)
and `system_df` commands
- node_agents.auto_prune + health sweep enqueues daily prune;
offline/online transitions notify admins
- CLI nodes update/prune/commands + MCP tools (prune confirm-gated)
- Usage page: install one-liner, per-node Prune + auto toggle
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat(nodes): node detail page — telemetry, containers, commands, controls
/nodes/:id (admin): cpu/mem sparklines from heartbeat history
(1h/24h/7d), containers on node, command history, inline rename,
auto-prune toggle, prune-now with volume opt-in, remove. Agent rows
on the Usage page link into it.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat(nodes): mesh awareness + node detail page
- agent reports tailscale/netbird/zerotier/wireguard interface IPs at
register (authoritative — absent interfaces clear stored state)
- backend stores under node_agents.metadata.mesh, merged on re-register
- node detail page shows mesh addresses under the primary IP
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---------
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
7547375cc2
commit
3f066b3b1e
23 files changed
+1410
-40
No files matched your search
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
# Containr node agent installer.
|
||||
# curl -fsSL <api>/api/agents/install.sh | bash -s -- --url <api> --token <enroll-token>
|
||||
#
|
||||
# One-shot: downloads the agent binary from the Containr instance (or GH
|
||||
# releases as fallback), writes a systemd unit, starts it. SSH is never
|
||||
# needed again — the agent heartbeats and polls commands outbound.
|
||||
set -euo pipefail
|
||||
|
||||
API_URL=""
|
||||
TOKEN=""
|
||||
AGENT_NAME=""
|
||||
VERSION=""
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--url) API_URL="$2"; shift 2 ;;
|
||||
--token) TOKEN="$2"; shift 2 ;;
|
||||
--name) AGENT_NAME="$2"; shift 2 ;;
|
||||
--version) VERSION="$2"; shift 2 ;;
|
||||
*) echo "unknown flag: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ -n "$API_URL" ] || { echo "--url is required" >&2; exit 2; }
|
||||
[ -n "$TOKEN" ] || { echo "--token is required (create one: containr nodes tokens create)" >&2; exit 2; }
|
||||
API_URL="${API_URL%/}"
|
||||
API_URL="${API_URL%/api/v1}"
|
||||
API_URL="${API_URL%/api}"
|
||||
|
||||
info() { printf '\033[1;34m==>\033[0m %s\n' "$*"; }
|
||||
err() { printf '\033[1;31mError:\033[0m %s\n' "$*" >&2; }
|
||||
|
||||
[ "$(id -u)" = "0" ] || { err "run as root (sudo bash -s -- --url … --token …)"; exit 1; }
|
||||
command -v docker >/dev/null 2>&1 || { err "docker not found"; exit 1; }
|
||||
command -v curl >/dev/null 2>&1 || { err "curl not found"; exit 1; }
|
||||
|
||||
ARCH="$(uname -m)"
|
||||
case "$ARCH" in
|
||||
x86_64|amd64) ARCH=amd64 ;;
|
||||
aarch64|arm64) ARCH=arm64 ;;
|
||||
*) err "unsupported architecture: $ARCH"; exit 1 ;;
|
||||
esac
|
||||
|
||||
BIN=/usr/local/bin/containr-agent
|
||||
info "downloading containr-agent (linux/$ARCH)"
|
||||
if ! curl -fsSL "$API_URL/api/agents/download/linux-$ARCH" -o "$BIN" 2>/dev/null; then
|
||||
info "instance has no bundled binary — trying GitHub releases"
|
||||
REF="${VERSION:-latest}"
|
||||
if [ "$REF" = "latest" ]; then
|
||||
DL="https://github.com/Dvorinka/Containr/releases/latest/download/containr-agent-linux-$ARCH"
|
||||
else
|
||||
DL="https://github.com/Dvorinka/Containr/releases/download/$REF/containr-agent-linux-$ARCH"
|
||||
fi
|
||||
curl -fsSL "$DL" -o "$BIN" || { err "agent download failed"; exit 1; }
|
||||
fi
|
||||
chmod +x "$BIN"
|
||||
|
||||
UNIT=/etc/systemd/system/containr-agent.service
|
||||
info "writing systemd unit"
|
||||
cat > "$UNIT" <<UNIT
|
||||
[Unit]
|
||||
Description=Containr node agent
|
||||
After=docker.service network-online.target
|
||||
Wants=network-online.target
|
||||
Requires=docker.service
|
||||
|
||||
[Service]
|
||||
Environment=CONTAINR_API_URL=$API_URL
|
||||
Environment=CONTAINR_AGENT_AUTH_TOKEN=$TOKEN
|
||||
Environment=CONTAINR_AGENT_NAME=${AGENT_NAME:-$(hostname)}
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
ExecStart=$BIN
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
UNIT
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now containr-agent
|
||||
info "agent installed and started — it should appear in Containr within ~15s"
|
||||
Reference in new issue
Block a user