[virt-manager PATCH 2/3] virtinst: add a basic StoragePoolCapabilities

Pino Toscano ptoscano at redhat.com
Tue Nov 24 14:21:11 UTC 2020


Introduce a basic StoragePoolCapabilities class to fetch the pool
capabilities (if available) from a libvirt connection, and query for
supported pool types.

The poolcaps-fs.xml file was copied from the libvirt test suite.

Signed-off-by: Pino Toscano <ptoscano at redhat.com>
---
 tests/data/capabilities/poolcaps-fs.xml | 207 ++++++++++++++++++++++++
 tests/test_capabilities.py              |  25 +++
 virtinst/__init__.py                    |   1 +
 virtinst/storagepoolcapabilities.py     |  61 +++++++
 4 files changed, 294 insertions(+)
 create mode 100644 tests/data/capabilities/poolcaps-fs.xml
 create mode 100644 virtinst/storagepoolcapabilities.py

diff --git a/tests/data/capabilities/poolcaps-fs.xml b/tests/data/capabilities/poolcaps-fs.xml
new file mode 100644
index 00000000..eee75af7
--- /dev/null
+++ b/tests/data/capabilities/poolcaps-fs.xml
@@ -0,0 +1,207 @@
+<storagepoolCapabilities>
+  <pool type='dir' supported='no'>
+    <volOptions>
+      <defaultFormat type='raw'/>
+      <enum name='targetFormatType'>
+        <value>none</value>
+        <value>raw</value>
+        <value>dir</value>
+        <value>bochs</value>
+        <value>cloop</value>
+        <value>dmg</value>
+        <value>iso</value>
+        <value>vpc</value>
+        <value>vdi</value>
+        <value>fat</value>
+        <value>vhd</value>
+        <value>ploop</value>
+        <value>cow</value>
+        <value>qcow</value>
+        <value>qcow2</value>
+        <value>qed</value>
+        <value>vmdk</value>
+      </enum>
+    </volOptions>
+  </pool>
+  <pool type='fs' supported='yes'>
+    <poolOptions>
+      <defaultFormat type='auto'/>
+      <enum name='sourceFormatType'>
+        <value>auto</value>
+        <value>ext2</value>
+        <value>ext3</value>
+        <value>ext4</value>
+        <value>ufs</value>
+        <value>iso9660</value>
+        <value>udf</value>
+        <value>gfs</value>
+        <value>gfs2</value>
+        <value>vfat</value>
+        <value>hfs+</value>
+        <value>xfs</value>
+        <value>ocfs2</value>
+        <value>vmfs</value>
+      </enum>
+    </poolOptions>
+    <volOptions>
+      <defaultFormat type='raw'/>
+      <enum name='targetFormatType'>
+        <value>none</value>
+        <value>raw</value>
+        <value>dir</value>
+        <value>bochs</value>
+        <value>cloop</value>
+        <value>dmg</value>
+        <value>iso</value>
+        <value>vpc</value>
+        <value>vdi</value>
+        <value>fat</value>
+        <value>vhd</value>
+        <value>ploop</value>
+        <value>cow</value>
+        <value>qcow</value>
+        <value>qcow2</value>
+        <value>qed</value>
+        <value>vmdk</value>
+      </enum>
+    </volOptions>
+  </pool>
+  <pool type='netfs' supported='no'>
+    <poolOptions>
+      <defaultFormat type='auto'/>
+      <enum name='sourceFormatType'>
+        <value>auto</value>
+        <value>nfs</value>
+        <value>glusterfs</value>
+        <value>cifs</value>
+      </enum>
+    </poolOptions>
+    <volOptions>
+      <defaultFormat type='raw'/>
+      <enum name='targetFormatType'>
+        <value>none</value>
+        <value>raw</value>
+        <value>dir</value>
+        <value>bochs</value>
+        <value>cloop</value>
+        <value>dmg</value>
+        <value>iso</value>
+        <value>vpc</value>
+        <value>vdi</value>
+        <value>fat</value>
+        <value>vhd</value>
+        <value>ploop</value>
+        <value>cow</value>
+        <value>qcow</value>
+        <value>qcow2</value>
+        <value>qed</value>
+        <value>vmdk</value>
+      </enum>
+    </volOptions>
+  </pool>
+  <pool type='logical' supported='no'>
+    <poolOptions>
+      <defaultFormat type='lvm2'/>
+      <enum name='sourceFormatType'>
+        <value>unknown</value>
+        <value>lvm2</value>
+      </enum>
+    </poolOptions>
+  </pool>
+  <pool type='disk' supported='no'>
+    <poolOptions>
+      <defaultFormat type='unknown'/>
+      <enum name='sourceFormatType'>
+        <value>unknown</value>
+        <value>dos</value>
+        <value>dvh</value>
+        <value>gpt</value>
+        <value>mac</value>
+        <value>bsd</value>
+        <value>pc98</value>
+        <value>sun</value>
+        <value>lvm2</value>
+      </enum>
+    </poolOptions>
+    <volOptions>
+      <defaultFormat type='none'/>
+      <enum name='targetFormatType'>
+        <value>none</value>
+        <value>linux</value>
+        <value>fat16</value>
+        <value>fat32</value>
+        <value>linux-swap</value>
+        <value>linux-lvm</value>
+        <value>linux-raid</value>
+        <value>extended</value>
+      </enum>
+    </volOptions>
+  </pool>
+  <pool type='iscsi' supported='no'>
+  </pool>
+  <pool type='iscsi-direct' supported='no'>
+  </pool>
+  <pool type='scsi' supported='no'>
+  </pool>
+  <pool type='mpath' supported='no'>
+  </pool>
+  <pool type='rbd' supported='no'>
+    <volOptions>
+      <defaultFormat type='raw'/>
+      <enum name='targetFormatType'>
+      </enum>
+    </volOptions>
+  </pool>
+  <pool type='sheepdog' supported='no'>
+  </pool>
+  <pool type='gluster' supported='no'>
+    <volOptions>
+      <defaultFormat type='raw'/>
+      <enum name='targetFormatType'>
+        <value>none</value>
+        <value>raw</value>
+        <value>dir</value>
+        <value>bochs</value>
+        <value>cloop</value>
+        <value>dmg</value>
+        <value>iso</value>
+        <value>vpc</value>
+        <value>vdi</value>
+        <value>fat</value>
+        <value>vhd</value>
+        <value>ploop</value>
+        <value>cow</value>
+        <value>qcow</value>
+        <value>qcow2</value>
+        <value>qed</value>
+        <value>vmdk</value>
+      </enum>
+    </volOptions>
+  </pool>
+  <pool type='zfs' supported='no'>
+  </pool>
+  <pool type='vstorage' supported='no'>
+    <volOptions>
+      <defaultFormat type='raw'/>
+      <enum name='targetFormatType'>
+        <value>none</value>
+        <value>raw</value>
+        <value>dir</value>
+        <value>bochs</value>
+        <value>cloop</value>
+        <value>dmg</value>
+        <value>iso</value>
+        <value>vpc</value>
+        <value>vdi</value>
+        <value>fat</value>
+        <value>vhd</value>
+        <value>ploop</value>
+        <value>cow</value>
+        <value>qcow</value>
+        <value>qcow2</value>
+        <value>qed</value>
+        <value>vmdk</value>
+      </enum>
+    </volOptions>
+  </pool>
+</storagepoolCapabilities>
diff --git a/tests/test_capabilities.py b/tests/test_capabilities.py
index 0182e20f..84cb6bdb 100644
--- a/tests/test_capabilities.py
+++ b/tests/test_capabilities.py
@@ -11,6 +11,8 @@ from tests import utils
 
 from virtinst import Capabilities
 from virtinst import DomainCapabilities
