diff --git a/src/github.com/coreos/go-systemd/dbus/methods.go b/src/github.com/coreos/go-systemd/dbus/methods.go index 37d82b1..f80b6dd 100644 --- a/src/github.com/coreos/go-systemd/dbus/methods.go +++ b/src/github.com/coreos/go-systemd/dbus/methods.go @@ -128,10 +128,7 @@ func (c *Conn) ReloadOrTryRestartUnit(name string, mode string) (string, error) // unique. mode is the same as in StartUnit(), properties contains properties // of the unit. func (c *Conn) StartTransientUnit(name string, mode string, properties ...Property) (string, error) { - // the dbus interface for this method does not use the last argument and - // should simply be given an empty list. We use a concrete type here - // (instead of the more appropriate interface{}) to satisfy the dbus library. - return c.runJob("org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]string, 0)) + return c.runJob("org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0)) } // KillUnit takes the unit name and a UNIX signal number to send. All of the unit's diff --git a/src/github.com/coreos/go-systemd/dbus/methods_test.go b/src/github.com/coreos/go-systemd/dbus/methods_test.go index 09bd212..64d4b8e 100644 --- a/src/github.com/coreos/go-systemd/dbus/methods_test.go +++ b/src/github.com/coreos/go-systemd/dbus/methods_test.go @@ -17,6 +17,8 @@ limitations under the License. package dbus import ( + "fmt" + "math/rand" "os" "path/filepath" "testing" @@ -153,3 +155,59 @@ func TestGetUnitPropertiesRejectsInvalidName(t *testing.T) { t.Fatal("Expected an error, got nil") } } + +// Ensure that basic transient unit starting and stopping works. +func TestStartStopTransientUnit(t *testing.T) { + conn := setupConn(t) + + props := []Property{ + PropExecStart([]string{"/bin/sleep", "400"}, false), + } + target := fmt.Sprintf("testing-transient-%d.service", rand.Int()) + + // Start the unit + job, err := conn.StartTransientUnit(target, "replace", props...) + if err != nil { + t.Fatal(err) + } + + if job != "done" { + t.Fatal("Job is not done, %v", job) + } + + units, err := conn.ListUnits() + + var unit *UnitStatus + for _, u := range units { + if u.Name == target { + unit = &u + } + } + + if unit == nil { + t.Fatalf("Test unit not found in list") + } + + if unit.ActiveState != "active" { + t.Fatalf("Test unit not active") + } + + // 3. Stop the unit + job, err = conn.StopUnit(target, "replace") + if err != nil { + t.Fatal(err) + } + + units, err = conn.ListUnits() + + unit = nil + for _, u := range units { + if u.Name == target { + unit = &u + } + } + + if unit != nil { + t.Fatalf("Test unit found in list, should be stopped") + } +} diff --git a/src/github.com/coreos/go-systemd/dbus/properties.go b/src/github.com/coreos/go-systemd/dbus/properties.go index 6347f0d..c813255 100644 --- a/src/github.com/coreos/go-systemd/dbus/properties.go +++ b/src/github.com/coreos/go-systemd/dbus/properties.go @@ -41,6 +41,11 @@ type Property struct { Value dbus.Variant } +type PropertyCollection struct { + Name string + Properties []Property +} + type execStart struct { Path string // the binary path to execute Args []string // an array with all arguments to pass to the executed command, starting with argument 0