kairos-sdk/machine/systemd/unit.go

115 lines
2.2 KiB
Go
Raw Normal View History

package systemd
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/kairos-io/kairos-sdk/utils"
)
type ServiceUnit struct {
content string
name, instance string
rootdir string
}
const overrideCmdTemplate string = `
[Service]
ExecStart=
ExecStart=%s
`
type ServiceOpts func(*ServiceUnit) error
func WithRoot(n string) ServiceOpts {
return func(su *ServiceUnit) error {
su.rootdir = n
return nil
}
}
func WithName(n string) ServiceOpts {
return func(su *ServiceUnit) error {
su.name = n
return nil
}
}
func WithInstance(n string) ServiceOpts {
return func(su *ServiceUnit) error {
su.instance = n
return nil
}
}
func WithUnitContent(n string) ServiceOpts {
return func(su *ServiceUnit) error {
su.content = n
return nil
}
}
func NewService(opts ...ServiceOpts) (ServiceUnit, error) {
s := &ServiceUnit{}
for _, o := range opts {
if err := o(s); err != nil {
return *s, err
}
}
return *s, nil
}
func (s ServiceUnit) WriteUnit() error {
uname := s.name
if s.instance != "" {
uname = fmt.Sprintf("%s@", s.name)
}
if err := os.WriteFile(filepath.Join(s.rootdir, fmt.Sprintf("/etc/systemd/system/%s.service", uname)), []byte(s.content), 0600); err != nil {
return err
}
_, err := utils.SH("systemctl daemon-reload")
return err
}
func (s ServiceUnit) OverrideCmd(cmd string) error {
svcDir := filepath.Join(s.rootdir, fmt.Sprintf("/etc/systemd/system/%s.service.d/", s.name))
os.MkdirAll(svcDir, 0600) //nolint:errcheck
return os.WriteFile(filepath.Join(svcDir, "override.conf"), []byte(fmt.Sprintf(overrideCmdTemplate, cmd)), 0600)
}
func (s ServiceUnit) Start() error {
return s.systemctl("start", false)
}
func (s ServiceUnit) Restart() error {
return s.systemctl("restart", false)
}
func (s ServiceUnit) Enable() error {
return s.systemctl("enable", false)
}
func (s ServiceUnit) StartBlocking() error {
return s.systemctl("start", true)
}
func (s ServiceUnit) systemctl(action string, blocking bool) error {
uname := s.name
if s.instance != "" {
uname = fmt.Sprintf("%s@%s", s.name, s.instance)
}
args := []string{action}
if !blocking {
args = append(args, "--no-block")
}
args = append(args, uname)
_, err := utils.SH(fmt.Sprintf("systemctl %s", strings.Join(args, " ")))
return err
}