+from virtinst import StoragePool
+from virtinst import StoragePoolCapabilities
 
 
 DATADIR = utils.DATADIR + "/capabilities"
@@ -112,3 +114,26 @@ def testDomainCapabilitiesAArch64():
     caps = DomainCapabilities(utils.URIs.open_testdriver_cached(), xml)
 
     assert "None" in caps.label_for_firmware_path(None)
+
+
+######################################
+# storagepoolcapabilities.py testing #
+######################################
+
+
+def testStoragePoolCapabilities():
+    xml = open(DATADIR + "/poolcaps-fs.xml").read()
+    caps = StoragePoolCapabilities(utils.URIs.open_testdriver_cached(), xml)
+
+    assert len(caps.pools) == 14
+    assert caps.supports_type(StoragePool.TYPE_DIR) is False
+    assert caps.supports_type(StoragePool.TYPE_FS) is True
+    assert caps.supports_type("unknownstoragepooltype") is False
+
+
+def testStoragePoolCapabilitiesNone():
+    caps = StoragePoolCapabilities(utils.URIs.open_testdriver_cached())
+
+    assert len(caps.pools) == 0
+    assert caps.supports_type(StoragePool.TYPE_DIR) is True
+    assert caps.supports_type("unknownstoragepooltype") is True
diff --git a/virtinst/__init__.py b/virtinst/__init__.py
index 02e852c1..f7e9d5ae 100644
--- a/virtinst/__init__.py
+++ b/virtinst/__init__.py
@@ -51,6 +51,7 @@ from virtinst.domain import *  # pylint: disable=wildcard-import
 
 from virtinst.capabilities import Capabilities
 from virtinst.domcapabilities import DomainCapabilities
