diff --git a/dbus/methods.go b/dbus/methods.go index 679f244e..3e1f3a71 100644 --- a/dbus/methods.go +++ b/dbus/methods.go @@ -830,3 +830,18 @@ func (c *Conn) listJobsInternal(ctx context.Context) ([]JobStatus, error) { return status, nil } + +// GetUnitFileStateContext returns UnitFileState +func (c *Conn) GetUnitFileStateContext(ctx context.Context, name string) (string, error) { + var prop dbus.Variant + obj := c.sysconn.Object("org.freedesktop.systemd1", "/org/freedesktop/systemd1") + err := obj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.GetUnitFileState", 0, name).Store(&prop) + if err != nil { + return "", err + } + state, ok := prop.Value().(string) + if !ok { + return "", fmt.Errorf("failed to cast UnitFileState prop to string") + } + return state, nil +} diff --git a/dbus/methods_test.go b/dbus/methods_test.go index aa751172..31221f62 100644 --- a/dbus/methods_test.go +++ b/dbus/methods_test.go @@ -15,12 +15,14 @@ package dbus import ( + "context" "fmt" "os" "os/exec" "path" "path/filepath" "reflect" + "strings" "syscall" "testing" "time" @@ -1600,3 +1602,27 @@ func TestUnitName(t *testing.T) { } } } + +// TestGetUnitFileState reads the `systemd-udevd.service` which should exist on all systemd +// systems and ensures that UnitFileState property is valid. +func TestGetUnitFileState(t *testing.T) { + conn := setupConn(t) + defer conn.Close() + service := "systemd-udevd.service" + got, err := conn.GetUnitFileStateContext(context.Background(), service) + if err != nil { + t.Fatal(err) + } + ok := false + // valid UnitFileState values + validUnitFileStates := []string{"enabled", "disabled", "static", "bad"} + for _, v := range validUnitFileStates { + if got == v { + ok = true + break + } + } + if !ok { + t.Errorf("invalid UnitFileState returned from GetUnitFileState(%s): got %s, want one of [%s]", service, got, strings.Join(validUnitFileStates, ", ")) + } +}