diff --git a/dbus/methods.go b/dbus/methods.go index 490248b8..d69632bf 100644 --- a/dbus/methods.go +++ b/dbus/methods.go @@ -718,6 +718,11 @@ func (c *Conn) ListJobsContext(ctx context.Context) ([]JobStatus, error) { return storeSlice[JobStatus](c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListJobs", 0).Store) } +// CancelJob cancels the specified job ID. +func (c *Conn) CancelJob(ctx context.Context, id uint32) error { + return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.CancelJob", 0, id).Store() +} + // FreezeUnit freezes the cgroup associated with the unit. // Note that FreezeUnit and [Conn.ThawUnit] are only supported on systems running with cgroup v2. func (c *Conn) FreezeUnit(ctx context.Context, unit string) error { diff --git a/dbus/methods_test.go b/dbus/methods_test.go index 87d2bd8e..868fa30b 100644 --- a/dbus/methods_test.go +++ b/dbus/methods_test.go @@ -1886,3 +1886,38 @@ func TestStopUnitReentrant(t *testing.T) { t.Fatal("JobListener jobs leaked") } } + +func TestCancel(t *testing.T) { + target := "cancelme.service" + conn := setupConn(t) + defer conn.Close() + + setupUnit(target, conn, t) + linkUnit(target, conn, t) + + reschan := make(chan string) + _, err := conn.StartUnit(target, "replace", reschan) + if err != nil { + t.Fatal(err) + } + + ctx := context.Background() + units, err := conn.ListUnitsByNamesContext(ctx, []string{target}) + if err != nil { + t.Fatal("couldn't list units ", err) + } + + if err := conn.CancelJob(ctx, units[0].JobId); err != nil { + t.Fatal("couldn't cancel job ", err) + } + + units, err = conn.ListUnitsByNamesContext(ctx, []string{target}) + if err != nil { + t.Fatal("couldn't list units after cancel ", err) + } + + job := <-reschan + if job != "canceled" { + t.Fatal("Job is not canceled:", job) + } +} diff --git a/fixtures/cancelme.service b/fixtures/cancelme.service new file mode 100644 index 00000000..77ab3835 --- /dev/null +++ b/fixtures/cancelme.service @@ -0,0 +1,6 @@ +[Unit] +Description=cancel unit test + +[Service] +ExecStartPre=/bin/sleep 400 +ExecStart=/bin/sleep 400