Example #1
0
    def doReboot(self):
        """
        Worker common to _cmdReboot and _doUpgrade that performs a system reboot.
        """
        # !! Not more exceptions beyond this point !!
        testboxcommons.log('Rebooting');

        # Stop anything that might be executing at this point.
        oCurTask = self._getCurTask();
        if oCurTask is not None:
            oCurTask.terminate();
            oCurTask.wait(self.kcSecStopBeforeRebootTimeout);

        # Invoke shutdown command line utility.
        sOs = utils.getHostOs();
        asCmd2 = None;
        if sOs == 'win':
            asCmd = ['shutdown', '/r', '/t', '0'];
        elif sOs == 'os2':
            asCmd = ['setboot', '/B'];
        elif sOs in ('solaris',):
            asCmd = ['/usr/sbin/reboot', '-p'];
            asCmd2 = ['/usr/sbin/reboot']; # Hack! S10 doesn't have -p, but don't know how to reliably detect S10.
        else:
            asCmd = ['/sbin/shutdown', '-r', 'now'];
        try:
            utils.sudoProcessOutputChecked(asCmd);
        except Exception, oXcpt:
            if asCmd2 is not None:
                try:
                    utils.sudoProcessOutputChecked(asCmd2);
                except Exception, oXcpt:
                    testboxcommons.log('Error executing reboot command "%s" as well as "%s": %s' % (asCmd, asCmd2, oXcpt));
                    return False;
