diff --git a/src/core/varlink-unit.c b/src/core/varlink-unit.c index cd6df5a5b8..e43395385e 100644 --- a/src/core/varlink-unit.c +++ b/src/core/varlink-unit.c @@ -663,6 +663,7 @@ static void transient_exec_command_item_done(TransientExecCommandItem *i) { static JSON_DISPATCH_ENUM_DEFINE(dispatch_service_type, ServiceType, service_type_from_string); static JSON_DISPATCH_ENUM_DEFINE(dispatch_job_mode, JobMode, job_mode_from_string); +static JSON_DISPATCH_ENUM_DEFINE(dispatch_collect_mode, CollectMode, collect_mode_from_string); typedef struct TransientWorkingDirectory { const char *path; @@ -811,6 +812,7 @@ static int dispatch_transient_exec_command(const char *name, sd_json_variant *va typedef struct StartTransientContextParameters { const char *id; const char *description; + CollectMode collect_mode; TransientExecContextParameters exec; TransientServiceParameters service; const char *bad_exec_field; /* Set by inner Exec dispatcher to the unknown sub-property name */ @@ -827,7 +829,9 @@ static void transient_exec_context_parameters_init(TransientExecContextParameter static void start_transient_context_parameters_init(StartTransientContextParameters *p) { assert(p); - *p = (StartTransientContextParameters) {}; + *p = (StartTransientContextParameters) { + .collect_mode = _COLLECT_MODE_INVALID, + }; transient_exec_context_parameters_init(&p->exec); transient_service_parameters_init(&p->service); } @@ -973,10 +977,11 @@ static int dispatch_transient_service(const char *name, sd_json_variant *variant static int dispatch_transient_context(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) { static const sd_json_dispatch_field context_dispatch[] = { - { "ID", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, offsetof(StartTransientContextParameters, id), SD_JSON_MANDATORY }, - { "Description", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(StartTransientContextParameters, description), 0 }, - { "Exec", SD_JSON_VARIANT_OBJECT, dispatch_transient_exec_context, 0, 0 }, - { "Service", SD_JSON_VARIANT_OBJECT, dispatch_transient_service, 0, 0 }, + { "ID", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, offsetof(StartTransientContextParameters, id), SD_JSON_MANDATORY }, + { "Description", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(StartTransientContextParameters, description), 0 }, + { "CollectMode", SD_JSON_VARIANT_STRING, dispatch_collect_mode, offsetof(StartTransientContextParameters, collect_mode), 0 }, + { "Exec", SD_JSON_VARIANT_OBJECT, dispatch_transient_exec_context, 0, 0 }, + { "Service", SD_JSON_VARIANT_OBJECT, dispatch_transient_service, 0, 0 }, {} }; @@ -1017,6 +1022,11 @@ static int transient_unit_apply_properties(Unit *u, StartTransientContextParamet unit_write_settingf(u, UNIT_RUNTIME|UNIT_ESCAPE_SPECIFIERS, "Description", "Description=%s", p->description); } + if (p->collect_mode >= 0) { + u->collect_mode = p->collect_mode; + unit_write_settingf(u, UNIT_RUNTIME, "CollectMode", "CollectMode=%s", collect_mode_to_string(p->collect_mode)); + } + return 0; } diff --git a/src/shared/varlink-io.systemd.Unit.c b/src/shared/varlink-io.systemd.Unit.c index 202b529e87..3c3b63b93e 100644 --- a/src/shared/varlink-io.systemd.Unit.c +++ b/src/shared/varlink-io.systemd.Unit.c @@ -1570,7 +1570,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE( SD_VARLINK_DEFINE_FIELD(parameter, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)); /* UnitContext is used both as input to StartTransient (subset settable at creation time: ID, - * Description, Service, and the Exec subset {WorkingDirectory, Environment, SetCredential, + * Description, CollectMode, Service, and the Exec subset {WorkingDirectory, Environment, SetCredential, * SetCredentialEncrypted}) and as output from List/StartTransient (full unit configuration). Fields * that are not settable at creation time are rejected with PropertyNotSupported when supplied as * input. */ diff --git a/test/units/TEST-74-AUX-UTILS.varlinkctl-unit.sh b/test/units/TEST-74-AUX-UTILS.varlinkctl-unit.sh index f20a7fd425..b684da9238 100755 --- a/test/units/TEST-74-AUX-UTILS.varlinkctl-unit.sh +++ b/test/units/TEST-74-AUX-UTILS.varlinkctl-unit.sh @@ -160,12 +160,14 @@ printf '%s' "$result" | jq --seq --slurp -e 'any(.[]; .job.Result == "done")' >/ # Transient service with Description and RemainAfterExit defer_transient_cleanup varlink-transient-desc.service result=$(varlinkctl call "$MANAGER_SOCKET" io.systemd.Unit.StartTransient \ - '{"context":{"ID":"varlink-transient-desc.service","Description":"Test description property","Service":{"Type":"oneshot","RemainAfterExit":true,"ExecStart":[{"path":"/bin/true"}]}}}') + '{"context":{"ID":"varlink-transient-desc.service","Description":"Test description property","CollectMode":"inactive_or_failed","Service":{"Type":"oneshot","RemainAfterExit":true,"ExecStart":[{"path":"/bin/true"}]}}}') echo "$result" | jq -e '.context.Description == "Test description property"' +echo "$result" | jq -e '.context.CollectMode == "inactive_or_failed"' echo "$result" | jq -e '.context.Service.Type == "oneshot"' echo "$result" | jq -e '.context.Service.RemainAfterExit == true' echo "$result" | jq -e '.context.Service.ExecStart[0].path == "/bin/true"' echo "$result" | jq -e '.runtime' +systemctl show -P CollectMode varlink-transient-desc.service | grep '^inactive-or-failed$' >/dev/null # Transient service with explicit arguments defer_transient_cleanup varlink-transient-args.service