|
|
6ae9ed |
From 6360c62ec2a0ccfb66346daa3566930111685598 Mon Sep 17 00:00:00 2001
|
|
|
6ae9ed |
Message-Id: <6360c62ec2a0ccfb66346daa3566930111685598@dist-git>
|
|
|
6ae9ed |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
6ae9ed |
Date: Tue, 2 Aug 2016 13:41:44 +0200
|
|
|
6ae9ed |
Subject: [PATCH] util: qemu: Allow nested objects in JSON -> commandline
|
|
|
6ae9ed |
generator
|
|
|
6ae9ed |
|
|
|
6ae9ed |
Move the iterator of objects to the recursive function so that nested
|
|
|
6ae9ed |
objects are supported by flattening the structure with '.' delimiters.
|
|
|
6ae9ed |
|
|
|
6ae9ed |
(cherry picked from commit cd86d6f4656d01894141840531d61595e40e4682)
|
|
|
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/util/virqemu.c | 70 ++++++++++++++++++++++++++++++++++-----------
|
|
|
6ae9ed |
tests/qemucommandutiltest.c | 8 ++++++
|
|
|
6ae9ed |
2 files changed, 61 insertions(+), 17 deletions(-)
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
|
|
|
6ae9ed |
index 99c14c2..df665ad 100644
|
|
|
6ae9ed |
--- a/src/util/virqemu.c
|
|
|
6ae9ed |
+++ b/src/util/virqemu.c
|
|
|
6ae9ed |
@@ -26,11 +26,49 @@
|
|
|
6ae9ed |
#include "virerror.h"
|
|
|
6ae9ed |
#include "virlog.h"
|
|
|
6ae9ed |
#include "virqemu.h"
|
|
|
6ae9ed |
+#include "virstring.h"
|
|
|
6ae9ed |
+#include "viralloc.h"
|
|
|
6ae9ed |
|
|
|
6ae9ed |
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
6ae9ed |
|
|
|
6ae9ed |
VIR_LOG_INIT("util.qemu");
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+struct virQEMUCommandLineJSONIteratorData {
|
|
|
6ae9ed |
+ const char *prefix;
|
|
|
6ae9ed |
+ virBufferPtr buf;
|
|
|
6ae9ed |
+};
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+static int
|
|
|
6ae9ed |
+virQEMUBuildCommandLineJSONRecurse(const char *key,
|
|
|
6ae9ed |
+ const virJSONValue *value,
|
|
|
6ae9ed |
+ virBufferPtr buf,
|
|
|
6ae9ed |
+ bool nested);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+/* internal iterator to handle nested object formatting */
|
|
|
6ae9ed |
+static int
|
|
|
6ae9ed |
+virQEMUBuildCommandLineJSONIterate(const char *key,
|
|
|
6ae9ed |
+ const virJSONValue *value,
|
|
|
6ae9ed |
+ void *opaque)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ struct virQEMUCommandLineJSONIteratorData *data = opaque;
|
|
|
6ae9ed |
+ char *tmpkey = NULL;
|
|
|
6ae9ed |
+ int ret = -1;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (data->prefix) {
|
|
|
6ae9ed |
+ if (virAsprintf(&tmpkey, "%s.%s", data->prefix, key) < 0)
|
|
|
6ae9ed |
+ return -1;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ ret = virQEMUBuildCommandLineJSONRecurse(tmpkey, value, data->buf, false);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ VIR_FREE(tmpkey);
|
|
|
6ae9ed |
+ } else {
|
|
|
6ae9ed |
+ ret = virQEMUBuildCommandLineJSONRecurse(key, value, data->buf, false);
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ return ret;
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
|
|
|
6ae9ed |
static int
|
|
|
6ae9ed |
virQEMUBuildCommandLineJSONRecurse(const char *key,
|
|
|
6ae9ed |
@@ -38,12 +76,19 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
|
|
|
6ae9ed |
virBufferPtr buf,
|
|
|
6ae9ed |
bool nested)
|
|
|
6ae9ed |
{
|
|
|
6ae9ed |
+ struct virQEMUCommandLineJSONIteratorData data = { key, buf };
|
|
|
6ae9ed |
virJSONValuePtr elem;
|
|
|
6ae9ed |
virBitmapPtr bitmap = NULL;
|
|
|
6ae9ed |
ssize_t pos = -1;
|
|
|
6ae9ed |
ssize_t end;
|
|
|
6ae9ed |
size_t i;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+ if (!key && value->type != VIR_JSON_TYPE_OBJECT) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
6ae9ed |
+ _("only JSON objects can be top level"));
|
|
|
6ae9ed |
+ return -1;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
switch ((virJSONType) value->type) {
|
|
|
6ae9ed |
case VIR_JSON_TYPE_STRING:
|
|
|
6ae9ed |
virBufferAsprintf(buf, ",%s=", key);
|
|
|
6ae9ed |
@@ -96,10 +141,15 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
|
|
|
6ae9ed |
break;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
case VIR_JSON_TYPE_OBJECT:
|
|
|
6ae9ed |
+ if (virJSONValueObjectForeachKeyValue(value,
|
|
|
6ae9ed |
+ virQEMUBuildCommandLineJSONIterate,
|
|
|
6ae9ed |
+ &data) < 0)
|
|
|
6ae9ed |
+ return -1;
|
|
|
6ae9ed |
+ break;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
case VIR_JSON_TYPE_NULL:
|
|
|
6ae9ed |
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
6ae9ed |
- _("NULL and OBJECT JSON types can't be converted to "
|
|
|
6ae9ed |
- "commandline string"));
|
|
|
6ae9ed |
+ _("NULL JSON type can't be converted to commandline"));
|
|
|
6ae9ed |
return -1;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
@@ -108,15 +158,6 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
-static int
|
|
|
6ae9ed |
-virQEMUBuildCommandLineJSONIterate(const char *key,
|
|
|
6ae9ed |
- const virJSONValue *value,
|
|
|
6ae9ed |
- void *opaque)
|
|
|
6ae9ed |
-{
|
|
|
6ae9ed |
- return virQEMUBuildCommandLineJSONRecurse(key, value, opaque, false);
|
|
|
6ae9ed |
-}
|
|
|
6ae9ed |
-
|
|
|
6ae9ed |
-
|
|
|
6ae9ed |
/**
|
|
|
6ae9ed |
* virQEMUBuildCommandLineJSON:
|
|
|
6ae9ed |
* @value: json object containing the value
|
|
|
6ae9ed |
@@ -131,12 +172,7 @@ 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 |
+ return virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, false);
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/tests/qemucommandutiltest.c b/tests/qemucommandutiltest.c
|
|
|
6ae9ed |
index 8299462..4872ea3 100644
|
|
|
6ae9ed |
--- a/tests/qemucommandutiltest.c
|
|
|
6ae9ed |
+++ b/tests/qemucommandutiltest.c
|
|
|
6ae9ed |
@@ -117,6 +117,14 @@ mymain(void)
|
|
|
6ae9ed |
"array=bleah,array=qwerty,array=1");
|
|
|
6ae9ed |
DO_TEST_COMMAND_OBJECT_FROM_JSON("{\"boolean\":true,\"hyphen-name\":1234,\"some_string\":\"bleah\"}",
|
|
|
6ae9ed |
"boolean=yes,hyphen-name=1234,some_string=bleah");
|
|
|
6ae9ed |
+ DO_TEST_COMMAND_OBJECT_FROM_JSON("{\"nest\": {\"boolean\":true,"
|
|
|
6ae9ed |
+ "\"hyphen-name\":1234,"
|
|
|
6ae9ed |
+ "\"some_string\":\"bleah\","
|
|
|
6ae9ed |
+ "\"bleah\":\"bl,eah\""
|
|
|
6ae9ed |
+ "}"
|
|
|
6ae9ed |
+ "}",
|
|
|
6ae9ed |
+ "nest.boolean=yes,nest.hyphen-name=1234,"
|
|
|
6ae9ed |
+ "nest.some_string=bleah,nest.bleah=bl,,eah");
|
|
|
6ae9ed |
|
|
|
6ae9ed |
return ret;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
--
|
|
|
6ae9ed |
2.9.2
|
|
|
6ae9ed |
|