Blob Blame History Raw
From eafefeba1bb510d26e37b9d7d9f3e84f9a41e462 Mon Sep 17 00:00:00 2001
Message-Id: <eafefeba1bb510d26e37b9d7d9f3e84f9a41e462@dist-git>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 2 Aug 2016 13:41:42 +0200
Subject: [PATCH] util: qemu: Add wrapper for JSON -> commandline conversion

Refactor the command line generator by adding a wrapper (with
documentation) that will handle the outermost object iteration.

This patch also renames the functions and tweaks the error message for
nested arrays to be more universal.

The new function is then reused to simplify qemucommandutiltest.

(cherry picked from commit f0276c34891cb17c4b20ad9956267d6249d24cfa)

https://bugzilla.redhat.com/show_bug.cgi?id=1134878 [JSON backing]
https://bugzilla.redhat.com/show_bug.cgi?id=1247521 [gluster multi-host]
---
 src/libvirt_private.syms    |  1 +
 src/util/virqemu.c          | 45 +++++++++++++++++++++++++++++++++------------
 src/util/virqemu.h          |  3 +++
 tests/qemucommandutiltest.c | 22 ++++++++++++++--------
 4 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3e4b2e7..70e40be 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2193,6 +2193,7 @@ virProcessWait;
 
 # util/virqemu.h
 virQEMUBuildBufferEscapeComma;
+virQEMUBuildCommandLineJSON;
 virQEMUBuildLuksOpts;
 virQEMUBuildObjectCommandlineFromJSON;
 
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 7d181e1..a5d5385 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -33,10 +33,10 @@ VIR_LOG_INIT("util.qemu");
 
 
 static int
-virQEMUBuildObjectCommandLinePropsInternal(const char *key,
-                                           const virJSONValue *value,
-                                           virBufferPtr buf,
-                                           bool nested)
+virQEMUBuildCommandLineJSONRecurse(const char *key,
+                                   const virJSONValue *value,
+                                   virBufferPtr buf,
+                                   bool nested)
 {
     virJSONValuePtr elem;
     virBitmapPtr bitmap = NULL;
@@ -64,7 +64,8 @@ virQEMUBuildObjectCommandLinePropsInternal(const char *key,
     case VIR_JSON_TYPE_ARRAY:
         if (nested) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("nested -object property arrays are not supported"));
+                           _("nested JSON array to commandline conversion is "
+                             "not supported"));
             return -1;
         }
 
@@ -87,8 +88,7 @@ virQEMUBuildObjectCommandLinePropsInternal(const char *key,
                 elem = virJSONValueArrayGet((virJSONValuePtr)value, i);
 
                 /* recurse to avoid duplicating code */
-                if (virQEMUBuildObjectCommandLinePropsInternal(key, elem, buf,
-                                                               true) < 0)
+                if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf, true) < 0)
                     return -1;
             }
         }
@@ -108,11 +108,34 @@ virQEMUBuildObjectCommandLinePropsInternal(const char *key,
 
 
 static int
-virQEMUBuildObjectCommandLineProps(const char *key,
+virQEMUBuildCommandLineJSONIterate(const char *key,
                                    const virJSONValue *value,
                                    void *opaque)
 {
-    return virQEMUBuildObjectCommandLinePropsInternal(key, value, opaque, false);
+    return virQEMUBuildCommandLineJSONRecurse(key, value, opaque, false);
+}
+
+
+/**
+ * virQEMUBuildCommandLineJSON:
+ * @value: json object containing the value
+ * @buf: otuput buffer
+ *
+ * Formats JSON value object into command line parameters suitable for use with
+ * qemu.
+ *
+ * Returns 0 on success -1 on error.
+ */
+int
+virQEMUBuildCommandLineJSON(const virJSONValue *value,
+                            virBufferPtr buf)
+{
+    if (virJSONValueObjectForeachKeyValue(value,
+                                          virQEMUBuildCommandLineJSONIterate,
+                                          buf) < 0)
+        return -1;
+
+    return 0;
 }
 
 
@@ -126,9 +149,7 @@ virQEMUBuildObjectCommandlineFromJSON(const char *type,
 
     virBufferAsprintf(&buf, "%s,id=%s", type, alias);
 
-    if (virJSONValueObjectForeachKeyValue(props,
-                                          virQEMUBuildObjectCommandLineProps,
-                                          &buf) < 0)
+    if (virQEMUBuildCommandLineJSON(props, &buf) < 0)
         goto cleanup;
 
     if (virBufferCheckError(&buf) < 0)
diff --git a/src/util/virqemu.h b/src/util/virqemu.h
index eb75d1b..efc6c42 100644
--- a/src/util/virqemu.h
+++ b/src/util/virqemu.h
@@ -29,6 +29,9 @@
 # include "virjson.h"
 # include "virstorageencryption.h"
 
+int virQEMUBuildCommandLineJSON(const virJSONValue *value,
+                                virBufferPtr buf);
+
 char *virQEMUBuildObjectCommandlineFromJSON(const char *type,
                                             const char *alias,
                                             virJSONValuePtr props);
diff --git a/tests/qemucommandutiltest.c b/tests/qemucommandutiltest.c
index c02d1db..21fef1c 100644
--- a/tests/qemucommandutiltest.c
+++ b/tests/qemucommandutiltest.c
@@ -33,11 +33,12 @@ typedef struct
 } testQemuCommandBuildObjectFromJSONData;
 
 static int
-testQemuCommandBuildObjectFromJSON(const void *opaque)
+testQemuCommandBuildFromJSON(const void *opaque)
 {
     const testQemuCommandBuildObjectFromJSONData *data = opaque;
     virJSONValuePtr val = NULL;
     char *expect = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     char *result = NULL;
     int ret = -1;
 
@@ -46,13 +47,18 @@ testQemuCommandBuildObjectFromJSON(const void *opaque)
         return -1;
     }
 
-    if (virAsprintf(&expect, "testobject,id=testalias%s%s",
-                    data->expectprops ? "," : "",
-                    data->expectprops ? data->expectprops : "") < 0)
+    if (data->expectprops &&
+        virAsprintf(&expect, ",%s", data->expectprops) < 0)
         return -1;
 
-    result = virQEMUBuildObjectCommandlineFromJSON("testobject",
-                                                   "testalias", val);
+    if (virQEMUBuildCommandLineJSON(val, &buf) < 0) {
+        fprintf(stderr,
+                "\nvirQEMUBuildCommandlineJSON failed process JSON:\n%s\n",
+                data->props);
+        goto cleanup;
+    }
+
+    result = virBufferContentAndReset(&buf);
 
     if (STRNEQ_NULLABLE(expect, result)) {
         fprintf(stderr, "\nFailed to create object string. "
@@ -80,14 +86,14 @@ mymain(void)
     return EXIT_AM_SKIP;
 #endif
 
-    virTestCounterReset("testQemuCommandBuildObjectFromJSON");
+    virTestCounterReset("testQemuCommandBuildFromJSON");
 
 #define DO_TEST_COMMAND_OBJECT_FROM_JSON(PROPS, EXPECT)             \
     do {                                                            \
         data1.props = PROPS;                                        \
         data1.expectprops = EXPECT;                                 \
         if (virTestRun(virTestCounterNext(),                        \
-                       testQemuCommandBuildObjectFromJSON,          \
+                       testQemuCommandBuildFromJSON,                \
                        &data1) < 0)                                 \
             ret = -1;                                               \
      } while (0)
-- 
2.9.2