Patch: Add glusterfs volumes support to virt-install

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello.
I would like to share my patch. It allows to create vm with volumes from glusterfs pools if volume already exists.



From 4bcb5ee8ec0df615b409af242306e568d4bb9827 Mon Sep 17 00:00:00 2001
From: Anatoly Belikov <wormblood@xxxxxxxxx>
Date: Thu, 23 Oct 2014 15:32:24 +0400
Subject: [PATCH] add gluster volume 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                      |   13 +++++++++++-
 virtinst/cli.py                        |   31 ++++++++++++++++++++++------
 virtinst/devicedisk.py                 |   25 +++++++++++++++--------
 virtinst/diskbackend.py                |   24 +++++++++++++++++-----
 virtinst/storage.py                    |    4 ++++
 8 files changed, 127 insertions(+), 21 deletions(-)

diff --git a/tests/testdriver.xml b/tests/testdriver.xml
index 579c756..70d5757 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>debian-gluster2.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..98d1600 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,8 +375,18 @@ class XMLParseTest(unittest.TestCase):
         check = self._make_checker(disk9)
         check("sourcePool", "defaultPool", "anotherPool")
 
-        self._alter_compare(guest.get_xml_config(), outfile)
+        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):
         xml = ("""<disk type="file" device="disk"><source file="/a.img"/>\n"""
                """<target dev="hda" bus="ide"/></disk>\n""")
diff --git a/virtinst/cli.py b/virtinst/cli.py
index e57ffbb..17baaa6 100644
--- a/virtinst/cli.py
+++ b/virtinst/cli.py
@@ -1530,7 +1530,9 @@ class ParserDisk(VirtCLIParser):
         self.set_param(None, "size", setter_cb=noset_cb)
         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,22 +1592,39 @@ 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 ""
-
+        
         inst = VirtCLIParser._parse(self, opts, inst)
-
+   
         create_kwargs = {"size": size, "fmt": fmt, "sparse": sparse,
             "vol_install": volinst, "backing_store": backing_store}
         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..2acbddf 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
@@ -100,7 +101,7 @@ def _is_dir_searchable(uid, username, path):
 def _distill_storage(conn, do_create, nomanaged,
                      path, vol_object, vol_install,
                      clone_path, backing_store,
-                     *args):
+                     *args, **kwargs):
     """
     Validates and updates params when the backing storage is changed
     """
@@ -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..a7259b2 100644
--- a/virtinst/diskbackend.py
+++ b/virtinst/diskbackend.py
@@ -38,9 +38,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 +58,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 +72,14 @@ 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()
+            import xml.etree.ElementTree as ET
+            root = ET.fromstring(pool.XMLDesc())
+            if root.attrib['type'] == 'gluster':
+                host_name = root.findall(".//host[@name]")[0].attrib['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 +467,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 +525,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..2b55cc6 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
-- 
1.7.10.4

_______________________________________________
virt-tools-list mailing list
virt-tools-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/virt-tools-list

[Index of Archives]     [Linux Virtualization]     [KVM Development]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]     [Video 4 Linux]

  Powered by Linux