'varlink-common.c',
'varlink-dynamic-user.c',
'varlink-execute.c',
+ 'varlink-job.c',
'varlink-kill.c',
'varlink-manager.c',
'varlink-metrics.c',
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "sd-varlink.h"
+
+#include "job.h"
+#include "json-util.h"
+#include "strv.h"
+#include "unit.h"
+#include "varlink-job.h"
+
+static int activation_details_build_json(sd_json_variant **ret, const char *name, void *userdata) {
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
+ _cleanup_strv_free_ char **pairs = NULL;
+ Job *j = ASSERT_PTR(userdata);
+ int r;
+
+ assert(ret);
+
+ r = activation_details_append_pair(j->activation_details, &pairs);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to get activation details: %m");
+ if (r == 0) {
+ *ret = NULL;
+ return 0;
+ }
+
+ STRV_FOREACH_PAIR(key, value, pairs) {
+ r = sd_json_variant_set_field_string(&v, *key, *value);
+ if (r < 0)
+ return r;
+ }
+
+ *ret = TAKE_PTR(v);
+ return 0;
+}
+
+int job_build_json(sd_json_variant **ret, const char *name, void *userdata) {
+ Job *j = ASSERT_PTR(userdata);
+
+ /* "Unit" is omitted in StartTransient streaming notifications where the caller already knows the unit. */
+ return sd_json_buildo(
+ ASSERT_PTR(ret),
+ SD_JSON_BUILD_PAIR_INTEGER("Id", j->id),
+ JSON_BUILD_PAIR_STRING_NON_EMPTY("Unit", j->unit ? j->unit->id : NULL),
+ JSON_BUILD_PAIR_ENUM("JobType", job_type_to_string(j->type)),
+ JSON_BUILD_PAIR_ENUM("State", job_state_to_string(j->state)),
+ JSON_BUILD_PAIR_ENUM_NON_EMPTY("Result", job_result_to_string(j->result)),
+ JSON_BUILD_PAIR_CALLBACK_NON_NULL("ActivationDetails", activation_details_build_json, j));
+}
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "core-forward.h"
+
+int job_build_json(sd_json_variant **ret, const char *name, void *userdata);
#include "varlink-cgroup.h"
#include "varlink-common.h"
#include "varlink-execute.h"
+#include "varlink-job.h"
#include "varlink-kill.h"
#include "varlink-mount.h"
#include "varlink-path.h"
SD_JSON_BUILD_PAIR_CALLBACK("runtime", unit_runtime_build_json, u));
}
-static int job_build_json(sd_json_variant **ret, const char *name, void *userdata) {
- Job *j = ASSERT_PTR(userdata);
-
- /* Note that "Result" is suppressed until the job reaches JOB_FINISHED. */
- return sd_json_buildo(
- ASSERT_PTR(ret),
- SD_JSON_BUILD_PAIR_INTEGER("Id", j->id),
- JSON_BUILD_PAIR_ENUM("JobType", job_type_to_string(j->type)),
- JSON_BUILD_PAIR_ENUM("State", job_state_to_string(j->state)),
- JSON_BUILD_PAIR_STRING_NON_EMPTY_UNDERSCORIFY("Result", job_result_to_string(j->result)));
-}
-
void varlink_job_send_change_signal(Job *j) {
assert(j);
SD_VARLINK_DEFINE_ENUM_VALUE(frozen),
SD_VARLINK_DEFINE_ENUM_VALUE(concurrency));
-/* Field names match the D-Bus Job properties (Id, JobType, State) */
+/* Field names match the D-Bus Job properties (Id, Unit, JobType, State) */
+#define VARLINK_DEFINE_JOB_FIELDS(direction) \
+ SD_VARLINK_FIELD_COMMENT("The numeric job ID"), \
+ SD_VARLINK_DEFINE_##direction(Id, SD_VARLINK_INT, 0), \
+ SD_VARLINK_FIELD_COMMENT("The unit name this job operates on"), \
+ SD_VARLINK_DEFINE_##direction(Unit, SD_VARLINK_STRING, SD_VARLINK_NULLABLE), \
+ SD_VARLINK_FIELD_COMMENT("The job type"), \
+ SD_VARLINK_DEFINE_##direction##_BY_TYPE(JobType, JobType, 0), \
+ SD_VARLINK_FIELD_COMMENT("Current job state. 'finished' indicates the job has completed; in that case Result is also set."), \
+ SD_VARLINK_DEFINE_##direction##_BY_TYPE(State, JobState, SD_VARLINK_NULLABLE), \
+ SD_VARLINK_FIELD_COMMENT("Job result. Only set once the job has reached the 'finished' state."), \
+ SD_VARLINK_DEFINE_##direction##_BY_TYPE(Result, JobResult, SD_VARLINK_NULLABLE), \
+ SD_VARLINK_FIELD_COMMENT("Activation details describing what triggered this job, as key-value pairs"), \
+ SD_VARLINK_DEFINE_##direction(ActivationDetails, SD_VARLINK_STRING, SD_VARLINK_NULLABLE|SD_VARLINK_MAP)
+
SD_VARLINK_DEFINE_STRUCT_TYPE(
Job,
- SD_VARLINK_FIELD_COMMENT("The numeric job ID"),
- SD_VARLINK_DEFINE_FIELD(Id, SD_VARLINK_INT, 0),
- SD_VARLINK_FIELD_COMMENT("The job type"),
- SD_VARLINK_DEFINE_FIELD_BY_TYPE(JobType, JobType, 0),
- SD_VARLINK_FIELD_COMMENT("Current job state. 'finished' indicates the job has completed; in that case Result is also set."),
- SD_VARLINK_DEFINE_FIELD_BY_TYPE(State, JobState, SD_VARLINK_NULLABLE),
- SD_VARLINK_FIELD_COMMENT("Job result. Only set once the job has reached the 'finished' state."),
- SD_VARLINK_DEFINE_FIELD_BY_TYPE(Result, JobResult, SD_VARLINK_NULLABLE));
+ VARLINK_DEFINE_JOB_FIELDS(FIELD));
SD_VARLINK_DEFINE_INTERFACE(
io_systemd_Job,