]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
LXC driver: started implementing connectDomainXMLFromNative
authorCédric Bosdonnat <cbosdonnat@suse.com>
Wed, 5 Feb 2014 14:10:00 +0000 (15:10 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 12 Feb 2014 17:52:46 +0000 (17:52 +0000)
This function aims at converting LXC configuration into a libvirt
domain XML description to help users migrate from LXC to libvirt.

Here is an example of how the lxc configuration works:
virsh -c lxc:/// domxml-from-native lxc-tools /var/lib/lxc/migrate_test/config

It is possible that some parts couldn't be properly mapped into a
domain XML fragment, so users should carefully review the result
before creating the domain.

fstab files in lxc.mount lines will need to be merged into the
configuration file as lxc.mount.entry.

As we can't know the amount of memory of the host, we have to set a
default value for max_balloon that users will probably want to adjust.

.gitignore
po/POTFILES.in
src/Makefile.am
src/lxc/lxc_driver.c
src/lxc/lxc_native.c [new file with mode: 0644]
src/lxc/lxc_native.h [new file with mode: 0644]
tests/Makefile.am
tests/lxcconf2xmldata/lxcconf2xml-simple.config [new file with mode: 0644]
tests/lxcconf2xmldata/lxcconf2xml-simple.xml [new file with mode: 0644]
tests/lxcconf2xmltest.c [new file with mode: 0644]

index 5fe60c68d2003b65d9aea83e11a094724ccdfbd2..1c1548992ec2fa41c27f1727856de069d694ba4f 100644 (file)
 /tests/hashtest
 /tests/jsontest
 /tests/libvirtdconftest
+/tests/lxcconf2xmltest
 /tests/metadatatest
 /tests/networkxml2argvtest
 /tests/nodeinfotest
index 0359b2fe4c32e061e9646761f5e3f018d6216843..fd36bc529e33344aea3fdd764f164b9c3475fd5a 100644 (file)
@@ -62,6 +62,7 @@ src/locking/sanlock_helper.c
 src/lxc/lxc_cgroup.c
 src/lxc/lxc_fuse.c
 src/lxc/lxc_hostdev.c
+src/lxc/lxc_native.c
 src/lxc/lxc_container.c
 src/lxc/lxc_conf.c
 src/lxc/lxc_controller.c
index 3f8d22f5e1eafee03fe73906b2aa88f931383bc3..4ac31e25d0706b621a6265af71bad5eeb4d21545 100644 (file)
@@ -619,6 +619,7 @@ LXC_DRIVER_SOURCES =                                                \
                lxc/lxc_monitor.c lxc/lxc_monitor.h             \
                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_driver.c lxc/lxc_driver.h
 
 LXC_CONTROLLER_SOURCES =                                       \
index 687046ea95e6b05841829bfd734405dad5ab190d..f735631d4526ef33d67742f898dd7e5af08432c1 100644 (file)
@@ -44,6 +44,7 @@
 #include "lxc_container.h"
 #include "lxc_domain.h"
 #include "lxc_driver.h"
+#include "lxc_native.h"
 #include "lxc_process.h"
 #include "viralloc.h"
 #include "virnetdevbridge.h"
@@ -988,6 +989,35 @@ cleanup:
     return ret;
 }
 
+static char *lxcConnectDomainXMLFromNative(virConnectPtr conn,
+                                           const char *nativeFormat,
+                                           const char *nativeConfig,
+                                           unsigned int flags)
+{
+    char *xml = NULL;
+    virDomainDefPtr def = NULL;
+
+    virCheckFlags(0, NULL);
+
+    if (virConnectDomainXMLFromNativeEnsureACL(conn) < 0)
+        goto cleanup;
+
+    if (STRNEQ(nativeFormat, LXC_CONFIG_FORMAT)) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("unsupported config type %s"), nativeFormat);
+        goto cleanup;
+    }
+
+    if (!(def = lxcParseConfigString(nativeConfig)))
+        goto cleanup;
+
+    xml = virDomainDefFormat(def, 0);
+
+cleanup:
+    virDomainDefFree(def);
+    return xml;
+}
+
 /**
  * lxcDomainCreateWithFiles:
  * @dom: domain to start
@@ -5374,6 +5404,7 @@ static virDriver lxcDriver = {
     .domainGetSecurityLabel = lxcDomainGetSecurityLabel, /* 0.9.10 */
     .nodeGetSecurityModel = lxcNodeGetSecurityModel, /* 0.9.10 */
     .domainGetXMLDesc = lxcDomainGetXMLDesc, /* 0.4.2 */
+    .connectDomainXMLFromNative = lxcConnectDomainXMLFromNative, /* 1.2.2 */
     .connectListDefinedDomains = lxcConnectListDefinedDomains, /* 0.4.2 */
     .connectNumOfDefinedDomains = lxcConnectNumOfDefinedDomains, /* 0.4.2 */
     .domainCreate = lxcDomainCreate, /* 0.4.4 */
diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c
new file mode 100644 (file)
index 0000000..723ebcf
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * lxc_native.c: LXC native configuration import
+ *
+ * Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * 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: Cedric Bosdonnat <cbosdonnat@suse.com>
+ */
+
+#include <config.h>
+
+#include "internal.h"
+#include "lxc_native.h"
+#include "util/viralloc.h"
+#include "util/virlog.h"
+#include "util/virstring.h"
+#include "util/virconf.h"
+
+#define VIR_FROM_THIS VIR_FROM_LXC
+
+virDomainDefPtr
+lxcParseConfigString(const char *config)
+{
+    virDomainDefPtr vmdef = NULL;
+    virConfPtr properties = NULL;
+    virConfValuePtr value;
+
+    if (!(properties = virConfReadMem(config, 0, VIR_CONF_FLAG_LXC_FORMAT)))
+        return NULL;
+
+    if (VIR_ALLOC(vmdef) < 0)
+        goto error;
+
+    if (virUUIDGenerate(vmdef->uuid) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("failed to generate uuid"));
+        goto error;
+    }
+    vmdef->id = -1;
+    vmdef->mem.max_balloon = 64 * 1024;
+
+    vmdef->onReboot = VIR_DOMAIN_LIFECYCLE_RESTART;
+    vmdef->onCrash = VIR_DOMAIN_LIFECYCLE_DESTROY;
+    vmdef->onPoweroff = VIR_DOMAIN_LIFECYCLE_DESTROY;
+    vmdef->virtType = VIR_DOMAIN_VIRT_LXC;
+
+    /* Value not handled by the LXC driver, setting to
+     * minimum required to make XML parsing pass */
+    vmdef->maxvcpus = 1;
+
+    if (VIR_STRDUP(vmdef->os.type, "exe") < 0)
+        goto error;
+
+    if (VIR_STRDUP(vmdef->os.init, "/sbin/init") < 0)
+        goto error;
+
+    if (!(value = virConfGetValue(properties, "lxc.utsname")) ||
+            !value->str || (VIR_STRDUP(vmdef->name, value->str) < 0))
+        goto error;
+    if (!vmdef->name && (VIR_STRDUP(vmdef->name, "unnamed") < 0))
+        goto error;
+
+    goto cleanup;
+
+error:
+    virDomainDefFree(vmdef);
+    vmdef = NULL;
+
+cleanup:
+    virConfFree(properties);
+
+    return vmdef;
+}
diff --git a/src/lxc/lxc_native.h b/src/lxc/lxc_native.h
new file mode 100644 (file)
index 0000000..a80f2b1
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * lxc_native.h: LXC native configuration import
+ *
+ * Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * 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: Cedric Bosdonnat <cbosdonnat@suse.com>
+ */
+
+#ifndef __LXC_NATIVE_H__
+# define __LXC_NATIVE_H__
+
+# include "domain_conf.h"
+
+# define LXC_CONFIG_FORMAT "lxc-tools"
+
+virDomainDefPtr lxcParseConfigString(const char *config);
+
+#endif /* __LXC_NATIVE_H__ */
index 1698455c6abf7c53d7b4f9c18bee329a8db3de51..62a19cbfc3dde151c7ef72e9332d3d28f70778d3 100644 (file)
@@ -200,7 +200,7 @@ test_programs += qemuxml2argvtest qemuxml2xmltest qemuxmlnstest \
 endif WITH_QEMU
 
 if WITH_LXC
-test_programs += lxcxml2xmltest
+test_programs += lxcxml2xmltest lxcconf2xmltest
 endif WITH_LXC
 
 if WITH_OPENVZ
@@ -523,6 +523,11 @@ lxcxml2xmltest_SOURCES = \
        lxcxml2xmltest.c testutilslxc.c testutilslxc.h \
        testutils.c testutils.h
 lxcxml2xmltest_LDADD = $(lxc_LDADDS)
+
+lxcconf2xmltest_SOURCES = \
+       lxcconf2xmltest.c \
+       testutils.c testutils.h
+lxcconf2xmltest_LDADD = $(lxc_LDADDS)
 else ! WITH_LXC
 EXTRA_DIST += lxcxml2xmltest.c testutilslxc.c testutilslxc.h
 endif ! WITH_LXC
