6ae9ed
From eafefeba1bb510d26e37b9d7d9f3e84f9a41e462 Mon Sep 17 00:00:00 2001
6ae9ed
Message-Id: <eafefeba1bb510d26e37b9d7d9f3e84f9a41e462@dist-git>
6ae9ed
From: Peter Krempa <pkrempa@redhat.com>
6ae9ed
Date: Tue, 2 Aug 2016 13:41:42 +0200
6ae9ed
Subject: [PATCH] util: qemu: Add wrapper for JSON -> commandline conversion
6ae9ed
6ae9ed
Refactor the command line generator by adding a wrapper (with
6ae9ed
documentation) that will handle the outermost object iteration.
6ae9ed
6ae9ed
This patch also renames the functions and tweaks the error message for
6ae9ed
nested arrays to be more universal.
6ae9ed
6ae9ed
The new function is then reused to simplify qemucommandutiltest.
6ae9ed
6ae9ed
(cherry picked from commit f0276c34891cb17c4b20ad9956267d6249d24cfa)
6ae9ed
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1134878 [JSON backing]
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1247521 [gluster multi-host]
6ae9ed
---
6ae9ed
 src/libvirt_private.syms    |  1 +
6ae9ed
 src/util/virqemu.c          | 45 +++++++++++++++++++++++++++++++++------------
6ae9ed
 src/util/virqemu.h          |  3 +++
6ae9ed
 tests/qemucommandutiltest.c | 22 ++++++++++++++--------
6ae9ed
 4 files changed, 51 insertions(+), 20 deletions(-)
6ae9ed
6ae9ed
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
6ae9ed
index 3e4b2e7..70e40be 100644
6ae9ed
--- a/src/libvirt_private.syms
6ae9ed
+++ b/src/libvirt_private.syms
6ae9ed
@@ -2193,6 +2193,7 @@ virProcessWait;
6ae9ed
 
6ae9ed
 # util/virqemu.h
6ae9ed
 virQEMUBuildBufferEscapeComma;
6ae9ed
+virQEMUBuildCommandLineJSON;
6ae9ed
 virQEMUBuildLuksOpts;
6ae9ed
 virQEMUBuildObjectCommandlineFromJSON;
6ae9ed
 
6ae9ed
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
6ae9ed
index 7d181e1..a5d5385 100644
6ae9ed
--- a/src/util/virqemu.c
6ae9ed
+++ b/src/util/virqemu.c
6ae9ed
@@ -33,10 +33,10 @@ VIR_LOG_INIT("util.qemu");
6ae9ed
 
6ae9ed
 
6ae9ed
 static int
6ae9ed
-virQEMUBuildObjectCommandLinePropsInternal(const char *key,
6ae9ed
-                                           const virJSONValue *value,
6ae9ed
-                                           virBufferPtr buf,
6ae9ed
-                                           bool nested)
6ae9ed
+virQEMUBuildCommandLineJSONRecurse(const char *key,
6ae9ed
+                                   const virJSONValue *value,
6ae9ed
+                                   virBufferPtr buf,
6ae9ed
+                                   bool nested)
6ae9ed
 {
6ae9ed
     virJSONValuePtr elem;
6ae9ed
     virBitmapPtr bitmap = NULL;
6ae9ed
@@ -64,7 +64,8 @@ virQEMUBuildObjectCommandLinePropsInternal(const char *key,
6ae9ed
     case VIR_JSON_TYPE_ARRAY:
6ae9ed
         if (nested) {
6ae9ed
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
6ae9ed
-                           _("nested -object property arrays are not supported"));
6ae9ed
+                           _("nested JSON array to commandline conversion is "
6ae9ed
+                             "not supported"));
6ae9ed
             return -1;
6ae9ed
         }
6ae9ed
 
6ae9ed
@@ -87,8 +88,7 @@ virQEMUBuildObjectCommandLinePropsInternal(const char *key,
6ae9ed
                 elem = virJSONValueArrayGet((virJSONValuePtr)value, i);
6ae9ed
 
6ae9ed
                 /* recurse to avoid duplicating code */
6ae9ed
-                if (virQEMUBuildObjectCommandLinePropsInternal(key, elem, buf,
6ae9ed
-                                                               true) < 0)
6ae9ed
+                if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf, true) < 0)
6ae9ed
                     return -1;
6ae9ed
             }
6ae9ed
         }
