// Package initsys selects the init system backend that installs and controls // unitdore services. package initsys import ( "fmt" "os" "path/filepath" "github.com/warkanum/unitdore/config" "github.com/warkanum/unitdore/openrc" "github.com/warkanum/unitdore/runit" "github.com/warkanum/unitdore/systemd" ) // Backend names. const ( Systemd = "systemd" OpenRC = "openrc" Runit = "runit" ) // Init is implemented by every init system backend. u.User selects the scope; // backends that cannot do per-user managers run user units as system services. type Init interface { Name() string ServiceName(u config.Unit, prefix, suffix string) string UnitPath(u config.Unit, prefix, suffix string) (string, error) Generate(u config.Unit, prefix, suffix string) (string, error) Install(u config.Unit, prefix, suffix string) error Uninstall(u config.Unit, prefix, suffix string) error Enable(u config.Unit, prefix, suffix string) error Disable(u config.Unit, prefix, suffix string) error Start(u config.Unit, prefix, suffix string) error Stop(u config.Unit, prefix, suffix string) error // Status returns active | inactive | failed | activating | deactivating | unknown. Status(u config.Unit, prefix, suffix string) string IsInstalled(u config.Unit, prefix, suffix string) bool // SupportsLinger reports whether user units need systemd-style linger. SupportsLinger() bool } // New returns the backend named in cfg.Init, or the detected one. func New(cfg *config.Config) (Init, error) { name := cfg.Init if name == "" { name = Detect("/") } switch name { case Systemd: return systemd.Backend{}, nil case OpenRC: return openrc.Backend{}, nil case Runit: return runit.Backend{ServiceDir: cfg.ServiceDir}, nil default: return nil, fmt.Errorf("unknown init %q (want systemd, openrc or runit)", name) } } // Detect guesses the running init system below root. Falls back to systemd. func Detect(root string) string { has := func(p string) bool { _, err := os.Stat(filepath.Join(root, p)) return err == nil } switch { case has("run/systemd/system"): return Systemd case has("run/openrc"), has("sbin/openrc-run"): return OpenRC case has("run/runit"), has("etc/runit"): return Runit default: return Systemd } }