コード例 #1
0
ファイル: vm.py プロジェクト: pancyber/snf-image-creator
    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

        winexe = WinEXE(self.admin.name, 'localhost', password=self.password)
        winexe.no_pass()

        if debug:
            winexe.debug(9)

        if uninstall:
            winexe.uninstall()

        try:
            (stdout, stderr, rc) = winexe.run(command)
        except WinexeTimeout:
            raise FatalError("Command: `%s' timeout out." % command)

        if rc != 0 and fatal:
            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()

            raise FatalError("Command: `%s' failed (rc=%d). See: %s" %
                             (command, rc, fname))

        return (stdout, stderr, rc)
コード例 #2
0
    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

        winexe = WinEXE(self.admin.name, 'localhost', password=self.password)
        winexe.no_pass()

        if debug:
            winexe.debug(9)

        if uninstall:
            winexe.uninstall()

        try:
            (stdout, stderr, rc) = winexe.run(command)
        except WinexeTimeout:
            raise FatalError("Command: `%s' timeout out." % command)

        if rc != 0 and fatal:
            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()

            raise FatalError("Command: `%s' failed (rc=%d). See: %s" %
                             (command, rc, fname))

        return (stdout, stderr, rc)
コード例 #3
0
ファイル: __init__.py プロジェクト: grnet/snf-image-creator
    def do_sysprep(self):
        """Prepare system for image creation."""

        self.out.info('Preparing system for image creation:')

        # Check if winexe is installed
        if not WinEXE.is_installed():
            raise FatalError(
                "Winexe not found! In order to be able to customize a Windows "
                "image you need to have Winexe installed.")

        if self.sysprepped:
            raise FatalError(
                "Microsoft's System Preparation Tool has ran on the media. "
                "Further image customization is not possible.")

        if len(self.virtio_state['viostor']) == 0:
            raise FatalError(
                "The media has no VirtIO SCSI controller driver installed. "
                "Further image customization is not possible.")

        if len(self.virtio_state['netkvm']) == 0:
            raise FatalError(
                "The media has no VirtIO Ethernet Adapter driver installed. "
                "Further image customization is not possible.")

        timeout = self.sysprep_params['boot_timeout'].value
        shutdown_timeout = self.sysprep_params['shutdown_timeout'].value

        self.out.info("Preparing media for boot ...", False)

        with self.mount(readonly=False, silent=True):

            if not self.registry.reset_account(self.vm.admin.rid):
                self._add_cleanup('sysprep', self.registry.reset_account,
                                  self.vm.admin.rid, False)

            old = self.registry.update_uac(0)
            if old != 0:
                self._add_cleanup('sysprep', self.registry.update_uac, old)

            old = self.registry.update_uac_remote_setting(1)
            if old != 1:
                self._add_cleanup('sysprep',
                                  self.registry.update_uac_remote_setting, old)

            def if_not_sysprepped(task, *args):
                """Only perform this if the image is not sysprepped"""
                if not self.sysprepped:
                    task(*args)

            # The next 2 registry values get completely removed by Microsoft
            # Sysprep. They should not be reverted if Sysprep gets executed.
            old = self.registry.update_noautoupdate(1)
            if old != 1:
                self._add_cleanup('sysprep', if_not_sysprepped,
                                  self.registry.update_noautoupdate, old)

            old = self.registry.update_auoptions(1)
            if old != 1:
                self._add_cleanup('sysprep', if_not_sysprepped,
                                  self.registry.update_auoptions, old)

            # disable the firewalls
            self._add_cleanup('sysprep', self.registry.update_firewalls,
                              *self.registry.update_firewalls(0, 0, 0))

            v_val = self.registry.reset_passwd(self.vm.admin.rid)

            self._add_boot_scripts()

            # Delete the pagefile. It will be recreated when the system boots
            try:
                pagefile = "%s/pagefile.sys" % self.systemroot
                self.image.g.rm_rf(self.image.g.case_sensitive_path(pagefile))
            except RuntimeError:
                pass

        self.out.success('done')

        self.image.disable_guestfs()
        booted = False
        try:
            self.out.info("Starting windows VM ...", False)
            self.vm.start()
            try:
                self.out.success("started (console on VNC display: %d)" %
                                 self.vm.display)

                self.out.info("Waiting for OS to boot ...", False)
                if not self.vm.wait_on_serial(timeout):
                    raise FatalError("Windows VM booting timed out!")
                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(5)

                self.out.info("Checking connectivity to the VM ...", False)
                self._check_connectivity()
                # self.out.success('done')

                # self.out.info("Disabling automatic logon ...", False)
                self._disable_autologon()
                self.out.success('done')

                self._exec_sysprep_tasks()

                self.out.info("Waiting for windows to shut 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:
                # if the VM is not already dead here, a Fatal Error will have
                # already been raised. There is no reason to make the command
                # fatal.
                self.vm.stop(shutdown_timeout if booted else 1, fatal=False)
        finally:
            self.image.enable_guestfs()

            self.out.info("Reverting media boot preparations ...", False)
            with self.mount(readonly=False, silent=True, fatal=False):

                if not self.ismounted:
                    self.out.warn("The boot changes cannot be reverted. "
                                  "The snapshot may be in a corrupted state.")
                else:
                    if not self.sysprepped:
                        # Reset the old password
                        self.registry.reset_passwd(self.vm.admin.rid, v_val)

                    self._cleanup('sysprep')
                    self.out.success("done")

        self.image.shrink(silent=True)
コード例 #4
0
    def do_sysprep(self):
        """Prepare system for image creation."""

        self.out.info('Preparing system for image creation:')

        # Check if winexe is installed
        if not WinEXE.is_installed():
            raise FatalError(
                "Winexe not found! In order to be able to customize a Windows "
                "image you need to have Winexe installed.")

        if self.sysprepped:
            raise FatalError(
                "Microsoft's System Preparation Tool has ran on the media. "
                "Further image customization is not possible.")

        if len(self.virtio_state['viostor']) == 0:
            raise FatalError(
                "The media has no VirtIO SCSI controller driver installed. "
                "Further image customization is not possible.")

        if len(self.virtio_state['netkvm']) == 0:
            raise FatalError(
                "The media has no VirtIO Ethernet Adapter driver installed. "
                "Further image customization is not possible.")

        timeout = self.sysprep_params['boot_timeout'].value
        shutdown_timeout = self.sysprep_params['shutdown_timeout'].value

        self.out.info("Preparing media for boot ...", False)

        with self.mount(readonly=False, silent=True):

            if not self.registry.reset_account(self.vm.admin.rid):
                self._add_cleanup('sysprep', self.registry.reset_account,
                                  self.vm.admin.rid, False)

            old = self.registry.update_uac(0)
            if old != 0:
                self._add_cleanup('sysprep', self.registry.update_uac, old)

            old = self.registry.update_uac_remote_setting(1)
            if old != 1:
                self._add_cleanup('sysprep',
                                  self.registry.update_uac_remote_setting, old)

            def if_not_sysprepped(task, *args):
                """Only perform this if the image is not sysprepped"""
                if not self.sysprepped:
                    task(*args)

            # The next 2 registry values get completely removed by Microsoft
            # Sysprep. They should not be reverted if Sysprep gets executed.
            old = self.registry.update_noautoupdate(1)
            if old != 1:
                self._add_cleanup('sysprep', if_not_sysprepped,
                                  self.registry.update_noautoupdate, old)

            old = self.registry.update_auoptions(1)
            if old != 1:
                self._add_cleanup('sysprep', if_not_sysprepped,
                                  self.registry.update_auoptions, old)

            # disable the firewalls
            self._add_cleanup('sysprep', self.registry.update_firewalls,
                              *self.registry.update_firewalls(0, 0, 0))

            v_val = self.registry.reset_passwd(self.vm.admin.rid)

            self._add_boot_scripts()

            # Delete the pagefile. It will be recreated when the system boots
            try:
                pagefile = "%s/pagefile.sys" % self.systemroot
                self.image.g.rm_rf(self.image.g.case_sensitive_path(pagefile))
            except RuntimeError:
                pass

        self.out.success('done')

        self.image.disable_guestfs()
        booted = False
        try:
            self.out.info("Starting windows VM ...", False)
            self.vm.start()
            try:
                self.out.success("started (console on VNC display: %d)" %
                                 self.vm.display)

                self.out.info("Waiting for OS to boot ...", False)
                if not self.vm.wait_on_serial(timeout):
                    raise FatalError("Windows VM booting timed out!")
                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(5)

                self.out.info("Checking connectivity to the VM ...", False)
                self._check_connectivity()
                # self.out.success('done')

                # self.out.info("Disabling automatic logon ...", False)
                self._disable_autologon()
                self.out.success('done')

                self._exec_sysprep_tasks()

                self.out.info("Waiting for windows to shut 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:
                # if the VM is not already dead here, a Fatal Error will have
                # already been raised. There is no reason to make the command
                # fatal.
                self.vm.stop(shutdown_timeout if booted else 1, fatal=False)
        finally:
            self.image.enable_guestfs()

            self.out.info("Reverting media boot preparations ...", False)
            with self.mount(readonly=False, silent=True, fatal=False):

                if not self.ismounted:
                    self.out.warn("The boot changes cannot be reverted. "
                                  "The snapshot may be in a corrupted state.")
                else:
                    if not self.sysprepped:
                        # Reset the old password
                        self.registry.reset_passwd(self.vm.admin.rid, v_val)

                    self._cleanup('sysprep')
                    self.out.success("done")

        self.image.shrink(silent=True)