From: Joris Hartog Date: Wed, 1 Dec 2021 14:06:29 +0000 (+0100) Subject: systemctl: support JSON output for "show-environment" X-Git-Tag: v250-rc1~73 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5ef599b324efbcb7af317c102b59c662df068500;p=thirdparty%2Fsystemd.git systemctl: support JSON output for "show-environment" This commit adds a function which converts a bus message containing the environment variables to a JSON object and uses this function to support JSON formatted output for the "systemctl show-environment" command. Fixes #21348 --- diff --git a/src/systemctl/systemctl-set-environment.c b/src/systemctl/systemctl-set-environment.c index 4c8d1acba13..aab0fe5fd02 100644 --- a/src/systemctl/systemctl-set-environment.c +++ b/src/systemctl/systemctl-set-environment.c @@ -8,6 +8,40 @@ #include "systemctl-util.h" #include "systemctl.h" +static int json_transform_message(sd_bus_message *m, JsonVariant **ret) { + _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; + char *text; + int r; + + assert(m); + assert(ret); + + while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &text)) > 0) { + _cleanup_(json_variant_unrefp) JsonVariant *w = NULL; + + char *sep = strchr(text, '='); + if (!sep) + return log_error_errno(SYNTHETIC_ERRNO(EUCLEAN), + "Invalid environment block"); + + *sep++ = '\0'; + + r = json_build(&w, JSON_BUILD_OBJECT(JSON_BUILD_PAIR(text, JSON_BUILD_STRING(sep)))); + if (r < 0) + return r; + + r = json_variant_merge(&v, w); + if (r < 0) + return r; + } + if (r < 0) + return bus_log_parse_error(r); + + *ret = TAKE_PTR(v); + + return r; +} + static int print_variable(const char *s) { const char *sep; _cleanup_free_ char *esc = NULL; @@ -46,13 +80,24 @@ int show_environment(int argc, char *argv[], void *userdata) { if (r < 0) return bus_log_parse_error(r); - while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0) { - r = print_variable(text); + if (OUTPUT_MODE_IS_JSON(arg_output)) { + _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; + JsonFormatFlags flags = output_mode_to_json_format_flags(arg_output); + + r = json_transform_message(reply, &v); if (r < 0) return r; + + json_variant_dump(v, flags, stdout, NULL); + } else { + while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0) { + r = print_variable(text); + if (r < 0) + return r; + } + if (r < 0) + return bus_log_parse_error(r); } - if (r < 0) - return bus_log_parse_error(r); r = sd_bus_message_exit_container(reply); if (r < 0) diff --git a/test/units/testsuite-26.sh b/test/units/testsuite-26.sh index 7df0d1dc8f3..ad084153174 100755 --- a/test/units/testsuite-26.sh +++ b/test/units/testsuite-26.sh @@ -19,6 +19,9 @@ systemctl daemon-reload systemctl show-environment | grep -q '^PATH=.*testaddition$' systemctl show-environment | grep -q '^FOO=BAR$' +# Check that JSON output is supported +systemctl show-environment --output=json | grep -q '^{.*"FOO":"BAR".*}$' + # Drop both systemctl unset-environment FOO PATH