virt: add more properties to generate volume XML

In order to generate almost all the volumes that libvirt can handle, add
the type, backingStore, permissions and allocation parameters to the
virt._gen_vol_xml() function.

Also make the format parameter optional since libvirt has default values
depending on the storage backend.
This commit is contained in:
Cédric Bosdonnat 2020-03-18 17:26:12 +01:00 committed by Daniel Wozniak
parent 720673dcc0
commit 2fd1556819
3 changed files with 88 additions and 5 deletions

View file

@ -665,15 +665,28 @@ def _gen_xml(
return template.render(**context)
def _gen_vol_xml(name, format, size):
def _gen_vol_xml(
name,
size,
format=None,
allocation=0,
type=None,
permissions=None,
backing_store=None,
nocow=False,
):
"""
Generate the XML string to define a libvirt storage volume
"""
size = int(size) * 1024 # MB
context = {
"type": type,
"name": name,
"target": {"permissions": permissions, "nocow": nocow},
"format": format,
"size": six.text_type(size),
"allocation": six.text_type(int(allocation) * 1024),
"backingStore": backing_store,
}
fn_ = "libvirt_volume.jinja"
try:
@ -1561,7 +1574,7 @@ def init(
log.debug("Generating libvirt XML for %s", _disk)
volume_name = "{0}/{1}".format(name, _disk["name"])
filename = "{0}.{1}".format(volume_name, _disk["format"])
vol_xml = _gen_vol_xml(filename, _disk["format"], _disk["size"])
vol_xml = _gen_vol_xml(filename, _disk["size"], format=_disk["format"])
define_vol_xml_str(vol_xml, pool=_disk.get("pool"))
elif virt_hypervisor in ["qemu", "kvm", "xen"]:

View file

@ -1,10 +1,39 @@
<volume>
<volume{% if type %} type='{{ type }}'{% endif %}>
<name>{{ name }}</name>
<source>
</source>
<capacity unit='KiB'>{{ size }}</capacity>
<allocation unit='KiB'>0</allocation>
<allocation unit='KiB'>{{ allocation }}</allocation>
<target>
{%- if format %}
<format type='{{ format }}'/>
{%- endif %}
{%- if target.permissions -%}
<permissions>
{%- if target.permissions.get('mode') %}
<mode>{{ target.permissions.mode }}</mode>
{%- endif %}
{%- if target.permissions.get('owner') %}
<owner>{{ target.permissions.owner }}</owner>
{%- endif %}
{%- if target.permissions.get('group') %}
<group>{{ target.permissions.group }}</group>
{%- endif %}
{%- if target.permissions.get('label') %}
<label>{{ target.permissions.label }}</label>
{%- endif %}
</permissions>
{%- endif %}
{%- if target.nocow %}
<nocow/>
{%- endif %}
</target>
{%- if backingStore %}
<backingStore>
<path>{{ backingStore.path }}</path>
{%- if backingStore.format %}
<format type='{{ backingStore.format }}'/>
{%- endif %}
</backingStore>
{%- endif %}
</volume>

View file

@ -538,13 +538,54 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
"""
Test virt._get_vol_xml() for the ESX case
"""
xml_data = virt._gen_vol_xml("vmname/system.vmdk", "vmdk", 8192)
xml_data = virt._gen_vol_xml("vmname/system.vmdk", 8192, format="vmdk")
root = ET.fromstring(xml_data)
self.assertIsNone(root.get("type"))
self.assertEqual(root.find("name").text, "vmname/system.vmdk")
self.assertEqual(root.find("capacity").attrib["unit"], "KiB")
self.assertEqual(root.find("capacity").text, six.text_type(8192 * 1024))
self.assertEqual(root.find("allocation").text, six.text_type(0))
self.assertEqual(root.find("target/format").get("type"), "vmdk")
self.assertIsNone(root.find("target/permissions"))
self.assertIsNone(root.find("target/nocow"))
self.assertIsNone(root.find("backingStore"))
def test_gen_vol_xml_file(self):
"""
Test virt._get_vol_xml() for a file volume
"""
xml_data = virt._gen_vol_xml(
"myvm_system.qcow2",
8192,
format="qcow2",
allocation=4096,
type="file",
permissions={
"mode": "0775",
"owner": "123",
"group": "456",
"label": "sec_label",
},
backing_store={"path": "/backing/image", "format": "raw"},
nocow=True,
)
root = ET.fromstring(xml_data)
self.assertEqual(root.get("type"), "file")
self.assertEqual(root.find("name").text, "myvm_system.qcow2")
self.assertIsNone(root.find("key"))
self.assertIsNone(root.find("target/path"))
self.assertEqual(root.find("target/format").get("type"), "qcow2")
self.assertEqual(root.find("capacity").attrib["unit"], "KiB")
self.assertEqual(root.find("capacity").text, six.text_type(8192 * 1024))
self.assertEqual(root.find("capacity").attrib["unit"], "KiB")
self.assertEqual(root.find("allocation").text, six.text_type(4096 * 1024))
self.assertEqual(root.find("target/permissions/mode").text, "0775")
self.assertEqual(root.find("target/permissions/owner").text, "123")
self.assertEqual(root.find("target/permissions/group").text, "456")
self.assertEqual(root.find("target/permissions/label").text, "sec_label")
self.assertIsNotNone(root.find("target/nocow"))
self.assertEqual(root.find("backingStore/path").text, "/backing/image")
self.assertEqual(root.find("backingStore/format").get("type"), "raw")
def test_gen_xml_for_kvm_default_profile(self):
"""