82 lines
1.7 KiB
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: "服务名称无效"}
|