I have fixed pylint warnings i introduced and some more. Sorry for not using git-email yet. I am having some problems setting it up right now.
2014-10-24 6:06 GMT+04:00 Chen, Hanxiao <chenhanxiao@xxxxxxxxxxxxxx>:
Hi Anatoly,
Thanks for your patch.
Please run:
python setup.py pylint
and you’ll find that pylint complained a lot :)
Also, ‘git send-email’ is preferred for an easy review.
Thanks,
- Chen
From: virt-tools-list-bounces@xxxxxxxxxx [mailto:virt-tools-list-bounces@xxxxxxxxxx] On Behalf Of Anatoly Belikov
Sent: Thursday, October 23, 2014 8:20 PM
To: virt-tools-list@xxxxxxxxxx
Subject: Patch: Add glusterfs volumes support to virt-install
Hello.
I would like to share my patch. It allows to create vm with volumes from glusterfs pools if volume already exists.
--
С уважением
А. Беликов
From ee5b3aaaa37cc3c75954608425eb0096879ee30a Mon Sep 17 00:00:00 2001 From: Anatoly Belikov <wormblood@xxxxxxxxx> Date: Fri, 24 Oct 2014 19:34:20 +0400 Subject: [PATCH] add glusterfs volumes support to virt-install --- tests/testdriver.xml | 35 +++++++++++++++++++++++++++++++++- tests/xmlparse-xml/change-disk-in.xml | 8 ++++++++ tests/xmlparse-xml/change-disk-out.xml | 8 ++++++++ tests/xmlparse.py | 11 +++++++++++ virtinst/cli.py | 22 +++++++++++++++++++-- virtinst/devicedisk.py | 25 ++++++++++++++++-------- virtinst/diskbackend.py | 26 ++++++++++++++++++++----- virtinst/storage.py | 10 +++++++--- 8 files changed, 126 insertions(+), 19 deletions(-) diff --git a/tests/testdriver.xml b/tests/testdriver.xml index 579c756..43c0755 100644 --- a/tests/testdriver.xml +++ b/tests/testdriver.xml @@ -1739,7 +1739,40 @@ ba</description> </pool> - +<pool type='gluster'> + <name>gluster-pool</name> + <uuid>7b83ef6d-28da-44f1-841f-2011320f13b0</uuid> + <capacity unit='bytes'>492258959360</capacity> + <allocation unit='bytes'>16975638528</allocation> + <available unit='bytes'>475283320832</available> + <source> + <host name='192.168.1.100'/> + <dir path='/'/> + <name>test-volume</name> + </source> + <volume type='network'> + <name>test-volume2.raw</name> + <key>gluster://192.168.1.100/test-volume/test-gluster.raw</key> + <source> + </source> + <capacity unit='bytes'>10737418240</capacity> + <allocation unit='bytes'>2489327616</allocation> + <target> + <path>gluster://192.168.1.100/test-volume/test-gluster.raw</path> + <format type='raw'/> + <permissions> + <mode>0666</mode> + <owner>0</owner> + <group>0</group> + </permissions> + <timestamps> + <atime>1413881655.870313004</atime> + <mtime>1411649104.965642390</mtime> + <ctime>1412163870.190503958</ctime> + </timestamps> + </target> + </volume> +</pool> diff --git a/tests/xmlparse-xml/change-disk-in.xml b/tests/xmlparse-xml/change-disk-in.xml index 9725e9b..16c1140 100644 --- a/tests/xmlparse-xml/change-disk-in.xml +++ b/tests/xmlparse-xml/change-disk-in.xml @@ -68,6 +68,14 @@ <target dev='vda' bus='virtio'/> <readonly/> </disk> + <disk type='network' device='disk'> + <driver name='qemu' type='raw'/> + <source protocol='sheepdog' name='sheepdog-pool/test-sheepdog.raw'> + <host name='test.domain'/> + </source> + <target dev='vdc' bus='virtio'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </disk> <input type="mouse" bus="ps2"/> <graphics type="vnc" display=":3.4" xauth="/tmp/.Xauthority"/> <console type="pty"/> diff --git a/tests/xmlparse-xml/change-disk-out.xml b/tests/xmlparse-xml/change-disk-out.xml index d9af1e3..5acd34a 100644 --- a/tests/xmlparse-xml/change-disk-out.xml +++ b/tests/xmlparse-xml/change-disk-out.xml @@ -70,6 +70,14 @@ <target dev="vda" bus="virtio"/> <readonly/> </disk> + <disk type="network" device="disk"> + <driver name="qemu" type="raw"/> + <source protocol="gluster" name="test-volume/test-gluster.raw"> + <host name="192.168.1.100"/> + </source> + <target dev="vdc" bus="virtio"/> + <address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x0"/> + </disk> <input type="mouse" bus="ps2"/> <graphics type="vnc" display=":3.4" xauth="/tmp/.Xauthority"/> <console type="pty"/> diff --git a/tests/xmlparse.py b/tests/xmlparse.py index 62aa410..0bde7b2 100644 --- a/tests/xmlparse.py +++ b/tests/xmlparse.py @@ -332,6 +332,7 @@ class XMLParseTest(unittest.TestCase): disk6 = disks[5] disk6.size = 1 disk9 = disks[8] + disk_gl = disks[9] check = self._make_checker(disk1) check("path", "/tmp/test.img", "/dev/null") @@ -374,6 +375,16 @@ class XMLParseTest(unittest.TestCase): check = self._make_checker(disk9) check("sourcePool", "defaultPool", "anotherPool") + check = self._make_checker(disk_gl) + + check("source_protocol", "sheepdog", "gluster") + + check("host_name", "test.domain", "192.168.1.100") + pool = conn.storagePoolLookupByName('gluster-pool') + vol = pool.listAllVolumes()[0] # virStorageVolLookupByName is not available yet + self.assertEquals(disk_gl.path, "sheepdog-pool/test-sheepdog.raw") + disk_gl.path = vol + self.assertEquals(disk_gl.path, "test-volume/test-gluster.raw") self._alter_compare(guest.get_xml_config(), outfile) def testSingleDisk(self): diff --git a/virtinst/cli.py b/virtinst/cli.py index e57ffbb..b040da1 100644 --- a/virtinst/cli.py +++ b/virtinst/cli.py @@ -1531,6 +1531,8 @@ class ParserDisk(VirtCLIParser): self.set_param(None, "format", setter_cb=noset_cb) self.set_param(None, "sparse", setter_cb=noset_cb) + self.set_param("source_protocol", "source_protocol") + self.set_param("host_name", "host_name") self.set_param("path", "path") self.set_param("device", "device") self.set_param("bus", "bus") @@ -1590,11 +1592,24 @@ class ParserDisk(VirtCLIParser): size = parse_size(opts.get_opt_param("size")) fmt = opts.get_opt_param("format") sparse = _on_off_convert("sparse", opts.get_opt_param("sparse")) + host_name = None + protocol = None abspath, volinst, volobj = _parse_disk_source( self.guest, path, pool, vol, size, fmt, sparse) - path = volobj and volobj.path() or abspath + if volobj and volobj.path(): + gluster_protocol = 'gluster://' + if volobj.path().startswith('gluster://'): + path = volobj + protocol = 'gluster' + tmp = volobj.path()[len(gluster_protocol):] + host_name = tmp.split('/')[0] + else: + path = volobj.path() + else: + path = abspath + if had_path or path: opts.opts["path"] = path or "" @@ -1605,7 +1620,10 @@ class ParserDisk(VirtCLIParser): if any(create_kwargs.values()): inst.set_create_storage(**create_kwargs) inst.cli_size = size - + if protocol: + inst.source_protocol = protocol + if host_name: + inst.host_name = host_name if not inst.target: skip_targets = [d.target for d in self.guest.get_devices("disk")] inst.generate_target(skip_targets) diff --git a/virtinst/devicedisk.py b/virtinst/devicedisk.py index 1d764d9..a74e980 100644 --- a/virtinst/devicedisk.py +++ b/virtinst/devicedisk.py @@ -24,6 +24,7 @@ import stat import pwd import subprocess import logging +import libvirt import re import urlgrabber.progress as progress @@ -104,6 +105,7 @@ def _distill_storage(conn, do_create, nomanaged, """ Validates and updates params when the backing storage is changed """ + pool = None path_is_pool = False storage_capable = conn.check_support(conn.SUPPORT_CONN_STORAGE) @@ -116,7 +118,6 @@ def _distill_storage(conn, do_create, nomanaged, path = os.path.abspath(path) (vol_object, pool, path_is_pool) = diskbackend.manage_path(conn, path) - creator = None backend = diskbackend.StorageBackend(conn, path, vol_object, path_is_pool and pool or None) @@ -139,7 +140,7 @@ def _distill_storage(conn, do_create, nomanaged, return backend, creator -_TARGET_PROPS = ["file", "dev", "dir"] +_TARGET_PROPS = ["file", "dev", "dir", "name"] class VirtualDisk(VirtualDevice): @@ -183,7 +184,8 @@ class VirtualDisk(VirtualDevice): TYPE_BLOCK = "block" TYPE_DIR = "dir" TYPE_VOLUME = "volume" - types = [TYPE_FILE, TYPE_BLOCK, TYPE_DIR, TYPE_VOLUME] + TYPE_NETWORK = "network" + types = [TYPE_FILE, TYPE_BLOCK, TYPE_DIR, TYPE_NETWORK] IO_MODE_NATIVE = "native" IO_MODE_THREADS = "threads" @@ -215,6 +217,8 @@ class VirtualDisk(VirtualDevice): return "dev" elif disk_type == VirtualDisk.TYPE_DIR: return "dir" + elif disk_type == VirtualDisk.TYPE_NETWORK: + return "name" elif disk_type == VirtualDisk.TYPE_VOLUME: return "volume" return "file" @@ -514,7 +518,7 @@ class VirtualDisk(VirtualDevice): "type", "device", "driver_name", "driver_type", "driver_cache", "driver_discard", "driver_io", "error_policy", - "_xmlpath", "target", "bus", + "_xmlpath", "source_protocol", "host_name", "target", "bus", ] def __init__(self, *args, **kwargs): @@ -535,14 +539,18 @@ class VirtualDisk(VirtualDevice): if self._storage_creator: return self._storage_creator.path return self._storage_backend.path + def _set_path(self, val): if self._storage_creator: raise ValueError("Can't change disk path if storage creation info " "has been set.") - self._change_backend(val, None) + if type(val) == libvirt.virStorageVol: + self._change_backend(None, val) + else: + self._change_backend(val, None) self._xmlpath = self.path - path = property(_get_path, _set_path) + path = property(_get_path, _set_path) def get_sparse(self): if self._storage_creator: @@ -610,6 +618,9 @@ class VirtualDisk(VirtualDevice): _TARGET_PROPS]) sourcePool = XMLProperty("./source/@pool") + source_protocol = XMLProperty("./source/@protocol") + host_name = XMLProperty("./source/host/@name") + sourceStartupPolicy = XMLProperty("./source/@startupPolicy") device = XMLProperty("./@device", default_cb=lambda s: s.DEVICE_DISK) @@ -618,8 +629,6 @@ class VirtualDisk(VirtualDevice): default_cb=_get_default_driver_name) driver_type = XMLProperty("./driver/@type", default_cb=_get_default_driver_type) - - bus = XMLProperty("./target/@bus") target = XMLProperty("./target/@dev") removable = XMLProperty("./target/@removable", is_onoff=True) diff --git a/virtinst/diskbackend.py b/virtinst/diskbackend.py index 32715d1..29ceb9a 100644 --- a/virtinst/diskbackend.py +++ b/virtinst/diskbackend.py @@ -22,6 +22,7 @@ import logging import os import statvfs +import libxml2 import libvirt from . import util @@ -38,9 +39,9 @@ def check_if_path_managed(conn, path): verr = None path_is_pool = False - def lookup_vol_by_path(): + def lookup_vol_by_path(a_vol_path): try: - vol = conn.storageVolLookupByPath(path) + vol = conn.storageVolLookupByPath(a_vol_path) vol.info() return vol, None except libvirt.libvirtError, e: @@ -58,7 +59,7 @@ def check_if_path_managed(conn, path): pass return None - vol = lookup_vol_by_path()[0] + vol = lookup_vol_by_path(path)[0] if not vol: pool = StoragePool.lookup_pool_by_path(conn, os.path.dirname(path)) @@ -72,7 +73,15 @@ def check_if_path_managed(conn, path): # Pool may need to be refreshed, but if it errors, # invalidate it pool.refresh(0) - vol, verr = lookup_vol_by_path() + + pool_xml = libxml2.parseDoc(pool.XMLDesc()) + if pool_xml.getRootElement().prop('type') == 'gluster': + ctxt = pool_xml.xpathNewContext() + host_name = ctxt.xpathEval("//host[@name]")[0].prop('name') + vol_path = 'gluster://' + host_name + '/' + path + else: + vol_path = path + vol, verr = lookup_vol_by_path(vol_path) if verr: vol = lookup_vol_name(os.path.basename(path)) except Exception, e: @@ -460,7 +469,12 @@ class StorageBackend(_StorageBase): def _get_path(self): if self._vol_object: - return self._get_vol_xml().target_path + result = self._get_vol_xml().target_path + gluster_protocol = 'gluster://' + if result.startswith(gluster_protocol): + tmp = result[len(gluster_protocol):] + return result.split(tmp[:tmp.find('/') + 1])[1] + return result return self._path path = property(_get_path) @@ -513,6 +527,8 @@ class StorageBackend(_StorageBase): self._dev_type = "file" elif t == libvirt.VIR_STORAGE_VOL_BLOCK: self._dev_type = "block" + elif t == libvirt.VIR_STORAGE_VOL_NETWORK: + self._dev_type = "network" else: self._dev_type = "file" diff --git a/virtinst/storage.py b/virtinst/storage.py index d090ce4..0b96f9f 100644 --- a/virtinst/storage.py +++ b/virtinst/storage.py @@ -254,6 +254,10 @@ class StoragePool(_StorageObject): if use_source: xml_path = pool.source_path else: + if pool.type == 'gluster': + if pool.source_name == path: + return True + return False xml_path = pool.target_path if xml_path is not None and os.path.abspath(xml_path) == path: return True @@ -291,14 +295,14 @@ class StoragePool(_StorageObject): pass if pool: raise ValueError(_("Name '%s' already in use by another pool." % - name)) + name)) def _get_default_target_path(self): if not self.supports_property("target_path"): return None if (self.type == self.TYPE_DIR or - self.type == self.TYPE_NETFS or - self.type == self.TYPE_FS): + self.type == self.TYPE_NETFS or + self.type == self.TYPE_FS): return (DEFAULT_DIR_TARGET_BASE + self.name) if self.type == self.TYPE_LOGICAL: name = self.name -- 1.9.1
_______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list