// Agent binary. Runs in two modes: live-image (default, no args) // parses /proc/cmdline and enters the claim loop; host-mode // ("vetting-agent host") reads /etc/vetting/host-agent.yaml and // becomes a persistent heartbeat reporter. package main import ( "context" "errors" "flag" "log" "os" "os/signal" "syscall" "vetting/agent" "vetting/agent/bootstate" "vetting/agent/hostmode" ) func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() sig := make(chan os.Signal, 1) signal.Notify(sig, os.Interrupt, syscall.SIGTERM) go func() { <-sig log.Printf("vetting-agent: signal received, shutting down") cancel() }() // `vetting-agent host` = persistent reporter (systemd service on // the installed host). No-arg = live-image agent that parses the // boot cmdline — keeping the default preserves PXE/initrd scripts. if len(os.Args) >= 2 && os.Args[1] == "host" { runHost(ctx, os.Args[2:]) return } runLive(ctx) } func runLive(ctx context.Context) { cmdlinePath := flag.String("cmdline", "/proc/cmdline", "path to kernel cmdline (override for local testing)") flag.Parse() p, err := bootstate.ParseCmdline(*cmdlinePath) if err != nil { log.Fatalf("bootstate: %v", err) } log.Printf("vetting-agent starting: run=%d mac=%s orchestrator=%s", p.RunID, p.MAC, p.OrchestratorURL) if err := agent.Run(ctx, p); err != nil && !errors.Is(err, context.Canceled) { log.Fatalf("agent: %v", err) } } func runHost(ctx context.Context, args []string) { fs := flag.NewFlagSet("host", flag.ExitOnError) cfgPath := fs.String("config", "/etc/vetting/host-agent.yaml", "path to host-agent.yaml") _ = fs.Parse(args) if err := hostmode.Run(ctx, *cfgPath); err != nil && !errors.Is(err, context.Canceled) { log.Fatalf("hostmode: %v", err) } }