vboxinstaller.py revision a9196bad0e58bf7f0f7d58fdab31a6699699f817
# -*- coding: utf-8 -*-
"""
VirtualBox Installer Wrapper Driver.
This installs VirtualBox, starts a sub driver which does the real testing,
and then uninstall VirtualBox afterwards. This reduces the complexity of the
other VBox test drivers.
"""
__copyright__ = \
"""
Copyright (C) 2010-2014 Oracle Corporation
This file is part of VirtualBox Open Source Edition (OSE), as
available from http://www.virtualbox.org. This file is free software;
General Public License (GPL) as published by the Free Software
Foundation, in version 2 as it comes in the "COPYING" file of the
VirtualBox OSE distribution. VirtualBox OSE is distributed in the
hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
The contents of this file may alternatively be used under the terms
of the Common Development and Distribution License Version 1.0
(CDDL) only, as it comes in the "COPYING.CDDL" file of the
VirtualBox OSE distribution, in which case the provisions of the
CDDL are applicable instead of those of the GPL.
You may elect to license modified versions of this file under the
terms and conditions of either the GPL or the CDDL or both.
"""
__version__ = "$Revision$"
# Standard Python imports.
import os
import sys
import re
import socket
import tempfile
import time
# Only the main script needs to modify the path.
try: __file__
# Validation Kit imports.
from testdriver import reporter;
"""
Implementation of a top level test driver.
"""
## State file indicating that we've skipped installation.
ksVar_Skipped = 'vboxinstaller-skipped';
#
# Base method we override
#
# 0 1 2 3 4 5 6 7 8
# 012345678901234567890123456789012345678901234567890123456789012345678901234567890
return rc;
"""
Parse our arguments.
"""
# End of our parameters and start of the sub driver invocation.
else:
return iArg + 1;
def completeOptions(self):
#
# Check that we've got what we need.
#
return False;
return False;
#
# Construct _asBuildFiles as an array parallel to _asBuildUrls.
#
def actionExtract(self):
reporter.error('vboxinstall does not support extracting resources, you have to do that using the sub testdriver.');
return False;
def actionCleanupBefore(self):
"""
Kills all VBox process we see.
This is only supposed to execute on a testbox so we don't need to go
all complicated wrt other users.
"""
return self._killAllVBoxProcesses();
def actionConfig(self):
"""
Install VBox and pass on the configure request to the sub testdriver.
"""
## @todo vbox.py still has bugs preventing us from invoking it seperately with each action.
return fRc;
def actionExecute(self):
"""
Execute the sub testdriver.
"""
def actionCleanupAfter(self):
"""
Forward this to the sub testdriver, then uninstall VBox.
"""
if not self._killAllVBoxProcesses():
return fRc;
def actionAbort(self):
"""
Forward this to the sub testdriver first, then do the default pid file
based cleanup and finally swipe the scene with the heavy artillery.
"""
#
# Persistent variables.
#
## @todo integrate into the base driver. Persisten accross scratch wipes?
"""Returns the (full) filename for the given persistent variable."""
"""
Sets a persistent variable.
Returns True on success, False + reporter.error on failure.
May raise exception if the variable name is invalid or something
unexpected happens.
"""
try:
except:
return False;
return True;
"""
Unsets a persistent variable.
Returns True on success, False + reporter.error on failure.
May raise exception if the variable name is invalid or something
unexpected happens.
"""
try:
except:
return False;
return True;
"""
Checks if a persistent variable exists.
May raise exception if the variable name is invalid or something
unexpected happens.
"""
"""
Gets the value of a persistent variable.
Returns variable value on success.
Returns None if the variable doesn't exist or if an
error (reported) occured.
May raise exception if the variable name is invalid or something
unexpected happens.
"""
return None;
try:
except:
return None;
return sValue;
#
# Helpers.
#
def _killAllVBoxProcesses(self):
"""
Kills all virtual box related processes we find in the system.
"""
# Gather processes to kill.
aoTodo = [];
if sBase is None:
continue;
if sBase in [ 'vboxsvc', 'virtualbox', 'virtualboxvm', 'vboxheadless', 'vboxmanage', 'vboxsdl', 'vboxwebsrv',
'vboxautostart', 'vboxballoonctrl', 'vboxbfe', 'vboxextpackhelperapp', 'vboxnetdhcp',
'vboxnetadpctl', 'vboxtestogl', 'vboxtunctl', 'vboxvmmpreload', 'vboxxpcomipcd', 'vmCreator', ]:
return True;
# Kill.
# Check if they're all dead like they should be.
break;
return False;
"""
Executes a child process synchronously.
Returns True if the process executed successfully and returned 0,
otherwise False is returned.
"""
try:
except:
return False;
return iRc is 0;
"""
Executes a sudo child process synchronously.
Returns a tuple [True, 0] if the process executed successfully
and returned 0, otherwise [False, rc] is returned.
"""
iRc = 0;
try:
except:
return (False, 0);
"""
Execute the sub testdriver with the specified action.
"""
"""
Attempts to unpack the given build file.
Updates _asBuildFiles.
"""
if asMembers is None:
return False;
return True;
def _installVBox(self):
"""
Download / copy the build files into the scratch area and install them.
"""
#
# Download the build files.
#
return None; # Failed to get binaries, probably deleted. Skip the test run.
#
# Unpack anything we know what is and append it to the build files
# list. This allows us to use VBoxAll*.tar.gz files.
#
return None; # Failed to unpack. Probably local error, like busy
# DLLs on windows, no reason for failing the build.
#
# Go to system specific installation code.
#
else:
#
# Install the extension pack.
#
# Some debugging...
try:
reporter.log('Disk usage after VBox install: %d MB available at %s' % (cMbFreeSpace, self.sScratchPath,));
except:
return fRc;
"""
Uninstall VirtualBox.
"""
else:
return fRc;
"""
Returns the first build file that matches the given regular expression
(basename only).
Returns None if no match was found, logging it as an error if
fMandatory is set.
"""
return sFile;
if fMandatory:
return None;
"""
Check and wait for network connectivity to the test manager.
This is used with the windows installation and uninstallation since
these usually disrupts network connectivity when installing the filter
driver. If we proceed to quickly, we might finish the test at a time
when we cannot report to the test manager and thus end up with an
abandonded test error.
"""
cSecElapsed = 0;
if cSecElapsed >= cSecTimeout:
return False;
if cSecElapsed > 0:
return True;
#
# Darwin (Mac OS X).
#
def _darwinDmgPath(self):
""" Returns the path to the DMG mount."""
"""
Umount any DMG on at the default mount point.
"""
return True;
# Unmount.
if not fRc and not fIgnoreError:
# Remove dir.
try:
except:
if not fIgnoreError:
return fRc;
"""
Mount the DMG at the default mount point.
"""
try:
except:
return False;
return self._executeSync(['hdiutil', 'attach', '-readonly', '-mount', 'required', '-mountpoint', sMountPath, sDmg, ]);
def _installVBoxOnDarwin(self):
""" Installs VBox on Mac OS X."""
if sDmg is None:
return False;
# Mount the DMG.
return False;
# Uninstall any previous vbox version first.
# Install the package.
fRc, _ = self._sudoExecuteSync(['installer', '-verbose', '-dumplog', '-pkg', sPkg, '-target', '/']);
# Unmount the DMG and we're done.
return fRc;
def _uninstallVBoxOnDarwin(self):
""" Uninstalls VBox on Mac OS X."""
# Is VirtualBox installed? If not, don't try uninstall it.
if sVBox is None:
return True;
# Find the dmg.
if sDmg is None:
return False;
return True;
# Mount the DMG.
return False;
# Execute the uninstaller.
# Unmount the DMG and we're done.
return fRc;
#
#
def _installVBoxOnLinux(self):
""" Installs VBox on Linux."""
if sRun is None:
return False;
# Install the new one.
return fRc;
def _uninstallVBoxOnLinux(self):
""" Uninstalls VBox on Linux."""
# Is VirtualBox installed? If not, don't try uninstall it.
if sVBox is None:
return True;
# Find the .run file and use it.
if sRun is not None:
return fRc;
# Try the installed uninstaller.
return fRc;
return True;
#
# Solaris
#
"""
Generates an autoresponse file on solaris, returning the name.
None is return on failure.
"""
'runlevel=nocheck\n'
'conflict=quit\n'
'setuid=nocheck\n'
'action=nocheck\n'
'partial=quit\n'
'instance=unique\n'
'idepend=quit\n'
'rdepend=quit\n'
'space=quit\n'
'mail=\n');
return sPath;
def _installVBoxOnSolaris(self):
""" Installs VBox on Solaris."""
if sPkg is None:
if sTar is not None:
return False;
return False;
# Uninstall first (ignore result).
# Install the new one.
return fRc;
def _uninstallVBoxOnSolaris(self):
""" Uninstalls VBox on Solaris."""
return True;
return fRc;
#
# Windows
#
def _installVBoxOnWindows(self):
""" Installs VBox on Windows."""
if sExe is None:
return False;
# Uninstall any previous vbox version first.
return None; # There shouldn't be anything to uninstall, and if there is, it's not our fault.
# Install the new one.
if sVBoxInstallPath is not None:
# Optional, don't fail.
else:
if sLogFile is not None \
return fRc;
def _uninstallVBoxOnWindows(self):
"""
Uninstalls VBox on Windows, all installations we find to be on the safe side...
"""
resultCLSID = '{000C1090-0000-0000-C000-000000000046}')
# Search installed products for VirtualBox.
asProdCodes = [];
try:
except:
continue;
#reporter.log('Info: %s=%s' % (sProdCode, sProdName));
# Before we start uninstalling anything, just ruthlessly kill any
# msiexec process we might find hanging around.
cKilled = 0;
cKilled += 1;
if cKilled > 0:
# Do the uninstalling.
fRc2, iRc = self._sudoExecuteSync(['msiexec', '/uninstall', sProdCode, '/quiet', '/passive', '/norestart',
# Optional, don't fail.
else:
# TEMPORARY HACK - START
sMagicScript = os.path.abspath(os.path.join(g_ksValidationKitDir, 'testdriver', 'win-vbox-net-uninstall.ps1'));
fRc2, _ = self._sudoExecuteSync(['powershell.exe', '-Command', 'set-executionpolicy unrestricted']);
if not fRc2:
if not fRc2:
# TEMPORARY HACK - END
return fRc;
#
# Extension pack.
#
""" Returns the default VBox installation path. """
if sHost == 'win':
asLocs = [
];
elif sHost == 'darwin':
asLocs = [ '/Applications/VirtualBox.app/Contents/MacOS' ];
else:
asLocs = [ '/opt/VirtualBox' ];
return sLoc;
if fFailIfNotFound:
else:
return None;
def _installExtPack(self):
""" Installs the extension pack. """
if sVBox is None:
return False;
return False;
if sExtPack is None:
if sExtPack is None:
return True;
'--extract',
'--verbose',
'--gzip',
'--file', sExtPack,
'--directory', sDstDir,
'--file-mode-and-mask', '0644',
'--file-mode-or-mask', '0644',
'--dir-mode-and-mask', '0755',
'--dir-mode-or-mask', '0755',
'--owner', '0',
'--group', '0',
]);
return fRc;
def _uninstallAllExtPacks(self):
""" Uninstalls all extension packs. """
if sVBox is None:
return True;
return True;
return fRc;
if __name__ == '__main__':