diff --git a/changelog/57477.fixed b/changelog/57477.fixed new file mode 100644 index 00000000000..f32f32fdfc7 --- /dev/null +++ b/changelog/57477.fixed @@ -0,0 +1 @@ +virt.init fix the disk target names diff --git a/salt/modules/virt.py b/salt/modules/virt.py index 8150e37fa1c..308cbb5aad7 100644 --- a/salt/modules/virt.py +++ b/salt/modules/virt.py @@ -712,15 +712,17 @@ def _gen_xml( context["disks"] = [] disk_bus_map = {"virtio": "vd", "xen": "xvd", "fdc": "fd", "ide": "hd"} + targets = [] for i, disk in enumerate(diskp): prefix = disk_bus_map.get(disk["model"], "sd") disk_context = { "device": disk.get("device", "disk"), - "target_dev": "{0}{1}".format(prefix, string.ascii_lowercase[i]), + "target_dev": _get_disk_target(targets, len(diskp), prefix), "disk_bus": disk["model"], "format": disk.get("format", "raw"), "index": six.text_type(i), } + targets.append(disk_context["target_dev"]) if disk.get("source_file"): url = urlparse(disk["source_file"]) if not url.scheme or not url.hostname: @@ -2115,6 +2117,21 @@ def _remove_indent(node): return diff +def _get_disk_target(targets, disks_count, prefix): + """ + Compute the disk target name for a given prefix. + + :param targets: the list of already computed targets + :param disks: the number of disks + :param prefix: the prefix of the target name, i.e. "hd" + """ + return [ + "{0}{1}".format(prefix, string.ascii_lowercase[i]) + for i in range(disks_count) + if "{0}{1}".format(prefix, string.ascii_lowercase[i]) not in targets + ][0] + + def _diff_disk_lists(old, new): """ Compare disk definitions to extract the changes and fix target devices @@ -2131,11 +2148,7 @@ def _diff_disk_lists(old, new): target_node = disk.find("target") target = target_node.get("dev") prefix = [item for item in prefixes if target.startswith(item)][0] - new_target = [ - "{0}{1}".format(prefix, string.ascii_lowercase[i]) - for i in range(len(new)) - if "{0}{1}".format(prefix, string.ascii_lowercase[i]) not in targets - ][0] + new_target = _get_disk_target(targets, len(new), prefix) target_node.set("dev", new_target) targets.append(new_target) diff --git a/tests/unit/modules/test_virt.py b/tests/unit/modules/test_virt.py index 2ffe4600ae1..090856fc812 100644 --- a/tests/unit/modules/test_virt.py +++ b/tests/unit/modules/test_virt.py @@ -803,7 +803,10 @@ def test_gen_xml_for_kvm_custom_profile(self): self.assertEqual(root.find("vcpu").text, "1") self.assertEqual(root.find("memory").text, six.text_type(512 * 1024)) self.assertEqual(root.find("memory").attrib["unit"], "KiB") - self.assertTrue(len(root.findall(".//disk")) == 2) + disks = root.findall(".//disk") + self.assertTrue(len(disks) == 2) + self.assertEqual(disks[0].find("target").get("dev"), "vda") + self.assertEqual(disks[1].find("target").get("dev"), "vdb") self.assertTrue(len(root.findall(".//interface")) == 2) def test_disk_profile_kvm_disk_pool(self): @@ -1137,11 +1140,15 @@ def test_gen_xml_cdrom(self): """ Test virt._gen_xml(), generating a cdrom device (different disk type, no source) """ + self.mock_conn.storagePoolLookupByName.return_value.XMLDesc.return_value = ( + "" + ) diskp = virt._disk_profile( self.mock_conn, None, "kvm", [ + {"name": "system", "pool": "default"}, { "name": "tested", "device": "cdrom", @@ -1162,12 +1169,13 @@ def test_gen_xml_cdrom(self): self.mock_conn, "hello", 1, 512, diskp, nicp, "kvm", "hvm", "x86_64", ) root = ET.fromstring(xml_data) - disk = root.findall(".//disk")[0] + disk = root.findall(".//disk")[1] self.assertEqual(disk.get("type"), "file") self.assertEqual(disk.attrib["device"], "cdrom") self.assertIsNone(disk.find("source")) + self.assertEqual(disk.find("target").get("dev"), "hda") - disk = root.findall(".//disk")[1] + disk = root.findall(".//disk")[2] self.assertEqual(disk.get("type"), "network") self.assertEqual(disk.attrib["device"], "cdrom") self.assertEqual(