util: qemu: Add support for numbered array members

Add support for converting objects nested in arrays with a numbering
discriminator on the command line. This syntax is used for the
object-based specification of disk source properties.
This commit is contained in:
Peter Krempa 2016-07-25 19:47:40 +02:00
parent f1bbc7df4a
commit 74df83a9eb
4 changed files with 70 additions and 3 deletions

View File

@ -2206,6 +2206,7 @@ virProcessWait;
virQEMUBuildBufferEscapeComma;
virQEMUBuildCommandLineJSON;
virQEMUBuildCommandLineJSONArrayBitmap;
virQEMUBuildCommandLineJSONArrayNumbered;
virQEMUBuildLuksOpts;
virQEMUBuildObjectCommandlineFromJSON;

View File

@ -79,6 +79,39 @@ virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
}
int
virQEMUBuildCommandLineJSONArrayNumbered(const char *key,
const virJSONValue *array,
virBufferPtr buf)
{
const virJSONValue *member;
size_t nelems = virJSONValueArraySize(array);
char *prefix = NULL;
size_t i;
int ret = 0;
for (i = 0; i < nelems; i++) {
member = virJSONValueArrayGet((virJSONValuePtr) array, i);
if (virAsprintf(&prefix, "%s.%zu", key, i) < 0)
goto cleanup;
if (virQEMUBuildCommandLineJSONRecurse(prefix, member, buf,
virQEMUBuildCommandLineJSONArrayNumbered,
true) < 0)
goto cleanup;
VIR_FREE(prefix);
}
ret = 0;
cleanup:
VIR_FREE(prefix);
return ret;
}
/* internal iterator to handle nested object formatting */
static int
virQEMUBuildCommandLineJSONIterate(const char *key,

View File

@ -35,6 +35,9 @@ typedef int (*virQEMUBuildCommandLineJSONArrayFormatFunc)(const char *key,
int virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
const virJSONValue *array,
virBufferPtr buf);
int virQEMUBuildCommandLineJSONArrayNumbered(const char *key,
const virJSONValue *array,
virBufferPtr buf);
int virQEMUBuildCommandLineJSON(const virJSONValue *value,
virBufferPtr buf,

View File

@ -30,6 +30,7 @@ typedef struct
{
const char *props;
const char *expectprops;
virQEMUBuildCommandLineJSONArrayFormatFunc arrayfunc;
} testQemuCommandBuildObjectFromJSONData;
static int
@ -46,8 +47,7 @@ testQemuCommandBuildFromJSON(const void *opaque)
return -1;
}
if (virQEMUBuildCommandLineJSON(val, &buf,
virQEMUBuildCommandLineJSONArrayBitmap) < 0) {
if (virQEMUBuildCommandLineJSON(val, &buf, data->arrayfunc) < 0) {
fprintf(stderr,
"\nvirQEMUBuildCommandlineJSON failed process JSON:\n%s\n",
data->props);
@ -83,16 +83,23 @@ mymain(void)
virTestCounterReset("testQemuCommandBuildFromJSON");
#define DO_TEST_COMMAND_OBJECT_FROM_JSON(PROPS, EXPECT) \
#define DO_TEST_COMMAND_FROM_JSON(PROPS, ARRAYFUNC, EXPECT) \
do { \
data1.props = PROPS; \
data1.expectprops = EXPECT; \
data1.arrayfunc = ARRAYFUNC; \
if (virTestRun(virTestCounterNext(), \
testQemuCommandBuildFromJSON, \
&data1) < 0) \
ret = -1; \
} while (0)
#define DO_TEST_COMMAND_OBJECT_FROM_JSON(PROPS, EXPECT) \
DO_TEST_COMMAND_FROM_JSON(PROPS, virQEMUBuildCommandLineJSONArrayBitmap, EXPECT)
#define DO_TEST_COMMAND_DRIVE_FROM_JSON(PROPS, EXPECT) \
DO_TEST_COMMAND_FROM_JSON(PROPS, virQEMUBuildCommandLineJSONArrayNumbered, EXPECT)
DO_TEST_COMMAND_OBJECT_FROM_JSON("{}", NULL);
DO_TEST_COMMAND_OBJECT_FROM_JSON("{\"string\":\"qwer\"}", "string=qwer");
DO_TEST_COMMAND_OBJECT_FROM_JSON("{\"string\":\"qw,e,r\"}", "string=qw,,e,,r");
@ -120,6 +127,29 @@ mymain(void)
"}",
"nest.boolean=yes,nest.hyphen-name=1234,"
"nest.some_string=bleah,nest.bleah=bl,,eah");
DO_TEST_COMMAND_DRIVE_FROM_JSON("{\"driver\":\"gluster\","
"\"volume\":\"test\","
"\"path\":\"img\","
"\"server\":[ { \"type\":\"tcp\","
"\"host\":\"example.com\","
"\"port\":\"1234\""
"},"
"{ \"type\":\"unix\","
"\"socket\":\"/path/socket\""
"},"
"{ \"type\":\"tcp\","
"\"host\":\"example.com\""
"}"
"]"
"}",
"driver=gluster,volume=test,path=img,"
"server.0.type=tcp,"
"server.0.host=example.com,"
"server.0.port=1234,"
"server.1.type=unix,"
"server.1.socket=/path/socket,"
"server.2.type=tcp,"
"server.2.host=example.com");
return ret;