Quick note: next time you send a patch series, add a cover letter to it.
You can get git to automatically ask you about one by running
git config add format.coverletter auto
Having reviewed them off-list first, ACK from me to those changes.
Daniel, do you want to double-review them?
--
Cedric
On Fri, 2017-06-16 at 19:59 +0530, Venkat Datta N H wrote:
Docker Memory and VCPU configuration is converted to fit for LXC
container XML configuration
---
po/POTFILES.in | 1 +
src/Makefile.am | 1 +
src/lxc/lxc_driver.c | 13 ++-
src/lxc/lxc_native.h | 1 +
src/lxc/lxc_native_docker.c | 112 ++++++++++++++++++
src/lxc/lxc_native_docker.h | 30 +++++
tests/Makefile.am | 8 +-
.../dockerjson2xmldata-simple.json | 36 ++++++
.../dockerjson2xmldata-simple.xml | 15 +++
tests/dockerjson2xmltest.c | 127 +++++++++++++++++++++
10 files changed, 338 insertions(+), 6 deletions(-)
create mode 100644 src/lxc/lxc_native_docker.c
create mode 100644 src/lxc/lxc_native_docker.h
create mode 100644 tests/dockerjson2xmldata/dockerjson2xmldata-simple.json
create mode 100644 tests/dockerjson2xmldata/dockerjson2xmldata-simple.xml
create mode 100644 tests/dockerjson2xmltest.c
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 275df1f..098be9f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -111,6 +111,7 @@ src/lxc/lxc_driver.c
src/lxc/lxc_fuse.c
src/lxc/lxc_hostdev.c
src/lxc/lxc_native.c
+src/lxc/lxc_native_docker.c
src/lxc/lxc_process.c
src/network/bridge_driver.c
src/network/bridge_driver_linux.c
diff --git a/src/Makefile.am b/src/Makefile.am
index eae32dc..53d1bca 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -839,6 +839,7 @@ LXC_DRIVER_SOURCES = \
lxc/lxc_process.c lxc/lxc_process.h \
lxc/lxc_fuse.c lxc/lxc_fuse.h \
lxc/lxc_native.c lxc/lxc_native.h \
+ lxc/lxc_native_docker.c lxc/lxc_native_docker.h \
lxc/lxc_driver.c lxc/lxc_driver.h
LXC_CONTROLLER_SOURCES = \
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 22c8b58..0f5a7870 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -53,6 +53,7 @@
#include "lxc_driver.h"
#include "lxc_native.h"
#include "lxc_process.h"
+#include "lxc_native_docker.h"
#include "viralloc.h"
#include "virnetdevbridge.h"
#include "virnetdevveth.h"
@@ -1062,15 +1063,17 @@ static char *lxcConnectDomainXMLFromNative(virConnectPtr conn,
if (virConnectDomainXMLFromNativeEnsureACL(conn) < 0)
goto cleanup;
- if (STRNEQ(nativeFormat, LXC_CONFIG_FORMAT)) {
+ if (STREQ(nativeFormat, DOCKER_CONFIG_FORMAT)) {
+ if (!(def = dockerParseJSONConfig(caps, driver->xmlopt, nativeConfig)))
+ goto cleanup;
+ } else if (STREQ(nativeFormat, LXC_CONFIG_FORMAT)) {
+ if (!(def = lxcParseConfigString(nativeConfig, caps, driver->xmlopt)))
+ goto cleanup;
+ } else {
virReportError(VIR_ERR_INVALID_ARG,
_("unsupported config type %s"), nativeFormat);
goto cleanup;
}
-
- if (!(def = lxcParseConfigString(nativeConfig, caps, driver->xmlopt)))
- goto cleanup;
-
xml = virDomainDefFormat(def, caps, 0);
cleanup:
diff --git a/src/lxc/lxc_native.h b/src/lxc/lxc_native.h
index 15fa0d5..88263ae 100644
--- a/src/lxc/lxc_native.h
+++ b/src/lxc/lxc_native.h
@@ -26,6 +26,7 @@
# include "domain_conf.h"
# define LXC_CONFIG_FORMAT "lxc-tools"
+# define DOCKER_CONFIG_FORMAT "docker"
virDomainDefPtr lxcParseConfigString(const char *config,
virCapsPtr caps,
diff --git a/src/lxc/lxc_native_docker.c b/src/lxc/lxc_native_docker.c
new file mode 100644
index 0000000..a278309
--- /dev/null
+++ b/src/lxc/lxc_native_docker.c
@@ -0,0 +1,112 @@
+/*
+ * lxc_native_docker.c: LXC native docker configuration import
+ *
+ * Copyright (C) 2017 Venkat Datta N H
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ *
+ * Author: Venkat Datta N H <nhvenkatdatta(a)gmail.com>
+ */
+#include <config.h>
+#include "util/viralloc.h"
+#include "util/virfile.h"
+#include "util/virstring.h"
+#include "util/virconf.h"
+#include "util/virjson.h"
+#include "util/virutil.h"
+#include "virerror.h"
+#include "virlog.h"
+#include "conf/domain_conf.h"
+#include "lxc_native_docker.h"
+#include "secret_conf.h"
+#define VIR_FROM_THIS VIR_FROM_LXC
+VIR_LOG_INIT("lxc.lxc_native_docker");
+
+static int dockerParseVCpus(virDomainDefPtr dom,
+ virDomainXMLOptionPtr xmlopt,
+ virJSONValuePtr prop)
+{
+ int vcpus;
+
+ if (virJSONValueObjectGetNumberInt(prop, "CpuShares", &vcpus) != 0)
+ return -1;
+
+ if (virDomainDefSetVcpusMax(dom, vcpus, xmlopt) < 0)
+ return -1;
+
+ if (virDomainDefSetVcpus(dom, vcpus) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int dockerParseMem(virDomainDefPtr dom,
+ virJSONValuePtr prop)
+{
+ unsigned long long mem;
+
+ if (virJSONValueObjectGetNumberUlong(prop, "Memory", &mem) != 0)
+ return -1;
+
+ virDomainDefSetMemoryTotal(dom, mem / 1024);
+ dom->mem.cur_balloon = mem / 1024;
+
+ return 0;
+}
+
+virDomainDefPtr dockerParseJSONConfig(virCapsPtr caps ATTRIBUTE_UNUSED,
+ virDomainXMLOptionPtr xmlopt,
+ const char *config)
+{
+ virJSONValuePtr json_obj;
+ virJSONValuePtr host_config;
+
+ if (!(json_obj = virJSONValueFromString(config)))
+ return NULL;
+
+ virDomainDefPtr def;
+
+ if (!(def = virDomainDefNew()))
+ goto error;
+
+ def->id = -1;
+ def->mem.cur_balloon = 64*1024;
+ virDomainDefSetMemoryTotal(def, def->mem.cur_balloon);
+
+ if ((host_config = virJSONValueObjectGetObject(json_obj, "HostConfig")) !=
NULL) {
+ if (dockerParseVCpus(def, xmlopt, host_config) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to
parse VCpu"));
+ goto error;
+ }
+
+ if (dockerParseMem(def, host_config) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to
parse Memory"));
+ goto error;
+ }
+ }
+
+ def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC;
+ def->onReboot = VIR_DOMAIN_LIFECYCLE_RESTART;
+ def->onCrash = VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY;
+ def->onPoweroff = VIR_DOMAIN_LIFECYCLE_DESTROY;
+ def->virtType = VIR_DOMAIN_VIRT_LXC;
+ def->os.type = VIR_DOMAIN_OSTYPE_EXE;
+
+ return def;
+
+ error:
+ virDomainDefFree(def);
+ return NULL;
+}
diff --git a/src/lxc/lxc_native_docker.h b/src/lxc/lxc_native_docker.h
new file mode 100644
index 0000000..40285f9
--- /dev/null
+++ b/src/lxc/lxc_native_docker.h
@@ -0,0 +1,30 @@
+/*
+ * lxc_native_docker.h: header file for LXC native docker configuration
+ *
+ * Copyright (C) 2017 Venkat Datta N H
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ *
+ * Author: Venkat Datta N H <nhvenkatdatta(a)gmail.com>
+ */
+#ifndef __LXC_NATIVE_DOCKER_H__
+# define __LXC_NATIVE_DOCKER_H__
+# include "domain_conf.h"
+
+virDomainDefPtr dockerParseJSONConfig(virCapsPtr caps,
+ virDomainXMLOptionPtr xmlopt,
+ const char *config);
+
+#endif
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 19986dc..3beb634 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -93,6 +93,7 @@ EXTRA_DIST = \
capabilityschemadata \
commanddata \
cputestdata \
+ dockerjson2xmldata \
domaincapsschemadata \
domainconfdata \
domainschemadata \
@@ -295,7 +296,7 @@ test_libraries += libqemumonitortestutils.la \
endif WITH_QEMU
if WITH_LXC
-test_programs += lxcxml2xmltest lxcconf2xmltest
+test_programs += lxcxml2xmltest lxcconf2xmltest dockerjson2xmltest
endif WITH_LXC
if WITH_OPENVZ
@@ -693,6 +694,11 @@ lxcconf2xmltest_SOURCES = \
lxcconf2xmltest.c testutilslxc.c testutilslxc.h \
testutils.c testutils.h
lxcconf2xmltest_LDADD = $(lxc_LDADDS)
+
+dockerjson2xmltest_SOURCES = \
+ dockerjson2xmltest.c testutilslxc.c testutilslxc.h \
+ testutils.c testutils.h
+dockerjson2xmltest_LDADD = $(lxc_LDADDS)
else ! WITH_LXC
EXTRA_DIST += lxcxml2xmltest.c testutilslxc.c testutilslxc.h
endif ! WITH_LXC
diff --git a/tests/dockerjson2xmldata/dockerjson2xmldata-simple.json
b/tests/dockerjson2xmldata/dockerjson2xmldata-
simple.json
new file mode 100644
index 0000000..63470be
--- /dev/null
+++ b/tests/dockerjson2xmldata/dockerjson2xmldata-simple.json
@@ -0,0 +1,36 @@
+{
+ "Id":
"dbb1ae21dac15973d66e6c2b8516d270b32ca766e0cf7551d8b7973513e5f079",
+ "Created": "2017-05-25T18:55:17.922934825Z",
+ "Path": "/bin/bash",
+ "Args": [],
+ "HostConfig": {
+ "Binds": null,
+ "ContainerIDFile": "",
+ "LogConfig": {
+ "Type": "json-file",
+ "Config": {}
+ },
+ "NetworkMode": "default",
+ "PortBindings": {},
+ "ShmSize": 67108864,
+ "Runtime": "runc",
+ "Isolation": "",
+ "CpuShares": 2,
+ "Memory": 1073741824,
+ "CgroupParent": "",
+ "CpuPeriod": 0,
+ "CpuQuota": 0,
+ "CpusetCpus": "",
+ "CpusetMems": "",
+ "KernelMemory": 0,
+ "MemoryReservation": 0,
+ "MemorySwap": -1,
+ "MemorySwappiness": -1,
+ "PidsLimit": 0,
+ "Ulimits": null,
+ "CpuCount": 0,
+ "CpuPercent": 0,
+ "IOMaximumIOps": 0,
+ "IOMaximumBandwidth": 0
+ }
+}
diff --git a/tests/dockerjson2xmldata/dockerjson2xmldata-simple.xml
b/tests/dockerjson2xmldata/dockerjson2xmldata-
simple.xml
new file mode 100644
index 0000000..8be1ace
--- /dev/null
+++ b/tests/dockerjson2xmldata/dockerjson2xmldata-simple.xml
@@ -0,0 +1,15 @@
+<domain type='lxc'>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>2</vcpu>
+ <os>
+ <type>exe</type>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/dockerjson2xmltest.c b/tests/dockerjson2xmltest.c
new file mode 100644
index 0000000..41c46a1
--- /dev/null
+++ b/tests/dockerjson2xmltest.c
@@ -0,0 +1,127 @@
+#include <config.h>
+
+#include "testutils.h"
+
+#ifdef WITH_LXC
+
+# include "lxc/lxc_native_docker.h"
+# include "lxc/lxc_conf.h"
+# include "testutilslxc.h"
+
+# define VIR_FROM_THIS VIR_FROM_NONE
+
+static virCapsPtr caps;
+static virDomainXMLOptionPtr xmlopt;
+
+static int testSanitizeDef(virDomainDefPtr vmdef)
+{
+ /* Remove UUID randomness */
+ if (virUUIDParse("c7a5fdbd-edaf-9455-926a-d65c16db1809", vmdef->uuid)
< 0)
+ return -1;
+ return 0;
+}
+
+static int
+testCompareXMLToConfigFiles(const char *xmlfile,
+ const char *configfile,
+ bool expectError)
+{
+ int ret = -1;
+ char *config = NULL;
+ char *actualxml = NULL;
+ virDomainDefPtr vmdef = NULL;
+
+ if (virTestLoadFile(configfile, &config) < 0)
+ goto fail;
+
+ vmdef = dockerParseJSONConfig(caps, xmlopt, config);
+
+ if (vmdef && expectError) {
+ if (testSanitizeDef(vmdef) < 0)
+ goto fail;
+
+ if (!(actualxml = virDomainDefFormat(vmdef, caps, 0)))
+ goto fail;
+
+ if (virTestCompareToFile(actualxml, xmlfile) < 0)
+ goto fail;
+ }
+
+ ret = 0;
+
+ fail:
+ VIR_FREE(actualxml);
+ VIR_FREE(config);
+ virDomainDefFree(vmdef);
+ return ret;
+}
+
+struct testInfo {
+ const char *name;
+ bool expectError;
+};
+
+static int
+testCompareXMLToConfigHelper(const void *data)
+{
+ int result = -1;
+ const struct testInfo *info = data;
+ char *xml = NULL;
+ char *config = NULL;
+
+ if (virAsprintf(&xml,
"%s/dockerjson2xmldata/dockerjson2xmldata-%s.xml",
+ abs_srcdir, info->name) < 0 ||
+ virAsprintf(&config,
"%s/dockerjson2xmldata/dockerjson2xmldata-%s.json",
+ abs_srcdir, info->name) < 0)
+ goto cleanup;
+
+ result = testCompareXMLToConfigFiles(xml, config, info->expectError);
+
+ cleanup:
+ VIR_FREE(xml);
+ VIR_FREE(config);
+ return result;
+}
+
+static int
+mymain(void)
+{
+ int ret = EXIT_SUCCESS;
+
+ if (!(caps = testLXCCapsInit()))
+ return EXIT_FAILURE;
+
+ if (!(xmlopt = lxcDomainXMLConfInit())) {
+ virObjectUnref(caps);
+ return EXIT_FAILURE;
+ }
+
+
+# define DO_TEST(name, expectError) \
+ do { \
+ const struct testInfo info = { name, expectError }; \
+ if (virTestRun("DOCKER JSON-2-XML " name, \
+ testCompareXMLToConfigHelper, \
+ &info) < 0) \
+ ret = EXIT_FAILURE; \
+ } while (0)
+
+ DO_TEST("simple", true);
+
+ virObjectUnref(xmlopt);
+ virObjectUnref(caps);
+
+ return ret;
+}
+
+VIR_TEST_MAIN(mymain)
+
+#else
+
+int
+main(void)
+{
+ return EXIT_AM_SKIP;
+}
+
+#endif /* WITH_LXC */