mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-02-08 05:57:43 +03:00
storage: Simplify source pool enumeration
Don't return an XML object stub, just return the relevant data. Make it explicit that we currently are only supporting lvm enumeration
This commit is contained in:
parent
4d86e1129b
commit
105553563a
@ -1,11 +0,0 @@
|
|||||||
<pool type="logical">
|
|
||||||
<name>pool-logical-list0</name>
|
|
||||||
<source>
|
|
||||||
<format type="lvm2"/>
|
|
||||||
<device path="/dev/sda20"/>
|
|
||||||
<name>testvg1</name>
|
|
||||||
</source>
|
|
||||||
<target>
|
|
||||||
<path>/dev/testvg1</path>
|
|
||||||
</target>
|
|
||||||
</pool>
|
|
@ -1,11 +0,0 @@
|
|||||||
<pool type="logical">
|
|
||||||
<name>pool-logical-list1</name>
|
|
||||||
<source>
|
|
||||||
<format type="lvm2"/>
|
|
||||||
<device path="/dev/sda21"/>
|
|
||||||
<name>testvg2</name>
|
|
||||||
</source>
|
|
||||||
<target>
|
|
||||||
<path>/dev/testvg2</path>
|
|
||||||
</target>
|
|
||||||
</pool>
|
|
@ -1,11 +0,0 @@
|
|||||||
<pool type="netfs">
|
|
||||||
<source>
|
|
||||||
<host name="example.com"/>
|
|
||||||
<format type="nfs"/>
|
|
||||||
<dir path="/testshare"/>
|
|
||||||
</source>
|
|
||||||
<name>pool-netfs-list0</name>
|
|
||||||
<target>
|
|
||||||
<path>/var/lib/libvirt/images/pool-netfs-list0</path>
|
|
||||||
</target>
|
|
||||||
</pool>
|
|
@ -223,34 +223,7 @@ class TestStorage(unittest.TestCase):
|
|||||||
StoragePool.find_free_name(fullconn, "gluster-pool"),
|
StoragePool.find_free_name(fullconn, "gluster-pool"),
|
||||||
"gluster-pool-1")
|
"gluster-pool-1")
|
||||||
|
|
||||||
|
|
||||||
##############################
|
|
||||||
# Tests for pool-sources API #
|
|
||||||
##############################
|
|
||||||
|
|
||||||
def _enumerateCompare(self, name, pool_list):
|
|
||||||
for pool in pool_list:
|
|
||||||
pool.name = name + str(pool_list.index(pool))
|
|
||||||
poolobj = poolCompare(pool)
|
|
||||||
removePool(poolobj)
|
|
||||||
|
|
||||||
def testEnumerateLogical(self):
|
def testEnumerateLogical(self):
|
||||||
name = "pool-logical-list"
|
|
||||||
lst = StoragePool.pool_list_from_sources(self.conn,
|
lst = StoragePool.pool_list_from_sources(self.conn,
|
||||||
StoragePool.TYPE_LOGICAL)
|
StoragePool.TYPE_LOGICAL)
|
||||||
self._enumerateCompare(name, lst)
|
self.assertEqual(lst, ["testvg1", "testvg2"])
|
||||||
|
|
||||||
def testEnumerateNetFS(self):
|
|
||||||
name = "pool-netfs-list"
|
|
||||||
host = "example.com"
|
|
||||||
lst = StoragePool.pool_list_from_sources(self.conn,
|
|
||||||
StoragePool.TYPE_NETFS,
|
|
||||||
host=host)
|
|
||||||
self._enumerateCompare(name, lst)
|
|
||||||
|
|
||||||
def testEnumerateiSCSI(self):
|
|
||||||
host = "example.com"
|
|
||||||
lst = StoragePool.pool_list_from_sources(self.conn,
|
|
||||||
StoragePool.TYPE_ISCSI,
|
|
||||||
host=host)
|
|
||||||
self.assertTrue(len(lst) == 0)
|
|
||||||
|
@ -101,7 +101,7 @@ class vmmCreatePool(vmmGObjectUI):
|
|||||||
# Target path combo box entry
|
# Target path combo box entry
|
||||||
target_list = self.widget("pool-target-path")
|
target_list = self.widget("pool-target-path")
|
||||||
# target_path, Label, pool class instance
|
# target_path, Label, pool class instance
|
||||||
target_model = Gtk.ListStore(str, str, object)
|
target_model = Gtk.ListStore(str, str)
|
||||||
target_model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
target_model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
||||||
target_list.set_model(target_model)
|
target_list.set_model(target_model)
|
||||||
target_list.set_entry_text_column(0)
|
target_list.set_entry_text_column(0)
|
||||||
@ -109,7 +109,7 @@ class vmmCreatePool(vmmGObjectUI):
|
|||||||
# Source path combo box entry
|
# Source path combo box entry
|
||||||
source_list = self.widget("pool-source-path")
|
source_list = self.widget("pool-source-path")
|
||||||
# source_path, Label, pool class instance
|
# source_path, Label, pool class instance
|
||||||
source_model = Gtk.ListStore(str, str, object)
|
source_model = Gtk.ListStore(str, str)
|
||||||
source_model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
source_model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
||||||
source_list.set_model(source_model)
|
source_list.set_model(source_model)
|
||||||
source_list.set_entry_text_column(0)
|
source_list.set_entry_text_column(0)
|
||||||
@ -155,14 +155,15 @@ class vmmCreatePool(vmmGObjectUI):
|
|||||||
use_model = source_model
|
use_model = source_model
|
||||||
entry_list = []
|
entry_list = []
|
||||||
if pooltype == StoragePool.TYPE_SCSI:
|
if pooltype == StoragePool.TYPE_SCSI:
|
||||||
entry_list = self._list_scsi_adapters()
|
host_list = self._list_scsi_adapters()
|
||||||
|
entry_list = [[h, h] for h in host_list]
|
||||||
use_list = source_list
|
use_list = source_list
|
||||||
use_model = source_model
|
use_model = source_model
|
||||||
|
|
||||||
elif pooltype == StoragePool.TYPE_LOGICAL:
|
elif pooltype == StoragePool.TYPE_LOGICAL:
|
||||||
pool_list = self._list_pool_sources(pooltype)
|
vglist = self._list_pool_sources(pooltype)
|
||||||
entry_list = [[p.target_path, p.target_path, p]
|
target_paths = ["/dev/%s" % vgname for vgname in vglist]
|
||||||
for p in pool_list if p.target_path]
|
entry_list = [[t, t] for t in target_paths]
|
||||||
use_list = target_list
|
use_list = target_list
|
||||||
use_model = target_model
|
use_model = target_model
|
||||||
|
|
||||||
@ -175,26 +176,13 @@ class vmmCreatePool(vmmGObjectUI):
|
|||||||
def _list_scsi_adapters(self):
|
def _list_scsi_adapters(self):
|
||||||
scsi_hosts = self.conn.filter_nodedevs("scsi_host")
|
scsi_hosts = self.conn.filter_nodedevs("scsi_host")
|
||||||
host_list = [dev.xmlobj.host for dev in scsi_hosts]
|
host_list = [dev.xmlobj.host for dev in scsi_hosts]
|
||||||
|
return ["host%s" % h for h in host_list]
|
||||||
|
|
||||||
clean_list = []
|
def _list_pool_sources(self, pool_type):
|
||||||
for h in host_list:
|
|
||||||
name = "host%s" % h
|
|
||||||
tmppool = self._make_stub_pool()
|
|
||||||
tmppool.source_path = name
|
|
||||||
|
|
||||||
entry = [name, name, tmppool]
|
|
||||||
if name not in [l[0] for l in clean_list]:
|
|
||||||
clean_list.append(entry)
|
|
||||||
|
|
||||||
return clean_list
|
|
||||||
|
|
||||||
def _list_pool_sources(self, pool_type, host=None):
|
|
||||||
plist = []
|
plist = []
|
||||||
try:
|
try:
|
||||||
plist = StoragePool.pool_list_from_sources(
|
plist = StoragePool.pool_list_from_sources(
|
||||||
self.conn.get_backend(),
|
self.conn.get_backend(), pool_type)
|
||||||
pool_type,
|
|
||||||
host=host)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
log.exception("Pool enumeration failed")
|
log.exception("Pool enumeration failed")
|
||||||
|
|
||||||
@ -315,31 +303,13 @@ class vmmCreatePool(vmmGObjectUI):
|
|||||||
# Object building #
|
# Object building #
|
||||||
###################
|
###################
|
||||||
|
|
||||||
def _get_pool_from_sourcelist(self):
|
|
||||||
"""
|
|
||||||
If an enumerated pool source was selected, use that as the
|
|
||||||
basis for our pool object
|
|
||||||
"""
|
|
||||||
source_list = self.widget("pool-source-path")
|
|
||||||
target_list = self.widget("pool-target-path")
|
|
||||||
|
|
||||||
pool = uiutil.get_list_selection(source_list, column=2,
|
|
||||||
check_entry=False)
|
|
||||||
if pool is None:
|
|
||||||
pool = uiutil.get_list_selection(target_list, column=2,
|
|
||||||
check_entry=False)
|
|
||||||
|
|
||||||
return pool
|
|
||||||
|
|
||||||
def _build_xmlobj_from_xmleditor(self):
|
def _build_xmlobj_from_xmleditor(self):
|
||||||
xml = self._xmleditor.get_xml()
|
xml = self._xmleditor.get_xml()
|
||||||
log.debug("Using XML from xmleditor:\n%s", xml)
|
log.debug("Using XML from xmleditor:\n%s", xml)
|
||||||
return StoragePool(self.conn.get_backend(), parsexml=xml)
|
return StoragePool(self.conn.get_backend(), parsexml=xml)
|
||||||
|
|
||||||
def _make_stub_pool(self):
|
def _make_stub_pool(self):
|
||||||
pool = self._get_pool_from_sourcelist()
|
pool = StoragePool(self.conn.get_backend())
|
||||||
if not pool:
|
|
||||||
pool = StoragePool(self.conn.get_backend())
|
|
||||||
pool.type = self._get_config_pool_type()
|
pool.type = self._get_config_pool_type()
|
||||||
pool.name = self.widget("pool-name").get_text()
|
pool.name = self.widget("pool-name").get_text()
|
||||||
return pool
|
return pool
|
||||||
|
@ -63,15 +63,6 @@ def _lookup_poolxml_by_path(conn, path):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class _EnumerateSource(XMLBuilder):
|
|
||||||
XML_NAME = "source"
|
|
||||||
|
|
||||||
|
|
||||||
class _EnumerateSources(XMLBuilder):
|
|
||||||
XML_NAME = "sources"
|
|
||||||
sources = XMLChildProperty(_EnumerateSource)
|
|
||||||
|
|
||||||
|
|
||||||
class _Host(XMLBuilder):
|
class _Host(XMLBuilder):
|
||||||
_XML_PROP_ORDER = ["name", "port"]
|
_XML_PROP_ORDER = ["name", "port"]
|
||||||
XML_NAME = "host"
|
XML_NAME = "host"
|
||||||
@ -98,47 +89,32 @@ class StoragePool(_StorageObject):
|
|||||||
TYPE_ZFS = "zfs"
|
TYPE_ZFS = "zfs"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def pool_list_from_sources(conn, pool_type, host=None):
|
def pool_list_from_sources(conn, pool_type):
|
||||||
"""
|
"""
|
||||||
Return a list of StoragePool instances built from libvirt's pool
|
Return a list of StoragePool instances built from libvirt's pool
|
||||||
source enumeration (if supported).
|
source enumeration (if supported).
|
||||||
|
|
||||||
:param conn: Libvirt connection
|
:param conn: Libvirt connection
|
||||||
:param name: Name for the new pool
|
|
||||||
:param pool_type: Pool type string from I{Types}
|
:param pool_type: Pool type string from I{Types}
|
||||||
:param host: Option host string to poll for sources
|
|
||||||
"""
|
"""
|
||||||
if host:
|
source_xml = "<source/>"
|
||||||
source_xml = "<source><host name='%s'/></source>" % host
|
|
||||||
else:
|
|
||||||
source_xml = "<source/>"
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
xml = conn.findStoragePoolSources(pool_type, source_xml, 0)
|
xml = conn.findStoragePoolSources(pool_type, source_xml, 0)
|
||||||
except Exception as e:
|
except Exception as e: # pragma: no cover
|
||||||
if conn.support.is_error_nosupport(e):
|
if conn.support.is_error_nosupport(e):
|
||||||
return []
|
return []
|
||||||
raise # pragma: no cover
|
raise
|
||||||
|
|
||||||
ret = []
|
log.debug("Libvirt returned pool sources XML:\n%s", xml)
|
||||||
sources = _EnumerateSources(conn, xml)
|
|
||||||
for source in sources.sources:
|
|
||||||
source_xml = source.get_xml()
|
|
||||||
|
|
||||||
pool_xml = "<pool>\n%s\n</pool>" % source_xml
|
import xml.etree.ElementTree as ET
|
||||||
parseobj = StoragePool(conn, parsexml=pool_xml)
|
root = ET.fromstring(xml)
|
||||||
parseobj.type = pool_type
|
|
||||||
|
|
||||||
obj = StoragePool(conn)
|
# We implicitly only support this for pool TYPE_LOGICAL
|
||||||
obj.type = pool_type
|
ret = [e.text for e in root.findall("./source/name")]
|
||||||
obj.source_path = parseobj.source_path
|
|
||||||
for h in parseobj.hosts:
|
|
||||||
parseobj.remove_child(h)
|
|
||||||
obj.add_child(h)
|
|
||||||
obj.source_name = parseobj.source_name
|
|
||||||
obj.format = parseobj.format
|
|
||||||
|
|
||||||
ret.append(obj)
|
log.debug("Sources returning: %s", ret)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
Loading…
x
Reference in New Issue
Block a user