The following patch changes around how the 'disks' and 'nics' lists in a Guest object are used during an install. These lists are the public attributes used to specify the devices to connect to the guest at install time. Currently, during the actual install, these lists can be manipulated by the installer, to add a boot.iso as a CDROM disk to use for the install, for example ('nics' actually isn't altered during any install path but I wanted to be consistent.) This causes issues if the install fails, but the Guest object is kept around to try again (i.e. virt-manager): any re-attempt would append another cdrom disk based off the boot.iso. Rather than have an error cleanup restore things to their post install state, which would probably cause this bug to pop up again if another error path was added, I went with a small reorg which seems to be the right way to fix this. 'disks' and 'nics' remain but they are copied over to private lists at the start of the install to be used for all mid-install disk/nic additions. The public interface remains the same, its just behind the scenes workings that are shuffled. Any comments appreciated! - Cole -- Cole Robinson crobinso@xxxxxxxxxx
diff -r 9a1d35776b3c virtinst/DistroManager.py --- a/virtinst/DistroManager.py Mon Oct 29 16:28:39 2007 -0400 +++ b/virtinst/DistroManager.py Wed Nov 07 17:14:19 2007 -0500 @@ -626,10 +626,10 @@ class DistroInstaller(Guest.Installer): distro = distro) self._tmpfiles.append(cdrom) - guest.disks.append(Guest.VirtualDisk(cdrom, - device=Guest.VirtualDisk.DEVICE_CDROM, - readOnly=True, - transient=True)) + self._install_disk = Guest.VirtualDisk(cdrom, + device=Guest.VirtualDisk.DEVICE_CDROM, + readOnly=True, + transient=True) def _prepare_kernel_and_initrd(self, guest, distro, meter): if self.boot is not None: @@ -662,9 +662,9 @@ class DistroInstaller(Guest.Installer): # If they're installing off a local file/device, we map it # through to a virtual harddisk if self.location is not None and self.location.startswith("/"): - guest.disks.append(Guest.VirtualDisk(self.location, - readOnly=True, - transient=True)) + self._install_disk = Guest.VirtualDisk(self.location, + readOnly=True, + transient=True) def prepare(self, guest, meter, distro = None): self.cleanup() @@ -716,7 +716,7 @@ class DistroInstaller(Guest.Installer): def post_install_check(self, guest): # Check for the 0xaa55 signature at the end of the MBR - fd = os.open(guest.disks[0].path, os.O_RDONLY) + fd = os.open(guest._install_disks[0].path, os.O_RDONLY) buf = os.read(fd, 512) os.close(fd) return len(buf) == 512 and struct.unpack("H", buf[0x1fe: 0x200]) == (0xaa55,) @@ -761,7 +761,7 @@ class PXEInstaller(Guest.Installer): def post_install_check(self, guest): # Check for the 0xaa55 signature at the end of the MBR - fd = os.open(guest.disks[0].path, os.O_RDONLY) + fd = os.open(guest._install_disks[0].path, os.O_RDONLY) buf = os.read(fd, 512) os.close(fd) return len(buf) == 512 and struct.unpack("H", buf[0x1fe: 0x200]) == (0xaa55,) diff -r 9a1d35776b3c virtinst/FullVirtGuest.py --- a/virtinst/FullVirtGuest.py Mon Oct 29 16:28:39 2007 -0400 +++ b/virtinst/FullVirtGuest.py Wed Nov 07 17:14:19 2007 -0500 @@ -205,10 +205,13 @@ class FullVirtGuest(Guest.XenGuest): Guest.Guest.validate_parms(self) def _prepare_install(self, meter): + Guest.Guest._prepare_install(self, meter) if self.location or self.cdrom: self._installer.prepare(guest = self, meter = meter, distro = self.os_distro) + if self._installer.install_disk is not None: + self._install_disks.append(self._installer.install_disk) def get_continue_inst(self): if self.os_type is not None: @@ -248,7 +251,7 @@ class FullVirtGuest(Guest.XenGuest): # First assign CDROM device nodes, since they're scarce resource cdnode = self.disknode + "c" - for d in self.disks: + for d in self._install_disks: if d.device != Guest.VirtualDisk.DEVICE_CDROM: continue @@ -263,7 +266,7 @@ class FullVirtGuest(Guest.XenGuest): nodes[d.target] = d # Now assign regular disk node with remainder - for d in self.disks: + for d in self._install_disks: if d.device == Guest.VirtualDisk.DEVICE_CDROM: continue @@ -278,7 +281,7 @@ class FullVirtGuest(Guest.XenGuest): raise ValueError, "The disk device %s is already used" % d.target nodes[d.target] = d - for d in self.disks: + for d in self._install_disks: saved_path = None if d.device == Guest.VirtualDisk.DEVICE_CDROM and d.transient and not install: # XXX hack. libvirt can't currently handle QEMU having an empty disk path.. diff -r 9a1d35776b3c virtinst/Guest.py --- a/virtinst/Guest.py Mon Oct 29 16:28:39 2007 -0400 +++ b/virtinst/Guest.py Wed Nov 07 17:14:19 2007 -0500 @@ -386,6 +386,7 @@ class Installer(object): self._extraargs = None self._boot = None self._cdrom = False + self._install_disk = None # VirtualDisk that contains install media if type is None: type = "xen" @@ -405,6 +406,10 @@ class Installer(object): logging.debug("Removing " + f) os.unlink(f) self._tmpfiles = [] + + def get_install_disk(self): + return self._install_disk + install_disk = property(get_install_disk) def get_type(self): return self._type @@ -464,8 +469,6 @@ class Guest(object): class Guest(object): def __init__(self, type=None, connection=None, hypervisorURI=None, installer=None): self._installer = installer - self.disks = [] - self.nics = [] self._name = None self._uuid = None self._memory = None @@ -473,6 +476,14 @@ class Guest(object): self._vcpus = None self._graphics = { "enabled": False } self._keymap = None + + # Public device lists unaltered by install process + self.disks = [] + self.nics = [] + + # Device lists to use/alter during install process + self._install_disks = [] + self._install_nics = [] self.domain = None self.conn = connection @@ -657,9 +668,9 @@ class Guest(object): def _create_devices(self,progresscb): """Ensure that devices are setup""" - for disk in self.disks: + for disk in self._install_disks: disk.setup(progresscb) - for nic in self.nics: + for nic in self._install_nics: nic.setup(self.conn) def _get_network_xml(self, install = True): @@ -744,6 +755,10 @@ class Guest(object): finally: self._installer.cleanup() + def _prepare_install(self, meter): + self._install_disks = self.disks[:] + self._install_nics = self.nics[:] + def _do_install(self, consolecb, meter): try: if self.conn.lookupByName(self.name) is not None: diff -r 9a1d35776b3c virtinst/ParaVirtGuest.py --- a/virtinst/ParaVirtGuest.py Mon Oct 29 16:28:39 2007 -0400 +++ b/virtinst/ParaVirtGuest.py Wed Nov 07 17:14:19 2007 -0500 @@ -45,7 +45,11 @@ class ParaVirtGuest(Guest.XenGuest): Guest.Guest.validate_parms(self) def _prepare_install(self, meter): + Guest.Guest._prepare_install(self, meter) self._installer.prepare(guest = self, meter = meter) + if self._installer.install_disk is not None: + self._install_disks.append(self._installer.install_disk) + def _get_disk_xml(self, install = True): """Get the disk config in the libvirt XML format""" @@ -54,7 +58,7 @@ class ParaVirtGuest(Guest.XenGuest): for i in range(16): n = "%s%c" % (self.disknode, ord('a') + i) nodes[n] = None - for d in self.disks: + for d in self._install_disks: if d.transient and not install: continue target = d.target
_______________________________________________ et-mgmt-tools mailing list et-mgmt-tools@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/et-mgmt-tools