Scert/backend/internal/servicehost/linux.go

82 lines
1.7 KiB
Go

//go:build linux
package servicehost
import (
"context"
"os/exec"
)
func Install(ctx context.Context, options Options) error {
o, err := options.normalized()
if err != nil {
return err
}
if err := runSystemctl(ctx, "enable", o.Name); err != nil {
return commandError("注册", err)
}
return nil
}
func Uninstall(ctx context.Context, name string) error {
if err := validateName(name); err != nil {
return err
}
if err := runSystemctl(ctx, "disable", name); err != nil {
return commandError("取消注册", err)
}
return nil
}
func Start(ctx context.Context, name string) error {
if err := validateName(name); err != nil {
return err
}
if err := runSystemctl(ctx, "start", name); err != nil {
return commandError("启动", err)
}
return nil
}
func Stop(ctx context.Context, name string) error {
if err := validateName(name); err != nil {
return err
}
if err := runSystemctl(ctx, "stop", name); err != nil {
return commandError("停止", err)
}
return nil
}
func runSystemctl(ctx context.Context, args ...string) error {
command := exec.CommandContext(ctx, "systemctl", args...)
output, err := command.CombinedOutput()
if err != nil {
return &commandFailure{output: string(output), err: err}
}
return nil
}
type commandFailure struct {
output string
err error
}
func (e *commandFailure) Error() string {
if e.err != nil {
return e.output + ": " + e.err.Error()
}
return e.output
}
func (e *commandFailure) Unwrap() error { return e.err }
func validateName(name string) error {
if name == "" || name == "." || name == ".." {
return ErrInvalidName
}
return nil
}
var ErrInvalidName = &commandFailure{output: "服务名称无效"}