diff --git a/image_creator/os_type/windows/__init__.py b/image_creator/os_type/windows/__init__.py index 9ce8688655e4ac3b4e269b5e8c479937d35108ad..457ef0bca88f9cbb6e566efd2ccde3fd5dadd16e 100644 --- a/image_creator/os_type/windows/__init__.py +++ b/image_creator/os_type/windows/__init__.py @@ -30,6 +30,7 @@ import tempfile import re import os import uuid +import time # For more info see: http://technet.microsoft.com/en-us/library/jj612867.aspx KMS_CLIENT_SETUP_KEYS = { @@ -339,7 +340,7 @@ class Windows(OSBase): """ self.vm.rexec(r'C:\Windows\system32\sysprep\sysprep ' - r'/quiet /generalize /oobe /shutdown') + r'/quiet /generalize /oobe /shutdown', uninstall=True) self.sysprepped = True @sysprep('Converting the image into a KMS client', enabled=False) @@ -422,7 +423,7 @@ class Windows(OSBase): r'IF NOT !ERRORLEVEL! EQU 0 EXIT /B 1 & ' + r'DEL /Q %SCRIPT%"') - stdout, stderr, rc = self.vm.rexec(cmd, False) + stdout, stderr, rc = self.vm.rexec(cmd, fatal=False) if rc != 0: FatalError("Shrinking failed. Please make sure the media is " @@ -430,7 +431,7 @@ class Windows(OSBase): "`Defrag.exe /U /X /W'") for line in stdout.splitlines(): if line.find('shrunk') >= 0: - self.out.output(line) + self.out.output(" %s" % line) def do_sysprep(self): """Prepare system for image creation.""" @@ -496,6 +497,11 @@ class Windows(OSBase): self.out.success('done') booted = True + # Since the password is reset when logging in, sleep a little + # bit before checking the connectivity, to avoid race + # conditions + time.sleep(2) + self.out.output("Checking connectivity to the VM ...", False) self._check_connectivity() # self.out.success('done') @@ -565,7 +571,7 @@ class Windows(OSBase): def _shutdown(self): """Shuts down the windows VM""" - self.vm.rexec(r'shutdown /s /t 5') + self.vm.rexec(r'shutdown /s /t 5', uninstall=True) def _disable_autologon(self): """Disable automatic logon on the windows image""" diff --git a/image_creator/os_type/windows/vm.py b/image_creator/os_type/windows/vm.py index 386974e58b1c08156f13dfbadbbb8f978aa70adc..2ce262b89a512cad73d97d3b4b26f44fc3bf4aa6 100644 --- a/image_creator/os_type/windows/vm.py +++ b/image_creator/os_type/windows/vm.py @@ -205,26 +205,51 @@ class VM(object): return (stdout, stderr, self.process.poll()) - def rexec(self, command, fatal=True, debug=False): - """Remote execute a command on the windows VM""" + def rexec(self, command, **kwargs): + """Remote execute a command on the windows VM + + The following optional flags are allowed: + + * fatal: If True, a FatalError is thrown if the command fails + + * debug: If True, WinEXE is executed in the highest debug level + + * uninstall: If True, the winexesvc.exe service will be uninstalled + after the execution of the command. + """ + + fatal = kwargs['fatal'] if 'fatal' in kwargs else True + debug = kwargs['debug'] if 'debug' in kwargs else False + uninstall = kwargs['uninstall'] if 'uninstall' in kwargs else False user = self.params['admin'].value winexe = WinEXE(user, 'localhost', password=self.password) - winexe.runas(user, self.password).uninstall().no_pass() + winexe.runas(user, self.password).no_pass() + if debug: winexe.debug(9) + if uninstall: + winexe.uninstall() + try: (stdout, stderr, rc) = winexe.run(command) except WinexeTimeout: FatalError("Command: `%s' timeout out." % command) if rc != 0 and fatal: - reason = stderr if len(stderr) else stdout + log = tempfile.NamedTemporaryFile(delete=False) + try: + log.file.write("STDOUT:\n%s\n" % stdout) + log.file.write("STDERR:\n%s\n" % stderr) + finally: + fname = log.name + log.close() + # self.out.output("Command: `%s' failed (rc=%d). Reason: %s" % # (command, rc, reason)) - raise FatalError("Command: `%s' failed (rc=%d). Reason: %s" % - (command, rc, reason)) + raise FatalError("Command: `%s' failed (rc=%d). See: %s" % + (command, rc, fname)) return (stdout, stderr, rc)