* 默认监听调整为 0.0.0.0:8080,并要求查询参数 token * 支持首次 run 自动生成含随机 token 的配置文件 * 补充 HTTP 鉴权、配置校验和相关测试 * 完善代码注释,覆盖缓存、上报、服务和平台采集路径 * 新增架构与开发流程文档,补充一键构建脚本
88 lines
2.7 KiB
Go
88 lines
2.7 KiB
Go
//go:build linux
|
||
|
||
package service
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
"os/exec"
|
||
"strings"
|
||
|
||
"mfd-monitor-agent/internal/config"
|
||
)
|
||
|
||
// currentUID 是测试可替换的当前用户 ID 查询函数。
|
||
var currentUID = os.Geteuid
|
||
|
||
// linuxManager 通过 systemd 管理 agent 服务。
|
||
type linuxManager struct{}
|
||
|
||
// newManager 返回基于 Linux systemd 的服务管理器。
|
||
func newManager() Manager {
|
||
return linuxManager{}
|
||
}
|
||
|
||
// Install 写入 systemd unit、重载 systemd 并 enable 配置的服务。
|
||
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"
|
||
// 安装阶段写入 systemd unit,需要 root 权限且会影响系统服务注册。
|
||
if err := os.WriteFile(path, []byte(unit), 0644); err != nil {
|
||
return fmt.Errorf("write systemd unit: %w", err)
|
||
}
|
||
// unit 文件变化后必须重载 systemd,再启用服务随系统启动。
|
||
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 生成 Install 使用的 Linux systemd unit 内容。
|
||
func renderSystemdUnit(executable string, configPath string, cfg config.Config) string {
|
||
args := []string{executable, "run"}
|
||
if configPath != "" {
|
||
// install 接收的 -config 会固化到 ExecStart,保证服务模式读取同一配置。
|
||
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 禁用服务、删除 unit 文件并重载 systemd。
|
||
func (linuxManager) Uninstall(cfg config.Config) error {
|
||
// 服务可能已经停止或未启用,忽略 disable 错误以继续清理 unit 文件。
|
||
_ = 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 请求 systemd 启动配置的服务。
|
||
func (linuxManager) Start(cfg config.Config) error {
|
||
return exec.Command("systemctl", "start", cfg.Service.Name).Run()
|
||
}
|
||
|
||
// Stop 请求 systemd 停止配置的服务。
|
||
func (linuxManager) Stop(cfg config.Config) error {
|
||
return exec.Command("systemctl", "stop", cfg.Service.Name).Run()
|
||
}
|