diff --git a/tests/lxcconf2xmldata/lxcconf2xml-simple.config b/tests/lxcconf2xmldata/lxcconf2xml-simple.config
new file mode 100644 (file)
index 0000000..12428bb
--- /dev/null
@@ -0,0 +1,38 @@
+# Template used to create this container: opensuse
+# Template script checksum (SHA-1): 27307e0a95bd81b2c0bd82d6f87fdbe83be075ef
+
+lxc.network.type = veth
+lxc.network.flags = up
+lxc.network.link = virbr0
+lxc.network.hwaddr = 02:00:15:8f:05:c1
+lxc.network.name = eth0
+
+#remove next line if host DNS configuration should not be available to container
+lxc.mount.entry = /etc/resolv.conf etc/resolv.conf none bind,ro 0 0
+lxc.rootfs = /var/lib/lxc/migrate_test/rootfs
+lxc.utsname = migrate_test
+lxc.autodev=1
+lxc.tty = 2
+lxc.pts = 1024
+lxc.mount = /var/lib/lxc/migrate_test/fstab
+lxc.cap.drop = sys_module mac_admin mac_override mknod
+
+# When using LXC with apparmor, uncomment the next line to run unconfined:
+#lxc.aa_profile = unconfined
+
+lxc.cgroup.devices.deny = a
+# /dev/null and zero
+lxc.cgroup.devices.allow = c 1:3 rwm
+lxc.cgroup.devices.allow = c 1:5 rwm
+# consoles
+lxc.cgroup.devices.allow = c 5:1 rwm
+lxc.cgroup.devices.allow = c 5:0 rwm
+lxc.cgroup.devices.allow = c 4:0 rwm
+lxc.cgroup.devices.allow = c 4:1 rwm
+# /dev/{,u}random
+lxc.cgroup.devices.allow = c 1:9 rwm
+lxc.cgroup.devices.allow = c 1:8 rwm
+lxc.cgroup.devices.allow = c 136:* rwm
+lxc.cgroup.devices.allow = c 5:2 rwm
+# rtc
+lxc.cgroup.devices.allow = c 254:0 rwm
diff --git a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml
new file mode 100644 (file)
index 0000000..641e624
--- /dev/null
@@ -0,0 +1,17 @@
+<domain type='lxc'>
+  <name>migrate_test</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>65536</memory>
+  <currentMemory unit='KiB'>0</currentMemory>
+  <vcpu placement='static' current='0'>1</vcpu>
+  <os>
+    <type>exe</type>
+    <init>/sbin/init</init>
+  </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/lxcconf2xmltest.c b/tests/lxcconf2xmltest.c
new file mode 100644 (file)
index 0000000..9a840f9
--- /dev/null
@@ -0,0 +1,107 @@
+#include <config.h>
+
+#include "testutils.h"
+
+#ifdef WITH_LXC
+
+# include "lxc/lxc_native.h"
+
+# define VIR_FROM_THIS VIR_FROM_NONE
+
+static int
+blankProblemElements(char *data)
+{
+    if (virtTestClearLineRegex("<uuid>([[:alnum:]]|-)+</uuid>", data) < 0)
+        return -1;
+    return 0;
+}
+
+static int
+testCompareXMLToConfigFiles(const char *xml,
+                            const char *configfile)
+{
+    int ret = -1;
+    char *config = NULL;
+    char *expectxml = NULL;
+    char *actualxml = NULL;
+    virDomainDefPtr vmdef = NULL;
+
+    if (virtTestLoadFile(configfile, &config) < 0)
+        goto fail;
+    if (virtTestLoadFile(xml, &expectxml) < 0)
+        goto fail;
+
+    if (!(vmdef = lxcParseConfigString(config)))
+        goto fail;
+
+    if (!(actualxml = virDomainDefFormat(vmdef, 0)))
+        goto fail;
+
+    if (blankProblemElements(expectxml) < 0 ||
+        blankProblemElements(actualxml) < 0)
+        goto fail;
+
+    if (STRNEQ(expectxml, actualxml)) {
+        virtTestDifference(stderr, expectxml, actualxml);
+        goto fail;
+    }
+
+    ret = 0;
+
+fail:
+    VIR_FREE(expectxml);
+    VIR_FREE(actualxml);
+    VIR_FREE(config);
+    virDomainDefFree(vmdef);
+    return ret;
+}
+
+static int
+testCompareXMLToConfigHelper(const void *data)
+{
+    int result = -1;
+    const char *name = data;
+    char *xml = NULL;
+    char *config = NULL;
+
+    if (virAsprintf(&xml, "%s/lxcconf2xmldata/lxcconf2xml-%s.xml",
+                    abs_srcdir, name) < 0 ||
+        virAsprintf(&config, "%s/lxcconf2xmldata/lxcconf2xml-%s.config",
+                    abs_srcdir, name) < 0)
+        goto cleanup;
+
+    result = testCompareXMLToConfigFiles(xml, config);
+
+cleanup:
+    VIR_FREE(xml);
+    VIR_FREE(config);
+    return result;
+}
+
+static int
+mymain(void)
+{
+    int ret = EXIT_SUCCESS;
+
+# define DO_TEST(name)                                  \
+    if (virtTestRun("LXC Native-2-XML " name,           \
+                    testCompareXMLToConfigHelper,       \
+                    name) < 0)                          \
+        ret = EXIT_FAILURE
+
+    DO_TEST("simple");
+
+    return ret;
+}
+
+VIRT_TEST_MAIN(mymain)
+
+#else
+
+int
+main(void)
+{
+    return EXIT_AM_SKIP;
+}
+
+#endif /* WITH_LXC */