storage: Handle guest collision checking
This pattern is already used in two places. Formalize and centralize it
This commit is contained in:
parent
58dfe05344
commit
47a6f3a6d5
|
@ -1524,10 +1524,8 @@ class vmmAddHardware(vmmGObjectUI):
|
|||
for c in self.vm.xmlobj.devices.controller])):
|
||||
controller_model = "virtio-scsi"
|
||||
|
||||
collidelist = [d.path for d in self.vm.xmlobj.devices.disk]
|
||||
|
||||
disk = self.addstorage.build_device(self.vm.get_name(),
|
||||
collidelist=collidelist, device=device)
|
||||
collideguest=self.vm.xmlobj, device=device)
|
||||
|
||||
used = []
|
||||
disk.bus = bus
|
||||
|
|
|
@ -142,7 +142,7 @@ class vmmAddStorage(vmmGObjectUI):
|
|||
use_storage.set_sensitive(True)
|
||||
storage_area.set_tooltip_text(storage_tooltip or "")
|
||||
|
||||
def get_default_path(self, name, collidelist=None):
|
||||
def get_default_path(self, name, collideguest=None):
|
||||
pool = self.conn.get_default_pool()
|
||||
if not pool:
|
||||
return
|
||||
|
@ -151,15 +151,9 @@ class vmmAddStorage(vmmGObjectUI):
|
|||
suffix = virtinst.StorageVolume.get_file_extension_for_format(fmt)
|
||||
suffix = suffix or ".img"
|
||||
|
||||
# Sanitize collidelist to work with the collision checker
|
||||
newcollidelist = []
|
||||
for c in (collidelist or []):
|
||||
if c and os.path.dirname(c) == pool.get_target_path():
|
||||
newcollidelist.append(os.path.basename(c))
|
||||
|
||||
path = virtinst.StorageVolume.find_free_name(
|
||||
pool.get_backend(), name,
|
||||
suffix=suffix, collidelist=newcollidelist)
|
||||
self.conn.get_backend(), pool.get_backend(), name,
|
||||
suffix=suffix, collideguest=collideguest)
|
||||
|
||||
return os.path.join(pool.xmlobj.target_path, path)
|
||||
|
||||
|
@ -167,10 +161,10 @@ class vmmAddStorage(vmmGObjectUI):
|
|||
return self.widget("storage-create").get_active()
|
||||
|
||||
def build_device(self, vmname,
|
||||
path=None, device="disk", collidelist=None):
|
||||
path=None, device="disk", collideguest=None):
|
||||
if path is None:
|
||||
if self.is_default_storage():
|
||||
path = self.get_default_path(vmname, collidelist or [])
|
||||
path = self.get_default_path(vmname, collideguest=collideguest)
|
||||
else:
|
||||
path = self.widget("storage-entry").get_text().strip()
|
||||
|
||||
|
|
|
@ -160,6 +160,7 @@ class vmmCreateVolume(vmmGObjectUI):
|
|||
ret = ""
|
||||
try:
|
||||
ret = StorageVolume.find_free_name(
|
||||
self.conn.get_backend(),
|
||||
self._parent_pool.get_backend(),
|
||||
hint, suffix=suffix)
|
||||
if ret and suffix:
|
||||
|
|
|
@ -2738,15 +2738,9 @@ def _get_default_image_format(conn, poolobj):
|
|||
|
||||
|
||||
def _generate_new_volume_name(guest, poolobj, fmt):
|
||||
collidelist = []
|
||||
for disk in guest.devices.disk:
|
||||
if (disk.get_vol_install() and
|
||||
disk.get_vol_install().pool.name() == poolobj.name()):
|
||||
collidelist.append(os.path.basename(disk.path))
|
||||
|
||||
ext = StorageVolume.get_file_extension_for_format(fmt)
|
||||
return StorageVolume.find_free_name(
|
||||
poolobj, guest.name, suffix=ext, collidelist=collidelist)
|
||||
guest.conn, poolobj, guest.name, suffix=ext, collideguest=guest)
|
||||
|
||||
|
||||
class ParserDisk(VirtCLIParser):
|
||||
|
|
|
@ -76,7 +76,7 @@ def _upload_file(conn, meter, destpool, src):
|
|||
# Build placeholder volume
|
||||
size = os.path.getsize(src)
|
||||
basename = os.path.basename(src)
|
||||
name = StorageVolume.find_free_name(destpool, basename)
|
||||
name = StorageVolume.find_free_name(conn, destpool, basename)
|
||||
if name != basename:
|
||||
logging.debug("Generated non-colliding volume name %s", name)
|
||||
|
||||
|
|
|
@ -535,11 +535,29 @@ class StorageVolume(_StorageObject):
|
|||
return "." + fmt
|
||||
|
||||
@staticmethod
|
||||
def find_free_name(pool_object, basename, **kwargs):
|
||||
def find_free_name(conn, pool_object, basename, collideguest=None, **kwargs):
|
||||
"""
|
||||
Finds a name similar (or equal) to passed 'basename' that is not
|
||||
in use by another volume. Extra params are passed to generate_name
|
||||
|
||||
:param collideguest: Guest object. If specified, also check to
|
||||
ensure we don't collide with any disk paths there
|
||||
"""
|
||||
collidelist = []
|
||||
if collideguest:
|
||||
pooltarget = None
|
||||
poolname = pool_object.name()
|
||||
for poolxml in conn.fetch_all_pools():
|
||||
if poolxml.name == poolname:
|
||||
pooltarget = poolxml.target_path
|
||||
break
|
||||
|
||||
for disk in collideguest.devices.disk:
|
||||
if (pooltarget and disk.path and
|
||||
os.path.dirname(disk.path) == pooltarget):
|
||||
collidelist.append(os.path.basename(disk.path))
|
||||
|
||||
kwargs["collidelist"] = collidelist
|
||||
StoragePool.ensure_pool_is_running(pool_object, refresh=True)
|
||||
return generatename.generate_name(basename,
|
||||
pool_object.storageVolLookupByName,
|
||||
|
|
Loading…
Reference in New Issue