cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# -*- coding: utf-8 -*-
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# $Id$
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncTestBox Script - Upgrade from local file ZIP.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync__copyright__ = \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCopyright (C) 2012-2014 Oracle Corporation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThis file is part of VirtualBox Open Source Edition (OSE), as
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncavailable from http://www.virtualbox.org. This file is free software;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncyou can redistribute it and/or modify it under the terms of the GNU
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGeneral Public License (GPL) as published by the Free Software
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncFoundation, in version 2 as it comes in the "COPYING" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncVirtualBox OSE distribution. VirtualBox OSE is distributed in the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsynchope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThe contents of this file may alternatively be used under the terms
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncof the Common Development and Distribution License Version 1.0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync(CDDL) only, as it comes in the "COPYING.CDDL" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncVirtualBox OSE distribution, in which case the provisions of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCDDL are applicable instead of those of the GPL.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncYou may elect to license modified versions of this file under the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncterms and conditions of either the GPL or the CDDL or both.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync__version__ = "$Revision$"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Standard python imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport os
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport shutil
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport sys
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport subprocess
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport threading
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport uuid;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport zipfile
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Validation Kit imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport testboxcommons
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testboxscript import TBS_EXITCODE_SYNTAX;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom common import utils;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Figure where we are.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsynctry: __file__
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncexcept: __file__ = sys.argv[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncg_ksTestScriptDir = os.path.dirname(os.path.abspath(__file__));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncg_ksValidationKitDir = os.path.dirname(g_ksTestScriptDir);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef _doUpgradeThreadProc(oStdOut, asBuf):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Thread procedure for the upgrade test drive."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asBuf.append(oStdOut.read());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef _doUpgradeCheckZip(oZip):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Check that the essential files are there.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns list of members on success, None on failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asMembers = oZip.namelist();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if ('testboxscript/testboxscript/testboxscript.py' not in asMembers) \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or ('testboxscript/testboxscript/testboxscript_real.py' not in asMembers):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Missing one or both testboxscripts (members: %s)' % (asMembers,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sMember in asMembers:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not sMember.startswith('testboxscript/'):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('zip file contains member outside testboxscript/: "%s"' % (sMember,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sMember.find('/../') > 0 or sMember.endswith('/..'):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('zip file contains member with escape sequence: "%s"' % (sMember,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return asMembers;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef _doUpgradeUnzipAndCheck(oZip, sUpgradeDir, asMembers):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Unzips the files into sUpdateDir, does chmod(755) on all files and
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync checks that there are no symlinks or special files.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns True/False.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Extract the files.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if os.path.exists(sUpgradeDir):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shutil.rmtree(sUpgradeDir);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sMember in asMembers:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sMember.endswith('/'):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.makedirs(os.path.join(sUpgradeDir, sMember.replace('/', os.path.sep)), 0775);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oZip.extract(sMember, sUpgradeDir);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Make all files executable and make sure only owner can write to them.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # While at it, also check that there are only files and directory, no
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # symbolic links or special stuff.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sMember in asMembers:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sFull = os.path.join(sUpgradeDir, sMember);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sMember.endswith('/'):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not os.path.isdir(sFull):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Not directory: "%s"' % sFull);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not os.path.isfile(sFull):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Not regular file: "%s"' % sFull);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.chmod(sFull, 0755);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('warning chmod error on %s: %s' % (sFull, oXcpt));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef _doUpgradeTestRun(sUpgradeDir):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Do a testrun of the new script, to make sure it doesn't fail with
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync to run in any way because of old python, missing import or generally
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync busted upgrade.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns True/False.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asArgs = [os.path.join(sUpgradeDir, 'testboxscript', 'testboxscript', 'testboxscript.py'), '--version' ];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Testing the new testbox script (%s)...' % (asArgs[0],));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sys.executable is not None and len(sys.executable) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asArgs.insert(0, sys.executable);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oChild = subprocess.Popen(asArgs, shell = False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asBuf = []
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oThread = threading.Thread(target=_doUpgradeThreadProc, args=(oChild.stdout, asBuf));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oThread.daemon = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oThread.start();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oThread.join(30);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iStatus = oChild.poll();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if iStatus is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Checking the new testboxscript timed out.');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oChild.terminate();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oThread.join(5);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if iStatus is not TBS_EXITCODE_SYNTAX:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('The new testboxscript returned %d instead of %d during check.' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (iStatus, TBS_EXITCODE_SYNTAX));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sOutput = ''.join(asBuf);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sOutput = sOutput.strip();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iNewVersion = int(sOutput);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('The new testboxscript returned an unparseable version string: "%s"!' % (sOutput,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('New script version: %s' % (iNewVersion,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef _doUpgradeApply(sUpgradeDir, asMembers):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Apply the directories and files from the upgrade.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync returns True/False/Exception.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Create directories first since that's least intrusive.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sMember in asMembers:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sMember[-1] == '/':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sMember = sMember[len('testboxscript/'):];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sMember != '':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sFull = os.path.join(g_ksValidationKitDir, sMember);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not os.path.isdir(sFull):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.makedirs(sFull, 0755);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Move the files into place.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asOldFiles = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sMember in asMembers:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sMember[-1] != '/':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sSrc = os.path.join(sUpgradeDir, sMember);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sDst = os.path.join(g_ksValidationKitDir, sMember[len('testboxscript/'):]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Move the old file out of the way first.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sDstRm = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if os.path.exists(sDst):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log2('Info: Installing "%s"' % (sDst,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sDstRm = '%s-delete-me-%s' % (sDst, uuid.uuid4(),);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.rename(sDst, sDstRm);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Error: failed to rename (old) "%s" to "%s": %s' % (sDst, sDstRm, oXcpt));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shutil.copy(sDst, sDstRm);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Error: failed to copy (old) "%s" to "%s": %s' % (sDst, sDstRm, oXcpt));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.unlink(sDst);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Error: failed to unlink (old) "%s": %s' % (sDst, oXcpt));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Move/copy the new one into place.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log2('Info: Installing "%s"' % (sDst,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.rename(sSrc, sDst);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Warning: failed to rename (new) "%s" to "%s": %s' % (sSrc, sDst, oXcpt));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shutil.copy(sSrc, sDst);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Error: failed to copy (new) "%s" to "%s": %s' % (sSrc, sDst, oXcpt));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fRc = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Roll back on failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fRc is not True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Attempting to roll back old files...');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sDstRm in asOldFiles:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sDst = sDstRm[:sDstRm.rfind('-delete-me')];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log2('Info: Rolling back "%s" (%s)' % (sDst, os.path.basename(sDstRm)));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shutil.move(sDstRm, sDst);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Error: failed to rollback "%s" onto "%s": %s' % (sDstRm, sDst, oXcpt));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef _doUpgradeRemoveOldStuff(sUpgradeDir, asMembers):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Clean up all obsolete files and directories.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns True (shouldn't fail or raise any exceptions).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shutil.rmtree(sUpgradeDir, ignore_errors = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asKnownFiles = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asKnownDirs = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sMember in asMembers:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sMember = sMember[len('testboxscript/'):];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sMember == '':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sMember[-1] == '/':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asKnownDirs.append(os.path.normpath(os.path.join(g_ksValidationKitDir, sMember[:-1])));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asKnownFiles.append(os.path.normpath(os.path.join(g_ksValidationKitDir, sMember)));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sDirPath, asDirs, asFiles in os.walk(g_ksValidationKitDir, topdown=False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sDir in asDirs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sFull = os.path.normpath(os.path.join(sDirPath, sDir));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sFull not in asKnownDirs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log2('Info: Removing obsolete directory "%s"' % (sFull,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.rmdir(sFull);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Warning: failed to rmdir obsolete dir "%s": %s' % (sFull, oXcpt));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sFile in asFiles:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sFull = os.path.normpath(os.path.join(sDirPath, sFile));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sFull not in asKnownFiles:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log2('Info: Removing obsolete file "%s"' % (sFull,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync os.unlink(sFull);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except Exception, oXcpt:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Warning: failed to unlink obsolete file "%s": %s' % (sFull, oXcpt));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncdef upgradeFromZip(sZipFile):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Upgrade the testboxscript install using the specified zip file.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns True/False.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # A little precaution.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if utils.isRunningFromCheckout():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Use "svn up" to "upgrade" your source tree!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Prepare.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Note! Don't bother cleaning up files and dirs in the error paths,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # they'll be restricted to the one zip and the one upgrade dir.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # We'll remove them next time we upgrade.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oZip = zipfile.ZipFile(sZipFile, 'r');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asMembers = _doUpgradeCheckZip(oZip);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if asMembers is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sUpgradeDir = os.path.join(g_ksTestScriptDir, 'upgrade');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync testboxcommons.log('Unzipping "%s" to "%s"...' % (sZipFile, sUpgradeDir));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if _doUpgradeUnzipAndCheck(oZip, sUpgradeDir, asMembers) is not True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oZip.close();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if _doUpgradeTestRun(sUpgradeDir) is not True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Execute.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if _doUpgradeApply(sUpgradeDir, asMembers) is not True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _doUpgradeRemoveOldStuff(sUpgradeDir, asMembers);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# For testing purposes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncif __name__ == '__main__':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sys.exit(upgradeFromZip(sys.argv[1]));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync