d090f67bff
- Use Windows named pipe \.\pipe\studioe5-tailscaled instead of Unix socket - Apply hideWindow to all child processes (tailscale, podman, docker, browser) - Redirect agent logs to <data-dir>/agent.log and tailscaled logs to tailscaled.log - Fix double tailscale/ tailscale dir path in startTailscaleAndReport - Remove --operator=root on Windows - Bump agent version to 0.3.1
106 lines
2.6 KiB
Go
106 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"time"
|
|
)
|
|
|
|
// version is injected at build time via -ldflags "-X main.version=X.Y.Z"
|
|
var version = "dev"
|
|
|
|
const (
|
|
AGENT_VERSION = "0.3.0"
|
|
APP_NAME = "studioE5"
|
|
)
|
|
|
|
var (
|
|
dataDir = flag.String("data-dir", "./studioE5-data", "Répertoire de données")
|
|
uiEnabled = flag.Bool("ui", true, "Activer l'interface locale HTMX")
|
|
noTray = flag.Bool("no-tray", false, "Désactiver l'icône dans la barre système (mode console)")
|
|
)
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
dd := *dataDir
|
|
if !filepath.IsAbs(dd) {
|
|
ex, err := os.Executable()
|
|
if err == nil {
|
|
dd = filepath.Join(filepath.Dir(ex), dd)
|
|
} else {
|
|
wd, _ := os.Getwd()
|
|
dd = filepath.Join(wd, dd)
|
|
}
|
|
}
|
|
*dataDir = dd
|
|
|
|
if err := os.MkdirAll(*dataDir, 0755); err != nil {
|
|
log.Fatalf("Cannot create data-dir: %v", err)
|
|
}
|
|
|
|
// Redirect agent logs to a file so the console can be hidden on Windows.
|
|
agentLogPath := filepath.Join(*dataDir, "agent.log")
|
|
if agentLogFile, err := os.OpenFile(agentLogPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644); err == nil {
|
|
log.SetOutput(agentLogFile)
|
|
} else {
|
|
log.Printf("Cannot open agent log file %s: %v", agentLogPath, err)
|
|
}
|
|
|
|
cfg, _, err := loadOrCreateConfig(*dataDir)
|
|
if err != nil {
|
|
log.Fatalf("Cannot load config: %v", err)
|
|
}
|
|
|
|
if err := saveConfig(*dataDir, cfg); err != nil {
|
|
log.Fatalf("Cannot save config: %v", err)
|
|
}
|
|
|
|
log.Printf("[%s Agent] version=%s node=%s data-dir=%s server=%s", APP_NAME, AGENT_VERSION, cfg.NodeID, *dataDir, cfg.Server)
|
|
|
|
if *uiEnabled {
|
|
go startUI(*dataDir, cfg.NodeID, cfg.Server)
|
|
}
|
|
|
|
go startWebSocket(cfg.Server, cfg.NodeID, *dataDir, cfg.HeadscaleURL, cfg.HeadscaleAuthKey)
|
|
|
|
shutdownCh := make(chan struct{})
|
|
if *noTray {
|
|
log.Printf("[%s Agent] running in console mode (no tray)", APP_NAME)
|
|
<-shutdownCh
|
|
return
|
|
}
|
|
|
|
// Run tray on its own locked OS thread; keep main blocked so the process
|
|
// does not exit when systray is not available (e.g. headless Linux).
|
|
go func() {
|
|
runtime.LockOSThread()
|
|
defer runtime.UnlockOSThread()
|
|
runTray(APP_NAME, shutdownCh)
|
|
}()
|
|
|
|
<-shutdownCh
|
|
}
|
|
|
|
func startTailscaleAndReport(dataDir, nodeID, headscaleURL, authKey string) {
|
|
ip, err := startTailscale(dataDir, nodeID, headscaleURL, authKey)
|
|
if err != nil {
|
|
log.Printf("Tailscale error: %v", err)
|
|
return
|
|
}
|
|
log.Printf("Tailscale IP obtained: %s", ip)
|
|
|
|
for {
|
|
if err := sendMessage(WSMessage{Action: "tailscale_ip", NodeID: nodeID, TailscaleIP: ip}); err != nil {
|
|
log.Printf("Waiting for WebSocket to send tailscale_ip...")
|
|
time.Sleep(1 * time.Second)
|
|
continue
|
|
}
|
|
log.Printf("Sent tailscale_ip to server: %s", ip)
|
|
break
|
|
}
|
|
}
|