From 6b8241ed7cae4be1c2fcfe01e836c393f55a5d6c Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Sun, 16 May 2021 17:20:03 -0700 Subject: [PATCH] Make IsEnabled match the documentation --- errors.go | 2 + systemctl.go | 186 ++++++++++++++++++++++++++++++++------------------- 2 files changed, 121 insertions(+), 67 deletions(-) diff --git a/errors.go b/errors.go index 2259d82..18a016e 100644 --- a/errors.go +++ b/errors.go @@ -16,6 +16,8 @@ var ( // Running as superuser or adding the correct PolicyKit definitions can fix this // See https://wiki.debian.org/PolicyKit for more information ErrInsufficientPermissions = errors.New("insufficient permissions") + // Selected unit file resides outside of the unit file search path + ErrLinked = errors.New("unit file linked") // Masked units can only be unmasked, but something else was attempted // Unmask the unit before enabling or disabling it ErrMasked = errors.New("unit masked") diff --git a/systemctl.go b/systemctl.go index 7883936..3addd8c 100644 --- a/systemctl.go +++ b/systemctl.go @@ -8,22 +8,54 @@ import ( "github.com/taigrr/systemctl/properties" ) -func IsFailed(ctx context.Context, unit string, opts Options) (bool, error) { - var args = []string{"is-failed", "--system", unit} +// Reload systemd manager configuration. +// +// This will rerun all generators (see systemd. generator(7)), reload all unit +// files, and recreate the entire dependency tree. While the daemon is being +// reloaded, all sockets systemd listens on behalf of user configuration will +// stay accessible. +func DaemonReload(ctx context.Context, opts Options) error { + var args = []string{"daemon-reload", "--system"} if opts.UserMode { args[1] = "--user" } - stdout, _, _, err := execute(ctx, args) - if matched, _ := regexp.MatchString(`inactive`, stdout); matched { - return false, nil - } else if matched, _ := regexp.MatchString(`active`, stdout); matched { - return false, nil - } else if matched, _ := regexp.MatchString(`failed`, stdout); matched { - return true, nil - } - return false, err + _, _, _, err := execute(ctx, args) + return err } +// Disables one or more units. +// +// This removes all symlinks to the unit files backing the specified units from +// the unit configuration directory, and hence undoes any changes made by +// enable or link. +func Disable(ctx context.Context, unit string, opts Options) error { + var args = []string{"disable", "--system", unit} + if opts.UserMode { + args[1] = "--user" + } + _, _, _, err := execute(ctx, args) + return err +} + +// Enable one or more units or unit instances. +// +// This will create a set of symlinks, as encoded in the [Install] sections of +// the indicated unit files. After the symlinks have been created, the system +// manager configuration is reloaded (in a way equivalent to daemon-reload), +// in order to ensure the changes are taken into account immediately. +func Enable(ctx context.Context, unit string, opts Options) error { + var args = []string{"enable", "--system", unit} + if opts.UserMode { + args[1] = "--user" + } + _, _, _, err := execute(ctx, args) + return err +} + +// Check whether any of the specified units are active (i.e. running). +// +// Returns true if the unit is active, false if inactive or failed. +// Also returns false in an error case. func IsActive(ctx context.Context, unit string, opts Options) (bool, error) { var args = []string{"is-active", "--system", unit} if opts.UserMode { @@ -41,30 +73,77 @@ func IsActive(ctx context.Context, unit string, opts Options) (bool, error) { return false, err } +// Checks whether any of the specified unit files are enabled (as with enable). +// +// Returns true if the unit is enabled, aliased, static, indirect, generated +// or transient. +// +// Returns false if disabled. Also returns an error if linked, masked, or bad. +// +// See https://www.freedesktop.org/software/systemd/man/systemctl.html#is-enabled%20UNIT%E2%80%A6 +// for more information func IsEnabled(ctx context.Context, unit string, opts Options) (bool, error) { var args = []string{"is-enabled", "--system", unit} if opts.UserMode { args[1] = "--user" } stdout, _, _, err := execute(ctx, args) - if matched, _ := regexp.MatchString(`enabled`, stdout); matched { + switch stdout { + case "enabled": return true, nil - } else if matched, _ := regexp.MatchString(`disabled`, stdout); matched { - return false, nil - } else if matched, _ := regexp.MatchString(`masked`, stdout); matched { + case "enabled-runtime": + return true, nil + case "linked": + return false, ErrLinked + case "linked-runtime": + return false, ErrLinked + case "alias": + return true, nil + case "masked": + return false, ErrMasked + case "masked-runtime": + return false, ErrMasked + case "static": + return true, nil + case "indirect": + return true, nil + case "disabled": return false, nil + case "generated": + return true, nil + case "transient": + return true, nil } - - return false, err + if err != nil { + return false, err + } + return false, ErrUnspecified } -func Status(ctx context.Context, unit string, opts Options) (string, error) { - var args = []string{"status", "--system", unit} +// Check whether any of the specified units are in a "failed" state. +func IsFailed(ctx context.Context, unit string, opts Options) (bool, error) { + var args = []string{"is-failed", "--system", unit} if opts.UserMode { args[1] = "--user" } stdout, _, _, err := execute(ctx, args) - return stdout, err + if matched, _ := regexp.MatchString(`inactive`, stdout); matched { + return false, nil + } else if matched, _ := regexp.MatchString(`active`, stdout); matched { + return false, nil + } else if matched, _ := regexp.MatchString(`failed`, stdout); matched { + return true, nil + } + return false, err +} + +func Mask(ctx context.Context, unit string, opts Options) error { + var args = []string{"mask", "--system", unit} + if opts.UserMode { + args[1] = "--user" + } + _, _, _, err := execute(ctx, args) + return err } func Restart(ctx context.Context, unit string, opts Options) error { @@ -76,51 +155,6 @@ func Restart(ctx context.Context, unit string, opts Options) error { return err } -func Start(ctx context.Context, unit string, opts Options) error { - var args = []string{"start", "--system", unit} - if opts.UserMode { - args[1] = "--user" - } - _, _, _, err := execute(ctx, args) - return err -} - -func Stop(ctx context.Context, unit string, opts Options) error { - var args = []string{"stop", "--system", unit} - if opts.UserMode { - args[1] = "--user" - } - _, _, _, err := execute(ctx, args) - return err -} - -func Enable(ctx context.Context, unit string, opts Options) error { - var args = []string{"enable", "--system", unit} - if opts.UserMode { - args[1] = "--user" - } - _, _, _, err := execute(ctx, args) - return err -} - -func Disable(ctx context.Context, unit string, opts Options) error { - var args = []string{"disable", "--system", unit} - if opts.UserMode { - args[1] = "--user" - } - _, _, _, err := execute(ctx, args) - return err -} - -func DaemonReload(ctx context.Context, opts Options) error { - var args = []string{"daemon-reload", "--system"} - if opts.UserMode { - args[1] = "--user" - } - _, _, _, err := execute(ctx, args) - return err -} - func Show(ctx context.Context, unit string, property properties.Property, opts Options) (string, error) { var args = []string{"show", "--system", unit, "--property", string(property)} if opts.UserMode { @@ -132,8 +166,26 @@ func Show(ctx context.Context, unit string, property properties.Property, opts O return stdout, err } -func Mask(ctx context.Context, unit string, opts Options) error { - var args = []string{"mask", "--system", unit} +func Start(ctx context.Context, unit string, opts Options) error { + var args = []string{"start", "--system", unit} + if opts.UserMode { + args[1] = "--user" + } + _, _, _, err := execute(ctx, args) + return err +} + +func Status(ctx context.Context, unit string, opts Options) (string, error) { + var args = []string{"status", "--system", unit} + if opts.UserMode { + args[1] = "--user" + } + stdout, _, _, err := execute(ctx, args) + return stdout, err +} + +func Stop(ctx context.Context, unit string, opts Options) error { + var args = []string{"stop", "--system", unit} if opts.UserMode { args[1] = "--user" }