From 4445d421ed0ffaf76a5c589170f731afbf9071f3 Mon Sep 17 00:00:00 2001 From: Nikos Skalkotos <skalkoto@grnet.gr> Date: Tue, 9 Sep 2014 18:11:50 +0300 Subject: [PATCH] windows: Fix a bug in the VirtIO installation code Make sure the guestfs VM is killed before we launch the VM that installs the VirtIO drivers. --- image_creator/os_type/windows/__init__.py | 79 ++++++++++++++--------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/image_creator/os_type/windows/__init__.py b/image_creator/os_type/windows/__init__.py index a664c46..791c0f2 100644 --- a/image_creator/os_type/windows/__init__.py +++ b/image_creator/os_type/windows/__init__.py @@ -721,6 +721,7 @@ class Windows(OSBase): self.out.output("failed! See: `%s' for the full output" % log.name) if i < retries - 1: self.out.output("retrying ...", False) + time.sleep(1) raise FatalError("Connection to the Windows VM failed after %d retries" % retries) @@ -866,8 +867,17 @@ class Windows(OSBase): tmp = uuid.uuid4().hex self.image.g.mkdir_p("%s/%s" % (self.systemroot, tmp)) - self._add_cleanup('virtio', self.image.g.rm_rf, - "%s/%s" % (self.systemroot, tmp)) + + # This is a hack. We create a function here and pass it to + # _add_cleanup because self.image.g may change and the _add_cleanup + # will cache it which is wrong. For older versions of the guestfs + # library we recreate the g handler in enable_guestfs() and the + # program will crash if cleanup retains an older value for the + # guestfs handler. + def remove_tmp(): + self.image.g.rm_rf("%s/%s" % (self.systemroot, tmp)) + + self._add_cleanup('virtio', remove_tmp) for fname in os.listdir(dirname): full_path = os.path.join(dirname, fname) @@ -929,38 +939,43 @@ class Windows(OSBase): def _boot_virtio_vm(self): """Boot the media and install the VirtIO drivers""" - timeout = self.sysprep_params['boot_timeout'].value - shutdown_timeout = self.sysprep_params['shutdown_timeout'].value - virtio_timeout = self.sysprep_params['virtio_timeout'].value - self.out.output("Starting Windows VM ...", False) - booted = False + old_windows = self.check_version(6, 1) <= 0 + self.image.disable_guestfs() try: - if self.check_version(6, 1) <= 0: - self.vm.start() - else: - self.vm.interface = 'ide' - self.vm.start(extra_disk=('/dev/null', 'virtio')) - self.vm.interface = 'virtio' - - self.out.success("started (console on VNC display: %d)" % - self.vm.display) - self.out.output("Waiting for Windows to boot ...", False) - if not self.vm.wait_on_serial(timeout): - raise FatalError("Windows VM booting timed out!") - self.out.success('done') - booted = True - self.out.output("Installing new drivers ...", False) - if not self.vm.wait_on_serial(virtio_timeout): - raise FatalError("Windows VirtIO installation timed out!") - self.out.success('done') - self.out.output('Shutting down ...', False) - (_, stderr, rc) = self.vm.wait(shutdown_timeout) - if rc != 0 or "terminating on signal" in stderr: - raise FatalError("Windows VM died unexpectedly!\n\n" - "(rc=%d)\n%s" % (rc, stderr)) - self.out.success('done') + timeout = self.sysprep_params['boot_timeout'].value + shutdown_timeout = self.sysprep_params['shutdown_timeout'].value + virtio_timeout = self.sysprep_params['virtio_timeout'].value + self.out.output("Starting Windows VM ...", False) + booted = False + try: + if old_windows: + self.vm.start() + else: + self.vm.interface = 'ide' + self.vm.start(extra_disk=('/dev/null', 'virtio')) + self.vm.interface = 'virtio' + + self.out.success("started (console on VNC display: %d)" % + self.vm.display) + self.out.output("Waiting for Windows to boot ...", False) + if not self.vm.wait_on_serial(timeout): + raise FatalError("Windows VM booting timed out!") + self.out.success('done') + booted = True + self.out.output("Installing new drivers ...", False) + if not self.vm.wait_on_serial(virtio_timeout): + raise FatalError("Windows VirtIO installation timed out!") + self.out.success('done') + self.out.output('Shutting down ...', False) + (_, stderr, rc) = self.vm.wait(shutdown_timeout) + if rc != 0 or "terminating on signal" in stderr: + raise FatalError("Windows VM died unexpectedly!\n\n" + "(rc=%d)\n%s" % (rc, stderr)) + self.out.success('done') + finally: + self.vm.stop(shutdown_timeout if booted else 1, fatal=False) finally: - self.vm.stop(shutdown_timeout if booted else 1, fatal=False) + self.image.enable_guestfs() with self.mount(readonly=True, silent=True): self.virtio_state = self.compute_virtio_state() -- GitLab