xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Ian Campbell <ian.campbell@citrix.com>
To: xen-devel@lists.xen.org
Cc: waldi@debian.org, ian.jackson@citrix.com
Subject: [PATCH] xl: make "xl list -l" proper JSON
Date: Wed, 15 Aug 2012 17:03:34 +0100	[thread overview]
Message-ID: <add1552b607e014717f9.1345046614@cosworth.uk.xensource.com> (raw)

# HG changeset patch
# User Ian Campbell <ian.campbell@citrix.com>
# Date 1345046605 -3600
# Node ID add1552b607e014717f9e48bff61606bc62ff269
# Parent  7cec0543f67cefe3755bbad0c2262fa2e820d746
xl: make "xl list -l" proper JSON

Bastian Blank reports that the output of this command is just multiple
JSON objects concatenated and is not a single properly formed JSON
object.

Fix this by wrapping in an array. This turned out to be a bit more
intrusive than I was expecting due to the requirement to keep
supporting the SXP output mode.

Python's json module is happy to parse the result...

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

diff -r 7cec0543f67c -r add1552b607e tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Wed Aug 15 16:58:21 2012 +0100
+++ b/tools/libxl/xl_cmdimpl.c	Wed Aug 15 17:03:25 2012 +0100
@@ -320,23 +320,10 @@ static void dolog(const char *file, int 
     free(s);
 }
 
-static void printf_info(enum output_format output_format,
-                        int domid,
-                        libxl_domain_config *d_config)
-{
-    if (output_format == OUTPUT_FORMAT_SXP)
-        return printf_info_sexp(domid, d_config);
-
-    const char *buf;
-    libxl_yajl_length len = 0;
+static yajl_gen_status printf_info_one_json(yajl_gen hand, int domid,
+                                            libxl_domain_config *d_config)
+{
     yajl_gen_status s;
-    yajl_gen hand;
-
-    hand = libxl_yajl_gen_alloc(NULL);
-    if (!hand) {
-        fprintf(stderr, "unable to allocate JSON generator\n");
-        return;
-    }
 
     s = yajl_gen_map_open(hand);
     if (s != yajl_gen_status_ok)
@@ -365,6 +352,31 @@ static void printf_info(enum output_form
     if (s != yajl_gen_status_ok)
         goto out;
 
+out:
+    return s;
+}
+static void printf_info(enum output_format output_format,
+                        int domid,
+                        libxl_domain_config *d_config)
+{
+    if (output_format == OUTPUT_FORMAT_SXP)
+        return printf_info_sexp(domid, d_config);
+
+    const char *buf;
+    libxl_yajl_length len = 0;
+    yajl_gen_status s;
+    yajl_gen hand;
+
+    hand = libxl_yajl_gen_alloc(NULL);
+    if (!hand) {
+        fprintf(stderr, "unable to allocate JSON generator\n");
+        return;
+    }
+
+    s = printf_info_one_json(hand, domid, d_config);
+    if (s != yajl_gen_status_ok)
+        goto out;
+
     s = yajl_gen_get_buf(hand, (const unsigned char **)&buf, &len);
     if (s != yajl_gen_status_ok)
         goto out;
@@ -2679,6 +2691,24 @@ static void list_domains_details(const l
     uint8_t *data;
     int i, len, rc;
 
+    yajl_gen hand;
+    yajl_gen_status s;
+    const char *buf;
+    libxl_yajl_length yajl_len = 0;
+
+    if (default_output_format == OUTPUT_FORMAT_JSON) {
+        hand = libxl_yajl_gen_alloc(NULL);
+        if (!hand) {
+            fprintf(stderr, "unable to allocate JSON generator\n");
+            return;
+        }
+
+        s = yajl_gen_array_open(hand);
+        if (s != yajl_gen_status_ok)
+            goto out;
+    } else
+        s = yajl_gen_status_ok;
+
     for (i = 0; i < nb_domain; i++) {
         /* no detailed info available on dom0 */
         if (info[i].domid == 0)
@@ -2689,10 +2719,35 @@ static void list_domains_details(const l
         CHK_ERRNO(asprintf(&config_source, "<domid %d data>", info[i].domid));
         libxl_domain_config_init(&d_config);
         parse_config_data(config_source, (char *)data, len, &d_config, NULL);
-        printf_info(default_output_format, info[i].domid, &d_config);
+        if (default_output_format == OUTPUT_FORMAT_SXP)
+            printf_info_sexp(domid, &d_config);
+        else
+            s = printf_info_one_json(hand, info[i].domid, &d_config);
         libxl_domain_config_dispose(&d_config);
         free(data);
         free(config_source);
+        if (s != yajl_gen_status_ok)
+            goto out;
+    }
+
+    if (default_output_format == OUTPUT_FORMAT_JSON) {
+        s = yajl_gen_array_close(hand);
+        if (s != yajl_gen_status_ok)
+            goto out;
+
+        s = yajl_gen_get_buf(hand, (const unsigned char **)&buf, &yajl_len);
+        if (s != yajl_gen_status_ok)
+            goto out;
+
+        puts(buf);
+    }
+
+out:
+    if (default_output_format == OUTPUT_FORMAT_JSON) {
+        yajl_gen_free(hand);
+        if (s != yajl_gen_status_ok)
+            fprintf(stderr,
+                    "unable to format domain config as JSON (YAJL:%d)\n", s);
     }
 }

             reply	other threads:[~2012-08-15 16:03 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-15 16:03 Ian Campbell [this message]
2012-08-23 18:13 ` [PATCH] xl: make "xl list -l" proper JSON Ian Jackson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=add1552b607e014717f9.1345046614@cosworth.uk.xensource.com \
    --to=ian.campbell@citrix.com \
    --cc=ian.jackson@citrix.com \
    --cc=waldi@debian.org \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).