Re: [libvirt] [sandbox PATCH v3 14/22] Image: Add run function
On Tue, 2015-08-18 at 06:53 +, Eren Yagdiran wrote: Run an already-built template If there is no execution command specified by user, source.get_command will find the command to invoke --- virt-sandbox-image/virt-sandbox-image.py | 25 + 1 file changed, 25 insertions(+) diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index c46abd4..278d19a 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -128,6 +128,31 @@ def check_connect(connectstr): raise ValueError(%s is not supported by Virt-sandbox %connectstr) return True +def run(args): +try: +if args.connect is not None: +check_connect(args.connect) +source = dynamic_source_loader(args.source) +diskfile,configfile = source.get_disk(name=args.name,templatedir=args.template_dir) This is the place where the temporary disk file would be created. Don't forget it's a per-sandbox disk layer. Compute the sandbox name here, use it to create the disk layer in the sandbox state directory... + +format = qcow2 +commandToRun = args.igniter +if commandToRun is None: +commandToRun = source.get_command(configfile) +cmd = ['virt-sandbox'] ...and add --name parameter to virt-sandbox to define that name. -- Cedric +if args.connect is not None: +cmd.append(-c) +cmd.append(args.connect) +params = ['-m','host-image:/=%s,format=%s' %(diskfile,format), + '--', + commandToRun] +cmd = cmd + params +subprocess.call(cmd) +subprocess.call([rm, -rf, diskfile]) Remove the temporary disk layer and the sandbox state directory here. -- Cedric +except Exception,e: +print Run Error %s % str(e) + def requires_name(parser): parser.add_argument(name, help=_(name of the template)) -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [RFC PATCH 2/3] Use mockup cache
Create capabilities cache using neq qemuTestMakeCapsCache() before parsing XML files Signed-off-by: Pavel Fedin p.fe...@samsung.com --- tests/qemuagenttest.c| 9 - tests/qemuargv2xmltest.c | 5 + tests/qemuhotplugtest.c | 23 +++ tests/qemuxml2argvtest.c | 5 + tests/qemuxml2xmltest.c | 6 ++ tests/qemuxmlnstest.c| 5 + 6 files changed, 44 insertions(+), 9 deletions(-) mode change 100644 = 100755 tests/qemuagenttest.c mode change 100644 = 100755 tests/qemuhotplugtest.c mode change 100644 = 100755 tests/qemuxml2xmltest.c diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c old mode 100644 new mode 100755 index 52cc834..729b82b --- a/tests/qemuagenttest.c +++ b/tests/qemuagenttest.c @@ -31,6 +31,8 @@ #define VIR_FROM_THIS VIR_FROM_NONE +static virQEMUDriver driver; + static int testQemuAgentFSFreeze(const void *data) { @@ -181,6 +183,10 @@ testQemuAgentGetFSInfo(const void *data) abs_srcdir) 0) goto cleanup; +driver.qemuCapsCache = qemuTestMakeCapsCache(, NULL); +if (!driver.qemuCapsCache) +goto cleanup; + if (!(def = virDomainDefParseFile(domain_filename, caps, xmlopt, VIR_DOMAIN_DEF_PARSE_INACTIVE))) goto cleanup; @@ -293,6 +299,7 @@ testQemuAgentGetFSInfo(const void *data) virDomainFSInfoFree(info[i]); VIR_FREE(info); VIR_FREE(domain_filename); +virQEMUCapsCacheFree(driver.qemuCapsCache); virObjectUnref(caps); virDomainDefFree(def); qemuMonitorTestFree(test); @@ -917,7 +924,7 @@ mymain(void) #endif if (virThreadInitialize() 0 || -!(xmlopt = virQEMUDriverCreateXMLConf(NULL))) +!(xmlopt = virQEMUDriverCreateXMLConf(driver))) return EXIT_FAILURE; virEventRegisterDefaultImpl(); diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c index ea85913..348f2dc 100644 --- a/tests/qemuargv2xmltest.c +++ b/tests/qemuargv2xmltest.c @@ -130,9 +130,14 @@ testCompareXMLToArgvHelper(const void *data) abs_srcdir, info-name) 0) goto cleanup; +driver.qemuCapsCache = qemuTestMakeCapsCache(info-name, NULL); +if (!driver.qemuCapsCache) +goto cleanup; + result = testCompareXMLToArgvFiles(xml, args, info-flags); cleanup: +virQEMUCapsCacheFree(driver.qemuCapsCache); VIR_FREE(xml); VIR_FREE(args); return result; diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c old mode 100644 new mode 100755 index 368a5e7..0f9932d --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -57,7 +57,7 @@ static int qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, virDomainObjPtr *vm, const char *domxml, - bool event) + bool event, const char *testname) { int ret = -1; qemuDomainObjPrivatePtr priv = NULL; @@ -65,12 +65,6 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, if (!(*vm = virDomainObjNew(xmlopt))) goto cleanup; -if (!((*vm)-def = virDomainDefParseString(domxml, - driver.caps, - driver.xmlopt, - VIR_DOMAIN_DEF_PARSE_INACTIVE))) -goto cleanup; - priv = (*vm)-privateData; if (!(priv-qemuCaps = virQEMUCapsNew())) @@ -85,6 +79,16 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, if (event) virQEMUCapsSet(priv-qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT); +driver.qemuCapsCache = qemuTestMakeCapsCache(testname, priv-qemuCaps); +if (!driver.qemuCapsCache) +goto cleanup; + +if (!((*vm)-def = virDomainDefParseString(domxml, + driver.caps, + driver.xmlopt, + VIR_DOMAIN_DEF_PARSE_INACTIVE))) +goto cleanup; + if (qemuDomainAssignAddresses((*vm)-def, priv-qemuCaps, *vm) 0) goto cleanup; @@ -243,7 +247,8 @@ testQemuHotplug(const void *data) vm = test-vm; } else { if (qemuHotplugCreateObjects(driver.xmlopt, vm, domain_xml, - test-deviceDeletedEvent) 0) + test-deviceDeletedEvent, + test-domain_filename) 0) goto cleanup; } @@ -318,10 +323,12 @@ testQemuHotplug(const void *data) } else { virObjectUnref(vm); test-vm = NULL; +virQEMUCapsCacheFree(driver.qemuCapsCache); } virDomainDeviceDefFree(dev); virObjectUnref(caps); qemuMonitorTestFree(test_mon); + return ((ret 0 fail) || (!ret !fail)) ? 0 : -1; } diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index c2482e6..428204d 100644
[libvirt] [PATCH] conf/qemu: enforce NUMA nodes only for x86 memory hotplug
libvirt enforces at least one NUMA node for memory hotplug support on all architectures. While it might be required for some x86 guest, PowerPC can hotplug memory on non-NUMA system. The generic checks are replaced with arch specific check and xml validation too does not enforce node for non-x86 arch. CC: Peter Krempa pkre...@redhat.com Signed-off-by: Nikunj A Dadhania nik...@linux.vnet.ibm.com --- src/conf/domain_conf.c | 9 ++--- src/qemu/qemu_command.c | 28 +--- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fd0450f..4cb2d4a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -12430,6 +12430,7 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node, static int virDomainMemoryTargetDefParseXML(xmlNodePtr node, + const virDomainDef *domDef, xmlXPathContextPtr ctxt, virDomainMemoryDefPtr def) { @@ -12437,7 +12438,7 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node, xmlNodePtr save = ctxt-node; ctxt-node = node; -if (virXPathUInt(string(./node), ctxt, def-targetNode) 0) { +if (virXPathUInt(string(./node), ctxt, def-targetNode) 0 ARCH_IS_X86(domDef-os.arch)) { virReportError(VIR_ERR_XML_ERROR, %s, _(invalid or missing value of memory device node)); goto cleanup; @@ -12457,6 +12458,7 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node, static virDomainMemoryDefPtr virDomainMemoryDefParseXML(xmlNodePtr memdevNode, + const virDomainDef *domDef, xmlXPathContextPtr ctxt, unsigned int flags) { @@ -12495,7 +12497,7 @@ virDomainMemoryDefParseXML(xmlNodePtr memdevNode, goto error; } -if (virDomainMemoryTargetDefParseXML(node, ctxt, def) 0) +if (virDomainMemoryTargetDefParseXML(node, domDef, ctxt, def) 0) goto error; if (virDomainDeviceInfoParseXML(memdevNode, NULL, def-info, flags) 0) @@ -12647,7 +12649,7 @@ virDomainDeviceDefParse(const char *xmlStr, goto error; break; case VIR_DOMAIN_DEVICE_MEMORY: -if (!(dev-data.memory = virDomainMemoryDefParseXML(node, ctxt, flags))) +if (!(dev-data.memory = virDomainMemoryDefParseXML(node, def, ctxt, flags))) goto error; break; case VIR_DOMAIN_DEVICE_NONE: @@ -16328,6 +16330,7 @@ virDomainDefParseXML(xmlDocPtr xml, for (i = 0; i n; i++) { virDomainMemoryDefPtr mem = virDomainMemoryDefParseXML(nodes[i], + def, ctxt, flags); if (!mem) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ae03618..51160e7 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4979,8 +4979,12 @@ qemuBuildMemoryBackendStr(unsigned long long size, *backendProps = NULL; *backendType = NULL; -/* memory devices could provide a invalid guest node */ -if (guestNode = virDomainNumaGetNodeCount(def-numa)) { +/* memory devices could provide a invalid guest node. Moreover, + * x86 guests needs at least one numa node to support memory + * hotplug + */ +if ((virDomainNumaGetNodeCount(def-numa) == 0 ARCH_IS_X86(def-os.arch)) || +guestNode virDomainNumaGetNodeCount(def-numa)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _(can't add memory backend for guest node '%d' as the guest has only '%zu' NUMA nodes configured), @@ -4991,10 +4995,12 @@ qemuBuildMemoryBackendStr(unsigned long long size, if (!(props = virJSONValueNewObject())) return -1; -memAccess = virDomainNumaGetNodeMemoryAccessMode(def-numa, guestNode); -if (virDomainNumatuneGetMode(def-numa, guestNode, mode) 0 -virDomainNumatuneGetMode(def-numa, -1, mode) 0) -mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT; +if (virDomainNumaGetNodeCount(def-numa)) { +memAccess = virDomainNumaGetNodeMemoryAccessMode(def-numa, guestNode); +if (virDomainNumatuneGetMode(def-numa, guestNode, mode) 0 +virDomainNumatuneGetMode(def-numa, -1, mode) 0) +mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT; +} if (pagesize == 0) { /* Find the huge page size we want to use */ @@ -9238,11 +9244,11 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; } -/* due to guest support, qemu would silently enable NUMA with one node - * once the memory hotplug backend is enabled. To avoid possible - * confusion we will enforce user originated numa configuration along - * with memory hotplug. */ -if
Re: [libvirt] [sandbox PATCH v3 13/22] Image: Add get_disk function to Source
On Tue, 2015-08-18 at 06:53 +, Eren Yagdiran wrote: Provide a way to know which disk image to use for the sandbox depending on the used source DockerSource will need to locate the topmost disk image among all the layers images --- virt-sandbox-image/sources/DockerSource.py | 18 ++ virt-sandbox-image/sources/Source.py | 4 2 files changed, 22 insertions(+) diff --git a/virt-sandbox-image/sources/DockerSource.py b/virt-sandbox-image/sources/DockerSource.py index 3e0362b..1e7f633 100644 --- a/virt-sandbox-image/sources/DockerSource.py +++ b/virt-sandbox-image/sources/DockerSource.py @@ -28,6 +28,8 @@ import traceback import os import subprocess import shutil +import random +import string class DockerConfParser(): @@ -372,6 +374,22 @@ class DockerSource(Source): parent = None imagetagid = parent +def get_disk(self,**args): +name = args['name'] +destdir = args['templatedir'] +imageList = self._get_image_list(name,destdir) +toplayer = imageList[0] +diskfile = destdir + / + toplayer + /template.qcow2 +configfile = destdir + / + toplayer + /template.json +tempfile = ''.join(random.choice(string.lowercase) for i in range(10)) This isn't really where the temporary disk should be created. I would let the get_disk function return the top-most image, and have the temporary disk created in the run function of virt-sandbox-image.py. More over the temporary disk image shouldn't be created next to the templates, but in the sandbox state directory. I wouldn't have it named randomly, but rather sandbox-name.qcow, where the sandbox-name would be computed based on the template name and an incremented counter. -- Cedric +tempfile = destdir + / + toplayer + / + tempfile + .qcow2 +cmd = [qemu-img,create,-q,-f,qcow2] +cmd.append(-o) +cmd.append(backing_fmt=qcow2,backing_file=%s % diskfile) +cmd.append(tempfile) +subprocess.call(cmd) +return (tempfile,configfile) + def get_command(self,configfile): configParser = DockerConfParser(configfile) commandToRun = configParser.getRunCommand() diff --git a/virt-sandbox-image/sources/Source.py b/virt-sandbox-image/sources/Source.py index 9daf62d..9a3da59 100644 --- a/virt-sandbox-image/sources/Source.py +++ b/virt-sandbox-image/sources/Source.py @@ -41,3 +41,7 @@ class Source(): @abstractmethod def get_command(self,**args): pass + +@abstractmethod +def get_disk(self,**args): + pass -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [sandbox PATCH v3 18/22] Add configuration object for environment variables
On Tue, 2015-08-18 at 06:53 +, Eren Yagdiran wrote: Add the config gobject to store custom environment variables. This will allow creating custom environment variables on a sandbox with a parameter formatted like --env key1=val1 --- libvirt-sandbox/Makefile.am | 2 + libvirt-sandbox/libvirt-sandbox-config-all.h | 1 + libvirt-sandbox/libvirt-sandbox-config-env.c | 199 +++ libvirt-sandbox/libvirt-sandbox-config-env.h | 78 +++ libvirt-sandbox/libvirt-sandbox-config.c | 187 - libvirt-sandbox/libvirt-sandbox-config.h | 12 ++ libvirt-sandbox/libvirt-sandbox.h| 1 + libvirt-sandbox/libvirt-sandbox.sym | 6 + 8 files changed, 485 insertions(+), 1 deletion(-) create mode 100644 libvirt-sandbox/libvirt-sandbox-config-env.c create mode 100644 libvirt-sandbox/libvirt-sandbox-config-env.h diff --git a/libvirt-sandbox/Makefile.am b/libvirt-sandbox/Makefile.am index 597803e..5383b0d 100644 --- a/libvirt-sandbox/Makefile.am +++ b/libvirt-sandbox/Makefile.am @@ -53,6 +53,7 @@ SANDBOX_RPC_FILES = \ SANDBOX_CONFIG_HEADER_FILES = \ libvirt-sandbox-config.h \ libvirt-sandbox-config-disk.h \ + libvirt-sandbox-config-env.h \ libvirt-sandbox-config-network.h \ libvirt-sandbox-config-network-address.h \ libvirt-sandbox-config-network-filterref-parameter.h \ @@ -92,6 +93,7 @@ SANDBOX_CONFIG_SOURCE_FILES = \ libvirt-sandbox-util.c \ libvirt-sandbox-config.c \ libvirt-sandbox-config-disk.c \ + libvirt-sandbox-config-env.c \ libvirt-sandbox-config-network.c \ libvirt-sandbox-config-network-address.c \ libvirt-sandbox-config-network-filterref.c \ diff --git a/libvirt-sandbox/libvirt-sandbox-config-all.h b/libvirt-sandbox/libvirt-sandbox-config-all.h index 8cb25c4..756bb3e 100644 --- a/libvirt-sandbox/libvirt-sandbox-config-all.h +++ b/libvirt-sandbox/libvirt-sandbox-config-all.h @@ -32,6 +32,7 @@ /* Local includes */ #include libvirt-sandbox/libvirt-sandbox-util.h #include libvirt-sandbox/libvirt-sandbox-config-disk.h +#include libvirt-sandbox/libvirt-sandbox-config-env.h #include libvirt-sandbox/libvirt-sandbox-config-mount.h #include libvirt-sandbox/libvirt-sandbox-config-mount-file.h #include libvirt-sandbox/libvirt-sandbox-config-mount-host-bind.h diff --git a/libvirt-sandbox/libvirt-sandbox-config-env.c b/libvirt-sandbox/libvirt-sandbox-config-env.c new file mode 100644 index 000..eaf0fb2 --- /dev/null +++ b/libvirt-sandbox/libvirt-sandbox-config-env.c @@ -0,0 +1,199 @@ +/* + * libvirt-sandbox-config-env.c: libvirt sandbox configuration + * + * Copyright (C) 2015 Universitat Politècnica de Catalunya. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Eren Yagdiran erenyagdi...@gmail.com + */ + +#include config.h +#include string.h + +#include libvirt-sandbox/libvirt-sandbox-config-all.h + +/** + * SECTION: libvirt-sandbox-config-env + * @short_description: Disk attachment configuration details + * @include: libvirt-sandbox/libvirt-sandbox.h + * @see_aloso: #GVirSandboxConfig + * + * Provides an object to store information about a environment variable in the sandbox + * + */ + +#define GVIR_SANDBOX_CONFIG_ENV_GET_PRIVATE(obj) \ +(G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_SANDBOX_TYPE_CONFIG_ENV, GVirSandboxConfigEnvPrivate)) + + +struct _GVirSandboxConfigEnvPrivate +{ +gchar *key; +gchar *value; +}; Any reason for not having removed that class and used a GHashMap instead? -- Cedric +G_DEFINE_TYPE(GVirSandboxConfigEnv, gvir_sandbox_config_env, G_TYPE_OBJECT); + + +enum { +PROP_0, +PROP_KEY, +PROP_VALUE +}; + +enum { +LAST_SIGNAL +}; + + + +static void gvir_sandbox_config_env_get_property(GObject *object, + guint prop_id, + GValue *value, +
[libvirt] [sandbox PATCH v3 17/22] Image: man file for virt-sandbox-image
--- bin/Makefile.am| 5 ++ bin/virt-sandbox-image.pod | 172 + 2 files changed, 177 insertions(+) create mode 100644 bin/virt-sandbox-image.pod diff --git a/bin/Makefile.am b/bin/Makefile.am index df4c7dc..5d7ff8a 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -23,6 +23,7 @@ POD_FILES = \ virt-sandbox-service-delete.pod \ virt-sandbox-service-reload.pod \ virt-sandbox-service-upgrade.pod \ + virt-sandbox-image.pod \ $(NULL) EXTRA_DIST = virt-sandbox-service \ virt-sandbox-image.in \ @@ -40,6 +41,7 @@ man1_MANS = \ virt-sandbox-service-delete.1 \ virt-sandbox-service-reload.1 \ virt-sandbox-service-upgrade.1 \ + virt-sandbox-image.1 \ $(NULL) POD2MAN = pod2man -c Virtualization Support -r $(PACKAGE)-$(VERSION) @@ -71,6 +73,9 @@ virt-sandbox-service-reload.1: virt-sandbox-service-reload.pod Makefile virt-sandbox-service-upgrade.1: virt-sandbox-service-upgrade.pod Makefile $(AM_V_GEN)$(POD2MAN) $ $(srcdir)/$@ +virt-sandbox-image.1: virt-sandbox-image.pod Makefile + $(AM_V_GEN)$(POD2MAN) $ $(srcdir)/$@ + CLEANFILES = $(man1_MANS) \ virt-sandbox-image diff --git a/bin/virt-sandbox-image.pod b/bin/virt-sandbox-image.pod new file mode 100644 index 000..a85fcd9 --- /dev/null +++ b/bin/virt-sandbox-image.pod @@ -0,0 +1,172 @@ +=head1 NAME + +virt-sandbox-image - Sandbox Container Image Tool + +=head1 SYNOPSIS + + {download,create,run,delete} + + commands: + +download Download template data + +createCreate image from template data + +run Run an already built image + +deleteDelete template data + +=head1 DESCRIPTION + +virt-sandbox-image.py is a sandbox container image tool developed in python. +This tool can download,create,run and delete templates which are provided by +different sources. This tool comes with Docker source by default. Other sources +can be implemented by extending source class + +=head1 OPTIONS + +=over 4 + +=item Bdownload name -s source -r registry -u username -p password -t template_directory + +Download a template by given name with a specified source. + +=over 6 + +=item Bname + +Template name to download + +=item B-s or --source + +Source parameter will try load source module under sources/ directory. Each source has to implement Source.py base class and register itself with a proper name +Default source is Docker. + +=item B-r or --registry + +Custom registry url for downloading data. This might need privileged credentials which can be specified by --username and --password parameters. + +=item B-u or --username + +Username for custom registry authentication + +=item B-p or --password + +Password for custom registry authentication + +=item B-t or --template-dir + +Custom directory for downloading template data + +=back + +=item Bcreate name imagepath format -s source -d driver + +Create already downloaded template into image with given format. + +=over 5 + +=item Bname + +Template name to download. + +=item Bimagepath + +Image path where template image will be stored. + +=item Bformat + +Image format e.g qcow2 + +=item B-s or --source + +Source parameter will try load source module under sources/ directory. Each source has to implement Source.py base class and register itself with a proper name +Default source is Docker. + +=item B-d or --driver + +Driver parameter can be specified with only supported driver by libvirt-sandbox. These are lxc:///, qemu:///session, qemu:///system. + +=back + +=item Brun name imagepath format -c command -n network -v volume -s source -d driver + +Run already built image. + +=over 6 + +=item Bname + +Template name to download. + +=item Bimagepath + +Image path where template image will be stored. + +=item B-c or --command + +Command for running a image. If it is not specified, virt-sandbox-image will try to load command params from specified source. E.g /bin/bash + +=item B-n or --network + +Network params will be passed directly to the virt-sandbox. More information about network params, See Cvirt-sandbox(8) + +=item B-v or --volume + +Volume params are for binding host-paths to the guest. E.g -v /home:/home will map /home directory from host to the guest. + +=item B-d or --driver + +Driver parameter can be specified with only supported driver by libvirt-sandbox. These are lxc:///, qemu:///session, qemu:///system. + +=back + +=item Bdelete name imagepath -s source + +Delete downloaded template data and its built image. + +=over 3 + +=item Bname + +Template name to delete. + +=item Bimagepath + +Image path where template data or image stays. + +=item B-s or --source + +Source parameter will try load source module under sources/ directory. Each source has to implement Source.py base class and register itself with a proper name +Default source is Docker. + +=back + +=back
Re: [libvirt] [sandbox PATCH v3 06/22] Image: Add check_writable and runtime resolver
On Tue, 2015-08-18 at 06:53 +, Eren Yagdiran wrote: These helper functions are for selecting right directories according to running user privileges --- virt-sandbox-image/virt-sandbox-image.py | 27 ++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index 9e98bf2..5917dd6 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -32,6 +32,8 @@ import sys import urllib2 import subprocess +template_dir = None +storage_dir = None default_privileged_template_dir = /var/lib/libvirt/templates default_home_dir = os.environ['HOME'] default_unprivileged_template_dir = default_home_dir + /.local/share/libvirt/templates @@ -40,6 +42,29 @@ default_unprivileged_storage_dir = default_unprivileged_template_dir + /storage debug = False verbose = False +def check_dir_writable(path): +if not os.access(path,os.W_OK): +return False +return True Is that function really useful? Can't you just call os.access instead of it? +def runtime_dir_resolver(): +global default_privileged_template_dir +global default_privileged_storage_dir +global default_unprivileged_template_dir +global default_unprivileged_storage_dir +global template_dir +global storage_dir +if(check_dir_writable(default_privileged_template_dir)): Better use os.access(default_privileged_template_dir, os.W_OK) here -- Cedric +template_dir = default_privileged_template_dir +storage_dir = default_privileged_storage_dir +return +template_dir = default_unprivileged_template_dir +storage_dir = default_unprivileged_storage_dir +if not os.path.exists(template_dir): +os.makedirs(template_dir) +if not os.path.exists(storage_dir): +os.makedirs(storage_dir) + sys.dont_write_byte_code = True import importlib @@ -380,8 +405,8 @@ def gen_create_args(subparser): parser.set_defaults(func=create) if __name__ == '__main__': +runtime_dir_resolver() parser = argparse.ArgumentParser(description='Sandbox Container Image Tool') - subparser = parser.add_subparsers(help=_(commands)) gen_download_args(subparser) gen_delete_args(subparser) -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [RFC PATCH 0/3] Implement mockup capabilities cache in QEMU tests
Since commit e8d55172544c1fafe31a9e09346bdebca4f0d6f9 qemu driver checks emulator capabilities during domain XML post-parse. However, test suite does not initialize it, therefore a condition to skip all checks if there is no cache supplied was added. This is actually a hack, whose sole purpose is to make existing test suite working. Additionally, it prevents from writing new tests for this particular functionality. This series attempts to solve this problem by implementing proper cache mockup in test suite. The main idea is to create a cache in standard way and put there a pre-defined capabilities set (which tests already have). The main problem here is to know emulator binary name, which is contained in the source XML. However, we have to create our cache before reading the XML. The simplest way to resolve this is to assume particular binary name from test name. Currently tests which assume cross-architecture binary are all prefixed with the architecture name (with one exception of keywrap tests which all assume /usr/bin/qemu-system-s390x and do not have s390- prefix in their name). This scheme works fine, unless we use native emulator binary. Here we have a mess. Most newer tests use /usr/bin/qemu, however there is a large number of tests which use /usr/libexec/qemu-kvm or /usr/bin/kvm (i guess these are leftovers from the epoch when qemu-kvm was a separate fork of qemu). This is currently not handled in any way, and these tests may report errors due to missing binaries (because virQEMUCapsCacheLookup() attempts to populate the cache automatically by querying the binary if not already known). There are several possible ways to resolve this: a) Add all possible names as aliases for /usr/bin/qemu b) Forbid to use oldstyle names at all in these tests c) Declare some prefix like kvm- for those tests who want to use /usr/libexec/qemu-kvm. Again, this would ban /usr/bin/kvm and /usr/bin/qemu-kvm (if not using aliases like in (b) d) Hardcode (optional) emulator name per test. IMHO a bad idea because number of tests is huge. e) Do some preparsing of the XML and extract binary name from it. Again, i disliked it for not being simple enough. I also thought about an alternate implementation which would patch postParseCallback and insert own function there which builds a cache. At this point binary name is already known from the XML. However, such a design looks like an ugly hack by itself, so i stopped going in this direction. Comments and opinions are welcome. Pavel Fedin (3): Implement virQEMUCapsCache mockup Use mockup cache Removed unneeded check src/qemu/qemu_capabilities.c | 10 +- src/qemu/qemu_capspriv.h | 36 +++ src/qemu/qemu_domain.c | 5 + tests/qemuagenttest.c| 9 - tests/qemuargv2xmltest.c | 5 + tests/qemuhotplugtest.c | 23 ++ tests/qemuxml2argvtest.c | 5 + tests/qemuxml2xmltest.c | 6 ++ tests/qemuxmlnstest.c| 5 + tests/testutilsqemu.c| 45 tests/testutilsqemu.h| 3 +++ 11 files changed, 130 insertions(+), 22 deletions(-) create mode 100644 src/qemu/qemu_capspriv.h mode change 100644 = 100755 tests/qemuagenttest.c mode change 100644 = 100755 tests/qemuhotplugtest.c mode change 100644 = 100755 tests/qemuxml2xmltest.c mode change 100644 = 100755 tests/testutilsqemu.c -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [RFC PATCH 3/3] Removed unneeded check
Since test suite now correctly creates capabilities cache, the hack is not needed any more. Signed-off-by: Pavel Fedin p.fe...@samsung.com --- src/qemu/qemu_domain.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 84e5fa5..11b28cb 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1039,10 +1039,7 @@ qemuDomainDefPostParse(virDomainDefPtr def, return ret; -/* This condition is actually a (temporary) hack for test suite which - * does not create capabilities cache */ -if (driver driver-qemuCapsCache) -qemuCaps = virQEMUCapsCacheLookup(driver-qemuCapsCache, def-emulator); +qemuCaps = virQEMUCapsCacheLookup(driver-qemuCapsCache, def-emulator); /* Add implicit PCI root controller if the machine has one */ switch (def-os.arch) { -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [sandbox PATCH v3 16/22] Image: Add Volume Support
On Tue, 2015-08-18 at 06:53 +, Eren Yagdiran wrote: Volumes let user to map host-paths into guest. Docker containers need volumes because its filesystem read-only by default. Please reword that wrong commit message... docker file system isn't read-only by default. -- Cedric --- virt-sandbox-image/sources/DockerSource.py | 12 virt-sandbox-image/sources/Source.py | 4 virt-sandbox-image/virt-sandbox-image.py | 22 ++ 3 files changed, 38 insertions(+) diff --git a/virt-sandbox-image/sources/DockerSource.py b/virt-sandbox-image/sources/DockerSource.py index 1e7f633..67bcf6b 100644 --- a/virt-sandbox-image/sources/DockerSource.py +++ b/virt-sandbox-image/sources/DockerSource.py @@ -30,6 +30,7 @@ import subprocess import shutil import random import string +import collections class DockerConfParser(): @@ -39,6 +40,13 @@ class DockerConfParser(): def getRunCommand(self): cmd = self.json_data['container_config']['Cmd'][2] return cmd[cmd.index('') + 1:cmd.rindex('')] +def getVolumes(self): +volumes = self.json_data['container_config']['Volumes'] +volumelist = [] +if isinstance(volumes,collections.Iterable): + for key,value in volumes.iteritems(): +volumelist.append(key) +return volumelist class DockerSource(Source): @@ -395,5 +403,9 @@ class DockerSource(Source): commandToRun = configParser.getRunCommand() return commandToRun +def get_volume(self,configfile): +configParser = DockerConfParser(configfile) +return configParser.getVolumes() + def debug(msg): sys.stderr.write(msg) diff --git a/virt-sandbox-image/sources/Source.py b/virt-sandbox-image/sources/Source.py index 9a3da59..8cc508e 100644 --- a/virt-sandbox-image/sources/Source.py +++ b/virt-sandbox-image/sources/Source.py @@ -45,3 +45,7 @@ class Source(): @abstractmethod def get_disk(self,**args): pass + +@abstractmethod +def get_volume(self,**args): + pass diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index 3ce3a8b..e554d8a 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -130,6 +130,7 @@ def check_connect(connectstr): def run(args): try: +global storage_dir if args.connect is not None: check_connect(args.connect) source = dynamic_source_loader(args.source) @@ -148,6 +149,25 @@ def run(args): if networkArgs is not None: params.append('-N') params.append(networkArgs) +allVolumes = source.get_volume(configfile) +volumeArgs = args.volume +if volumeArgs is not None: +allVolumes = allVolumes + volumeArgs +for volume in allVolumes: +volumeSplit = volume.split(:) +volumelen = len(volumeSplit) +if volumelen == 2: +hostPath = volumeSplit[0] +guestPath = volumeSplit[1] +elif volumelen == 1: +guestPath = volumeSplit[0] +hostPath = storage_dir + guestPath +if not os.path.exists(hostPath): +os.makedirs(hostPath) +else: +pass +params.append(--mount) +params.append(host-bind:%s=%s %(guestPath,hostPath)) params.append('--') params.append(commandToRun) cmd = cmd + params @@ -225,6 +245,8 @@ def gen_run_args(subparser): help=_(Igniter command for image)) parser.add_argument(-n,--network, help=_(Network params for running template)) +parser.add_argument(-v,--volume,action=append, +help=_(Volume params for running template)) parser.set_defaults(func=run) if __name__ == '__main__': -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 00/22] *** Virt-sandbox-image ***
V3 Changes: * License syntax fixed * Source abstract method get_env fixed * Discarding byte code generation now resides into a new commit * Template_dir and storage_dir refactored and runtime resolver is added for checking permissions * -f,--format parameter is refactored. Default is qcow2. * Ssl warning is now using stderr * get_disk method in Source now adds another layer with a randomized name Daniel P Berrange (1): Add virt-sandbox-image Eren Yagdiran (21): Fix virt-sandbox-image Image: Add Hooking Mechanism Image: virt-sandbox-image default dir constants Image: Discard caching bytecode Image: Add check_writable and runtime resolver Image: Add download function Image: Refactor create function Image: Add delete function Image: Add get_command function to Source Image: Add run args Image: Add check_connect function Image: Add get_disk function to Source Image: Add run function Image: Add network support Image: Add Volume Support Image: man file for virt-sandbox-image Add configuration object for environment variables Add environment parameter to virt-sandbox Common-init: Exporting custom environment variables Add testcase for custom environment variables Image: Add custom environment support .gitignore| 1 + bin/Makefile.am | 21 +- bin/virt-sandbox-image.in | 3 + bin/virt-sandbox-image.pod| 172 +++ bin/virt-sandbox.c| 14 + configure.ac | 2 + libvirt-sandbox/Makefile.am | 2 + libvirt-sandbox/libvirt-sandbox-config-all.h | 1 + libvirt-sandbox/libvirt-sandbox-config-env.c | 199 libvirt-sandbox/libvirt-sandbox-config-env.h | 78 + libvirt-sandbox/libvirt-sandbox-config.c | 187 +++- libvirt-sandbox/libvirt-sandbox-config.h | 12 + libvirt-sandbox/libvirt-sandbox-init-common.c | 30 ++ libvirt-sandbox/libvirt-sandbox.h | 1 + libvirt-sandbox/libvirt-sandbox.sym | 6 + libvirt-sandbox/tests/test-config.c | 10 + po/POTFILES.in| 1 + virt-sandbox-image/Makefile.am| 14 + virt-sandbox-image/sources/DockerSource.py| 421 ++ virt-sandbox-image/sources/Source.py | 55 virt-sandbox-image/sources/__init__.py| 26 ++ virt-sandbox-image/virt-sandbox-image.py | 299 ++ 22 files changed, 1550 insertions(+), 5 deletions(-) create mode 100644 bin/virt-sandbox-image.in create mode 100644 bin/virt-sandbox-image.pod create mode 100644 libvirt-sandbox/libvirt-sandbox-config-env.c create mode 100644 libvirt-sandbox/libvirt-sandbox-config-env.h create mode 100644 virt-sandbox-image/Makefile.am create mode 100644 virt-sandbox-image/sources/DockerSource.py create mode 100644 virt-sandbox-image/sources/Source.py create mode 100644 virt-sandbox-image/sources/__init__.py create mode 100755 virt-sandbox-image/virt-sandbox-image.py -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 11/22] Image: Add run args
Commandline parameters for running a template --- virt-sandbox-image/virt-sandbox-image.py | 13 + 1 file changed, 13 insertions(+) diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index 1da5150..d6b682f 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -178,6 +178,18 @@ def gen_create_args(subparser): help=_(format format for image)) parser.set_defaults(func=create) +def gen_run_args(subparser): +parser = subparser.add_parser(run, + help=_(Run a already built image)) +requires_name(parser) +requires_source(parser) +requires_connect(parser) +parser.add_argument(-t,--template-dir, +help=_(Template directory for saving templates)) +parser.add_argument(-i,--igniter, +help=_(Igniter command for image)) +parser.set_defaults(func=run) + if __name__ == '__main__': runtime_dir_resolver() parser = argparse.ArgumentParser(description='Sandbox Container Image Tool') @@ -185,6 +197,7 @@ if __name__ == '__main__': gen_download_args(subparser) gen_delete_args(subparser) gen_create_args(subparser) +gen_run_args(subparser) try: args = parser.parse_args() -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 21/22] Add testcase for custom environment variables
make check now includes testcase for environment variables --- libvirt-sandbox/tests/test-config.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/libvirt-sandbox/tests/test-config.c b/libvirt-sandbox/tests/test-config.c index da05187..ac10bab 100644 --- a/libvirt-sandbox/tests/test-config.c +++ b/libvirt-sandbox/tests/test-config.c @@ -58,6 +58,13 @@ int main(int argc, char **argv) host-bind:/tmp=, NULL }; + + const gchar *envs[] = { +key1=val1, +key2=val2, +NULL +}; + const gchar *disks[] = { file:dbdata=/tmp/img.blah,format=qcow2, file:cache=/tmp/img.qcow2, @@ -103,6 +110,9 @@ int main(int argc, char **argv) if (!gvir_sandbox_config_add_mount_strv(cfg1, (gchar**)mounts, err)) goto cleanup; +if (!gvir_sandbox_config_add_env_strv(cfg1, (gchar**)envs, err)) +goto cleanup; + if (!gvir_sandbox_config_add_disk_strv(cfg1, (gchar**)disks, err)) goto cleanup; -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 14/22] Image: Add run function
Run an already-built template If there is no execution command specified by user, source.get_command will find the command to invoke --- virt-sandbox-image/virt-sandbox-image.py | 25 + 1 file changed, 25 insertions(+) diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index c46abd4..278d19a 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -128,6 +128,31 @@ def check_connect(connectstr): raise ValueError(%s is not supported by Virt-sandbox %connectstr) return True +def run(args): +try: +if args.connect is not None: +check_connect(args.connect) +source = dynamic_source_loader(args.source) +diskfile,configfile = source.get_disk(name=args.name,templatedir=args.template_dir) + +format = qcow2 +commandToRun = args.igniter +if commandToRun is None: +commandToRun = source.get_command(configfile) +cmd = ['virt-sandbox'] +if args.connect is not None: +cmd.append(-c) +cmd.append(args.connect) +params = ['-m','host-image:/=%s,format=%s' %(diskfile,format), + '--', + commandToRun] +cmd = cmd + params +subprocess.call(cmd) +subprocess.call([rm, -rf, diskfile]) + +except Exception,e: +print Run Error %s % str(e) + def requires_name(parser): parser.add_argument(name, help=_(name of the template)) -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 07/22] Image: Add download function
Refactor download function from virt-sandbox-image to use the newly introduced Source abstract class. The docker-specific download code is moved to a new DockerSource class. --- virt-sandbox-image/Makefile.am | 1 + virt-sandbox-image/sources/DockerSource.py | 214 + virt-sandbox-image/sources/Source.py | 4 + virt-sandbox-image/virt-sandbox-image.py | 204 +-- 4 files changed, 251 insertions(+), 172 deletions(-) create mode 100644 virt-sandbox-image/sources/DockerSource.py diff --git a/virt-sandbox-image/Makefile.am b/virt-sandbox-image/Makefile.am index 5ab4d2e..8188c80 100644 --- a/virt-sandbox-image/Makefile.am +++ b/virt-sandbox-image/Makefile.am @@ -8,6 +8,7 @@ install-data-local: $(INSTALL) -m 0755 $(srcdir)/virt-sandbox-image.py $(DESTDIR)$(pkgpythondir) $(INSTALL) -m 0644 $(srcdir)/sources/__init__.py $(DESTDIR)$(pkgpythondir)/sources $(INSTALL) -m 0644 $(srcdir)/sources/Source.py $(DESTDIR)$(pkgpythondir)/sources + $(INSTALL) -m 0644 $(srcdir)/sources/DockerSource.py $(DESTDIR)$(pkgpythondir)/sources uninstall-local: rm -f $(DESTDIR)$(pkgpythondir) diff --git a/virt-sandbox-image/sources/DockerSource.py b/virt-sandbox-image/sources/DockerSource.py new file mode 100644 index 000..f3cf5f3 --- /dev/null +++ b/virt-sandbox-image/sources/DockerSource.py @@ -0,0 +1,214 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2015 Universitat Polit??cnica de Catalunya. +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Author: Eren Yagdiran erenyagdi...@gmail.com +# + +from Source import Source +import urllib2 +import sys +import json +import traceback +import os +import subprocess +import shutil + +class DockerSource(Source): + +www_auth_username = None +www_auth_password = None + +def __init__(self): +self.default_index_server = index.docker.io + +def _check_cert_validate(self): +major = sys.version_info.major +SSL_WARNING = SSL certificates couldn't be validated by default. You need to have 2.7.9/3.4.3 or higher +SSL_WARNING +=\nSee https://bugs.python.org/issue22417\n; +py2_7_9_hexversion = 34015728 +py3_4_3_hexversion = 50594800 +if (major == 2 and sys.hexversion py2_7_9_hexversion) or (major == 3 and sys.hexversion py3_4_3_hexversion): +sys.stderr.write(SSL_WARNING) + +def download_template(self,**args): +name = args['name'] +registry = args['registry'] if args['registry'] is not None else self.default_index_server +username = args['username'] +password = args['password'] +templatedir = args['templatedir'] +self._download_template(name,registry,username,password,templatedir) + +def _download_template(self,name, server,username,password,destdir): + +if username is not None: +self.www_auth_username = username +self.www_auth_password = password + +self._check_cert_validate() +tag = latest +offset = name.find(':') +if offset != -1: +tag = name[offset + 1:] +name = name[0:offset] +try: +(data, res) = self._get_json(server, /v1/repositories/ + name + /images, + {X-Docker-Token: true}) +except urllib2.HTTPError, e: +raise ValueError([Image '%s' does not exist % name]) + +registryserver = res.info().getheader('X-Docker-Endpoints') +token = res.info().getheader('X-Docker-Token') +checksums = {} +for layer in data: +pass +(data, res) = self._get_json(registryserver, /v1/repositories/ + name + /tags, + { Authorization: Token + token }) + +cookie = res.info().getheader('Set-Cookie') + +if not tag in data: +raise ValueError([Tag '%s' does not exist for image '%s' % (tag, name)]) +imagetagid = data[tag] + +(data, res) = self._get_json(registryserver, /v1/images/ + imagetagid + /ancestry, + { Authorization: Token +token }) + +if data[0] != imagetagid: +raise ValueError([Expected first layer id '%s' to match image id
[libvirt] [sandbox PATCH v3 08/22] Image: Refactor create function
Move the docker-related code to the DockerSource and use the Source mechanism --- virt-sandbox-image/sources/DockerSource.py | 100 + virt-sandbox-image/sources/Source.py | 4 ++ virt-sandbox-image/virt-sandbox-image.py | 76 +- 3 files changed, 121 insertions(+), 59 deletions(-) diff --git a/virt-sandbox-image/sources/DockerSource.py b/virt-sandbox-image/sources/DockerSource.py index f3cf5f3..09eea85 100644 --- a/virt-sandbox-image/sources/DockerSource.py +++ b/virt-sandbox-image/sources/DockerSource.py @@ -210,5 +210,105 @@ class DockerSource(Source): debug(FAIL %s\n % str(e)) raise +def create_template(self,**args): +name = args['name'] +connect = args['connect'] +templatedir = args['templatedir'] +format = args['format'] +format = format if format is not None else self.default_disk_format + +self._create_template(name, + connect, + templatedir, + format) + +def _create_template(self,name,connect,templatedir,format): +self._check_disk_format(format) +imagelist = self._get_image_list(name,templatedir) +imagelist.reverse() + +parentImage = None +for imagetagid in imagelist: +templateImage = templatedir + / + imagetagid + /template. + format +cmd = [qemu-img,create,-f,qcow2] +if parentImage is not None: +cmd.append(-o) +cmd.append(backing_fmt=qcow2,backing_file=%s % parentImage) +cmd.append(templateImage) +if parentImage is None: +cmd.append(10G) +subprocess.call(cmd) + +if parentImage is None: +self._format_disk(templateImage,format,connect) + +self._extract_tarballs(templatedir + / + imagetagid + /template.,format,connect) +parentImage = templateImage + + +def _check_disk_format(self,format): +supportedFormats = ['qcow2'] +if not format in supportedFormats: +raise ValueError([Unsupported image format %s % format]) + +def _get_image_list(self,name,destdir): +imageparent = {} +imagenames = {} +imagedirs = os.listdir(destdir) +for imagetagid in imagedirs: +indexfile = destdir + / + imagetagid + /index.json +if os.path.exists(indexfile): +with open(indexfile,r) as f: +index = json.load(f) +imagenames[index[name]] = imagetagid +jsonfile = destdir + / + imagetagid + /template.json +if os.path.exists(jsonfile): +with open(jsonfile,r) as f: +template = json.load(f) +parent = template.get(parent,None) +if parent: +imageparent[imagetagid] = parent +if not name in imagenames: +raise ValueError([Image %s does not exist locally %name]) +imagetagid = imagenames[name] +imagelist = [] +while imagetagid != None: +imagelist.append(imagetagid) +parent = imageparent.get(imagetagid,None) +imagetagid = parent +return imagelist + +def _format_disk(self,disk,format,connect): +cmd = ['virt-sandbox'] +if connect is not None: +cmd.append(-c) +cmd.append(connect) +cmd.append(-p) +params = ['--disk=file:disk_image=%s,format=%s' %(disk,format), + '/sbin/mkfs.ext3', + '/dev/disk/by-tag/disk_image'] +cmd = cmd + params +subprocess.call(cmd) + +def _extract_tarballs(self,directory,format,connect): +tempdir = /mnt +tarfile = directory + tar.gz +diskfile = directory + qcow2 +cmd = ['virt-sandbox'] +if connect is not None: +cmd.append(-c) +cmd.append(connect) +cmd.append(-p) +params = ['-m', + 'host-image:/mnt=%s,format=%s' %(diskfile,format), + '--', + '/bin/tar', + 'zxf', + '%s' %tarfile, + '-C', + '/mnt'] +cmd = cmd + params +subprocess.call(cmd) + def debug(msg): sys.stderr.write(msg) diff --git a/virt-sandbox-image/sources/Source.py b/virt-sandbox-image/sources/Source.py index 8751689..6ac08dc 100644 --- a/virt-sandbox-image/sources/Source.py +++ b/virt-sandbox-image/sources/Source.py @@ -29,3 +29,7 @@ class Source(): @abstractmethod def download_template(self,**args): pass + +@abstractmethod +def create_template(self,**args): + pass diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index 4f371d7..745401c 100755 ---
[libvirt] [sandbox PATCH v3 06/22] Image: Add check_writable and runtime resolver
These helper functions are for selecting right directories according to running user privileges --- virt-sandbox-image/virt-sandbox-image.py | 27 ++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index 9e98bf2..5917dd6 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -32,6 +32,8 @@ import sys import urllib2 import subprocess +template_dir = None +storage_dir = None default_privileged_template_dir = /var/lib/libvirt/templates default_home_dir = os.environ['HOME'] default_unprivileged_template_dir = default_home_dir + /.local/share/libvirt/templates @@ -40,6 +42,29 @@ default_unprivileged_storage_dir = default_unprivileged_template_dir + /storage debug = False verbose = False +def check_dir_writable(path): +if not os.access(path,os.W_OK): +return False +return True + +def runtime_dir_resolver(): +global default_privileged_template_dir +global default_privileged_storage_dir +global default_unprivileged_template_dir +global default_unprivileged_storage_dir +global template_dir +global storage_dir +if(check_dir_writable(default_privileged_template_dir)): +template_dir = default_privileged_template_dir +storage_dir = default_privileged_storage_dir +return +template_dir = default_unprivileged_template_dir +storage_dir = default_unprivileged_storage_dir +if not os.path.exists(template_dir): +os.makedirs(template_dir) +if not os.path.exists(storage_dir): +os.makedirs(storage_dir) + sys.dont_write_byte_code = True import importlib @@ -380,8 +405,8 @@ def gen_create_args(subparser): parser.set_defaults(func=create) if __name__ == '__main__': +runtime_dir_resolver() parser = argparse.ArgumentParser(description='Sandbox Container Image Tool') - subparser = parser.add_subparsers(help=_(commands)) gen_download_args(subparser) gen_delete_args(subparser) -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 15/22] Image: Add network support
Virt-sandbox-image will pass exact network arguments to virt-sandbox --- virt-sandbox-image/virt-sandbox-image.py | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index 278d19a..3ce3a8b 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -143,9 +143,13 @@ def run(args): if args.connect is not None: cmd.append(-c) cmd.append(args.connect) -params = ['-m','host-image:/=%s,format=%s' %(diskfile,format), - '--', - commandToRun] +params = ['-m','host-image:/=%s,format=%s' %(diskfile,format)] +networkArgs = args.network +if networkArgs is not None: +params.append('-N') +params.append(networkArgs) +params.append('--') +params.append(commandToRun) cmd = cmd + params subprocess.call(cmd) subprocess.call([rm, -rf, diskfile]) @@ -219,6 +223,8 @@ def gen_run_args(subparser): help=_(Template directory for saving templates)) parser.add_argument(-i,--igniter, help=_(Igniter command for image)) +parser.add_argument(-n,--network, +help=_(Network params for running template)) parser.set_defaults(func=run) if __name__ == '__main__': -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 16/22] Image: Add Volume Support
Volumes let user to map host-paths into guest. Docker containers need volumes because its filesystem read-only by default. --- virt-sandbox-image/sources/DockerSource.py | 12 virt-sandbox-image/sources/Source.py | 4 virt-sandbox-image/virt-sandbox-image.py | 22 ++ 3 files changed, 38 insertions(+) diff --git a/virt-sandbox-image/sources/DockerSource.py b/virt-sandbox-image/sources/DockerSource.py index 1e7f633..67bcf6b 100644 --- a/virt-sandbox-image/sources/DockerSource.py +++ b/virt-sandbox-image/sources/DockerSource.py @@ -30,6 +30,7 @@ import subprocess import shutil import random import string +import collections class DockerConfParser(): @@ -39,6 +40,13 @@ class DockerConfParser(): def getRunCommand(self): cmd = self.json_data['container_config']['Cmd'][2] return cmd[cmd.index('') + 1:cmd.rindex('')] +def getVolumes(self): +volumes = self.json_data['container_config']['Volumes'] +volumelist = [] +if isinstance(volumes,collections.Iterable): + for key,value in volumes.iteritems(): +volumelist.append(key) +return volumelist class DockerSource(Source): @@ -395,5 +403,9 @@ class DockerSource(Source): commandToRun = configParser.getRunCommand() return commandToRun +def get_volume(self,configfile): +configParser = DockerConfParser(configfile) +return configParser.getVolumes() + def debug(msg): sys.stderr.write(msg) diff --git a/virt-sandbox-image/sources/Source.py b/virt-sandbox-image/sources/Source.py index 9a3da59..8cc508e 100644 --- a/virt-sandbox-image/sources/Source.py +++ b/virt-sandbox-image/sources/Source.py @@ -45,3 +45,7 @@ class Source(): @abstractmethod def get_disk(self,**args): pass + +@abstractmethod +def get_volume(self,**args): + pass diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index 3ce3a8b..e554d8a 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -130,6 +130,7 @@ def check_connect(connectstr): def run(args): try: +global storage_dir if args.connect is not None: check_connect(args.connect) source = dynamic_source_loader(args.source) @@ -148,6 +149,25 @@ def run(args): if networkArgs is not None: params.append('-N') params.append(networkArgs) +allVolumes = source.get_volume(configfile) +volumeArgs = args.volume +if volumeArgs is not None: +allVolumes = allVolumes + volumeArgs +for volume in allVolumes: +volumeSplit = volume.split(:) +volumelen = len(volumeSplit) +if volumelen == 2: +hostPath = volumeSplit[0] +guestPath = volumeSplit[1] +elif volumelen == 1: +guestPath = volumeSplit[0] +hostPath = storage_dir + guestPath +if not os.path.exists(hostPath): +os.makedirs(hostPath) +else: +pass +params.append(--mount) +params.append(host-bind:%s=%s %(guestPath,hostPath)) params.append('--') params.append(commandToRun) cmd = cmd + params @@ -225,6 +245,8 @@ def gen_run_args(subparser): help=_(Igniter command for image)) parser.add_argument(-n,--network, help=_(Network params for running template)) +parser.add_argument(-v,--volume,action=append, +help=_(Volume params for running template)) parser.set_defaults(func=run) if __name__ == '__main__': -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 18/22] Add configuration object for environment variables
Add the config gobject to store custom environment variables. This will allow creating custom environment variables on a sandbox with a parameter formatted like --env key1=val1 --- libvirt-sandbox/Makefile.am | 2 + libvirt-sandbox/libvirt-sandbox-config-all.h | 1 + libvirt-sandbox/libvirt-sandbox-config-env.c | 199 +++ libvirt-sandbox/libvirt-sandbox-config-env.h | 78 +++ libvirt-sandbox/libvirt-sandbox-config.c | 187 - libvirt-sandbox/libvirt-sandbox-config.h | 12 ++ libvirt-sandbox/libvirt-sandbox.h| 1 + libvirt-sandbox/libvirt-sandbox.sym | 6 + 8 files changed, 485 insertions(+), 1 deletion(-) create mode 100644 libvirt-sandbox/libvirt-sandbox-config-env.c create mode 100644 libvirt-sandbox/libvirt-sandbox-config-env.h diff --git a/libvirt-sandbox/Makefile.am b/libvirt-sandbox/Makefile.am index 597803e..5383b0d 100644 --- a/libvirt-sandbox/Makefile.am +++ b/libvirt-sandbox/Makefile.am @@ -53,6 +53,7 @@ SANDBOX_RPC_FILES = \ SANDBOX_CONFIG_HEADER_FILES = \ libvirt-sandbox-config.h \ libvirt-sandbox-config-disk.h \ + libvirt-sandbox-config-env.h \ libvirt-sandbox-config-network.h \ libvirt-sandbox-config-network-address.h \ libvirt-sandbox-config-network-filterref-parameter.h \ @@ -92,6 +93,7 @@ SANDBOX_CONFIG_SOURCE_FILES = \ libvirt-sandbox-util.c \ libvirt-sandbox-config.c \ libvirt-sandbox-config-disk.c \ + libvirt-sandbox-config-env.c \ libvirt-sandbox-config-network.c \ libvirt-sandbox-config-network-address.c \ libvirt-sandbox-config-network-filterref.c \ diff --git a/libvirt-sandbox/libvirt-sandbox-config-all.h b/libvirt-sandbox/libvirt-sandbox-config-all.h index 8cb25c4..756bb3e 100644 --- a/libvirt-sandbox/libvirt-sandbox-config-all.h +++ b/libvirt-sandbox/libvirt-sandbox-config-all.h @@ -32,6 +32,7 @@ /* Local includes */ #include libvirt-sandbox/libvirt-sandbox-util.h #include libvirt-sandbox/libvirt-sandbox-config-disk.h +#include libvirt-sandbox/libvirt-sandbox-config-env.h #include libvirt-sandbox/libvirt-sandbox-config-mount.h #include libvirt-sandbox/libvirt-sandbox-config-mount-file.h #include libvirt-sandbox/libvirt-sandbox-config-mount-host-bind.h diff --git a/libvirt-sandbox/libvirt-sandbox-config-env.c b/libvirt-sandbox/libvirt-sandbox-config-env.c new file mode 100644 index 000..eaf0fb2 --- /dev/null +++ b/libvirt-sandbox/libvirt-sandbox-config-env.c @@ -0,0 +1,199 @@ +/* + * libvirt-sandbox-config-env.c: libvirt sandbox configuration + * + * Copyright (C) 2015 Universitat Polit??cnica de Catalunya. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Eren Yagdiran erenyagdi...@gmail.com + */ + +#include config.h +#include string.h + +#include libvirt-sandbox/libvirt-sandbox-config-all.h + +/** + * SECTION: libvirt-sandbox-config-env + * @short_description: Disk attachment configuration details + * @include: libvirt-sandbox/libvirt-sandbox.h + * @see_aloso: #GVirSandboxConfig + * + * Provides an object to store information about a environment variable in the sandbox + * + */ + +#define GVIR_SANDBOX_CONFIG_ENV_GET_PRIVATE(obj) \ +(G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_SANDBOX_TYPE_CONFIG_ENV, GVirSandboxConfigEnvPrivate)) + + +struct _GVirSandboxConfigEnvPrivate +{ +gchar *key; +gchar *value; +}; + +G_DEFINE_TYPE(GVirSandboxConfigEnv, gvir_sandbox_config_env, G_TYPE_OBJECT); + + +enum { +PROP_0, +PROP_KEY, +PROP_VALUE +}; + +enum { +LAST_SIGNAL +}; + + + +static void gvir_sandbox_config_env_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ +GVirSandboxConfigEnv *config = GVIR_SANDBOX_CONFIG_ENV(object); +GVirSandboxConfigEnvPrivate *priv = config-priv; + +switch (prop_id) { +case PROP_KEY:
[libvirt] [sandbox PATCH v3 13/22] Image: Add get_disk function to Source
Provide a way to know which disk image to use for the sandbox depending on the used source DockerSource will need to locate the topmost disk image among all the layers images --- virt-sandbox-image/sources/DockerSource.py | 18 ++ virt-sandbox-image/sources/Source.py | 4 2 files changed, 22 insertions(+) diff --git a/virt-sandbox-image/sources/DockerSource.py b/virt-sandbox-image/sources/DockerSource.py index 3e0362b..1e7f633 100644 --- a/virt-sandbox-image/sources/DockerSource.py +++ b/virt-sandbox-image/sources/DockerSource.py @@ -28,6 +28,8 @@ import traceback import os import subprocess import shutil +import random +import string class DockerConfParser(): @@ -372,6 +374,22 @@ class DockerSource(Source): parent = None imagetagid = parent +def get_disk(self,**args): +name = args['name'] +destdir = args['templatedir'] +imageList = self._get_image_list(name,destdir) +toplayer = imageList[0] +diskfile = destdir + / + toplayer + /template.qcow2 +configfile = destdir + / + toplayer + /template.json +tempfile = ''.join(random.choice(string.lowercase) for i in range(10)) +tempfile = destdir + / + toplayer + / + tempfile + .qcow2 +cmd = [qemu-img,create,-q,-f,qcow2] +cmd.append(-o) +cmd.append(backing_fmt=qcow2,backing_file=%s % diskfile) +cmd.append(tempfile) +subprocess.call(cmd) +return (tempfile,configfile) + def get_command(self,configfile): configParser = DockerConfParser(configfile) commandToRun = configParser.getRunCommand() diff --git a/virt-sandbox-image/sources/Source.py b/virt-sandbox-image/sources/Source.py index 9daf62d..9a3da59 100644 --- a/virt-sandbox-image/sources/Source.py +++ b/virt-sandbox-image/sources/Source.py @@ -41,3 +41,7 @@ class Source(): @abstractmethod def get_command(self,**args): pass + +@abstractmethod +def get_disk(self,**args): + pass -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 02/22] Fix virt-sandbox-image
Authentication fix for Docker REST API. --- virt-sandbox-image/virt-sandbox-image.py | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index 4f5443b..a9cb0ff 100644 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -1,8 +1,10 @@ #!/usr/bin/python -Es # # Authors: Daniel P. Berrange berra...@redhat.com +# Eren Yagdiran erenyagdi...@gmail.com # # Copyright (C) 2013 Red Hat, Inc. +# Copyright (C) 2015 Universitat Polit??cnica de Catalunya. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -166,7 +168,7 @@ def download_template(name, server, destdir): # or more parents, in a linear stack. Here we are getting the list # of layers for the image with the tag we used. (data, res) = get_json(registryserver, /v1/images/ + imagetagid + /ancestry, - { Cookie: cookie }) + { Authorization: Token + token }) if data[0] != imagetagid: raise ValueError([Expected first layer id '%s' to match image id '%s', @@ -188,9 +190,9 @@ def download_template(name, server, destdir): if not os.path.exists(jsonfile) or not os.path.exists(datafile): # The '/json' URL gives us some metadata about the layer res = save_data(registryserver, /v1/images/ + layerid + /json, -{ Cookie: cookie }, jsonfile) +{ Authorization: Token + token }, jsonfile) createdFiles.append(jsonfile) -layersize = int(res.info().getheader(x-docker-size)) +layersize = int(res.info().getheader(Content-Length)) datacsum = None if layerid in checksums: @@ -199,7 +201,7 @@ def download_template(name, server, destdir): # and the '/layer' URL is the actual payload, provided # as a tar.gz archive save_data(registryserver, /v1/images/ + layerid + /layer, - { Cookie: cookie }, datafile, datacsum, layersize) + { Authorization: Token + token }, datafile, datacsum, layersize) createdFiles.append(datafile) # Strangely the 'json' data for a layer doesn't include -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 01/22] Add virt-sandbox-image
From: Daniel P Berrange berra...@redhat.com virt-sandbox-image.py is a python script that lets you download Docker images easily. It is a proof of concept code and consumes Docker Rest API. --- po/POTFILES.in | 1 + virt-sandbox-image/virt-sandbox-image.py | 394 +++ 2 files changed, 395 insertions(+) create mode 100644 virt-sandbox-image/virt-sandbox-image.py diff --git a/po/POTFILES.in b/po/POTFILES.in index afcb050..7204112 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -11,3 +11,4 @@ libvirt-sandbox/libvirt-sandbox-context-interactive.c libvirt-sandbox/libvirt-sandbox-init-common.c libvirt-sandbox/libvirt-sandbox-rpcpacket.c libvirt-sandbox/libvirt-sandbox-util.c +virt-sandbox-image/virt-sandbox-image.py diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py new file mode 100644 index 000..4f5443b --- /dev/null +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -0,0 +1,394 @@ +#!/usr/bin/python -Es +# +# Authors: Daniel P. Berrange berra...@redhat.com +# +# Copyright (C) 2013 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +import argparse +import gettext +import hashlib +import json +import os +import os.path +import shutil +import sys +import urllib2 +import subprocess + +default_index_server = index.docker.io +default_template_dir = /var/lib/libvirt/templates + +debug = True +verbose = True + +gettext.bindtextdomain(libvirt-sandbox, /usr/share/locale) +gettext.textdomain(libvirt-sandbox) +try: +gettext.install(libvirt-sandbox, +localedir=/usr/share/locale, +unicode=False, +codeset = 'utf-8') +except IOError: +import __builtin__ +__builtin__.__dict__['_'] = unicode + + +def debug(msg): +sys.stderr.write(msg) + +def info(msg): +sys.stdout.write(msg) + +def get_url(server, path, headers): +url = https://; + server + path +debug( Fetching %s... % url) +req = urllib2.Request(url=url) + +if json: +req.add_header(Accept, application/json) + +for h in headers.keys(): +req.add_header(h, headers[h]) + +return urllib2.urlopen(req) + +def get_json(server, path, headers): +try: +res = get_url(server, path, headers) +data = json.loads(res.read()) +debug(OK\n) +return (data, res) +except Exception, e: +debug(FAIL %s\n % str(e)) +raise + +def save_data(server, path, headers, dest, checksum=None, datalen=None): +try: +res = get_url(server, path, headers) + +csum = None +if checksum is not None: +csum = hashlib.sha256() + +pattern = [., o, O, o] +patternIndex = 0 +donelen = 0 + +with open(dest, w) as f: +while 1: +buf = res.read(1024*64) +if not buf: +break +if csum is not None: +csum.update(buf) +f.write(buf) + +if datalen is not None: +donelen = donelen + len(buf) +debug(\x1b[s%s (%5d Kb of %5d Kb)\x1b8 % ( +pattern[patternIndex], (donelen/1024), (datalen/1024) +)) +patternIndex = (patternIndex + 1) % 4 + +debug(\x1b[K) +if csum is not None: +csumstr = sha256: + csum.hexdigest() +if csumstr != checksum: +debug(FAIL checksum '%s' does not match '%s' % (csumstr, checksum)) +os.remove(dest) +raise IOError(Checksum '%s' for data does not match '%s' % (csumstr, checksum)) +debug(OK\n) +return res +except Exception, e: +debug(FAIL %s\n % str(e)) +raise + + +def download_template(name, server, destdir): +tag = latest + +offset = name.find(':') +if offset != -1: +tag = name[offset + 1:] +name = name[0:offset] + +# First we must ask the index server about the image name. THe +# index server will return an auth token we can use when talking +# to the registry server. We need this token even when anonymous +try: +(data, res) = get_json(server, /v1/repositories/ + name + /images, +
[libvirt] [sandbox PATCH v3 20/22] Common-init: Exporting custom environment variables
Common-init reads config file and export custom environment variables from config file and apply them to the running sandbox. --- libvirt-sandbox/libvirt-sandbox-init-common.c | 30 +++ 1 file changed, 30 insertions(+) diff --git a/libvirt-sandbox/libvirt-sandbox-init-common.c b/libvirt-sandbox/libvirt-sandbox-init-common.c index d35f760..0b0aa98 100644 --- a/libvirt-sandbox/libvirt-sandbox-init-common.c +++ b/libvirt-sandbox/libvirt-sandbox-init-common.c @@ -336,6 +336,33 @@ static gboolean setup_network(GVirSandboxConfig *config, GError **error) } +static gboolean setup_custom_env(GVirSandboxConfig *config, GError **error) +{ +GList *envs, *tmp; +gboolean ret = FALSE; +gchar *key = NULL; +gchar *value = NULL; + +envs = tmp = gvir_sandbox_config_get_envs(config); + +while (tmp) { +GVirSandboxConfigEnv *env = GVIR_SANDBOX_CONFIG_ENV(tmp-data); +key = g_strdup(gvir_sandbox_config_env_get_key(env)); +value = g_strdup(gvir_sandbox_config_env_get_value(env)); +if(setenv(key,value,1)!=0) +goto cleanup; +g_free(key); +g_free(value); +tmp = tmp-next; +} + +ret = TRUE; + cleanup: +g_list_foreach(envs, (GFunc)g_object_unref, NULL); +g_list_free(envs); +return ret; +} + static int change_user(const gchar *user, uid_t uid, gid_t gid, @@ -1262,6 +1289,9 @@ int main(int argc, char **argv) { if (!setup_disk_tags()) exit(EXIT_FAILURE); +if (!setup_custom_env(config, error)) +goto error; + if (!setup_network(config, error)) goto error; -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 03/22] Image: Add Hooking Mechanism
Any custom source provider can be added to virt-sandbox-image as a source --- .gitignore | 1 + bin/Makefile.am | 16 bin/virt-sandbox-image.in| 3 +++ configure.ac | 2 ++ virt-sandbox-image/Makefile.am | 13 + virt-sandbox-image/sources/Source.py | 27 +++ virt-sandbox-image/sources/__init__.py | 26 ++ virt-sandbox-image/virt-sandbox-image.py | 15 +-- 8 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 bin/virt-sandbox-image.in create mode 100644 virt-sandbox-image/Makefile.am create mode 100644 virt-sandbox-image/sources/Source.py create mode 100644 virt-sandbox-image/sources/__init__.py mode change 100644 = 100755 virt-sandbox-image/virt-sandbox-image.py diff --git a/.gitignore b/.gitignore index f77ea12..ef5b5aa 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,4 @@ bin/virt-sandbox bin/virt-sandbox-service-util build/ bin/*.1 +bin/virt-sandbox-image diff --git a/bin/Makefile.am b/bin/Makefile.am index 416f86f..df4c7dc 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -3,7 +3,11 @@ bin_PROGRAMS = virt-sandbox libexec_PROGRAMS = virt-sandbox-service-util -bin_SCRIPTS = virt-sandbox-service +bin_SCRIPTS = virt-sandbox-service \ + virt-sandbox-image + +virt-sandbox-image: virt-sandbox-image.in + sed -e 's,[@]pkgpythondir[@],$(pkgpythondir),g' $ $@ virtsandboxcompdir = $(datarootdir)/bash-completion/completions/ @@ -20,8 +24,11 @@ POD_FILES = \ virt-sandbox-service-reload.pod \ virt-sandbox-service-upgrade.pod \ $(NULL) -EXTRA_DIST = $(bin_SCRIPTS) $(POD_FILES) virt-sandbox-service-bash-completion.sh virt-sandbox-service.logrotate -EXTRA_DIST += virt-sandbox-service-bash-completion.sh +EXTRA_DIST = virt-sandbox-service \ + virt-sandbox-image.in \ + $(POD_FILES) \ + virt-sandbox-service-bash-completion.sh \ + virt-sandbox-service.logrotate man1_MANS = \ virt-sandbox.1 \ @@ -64,7 +71,8 @@ virt-sandbox-service-reload.1: virt-sandbox-service-reload.pod Makefile virt-sandbox-service-upgrade.1: virt-sandbox-service-upgrade.pod Makefile $(AM_V_GEN)$(POD2MAN) $ $(srcdir)/$@ -CLEANFILES = $(man1_MANS) +CLEANFILES = $(man1_MANS) \ + virt-sandbox-image virt_sandbox_SOURCES = virt-sandbox.c virt_sandbox_CFLAGS = \ diff --git a/bin/virt-sandbox-image.in b/bin/virt-sandbox-image.in new file mode 100644 index 000..732bb38 --- /dev/null +++ b/bin/virt-sandbox-image.in @@ -0,0 +1,3 @@ +#!/bin/sh + +exec @pkgpythondir@/virt-sandbox-image.py $@ diff --git a/configure.ac b/configure.ac index 8f6da04..69b5870 100644 --- a/configure.ac +++ b/configure.ac @@ -124,11 +124,13 @@ dnl Should be in m4/virt-gettext.m4 but intltoolize is too dnl dumb to find it there IT_PROG_INTLTOOL([0.35.0]) +AM_PATH_PYTHON AC_OUTPUT(Makefile libvirt-sandbox/Makefile libvirt-sandbox/tests/Makefile bin/Makefile + virt-sandbox-image/Makefile examples/Makefile docs/Makefile docs/libvirt-sandbox/Makefile diff --git a/virt-sandbox-image/Makefile.am b/virt-sandbox-image/Makefile.am new file mode 100644 index 000..5ab4d2e --- /dev/null +++ b/virt-sandbox-image/Makefile.am @@ -0,0 +1,13 @@ + +EXTRA_DIST = \ + virt-sandbox-image.py \ + sources + +install-data-local: + $(mkinstalldirs) $(DESTDIR)/$(pkgpythondir)/sources + $(INSTALL) -m 0755 $(srcdir)/virt-sandbox-image.py $(DESTDIR)$(pkgpythondir) + $(INSTALL) -m 0644 $(srcdir)/sources/__init__.py $(DESTDIR)$(pkgpythondir)/sources + $(INSTALL) -m 0644 $(srcdir)/sources/Source.py $(DESTDIR)$(pkgpythondir)/sources + +uninstall-local: + rm -f $(DESTDIR)$(pkgpythondir) diff --git a/virt-sandbox-image/sources/Source.py b/virt-sandbox-image/sources/Source.py new file mode 100644 index 000..508ca80 --- /dev/null +++ b/virt-sandbox-image/sources/Source.py @@ -0,0 +1,27 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2015 Universitat Polit??cnica de Catalunya. +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
[libvirt] [sandbox PATCH v3 04/22] Image: virt-sandbox-image default dir constants
Conflicts: virt-sandbox-image/virt-sandbox-image.py --- virt-sandbox-image/virt-sandbox-image.py | 8 1 file changed, 8 insertions(+) diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index fa9e1c8..55aea6a 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -32,6 +32,14 @@ import sys import urllib2 import subprocess +default_privileged_template_dir = /var/lib/libvirt/templates +default_home_dir = os.environ['HOME'] +default_unprivileged_template_dir = default_home_dir + /.local/share/libvirt/templates +default_privileged_storage_dir = default_privileged_template_dir + /storage +default_unprivileged_storage_dir = default_unprivileged_template_dir + /storage +debug = False +verbose = False + import importlib def dynamic_source_loader(name): name = name[0].upper() + name[1:] -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 05/22] Image: Discard caching bytecode
--- virt-sandbox-image/virt-sandbox-image.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index 55aea6a..9e98bf2 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -40,6 +40,8 @@ default_unprivileged_storage_dir = default_unprivileged_template_dir + /storage debug = False verbose = False +sys.dont_write_byte_code = True + import importlib def dynamic_source_loader(name): name = name[0].upper() + name[1:] -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 22/22] Image: Add custom environment support
Any custom key=value pair can be used as a custom environment variable in virt-sandbox-image. e.g virt-sandbox-image run ubuntu /var/lib/libvirt/templates -c lxc:/// -i /bin/bash -e key1=val1 --- virt-sandbox-image/sources/DockerSource.py | 10 ++ virt-sandbox-image/sources/Source.py | 4 virt-sandbox-image/virt-sandbox-image.py | 19 +++ 3 files changed, 33 insertions(+) diff --git a/virt-sandbox-image/sources/DockerSource.py b/virt-sandbox-image/sources/DockerSource.py index 67bcf6b..c84b84e 100644 --- a/virt-sandbox-image/sources/DockerSource.py +++ b/virt-sandbox-image/sources/DockerSource.py @@ -47,6 +47,12 @@ class DockerConfParser(): for key,value in volumes.iteritems(): volumelist.append(key) return volumelist +def getEnvs(self): +lst = self.json_data['container_config']['Env'] +if lst is not None and isinstance(lst,list): + return lst +else: + return [] class DockerSource(Source): @@ -407,5 +413,9 @@ class DockerSource(Source): configParser = DockerConfParser(configfile) return configParser.getVolumes() +def get_env(self,configfile): +configParser = DockerConfParser(configfile) +return configParser.getEnvs() + def debug(msg): sys.stderr.write(msg) diff --git a/virt-sandbox-image/sources/Source.py b/virt-sandbox-image/sources/Source.py index 8cc508e..c467ce2 100644 --- a/virt-sandbox-image/sources/Source.py +++ b/virt-sandbox-image/sources/Source.py @@ -49,3 +49,7 @@ class Source(): @abstractmethod def get_volume(self,**args): pass + +@abstractmethod +def get_env(self,**args): + pass diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index e554d8a..dacfa0c 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -145,10 +145,12 @@ def run(args): cmd.append(-c) cmd.append(args.connect) params = ['-m','host-image:/=%s,format=%s' %(diskfile,format)] + networkArgs = args.network if networkArgs is not None: params.append('-N') params.append(networkArgs) + allVolumes = source.get_volume(configfile) volumeArgs = args.volume if volumeArgs is not None: @@ -168,6 +170,20 @@ def run(args): pass params.append(--mount) params.append(host-bind:%s=%s %(guestPath,hostPath)) + +allEnvs = source.get_env(configfile) +envArgs = args.env +if envArgs is not None: +allEnvs = allEnvs + envArgs +for env in allEnvs: +envsplit = env.split(=) +envlen = len(envsplit) +if envlen == 2: +params.append(--env) +params.append(env) +else: +pass + params.append('--') params.append(commandToRun) cmd = cmd + params @@ -247,6 +263,9 @@ def gen_run_args(subparser): help=_(Network params for running template)) parser.add_argument(-v,--volume,action=append, help=_(Volume params for running template)) +parser.add_argument(-e,--env,action=append, +help=_(Environment params for running template)) + parser.set_defaults(func=run) if __name__ == '__main__': -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 12/22] Image: Add check_connect function
Check if user-specified connect argument is valid --- virt-sandbox-image/virt-sandbox-image.py | 6 ++ 1 file changed, 6 insertions(+) diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index d6b682f..c46abd4 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -122,6 +122,12 @@ def create(args): except Exception,e: print Create Error %s % str(e) +def check_connect(connectstr): +supportedDrivers = ['lxc:///','qemu:///session','qemu:///system'] +if not connectstr in supportedDrivers: +raise ValueError(%s is not supported by Virt-sandbox %connectstr) +return True + def requires_name(parser): parser.add_argument(name, help=_(name of the template)) -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 19/22] Add environment parameter to virt-sandbox
Allow users to add custom environment variables to their sandbox. --- bin/virt-sandbox.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/bin/virt-sandbox.c b/bin/virt-sandbox.c index 195515f..e90b698 100644 --- a/bin/virt-sandbox.c +++ b/bin/virt-sandbox.c @@ -64,6 +64,7 @@ int main(int argc, char **argv) { GError *error = NULL; gchar *name = NULL; gchar **disks = NULL; +gchar **envs = NULL; gchar **mounts = NULL; gchar **includes = NULL; gchar *includefile = NULL; @@ -95,6 +96,8 @@ int main(int argc, char **argv) { N_(root directory of the sandbox), DIR }, { disk, ' ', 0, G_OPTION_ARG_STRING_ARRAY, disks, N_(add a disk in the guest), TYPE:TAGNAME=SOURCE,format=FORMAT }, +{ env, 'e', 0, G_OPTION_ARG_STRING_ARRAY, envs, + N_(add a environment variable for the sandbox), KEY=VALUE }, { mount, 'm', 0, G_OPTION_ARG_STRING_ARRAY, mounts, N_(mount a filesystem in the guest), TYPE:TARGET=SOURCE }, { include, 'i', 0, G_OPTION_ARG_STRING_ARRAY, includes, @@ -185,6 +188,13 @@ int main(int argc, char **argv) { gvir_sandbox_config_set_username(cfg, root); } +if (envs +!gvir_sandbox_config_add_env_strv(cfg, envs, error)) { +g_printerr(_(Unable to parse custom environment variables: %s\n), + error error-message ? error-message : _(Unknown failure)); +goto cleanup; +} + if (disks !gvir_sandbox_config_add_disk_strv(cfg, disks, error)) { g_printerr(_(Unable to parse disks: %s\n), @@ -329,6 +339,10 @@ inheriting the host's root filesystem. NB. CDIR must contain a matching install of the libvirt-sandbox package. This restriction may be lifted in a future version. +=item B--env key=value + +Sets up a custom environment variable on a running sandbox. + =item B--disk TYPE:TAGNAME=SOURCE,format=FORMAT Sets up a disk inside the sandbox by using BSOURCE with a symlink named as BTAGNAME -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [sandbox PATCH v3 09/22] Image: Add delete function
Refactoring delete function from virt-sandbox-image to DockerSource. Delete function can delete templates by name. --- virt-sandbox-image/sources/DockerSource.py | 53 +++ virt-sandbox-image/sources/Source.py | 4 +++ virt-sandbox-image/virt-sandbox-image.py | 58 -- 3 files changed, 64 insertions(+), 51 deletions(-) diff --git a/virt-sandbox-image/sources/DockerSource.py b/virt-sandbox-image/sources/DockerSource.py index 09eea85..760ba6c 100644 --- a/virt-sandbox-image/sources/DockerSource.py +++ b/virt-sandbox-image/sources/DockerSource.py @@ -310,5 +310,58 @@ class DockerSource(Source): cmd = cmd + params subprocess.call(cmd) +def delete_template(self,**args): +imageusage = {} +imageparent = {} +imagenames = {} +name = args['name'] +destdir = args['templatedir'] +destdir = destdir if destdir is not None else default_template_dir +imagedirs = os.listdir(destdir) +for imagetagid in imagedirs: +indexfile = destdir + / + imagetagid + /index.json +if os.path.exists(indexfile): +with open(indexfile,r) as f: +index = json.load(f) +imagenames[index[name]] = imagetagid +jsonfile = destdir + / + imagetagid + /template.json +if os.path.exists(jsonfile): +with open(jsonfile,r) as f: +template = json.load(f) + +parent = template.get(parent,None) +if parent: +if parent not in imageusage: +imageusage[parent] = [] +imageusage[parent].append(imagetagid) +imageparent[imagetagid] = parent + + +if not name in imagenames: +raise ValueError([Image %s does not exist locally %name]) + +imagetagid = imagenames[name] +while imagetagid != None: +debug(Remove %s\n % imagetagid) +parent = imageparent.get(imagetagid,None) + +indexfile = destdir + / + imagetagid + /index.json +if os.path.exists(indexfile): + os.remove(indexfile) +jsonfile = destdir + / + imagetagid + /template.json +if os.path.exists(jsonfile): +os.remove(jsonfile) +datafile = destdir + / + imagetagid + /template.tar.gz +if os.path.exists(datafile): +os.remove(datafile) +imagedir = destdir + / + imagetagid +shutil.rmtree(imagedir) + +if parent: +if len(imageusage[parent]) != 1: +debug(Parent %s is shared\n % parent) +parent = None +imagetagid = parent + def debug(msg): sys.stderr.write(msg) diff --git a/virt-sandbox-image/sources/Source.py b/virt-sandbox-image/sources/Source.py index 6ac08dc..d66e61e 100644 --- a/virt-sandbox-image/sources/Source.py +++ b/virt-sandbox-image/sources/Source.py @@ -33,3 +33,7 @@ class Source(): @abstractmethod def create_template(self,**args): pass + +@abstractmethod +def delete_template(self,**args): + pass diff --git a/virt-sandbox-image/virt-sandbox-image.py b/virt-sandbox-image/virt-sandbox-image.py index 745401c..1da5150 100755 --- a/virt-sandbox-image/virt-sandbox-image.py +++ b/virt-sandbox-image/virt-sandbox-image.py @@ -94,55 +94,6 @@ def debug(msg): def info(msg): sys.stdout.write(msg) -def delete_template(name, destdir): -imageusage = {} -imageparent = {} -imagenames = {} -imagedirs = os.listdir(destdir) -for imagetagid in imagedirs: -indexfile = destdir + / + imagetagid + /index.json -if os.path.exists(indexfile): -with open(indexfile, r) as f: -index = json.load(f) -imagenames[index[name]] = imagetagid -jsonfile = destdir + / + imagetagid + /template.json -if os.path.exists(jsonfile): -with open(jsonfile, r) as f: -template = json.load(f) - -parent = template.get(parent, None) -if parent: -if parent not in imageusage: -imageusage[parent] = [] -imageusage[parent].append(imagetagid) -imageparent[imagetagid] = parent - -if not name in imagenames: -raise ValueError([Image %s does not exist locally % name]) - -imagetagid = imagenames[name] -while imagetagid != None: -debug(Remove %s\n % imagetagid) -parent = imageparent.get(imagetagid, None) - -indexfile = destdir + / + imagetagid + /index.json -if os.path.exists(indexfile): -os.remove(indexfile) -jsonfile = destdir + / + imagetagid + /template.json -if os.path.exists(jsonfile): -os.remove(jsonfile) -datafile = destdir + / + imagetagid +
[libvirt] [sandbox PATCH v3 10/22] Image: Add get_command function to Source
Provide a way to know how a template can be started depending on the used source DockerSource will need to parse the topmost config file in order to find the igniter command --- virt-sandbox-image/sources/DockerSource.py | 14 ++ virt-sandbox-image/sources/Source.py | 4 2 files changed, 18 insertions(+) diff --git a/virt-sandbox-image/sources/DockerSource.py b/virt-sandbox-image/sources/DockerSource.py index 760ba6c..3e0362b 100644 --- a/virt-sandbox-image/sources/DockerSource.py +++ b/virt-sandbox-image/sources/DockerSource.py @@ -29,6 +29,15 @@ import os import subprocess import shutil +class DockerConfParser(): + +def __init__(self,jsonfile): +with open(jsonfile) as json_file: +self.json_data = json.load(json_file) +def getRunCommand(self): +cmd = self.json_data['container_config']['Cmd'][2] +return cmd[cmd.index('') + 1:cmd.rindex('')] + class DockerSource(Source): www_auth_username = None @@ -363,5 +372,10 @@ class DockerSource(Source): parent = None imagetagid = parent +def get_command(self,configfile): +configParser = DockerConfParser(configfile) +commandToRun = configParser.getRunCommand() +return commandToRun + def debug(msg): sys.stderr.write(msg) diff --git a/virt-sandbox-image/sources/Source.py b/virt-sandbox-image/sources/Source.py index d66e61e..9daf62d 100644 --- a/virt-sandbox-image/sources/Source.py +++ b/virt-sandbox-image/sources/Source.py @@ -37,3 +37,7 @@ class Source(): @abstractmethod def delete_template(self,**args): pass + +@abstractmethod +def get_command(self,**args): + pass -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] virconf: fix the inconsistent name
Fix the name inconsistency between func comments and parameter of virConfGetValue/virConfSetValue Signed-off-by: Cao jin caoj.f...@cn.fujitsu.com --- src/util/virconf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/virconf.c b/src/util/virconf.c index 86d76b5..ab98c5c 100644 --- a/src/util/virconf.c +++ b/src/util/virconf.c @@ -840,7 +840,7 @@ virConfFree(virConfPtr conf) /** * virConfGetValue: * @conf: a configuration file handle - * @entry: the name of the entry + * @setting: the name of the entry * * Lookup the value associated to this entry in the configuration file * @@ -870,7 +870,7 @@ virConfGetValue(virConfPtr conf, const char *setting) /** * virConfSetValue: * @conf: a configuration file handle - * @entry: the name of the entry + * @setting: the name of the entry * @value: the new configuration value * * Set (or replace) the value associated to this entry in the configuration -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] virsh: fix output the incorrect error after try failed
On 17/08/15 11:56, Luyao Huang wrote: https://bugzilla.redhat.com/show_bug.cgi?id=1254152 When we use some virsh cmd which need specify domain name/id/uuid, if the command get failure we will get error like this: # virsh domif-setlink 123 vnet1 up error: interface (target: vnet1) not found error: Domain not found: no domain with matching id 123 The second line should be reset after call virshLookupDomainInternal, because after some tries we get domain pointer, so output error during we tried will make user confuse. Signed-off-by: Luyao Huang lhu...@redhat.com --- tools/virsh-domain.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 173bb15..69c5562 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -98,6 +98,8 @@ virshLookupDomainInternal(vshControl *ctl, dom = virDomainLookupByName(priv-conn, name); } +vshResetLibvirtError(); + if (!dom) vshError(ctl, _(failed to get domain '%s'), name); ACK, I reworded the commit message and pushed. Erik -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 3/5] util: Add getters for cgroup block device I/O throttling
On 08/03/2015 10:50 AM, Martin Kletzander wrote: Since now they were not needed, but I sense they will be in a short while. Signed-off-by: Martin Kletzander mklet...@redhat.com --- src/libvirt_private.syms | 5 + src/util/vircgroup.c | 277 ++- src/util/vircgroup.h | 20 3 files changed, 299 insertions(+), 3 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d22bde70e17d..8803777cde80 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1175,6 +1175,11 @@ virCgroupDenyDeviceMajor; virCgroupDenyDevicePath; virCgroupDetectMountsFromFile; virCgroupFree; +virCgroupGetBlkioDeviceReadBps; +virCgroupGetBlkioDeviceReadIops; +virCgroupGetBlkioDeviceWeight; +virCgroupGetBlkioDeviceWriteBps; +virCgroupGetBlkioDeviceWriteIops; virCgroupGetBlkioIoDeviceServiced; virCgroupGetBlkioIoServiced; virCgroupGetBlkioWeight; diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index afa85ded9061..9d527fb8b99a 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -804,6 +804,36 @@ virCgroupGetValueStr(virCgroupPtr group, static int +virCgroupGetValueForBlkDev(virCgroupPtr group, + int controller, + const char *key, + const char *path, + char **value) +{ +char *prefix = NULL; +char *str = NULL; +char **lines = NULL; +int ret = -1; + +if (virCgroupGetValueStr(group, controller, key, str) 0) +goto error; + +if (!(prefix = virCgroupGetBlockDevString(path))) +return -1; ^^^ str is leaked. (Coverity found) + +if (!(lines = virStringSplit(str, \n, -1))) +goto error; + +ret = VIR_STRDUP(*value, virStringGetFirstWithPrefix(lines, prefix)); ^^^ can return NULL VIR_STRDUP(*value, NULL) ?? + error: +VIR_FREE(str); +VIR_FREE(prefix); +virStringFreeList(lines); +return ret; +} + + +static int virCgroupSetValueU64(virCgroupPtr group, int controller, const char *key, @@ -2259,9 +2289,6 @@ virCgroupSetBlkioDeviceWriteBps(virCgroupPtr group, * @weight: The new device weight (100-1000), * (10-1000) after kernel 2.6.39, or 0 to clear * - * device_weight is treated as a write-only parameter, so - * there isn't a getter counterpart. - * * Returns: 0 on success, -1 on error */ int @@ -2289,6 +2316,196 @@ virCgroupSetBlkioDeviceWeight(virCgroupPtr group, return ret; } +/** + * virCgroupGetBlkioDeviceReadIops: + * @group: The cgroup to gather block io setting for + * @path: The path of device + * @riops: Returned device read iops throttle, 0 if there is none + * + * Returns: 0 on success, -1 on error + */ +int +virCgroupGetBlkioDeviceReadIops(virCgroupPtr group, +const char *path, +unsigned int *riops) +{ +char *str = NULL; +int ret = -1; + +if (virCgroupGetValueForBlkDev(group, + VIR_CGROUP_CONTROLLER_BLKIO, + blkio.throttle.read_iops_device, + path, + str) 0) +goto error; + +if (!str) { +*riops = 0; +} else if (virStrToLong_ui(str, NULL, 10, riops) 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(Unable to parse '%s' as an integer), + str); +goto error; +} + +ret = 0; + error: +VIR_FREE(str); +return ret; +} + +/** + * virCgroupGetBlkioDeviceWriteIops: + * @group: The cgroup to gather block io setting for + * @path: The path of device + * @wiops: Returned device write iops throttle, 0 if there is none + * + * Returns: 0 on success, -1 on error + */ +int +virCgroupGetBlkioDeviceWriteIops(virCgroupPtr group, + const char *path, + unsigned int *wiops) +{ +char *str = NULL; +int ret = -1; + +if (virCgroupGetValueForBlkDev(group, + VIR_CGROUP_CONTROLLER_BLKIO, + blkio.throttle.write_iops_device, + path, + str) 0) +goto error; + +if (!str) { +*wiops = 0; +} else if (virStrToLong_ui(str, NULL, 10, wiops) 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(Unable to parse '%s' as an integer), + str); +goto error; +} + +ret = 0; + error: +VIR_FREE(str); +return ret; +} + +/** + * virCgroupGetBlkioDeviceReadBps: + * @group: The cgroup to gather block io setting for + * @path:
Re: [libvirt] [PATCH] qemu: fix the error cover issue in qemuDomainAddCgroupForThread
On 14.08.2015 08:59, Luyao Huang wrote: Just like commit 704cf06, the error already will be set in virCgroup* function, and virCgroupAddTask will return -1, so We will always report error Operation not permitted in this place. Signed-off-by: Luyao Huang lhu...@redhat.com --- Reworded the commit message a bit, ACKed and pushed. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 0/3] Some minor IOThread API adjustments/checks
On 13.08.2015 17:00, John Ferlan wrote: As a result of the review of a related issue for virDomainAddIOThread it was noted that it's only our implementation for qemu that doesn't want an iothread_id == 0, see: http://www.redhat.com/archives/libvir-list/2015-August/msg00310.html Continued IRC chats with the submittor of that patch discovered some inconsistencies which are dealt with in this patch series... Patch 1 - Remove the iothread_id arg check in virDomainPinIOThread. Since 0 was allowed by the API anyway and left up to the hypervisor. The argument is unsigned - so in reality all that was being checked was 0 - other similar callers work on 'int' values not 'unsigned int'. Patch 2 - Adjust the description in virDomainAddIOThread to remove the positive non-zero value and then rework the text to be clearer that it's up to the hypervisor to decide what values are legal and how to handle possible duplication. Patch 3 - Add check in qemu_driver Add/Del IOThread API for the invalid 0 value for iothread_id NOTE: It's not necessary to add a specific illegal argument check for iothread_id = 0 in qemuDomainPinIOThread since both the live and config paths will first search for the iothread_id value and fail if not found in the iothreadid list. I'm not opposed to adding a specific error message if so desired... John Ferlan (3): api: Remove check on iothread_id arg in virDomainPinIOThread api: Adjust comment for virDomainAddIOThread qemu: Add check for invalid iothread_id in qemuDomainChgIOThread src/libvirt-domain.c | 7 +++ src/qemu/qemu_driver.c | 6 ++ 2 files changed, 9 insertions(+), 4 deletions(-) ACK series. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 0/5] Make sure internal blkiotune values are in sync
On 08/03/2015 10:50 AM, Martin Kletzander wrote: We were blindly setting blkiotune values for devices, but kernel can throw some of them away. This series reworks the logic the same wayother tuning values are updated. That is, after the value gets set, it is read back again to make sure internal structures are in sync and we can return the values from them. Little example should clear up everything. Before: === $ virsh blkiotune dummy --device-read-bytes-sec /dev/sda,18446744073709551614 $ virsh blkiotune dummy weight : 500 device_weight : device_read_iops_sec: device_write_iops_sec: device_read_bytes_sec: /dev/sda,18446744073709551614 device_write_bytes_sec: $ cat /sys/fs/cgroup/blkio/machine/dummy.libvirt-qemu/blkio.throttle.read_bps_device 8:0 18446744073709551614 $ virsh blkiotune dummy --device-read-bytes-sec /dev/sda,18446744073709551615 $ virsh blkiotune dummy weight : 500 device_weight : device_read_iops_sec: device_write_iops_sec: device_read_bytes_sec: /dev/sda,18446744073709551615 device_write_bytes_sec: $ cat /sys/fs/cgroup/blkio/machine/dummy.libvirt-qemu/blkio.throttle.read_bps_device $ After: == $ virsh blkiotune dummy --device-read-bytes-sec /dev/sda,18446744073709551614 $ virsh blkiotune dummy weight : 500 device_weight : device_read_iops_sec: device_write_iops_sec: device_read_bytes_sec: /dev/sda,18446744073709551614 device_write_bytes_sec: $ cat /sys/fs/cgroup/blkio/machine/dummy.libvirt-qemu/blkio.throttle.read_bps_device 8:0 18446744073709551614 $ virsh blkiotune dummy --device-read-bytes-sec /dev/sda,18446744073709551615 $ virsh blkiotune dummy weight : 500 device_weight : device_read_iops_sec: device_write_iops_sec: device_read_bytes_sec: device_write_bytes_sec: $ cat /sys/fs/cgroup/blkio/machine/dummy.libvirt-qemu/blkio.throttle.read_bps_device $ Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1165580 Martin Kletzander (5): util: Add virStringGetFirstWithPrefix util: Add virCgroupGetBlockDevString util: Add getters for cgroup block device I/O throttling lxc: Sync BlkioDevice values when setting them in cgroups qemu: Sync BlkioDevice values when setting them in cgroups src/libvirt_private.syms | 6 + src/lxc/lxc_cgroup.c | 20 ++- src/lxc/lxc_driver.c | 25 ++- src/qemu/qemu_cgroup.c | 20 ++- src/qemu/qemu_driver.c | 25 ++- src/util/vircgroup.c | 457 +++ src/util/vircgroup.h | 20 +++ src/util/virstring.c | 17 ++ src/util/virstring.h | 2 + 9 files changed, 459 insertions(+), 133 deletions(-) -- 2.5.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list ACK series with adjustments in patch 3 John -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: fix the error cover issue in qemuDomainAddCgroupForThread
On 08/14/2015 02:59 AM, Luyao Huang wrote: Just like commit 704cf06, the error already will be set in virCgroup* function, and virCgroupAddTask will return -1, so We will always report error Operation not permitted in this place. Signed-off-by: Luyao Huang lhu...@redhat.com --- src/qemu/qemu_driver.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index fa655b5..e0d7fa5 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4606,9 +4606,6 @@ qemuDomainAddCgroupForThread(virCgroupPtr cgroup, /* Add pid/thread to the cgroup */ rv = virCgroupAddTask(new_cgroup, pid); if (rv 0) { -virReportSystemError(-rv, - _(unable to add id %d task %d to cgroup), - idx, pid); virCgroupRemove(new_cgroup); Apparently virCgroupRemove can also overwrite a message, see virCgroupNewMachineSystemd for an example of how to save the error message and restore it.. Perhaps all the callers that fail would need a similar sequence John I'm at KVM Forum this week so digging and finding out the answer myself is a challenge with the flakiness of our network connection... goto error; } -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemuDomainRename: Don't leave a domain locked uppon fail
Well, yet again one case of 'goto cleanup' while 'goto endjob' was needed. Sorry. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- Pushed as trivial. src/qemu/qemu_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 180dd88..99a3817 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -19943,7 +19943,7 @@ static int qemuDomainRename(virDomainPtr dom, if (STREQ(vm-def-name, new_name)) { virReportError(VIR_ERR_OPERATION_INVALID, %s, _(Can't rename domain to itself)); -goto cleanup; +goto endjob; } if (VIR_STRDUP(new_dom_name, new_name) 0) -- 2.4.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: fix not update weight in def after success
On 08/12/2015 09:53 PM, Luyao Huang wrote: https://bugzilla.redhat.com/show_bug.cgi?id=1253107 Update the weight in vm def to fix this. Signed-off-by: Luyao Huang lhu...@redhat.com --- src/qemu/qemu_driver.c | 2 ++ 1 file changed, 2 insertions(+) Considering the series I recently ACK from Martin - shouldn't this to make a virCgroupGetBlkioWeight type call to ensure you get/save whatever the kernel saved? John See: http://www.redhat.com/archives/libvir-list/2015-August/msg00065.html diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7a984a8..0b984dc 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9170,6 +9170,8 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, if (STREQ(param-field, VIR_DOMAIN_BLKIO_WEIGHT)) { if (virCgroupSetBlkioWeight(priv-cgroup, param-value.ui) 0) ret = -1; +else +def-blkio.weight = param-value.ui; } else if (STREQ(param-field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT) || STREQ(param-field, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS) || STREQ(param-field, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS) || -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] conf/qemu: enforce NUMA nodes only for x86 memory hotplug
On Tue, Aug 18, 2015 at 03:35:11PM +0530, Nikunj A Dadhania wrote: libvirt enforces at least one NUMA node for memory hotplug support on all architectures. While it might be required for some x86 guest, PowerPC can hotplug memory on non-NUMA system. The generic checks are replaced with arch specific check and xml validation too does not enforce node for non-x86 arch. CC: Peter Krempa pkre...@redhat.com Signed-off-by: Nikunj A Dadhania nik...@linux.vnet.ibm.com For future reference, can you CC Andrea Bolognani abolo...@redhat.com on Power related libvirt patches? He's handling most of our Power / libvirt work here at Red Hat. -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson pgpuEBQ8LUWXO.pgp Description: PGP signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] virconf: fix the inconsistent name
On 18.08.2015 14:38, Cao jin wrote: Fix the name inconsistency between func comments and parameter of virConfGetValue/virConfSetValue Signed-off-by: Cao jin caoj.f...@cn.fujitsu.com --- src/util/virconf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) ACKed and pushed. Although, there are some more occurrences of the same problem in the file, e.g. virConfWalk. Wanna fix them too? Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemu: Report better error message when renaming to existing domain name
Signed-off-by: Martin Kletzander mklet...@redhat.com --- src/qemu/qemu_driver.c | 16 1 file changed, 16 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 99a3817ff5ab..16061a51d4a7 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -19892,6 +19892,7 @@ static int qemuDomainRename(virDomainPtr dom, virQEMUDriverPtr driver = dom-conn-privateData; virQEMUDriverConfigPtr cfg = NULL; virDomainObjPtr vm = NULL; +virDomainObjPtr tmp_dom = NULL; virObjectEventPtr event_new = NULL; virObjectEventPtr event_old = NULL; int ret = -1; @@ -19946,6 +19947,21 @@ static int qemuDomainRename(virDomainPtr dom, goto endjob; } +/* + * This is a rather racy check, but still better than reporting + * internal error. And since new_name != name here, there's no + * deadlock imminent. + */ +tmp_dom = virDomainObjListFindByName(driver-domains, new_name); +if (tmp_dom) { +virObjectUnlock(tmp_dom); +virObjectUnref(tmp_dom); +virReportError(VIR_ERR_OPERATION_INVALID, + _(domain with name '%s' already exists), + new_name); +goto endjob; +} + if (VIR_STRDUP(new_dom_name, new_name) 0) goto endjob; -- 2.5.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] virDomainRename: Extended API documentation
Signed-off-by: Tomas Meszaros e...@tty.sk --- src/libvirt-domain.c | 5 + 1 file changed, 5 insertions(+) diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 5c8bf2b..60e0def 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -8783,6 +8783,11 @@ virDomainIsPersistent(virDomainPtr dom) * argument. Depending on each driver implementation it may be * required that domain is in a specific state. * + * There might be some attributes and/or elements in domain XML that if no + * value provided at XML defining time, libvirt will derive their value from + * domain name. These are not updated by this API. Users are strongly advised + * to change these after the rename was successful. + * * Returns 0 if successfully renamed, -1 on error */ int -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: fix the error cover issue in qemuDomainAddCgroupForThread
On 08/19/2015 01:40 AM, John Ferlan wrote: On 08/14/2015 02:59 AM, Luyao Huang wrote: Just like commit 704cf06, the error already will be set in virCgroup* function, and virCgroupAddTask will return -1, so We will always report error Operation not permitted in this place. Signed-off-by: Luyao Huang lhu...@redhat.com --- src/qemu/qemu_driver.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index fa655b5..e0d7fa5 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4606,9 +4606,6 @@ qemuDomainAddCgroupForThread(virCgroupPtr cgroup, /* Add pid/thread to the cgroup */ rv = virCgroupAddTask(new_cgroup, pid); if (rv 0) { -virReportSystemError(-rv, - _(unable to add id %d task %d to cgroup), - idx, pid); virCgroupRemove(new_cgroup); Apparently virCgroupRemove can also overwrite a message, see virCgroupNewMachineSystemd for an example of how to save the error message and restore it.. Perhaps all the callers that fail would need a similar sequence You are right, maybe we could introduce a macro maybe named virErrorAvoidRecover for these case. John I'm at KVM Forum this week so digging and finding out the answer myself is a challenge with the flakiness of our network connection... So lucky you are (of course i mean KVM Forum), i will fix them in another patches. Thanks a lot for your review. Luyao goto error; } -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: fix the error cover issue in qemuDomainAddCgroupForThread
On 08/19/2015 02:17 AM, Michal Privoznik wrote: On 14.08.2015 08:59, Luyao Huang wrote: Just like commit 704cf06, the error already will be set in virCgroup* function, and virCgroupAddTask will return -1, so We will always report error Operation not permitted in this place. Signed-off-by: Luyao Huang lhu...@redhat.com --- Reworded the commit message a bit, ACKed and pushed. Thanks a lot for your review and help. Michal Luyao -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] virConfWalk: fix the inconsistent name
Fix inconsistency between function description and actual parameter name. Signed-off-by: Cao jin caoj.f...@cn.fujitsu.com --- src/util/virconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/virconf.c b/src/util/virconf.c index ab98c5c..9f2d116 100644 --- a/src/util/virconf.c +++ b/src/util/virconf.c @@ -930,7 +930,7 @@ virConfSetValue(virConfPtr conf, * virConfWalk: * @conf: a configuration file handle * @callback: the function to call to process each entry - * @data: obscure data passed to callback + * @opaque: obscure data passed to callback * * Walk over all entries of the configuration file and run the callback * for each with entry name, value and the obscure data. -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCHv2] qemu: fix not update weight in def after success
https://bugzilla.redhat.com/show_bug.cgi?id=1253107 Call virCgroupGetBlkioWeight to re-read blkio.weight right after it are set in order to keep our internal structures up-to-date. Signed-off-by: Luyao Huang lhu...@redhat.com --- src/qemu/qemu_driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b6ac075..5cc38ad 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9183,7 +9183,8 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, virTypedParameterPtr param = params[i]; if (STREQ(param-field, VIR_DOMAIN_BLKIO_WEIGHT)) { -if (virCgroupSetBlkioWeight(priv-cgroup, param-value.ui) 0) +if (virCgroupSetBlkioWeight(priv-cgroup, param-value.ui) 0 || +virCgroupGetBlkioWeight(priv-cgroup, def-blkio.weight) 0) ret = -1; } else if (STREQ(param-field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT) || STREQ(param-field, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS) || -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: fix not update weight in def after success
On 08/19/2015 01:32 AM, John Ferlan wrote: On 08/12/2015 09:53 PM, Luyao Huang wrote: https://bugzilla.redhat.com/show_bug.cgi?id=1253107 Update the weight in vm def to fix this. Signed-off-by: Luyao Huang lhu...@redhat.com --- src/qemu/qemu_driver.c | 2 ++ 1 file changed, 2 insertions(+) Considering the series I recently ACK from Martin - shouldn't this to make a virCgroupGetBlkioWeight type call to ensure you get/save whatever the kernel saved? Indeed, it will be better to check the value again (blkio.weigh and blkio.weight_device range is [10, 1000] right now, so seems these 2 value won't hit the issue that was fixed by Martin), i will write a new version later. Thanks a lot for your review. John Luyao See: http://www.redhat.com/archives/libvir-list/2015-August/msg00065.html diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7a984a8..0b984dc 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9170,6 +9170,8 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, if (STREQ(param-field, VIR_DOMAIN_BLKIO_WEIGHT)) { if (virCgroupSetBlkioWeight(priv-cgroup, param-value.ui) 0) ret = -1; +else +def-blkio.weight = param-value.ui; } else if (STREQ(param-field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT) || STREQ(param-field, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS) || STREQ(param-field, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS) || -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCHv2] utils: Remove the logging of errors from virNetDevSendEthtoolIoctl
This patch remove the logging of errors of ioctl api and instead let the caller to choose what errors to log --- src/util/virnetdev.c | 56 ++--- 1 files changed, 16 insertions(+), 40 deletions(-) diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 2f3690e..5fcf805 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -3032,39 +3032,15 @@ static int virNetDevSendEthtoolIoctl(const char *ifname, void *cmd) { int ret = -1; -int sock = -1; -virIfreq ifr; - -sock = socket(AF_LOCAL, SOCK_DGRAM, 0); -if (sock 0) { -virReportSystemError(errno, %s, _(Cannot open control socket)); -goto cleanup; -} +int fd; +struct ifreq ifr; -memset(ifr, 0, sizeof(ifr)); -strcpy(ifr.ifr_name, ifname); +if ((fd = virNetDevSetupControl(ifname, ifr)) 0) +return ret; ifr.ifr_data = cmd; -ret = ioctl(sock, SIOCETHTOOL, ifr); -if (ret != 0) { -switch (errno) { -case EPERM: -VIR_DEBUG(ethtool ioctl: permission denied); -break; -case EINVAL: -VIR_DEBUG(ethtool ioctl: invalid request); -break; -case EOPNOTSUPP: -VIR_DEBUG(ethtool ioctl: request not supported); -break; -default: -virReportSystemError(errno, %s, _(ethtool ioctl error)); -goto cleanup; -} -} +ret = ioctl(fd, SIOCETHTOOL, ifr); - cleanup: -if (sock) -VIR_FORCE_CLOSE(sock); +VIR_FORCE_CLOSE(fd); return ret; } @@ -3081,12 +3057,12 @@ virNetDevSendEthtoolIoctl(const char *ifname, void *cmd) static int virNetDevFeatureAvailable(const char *ifname, struct ethtool_value *cmd) { -int ret = -1; - cmd = (void*)cmd; -if (!virNetDevSendEthtoolIoctl(ifname, cmd)) -ret = cmd-data 0 ? 1 : 0; -return ret; +if (virNetDevSendEthtoolIoctl(ifname, cmd) 0) { +virReportSystemError(errno, _(Cannot get device %s flags), ifname); +return -1; +} +return cmd-data 0 ? 1 : 0; } @@ -3103,12 +3079,12 @@ virNetDevFeatureAvailable(const char *ifname, struct ethtool_value *cmd) static int virNetDevGFeatureAvailable(const char *ifname, struct ethtool_gfeatures *cmd) { -int ret = -1; - cmd = (void*)cmd; -if (!virNetDevSendEthtoolIoctl(ifname, cmd)) -ret = FEATURE_BIT_IS_SET(cmd-features, TX_UDP_TNL, active); -return ret; +if (virNetDevSendEthtoolIoctl(ifname, cmd) 0) { +virReportSystemError(errno, _(Cannot get device %s generic features), ifname); +return -1; +} +return FEATURE_BIT_IS_SET(cmd-features, TX_UDP_TNL, active); } # endif -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [RFC PATCH 1/3] Implement virQEMUCapsCache mockup
This patch introduces qemuTestMakeCapsCache() function, which creates capability cache containing predefined set of capabilities associated with predefined binary. For simplicity of integration binary name is deduced from test name, which follows a simple scheme of being prefixed with architecture name, with some exceptions. Signed-off-by: Pavel Fedin p.fe...@samsung.com --- src/qemu/qemu_capabilities.c | 10 +- src/qemu/qemu_capspriv.h | 36 +++ tests/testutilsqemu.c| 45 tests/testutilsqemu.h| 3 +++ 4 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 src/qemu/qemu_capspriv.h mode change 100644 = 100755 tests/testutilsqemu.c diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 43d11af..62b1aea 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -42,6 +42,7 @@ #include virstring.h #include qemu_hostdev.h #include qemu_domain.h +#include qemu_capspriv.h #include fcntl.h #include sys/stat.h @@ -327,15 +328,6 @@ struct _virQEMUCaps { unsigned int *machineMaxCpus; }; -struct _virQEMUCapsCache { -virMutex lock; -virHashTablePtr binaries; -char *libDir; -char *cacheDir; -uid_t runUid; -gid_t runGid; -}; - struct virQEMUCapsSearchData { virArch arch; }; diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h new file mode 100644 index 000..f915ea9 --- /dev/null +++ b/src/qemu/qemu_capspriv.h @@ -0,0 +1,36 @@ +/* + * qemu_capspriv.h: private declarations for QEMU capabilities generation + * + * Copyright (C) 2015 Samsung Electronics Co. Ltd + * Copyright (C) 2015 Pavel Fedin + * + * 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: Pavel Fedin p.fe...@samsung.com + */ + +#ifndef __QEMU_CAPSPRIV_H__ +#define __QEMU_CAPSPRIV_H__ + +struct _virQEMUCapsCache { +virMutex lock; +virHashTablePtr binaries; +char *libDir; +char *cacheDir; +uid_t runUid; +gid_t runGid; +}; + +#endif diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c old mode 100644 new mode 100755 index a2f4299..3dc50f2 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -8,6 +8,7 @@ # include cpu_conf.h # include qemu/qemu_driver.h # include qemu/qemu_domain.h +# include qemu/qemu_capspriv.h # include virstring.h # define VIR_FROM_THIS VIR_FROM_QEMU @@ -526,4 +527,48 @@ qemuTestParseCapabilities(const char *capsFile) xmlXPathFreeContext(ctxt); return NULL; } + +virQEMUCapsCachePtr +qemuTestMakeCapsCache(const char *test, virQEMUCapsPtr caps) +{ +virQEMUCapsCachePtr cache; +const char *binary; + +cache = virQEMUCapsCacheNew(/dev/null, /dev/null, 0, 0); +if (!cache) +return NULL; + +if (caps) { +/* Our caps were created artificially, so we don't want + * virQEMUCapsCacheFree() to attempt to deallocate them */ +virObjectRef(caps); +} else { +caps = virQEMUCapsNew(); +if (!caps) { +virQEMUCapsCacheFree(cache); +return NULL; +} +} + +if (STRPREFIX(test, aarch64-)) +binary = /usr/bin/qemu-system-aarch64; +else if (STRPREFIX(test, arm-)) +binary = /usr/bin/qemu-system-arm; +else if (STRPREFIX(test, pseries-)) +binary = /usr/bin/qemu-system-ppc64; +else if (STRPREFIX(test, s390-)) +binary = /usr/bin/qemu-system-s390x; +else if (strstr(test, keywrap-)) /* May be rename these ? */ +binary = /usr/bin/qemu-system-s390x; +else +binary = /usr/bin/qemu; + +if (virHashAddEntry(cache-binaries, binary, caps) 0) { +virQEMUCapsCacheFree(cache); +virObjectUnref(caps); +return NULL; +} + +return cache; +} #endif diff --git a/tests/testutilsqemu.h b/tests/testutilsqemu.h index 0ec5dad..6fe923b 100644 --- a/tests/testutilsqemu.h +++ b/tests/testutilsqemu.h @@ -16,4 +16,7 @@ extern virCPUDefPtr cpuHaswell; void testQemuCapsSetCPU(virCapsPtr caps, virCPUDefPtr hostCPU); +virQEMUCapsCachePtr qemuTestMakeCapsCache(const char *test, + virQEMUCapsPtr caps); + #endif -- 2.1.4 -- libvir-list mailing list libvir-list@redhat.com
[libvirt] [PATCH 3/4] cpu: Move check for NULL CPU model inside the driver
While the check is appropriate for eg. the x86 and generic drivers, there are some valid ppc64 guest configurations where the CPU model is supposed to be NULL. Moving this check from the generic code to the drivers makes it possible to accomodate both use cases. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1251927 --- src/cpu/cpu.c | 12 src/cpu/cpu_generic.c | 6 ++ src/cpu/cpu_ppc64.c | 3 ++- src/cpu/cpu_x86.c | 6 ++ 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 731df26..1952b53 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -142,12 +142,6 @@ cpuCompare(virCPUDefPtr host, VIR_DEBUG(host=%p, cpu=%p, host, cpu); -if (!cpu-model) { -virReportError(VIR_ERR_INVALID_ARG, %s, - _(no guest CPU model specified)); -return VIR_CPU_COMPARE_ERROR; -} - if ((driver = cpuGetSubDriver(host-arch)) == NULL) return VIR_CPU_COMPARE_ERROR; @@ -376,12 +370,6 @@ cpuGuestData(virCPUDefPtr host, VIR_DEBUG(host=%p, guest=%p, data=%p, msg=%p, host, guest, data, msg); -if (!guest-model) { -virReportError(VIR_ERR_INVALID_ARG, %s, - _(no guest CPU model specified)); -return VIR_CPU_COMPARE_ERROR; -} - if ((driver = cpuGetSubDriver(host-arch)) == NULL) return VIR_CPU_COMPARE_ERROR; diff --git a/src/cpu/cpu_generic.c b/src/cpu/cpu_generic.c index a9cde4c..f26a62d 100644 --- a/src/cpu/cpu_generic.c +++ b/src/cpu/cpu_generic.c @@ -65,6 +65,12 @@ genericCompare(virCPUDefPtr host, size_t i; unsigned int reqfeatures; +if (!cpu-model) { +virReportError(VIR_ERR_INVALID_ARG, %s, + _(no guest CPU model specified)); +goto cleanup; +} + if ((cpu-arch != VIR_ARCH_NONE host-arch != cpu-arch) || STRNEQ(host-model, cpu-model)) { diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c index 1a1b15b..4fdefb7 100644 --- a/src/cpu/cpu_ppc64.c +++ b/src/cpu/cpu_ppc64.c @@ -71,7 +71,8 @@ ppc64ConvertLegacyCPUDef(const virCPUDef *legacy) if (!(cpu = virCPUDefCopy(legacy))) goto out; -if (!(STREQ(cpu-model, POWER7_v2.1) || +if (!cpu-model || +!(STREQ(cpu-model, POWER7_v2.1) || STREQ(cpu-model, POWER7_v2.3) || STREQ(cpu-model, POWER7+_v2.1) || STREQ(cpu-model, POWER8_v1.0))) { diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index f5f7697..90949f6 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -1371,6 +1371,12 @@ x86Compute(virCPUDefPtr host, virArch arch; size_t i; +if (!cpu-model) { +virReportError(VIR_ERR_INVALID_ARG, %s, + _(no guest CPU model specified)); +return VIR_CPU_COMPARE_ERROR; +} + if (cpu-arch != VIR_ARCH_NONE) { bool found = false; -- 2.4.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/4] cpu: Better support for ppc64 compatibility modes
Not all combinations of host CPU models and compatibility modes are valid, so we need to make sure we don't try to do something that QEMU will reject. Moreover, we need to apply a different logic to guests using host-model and host-passthrough modes when testing them for host compatibility. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1251927 --- src/cpu/cpu_ppc64.c | 93 +++-- 1 file changed, 90 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c index 72b8fa0..1a1b15b 100644 --- a/src/cpu/cpu_ppc64.c +++ b/src/cpu/cpu_ppc64.c @@ -84,6 +84,57 @@ ppc64ConvertLegacyCPUDef(const virCPUDef *legacy) return cpu; } +/* Some hosts can run guests in compatibility mode, but not all + * host CPUs support this and not all combinations are valid. + * This function performs the necessary checks */ +static virCPUCompareResult +ppc64CheckCompatibilityMode(const char *host_model, +const char *compat_mode) +{ +int host; +int compat; +char *tmp; +virCPUCompareResult ret = VIR_CPU_COMPARE_IDENTICAL; + +if (!compat_mode) +goto out; + +ret = VIR_CPU_COMPARE_ERROR; + +/* Valid host CPUs: POWER6, POWER7, POWER8 */ +if (!STRPREFIX(host_model, POWER) || +!(tmp = (char *) host_model + strlen(POWER)) || +virStrToLong_i(tmp, NULL, 10, host) 0 || +host 6 || host 8) { +virReportError(VIR_ERR_INTERNAL_ERROR, + %s, + _(Host CPU does not support compatibility modes)); +goto out; +} + +/* Valid compatibility modes: power6, power7, power8 */ +if (!STRPREFIX(compat_mode, power) || +!(tmp = (char *) compat_mode + strlen(power)) || +virStrToLong_i(tmp, NULL, 10, compat) 0 || +compat 6 || compat 8) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(Unknown compatibility mode %s), + compat_mode); +goto out; +} + +ret = VIR_CPU_COMPARE_INCOMPATIBLE; + +/* Version check */ +if (compat host) +goto out; + +ret = VIR_CPU_COMPARE_IDENTICAL; + + out: +return ret; +} + static void ppc64DataFree(virCPUppc64Data *data) { @@ -509,11 +560,47 @@ ppc64Compute(virCPUDefPtr host, goto cleanup; } -if (!(map = ppc64LoadMap()) || -!(host_model = ppc64ModelFromCPU(host, map)) || -!(guest_model = ppc64ModelFromCPU(cpu, map))) +if (!(map = ppc64LoadMap())) goto cleanup; +/* Host CPU information */ +if (!(host_model = ppc64ModelFromCPU(host, map))) +goto cleanup; + +if (cpu-type == VIR_CPU_TYPE_GUEST) { +/* Guest CPU information */ +virCPUCompareResult tmp; +switch (cpu-mode) { +case VIR_CPU_MODE_HOST_MODEL: +/* host-model only: + * we need to take compatibility modes into account */ +tmp = ppc64CheckCompatibilityMode(host-model, cpu-model); +if (tmp != VIR_CPU_COMPARE_IDENTICAL) { +ret = tmp; +goto cleanup; +} +/* fallthrough */ + +case VIR_CPU_MODE_HOST_PASSTHROUGH: +/* host-model and host-passthrough: + * the guest CPU is the same as the host */ +if (!(guest_model = ppc64ModelCopy(host_model))) +goto cleanup; +break; + +case VIR_CPU_MODE_CUSTOM: +/* custom: + * look up guest CPU information */ +if (!(guest_model = ppc64ModelFromCPU(cpu, map))) +goto cleanup; +break; +} +} else { +/* Other host CPU information */ +if (!(guest_model = ppc64ModelFromCPU(cpu, map))) +goto cleanup; +} + if (STRNEQ(guest_model-name, host_model-name)) { VIR_DEBUG(host CPU model does not match required CPU model %s, guest_model-name); -- 2.4.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/4] cpu: Don't update host-model guest CPUs on ppc64
If a guest CPU is defined using cpu mode='host-model'/ the model sub-element will contain the compatibility mode to use. That means we can't just copy the host CPU model on cpuUpdate(), otherwise we'll overwrite that information and migration of such guests will fail. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1251927 --- src/cpu/cpu_ppc64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c index 85aa5bc..72b8fa0 100644 --- a/src/cpu/cpu_ppc64.c +++ b/src/cpu/cpu_ppc64.c @@ -667,13 +667,13 @@ ppc64DriverUpdate(virCPUDefPtr guest, const virCPUDef *host) { switch ((virCPUMode) guest-mode) { -case VIR_CPU_MODE_HOST_MODEL: case VIR_CPU_MODE_HOST_PASSTHROUGH: guest-match = VIR_CPU_MATCH_EXACT; guest-fallback = VIR_CPU_FALLBACK_FORBID; virCPUDefFreeModel(guest); return virCPUDefCopyModel(guest, host, true); +case VIR_CPU_MODE_HOST_MODEL: case VIR_CPU_MODE_CUSTOM: return 0; -- 2.4.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] virconf: fix the inconsistent name
Hi Michal On 08/19/2015 01:51 AM, Michal Privoznik wrote: On 18.08.2015 14:38, Cao jin wrote: Fix the name inconsistency between func comments and parameter of virConfGetValue/virConfSetValue Signed-off-by: Cao jin caoj.f...@cn.fujitsu.com --- src/util/virconf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) ACKed and pushed. Although, there are some more occurrences of the same problem in the file, e.g. virConfWalk. Wanna fix them too? Michal Yup...I scaned that file with my eyes, want to see if any same issue, seems I missed the func you mentioned. thanks for your reminding, the patch is on the way:) -- Yours Sincerely, Cao Jin -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/4] Improve handling of ppc64 compatibility modes
This series fixes an issue that prevented save / restore from working when using compatibility modes; it also introduces some new checks to make sure the requested compability configuration is actually supported and a few test cases. Cheers. Andrea Bolognani (4): cpu: Don't update host-model guest CPUs on ppc64 cpu: Better support for ppc64 compatibility modes cpu: Move check for NULL CPU model inside the driver tests: Add some compatibility-related cases to the CPU tests src/cpu/cpu.c | 12 --- src/cpu/cpu_generic.c | 6 ++ src/cpu/cpu_ppc64.c| 98 -- src/cpu/cpu_x86.c | 6 ++ tests/cputest.c| 14 .../ppc64-guest-compat-incompatible.xml| 3 + tests/cputestdata/ppc64-guest-compat-invalid.xml | 3 + tests/cputestdata/ppc64-guest-compat-none.xml | 1 + tests/cputestdata/ppc64-guest-compat-valid.xml | 3 + tests/cputestdata/ppc64-guest-host-model.xml | 3 + .../ppc64-host+guest-compat-incompatible.xml | 3 + .../ppc64-host+guest-compat-invalid.xml| 3 + tests/cputestdata/ppc64-host+guest-compat-none.xml | 3 + .../cputestdata/ppc64-host+guest-compat-valid.xml | 3 + tests/cputestdata/ppc64-host+guest-host-model.xml | 3 + .../ppc64-host+guest-legacy-incompatible.xml | 3 + .../ppc64-host+guest-legacy-invalid.xml| 3 + tests/cputestdata/ppc64-host+guest-legacy.xml | 3 + tests/cputestdata/ppc64-host+guest-nofallback.xml | 3 + tests/cputestdata/ppc64-host+guest.xml | 3 + 20 files changed, 162 insertions(+), 17 deletions(-) create mode 100644 tests/cputestdata/ppc64-guest-compat-incompatible.xml create mode 100644 tests/cputestdata/ppc64-guest-compat-invalid.xml create mode 100644 tests/cputestdata/ppc64-guest-compat-none.xml create mode 100644 tests/cputestdata/ppc64-guest-compat-valid.xml create mode 100644 tests/cputestdata/ppc64-guest-host-model.xml create mode 100644 tests/cputestdata/ppc64-host+guest-compat-incompatible.xml create mode 100644 tests/cputestdata/ppc64-host+guest-compat-invalid.xml create mode 100644 tests/cputestdata/ppc64-host+guest-compat-none.xml create mode 100644 tests/cputestdata/ppc64-host+guest-compat-valid.xml create mode 100644 tests/cputestdata/ppc64-host+guest-host-model.xml create mode 100644 tests/cputestdata/ppc64-host+guest-legacy-incompatible.xml create mode 100644 tests/cputestdata/ppc64-host+guest-legacy-invalid.xml create mode 100644 tests/cputestdata/ppc64-host+guest-legacy.xml create mode 100644 tests/cputestdata/ppc64-host+guest-nofallback.xml create mode 100644 tests/cputestdata/ppc64-host+guest.xml -- 2.4.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 4/4] tests: Add some compatibility-related cases to the CPU tests
--- tests/cputest.c| 14 ++ tests/cputestdata/ppc64-guest-compat-incompatible.xml | 3 +++ tests/cputestdata/ppc64-guest-compat-invalid.xml | 3 +++ tests/cputestdata/ppc64-guest-compat-none.xml | 1 + tests/cputestdata/ppc64-guest-compat-valid.xml | 3 +++ tests/cputestdata/ppc64-guest-host-model.xml | 3 +++ tests/cputestdata/ppc64-host+guest-compat-incompatible.xml | 3 +++ tests/cputestdata/ppc64-host+guest-compat-invalid.xml | 3 +++ tests/cputestdata/ppc64-host+guest-compat-none.xml | 3 +++ tests/cputestdata/ppc64-host+guest-compat-valid.xml| 3 +++ tests/cputestdata/ppc64-host+guest-host-model.xml | 3 +++ tests/cputestdata/ppc64-host+guest-legacy-incompatible.xml | 3 +++ tests/cputestdata/ppc64-host+guest-legacy-invalid.xml | 3 +++ tests/cputestdata/ppc64-host+guest-legacy.xml | 3 +++ tests/cputestdata/ppc64-host+guest-nofallback.xml | 3 +++ tests/cputestdata/ppc64-host+guest.xml | 3 +++ 16 files changed, 57 insertions(+) create mode 100644 tests/cputestdata/ppc64-guest-compat-incompatible.xml create mode 100644 tests/cputestdata/ppc64-guest-compat-invalid.xml create mode 100644 tests/cputestdata/ppc64-guest-compat-none.xml create mode 100644 tests/cputestdata/ppc64-guest-compat-valid.xml create mode 100644 tests/cputestdata/ppc64-guest-host-model.xml create mode 100644 tests/cputestdata/ppc64-host+guest-compat-incompatible.xml create mode 100644 tests/cputestdata/ppc64-host+guest-compat-invalid.xml create mode 100644 tests/cputestdata/ppc64-host+guest-compat-none.xml create mode 100644 tests/cputestdata/ppc64-host+guest-compat-valid.xml create mode 100644 tests/cputestdata/ppc64-host+guest-host-model.xml create mode 100644 tests/cputestdata/ppc64-host+guest-legacy-incompatible.xml create mode 100644 tests/cputestdata/ppc64-host+guest-legacy-invalid.xml create mode 100644 tests/cputestdata/ppc64-host+guest-legacy.xml create mode 100644 tests/cputestdata/ppc64-host+guest-nofallback.xml create mode 100644 tests/cputestdata/ppc64-host+guest.xml diff --git a/tests/cputest.c b/tests/cputest.c index 5992dd0..431b587 100644 --- a/tests/cputest.c +++ b/tests/cputest.c @@ -607,6 +607,10 @@ mymain(void) DO_TEST_COMPARE(ppc64, host, guest-legacy, VIR_CPU_COMPARE_IDENTICAL); DO_TEST_COMPARE(ppc64, host, guest-legacy-incompatible, VIR_CPU_COMPARE_INCOMPATIBLE); DO_TEST_COMPARE(ppc64, host, guest-legacy-invalid, VIR_CPU_COMPARE_ERROR); +DO_TEST_COMPARE(ppc64, host, guest-compat-none, VIR_CPU_COMPARE_IDENTICAL); +DO_TEST_COMPARE(ppc64, host, guest-compat-valid, VIR_CPU_COMPARE_IDENTICAL); +DO_TEST_COMPARE(ppc64, host, guest-compat-invalid, VIR_CPU_COMPARE_ERROR); +DO_TEST_COMPARE(ppc64, host, guest-compat-incompatible, VIR_CPU_COMPARE_INCOMPATIBLE); /* guest updates for migration * automatically compares host CPU with the result */ @@ -618,6 +622,16 @@ mymain(void) DO_TEST_UPDATE(x86, host, host-passthrough, VIR_CPU_COMPARE_IDENTICAL); DO_TEST_UPDATE(x86, host-invtsc, host-model, VIR_CPU_COMPARE_SUPERSET); +DO_TEST_UPDATE(ppc64, host, guest, VIR_CPU_COMPARE_IDENTICAL); +DO_TEST_UPDATE(ppc64, host, guest-nofallback, VIR_CPU_COMPARE_INCOMPATIBLE); +DO_TEST_UPDATE(ppc64, host, guest-legacy, VIR_CPU_COMPARE_IDENTICAL); +DO_TEST_UPDATE(ppc64, host, guest-legacy-incompatible, VIR_CPU_COMPARE_INCOMPATIBLE); +DO_TEST_UPDATE(ppc64, host, guest-legacy-invalid, VIR_CPU_COMPARE_ERROR); +DO_TEST_UPDATE(ppc64, host, guest-compat-none, VIR_CPU_COMPARE_IDENTICAL); +DO_TEST_UPDATE(ppc64, host, guest-compat-valid, VIR_CPU_COMPARE_IDENTICAL); +DO_TEST_UPDATE(ppc64, host, guest-compat-invalid, VIR_CPU_COMPARE_ERROR); +DO_TEST_UPDATE(ppc64, host, guest-compat-incompatible, VIR_CPU_COMPARE_INCOMPATIBLE); + /* computing baseline CPUs */ DO_TEST_BASELINE(x86, incompatible-vendors, 0, -1); DO_TEST_BASELINE(x86, no-vendor, 0, 0); diff --git a/tests/cputestdata/ppc64-guest-compat-incompatible.xml b/tests/cputestdata/ppc64-guest-compat-incompatible.xml new file mode 100644 index 000..3f130fa --- /dev/null +++ b/tests/cputestdata/ppc64-guest-compat-incompatible.xml @@ -0,0 +1,3 @@ +cpu mode='host-model' + modelpower8/model +/cpu diff --git a/tests/cputestdata/ppc64-guest-compat-invalid.xml b/tests/cputestdata/ppc64-guest-compat-invalid.xml new file mode 100644 index 000..f35cb21 --- /dev/null +++ b/tests/cputestdata/ppc64-guest-compat-invalid.xml @@ -0,0 +1,3 @@ +cpu mode='host-model' + modelpower7+/model +/cpu diff --git a/tests/cputestdata/ppc64-guest-compat-none.xml b/tests/cputestdata/ppc64-guest-compat-none.xml new file mode 100644 index 000..fd50c03 --- /dev/null +++ b/tests/cputestdata/ppc64-guest-compat-none.xml @@ -0,0 +1 @@ +cpu mode='host-model'/ diff --git
Re: [libvirt] [PATCH] conf: Check for attach disk usage of iothread=0
On 08/12/2015 05:27 PM, John Ferlan wrote: Since iothreadid = 0 is invalid, we need to check for it when attempting to add a disk; otherwise, someone would think/believe their attempt to add an IOThread to the disk would succeed. Luckily other code ignored things when -iothread == 0... Signed-off-by: John Ferlan jfer...@redhat.com --- src/conf/domain_conf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) Ping - also see https://bugzilla.redhat.com/show_bug.cgi?id=1253108 Tks - John diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b743bdd..10630c0 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7448,7 +7448,8 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, } if (driverIOThread) { -if (virStrToLong_uip(driverIOThread, NULL, 10, def-iothread) 0) { +if (virStrToLong_uip(driverIOThread, NULL, 10, def-iothread) 0 || +def-iothread == 0) { virReportError(VIR_ERR_XML_ERROR, _(Invalid iothread attribute in disk driver element: %s), driverIOThread); -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 3/5] util: Add getters for cgroup block device I/O throttling
On Tue, Aug 18, 2015 at 01:15:43PM -0400, John Ferlan wrote: On 08/03/2015 10:50 AM, Martin Kletzander wrote: Since now they were not needed, but I sense they will be in a short while. Signed-off-by: Martin Kletzander mklet...@redhat.com --- src/libvirt_private.syms | 5 + src/util/vircgroup.c | 277 ++- src/util/vircgroup.h | 20 3 files changed, 299 insertions(+), 3 deletions(-) diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index afa85ded9061..9d527fb8b99a 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -804,6 +804,36 @@ virCgroupGetValueStr(virCgroupPtr group, static int +virCgroupGetValueForBlkDev(virCgroupPtr group, + int controller, + const char *key, + const char *path, + char **value) +{ +char *prefix = NULL; +char *str = NULL; +char **lines = NULL; +int ret = -1; + +if (virCgroupGetValueStr(group, controller, key, str) 0) +goto error; + +if (!(prefix = virCgroupGetBlockDevString(path))) +return -1; ^^^ str is leaked. (Coverity found) Copy-paste error, thanks for catching that. + +if (!(lines = virStringSplit(str, \n, -1))) +goto error; + +ret = VIR_STRDUP(*value, virStringGetFirstWithPrefix(lines, prefix)); ^^^ can return NULL VIR_STRDUP(*value, NULL) ?? That wouldn't actually do any harm, the function would return 0, but to make it as clear as possible, this is the diff that I applied before pushing: diff --git c/src/util/vircgroup.c w/src/util/vircgroup.c index 9d527fb8b99a..c94512a148b9 100644 --- c/src/util/vircgroup.c +++ w/src/util/vircgroup.c @@ -819,12 +819,15 @@ virCgroupGetValueForBlkDev(virCgroupPtr group, goto error; if (!(prefix = virCgroupGetBlockDevString(path))) -return -1; +goto error; if (!(lines = virStringSplit(str, \n, -1))) goto error; -ret = VIR_STRDUP(*value, virStringGetFirstWithPrefix(lines, prefix)); +if (VIR_STRDUP(*value, virStringGetFirstWithPrefix(lines, prefix)) 0) +goto error; + +ret = 0; error: VIR_FREE(str); VIR_FREE(prefix); -- Martin signature.asc Description: PGP signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] virsh: fix output the incorrect error after try failed
On 08/18/2015 08:56 PM, Erik Skultety wrote: On 17/08/15 11:56, Luyao Huang wrote: https://bugzilla.redhat.com/show_bug.cgi?id=1254152 When we use some virsh cmd which need specify domain name/id/uuid, if the command get failure we will get error like this: # virsh domif-setlink 123 vnet1 up error: interface (target: vnet1) not found error: Domain not found: no domain with matching id 123 The second line should be reset after call virshLookupDomainInternal, because after some tries we get domain pointer, so output error during we tried will make user confuse. Signed-off-by: Luyao Huang lhu...@redhat.com --- tools/virsh-domain.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 173bb15..69c5562 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -98,6 +98,8 @@ virshLookupDomainInternal(vshControl *ctl, dom = virDomainLookupByName(priv-conn, name); } +vshResetLibvirtError(); + if (!dom) vshError(ctl, _(failed to get domain '%s'), name); ACK, I reworded the commit message and pushed. Thanks a lot for your quick review and help. Erik Luyao -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] conf/qemu: enforce NUMA nodes only for x86 memory hotplug
David Gibson da...@gibson.dropbear.id.au writes: On Tue, Aug 18, 2015 at 03:35:11PM +0530, Nikunj A Dadhania wrote: libvirt enforces at least one NUMA node for memory hotplug support on all architectures. While it might be required for some x86 guest, PowerPC can hotplug memory on non-NUMA system. The generic checks are replaced with arch specific check and xml validation too does not enforce node for non-x86 arch. CC: Peter Krempa pkre...@redhat.com Signed-off-by: Nikunj A Dadhania nik...@linux.vnet.ibm.com For future reference, can you CC Andrea Bolognani abolo...@redhat.com on Power related libvirt patches? He's handling most of our Power / libvirt work here at Red Hat. Sure David Regards, Nikunj -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list