diff --git a/tests/data/xmlparse/disk-change-bus-in.xml b/tests/data/xmlparse/disk-change-bus-in.xml
new file mode 100644
index 000000000..6b9f4d5db
--- /dev/null
+++ b/tests/data/xmlparse/disk-change-bus-in.xml
@@ -0,0 +1,25 @@
+
+ f30
+ 8294400
+
+ hvm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/data/xmlparse/disk-change-bus-out.xml b/tests/data/xmlparse/disk-change-bus-out.xml
new file mode 100644
index 000000000..8b9256ecf
--- /dev/null
+++ b/tests/data/xmlparse/disk-change-bus-out.xml
@@ -0,0 +1,22 @@
+
+ f30
+ 8294400
+
+ hvm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/test_xmlparse.py b/tests/test_xmlparse.py
index ebbbdbe02..5d285ea3c 100644
--- a/tests/test_xmlparse.py
+++ b/tests/test_xmlparse.py
@@ -1206,6 +1206,22 @@ class XMLParseTest(unittest.TestCase):
self._alter_compare(guest.get_xml(), outfile)
+ def testDiskChangeBus(self):
+ guest, outfile = self._get_test_content("disk-change-bus")
+
+ disk = guest.devices.disk[0]
+
+ # Same bus is a no-op
+ origxml = disk.get_xml()
+ disk.change_bus(guest, "virtio")
+ assert origxml == disk.get_xml()
+ disk.change_bus(guest, "ide")
+
+ disk = guest.devices.disk[2]
+ disk.change_bus(guest, "scsi")
+
+ self._alter_compare(guest.get_xml(), outfile)
+
##################
# Snapshot tests #
diff --git a/virtManager/object/domain.py b/virtManager/object/domain.py
index 71d0fe745..9349073a4 100644
--- a/virtManager/object/domain.py
+++ b/virtManager/object/domain.py
@@ -648,31 +648,6 @@ class vmmDomain(vmmLibvirtObject):
if not editdev:
return
- def _change_bus():
- oldprefix = editdev.get_target_prefix()[0]
- oldbus = editdev.bus
- editdev.bus = bus
-
- if oldbus == bus:
- return
-
- editdev.address.clear()
-
- if oldprefix == editdev.get_target_prefix()[0]:
- return
-
- used = []
- disks = (self.xmlobj.devices.disk +
- self.get_xmlobj(inactive=True).devices.disk)
- for d in disks:
- used.append(d.target)
-
- if editdev.target:
- used.remove(editdev.target)
-
- editdev.target = None
- editdev.generate_target(used)
-
if path != _SENTINEL:
editdev.path = path
if not do_hotplug:
@@ -693,7 +668,7 @@ class vmmDomain(vmmLibvirtObject):
editdev.driver_detect_zeroes = detect_zeroes or None
if bus != _SENTINEL:
- _change_bus()
+ editdev.change_bus(self.xmlobj, bus)
if do_hotplug:
self.hotplug(device=editdev)
diff --git a/virtinst/devices/disk.py b/virtinst/devices/disk.py
index c9b08b77b..cfe6ae914 100644
--- a/virtinst/devices/disk.py
+++ b/virtinst/devices/disk.py
@@ -890,6 +890,30 @@ class DeviceDisk(Device):
raise ValueError(_("Only %s disks for bus '%s' are supported"
% (maxnode, self.bus)))
+ def change_bus(self, guest, newbus):
+ """
+ Change the bus value for an existing disk, which has some
+ follow on side effects.
+ """
+ if self.bus == newbus:
+ return
+
+ oldprefix = self.get_target_prefix()[0]
+ self.bus = newbus
+
+ self.address.clear()
+
+ if oldprefix == self.get_target_prefix()[0]:
+ return
+
+ used = [disk.target for disk in guest.devices.disk]
+
+ if self.target:
+ used.remove(self.target)
+
+ self.target = None
+ self.generate_target(used)
+
##################
# Default config #