first commit
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
//go:build linux
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const systemdUnitTemplate = `[Unit]
|
||||
Description=USB Client (%s mode)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=%s %s --config %s
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
User=root
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
`
|
||||
|
||||
const serviceName = "usb-client"
|
||||
|
||||
// Install creates and enables a systemd service
|
||||
func Install(mode, configPath string) error {
|
||||
// Find the executable
|
||||
exePath, err := os.Executable()
|
||||
if err != nil {
|
||||
return fmt.Errorf("finding executable: %w", err)
|
||||
}
|
||||
exePath, err = filepath.Abs(exePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving path: %w", err)
|
||||
}
|
||||
|
||||
absConfigPath, err := filepath.Abs(configPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving config path: %w", err)
|
||||
}
|
||||
|
||||
unitContent := fmt.Sprintf(systemdUnitTemplate, mode, exePath, mode, absConfigPath)
|
||||
unitPath := fmt.Sprintf("/etc/systemd/system/%s.service", serviceName)
|
||||
|
||||
if err := os.WriteFile(unitPath, []byte(unitContent), 0644); err != nil {
|
||||
return fmt.Errorf("writing unit file: %w (need root?)", err)
|
||||
}
|
||||
|
||||
// Reload systemd
|
||||
if err := exec.Command("systemctl", "daemon-reload").Run(); err != nil {
|
||||
return fmt.Errorf("daemon-reload: %w", err)
|
||||
}
|
||||
|
||||
// Enable and start
|
||||
if err := exec.Command("systemctl", "enable", serviceName).Run(); err != nil {
|
||||
return fmt.Errorf("enable: %w", err)
|
||||
}
|
||||
|
||||
if err := exec.Command("systemctl", "start", serviceName).Run(); err != nil {
|
||||
return fmt.Errorf("start: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Uninstall stops and removes the systemd service
|
||||
func Uninstall() error {
|
||||
// Stop and disable
|
||||
exec.Command("systemctl", "stop", serviceName).Run()
|
||||
exec.Command("systemctl", "disable", serviceName).Run()
|
||||
|
||||
// Remove unit file
|
||||
unitPath := fmt.Sprintf("/etc/systemd/system/%s.service", serviceName)
|
||||
os.Remove(unitPath)
|
||||
|
||||
// Reload
|
||||
exec.Command("systemctl", "daemon-reload").Run()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status returns the systemd service status
|
||||
func Status() (string, error) {
|
||||
out, err := exec.Command("systemctl", "status", serviceName).CombinedOutput()
|
||||
if err != nil {
|
||||
return string(out), nil // status returns non-zero for inactive services
|
||||
}
|
||||
return string(out), nil
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//go:build windows
|
||||
|
||||
package service
|
||||
|
||||
import "fmt"
|
||||
|
||||
func Install(mode, configPath string) error {
|
||||
return fmt.Errorf("Windows service installation not yet implemented")
|
||||
}
|
||||
|
||||
func Uninstall() error {
|
||||
return fmt.Errorf("Windows service uninstallation not yet implemented")
|
||||
}
|
||||
|
||||
func Status() (string, error) {
|
||||
return "not implemented on Windows", nil
|
||||
}
|
||||
Reference in New Issue
Block a user