Add host-mode heartbeat: vetting-agent host + last-seen badge
CI / Lint + build + test (push) Has been cancelled
CI / Lint + build + test (push) Has been cancelled
vetting-agent gains a `host` subcommand that runs as a systemd service
installed by the quick-register one-liner, POSTing every 30s to
/api/v1/hosts/{mac}/heartbeat so the dashboard tile shows "online" or
"Nm ago" without waiting on WoL. Ships dormant client code for the
Phase 2 reboot_for_vetting command so the server can flip it on later
without a binary redeploy.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package hostmode
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// cmdRebootForVetting is the Phase 2 command the orchestrator sends
|
||||
// when the operator clicked "Start vetting" and the host is actively
|
||||
// heartbeating — the agent redirects next boot to PXE and reboots
|
||||
// itself, obviating WoL.
|
||||
const cmdRebootForVetting = "reboot_for_vetting"
|
||||
|
||||
// handleResponse dispatches on the heartbeat response. Phase 1 never
|
||||
// sees a non-empty Cmd (the server omits the field). Phase 2 adds
|
||||
// reboot_for_vetting handling.
|
||||
func handleResponse(ctx context.Context, resp *heartbeatResponse) {
|
||||
if resp == nil || resp.Cmd == "" {
|
||||
return
|
||||
}
|
||||
switch resp.Cmd {
|
||||
case cmdRebootForVetting:
|
||||
log.Printf("hostmode: orchestrator requested reboot_for_vetting (run=%d)", resp.RunID)
|
||||
rebootForVetting(ctx)
|
||||
default:
|
||||
log.Printf("hostmode: unknown cmd %q, ignoring", resp.Cmd)
|
||||
}
|
||||
}
|
||||
|
||||
// rebootForVetting redirects next boot to PXE (best-effort on UEFI
|
||||
// via efibootmgr) and triggers a clean reboot. BIOS/legacy hosts
|
||||
// typically PXE-boot via DHCP chain on every boot, so efibootmgr
|
||||
// missing is non-fatal.
|
||||
func rebootForVetting(ctx context.Context) {
|
||||
setPXEBootNext(ctx)
|
||||
log.Printf("hostmode: executing systemctl reboot")
|
||||
if err := exec.CommandContext(ctx, "systemctl", "reboot").Run(); err != nil {
|
||||
log.Printf("hostmode: systemctl reboot failed: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user