feat(windows): platform ops, service wrapper, helper, and air-gap paths
First Windows parity milestone (DESIGN-WINDOWS.md §13 build order item 1).
- Add a PlatformOps abstraction so command dispatch is OS-neutral:
- linuxPlatformOps keeps today's systemctl/journalctl/bash behavior (deliberately
untagged so shared dispatch tests run on Windows CI)
- windowsPlatformOps maps reboot/shutdown to shutdown.exe, service control to
sc.exe (stop+start for restart), fetch_logs to Get-WinEvent, arbitrary_bash to
powershell -EncodedCommand (byte-exact under arbitrary quoting), and declines
configure_ldap (Windows logon goes through OpenCredential)
- Run theta-agent as a Windows service (x/sys/windows/svc): SYSTEM auto-start,
SCM stop/shutdown handling; CLI install-service/remove-service via svc/mgr
- Add theta-agent-helper (session-0 companion): lock/display_off/logout via
user32/wtsapi32, and staged self-update (wait for service stop, swap the
locked exe, sc start)
- Self-update becomes platform-aware: Linux renames over the running binary;
Windows stages .new and hands the swap to the helper (running exe is locked)
- Platform paths: agent.yml and tray.sock under %ProgramData%\Theta42 (the
service runs as SYSTEM while the tray runs as the user, so the per-user temp
dir no longer works for tray IPC); LDAP byte-pump falls back to TCP loopback
- config: service_name, desktop_helper, public_ip_detect (air-gap: skips
external public-IP lookups in telemetry + home monitor), wireguard block
- cli: platform-aware config path + self-update artifact name + service restart
- tests: dispatch tests pin linuxPlatformOps; 0600 mode assertions gated to
POSIX so the suite is green on Windows
Rebuilds all tracked dist binaries (v2.1.0).
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
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()
|
||||
}
|
||||
|
||||
// defaultPlatformOps is the ops implementation the command dispatcher uses.
|
||||
// Pinned by runAgent after config load; tests override it directly.
|
||||
var defaultPlatformOps = NewPlatformOps(&Config{}, &SystemExecutor{})
|
||||
Reference in New Issue
Block a user