[libvirt] [PATCH 1/2] lxc: add support for docker-json Memory and VCPU conversion
Cedric Bosdonnat
cbosdonnat at suse.com
Fri Jun 16 15:49:54 UTC 2017
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 at 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 at 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 */
More information about the libvir-list
mailing list