Files
mfd-monitor-agent/internal/service/service_linux.go
codex de3fd88948 ✨ feat(agent): 添加 token 鉴权和流程文档
* 默认监听调整为 0.0.0.0:8080,并要求查询参数 token
* 支持首次 run 自动生成含随机 token 的配置文件
* 补充 HTTP 鉴权、配置校验和相关测试
* 完善代码注释,覆盖缓存、上报、服务和平台采集路径
* 新增架构与开发流程文档,补充一键构建脚本
2026-05-22 06:46:21 +00:00

88 lines
2.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//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()
}