From 10dc8f3a3d17c38f5089616e541da4b2105bf8fe Mon Sep 17 00:00:00 2001 From: Erik Skultety Date: Thu, 18 May 2023 15:29:53 +0200 Subject: libvirt_wrapper: Add support for specifying a backing volume for create This whole storage volume creation process we decided to go through only makes sense when paired with a backing store volume. This can either be a vendor provided cloud image or a custom template image. What's important though is that in most cases we won't probably know anything about this backing volume but we need to in order to construct a correct volume XML for libvirt. This patch was inspired by virt-manager which (though in much more complexity) creates a transient storage pool for user-specified backing store files to let libvirt gather the necessary information for us to be populated back to libvirt in an XML for a new volume to be created. Signed-off-by: Erik Skultety --- lcitool/libvirt_wrapper.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/lcitool/libvirt_wrapper.py b/lcitool/libvirt_wrapper.py index 87154c6..e044861 100644 --- a/lcitool/libvirt_wrapper.py +++ b/lcitool/libvirt_wrapper.py @@ -182,7 +182,8 @@ class LibvirtStoragePoolObject(LibvirtAbstractObject): self.raw.storageVolLookupByName(name)) def create_volume(self, name, capacity, allocation=None, _format="qcow2", - units='bytes', owner=None, group=None, mode=None,): + units='bytes', owner=None, group=None, mode=None, + backing_store=None): import re unit_pattern = '^(bytes|B|[K,M,G,T,P,E](iB|B)?)$' @@ -221,6 +222,35 @@ class LibvirtStoragePoolObject(LibvirtAbstractObject): node_el = ET.SubElement(perms_el, perm) node_el.text = perm_var + if backing_store: + backing_store_path_str = backing_store.as_posix() + backingStore_el = ET.SubElement(root_el, "backingStore") + path_el = ET.SubElement(backingStore_el, "path") + format_el = ET.SubElement(backingStore_el, "format") + path_el.text = backing_store_path_str + + volobj = self._volume_by_path(backing_store_path_str) + if volobj: + format_ = volobj.format + else: + import uuid + + # We could not locate the backing store in any storage pool. + # In order to fill in the backingStore volume data correctly we + # need to create a transient pool of type dir which contains + # the backingStore file storage volume to let libvirt fetch the + # information for us. We'll destroy the pool afterwards. + + pool_dir = backing_store.parent.as_posix() + pool_name = "lcitool_" + str(uuid.uuid1()) + poolobj = self._create_transient_pool(self._conn, pool_name, + pool_dir) + volobj = self._volume_by_path(backing_store_path_str) + format_ = volobj.format + poolobj.destroy() + + format_el.attrib["type"] = format_ + volume_xml = ET.tostring(root_el, encoding="UTF-8", method="xml") return self._create_from_xml(name, volume_xml.decode("UTF-8")) -- cgit v1.1