114 lines
2.9 KiB
Go
114 lines
2.9 KiB
Go
//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
|
|
}
|