[libvirt] [PATCH 1/2] lxc: add support for docker-json Memory and VCPU conversion

Daniel P. Berrange berrange at redhat.com
Mon Jun 26 15:27:37 UTC 2017


On Fri, Jun 16, 2017 at 07:59:44PM +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/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>
> + */

Add blank line

> +#include <config.h>

Add blank line

> +#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"

Add blank line

> +#define VIR_FROM_THIS VIR_FROM_LXC

Add blank line

> +VIR_LOG_INIT("lxc.lxc_native_docker");
> +
> +static int dockerParseVCpus(virDomainDefPtr dom,
> +                            virDomainXMLOptionPtr xmlopt,
> +                            virJSONValuePtr prop)

Generally all functions should have a name prefix matching the driver
and file name. eg I'd expect all these methods to be named something
like  virLXCNativeDockerXXXX, or would accept  just virLXCDockerXXXX

For that matter the filename could just be lxc_docker.{c,h} too if
we pick the latter.

> +{
> +    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>
> + */

Add blank line

> +#ifndef __LXC_NATIVE_DOCKER_H__
> +# define __LXC_NATIVE_DOCKER_H__

Add blank line

> +# include "domain_conf.h"
> +
> +virDomainDefPtr dockerParseJSONConfig(virCapsPtr caps,
> +                                           virDomainXMLOptionPtr xmlopt,
> +                                           const char *config);
> +
> +#endif

Usually expect a  /* ! __LXC_NATIVE_DOCKER_H__ */ comment after #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 \

Lets name it    lxcdocker2xmldata

>  	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

And   lxcdocker2xmltest


> 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 @@

Needs the license header boilerplate

> +#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 */


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




More information about the libvir-list mailing list