LXC driver: started implementing connectDomainXMLFromNative

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.
This commit is contained in:
Cédric Bosdonnat 2014-02-05 15:10:00 +01:00 committed by Daniel P. Berrange
parent 3daa14834a
commit 7195c807b2
10 changed files with 320 additions and 1 deletions

1
.gitignore vendored
View File

@ -157,6 +157,7 @@
/tests/hashtest
/tests/jsontest
/tests/libvirtdconftest
/tests/lxcconf2xmltest
/tests/metadatatest
/tests/networkxml2argvtest
/tests/nodeinfotest

View 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

View 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 = \

View 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 */

86
src/lxc/lxc_native.c Normal file
View File

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

32
src/lxc/lxc_native.h Normal file
View File

@ -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__ */

View 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

View File

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

View File

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

107
tests/lxcconf2xmltest.c Normal file
View File

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