]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl: support JSON output for "show-environment"
authorJoris Hartog <jorishartog@hotmail.com>
Wed, 1 Dec 2021 14:06:29 +0000 (15:06 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 6 Dec 2021 10:40:52 +0000 (11:40 +0100)
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

src/systemctl/systemctl-set-environment.c
test/units/testsuite-26.sh

index 4c8d1acba13ddb75d1568fca54759270dfec2976..aab0fe5fd027e98bf684e33a93c6f050726acf28 100644 (file)
@@ -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)
index 7df0d1dc8f3bfab4ff4c37c888f0c9f8a44733e7..ad084153174ee470815a340e2de05000c672f632 100755 (executable)
@@ -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