mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 11:46:49 +00:00
fix(instances): change a disk's bus without rebuilding it as a file disk
The edit_volume bus change detached the disk and attached a new one built as a file disk, so block and rbd disks lost their source and auth, and a failed attach left the disk detached. Add wvmInstance.change_disk_bus, which reuses the disk element and only changes <target> (dropping the old bus address), and re-attaches the original disk if attaching fails. edit_disk also rebuilt every disk with <source file=...>; it now keeps the existing <source> and <auth> of block and network disks.
This commit is contained in:
parent
7286ba079d
commit
9205e56e3b
4 changed files with 122 additions and 33 deletions
|
|
@ -844,6 +844,32 @@ class wvmInstance(wvmConnect):
|
|||
if self.get_status() == 5:
|
||||
self.instance.detachDeviceFlags(xml_disk, VIR_DOMAIN_AFFECT_CONFIG)
|
||||
|
||||
def change_disk_bus(self, target_dev, new_target_dev, new_bus):
|
||||
"""
|
||||
Move a disk to another bus in the persistent config. The disk element
|
||||
is reused as is (type, source, auth, driver), only <target> changes
|
||||
and the old bus address is dropped. If attaching fails, the original
|
||||
disk is attached again.
|
||||
"""
|
||||
tree = etree.fromstring(self._XMLDesc(0))
|
||||
disk_el = tree.xpath("./devices/disk/target[@dev=$dev]", dev=target_dev)[
|
||||
0
|
||||
].getparent()
|
||||
old_xml = etree.tostring(disk_el).decode()
|
||||
|
||||
disk_el.find("target").set("dev", new_target_dev)
|
||||
disk_el.find("target").set("bus", new_bus)
|
||||
for address in disk_el.findall("address"):
|
||||
disk_el.remove(address)
|
||||
new_xml = etree.tostring(disk_el).decode()
|
||||
|
||||
self.instance.detachDeviceFlags(old_xml, VIR_DOMAIN_AFFECT_CONFIG)
|
||||
try:
|
||||
self.instance.attachDeviceFlags(new_xml, VIR_DOMAIN_AFFECT_CONFIG)
|
||||
except libvirtError:
|
||||
self.instance.attachDeviceFlags(old_xml, VIR_DOMAIN_AFFECT_CONFIG)
|
||||
raise
|
||||
|
||||
def edit_disk(
|
||||
self,
|
||||
target_dev,
|
||||
|
|
@ -894,8 +920,16 @@ class wvmInstance(wvmConnect):
|
|||
f"<driver name='{old_driver_name}' type='{format}' {additionals}/>"
|
||||
)
|
||||
|
||||
xml_disk += f"""<source file='{source}'/>
|
||||
<target dev='{target_dev}' bus='{target_bus}'/>"""
|
||||
if disk_el.get("type") == "file":
|
||||
xml_disk += f"<source file='{source}'/>"
|
||||
else:
|
||||
# Block/network disks: keep their source (and auth) untouched;
|
||||
# the form only edits the path of file disks.
|
||||
for name in ("auth", "source"):
|
||||
el = disk_el.find(name)
|
||||
if el is not None:
|
||||
xml_disk += etree.tostring(el).decode()
|
||||
xml_disk += f"<target dev='{target_dev}' bus='{target_bus}'/>"
|
||||
if readonly:
|
||||
xml_disk += """<readonly/>"""
|
||||
if shareable:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue