Previously `decnet status` on an agent showed every microservice as DOWN
because deploy's auto-spawn was unihost-scoped and the agent CLI gate
hid the per-host commands. Now:
- collect, probe, profiler, sniffer drop out of MASTER_ONLY_COMMANDS
(they run per-host; master-side work stays master-gated).
- mutate stays master-only (it orchestrates swarm-wide respawns).
- decnet/mutator/ excluded from agent tarballs — never invoked there.
- decnet/web exclusion tightened: ship db/ + auth.py + dependencies.py
(profiler needs the repo singleton), drop api.py, swarm_api.py,
ingester.py, router/, templates/.
- Four new systemd unit templates (decnet-collector/prober/profiler/
sniffer) shipped in every enrollment tarball.
- enroll_bootstrap.sh enables + starts all four alongside agent and
forwarder at install time.
- updater restarts the aux units on code push so they pick up the new
release (best-effort — legacy enrollments without the units won't
fail the update).
- status table hides Mutator + API rows in agent mode.
87 lines
3.3 KiB
Django/Jinja
87 lines
3.3 KiB
Django/Jinja
#!/usr/bin/env bash
|
|
# DECNET bootstrap installer for agent {{ agent_name }} -> master {{ master_host }}.
|
|
# Fetches the code+certs payload, installs, and starts the agent daemon.
|
|
# Generated by the master at {{ generated_at }}. Expires {{ expires_at }}.
|
|
set -euo pipefail
|
|
|
|
[[ $EUID -eq 0 ]] || { echo "decnet-install: must run as root (use sudo)"; exit 1; }
|
|
for bin in python3 curl tar systemctl; do
|
|
command -v "$bin" >/dev/null || { echo "decnet-install: $bin required"; exit 1; }
|
|
done
|
|
|
|
WORK="$(mktemp -d)"
|
|
trap 'rm -rf "$WORK"' EXIT
|
|
|
|
echo "[DECNET] fetching payload..."
|
|
curl -fsSL "{{ tarball_url }}" | tar -xz -C "$WORK"
|
|
|
|
INSTALL_DIR=/opt/decnet
|
|
RELEASE_DIR="$INSTALL_DIR/releases/active"
|
|
VENV_DIR="$INSTALL_DIR/venv"
|
|
# Mirror the updater's layout from day one so `decnet updater` can rotate
|
|
# releases/active in-place and the shared venv is the thing on PATH.
|
|
mkdir -p "$RELEASE_DIR"
|
|
cp -a "$WORK/." "$RELEASE_DIR/"
|
|
ln -sfn "$RELEASE_DIR" "$INSTALL_DIR/current"
|
|
cd "$RELEASE_DIR"
|
|
|
|
echo "[DECNET] building shared venv at $VENV_DIR..."
|
|
python3 -m venv "$VENV_DIR"
|
|
"$VENV_DIR/bin/pip" install -q --upgrade pip
|
|
"$VENV_DIR/bin/pip" install -q "$RELEASE_DIR"
|
|
|
|
install -Dm0644 etc/decnet/decnet.ini /etc/decnet/decnet.ini
|
|
[[ -f services.ini ]] && install -Dm0644 services.ini /etc/decnet/services.ini
|
|
|
|
# Log directory the baked-in INI points at — must exist before `decnet` imports config.
|
|
install -d -m0755 /var/log/decnet
|
|
|
|
# Certs live under /etc/decnet/ (root-owned, 0600 keys) — this is a root
|
|
# daemon's data, not a user's. The baked INI's `agent-dir`/`updater-dir`
|
|
# point at these paths.
|
|
for f in ca.crt worker.crt worker.key; do
|
|
install -Dm0600 -o root -g root \
|
|
"home/.decnet/agent/$f" "/etc/decnet/agent/$f"
|
|
done
|
|
chmod 0755 /etc/decnet/agent
|
|
|
|
WITH_UPDATER="{{ with_updater }}"
|
|
if [[ "$WITH_UPDATER" == "true" && -d home/.decnet/updater ]]; then
|
|
for f in ca.crt updater.crt updater.key; do
|
|
install -Dm0600 -o root -g root \
|
|
"home/.decnet/updater/$f" "/etc/decnet/updater/$f"
|
|
done
|
|
chmod 0755 /etc/decnet/updater
|
|
fi
|
|
|
|
# Guarantee the pip-installed entrypoint is executable (some setuptools+editable
|
|
# combos drop it with mode 0644) and expose it on PATH.
|
|
chmod 0755 "$VENV_DIR/bin/decnet"
|
|
ln -sf "$VENV_DIR/bin/decnet" /usr/local/bin/decnet
|
|
|
|
echo "[DECNET] installing systemd units..."
|
|
for unit in \
|
|
decnet-agent decnet-forwarder decnet-engine \
|
|
decnet-collector decnet-prober decnet-profiler decnet-sniffer; do
|
|
install -Dm0644 "etc/systemd/system/${unit}.service" "/etc/systemd/system/${unit}.service"
|
|
done
|
|
if [[ "$WITH_UPDATER" == "true" ]]; then
|
|
install -Dm0644 etc/systemd/system/decnet-updater.service /etc/systemd/system/decnet-updater.service
|
|
fi
|
|
systemctl daemon-reload
|
|
|
|
# Agent + forwarder are the control plane; collector/prober/profiler/sniffer
|
|
# are the per-host microservices that used to require `decnet deploy` to
|
|
# auto-spawn. With systemd units they come up at boot and auto-restart.
|
|
ACTIVE_UNITS=(
|
|
decnet-agent.service decnet-forwarder.service
|
|
decnet-collector.service decnet-prober.service
|
|
decnet-profiler.service decnet-sniffer.service
|
|
)
|
|
if [[ "$WITH_UPDATER" == "true" ]]; then
|
|
ACTIVE_UNITS+=(decnet-updater.service)
|
|
fi
|
|
systemctl enable --now "${ACTIVE_UNITS[@]}"
|
|
|
|
echo "[DECNET] agent {{ agent_name }} enrolled -> {{ master_host }}. Units: ${ACTIVE_UNITS[*]} active."
|