6ae9ed
@@ -108,11 +108,34 @@ virQEMUBuildObjectCommandLinePropsInternal(const char *key,
6ae9ed
 
6ae9ed
 
6ae9ed
 static int
6ae9ed
-virQEMUBuildObjectCommandLineProps(const char *key,
6ae9ed
+virQEMUBuildCommandLineJSONIterate(const char *key,
6ae9ed
                                    const virJSONValue *value,
6ae9ed
                                    void *opaque)
6ae9ed
 {
6ae9ed
-    return virQEMUBuildObjectCommandLinePropsInternal(key, value, opaque, false);
6ae9ed
+    return virQEMUBuildCommandLineJSONRecurse(key, value, opaque, false);
6ae9ed
+}
6ae9ed
+
6ae9ed
+
6ae9ed
+/**
6ae9ed
+ * virQEMUBuildCommandLineJSON:
6ae9ed
+ * @value: json object containing the value
6ae9ed
+ * @buf: otuput buffer
6ae9ed
+ *
6ae9ed
+ * Formats JSON value object into command line parameters suitable for use with
6ae9ed
+ * qemu.
6ae9ed
+ *
6ae9ed
+ * Returns 0 on success -1 on error.
6ae9ed
+ */
6ae9ed
+int
6ae9ed
+virQEMUBuildCommandLineJSON(const virJSONValue *value,
6ae9ed
+                            virBufferPtr buf)
6ae9ed
+{
6ae9ed
+    if (virJSONValueObjectForeachKeyValue(value,
6ae9ed
+                                          virQEMUBuildCommandLineJSONIterate,
6ae9ed
+                                          buf) < 0)
6ae9ed
+        return -1;
6ae9ed
+
6ae9ed
+    return 0;
6ae9ed
 }
6ae9ed
 
6ae9ed
 
6ae9ed
@@ -126,9 +149,7 @@ virQEMUBuildObjectCommandlineFromJSON(const char *type,
6ae9ed
 
6ae9ed
     virBufferAsprintf(&buf, "%s,id=%s", type, alias);
6ae9ed
 
6ae9ed
-    if (virJSONValueObjectForeachKeyValue(props,
6ae9ed
-                                          virQEMUBuildObjectCommandLineProps,
6ae9ed
-                                          &buf) < 0)
6ae9ed
+    if (virQEMUBuildCommandLineJSON(props, &buf) < 0)
6ae9ed
         goto cleanup;
6ae9ed
 
6ae9ed
     if (virBufferCheckError(&buf) < 0)
6ae9ed
diff --git a/src/util/virqemu.h b/src/util/virqemu.h
6ae9ed
index eb75d1b..efc6c42 100644
6ae9ed
--- a/src/util/virqemu.h
6ae9ed
+++ b/src/util/virqemu.h
6ae9ed
@@ -29,6 +29,9 @@
6ae9ed
 # include "virjson.h"
6ae9ed
 # include "virstorageencryption.h"
6ae9ed
 
6ae9ed
+int virQEMUBuildCommandLineJSON(const virJSONValue *value,
6ae9ed
+                                virBufferPtr buf);
6ae9ed
+
6ae9ed
 char *virQEMUBuildObjectCommandlineFromJSON(const char *type,
6ae9ed
                                             const char *alias,
6ae9ed
                                             virJSONValuePtr props);
6ae9ed
diff --git a/tests/qemucommandutiltest.c b/tests/qemucommandutiltest.c
6ae9ed
index c02d1db..21fef1c 100644
6ae9ed
--- a/tests/qemucommandutiltest.c
6ae9ed
+++ b/tests/qemucommandutiltest.c
6ae9ed
@@ -33,11 +33,12 @@ typedef struct
6ae9ed
 } testQemuCommandBuildObjectFromJSONData;
6ae9ed
 
6ae9ed
 static int
6ae9ed
-testQemuCommandBuildObjectFromJSON(const void *opaque)
6ae9ed
+testQemuCommandBuildFromJSON(const void *opaque)
6ae9ed
 {
6ae9ed
     const testQemuCommandBuildObjectFromJSONData *data = opaque;
6ae9ed
     virJSONValuePtr val = NULL;
6ae9ed
     char *expect = NULL;
6ae9ed
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
6ae9ed
     char *result = NULL;
6ae9ed
     int ret = -1;
6ae9ed
 
6ae9ed
@@ -46,13 +47,18 @@ testQemuCommandBuildObjectFromJSON(const void *opaque)
6ae9ed
         return -1;
6ae9ed
     }
6ae9ed
 
6ae9ed
-    if (virAsprintf(&expect, "testobject,id=testalias%s%s",
6ae9ed
-                    data->expectprops ? "," : "",
6ae9ed
-                    data->expectprops ? data->expectprops : "") < 0)
6ae9ed
+    if (data->expectprops &&
6ae9ed
+        virAsprintf(&expect, ",%s", data->expectprops) < 0)
6ae9ed
         return -1;
6ae9ed
 
6ae9ed
-    result = virQEMUBuildObjectCommandlineFromJSON("testobject",
6ae9ed
-                                                   "testalias", val);
6ae9ed
+    if (virQEMUBuildCommandLineJSON(val, &buf) < 0) {
6ae9ed
+        fprintf(stderr,
6ae9ed
+                "\nvirQEMUBuildCommandlineJSON failed process JSON:\n%s\n",
6ae9ed
+                data->props);
6ae9ed
+        goto cleanup;
6ae9ed
+    }
6ae9ed
+
6ae9ed
+    result = virBufferContentAndReset(&buf;;
6ae9ed
 
6ae9ed
     if (STRNEQ_NULLABLE(expect, result)) {
6ae9ed
         fprintf(stderr, "\nFailed to create object string. "
6ae9ed
@@ -80,14 +86,14 @@ mymain(void)
6ae9ed
     return EXIT_AM_SKIP;
6ae9ed
 #endif
6ae9ed
 
6ae9ed
-    virTestCounterReset("testQemuCommandBuildObjectFromJSON");
6ae9ed
+    virTestCounterReset("testQemuCommandBuildFromJSON");
6ae9ed
 
6ae9ed
 #define DO_TEST_COMMAND_OBJECT_FROM_JSON(PROPS, EXPECT)             \
6ae9ed
     do {                                                            \
6ae9ed
         data1.props = PROPS;                                        \
6ae9ed
         data1.expectprops = EXPECT;                                 \
6ae9ed
         if (virTestRun(virTestCounterNext(),                        \
6ae9ed
-                       testQemuCommandBuildObjectFromJSON,          \
6ae9ed
+                       testQemuCommandBuildFromJSON,                \
6ae9ed
                        &data1) < 0)                                 \
6ae9ed
             ret = -1;                                               \
6ae9ed
      } while (0)
6ae9ed
-- 
6ae9ed
2.9.2
6ae9ed