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@xxxxxxxxx> + */ +#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@xxxxxxxxx> + */ +#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 */ -- 2.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list