core: introduce io.systemd.Unit.List (first PR) (#37432)
This commit is contained in:
@@ -65,6 +65,7 @@ libcore_sources = files(
|
||||
'varlink.c',
|
||||
'varlink-common.c',
|
||||
'varlink-manager.c',
|
||||
'varlink-unit.c',
|
||||
)
|
||||
|
||||
subdir('bpf/socket_bind')
|
||||
|
||||
@@ -47,7 +47,8 @@ static int manager_context_build_json(sd_json_variant **ret, const char *name, v
|
||||
if (!taints)
|
||||
return -ENOMEM;
|
||||
|
||||
return sd_json_buildo(ASSERT_PTR(ret),
|
||||
return sd_json_buildo(
|
||||
ASSERT_PTR(ret),
|
||||
SD_JSON_BUILD_PAIR_STRING("Version", GIT_VERSION),
|
||||
SD_JSON_BUILD_PAIR_STRING("Architecture", architecture_to_string(uname_architecture())),
|
||||
SD_JSON_BUILD_PAIR_STRING("Features", systemd_features),
|
||||
@@ -109,7 +110,8 @@ static int manager_runtime_build_json(sd_json_variant **ret, const char *name, v
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
dual_timestamp watchdog_last_ping;
|
||||
|
||||
return sd_json_buildo(ASSERT_PTR(ret),
|
||||
return sd_json_buildo(
|
||||
ASSERT_PTR(ret),
|
||||
SD_JSON_BUILD_PAIR_STRING("Virtualization", virtualization_to_string(detect_virtualization())),
|
||||
SD_JSON_BUILD_PAIR_STRING("ConfidentialVirtualization", confidential_virtualization_to_string(detect_confidential_virtualization())),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("ConfirmSpawn", manager_get_confirm_spawn(m)),
|
||||
@@ -166,7 +168,8 @@ int vl_method_describe_manager(sd_varlink *link, sd_json_variant *parameters, sd
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = sd_json_buildo(&v,
|
||||
r = sd_json_buildo(
|
||||
&v,
|
||||
SD_JSON_BUILD_PAIR_CALLBACK("context", manager_context_build_json, manager),
|
||||
SD_JSON_BUILD_PAIR_CALLBACK("runtime", manager_runtime_build_json, manager));
|
||||
if (r < 0)
|
||||
|
||||
@@ -0,0 +1,423 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "sd-json.h"
|
||||
|
||||
#include "bitfield.h"
|
||||
#include "cgroup.h"
|
||||
#include "condition.h"
|
||||
#include "execute.h"
|
||||
#include "install.h"
|
||||
#include "json-util.h"
|
||||
#include "manager.h"
|
||||
#include "pidref.h"
|
||||
#include "set.h"
|
||||
#include "strv.h"
|
||||
#include "unit.h"
|
||||
#include "unit-name.h"
|
||||
#include "varlink-common.h"
|
||||
#include "varlink-unit.h"
|
||||
#include "varlink-util.h"
|
||||
|
||||
#define JSON_BUILD_EMERGENCY_ACTION_NON_EMPTY(name, value) \
|
||||
SD_JSON_BUILD_PAIR_CONDITION(value > EMERGENCY_ACTION_NONE, name, SD_JSON_BUILD_STRING(emergency_action_to_string(value)))
|
||||
|
||||
static int unit_dependencies_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
UnitDependency d;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
assert(name);
|
||||
|
||||
d = unit_dependency_from_string(name);
|
||||
if (d < 0)
|
||||
return log_debug_errno(d, "Failed to get unit dependency for '%s': %m", name);
|
||||
|
||||
void *value;
|
||||
Unit *other;
|
||||
HASHMAP_FOREACH_KEY(value, other, unit_get_dependencies(u, d)) {
|
||||
r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_STRING(other->id));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unit_mounts_for_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
Hashmap **mounts_for = userdata;
|
||||
UnitMountDependencyType d;
|
||||
const char *p;
|
||||
void *value;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
assert(name);
|
||||
|
||||
if (!mounts_for)
|
||||
return 0;
|
||||
|
||||
d = unit_mount_dependency_type_from_string(name);
|
||||
if (d < 0)
|
||||
return log_debug_errno(d, "Failed to get unit mount dependency for '%s': %m", name);
|
||||
|
||||
HASHMAP_FOREACH_KEY(value, p, mounts_for[d]) {
|
||||
r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_STRING(p));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unit_conditions_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
bool do_asserts = streq(name, "Asserts");
|
||||
Condition *list = userdata;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
LIST_FOREACH(conditions, c, list) {
|
||||
r = sd_json_variant_append_arraybo(
|
||||
&v,
|
||||
SD_JSON_BUILD_PAIR_STRING("type", do_asserts ? assert_type_to_string(c->type)
|
||||
: condition_type_to_string(c->type)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("trigger", c->trigger),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("negate", c->negate),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("parameter", c->parameter));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unit_context_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
|
||||
return sd_json_buildo(
|
||||
ASSERT_PTR(ret),
|
||||
SD_JSON_BUILD_PAIR_STRING("Type", unit_type_to_string(u->type)),
|
||||
SD_JSON_BUILD_PAIR_STRING("ID", u->id),
|
||||
SD_JSON_BUILD_PAIR_CONDITION(!set_isempty(u->aliases), "Names", JSON_BUILD_STRING_SET(u->aliases)),
|
||||
|
||||
/* [Unit] Section Options
|
||||
* https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#%5BUnit%5D%20Section%20Options */
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("Description", u->description),
|
||||
JSON_BUILD_PAIR_STRV_NON_EMPTY("Documentation", u->documentation),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Wants", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("WantedBy", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Requires", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("RequiredBy", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Requisite", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("RequisiteOf", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("BindsTo", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("BoundBy", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("PartOf", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("ConsistsOf", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Upholds", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("UpheldBy", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Conflicts", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("ConflictedBy", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Before", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("After", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("OnFailure", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("OnFailureOf", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("OnSuccess", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("OnSuccessOf", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("PropagatesReloadTo", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("ReloadPropagatedFrom", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("PropagatesStopTo", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("StopPropagatedFrom", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("JoinsNamespaceOf", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("RequiresMountsFor", unit_mounts_for_build_json, &u->mounts_for),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("WantsMountsFor", unit_mounts_for_build_json, &u->mounts_for),
|
||||
SD_JSON_BUILD_PAIR_STRING("OnSuccessJobMode", job_mode_to_string(u->on_success_job_mode)),
|
||||
SD_JSON_BUILD_PAIR_STRING("OnFailureJobMode", job_mode_to_string(u->on_failure_job_mode)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("IgnoreOnIsolate", u->ignore_on_isolate),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("StopWhenUnneeded", u->stop_when_unneeded),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("RefuseManualStart", u->refuse_manual_start),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("RefuseManualStop", u->refuse_manual_stop),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("AllowIsolate", u->allow_isolate),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("DefaultDependencies", u->default_dependencies),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("SurviveFinalKillSignal", u->survive_final_kill_signal),
|
||||
SD_JSON_BUILD_PAIR_STRING("CollectMode", collect_mode_to_string(u->collect_mode)),
|
||||
JSON_BUILD_EMERGENCY_ACTION_NON_EMPTY("FailureAction", u->failure_action),
|
||||
JSON_BUILD_EMERGENCY_ACTION_NON_EMPTY("SuccessAction", u->success_action),
|
||||
JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE("FailureActionExitStatus", u->failure_action_exit_status),
|
||||
JSON_BUILD_PAIR_INTEGER_NON_NEGATIVE("SuccessActionExitStatus", u->success_action_exit_status),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("JobTimeoutUSec", u->job_timeout),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("JobRunningTimeoutUSec", u->job_running_timeout),
|
||||
JSON_BUILD_EMERGENCY_ACTION_NON_EMPTY("JobTimeoutAction", u->job_timeout_action),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("JobTimeoutRebootArgument", u->job_timeout_reboot_arg),
|
||||
JSON_BUILD_PAIR_RATELIMIT_ENABLED("StartLimit", &u->start_ratelimit),
|
||||
JSON_BUILD_EMERGENCY_ACTION_NON_EMPTY("StartLimitAction", u->start_limit_action),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("RebootArgument", u->reboot_arg),
|
||||
|
||||
/* Conditions and Asserts
|
||||
* https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Conditions%20and%20Asserts */
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Conditions", unit_conditions_build_json, u->conditions),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Asserts", unit_conditions_build_json, u->asserts),
|
||||
|
||||
/* Others */
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Triggers", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("TriggeredBy", unit_dependencies_build_json, u),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("AccessSELinuxContext", u->access_selinux_context),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("FragmentPath", u->fragment_path),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("SourcePath", u->source_path),
|
||||
JSON_BUILD_PAIR_STRV_NON_EMPTY("DropInPaths", u->dropin_paths),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("UnitFilePreset", preset_action_past_tense_to_string(unit_get_unit_file_preset(u))),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("Transient", u->transient),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("Perpetual", u->perpetual));
|
||||
|
||||
// TODO follow up PRs:
|
||||
// JSON_BUILD_PAIR_CALLBACK_NON_NULL("CGroup", cgroup_context_build_json, u)
|
||||
// JSON_BUILD_PAIR_CALLBACK_NON_NULL("Exec", exec_context_build_json, u)
|
||||
// JSON_BUILD_PAIR_CALLBACK_NON_NULL("Kill", kill_context_build_json, u)
|
||||
// Mount/Automount context
|
||||
// Path context
|
||||
// Scope context
|
||||
// Swap context
|
||||
// Timer context
|
||||
// Service context
|
||||
// Socket context
|
||||
}
|
||||
|
||||
static int can_clean_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
ExecCleanMask mask;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
r = unit_can_clean(u, &mask);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to check if unit can be cleaned: %m");
|
||||
|
||||
for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
|
||||
if (!BIT_SET(mask, t))
|
||||
continue;
|
||||
|
||||
r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_STRING(exec_resource_type_to_string(t)));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(mask, EXEC_CLEAN_FDSTORE)) {
|
||||
r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_STRING("fdstore"));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int markers_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
unsigned *markers = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
BIT_FOREACH(m, *markers) {
|
||||
r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_STRING(unit_marker_to_string(m)));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
const ActivationDetails *activation_details = userdata;
|
||||
_cleanup_strv_free_ char **pairs = NULL;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
/* activation_details_append_pair() gracefully takes activation_details==NULL */
|
||||
r = activation_details_append_pair(activation_details, &pairs);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get activation details: %m");
|
||||
|
||||
STRV_FOREACH_PAIR(key, value, pairs) {
|
||||
r = sd_json_variant_append_arraybo(&v,
|
||||
SD_JSON_BUILD_PAIR_STRING("type", *key),
|
||||
SD_JSON_BUILD_PAIR_STRING("name", *value));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unit_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
Unit *f = unit_following(u);
|
||||
|
||||
return sd_json_buildo(
|
||||
ASSERT_PTR(ret),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("Following", f ? f->id : NULL),
|
||||
SD_JSON_BUILD_PAIR_STRING("LoadState", unit_load_state_to_string(u->load_state)),
|
||||
SD_JSON_BUILD_PAIR_STRING("ActiveState", unit_active_state_to_string(unit_active_state(u))),
|
||||
SD_JSON_BUILD_PAIR_STRING("FreezerState", freezer_state_to_string(u->freezer_state)),
|
||||
SD_JSON_BUILD_PAIR_STRING("SubState", unit_sub_state_to_string(u)),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("UnitFileState", unit_file_state_to_string(unit_get_unit_file_state(u))),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("StateChangeTimestamp", &u->state_change_timestamp),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("ActiveEnterTimestamp", &u->active_enter_timestamp),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("ActiveExitTimestamp", &u->active_exit_timestamp),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("InactiveEnterTimestamp", &u->inactive_enter_timestamp),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("InactiveExitTimestamp", &u->inactive_exit_timestamp),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CanStart", unit_can_start_refuse_manual(u)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CanStop", unit_can_stop_refuse_manual(u)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CanReload", unit_can_reload(u)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CanIsolate", unit_can_isolate_refuse_manual(u)),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("CanClean", can_clean_build_json, u),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CanFreeze", unit_can_freeze(u)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CanLiveMount", unit_can_live_mount(u, /* error= */ NULL) >= 0),
|
||||
JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("JobId", u->job ? u->job->id : 0),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("NeedDaemonReload", unit_need_daemon_reload(u)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("ConditionResult", u->condition_result),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("AssertResult", u->assert_result),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("ConditionTimestamp", &u->condition_timestamp),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("AssertTimestamp", &u->assert_timestamp),
|
||||
SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(u->invocation_id), "InvocationID", SD_JSON_BUILD_UUID(u->invocation_id)),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Markers", markers_build_json, &u->markers),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("ActivationDetails", activation_details_build_json, u->activation_details),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("DebugInvocation", u->debug_invocation));
|
||||
}
|
||||
|
||||
static int list_unit_one(sd_varlink *link, Unit *unit, bool more) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(unit);
|
||||
|
||||
r = sd_json_buildo(
|
||||
&v,
|
||||
SD_JSON_BUILD_PAIR_CALLBACK("context", unit_context_build_json, unit),
|
||||
SD_JSON_BUILD_PAIR_CALLBACK("runtime", unit_runtime_build_json, unit));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (more)
|
||||
return sd_varlink_notify(link, v);
|
||||
|
||||
return sd_varlink_reply(link, v);
|
||||
}
|
||||
|
||||
static int lookup_unit_by_pidref(sd_varlink *link, Manager *manager, PidRef *pidref, Unit **ret_unit) {
|
||||
_cleanup_(pidref_done) PidRef peer = PIDREF_NULL;
|
||||
Unit *unit;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(manager);
|
||||
assert(ret_unit);
|
||||
|
||||
if (pidref_is_automatic(pidref)) {
|
||||
r = varlink_get_peer_pidref(link, &peer);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get peer pidref: %m");
|
||||
|
||||
pidref = &peer;
|
||||
} else if (!pidref_is_set(pidref))
|
||||
return -EINVAL;
|
||||
|
||||
unit = manager_get_unit_by_pidref(manager, pidref);
|
||||
if (!unit)
|
||||
return -ESRCH;
|
||||
|
||||
*ret_unit = unit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct UnitLookupParameters {
|
||||
const char *name;
|
||||
PidRef pidref;
|
||||
} UnitLookupParameters;
|
||||
|
||||
static void unit_lookup_parameters_done(UnitLookupParameters *p) {
|
||||
assert(p);
|
||||
pidref_done(&p->pidref);
|
||||
}
|
||||
|
||||
int vl_method_list_units(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "name", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, offsetof(UnitLookupParameters, name), 0 /* allows UNIT_NAME_PLAIN | UNIT_NAME_INSTANCE */ },
|
||||
{ "pid", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_pidref, offsetof(UnitLookupParameters, pidref), SD_JSON_RELAX /* allows PID_AUTOMATIC */ },
|
||||
{}
|
||||
};
|
||||
|
||||
Manager *manager = ASSERT_PTR(userdata);
|
||||
_cleanup_(unit_lookup_parameters_done) UnitLookupParameters p = {
|
||||
.pidref = PIDREF_NULL,
|
||||
};
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(parameters);
|
||||
|
||||
r = sd_varlink_dispatch(link, parameters, dispatch_table, &p);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
if (p.name) {
|
||||
Unit *unit = manager_get_unit(manager, p.name);
|
||||
if (!unit)
|
||||
return sd_varlink_error(link, VARLINK_ERROR_UNIT_NO_SUCH_UNIT, NULL);
|
||||
|
||||
return list_unit_one(link, unit, /* more = */ false);
|
||||
}
|
||||
|
||||
if (pidref_is_set(&p.pidref) || pidref_is_automatic(&p.pidref)) {
|
||||
Unit *unit;
|
||||
r = lookup_unit_by_pidref(link, manager, &p.pidref, &unit);
|
||||
if (r == -EINVAL)
|
||||
return sd_varlink_error_invalid_parameter_name(link, "pid");
|
||||
if (r == -ESRCH)
|
||||
return sd_varlink_error(link, VARLINK_ERROR_UNIT_NO_SUCH_UNIT, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return list_unit_one(link, unit, /* more = */ false);
|
||||
}
|
||||
|
||||
// TODO lookup by invocationID, CGroup
|
||||
|
||||
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
|
||||
return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL);
|
||||
|
||||
const char *k;
|
||||
Unit *u, *previous = NULL;
|
||||
HASHMAP_FOREACH_KEY(u, k, manager->units) {
|
||||
/* ignore aliases */
|
||||
if (k != u->id)
|
||||
continue;
|
||||
|
||||
if (previous) {
|
||||
r = list_unit_one(link, previous, /* more = */ true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
previous = u;
|
||||
}
|
||||
|
||||
if (previous)
|
||||
return list_unit_one(link, previous, /* more = */ false);
|
||||
|
||||
return sd_varlink_error(link, "io.systemd.Manager.NoSuchUnit", NULL);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "sd-varlink.h"
|
||||
|
||||
#define VARLINK_ERROR_UNIT_NO_SUCH_UNIT "io.systemd.Unit.NoSuchUnit"
|
||||
|
||||
int vl_method_list_units(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
|
||||
+6
-1
@@ -14,12 +14,15 @@
|
||||
#include "unit.h"
|
||||
#include "user-util.h"
|
||||
#include "varlink.h"
|
||||
#include "varlink-io.systemd.Manager.h"
|
||||
#include "varlink-internal.h"
|
||||
#include "varlink-io.systemd.ManagedOOM.h"
|
||||
#include "varlink-io.systemd.Manager.h"
|
||||
#include "varlink-io.systemd.Unit.h"
|
||||
#include "varlink-io.systemd.UserDatabase.h"
|
||||
#include "varlink-io.systemd.service.h"
|
||||
#include "varlink-manager.h"
|
||||
#include "varlink-serialize.h"
|
||||
#include "varlink-unit.h"
|
||||
#include "varlink-util.h"
|
||||
|
||||
typedef struct LookupParameters {
|
||||
@@ -610,6 +613,7 @@ int manager_setup_varlink_server(Manager *m) {
|
||||
r = sd_varlink_server_add_interface_many(
|
||||
s,
|
||||
&vl_interface_io_systemd_Manager,
|
||||
&vl_interface_io_systemd_Unit,
|
||||
&vl_interface_io_systemd_service);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to add interfaces to varlink server: %m");
|
||||
@@ -617,6 +621,7 @@ int manager_setup_varlink_server(Manager *m) {
|
||||
r = sd_varlink_server_bind_method_many(
|
||||
s,
|
||||
"io.systemd.Manager.Describe", vl_method_describe_manager,
|
||||
"io.systemd.Unit.List", vl_method_list_units,
|
||||
"io.systemd.service.Ping", varlink_method_ping,
|
||||
"io.systemd.service.GetEnvironment", varlink_method_get_environment);
|
||||
if (r < 0)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "syslog-util.h"
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
|
||||
int json_dispatch_unbase64_iovec(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
@@ -118,6 +119,33 @@ int json_dispatch_const_user_group_name(const char *name, sd_json_variant *varia
|
||||
return 0;
|
||||
}
|
||||
|
||||
int json_dispatch_const_unit_name(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
const char **s = ASSERT_PTR(userdata), *n;
|
||||
UnitNameFlags unitname_flags;
|
||||
|
||||
if (sd_json_variant_is_null(variant)) {
|
||||
*s = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!sd_json_variant_is_string(variant))
|
||||
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
|
||||
|
||||
if (FLAGS_SET(flags, SD_JSON_STRICT))
|
||||
unitname_flags = UNIT_NAME_PLAIN;
|
||||
else if (FLAGS_SET(flags, SD_JSON_RELAX))
|
||||
unitname_flags = UNIT_NAME_ANY;
|
||||
else
|
||||
unitname_flags = UNIT_NAME_PLAIN | UNIT_NAME_INSTANCE;
|
||||
|
||||
n = sd_json_variant_string(variant);
|
||||
if (!unit_name_is_valid(n, unitname_flags))
|
||||
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid unit name.", strna(name));
|
||||
|
||||
*s = n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int json_dispatch_in_addr(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
struct in_addr *address = ASSERT_PTR(userdata);
|
||||
_cleanup_(iovec_done) struct iovec iov = {};
|
||||
|
||||
@@ -112,6 +112,7 @@ int json_dispatch_unbase64_iovec(const char *name, sd_json_variant *variant, sd_
|
||||
int json_dispatch_byte_array_iovec(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int json_dispatch_user_group_name(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int json_dispatch_const_user_group_name(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int json_dispatch_const_unit_name(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int json_dispatch_in_addr(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int json_dispatch_path(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int json_dispatch_const_path(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
|
||||
@@ -207,6 +207,7 @@ shared_sources = files(
|
||||
'varlink-io.systemd.Resolve.c',
|
||||
'varlink-io.systemd.Resolve.Monitor.c',
|
||||
'varlink-io.systemd.Udev.c',
|
||||
'varlink-io.systemd.Unit.c',
|
||||
'varlink-io.systemd.UserDatabase.c',
|
||||
'varlink-io.systemd.oom.c',
|
||||
'varlink-io.systemd.service.c',
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "build.h"
|
||||
#include "varlink-idl-common.h"
|
||||
#include "varlink-io.systemd.Unit.h"
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
Condition,
|
||||
SD_VARLINK_FIELD_COMMENT("The condition type"),
|
||||
SD_VARLINK_DEFINE_FIELD(type, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether the condition is a triggering condition"),
|
||||
SD_VARLINK_DEFINE_FIELD(trigger, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether the result of the condition is negated"),
|
||||
SD_VARLINK_DEFINE_FIELD(negate, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("The parameter passed to the condition"),
|
||||
SD_VARLINK_DEFINE_FIELD(parameter, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
UnitContext,
|
||||
SD_VARLINK_FIELD_COMMENT("The unit type"),
|
||||
SD_VARLINK_DEFINE_FIELD(Type, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("The unit ID"),
|
||||
SD_VARLINK_DEFINE_FIELD(ID, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("The aliases of this unit"),
|
||||
SD_VARLINK_DEFINE_FIELD(Names, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
|
||||
/* [Unit] Section Options
|
||||
* https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#%5BUnit%5D%20Section%20Options */
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Description="),
|
||||
SD_VARLINK_DEFINE_FIELD(Description, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Documentation="),
|
||||
SD_VARLINK_DEFINE_FIELD(Documentation, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Wants="),
|
||||
SD_VARLINK_DEFINE_FIELD(Wants, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#WantedBy="),
|
||||
SD_VARLINK_DEFINE_FIELD(WantedBy, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Requires="),
|
||||
SD_VARLINK_DEFINE_FIELD(Requires, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#WantedBy="),
|
||||
SD_VARLINK_DEFINE_FIELD(RequiredBy, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Requisite="),
|
||||
SD_VARLINK_DEFINE_FIELD(Requisite, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Requisite="),
|
||||
SD_VARLINK_DEFINE_FIELD(RequisiteOf, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#BindsTo="),
|
||||
SD_VARLINK_DEFINE_FIELD(BindsTo, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#BindsTo="),
|
||||
SD_VARLINK_DEFINE_FIELD(BoundBy, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#PartOf="),
|
||||
SD_VARLINK_DEFINE_FIELD(PartOf, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#PartOf="),
|
||||
SD_VARLINK_DEFINE_FIELD(ConsistsOf, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Upholds="),
|
||||
SD_VARLINK_DEFINE_FIELD(Upholds, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#WantedBy="),
|
||||
SD_VARLINK_DEFINE_FIELD(UpheldBy, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Conflicts="),
|
||||
SD_VARLINK_DEFINE_FIELD(Conflicts, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The ConflictedBy= dependencies of this unit"),
|
||||
SD_VARLINK_DEFINE_FIELD(ConflictedBy, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Before="),
|
||||
SD_VARLINK_DEFINE_FIELD(Before, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Before="),
|
||||
SD_VARLINK_DEFINE_FIELD(After, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#OnFailure="),
|
||||
SD_VARLINK_DEFINE_FIELD(OnFailure, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The OnFailureOf= dependencies of this unit"),
|
||||
SD_VARLINK_DEFINE_FIELD(OnFailureOf, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#OnSuccess="),
|
||||
SD_VARLINK_DEFINE_FIELD(OnSuccess, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The OnSuccessOf= dependencies of this unit"),
|
||||
SD_VARLINK_DEFINE_FIELD(OnSuccessOf, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#PropagatesReloadTo="),
|
||||
SD_VARLINK_DEFINE_FIELD(PropagatesReloadTo, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#PropagatesReloadTo="),
|
||||
SD_VARLINK_DEFINE_FIELD(ReloadPropagatedFrom, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#PropagatesStopTo="),
|
||||
SD_VARLINK_DEFINE_FIELD(PropagatesStopTo, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#PropagatesStopTo="),
|
||||
SD_VARLINK_DEFINE_FIELD(StopPropagatedFrom, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#JoinsNamespaceOf="),
|
||||
SD_VARLINK_DEFINE_FIELD(JoinsNamespaceOf, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#RequiresMountsFor="),
|
||||
SD_VARLINK_DEFINE_FIELD(RequiresMountsFor, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#WantsMountsFor="),
|
||||
SD_VARLINK_DEFINE_FIELD(WantsMountsFor, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#OnSuccessJobMode="),
|
||||
SD_VARLINK_DEFINE_FIELD(OnSuccessJobMode, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#OnSuccessJobMode="),
|
||||
SD_VARLINK_DEFINE_FIELD(OnFailureJobMode, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#IgnoreOnIsolate="),
|
||||
SD_VARLINK_DEFINE_FIELD(IgnoreOnIsolate, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#StopWhenUnneeded="),
|
||||
SD_VARLINK_DEFINE_FIELD(StopWhenUnneeded, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#RefuseManualStart="),
|
||||
SD_VARLINK_DEFINE_FIELD(RefuseManualStart, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#RefuseManualStart="),
|
||||
SD_VARLINK_DEFINE_FIELD(RefuseManualStop, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#AllowIsolate="),
|
||||
SD_VARLINK_DEFINE_FIELD(AllowIsolate, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#DefaultDependencies="),
|
||||
SD_VARLINK_DEFINE_FIELD(DefaultDependencies, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#SurviveFinalKillSignal="),
|
||||
SD_VARLINK_DEFINE_FIELD(SurviveFinalKillSignal, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#CollectMode="),
|
||||
SD_VARLINK_DEFINE_FIELD(CollectMode, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#FailureAction="),
|
||||
SD_VARLINK_DEFINE_FIELD(FailureAction, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#FailureAction="),
|
||||
SD_VARLINK_DEFINE_FIELD(SuccessAction, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#FailureActionExitStatus="),
|
||||
SD_VARLINK_DEFINE_FIELD(FailureActionExitStatus, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#FailureActionExitStatus="),
|
||||
SD_VARLINK_DEFINE_FIELD(SuccessActionExitStatus, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#JobTimeoutSec="),
|
||||
SD_VARLINK_DEFINE_FIELD(JobTimeoutUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#JobTimeoutSec="),
|
||||
SD_VARLINK_DEFINE_FIELD(JobRunningTimeoutUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#JobTimeoutAction="),
|
||||
SD_VARLINK_DEFINE_FIELD(JobTimeoutAction, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#JobTimeoutAction="),
|
||||
SD_VARLINK_DEFINE_FIELD(JobTimeoutRebootArgument, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#StartLimitIntervalSec=interval"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(StartLimit, RateLimit, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#StartLimitIntervalSec=interval"),
|
||||
SD_VARLINK_DEFINE_FIELD(StartLimitAction, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#RebootArgument="),
|
||||
SD_VARLINK_DEFINE_FIELD(RebootArgument, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#SourcePath="),
|
||||
SD_VARLINK_DEFINE_FIELD(SourcePath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
|
||||
/* Conditions and Asserts
|
||||
* https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Conditions%20and%20Asserts */
|
||||
SD_VARLINK_FIELD_COMMENT("The conditions of this unit"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(Conditions, Condition, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The asserts of this unit"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(Asserts, Condition, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
|
||||
/* Others */
|
||||
SD_VARLINK_FIELD_COMMENT("The Triggers= dependencies of this unit"),
|
||||
SD_VARLINK_DEFINE_FIELD(Triggers, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The TriggeredBy= dependencies of this unit"),
|
||||
SD_VARLINK_DEFINE_FIELD(TriggeredBy, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The SELinux context that is used to control access to the unit"),
|
||||
SD_VARLINK_DEFINE_FIELD(AccessSELinuxContext, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The unit file path this unit was read from"),
|
||||
SD_VARLINK_DEFINE_FIELD(FragmentPath, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The paths from which drop-in files were read for this unit"),
|
||||
SD_VARLINK_DEFINE_FIELD(DropInPaths, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The unit file preset for this unit"),
|
||||
SD_VARLINK_DEFINE_FIELD(UnitFilePreset, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether this unit is transient"),
|
||||
SD_VARLINK_DEFINE_FIELD(Transient, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether this unit is perpetual"),
|
||||
SD_VARLINK_DEFINE_FIELD(Perpetual, SD_VARLINK_BOOL, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
ActivationDetails,
|
||||
SD_VARLINK_FIELD_COMMENT("Trigger unit type"),
|
||||
SD_VARLINK_DEFINE_FIELD(type, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Trigger unit name"),
|
||||
SD_VARLINK_DEFINE_FIELD(name, SD_VARLINK_STRING, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
UnitRuntime,
|
||||
SD_VARLINK_FIELD_COMMENT("If not empty, the field contains the name of another unit that this unit follows in state"),
|
||||
SD_VARLINK_DEFINE_FIELD(Following, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the configuration file of this unit has been loaded"),
|
||||
SD_VARLINK_DEFINE_FIELD(LoadState, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit is currently active or not"),
|
||||
SD_VARLINK_DEFINE_FIELD(ActiveState, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit is currently frozen or not"),
|
||||
SD_VARLINK_DEFINE_FIELD(FreezerState, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflect more fine-grained state that is unit-type-specific"),
|
||||
SD_VARLINK_DEFINE_FIELD(SubState, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects the install state of the unit file"),
|
||||
SD_VARLINK_DEFINE_FIELD(UnitFileState, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the firmware first began execution"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(StateChangeTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the unit entered active state"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(ActiveEnterTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the unit exited active state"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(ActiveExitTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the unit entered inactive state"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(InactiveEnterTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the unit exited inactive state"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(InactiveExitTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit can be started or not"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanStart, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit can be stopped or not"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanStop, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit can be reloaded or not"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanReload, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit may be started in isolation mode"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanIsolate, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Returns which unit resources can be cleaned up"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanClean, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether the unit supports the freeze operation"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanFreeze, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether the unit supports live mounting"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanLiveMount, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("The job ID of the job currently scheduled or being executed for this unit, if there is any."),
|
||||
SD_VARLINK_DEFINE_FIELD(JobId, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether the configuration file this unit is loaded from (i.e. FragmentPath or SourcePath) has changed since the configuration was read and hence whether a configuration reload is recommended"),
|
||||
SD_VARLINK_DEFINE_FIELD(NeedDaemonReload, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Condition result of the last time the configured conditions of this unit were checked"),
|
||||
SD_VARLINK_DEFINE_FIELD(ConditionResult, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Assert result of the last time the configured asserts of this unit were checked"),
|
||||
SD_VARLINK_DEFINE_FIELD(AssertResult, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("The last time the configured conditions of the unit have been checked"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(ConditionTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The last time the configured asserts of the unit have been checked"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(AssertTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Current invocation ID"),
|
||||
SD_VARLINK_DEFINE_FIELD(InvocationID, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit has been marked for reload, restart, etc."),
|
||||
SD_VARLINK_DEFINE_FIELD(Markers, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Provides details about why a unit was activated"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(ActivationDetails, ActivationDetails, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("When true, logs about this unit will be at debug level regardless of other log level settings"),
|
||||
SD_VARLINK_DEFINE_FIELD(DebugInvocation, SD_VARLINK_BOOL, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_ERROR(NoSuchUnit);
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD_FULL(
|
||||
List,
|
||||
SD_VARLINK_SUPPORTS_MORE,
|
||||
SD_VARLINK_FIELD_COMMENT("If non-null the name of a unit."),
|
||||
SD_VARLINK_DEFINE_INPUT(name, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("If non-null the PID of a unit. Special value 0 means to take pid of the caller."),
|
||||
SD_VARLINK_DEFINE_INPUT_BY_TYPE(pid, ProcessId, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Configuration of the unit"),
|
||||
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(context, UnitContext, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Runtime information of the unit"),
|
||||
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(runtime, UnitRuntime, 0));
|
||||
|
||||
SD_VARLINK_DEFINE_INTERFACE(
|
||||
io_systemd_Unit,
|
||||
"io.systemd.Unit",
|
||||
SD_VARLINK_SYMBOL_COMMENT("List units"),
|
||||
&vl_method_List,
|
||||
&vl_type_RateLimit,
|
||||
SD_VARLINK_SYMBOL_COMMENT("An object to represent a unit's conditions"),
|
||||
&vl_type_Condition,
|
||||
SD_VARLINK_SYMBOL_COMMENT("An object to represent a unit's context"),
|
||||
&vl_type_UnitContext,
|
||||
SD_VARLINK_SYMBOL_COMMENT("An object to represent a unit's runtime information"),
|
||||
&vl_type_UnitRuntime,
|
||||
SD_VARLINK_SYMBOL_COMMENT("A timestamp object consisting of both CLOCK_REALTIME and CLOCK_MONOTONIC timestamps"),
|
||||
&vl_type_Timestamp,
|
||||
SD_VARLINK_SYMBOL_COMMENT("An object to represent a unit's activation details"),
|
||||
&vl_type_ActivationDetails,
|
||||
SD_VARLINK_SYMBOL_COMMENT("An object for referencing UNIX processes"),
|
||||
&vl_type_ProcessId,
|
||||
SD_VARLINK_SYMBOL_COMMENT("No matching unit found"),
|
||||
&vl_error_NoSuchUnit);
|
||||
@@ -0,0 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "sd-varlink-idl.h"
|
||||
|
||||
extern const sd_varlink_interface vl_interface_io_systemd_Unit;
|
||||
@@ -1422,4 +1422,57 @@ TEST(fd_info) {
|
||||
pidref_done(&pidref);
|
||||
}
|
||||
|
||||
TEST(unit_name) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
ASSERT_OK(sd_json_buildo(&v,
|
||||
SD_JSON_BUILD_PAIR_STRING("plain", "myservice.service"),
|
||||
SD_JSON_BUILD_PAIR_STRING("instance", "myservice@instance1.service"),
|
||||
SD_JSON_BUILD_PAIR_STRING("template", "myservice@.service")));
|
||||
|
||||
sd_json_variant_dump(v, SD_JSON_FORMAT_COLOR|SD_JSON_FORMAT_PRETTY, NULL, NULL);
|
||||
|
||||
struct {
|
||||
const char *plain, *instance, *template;
|
||||
} data = {};
|
||||
|
||||
ASSERT_OK(sd_json_dispatch(
|
||||
v,
|
||||
(const sd_json_dispatch_field[]) {
|
||||
{ "plain", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, voffsetof(data, plain), SD_JSON_STRICT },
|
||||
{ "instance", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, voffsetof(data, instance), 0 },
|
||||
{ "template", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, voffsetof(data, template), SD_JSON_RELAX },
|
||||
{},
|
||||
},
|
||||
/* flags= */ 0,
|
||||
&data));
|
||||
|
||||
ASSERT_STREQ(data.plain, "myservice.service");
|
||||
ASSERT_STREQ(data.instance, "myservice@instance1.service");
|
||||
ASSERT_STREQ(data.template, "myservice@.service");
|
||||
|
||||
ASSERT_ERROR(sd_json_dispatch(
|
||||
v,
|
||||
(const sd_json_dispatch_field[]) {
|
||||
{ "plain", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, voffsetof(data, plain), SD_JSON_RELAX },
|
||||
/* instance value is not allowed with SD_JSON_STRICT */
|
||||
{ "instance", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, voffsetof(data, instance), SD_JSON_STRICT },
|
||||
{ "template", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, voffsetof(data, template), SD_JSON_RELAX },
|
||||
{},
|
||||
},
|
||||
/* flags= */ 0,
|
||||
&data), EINVAL);
|
||||
|
||||
ASSERT_ERROR(sd_json_dispatch(
|
||||
v,
|
||||
(const sd_json_dispatch_field[]) {
|
||||
{ "plain", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, voffsetof(data, plain), SD_JSON_RELAX },
|
||||
{ "instance", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, voffsetof(data, instance), SD_JSON_RELAX },
|
||||
/* template value is not allowed by default */
|
||||
{ "template", SD_JSON_VARIANT_STRING, json_dispatch_const_unit_name, voffsetof(data, template), 0 },
|
||||
{},
|
||||
},
|
||||
/* flags= */ 0,
|
||||
&data), EINVAL);
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_DEBUG);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "varlink-io.systemd.Resolve.h"
|
||||
#include "varlink-io.systemd.Resolve.Monitor.h"
|
||||
#include "varlink-io.systemd.Udev.h"
|
||||
#include "varlink-io.systemd.Unit.h"
|
||||
#include "varlink-io.systemd.UserDatabase.h"
|
||||
#include "varlink-io.systemd.oom.h"
|
||||
#include "varlink-io.systemd.service.h"
|
||||
@@ -211,6 +212,8 @@ TEST(parse_format) {
|
||||
print_separator();
|
||||
test_parse_format_one(&vl_interface_io_systemd_FactoryReset);
|
||||
print_separator();
|
||||
test_parse_format_one(&vl_interface_io_systemd_Unit);
|
||||
print_separator();
|
||||
test_parse_format_one(&vl_interface_xyz_test);
|
||||
}
|
||||
|
||||
|
||||
@@ -172,11 +172,25 @@ varlinkctl info /run/systemd/io.systemd.Manager
|
||||
varlinkctl introspect /run/systemd/io.systemd.Manager io.systemd.Manager
|
||||
varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Manager.Describe '{}'
|
||||
|
||||
# test io.systemd.Unit
|
||||
varlinkctl info /run/systemd/io.systemd.Manager
|
||||
varlinkctl introspect /run/systemd/io.systemd.Manager io.systemd.Unit
|
||||
varlinkctl --more call /run/systemd/io.systemd.Manager io.systemd.Unit.List '{}'
|
||||
varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List '{"name": "multi-user.target"}'
|
||||
varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List '{"pid": {"pid": 0}}'
|
||||
(! varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List '{"name": ""}')
|
||||
(! varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List '{"name": "non-existent.service"}')
|
||||
(! varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List '{"pid": {"pid": -1}}' )
|
||||
|
||||
# test io.systemd.Manager in user manager
|
||||
testuser_uid=$(id -u testuser)
|
||||
systemd-run --wait --pipe --user --machine testuser@ \
|
||||
varlinkctl info /run/user/"$testuser_uid"/systemd/io.systemd.Manager
|
||||
varlinkctl info "/run/user/$testuser_uid/systemd/io.systemd.Manager"
|
||||
systemd-run --wait --pipe --user --machine testuser@ \
|
||||
varlinkctl introspect /run/user/"$testuser_uid"/systemd/io.systemd.Manager
|
||||
varlinkctl introspect "/run/user/$testuser_uid/systemd/io.systemd.Manager"
|
||||
systemd-run --wait --pipe --user --machine testuser@ \
|
||||
varlinkctl call /run/user/"$testuser_uid"/systemd/io.systemd.Manager io.systemd.Manager.Describe '{}'
|
||||
varlinkctl call "/run/user/$testuser_uid/systemd/io.systemd.Manager" io.systemd.Manager.Describe '{}'
|
||||
|
||||
# test io.systemd.Unit in user manager
|
||||
systemd-run --wait --pipe --user --machine testuser@ \
|
||||
varlinkctl --more call "/run/user/$testuser_uid/systemd/io.systemd.Manager" io.systemd.Unit.List '{}'
|
||||
|
||||
Reference in New Issue
Block a user