package procctl import ( "bytes" "fmt" "io" "os/exec" "strconv" "strings" "time" ) // SystemCtlController 使用 systemctl 管理 Media Server type SystemCtlController struct { serviceName string } // NewSystemCtlController 创建 systemctl 控制器 func NewSystemCtlController(serviceName string) *SystemCtlController { return &SystemCtlController{ serviceName: serviceName, } } func (s *SystemCtlController) Enabled() bool { return s != nil } func (s *SystemCtlController) Status() (Status, error) { // 检查服务是否运行 cmd := exec.Command("systemctl", "is-active", "--quiet", s.serviceName) err := cmd.Run() if err != nil { // 服务未运行 return Status{Running: false}, nil } // 获取 PID pidCmd := exec.Command("systemctl", "show", "--property=MainPID", "--value", s.serviceName) out, err := pidCmd.Output() if err != nil { return Status{Running: true}, nil // 运行但无法获取 PID } pid, _ := strconv.Atoi(strings.TrimSpace(string(out))) if pid <= 0 { return Status{Running: true}, nil } return Status{ Running: true, Pid: pid, ConfigPath: "/opt/rk3588-media-server/etc/media-server.json", }, nil } func (s *SystemCtlController) Version() (string, error) { // 直接执行 media-server --version cmd := exec.Command("/opt/rk3588-media-server/bin/media-server", "--version") out, err := cmd.Output() if err != nil { return "", fmt.Errorf("get version failed: %w", err) } return strings.TrimSpace(string(out)), nil } func (s *SystemCtlController) Start(configName string) (Status, error) { // 使用 systemctl start cmd := exec.Command("systemctl", "start", s.serviceName) var stderr bytes.Buffer cmd.Stderr = &stderr if err := cmd.Run(); err != nil { return Status{}, fmt.Errorf("start failed: %w, stderr: %s", err, stderr.String()) } // 等待服务启动 time.Sleep(500 * time.Millisecond) return s.Status() } func (s *SystemCtlController) Stop() (Status, error) { cmd := exec.Command("systemctl", "stop", s.serviceName) if err := cmd.Run(); err != nil { return Status{}, fmt.Errorf("stop failed: %w", err) } return Status{Running: false}, nil } func (s *SystemCtlController) Restart(configName string) (Status, error) { cmd := exec.Command("systemctl", "restart", s.serviceName) if err := cmd.Run(); err != nil { return Status{}, fmt.Errorf("restart failed: %w", err) } time.Sleep(500 * time.Millisecond) return s.Status() } // 二进制更新相关功能在 systemctl 模式下不支持 func (s *SystemCtlController) BinaryInfo() (BinaryUpdateResult, error) { return BinaryUpdateResult{}, ErrNotSupported } func (s *SystemCtlController) UpdateBinary(r io.Reader, contentLength int64, expectedSha256 string) (BinaryUpdateResult, error) { return BinaryUpdateResult{}, ErrNotSupported } func (s *SystemCtlController) RollbackBinary(backupPath string) (BinaryUpdateResult, error) { return BinaryUpdateResult{}, ErrNotSupported }