fix(installer): Theta Directory branding, visible URL/join-key fields, GUI tray, service autostart
User-reported install fixes: - Branding: every user-facing 'SSO Manager' string now says 'Theta Directory' (agent logs, CLI usage, agent.yml.example, installer wizard). - Wizard page: the URL/join-key text boxes were never shown. The layout used Surface.Width (0 at wizard init) instead of SurfaceWidth and combined WordWrap with AutoSize (mutually exclusive in VCL). Rewritten with the canonical Inno pattern (SurfaceWidth + ScaleY + explicit label height). - No console window after install: the tray and helper now build as GUI-subsystem binaries (-H=windowsgui) in build_all.sh and scripts/setup-build-env.ps1. The agent stays a console app for foreground debugging (as a service it never shows a console). - The daemon never came up after install: install-service now starts the service immediately, so the tray IPC socket exists right away and the tray connects instead of logging 'actively refused' until a reboot. Verified: go build/vet/test green; tray+helper PE subsystem = GUI (2), agent = console (3); installer compiles; tray runs silently.
This commit is contained in:
+12
-12
@@ -26,7 +26,7 @@ public_key: ""
|
|||||||
|
|
||||||
location: "default" # Location identifier (e.g., site, datacenter) for naming
|
location: "default" # Location identifier (e.g., site, datacenter) for naming
|
||||||
|
|
||||||
# Local LDAP byte-pump socket (DESIGN.md §4). The agent forwards raw LDAP bytes
|
# Local LDAP byte-pump socket (DESIGN.md ??4). The agent forwards raw LDAP bytes
|
||||||
# from this socket to the SSO, which relays them into its OpenLDAP. The agent
|
# from this socket to the SSO, which relays them into its OpenLDAP. The agent
|
||||||
# never parses LDAP. Point SSSD at it with:
|
# never parses LDAP. Point SSSD at it with:
|
||||||
# ldap_uri = ldapi://%2frun%2ftheta%2fldap.sock
|
# ldap_uri = ldapi://%2frun%2ftheta%2fldap.sock
|
||||||
@@ -37,12 +37,12 @@ ldap_socket: "/run/theta/ldap.sock"
|
|||||||
# directory WebSocket is up. The tray checkbox persists here too.
|
# directory WebSocket is up. The tray checkbox persists here too.
|
||||||
auto_vpn: false
|
auto_vpn: false
|
||||||
|
|
||||||
# Windows-specific (DESIGN-WINDOWS.md §11). Ignored on Linux.
|
# Windows-specific (DESIGN-WINDOWS.md ??11). Ignored on Linux.
|
||||||
service_name: "theta-agent" # Windows service name
|
service_name: "theta-agent" # Windows service name
|
||||||
desktop_helper: "" # theta-agent-helper.exe path (session-0 ops)
|
desktop_helper: "" # theta-agent-helper.exe path (session-0 ops)
|
||||||
public_ip_detect: true # false = air-gap: never call external IP services
|
public_ip_detect: true # false = air-gap: never call external IP services
|
||||||
|
|
||||||
# WireGuard mesh client (DESIGN-WINDOWS.md §5). The signed wireguard_apply
|
# WireGuard mesh client (DESIGN-WINDOWS.md ??5). The signed wireguard_apply
|
||||||
# command pushes the peer config down the WSS channel; these are local paths.
|
# command pushes the peer config down the WSS channel; these are local paths.
|
||||||
wireguard:
|
wireguard:
|
||||||
tunnel_name: "theta-mesh"
|
tunnel_name: "theta-mesh"
|
||||||
@@ -54,25 +54,25 @@ capabilities:
|
|||||||
# Basic Capabilities (Safe, read-only or infrastructure management)
|
# Basic Capabilities (Safe, read-only or infrastructure management)
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
# Push CPU, RAM, GPU, and ZFS metrics to the SSO Manager
|
# Push CPU, RAM, GPU, and ZFS metrics to Theta Directory
|
||||||
telemetry: true
|
telemetry: true
|
||||||
|
|
||||||
# Allow the SSO Manager to push down SSSD and SSH keys configuration
|
# Allow Theta Directory to push down SSSD and SSH keys configuration
|
||||||
configure_ldap: true
|
configure_ldap: true
|
||||||
|
|
||||||
# Serve the local LDAP byte-pump socket for SSSD/PAM (DESIGN.md §4)
|
# Serve the local LDAP byte-pump socket for SSSD/PAM (DESIGN.md ??4)
|
||||||
ldap_tunnel: true
|
ldap_tunnel: true
|
||||||
|
|
||||||
# Render OpenBao secrets to local files from /etc/theta/templates (DESIGN.md §5)
|
# Render OpenBao secrets to local files from /etc/theta/templates (DESIGN.md ??5)
|
||||||
secrets: true
|
secrets: true
|
||||||
|
|
||||||
# Apply node IAM (sudo rules, SSH keys, access control, revocation) (DESIGN.md §6)
|
# Apply node IAM (sudo rules, SSH keys, access control, revocation) (DESIGN.md ??6)
|
||||||
iam: true
|
iam: true
|
||||||
|
|
||||||
# Accept signed wireguard_apply/wireguard_remove commands (DESIGN-WINDOWS.md §5)
|
# Accept signed wireguard_apply/wireguard_remove commands (DESIGN-WINDOWS.md ??5)
|
||||||
wireguard: false
|
wireguard: false
|
||||||
|
|
||||||
# Secret templates to render (DESIGN.md §5). Each maps a local template to a
|
# Secret templates to render (DESIGN.md ??5). Each maps a local template to a
|
||||||
# target file and an optional post-render reload. The template embeds secrets as
|
# target file and an optional post-render reload. The template embeds secrets as
|
||||||
# {{ bao "secret/data/nodes/<node-id>/<name>#<key>" }}.
|
# {{ bao "secret/data/nodes/<node-id>/<name>#<key>" }}.
|
||||||
# secrets:
|
# secrets:
|
||||||
@@ -84,7 +84,7 @@ capabilities:
|
|||||||
# Advanced Capabilities (High risk, remote operations)
|
# Advanced Capabilities (High risk, remote operations)
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
# Allow remote system reboots via the SSO Manager
|
# Allow remote system reboots via Theta Directory
|
||||||
reboot: false
|
reboot: false
|
||||||
|
|
||||||
# Allow restarting, starting, or stopping specific systemd services.
|
# Allow restarting, starting, or stopping specific systemd services.
|
||||||
@@ -93,6 +93,6 @@ capabilities:
|
|||||||
# Setting to true or [] denies all.
|
# Setting to true or [] denies all.
|
||||||
service_control: []
|
service_control: []
|
||||||
|
|
||||||
# CRITICAL: Allow the execution of raw bash scripts sent from the SSO Manager.
|
# CRITICAL: Allow the execution of raw bash scripts sent from Theta Directory.
|
||||||
# Useful for GitOps deployments, but allows remote code execution.
|
# Useful for GitOps deployments, but allows remote code execution.
|
||||||
arbitrary_bash: false
|
arbitrary_bash: false
|
||||||
|
|||||||
+9
-4
@@ -7,6 +7,11 @@ DIST_DIR="./dist"
|
|||||||
mkdir -p "$DIST_DIR"
|
mkdir -p "$DIST_DIR"
|
||||||
|
|
||||||
LDFLAGS="-s -w"
|
LDFLAGS="-s -w"
|
||||||
|
# Windows GUI binaries (tray, helper) build as GUI-subsystem so no console
|
||||||
|
# window pops up when the installer starts the tray or the service spawns the
|
||||||
|
# helper. The agent stays a console app (handy for foreground debugging; as a
|
||||||
|
# Windows service it never shows a console anyway).
|
||||||
|
GUI_LDFLAGS="$LDFLAGS -H=windowsgui"
|
||||||
|
|
||||||
echo "Building Theta Agent binaries..."
|
echo "Building Theta Agent binaries..."
|
||||||
|
|
||||||
@@ -26,10 +31,10 @@ echo " -> windows/arm64..."
|
|||||||
CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -ldflags="$LDFLAGS" -o "$DIST_DIR/theta-agent-windows-arm64.exe"
|
CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -ldflags="$LDFLAGS" -o "$DIST_DIR/theta-agent-windows-arm64.exe"
|
||||||
|
|
||||||
echo " -> windows/amd64 helper..."
|
echo " -> windows/amd64 helper..."
|
||||||
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="$LDFLAGS" -o "$DIST_DIR/theta-agent-helper-windows-amd64.exe" ./cmd/theta-agent-helper/
|
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="$GUI_LDFLAGS" -o "$DIST_DIR/theta-agent-helper-windows-amd64.exe" ./cmd/theta-agent-helper/
|
||||||
|
|
||||||
echo " -> windows/arm64 helper..."
|
echo " -> windows/arm64 helper..."
|
||||||
CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -ldflags="$LDFLAGS" -o "$DIST_DIR/theta-agent-helper-windows-arm64.exe" ./cmd/theta-agent-helper/
|
CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -ldflags="$GUI_LDFLAGS" -o "$DIST_DIR/theta-agent-helper-windows-arm64.exe" ./cmd/theta-agent-helper/
|
||||||
|
|
||||||
echo " -> darwin/amd64 (macOS Intel)..."
|
echo " -> darwin/amd64 (macOS Intel)..."
|
||||||
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags="$LDFLAGS" -o "$DIST_DIR/theta-agent-darwin-amd64"
|
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags="$LDFLAGS" -o "$DIST_DIR/theta-agent-darwin-amd64"
|
||||||
@@ -45,10 +50,10 @@ echo " -> linux/arm64 tray..."
|
|||||||
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="$LDFLAGS" -o "$DIST_DIR/theta-agent-tray-linux-arm64" ./cmd/theta-agent-tray/
|
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="$LDFLAGS" -o "$DIST_DIR/theta-agent-tray-linux-arm64" ./cmd/theta-agent-tray/
|
||||||
|
|
||||||
echo " -> windows/amd64 tray..."
|
echo " -> windows/amd64 tray..."
|
||||||
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="$LDFLAGS" -o "$DIST_DIR/theta-agent-tray-windows-amd64.exe" ./cmd/theta-agent-tray/
|
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="$GUI_LDFLAGS" -o "$DIST_DIR/theta-agent-tray-windows-amd64.exe" ./cmd/theta-agent-tray/
|
||||||
|
|
||||||
echo " -> windows/arm64 tray..."
|
echo " -> windows/arm64 tray..."
|
||||||
CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -ldflags="$LDFLAGS" -o "$DIST_DIR/theta-agent-tray-windows-arm64.exe" ./cmd/theta-agent-tray/
|
CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -ldflags="$GUI_LDFLAGS" -o "$DIST_DIR/theta-agent-tray-windows-arm64.exe" ./cmd/theta-agent-tray/
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Build complete! Artifacts in $DIST_DIR:"
|
echo "Build complete! Artifacts in $DIST_DIR:"
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ func printUsage() {
|
|||||||
fmt.Println(" theta-agent Run agent daemon in foreground")
|
fmt.Println(" theta-agent Run agent daemon in foreground")
|
||||||
fmt.Println(" theta-agent get-secret <key> Fetch single secret value from OpenBao")
|
fmt.Println(" theta-agent get-secret <key> Fetch single secret value from OpenBao")
|
||||||
fmt.Println(" theta-agent get-secrets [flags] Fetch all host/resource secrets (flags: --json, --env)")
|
fmt.Println(" theta-agent get-secrets [flags] Fetch all host/resource secrets (flags: --json, --env)")
|
||||||
fmt.Println(" theta-agent update Self-update binary from SSO Manager")
|
fmt.Println(" theta-agent update Self-update binary from Theta Directory")
|
||||||
fmt.Println(" theta-agent reinitialize [flags] Reset enrollment credentials & re-register")
|
fmt.Println(" theta-agent reinitialize [flags] Reset enrollment credentials & re-register")
|
||||||
fmt.Println(" theta-agent install-service (Windows) register the agent as a service")
|
fmt.Println(" theta-agent install-service (Windows) register the agent as a service")
|
||||||
fmt.Println(" theta-agent remove-service (Windows) unregister the agent service")
|
fmt.Println(" theta-agent remove-service (Windows) unregister the agent service")
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
; theta-agent-2.1.0-windows-amd64-setup.exe /SILENT ^
|
; theta-agent-2.1.0-windows-amd64-setup.exe /SILENT ^
|
||||||
; /SERVER_URL=https://sso.example.com /JOIN_KEY=tjk_...
|
; /SERVER_URL=https://sso.example.com /JOIN_KEY=tjk_...
|
||||||
;
|
;
|
||||||
; Interactively, a wizard page asks for the SSO Manager URL and a join key (with
|
; Interactively, a wizard page asks for the Theta Directory URL and a join key
|
||||||
; a button that opens the SSO's Directory -> Install Agent page to mint one).
|
; (with a button that opens the Theta Directory's Directory -> Install Agent page
|
||||||
; In silent mode, /SERVER_URL, /JOIN_KEY, /AUTH_TOKEN, /PUBLIC_KEY and
|
; to mint one). In silent mode, /SERVER_URL, /JOIN_KEY, /AUTH_TOKEN, /PUBLIC_KEY
|
||||||
; /B64_CONFIG (base64 of a full agent.yml) drive the same result. The values are
|
; and /B64_CONFIG (base64 of a full agent.yml) drive the same result. The values
|
||||||
; written into agent.yml so the installed service enrolls on first start.
|
; are written into agent.yml so the installed service enrolls on first start.
|
||||||
|
|
||||||
#ifndef MyAppVersion
|
#ifndef MyAppVersion
|
||||||
#define MyAppVersion "2.1.0"
|
#define MyAppVersion "2.1.0"
|
||||||
@@ -128,8 +128,8 @@ begin
|
|||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Opens the SSO's Directory page so the operator can mint a join key right from
|
// Opens the Theta Directory page so the operator can mint a join key right
|
||||||
// the wizard. Uses the Server URL they just typed.
|
// from the wizard. Uses the Server URL they just typed.
|
||||||
procedure OnOpenSSOClick(Sender: TObject);
|
procedure OnOpenSSOClick(Sender: TObject);
|
||||||
var
|
var
|
||||||
Url: String;
|
Url: String;
|
||||||
@@ -137,7 +137,7 @@ var
|
|||||||
begin
|
begin
|
||||||
Url := Trim(ServerURLEdit.Text);
|
Url := Trim(ServerURLEdit.Text);
|
||||||
if Url = '' then begin
|
if Url = '' then begin
|
||||||
MsgBox('Enter the SSO Manager URL first (e.g. https://sso.example.com).',
|
MsgBox('Enter the Theta Directory URL first (e.g. https://directory.example.com).',
|
||||||
mbInformation, MB_OK);
|
mbInformation, MB_OK);
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
@@ -150,48 +150,54 @@ var
|
|||||||
InfoLabel: TNewStaticText;
|
InfoLabel: TNewStaticText;
|
||||||
UrlLabel: TNewStaticText;
|
UrlLabel: TNewStaticText;
|
||||||
KeyLabel: TNewStaticText;
|
KeyLabel: TNewStaticText;
|
||||||
|
Y: Integer;
|
||||||
begin
|
begin
|
||||||
AgentConfigPage := CreateCustomPage(wpWelcome,
|
AgentConfigPage := CreateCustomPage(wpWelcome,
|
||||||
'SSO Manager connection',
|
'Theta Directory connection',
|
||||||
'Tell the agent which SSO to enroll with.');
|
'Tell the agent which Theta Directory to enroll with.');
|
||||||
|
|
||||||
InfoLabel := TNewStaticText.Create(AgentConfigPage);
|
InfoLabel := TNewStaticText.Create(AgentConfigPage);
|
||||||
InfoLabel.Parent := AgentConfigPage.Surface;
|
InfoLabel.Parent := AgentConfigPage.Surface;
|
||||||
InfoLabel.WordWrap := True;
|
InfoLabel.WordWrap := True;
|
||||||
InfoLabel.Caption := 'Paste the SSO Manager URL for this deployment. Then either paste a join key '
|
InfoLabel.Caption := 'Paste the Theta Directory URL for this deployment. Then either paste a join key '
|
||||||
+ '(mint one with the button below, under Directory -> Install Agent) or leave it blank to '
|
+ '(mint one with the button below, under Directory -> Install Agent) or leave it blank to '
|
||||||
+ 'enroll from the tray / CLI later.';
|
+ 'enroll from the tray / CLI later.';
|
||||||
InfoLabel.AutoSize := True;
|
// WordWrap + AutoSize are mutually exclusive in VCL; give the wrapped label a
|
||||||
InfoLabel.Width := AgentConfigPage.Surface.Width;
|
// fixed height so the fields below it land on screen.
|
||||||
|
InfoLabel.Width := AgentConfigPage.SurfaceWidth;
|
||||||
|
InfoLabel.Height := ScaleY(48);
|
||||||
|
|
||||||
|
Y := InfoLabel.Top + InfoLabel.Height + ScaleY(12);
|
||||||
|
|
||||||
UrlLabel := TNewStaticText.Create(AgentConfigPage);
|
UrlLabel := TNewStaticText.Create(AgentConfigPage);
|
||||||
UrlLabel.Parent := AgentConfigPage.Surface;
|
UrlLabel.Parent := AgentConfigPage.Surface;
|
||||||
UrlLabel.Caption := 'SSO Manager URL:';
|
UrlLabel.Caption := 'Theta Directory URL:';
|
||||||
UrlLabel.Top := InfoLabel.Top + InfoLabel.Height + 16;
|
UrlLabel.Top := Y;
|
||||||
|
|
||||||
ServerURLEdit := TNewEdit.Create(AgentConfigPage);
|
ServerURLEdit := TNewEdit.Create(AgentConfigPage);
|
||||||
ServerURLEdit.Parent := AgentConfigPage.Surface;
|
ServerURLEdit.Parent := AgentConfigPage.Surface;
|
||||||
ServerURLEdit.Top := UrlLabel.Top + UrlLabel.Height + 4;
|
ServerURLEdit.Top := UrlLabel.Top + UrlLabel.Height + ScaleY(4);
|
||||||
ServerURLEdit.Width := AgentConfigPage.Surface.Width;
|
ServerURLEdit.Width := AgentConfigPage.SurfaceWidth;
|
||||||
ServerURLEdit.Text := ServerURL;
|
ServerURLEdit.Text := ServerURL;
|
||||||
|
|
||||||
OpenSSOButton := TNewButton.Create(AgentConfigPage);
|
OpenSSOButton := TNewButton.Create(AgentConfigPage);
|
||||||
OpenSSOButton.Parent := AgentConfigPage.Surface;
|
OpenSSOButton.Parent := AgentConfigPage.Surface;
|
||||||
OpenSSOButton.Top := ServerURLEdit.Top + ServerURLEdit.Height + 8;
|
OpenSSOButton.Top := ServerURLEdit.Top + ServerURLEdit.Height + ScaleY(10);
|
||||||
OpenSSOButton.Left := ServerURLEdit.Left;
|
OpenSSOButton.Left := ServerURLEdit.Left;
|
||||||
OpenSSOButton.Caption := 'Open SSO install-agent page...';
|
OpenSSOButton.Caption := 'Open Theta Directory install-agent page...';
|
||||||
OpenSSOButton.Width := 190;
|
OpenSSOButton.Width := WizardForm.CalculateButtonWidth([OpenSSOButton.Caption]);
|
||||||
|
OpenSSOButton.Height := ScaleY(23);
|
||||||
OpenSSOButton.OnClick := @OnOpenSSOClick;
|
OpenSSOButton.OnClick := @OnOpenSSOClick;
|
||||||
|
|
||||||
KeyLabel := TNewStaticText.Create(AgentConfigPage);
|
KeyLabel := TNewStaticText.Create(AgentConfigPage);
|
||||||
KeyLabel.Parent := AgentConfigPage.Surface;
|
KeyLabel.Parent := AgentConfigPage.Surface;
|
||||||
KeyLabel.Caption := 'Join key (optional):';
|
KeyLabel.Caption := 'Join key (optional):';
|
||||||
KeyLabel.Top := OpenSSOButton.Top + OpenSSOButton.Height + 12;
|
KeyLabel.Top := OpenSSOButton.Top + OpenSSOButton.Height + ScaleY(12);
|
||||||
|
|
||||||
JoinKeyEdit := TNewEdit.Create(AgentConfigPage);
|
JoinKeyEdit := TNewEdit.Create(AgentConfigPage);
|
||||||
JoinKeyEdit.Parent := AgentConfigPage.Surface;
|
JoinKeyEdit.Parent := AgentConfigPage.Surface;
|
||||||
JoinKeyEdit.Top := KeyLabel.Top + KeyLabel.Height + 4;
|
JoinKeyEdit.Top := KeyLabel.Top + KeyLabel.Height + ScaleY(4);
|
||||||
JoinKeyEdit.Width := AgentConfigPage.Surface.Width;
|
JoinKeyEdit.Width := AgentConfigPage.SurfaceWidth;
|
||||||
JoinKeyEdit.Text := JoinKey;
|
JoinKeyEdit.Text := JoinKey;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ func runAgent() {
|
|||||||
}
|
}
|
||||||
cfg := cm.Get()
|
cfg := cm.Get()
|
||||||
|
|
||||||
log.Printf("Connecting to SSO Manager at %s", cfg.ServerURL)
|
log.Printf("Connecting to Theta Directory at %s", cfg.ServerURL)
|
||||||
log.Printf("Loaded capabilities: Telemetry=%v, LDAP=%v, Reboot=%v, Bash=%v",
|
log.Printf("Loaded capabilities: Telemetry=%v, LDAP=%v, Reboot=%v, Bash=%v",
|
||||||
cfg.Capabilities.Telemetry,
|
cfg.Capabilities.Telemetry,
|
||||||
cfg.Capabilities.ConfigureLDAP,
|
cfg.Capabilities.ConfigureLDAP,
|
||||||
@@ -83,7 +83,7 @@ func runAgent() {
|
|||||||
// Tray IPC server — desktop tray connects here for status updates.
|
// Tray IPC server — desktop tray connects here for status updates.
|
||||||
go globalTrayServer.Start()
|
go globalTrayServer.Start()
|
||||||
|
|
||||||
// WebSocket connection to SSO Manager
|
// WebSocket connection to Theta Directory
|
||||||
go connectWebSocket(cm, exec)
|
go connectWebSocket(cm, exec)
|
||||||
|
|
||||||
// Home detection + tray status push (polls public IP every 60s).
|
// Home detection + tray status push (polls public IP every 60s).
|
||||||
|
|||||||
@@ -251,13 +251,16 @@ function Invoke-Build {
|
|||||||
$dist = Join-Path $RepoRoot 'dist'
|
$dist = Join-Path $RepoRoot 'dist'
|
||||||
New-Item -ItemType Directory -Force -Path $dist | Out-Null
|
New-Item -ItemType Directory -Force -Path $dist | Out-Null
|
||||||
$flags = '-s -w'
|
$flags = '-s -w'
|
||||||
|
# The tray and helper are GUI-subsystem binaries: no console window pops up
|
||||||
|
# when the installer starts the tray or the service spawns the helper.
|
||||||
|
$guiFlags = '-s -w -H=windowsgui'
|
||||||
foreach ($arch in @('amd64','arm64')) {
|
foreach ($arch in @('amd64','arm64')) {
|
||||||
$env:GOOS='windows'; $env:GOARCH=$arch; $env:CGO_ENABLED='0'
|
$env:GOOS='windows'; $env:GOARCH=$arch; $env:CGO_ENABLED='0'
|
||||||
go build "-ldflags=$flags" -o (Join-Path $dist "theta-agent-windows-$arch.exe") $RepoRoot
|
go build "-ldflags=$flags" -o (Join-Path $dist "theta-agent-windows-$arch.exe") $RepoRoot
|
||||||
if ($LASTEXITCODE -ne 0) { Write-Fail "build agent windows/$arch failed"; return }
|
if ($LASTEXITCODE -ne 0) { Write-Fail "build agent windows/$arch failed"; return }
|
||||||
go build "-ldflags=$flags" -o (Join-Path $dist "theta-agent-tray-windows-$arch.exe") (Join-Path $RepoRoot 'cmd\theta-agent-tray')
|
go build "-ldflags=$guiFlags" -o (Join-Path $dist "theta-agent-tray-windows-$arch.exe") (Join-Path $RepoRoot 'cmd\theta-agent-tray')
|
||||||
if ($LASTEXITCODE -ne 0) { Write-Fail "build tray windows/$arch failed"; return }
|
if ($LASTEXITCODE -ne 0) { Write-Fail "build tray windows/$arch failed"; return }
|
||||||
go build "-ldflags=$flags" -o (Join-Path $dist "theta-agent-helper-windows-$arch.exe") (Join-Path $RepoRoot 'cmd\theta-agent-helper')
|
go build "-ldflags=$guiFlags" -o (Join-Path $dist "theta-agent-helper-windows-$arch.exe") (Join-Path $RepoRoot 'cmd\theta-agent-helper')
|
||||||
if ($LASTEXITCODE -ne 0) { Write-Fail "build helper windows/$arch failed"; return }
|
if ($LASTEXITCODE -ne 0) { Write-Fail "build helper windows/$arch failed"; return }
|
||||||
}
|
}
|
||||||
Remove-Item Env:GOOS,Env:GOARCH,Env:CGO_ENABLED -ErrorAction SilentlyContinue
|
Remove-Item Env:GOOS,Env:GOARCH,Env:CGO_ENABLED -ErrorAction SilentlyContinue
|
||||||
|
|||||||
@@ -59,7 +59,13 @@ func installService() {
|
|||||||
logFatal("cannot create service: %v", err)
|
logFatal("cannot create service: %v", err)
|
||||||
}
|
}
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
fmt.Printf("[+] Registered theta-agent service (%s)\n", filepath.Base(exe))
|
|
||||||
|
// Start it immediately so the daemon binds the tray IPC socket and the
|
||||||
|
// credential provider is live without waiting for a reboot.
|
||||||
|
if err := s.Start(); err != nil {
|
||||||
|
logFatal("cannot start service: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("[+] Registered and started theta-agent service (%s)\n", filepath.Base(exe))
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeService() {
|
func removeService() {
|
||||||
|
|||||||
+1
-1
@@ -663,6 +663,6 @@ func pushDiscovery(c MessageWriter, cfg *Config) {
|
|||||||
if err := c.WriteMessage(websocket.TextMessage, payload); err != nil {
|
if err := c.WriteMessage(websocket.TextMessage, payload); err != nil {
|
||||||
log.Printf("Failed to send discovery data: %v", err)
|
log.Printf("Failed to send discovery data: %v", err)
|
||||||
} else {
|
} else {
|
||||||
log.Println("Discovery data pushed to SSO Manager.")
|
log.Println("Discovery data pushed to Theta Directory.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -146,7 +146,7 @@ func connectWebSocket(cm *ConfigManager, exec Executor) {
|
|||||||
// credential every 5s just floods the SSO and its audit log
|
// credential every 5s just floods the SSO and its audit log
|
||||||
// forever, so back off hard and say plainly what is wrong.
|
// forever, so back off hard and say plainly what is wrong.
|
||||||
if resp != nil && (resp.StatusCode == http.StatusUnauthorized || resp.StatusCode == http.StatusForbidden) {
|
if resp != nil && (resp.StatusCode == http.StatusUnauthorized || resp.StatusCode == http.StatusForbidden) {
|
||||||
log.Printf("Server rejected our token (HTTP %d). Enroll this agent in the SSO Directory and put the issued token in agent.yml. Retrying in %s.", resp.StatusCode, authRetryInterval)
|
log.Printf("Server rejected our token (HTTP %d). Enroll this agent in the Theta Directory and put the issued token in agent.yml. Retrying in %s.", resp.StatusCode, authRetryInterval)
|
||||||
time.Sleep(authRetryInterval)
|
time.Sleep(authRetryInterval)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -155,7 +155,7 @@ func connectWebSocket(cm *ConfigManager, exec Executor) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Successfully connected to SSO Manager.")
|
log.Println("Successfully connected to Theta Directory.")
|
||||||
wsConnected.Store(true)
|
wsConnected.Store(true)
|
||||||
|
|
||||||
stopCh := make(chan struct{})
|
stopCh := make(chan struct{})
|
||||||
@@ -213,7 +213,7 @@ func connectWebSocket(cm *ConfigManager, exec Executor) {
|
|||||||
// than at Dial.
|
// than at Dial.
|
||||||
if websocket.IsCloseError(err, closeUnauthorized, closeRevoked, closeTokenRotated) {
|
if websocket.IsCloseError(err, closeUnauthorized, closeRevoked, closeTokenRotated) {
|
||||||
authRejected = true
|
authRejected = true
|
||||||
log.Printf("Server closed the connection: %v. This agent's token is not valid for that SSO — re-enroll it and update agent.yml.", err)
|
log.Printf("Server closed the connection: %v. This agent's token is not valid for that Theta Directory — re-enroll it and update agent.yml.", err)
|
||||||
} else {
|
} else {
|
||||||
log.Println("WebSocket read error:", err)
|
log.Println("WebSocket read error:", err)
|
||||||
}
|
}
|
||||||
@@ -345,7 +345,7 @@ func handleCommand(cm *ConfigManager, msg WSMessage, c MessageWriter, exec Execu
|
|||||||
log.Printf("Enrolled, but could not persist credentials: %v", err)
|
log.Printf("Enrolled, but could not persist credentials: %v", err)
|
||||||
log.Printf("This agent will re-enroll on every reconnect until %s is writable.", cm.configPath)
|
log.Printf("This agent will re-enroll on every reconnect until %s is writable.", cm.configPath)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Enrolled with the SSO. Credentials written to %s; the join key is no longer needed.", cm.configPath)
|
log.Printf("Enrolled with Theta Directory. Credentials written to %s; the join key is no longer needed.", cm.configPath)
|
||||||
}
|
}
|
||||||
sendResponse("ok", "enrollment stored")
|
sendResponse("ok", "enrollment stored")
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user