package main // PlatformOps abstracts the system operations the command dispatcher needs. // Command dispatch, capability gating and Ed25519 verification are // platform-neutral (websocket.go); the actual mechanics differ per OS: // // - linuxPlatformOps (platform_linuxops.go) — systemctl, journalctl, bash, ... // - windowsPlatformOps (platform_windows.go) — sc.exe, powershell, the // theta-agent-helper for session-0 ops and staged self-update. // // defaultPlatformOps is pinned at startup (runAgent) and swappable in tests so // command dispatch can be exercised identically on any host. type PlatformOps interface { // Reboot restarts the host. Reboot() ([]byte, error) // Shutdown powers the host off. Shutdown() ([]byte, error) // FetchLogs returns the last `lines` log lines for a service. FetchLogs(service string, lines int) ([]byte, error) // ServiceControl runs an action (start/stop/restart/status/...) against a // Windows service. Actions that don't map are executed best-effort. ServiceControl(service, action string) ([]byte, error) // RunScript executes an operator-supplied script (arbitrary_bash). RunScript(script string) ([]byte, error) // DesktopControl runs a desktop-control subaction (lock/logout/display/sleep) // for a target user. DesktopControl(subAction, targetUser string) ([]byte, error) // ConfigureLDAP writes the pushed LDAP configuration. Linux configures // SSSD; Windows manages logon via OpenCredential instead and declines. ConfigureLDAP(configData string) error // ApplyUpdate downloads, verifies and stages a new binary. The swap is // platform-specific: Linux renames over the running binary, Windows writes // a `.new` next to it and hands the swap to theta-agent-helper (the running // exe is locked and the service must stop first). ApplyUpdate(downloadURL, checksum string) error // SelfRestart terminates the agent so a staged update takes effect. Linux // exits; the Windows service handler stops itself (the helper restarts it). SelfRestart() // WireGuard mesh client (DESIGN-WINDOWS.md §5). ApplyWireGuard persists and // brings up a peer tunnel; RemoveWireGuard tears it down; WireGuardState // reports whether the tunnel is up; ConnectWireGuard/DisconnectWireGuard // drive the tunnel from the persisted config (auto-VPN). ApplyWireGuard(conf string) error RemoveWireGuard() error WireGuardState() (active bool) ConnectWireGuard() error DisconnectWireGuard() error // ApplyIAM applies a verified node identity payload (DESIGN.md §6). ApplyIAM(payload IAMPayload) error } // defaultPlatformOps is the ops implementation the command dispatcher uses. // Pinned by runAgent after config load; tests override it directly. var defaultPlatformOps = NewPlatformOps(&Config{}, &SystemExecutor{})