//go:build linux package service import ( "fmt" "os" "os/exec" "path/filepath" ) func newPlatformManager(configDir string) (platformManager, error) { return &linuxServiceManager{configDir: configDir}, nil } // linuxServiceManager manages services via systemd. Direct port of // LinuxServiceManager in service_manager.py. type linuxServiceManager struct { configDir string } func (l *linuxServiceManager) serviceFilePath(name string) string { return filepath.Join("/etc/systemd/system", name+".service") } func (l *linuxServiceManager) createServiceFile(cfg Config) error { execStart := cfg.ExecutablePath if cfg.Args != "" { execStart += " " + cfg.Args } description := cfg.Description if description == "" { description = cfg.Name } content := fmt.Sprintf(`[Unit] Description=%s After=network.target [Service] Type=simple ExecStart=%s Restart=always RestartSec=10 User=root [Install] WantedBy=multi-user.target `, description, execStart) servicePath := l.serviceFilePath(cfg.Name) if err := os.WriteFile(servicePath, []byte(content), 0o644); err != nil { return fmt.Errorf("failed to create service file: %w", err) } return nil } func (l *linuxServiceManager) Install(cfg Config) error { if err := l.createServiceFile(cfg); err != nil { return err } if out, err := exec.Command("systemctl", "daemon-reload").CombinedOutput(); err != nil { return fmt.Errorf("failed to install service: %s", out) } if out, err := exec.Command("systemctl", "enable", cfg.Name).CombinedOutput(); err != nil { return fmt.Errorf("failed to install service: %s", out) } if out, err := exec.Command("systemctl", "start", cfg.Name).CombinedOutput(); err != nil { return fmt.Errorf("failed to install service: %s", out) } return nil } func (l *linuxServiceManager) Uninstall(name string) error { exec.Command("systemctl", "stop", name).Run() if out, err := exec.Command("systemctl", "disable", name).CombinedOutput(); err != nil { return fmt.Errorf("failed to uninstall service: %s", out) } servicePath := l.serviceFilePath(name) if _, err := os.Stat(servicePath); err == nil { os.Remove(servicePath) } if out, err := exec.Command("systemctl", "daemon-reload").CombinedOutput(); err != nil { return fmt.Errorf("failed to uninstall service: %s", out) } return nil } func (l *linuxServiceManager) Start(name string) error { if out, err := exec.Command("systemctl", "start", name).CombinedOutput(); err != nil { return fmt.Errorf("failed to start service: %s", out) } return nil } func (l *linuxServiceManager) Stop(name string) error { if out, err := exec.Command("systemctl", "stop", name).CombinedOutput(); err != nil { return fmt.Errorf("failed to stop service: %s", out) } return nil } func (l *linuxServiceManager) Restart(name string) error { if out, err := exec.Command("systemctl", "restart", name).CombinedOutput(); err != nil { return fmt.Errorf("failed to restart service: %s", out) } return nil }