f0e7ac73d6
The merged fix told the operator to look in journalctl for "Fleetd.reportRequiredSecrets". That string never appears there — it is a method name. The logger is d.l.f.Fleetd and the lines read "startup secret NAME: set|MISSING", so the advice sent the operator looking for text that does not exist. Give the grep instead, and say what the report does not cover: it lists only names a configured profile references, so a secret nothing references is never reported.
78 lines
3.7 KiB
Desktop File
78 lines
3.7 KiB
Desktop File
# CB-504 — systemd unit for fleetd (Linux).
|
|
#
|
|
# The macOS launchd agent (deploy/dev.ltms.fleetd.plist) is the supervision target for the
|
|
# current single-host deployment. This unit exists for the per-host gateways CB-308 introduces,
|
|
# which will run on Linux.
|
|
#
|
|
# Install (user service — fleetd drives the user's herdr, not a system daemon):
|
|
# mkdir -p ~/.config/systemd/user
|
|
# cp deploy/fleetd.service ~/.config/systemd/user/
|
|
# # edit ExecStart / WorkingDirectory / Environment below, then:
|
|
# systemctl --user daemon-reload
|
|
# systemctl --user enable --now fleetd
|
|
# journalctl --user -u fleetd -f
|
|
|
|
[Unit]
|
|
Description=fleetd — claude-bridge message server
|
|
Documentation=https://git.ltms.dev/fleet/fleetd/wiki
|
|
# Ordering only: herdr is a user process and its socket may appear after us. This is advisory —
|
|
# fleetd retries the herdr socket rather than exiting, which is what actually makes a late
|
|
# socket survivable. Do NOT add Requires=: a herdr restart must not take fleetd down with it.
|
|
After=herdr.service
|
|
Wants=herdr.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
WorkingDirectory=%h/src/claude-bridge/fleetd
|
|
ExecStart=/usr/lib/jvm/temurin-25-jdk/bin/java -jar target/fleetd.jar fleetd.yaml
|
|
|
|
Environment=HERDR_SOCKET_PATH=%h/.config/herdr/herdr.sock
|
|
# PATH matters more than it looks (CB-511): fleetd propagates its own PATH to every worker it
|
|
# spawns, so this line decides whether the fleet can run a build at all. systemd does not source a
|
|
# login shell, so without it the daemon — and every worker — gets a bare default with no JDK/Maven.
|
|
Environment=PATH=/usr/lib/jvm/temurin-25-jdk/bin:/usr/share/maven/bin:/usr/local/bin:/usr/bin:/bin
|
|
# Secrets are NOT set here — this file is committed. Put ALL three tokens in a private drop-in
|
|
# that systemd reads with restrictive permissions. In `systemctl --user edit fleetd`, add:
|
|
# [Service]
|
|
# Environment=FLEETD_API_TOKEN=...
|
|
# Environment=WORKER_GITEA_TOKEN=...
|
|
# Environment=AI_GATEWAY_TOKEN=...
|
|
# FLEETD_API_TOKEN protects fleetd's API. WORKER_GITEA_TOKEN lets members open pull requests; if
|
|
# it is missing, fleetd still starts, but a member fails when it later tries to open a pull request.
|
|
# AI_GATEWAY_TOKEN authenticates gateway profiles; if it is missing, fleetd still starts, but a
|
|
# gateway profile later returns HTTP 401. Or, put the same three variables in a 0600 file and add:
|
|
# EnvironmentFile=%h/.config/fleetd/env
|
|
# After starting, check which of them actually resolved. The daemon reports every secret a
|
|
# configured profile references, by name, never by value:
|
|
# journalctl --user -u fleetd | grep 'startup secret'
|
|
# A resolved one logs "startup secret NAME: set (profile 'x' tokenEnv)". A missing one logs
|
|
# "startup secret NAME: MISSING" at WARN — and the daemon starts anyway, which is the whole
|
|
# problem: without this grep the first sign is a member that cannot open a pull request, hours
|
|
# later and in a different component.
|
|
# Note what the report can and cannot tell you. It lists only names some profile actually
|
|
# references (tokenEnv, gitTokenEnv, and the broker uriEnv). A secret nothing references is never
|
|
# reported, because nothing needs it.
|
|
|
|
Restart=on-failure
|
|
RestartSec=10s
|
|
# A bad config (e.g. a non-loopback bind without token auth) makes fleetd fail fast by design.
|
|
# Give up rather than restart-loop on a permanent error.
|
|
StartLimitBurst=5
|
|
StartLimitIntervalSec=120
|
|
|
|
# The daemon reads the repo, writes worktrees, and talks to a Unix socket — it needs no more.
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
ProtectSystem=strict
|
|
ProtectHome=read-write
|
|
ProtectKernelTunables=true
|
|
ProtectControlGroups=true
|
|
RestrictSUIDSGID=true
|
|
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
SyslogIdentifier=fleetd
|
|
|
|
[Install]
|
|
WantedBy=default.target
|