* 实现周期采集、快照缓存、本地 HTTP API 和主动上报 * 补齐 Linux 和 Windows 主机、网络、资源、进程和 TCP 采集 * 添加服务生命周期管理、配置加载、构建脚本和测试覆盖 BREAKING CHANGE: network.ips 拆分为 network.ipv4s 和 network.ipv6s。
83 lines
2.4 KiB
Go
83 lines
2.4 KiB
Go
//go:build linux
|
|
|
|
package service
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"mfd-monitor-agent/internal/config"
|
|
)
|
|
|
|
var currentUID = os.Geteuid
|
|
|
|
// linuxManager manages a systemd service for the agent.
|
|
type linuxManager struct{}
|
|
|
|
// newManager returns the Linux systemd-backed service manager.
|
|
func newManager() Manager {
|
|
return linuxManager{}
|
|
}
|
|
|
|
// Install writes a systemd unit, reloads systemd, and enables the configured service.
|
|
func (linuxManager) Install(executable string, cfg config.Config, opts InstallOptions) error {
|
|
if currentUID() != 0 {
|
|
return fmt.Errorf("install requires root")
|
|
}
|
|
unit := renderSystemdUnit(executable, opts.ConfigPath, cfg)
|
|
path := "/etc/systemd/system/" + cfg.Service.Name + ".service"
|
|
if err := os.WriteFile(path, []byte(unit), 0644); err != nil {
|
|
return fmt.Errorf("write systemd unit: %w", err)
|
|
}
|
|
if err := exec.Command("systemctl", "daemon-reload").Run(); err != nil {
|
|
return fmt.Errorf("systemctl daemon-reload: %w", err)
|
|
}
|
|
if err := exec.Command("systemctl", "enable", cfg.Service.Name).Run(); err != nil {
|
|
return fmt.Errorf("systemctl enable: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// renderSystemdUnit builds the Linux systemd unit used by Install.
|
|
func renderSystemdUnit(executable string, configPath string, cfg config.Config) string {
|
|
args := []string{executable, "run"}
|
|
if configPath != "" {
|
|
args = append(args, "-config", configPath)
|
|
}
|
|
return fmt.Sprintf(`[Unit]
|
|
Description=%s
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=%s
|
|
Restart=always
|
|
RestartSec=5s
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
`, cfg.Service.Description, strings.Join(args, " "))
|
|
}
|
|
|
|
// Uninstall disables the service, removes its unit file, and reloads systemd.
|
|
func (linuxManager) Uninstall(cfg config.Config) error {
|
|
_ = exec.Command("systemctl", "disable", "--now", cfg.Service.Name).Run()
|
|
if err := os.Remove("/etc/systemd/system/" + cfg.Service.Name + ".service"); err != nil && !os.IsNotExist(err) {
|
|
return err
|
|
}
|
|
return exec.Command("systemctl", "daemon-reload").Run()
|
|
}
|
|
|
|
// Start asks systemd to start the configured service.
|
|
func (linuxManager) Start(cfg config.Config) error {
|
|
return exec.Command("systemctl", "start", cfg.Service.Name).Run()
|
|
}
|
|
|
|
// Stop asks systemd to stop the configured service.
|
|
func (linuxManager) Stop(cfg config.Config) error {
|
|
return exec.Command("systemctl", "stop", cfg.Service.Name).Run()
|
|
}
|