Example #2
0
    def doReboot(self):
        """
        Worker common to _cmdReboot and _doUpgrade that performs a system reboot.
        """
        # !! Not more exceptions beyond this point !!
        testboxcommons.log('Rebooting');

        # Stop anything that might be executing at this point.
        oCurTask = self._getCurTask();
        if oCurTask is not None:
            oCurTask.terminate();
            oCurTask.wait(self.kcSecStopBeforeRebootTimeout);

        # Invoke shutdown command line utility.
        sOs = utils.getHostOs();
        asCmd2 = None;
        if sOs == 'win':
            asCmd = ['shutdown', '/r', '/t', '0', '/c', '"ValidationKit triggered reboot"', '/d', '4:1'];
        elif sOs == 'os2':
            asCmd = ['setboot', '/B'];
        elif sOs in ('solaris',):
            asCmd = ['/usr/sbin/reboot', '-p'];
            asCmd2 = ['/usr/sbin/reboot']; # Hack! S10 doesn't have -p, but don't know how to reliably detect S10.
        else:
            asCmd = ['/sbin/shutdown', '-r', 'now'];
        try:
            utils.sudoProcessOutputChecked(asCmd);
        except Exception, oXcpt:
            if asCmd2 is not None:
                try:
                    utils.sudoProcessOutputChecked(asCmd2);
                except Exception, oXcpt:
                    testboxcommons.log('Error executing reboot command "%s" as well as "%s": %s' % (asCmd, asCmd2, oXcpt));
                    return False;
    def _getHostSystemUuid(self):
        """
        Get the system UUID string from the System, return null-uuid if
        unable to get retrieve it.
        """
        if self._oOptions.sSystemUuid is not None:
            return self._oOptions.sSystemUuid;

        sUuid = self.ksNullUuid;

        #
        # Try get at the firmware UUID.
        #
        if utils.getHostOs() == 'linux':
            # NOTE: This requires to have kernel option enabled:
            #       Firmware Drivers -> Export DMI identification via sysfs to userspace
            if os.path.exists('/sys/devices/virtual/dmi/id/product_uuid'):
                try:
                    sVar = utils.sudoProcessOutputChecked(['cat', '/sys/devices/virtual/dmi/id/product_uuid']);
                    sUuid = str(uuid.UUID(sVar.strip()));
                except:
                    pass;
            ## @todo consider dmidecoder? What about EFI systems?

        elif utils.getHostOs() == 'win':
            # Windows: WMI
            try:
                import win32com.client;  # pylint: disable=F0401
                oWmi  = win32com.client.Dispatch('WbemScripting.SWbemLocator');
                oWebm = oWmi.ConnectServer('.', 'root\\cimv2');
                for oItem in oWebm.ExecQuery('SELECT * FROM Win32_ComputerSystemProduct'):
                    if oItem.UUID != None:
                        sUuid = str(uuid.UUID(oItem.UUID));
            except:
                pass;

        elif utils.getHostOs() == 'darwin':
            try:
                sVar = utils.processOutputChecked(['/bin/sh', '-c',
                                                   '/usr/sbin/ioreg -k IOPlatformUUID' \
                                                   + '| /usr/bin/grep IOPlatformUUID' \
                                                   + '| /usr/bin/head -1']);
                sVar = sVar.strip()[-(len(self.ksNullUuid) + 1):-1];
                sUuid = str(uuid.UUID(sVar));
            except:
                pass;

        elif utils.getHostOs() == 'solaris':
            # Solaris: The smbios util.
            try:
                sVar = utils.processOutputChecked(['/bin/sh', '-c',
                                                   '/usr/sbin/smbios ' \
                                                   + '| /usr/xpg4/bin/sed -ne \'s/^.*UUID: *//p\'' \
                                                   + '| /usr/bin/head -1']);
                sUuid = str(uuid.UUID(sVar.strip()));
            except:
                pass;

        if self._isUuidGood(sUuid):
            return sUuid;

        #
        # Try add the MAC address.
        # uuid.getnode may provide it, or it may return a random number...
        #
        lMacAddr = uuid.getnode();
        sNode = '%012x' % (lMacAddr,)
        if lMacAddr == uuid.getnode() and lMacAddr != 0 and len(sNode) == 12:
            return sUuid[:-12] + sNode;

        return sUuid;
    def _mountShare(self, sMountPoint, sType, sServer, sShare, sUser, sPassword, sWhat):
        """
        Mounts the specified share if needed.
        Raises exception on failure.
        """
        # Only mount if the type is specified.
        if sType is None:
            return True;

        # Test if already mounted.
        sTestFile = os.path.join(sMountPoint + os.path.sep, sShare + '.txt');
        if os.path.isfile(sTestFile):
            return True;

        #
        # Platform specific mount code.
        #
        sHostOs = utils.getHostOs()
        if sHostOs in ('darwin', 'freebsd'):
            utils.sudoProcessCall(['/sbin/umount', sMountPoint]);
            utils.sudoProcessCall(['/bin/mkdir', '-p', sMountPoint]);
            utils.sudoProcessCall(['/usr/sbin/chown', str(os.getuid()), sMountPoint]); # pylint: disable=E1101
            if sType == 'cifs':
                # Note! no smb://server/share stuff here, 10.6.8 didn't like it.
                utils.processOutputChecked(['/sbin/mount_smbfs', '-o', 'automounted,nostreams,soft,noowners,noatime,rdonly',
                                            '-f', '0555', '-d', '0555',
                                            '//%s:%s@%s/%s' % (sUser, sPassword, sServer, sShare),
                                            sMountPoint]);
            else:
                raise TestBoxScriptException('Unsupported server type %s.' % (sType,));

        elif sHostOs == 'linux':
            utils.sudoProcessCall(['/bin/umount', sMountPoint]);
            utils.sudoProcessCall(['/bin/mkdir', '-p', sMountPoint]);
            if sType == 'cifs':
                utils.sudoProcessOutputChecked(['/bin/mount', '-t', 'cifs',
                                                '-o',
                                                  'user='******',password='******',sec=ntlmv2'
                                                + ',uid=' + str(os.getuid()) # pylint: disable=E1101
                                                + ',gid=' + str(os.getgid()) # pylint: disable=E1101
                                                + ',nounix,file_mode=0555,dir_mode=0555,soft,ro',
                                                '//%s/%s' % (sServer, sShare),
                                                sMountPoint]);
            elif sType == 'nfs':
                utils.sudoProcessOutputChecked(['/bin/mount', '-t', 'nfs',
                                                '-o', 'soft,ro',
                                                '%s:%s' % (sServer, sShare if sShare.find('/') >= 0 else ('/export/' + sShare)),
                                                sMountPoint]);

            else:
                raise TestBoxScriptException('Unsupported server type %s.' % (sType,));

        elif sHostOs == 'solaris':
            utils.sudoProcessCall(['/sbin/umount', sMountPoint]);
            utils.sudoProcessCall(['/bin/mkdir', '-p', sMountPoint]);
            if sType == 'cifs':
                ## @todo This stuff doesn't work on wei01-x4600b.de.oracle.com running 11.1. FIXME!
                oPasswdFile = tempfile.TemporaryFile();
                oPasswdFile.write(sPassword + '\n');
                oPasswdFile.flush();
                utils.sudoProcessOutputChecked(['/sbin/mount', '-F', 'smbfs',
                                                '-o',
                                                  'user='******',uid=' + str(os.getuid()) # pylint: disable=E1101
                                                + ',gid=' + str(os.getgid()) # pylint: disable=E1101
                                                + ',fileperms=0555,dirperms=0555,noxattr,ro',
                                                '//%s/%s' % (sServer, sShare),
                                                sMountPoint],
                                               stdin = oPasswdFile);
                oPasswdFile.close();
            elif sType == 'nfs':
                utils.sudoProcessOutputChecked(['/sbin/mount', '-F', 'nfs',
                                                '-o', 'noxattr,ro',
                                                '%s:%s' % (sServer, sShare if sShare.find('/') >= 0 else ('/export/' + sShare)),
                                                sMountPoint]);

            else:
                raise TestBoxScriptException('Unsupported server type %s.' % (sType,));


        elif sHostOs == 'win':
            if sType != 'cifs':
                raise TestBoxScriptException('Only CIFS mounts are supported on Windows.');
            utils.processCall(['net', 'use', sMountPoint, '/d']);
            utils.processOutputChecked(['net', 'use', sMountPoint,
                                        '\\\\' + sServer + '\\' + sShare,
                                        sPassword,
                                        '/USER:'******'Unsupported host %s' % (sHostOs,));

        #
        # Re-test.
        #
        if not os.path.isfile(sTestFile):
            raise TestBoxException('Failed to mount %s (%s[%s]) at %s: %s not found'
                                   % (sWhat, sServer, sShare, sMountPoint, sTestFile));

        return True;
    def _getHostSystemUuid(self):
        """
        Get the system UUID string from the System, return null-uuid if
        unable to get retrieve it.
        """
        if self._oOptions.sSystemUuid is not None:
            return self._oOptions.sSystemUuid;

        sUuid = self.ksNullUuid;

        #
        # Try get at the firmware UUID.
        #
        if utils.getHostOs() == 'linux':
            # NOTE: This requires to have kernel option enabled:
            #       Firmware Drivers -> Export DMI identification via sysfs to userspace
            if os.path.exists('/sys/devices/virtual/dmi/id/product_uuid'):
                try:
                    sVar = utils.sudoProcessOutputChecked(['cat', '/sys/devices/virtual/dmi/id/product_uuid']);
                    sUuid = str(uuid.UUID(sVar.strip()));
                except:
                    pass;
            ## @todo consider dmidecoder? What about EFI systems?

        elif utils.getHostOs() == 'win':
            # Windows: WMI
            try:
                import win32com.client;  # pylint: disable=F0401
                oWmi  = win32com.client.Dispatch('WbemScripting.SWbemLocator');
                oWebm = oWmi.ConnectServer('.', 'root\\cimv2');
                for oItem in oWebm.ExecQuery('SELECT * FROM Win32_ComputerSystemProduct'):
                    if oItem.UUID != None:
                        sUuid = str(uuid.UUID(oItem.UUID));
            except:
                pass;

        elif utils.getHostOs() == 'darwin':
            try:
                sVar = utils.processOutputChecked(['/bin/sh', '-c',
                                                   '/usr/sbin/ioreg -k IOPlatformUUID' \
                                                   + '| /usr/bin/grep IOPlatformUUID' \
                                                   + '| /usr/bin/head -1']);
                sVar = sVar.strip()[-(len(self.ksNullUuid) + 1):-1];
                sUuid = str(uuid.UUID(sVar));
            except:
                pass;

        elif utils.getHostOs() == 'solaris':
            # Solaris: The smbios util.
            try:
                sVar = utils.processOutputChecked(['/bin/sh', '-c',
                                                   '/usr/sbin/smbios ' \
                                                   + '| /usr/xpg4/bin/sed -ne \'s/^.*UUID: *//p\'' \
                                                   + '| /usr/bin/head -1']);
                sUuid = str(uuid.UUID(sVar.strip()));
            except:
                pass;

        if self._isUuidGood(sUuid):
            return sUuid;

        #
        # Try add the MAC address.
        # uuid.getnode may provide it, or it may return a random number...
        #
        lMacAddr = uuid.getnode();
        sNode = '%012x' % (lMacAddr,)
        if lMacAddr == uuid.getnode() and lMacAddr != 0 and len(sNode) == 12:
            return sUuid[:-12] + sNode;

        return sUuid;
    def _mountShare(self, sMountPoint, sType, sServer, sShare, sUser, sPassword, sWhat):
        """
        Mounts the specified share if needed.
        Raises exception on failure.
        """
        # Only mount if the type is specified.
        if sType is None:
            return True;

        # Test if already mounted.
        sTestFile = os.path.join(sMountPoint + os.path.sep, sShare + '-new.txt');
        if os.path.isfile(sTestFile):
            return True;

        #
        # Platform specific mount code.
        #
        sHostOs = utils.getHostOs()
        if sHostOs in ('darwin', 'freebsd'):
            utils.sudoProcessCall(['/sbin/umount', sMountPoint]);
            utils.sudoProcessCall(['/bin/mkdir', '-p', sMountPoint]);
            utils.sudoProcessCall(['/usr/sbin/chown', str(os.getuid()), sMountPoint]); # pylint: disable=E1101
            if sType == 'cifs':
                # Note! no smb://server/share stuff here, 10.6.8 didn't like it.
                utils.processOutputChecked(['/sbin/mount_smbfs', '-o', 'automounted,nostreams,soft,noowners,noatime,rdonly',
                                            '-f', '0555', '-d', '0555',
                                            '//%s:%s@%s/%s' % (sUser, sPassword, sServer, sShare),
                                            sMountPoint]);
            else:
                raise TestBoxScriptException('Unsupported server type %s.' % (sType,));

        elif sHostOs == 'linux':
            utils.sudoProcessCall(['/bin/umount', sMountPoint]);
            utils.sudoProcessCall(['/bin/mkdir', '-p', sMountPoint]);
            if sType == 'cifs':
                utils.sudoProcessOutputChecked(['/bin/mount', '-t', 'cifs',
                                                '-o',
                                                'user='******',password='******',sec=ntlmv2'
                                                + ',uid=' + str(os.getuid()) # pylint: disable=E1101
                                                + ',gid=' + str(os.getgid()) # pylint: disable=E1101
                                                + ',nounix,file_mode=0555,dir_mode=0555,soft,ro',
                                                '//%s/%s' % (sServer, sShare),
                                                sMountPoint]);
            elif sType == 'nfs':
                utils.sudoProcessOutputChecked(['/bin/mount', '-t', 'nfs',
                                                '-o', 'soft,ro',
                                                '%s:%s' % (sServer, sShare if sShare.find('/') >= 0 else ('/export/' + sShare)),
                                                sMountPoint]);

            else:
                raise TestBoxScriptException('Unsupported server type %s.' % (sType,));

        elif sHostOs == 'solaris':
            utils.sudoProcessCall(['/sbin/umount', sMountPoint]);
            utils.sudoProcessCall(['/bin/mkdir', '-p', sMountPoint]);
            if sType == 'cifs':
                ## @todo This stuff doesn't work on wei01-x4600b.de.oracle.com running 11.1. FIXME!
                oPasswdFile = tempfile.TemporaryFile();
                oPasswdFile.write(sPassword + '\n');
                oPasswdFile.flush();
                utils.sudoProcessOutputChecked(['/sbin/mount', '-F', 'smbfs',
                                                '-o',
                                                'user='******',uid=' + str(os.getuid()) # pylint: disable=E1101
                                                + ',gid=' + str(os.getgid()) # pylint: disable=E1101
                                                + ',fileperms=0555,dirperms=0555,noxattr,ro',
                                                '//%s/%s' % (sServer, sShare),
                                                sMountPoint],
                                               stdin = oPasswdFile);
                oPasswdFile.close();
            elif sType == 'nfs':
                utils.sudoProcessOutputChecked(['/sbin/mount', '-F', 'nfs',
                                                '-o', 'noxattr,ro',
                                                '%s:%s' % (sServer, sShare if sShare.find('/') >= 0 else ('/export/' + sShare)),
                                                sMountPoint]);

            else:
                raise TestBoxScriptException('Unsupported server type %s.' % (sType,));


        elif sHostOs == 'win':
            if sType != 'cifs':
                raise TestBoxScriptException('Only CIFS mounts are supported on Windows.');
            utils.processCall(['net', 'use', sMountPoint, '/d']);
            utils.processOutputChecked(['net', 'use', sMountPoint,
                                        '\\\\' + sServer + '\\' + sShare,
                                        sPassword,
                                        '/USER:'******'Unsupported host %s' % (sHostOs,));

        #
        # Re-test.
        #
        if not os.path.isfile(sTestFile):
            raise TestBoxException('Failed to mount %s (%s[%s]) at %s: %s not found'
                                   % (sWhat, sServer, sShare, sMountPoint, sTestFile));

        return True;
Example #7
0
    def _uninstallVBoxOnWindows(self, sMode):
        """
        Uninstalls VBox on Windows, all installations we find to be on the safe side...
        """
        assert sMode in [
            'install',
            'uninstall',
        ]

        import win32com.client
        # pylint: disable=import-error
        win32com.client.gencache.EnsureModule(
            '{000C1092-0000-0000-C000-000000000046}', 1033, 1, 0)
        oInstaller = win32com.client.Dispatch(
            'WindowsInstaller.Installer',
            resultCLSID='{000C1090-0000-0000-C000-000000000046}')

        # Search installed products for VirtualBox.
        asProdCodes = []
        for sProdCode in oInstaller.Products:
            try:
                sProdName = oInstaller.ProductInfo(sProdCode, "ProductName")
            except:
                reporter.logXcpt()
                continue
            #reporter.log('Info: %s=%s' % (sProdCode, sProdName));
            if  sProdName.startswith('Oracle VM VirtualBox') \
             or sProdName.startswith('Sun VirtualBox'):
                asProdCodes.append([sProdCode, sProdName])

        # Before we start uninstalling anything, just ruthlessly kill any cdb,
        # msiexec, drvinst and some rundll process we might find hanging around.
        if self._isProcessPresent('rundll32'):
            cTimes = 0
            while cTimes < 3:
                cTimes += 1
                cKilled = self._terminateProcessesByNameAndArgSubstr(
                    'rundll32', 'InstallSecurityPromptRunDllW',
                    'MSI driver installation')
                if cKilled <= 0:
                    break
                time.sleep(10)
                # Give related drvinst process a chance to clean up after we killed the verification dialog.

        if self._isProcessPresent('drvinst'):
            time.sleep(15)
            # In the hope that it goes away.
            cTimes = 0
            while cTimes < 4:
                cTimes += 1
                cKilled = self._killProcessesByName('drvinst',
                                                    'MSI driver installation',
                                                    True)
                if cKilled <= 0:
                    break
                time.sleep(10)
                # Give related MSI process a chance to clean up after we killed the driver installer.

        if self._isProcessPresent('msiexec'):
            cTimes = 0
            while cTimes < 3:
                reporter.log('found running msiexec process, waiting a bit...')
                time.sleep(20)  # In the hope that it goes away.
                if not self._isProcessPresent('msiexec'):
                    break
                cTimes += 1
            ## @todo this could also be the msiexec system service, try to detect this case!
            if cTimes >= 6:
                cKilled = self._killProcessesByName('msiexec',
                                                    'MSI driver installation')
                if cKilled > 0:
                    time.sleep(16)
                    # fudge.

        # cdb.exe sometimes stays running (from utils.getProcessInfo), blocking
        # the scratch directory. No idea why.
        if self._isProcessPresent('cdb'):
            cTimes = 0
            while cTimes < 3:
                cKilled = self._killProcessesByName(
                    'cdb', 'cdb.exe from getProcessInfo')
                if cKilled <= 0:
                    break
                time.sleep(2)
                # fudge.

        # Do the uninstalling.
        fRc = True
        sLogFile = os.path.join(self.sScratchPath, 'VBoxUninstallLog.txt')
        for sProdCode, sProdName in asProdCodes:
            reporter.log('Uninstalling %s (%s)...' % (sProdName, sProdCode))
            fRc2, iRc = self._sudoExecuteSync([
                'msiexec',
                '/uninstall',
                sProdCode,
                '/quiet',
                '/passive',
                '/norestart',
                '/L*v',
                '%s' % (sLogFile),
            ])
            if fRc2 is False:
                if iRc == 3010:  # ERROR_SUCCESS_REBOOT_REQUIRED
                    reporter.error(
                        'Uninstaller required a reboot to complete uninstallation'
                    )
                else:
                    reporter.error('Uninstaller failed, exit code: %s' %
                                   (iRc, ))
                fRc = False

        self._waitForTestManagerConnectivity(30)

        # Upload the log on failure.  Do it early if the extra cleanups below causes trouble.
        if fRc is False and os.path.isfile(sLogFile):
            reporter.addLogFile(sLogFile, 'log/uninstaller',
                                "Verbose MSI uninstallation log file")
            sLogFile = None

        # Log driver service states (should ls \Driver\VBox* and \Device\VBox*).
        fHadLeftovers = False
        asLeftovers = []
        for sService in reversed(self.kasWindowsServices):
            cTries = 0
            while True:
                fRc2, _ = self._sudoExecuteSync(['sc.exe', 'query', sService])
                if not fRc2:
                    break
                fHadLeftovers = True

                cTries += 1
                if cTries > 3:
                    asLeftovers.append(sService, )
                    break

                # Get the status output.
                try:
                    sOutput = utils.sudoProcessOutputChecked(
                        ['sc.exe', 'query', sService])
                except:
                    reporter.logXcpt()
                else:
                    if re.search(r'STATE\s+:\s*1\s*STOPPED', sOutput) is None:
                        reporter.log('Trying to stop %s...' % (sService, ))
                        fRc2, _ = self._sudoExecuteSync(
                            ['sc.exe', 'stop', sService])
                        time.sleep(1)
                        # fudge

                    reporter.log('Trying to delete %s...' % (sService, ))
                    self._sudoExecuteSync(['sc.exe', 'delete', sService])

                time.sleep(1)
                # fudge

        if asLeftovers:
            reporter.log('Warning! Leftover VBox drivers: %s' %
                         (', '.join(asLeftovers), ))
            fRc = False

        if fHadLeftovers:
            self._waitForTestManagerConnectivity(30)

        # Upload the log if we have any leftovers and didn't upload it already.
        if sLogFile is not None and (
                fRc is False or fHadLeftovers) and os.path.isfile(sLogFile):
            reporter.addLogFile(sLogFile, 'log/uninstaller',
                                "Verbose MSI uninstallation log file")

        return fRc