+from virtinst.storagepoolcapabilities import StoragePoolCapabilities
 from virtinst.network import Network
 from virtinst.nodedev import NodeDevice
 from virtinst.storage import StoragePool, StorageVolume
diff --git a/virtinst/storagepoolcapabilities.py b/virtinst/storagepoolcapabilities.py
new file mode 100644
index 00000000..83627d59
--- /dev/null
+++ b/virtinst/storagepoolcapabilities.py
@@ -0,0 +1,61 @@
+#
+# Support for parsing libvirt's storagepoolcapabilities XML
+#
+# Copyright 2020 Red Hat, Inc.
+#
+# This work is licensed under the GNU GPLv2 or later.
+# See the COPYING file in the top-level directory.
+
+from .logger import log
+from .xmlbuilder import XMLBuilder, XMLChildProperty, XMLProperty
+
+
+##########################
+# Toplevel <pool> parser #
+##########################
+
+class _Pool(XMLBuilder):
+    XML_NAME = "pool"
+    pool_type = XMLProperty("./@type")
+    supported = XMLProperty("./@supported", is_yesno=True)
+
+
+######################################
+# StoragePoolCapabilities main class #
+######################################
+
+class StoragePoolCapabilities(XMLBuilder):
+    @staticmethod
+    def build_from_params(conn, flags=0):
+        xml = None
+        if conn.support.conn_storage_pool_capabilities():
+            try:
+                xml = conn.get_backend().getStoragePoolCapabilities(flags)
+            except Exception:  # pragma: no cover
+                log.debug("Error fetching storagepoolcapabilities XML",
+                    exc_info=True)
+
+        if not xml:
+            # If not supported, just use a stub object
+            return StoragePoolCapabilities(conn)
+        return StoragePoolCapabilities(conn, parsexml=xml)
+
+    def __init__(self, *args, **kwargs):
+        XMLBuilder.__init__(self, *args, **kwargs)
+        self._supported = kwargs.get('parsexml') is not None or len(args) >= 2
+
+    def supports_type(self, pool_type):
+        """
+        Returns True if either libvirt supports the passed pool type
+        or if libvirt does not have the getStoragePoolCapabilities API
+        (and thus there is no way to know).
+        """
+        if not self._supported:
+            return True
+        for pool in self.pools:
+            if pool.pool_type == pool_type:
+                return pool.supported
+        return False
+
+    XML_NAME = "storagepoolCapabilities"
+    pools = XMLChildProperty(_Pool)
-- 
2.28.0




More information about the virt-tools-list mailing list