From 392c371a9dceb907abdc84ac46ed5b0b80e713cc Mon Sep 17 00:00:00 2001 From: Nikos Skalkotos <skalkoto@grnet.gr> Date: Fri, 27 Jun 2014 17:07:19 +0300 Subject: [PATCH] windows: Support WIN8 virtio driver installation Support installing virtio drivers in Windows 8, 8.1, 2012 and 2012R2 --- image_creator/os_type/windows/__init__.py | 42 ++++++++++++++++----- image_creator/os_type/windows/powershell.py | 11 +++++- image_creator/os_type/windows/vm.py | 16 ++++++-- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/image_creator/os_type/windows/__init__.py b/image_creator/os_type/windows/__init__.py index d02f33a..377694b 100644 --- a/image_creator/os_type/windows/__init__.py +++ b/image_creator/os_type/windows/__init__.py @@ -23,7 +23,7 @@ from image_creator.util import FatalError from image_creator.os_type.windows.vm import VM from image_creator.os_type.windows.registry import Registry from image_creator.os_type.windows.winexe import WinEXE -from image_creator.os_type.windows.powershell import DRVINST +from image_creator.os_type.windows.powershell import DRVINST, SAFEBOOT import tempfile import random @@ -611,14 +611,23 @@ class Windows(OSBase): admin = self.sysprep_params['admin'].value v_val = self.registry.reset_passwd(admin) self.registry.enable_autologon(admin) - - self._install_viostor_driver(dirname) self._upload_virtio_drivers(dirname) + drvs_install = DRVINST.replace('\n', '\r\n') + + if self.check_version(6, 1) <= 0: + self._install_viostor_driver(dirname) + else: + # In newer windows, in order to reduce the boot process the + # boot drivers are cached. To be able to boot with viostor, we + # need to reboot in safe mode. + drvs_install += SAFEBOOT.replace('\n', '\r\n') + + drvs_install += "\r\nshutdown /s /t 0\r\n" + remotedir = self.image.g.case_sensitive_path("%s/VirtIO" % self.systemroot) - self.image.g.write(remotedir + "/InstallDrivers.ps1", - DRVINST.replace('\n', '\r\n')) + self.image.g.write(remotedir + "/InstallDrivers.ps1", drvs_install) cmd = ( '%(drive)s:%(root)s\\System32\\WindowsPowerShell\\v1.0\\' @@ -628,18 +637,32 @@ class Windows(OSBase): {'root': self.systemroot.replace('/', '\\'), 'drive': self.systemdrive}) - self.registry.runonce({'InstallDrivers': cmd}) + # The value name of RunOnce keys can be prefixed with an asterisk + # (*) to force the program to run even in Safe mode. + self.registry.runonce({'*InstallDrivers': cmd}) try: - self.vm.start() + 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) finally: self.vm.stop(6000) - with self.mount(readonly=True, silent=True): - self.virtio_state = self._virtio_state() + if self.check_version(6, 1) > 0: + # Hopefully restart in safe mode. + try: + self.vm.start() + finally: + self.vm.stop(6000) + with self.mount(readonly=True, silent=True): + self.virtio_state = self._virtio_state() def _install_viostor_driver(self, dirname): """Quick and dirty installation of the VirtIO SCSI controller driver. @@ -665,7 +688,6 @@ class Windows(OSBase): self.registry.add_viostor() - def _upload_virtio_drivers(self, dirname): """Install the virtio drivers to the media""" diff --git a/image_creator/os_type/windows/powershell.py b/image_creator/os_type/windows/powershell.py index 4454cbd..958b6f2 100644 --- a/image_creator/os_type/windows/powershell.py +++ b/image_creator/os_type/windows/powershell.py @@ -18,6 +18,7 @@ """This module hosts Windows PowerShell scripts that need to be injected into the windows image""" +# Installs drivers found in a directory DRVINST = r""" #requires -version 2 @@ -41,7 +42,15 @@ if (Test-Path "$dirName/viostor.inf") { pnputil.exe -a "$dirname\*.inf" -shutdown /s /t 5 """ +# Reboots system in safe mode +SAFEBOOT = r""" +bcdedit /set safeboot minimal +New-ItemProperty ` + -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce ` + -Name *snf-image-creator-restart -PropertyType String ` + -Value 'cmd /q /c "bcdedit /deletevalue safeboot & shutdown /s /t 0"' + +""" # vim: set sta sts=4 shiftwidth=4 sw=4 et ai : diff --git a/image_creator/os_type/windows/vm.py b/image_creator/os_type/windows/vm.py index aebd016..7e3fd44 100644 --- a/image_creator/os_type/windows/vm.py +++ b/image_creator/os_type/windows/vm.py @@ -36,6 +36,7 @@ class VM(object): self.disk = disk self.params = params + self.interface = 'virtio' kvm, needed_args = get_kvm_binary() if kvm is None: @@ -93,7 +94,7 @@ class VM(object): """Check if the VM is alive""" return self.process is not None and self.process.poll() is None - def start(self): + def start(self, **kwargs): """Start the windows VM""" args = [] @@ -105,12 +106,19 @@ class VM(object): if 'mem' in self.params: args.extend(['-m', str(self.params['mem'].value)]) - args.extend([ - '-drive', 'file=%s,format=raw,cache=unsafe,if=virtio' % self.disk]) + args.extend(['-drive', + 'file=%s,format=raw,cache=unsafe,if=%s' % + (self.disk, self.interface)]) args.extend( ['-netdev', 'type=user,hostfwd=tcp::445-:445,id=netdev0', - '-device', 'virtio-net-pci,mac=%s,netdev=netdev0' % self.mac]) + '-device', 'rtl8139,mac=%s,netdev=netdev0' % self.mac]) + + if 'extra_disk' in kwargs: + fname, iftype = kwargs['extra_disk'] + args.extend(['-drive', + 'file=%s,format=raw,cache=unsafe,if=%s' % + (fname, iftype)]) args.extend(['-vnc', ":%d" % self.display]) -- GitLab