def removeVersion(self, version_): """ Removes a version (Must have state != 'active') """ if not version_ in self.versions: self._log("remove-version").error( "removeVersion() called, version %s unknown", version_) raise InstallException( "Internal error detected in removeVersion()") curState = self.versions[version_][self.kTokenState] if curState == self.kStateActive: self._log("remove-version").error( "removeVersion() called, version %s is active", version_) raise InstallException( "Internal error detected in removeVersion()") #TODO(orens): think about failing here instead of warning subPkgsToRemove = self.getSubPkgsToRemoveOnRemoval(version_) if len(subPkgsToRemove) > 0: self._log("remove-version").warning( "removeVersion() called, version %s has sub-pkgs to remove: %s", version_, subPkgsToRemove) rpmsToRemove = self.getRpmsToRemoveOnRemoval(version_) if len(rpmsToRemove) > 0: self._log("remove-version").warning( "removeVersion() called, version %s has RPMs to remove: %s", version_, rpmsToRemove) del self.versions[version_] self._log("remove-version").info( "removeVersion() called, version %s removed", version_) self.save()
def getPilotName(self, version_): """ Gets pilot name. If none, returns None """ if not version_ in self.versions: self._log("get-pilot-name").error( "getPilotName() called, version %s unknown", version_) raise InstallException("Internal error detected in getPilotName()") return self.versions[version_].get(self.kTokenPilotName)
def addVersion(self, version_, subPkgs=None, subPkgsToRemove=None, rpmsToRemove=None): """Adds a version with state 'on-disk' """ curState = self.getVersionState(version_) if (curState == self.kStateActive) or (curState == self.kStateReady): self._log("add-version").error( "addVersion() called, version %s already known, in state %s", version_, curState) raise InstallException("Internal error detected in addVersion()") self.versions[version_] = {self.kTokenState: self.kStateOnDisk} if subPkgs != None: self.versions[version_][self.kTokenSubPkgs] = subPkgs if subPkgsToRemove != None: self.versions[version_][ self.kTokenSubPkgsToRemove] = subPkgsToRemove if rpmsToRemove != None: self.versions[version_][self.kTokenRpmsToRemove] = rpmsToRemove self._log("add-version").info( "addVersion() called, version %s added (subPkgs=%s, sptr=%s, rtr=%s)", version_, subPkgs, subPkgsToRemove, rpmsToRemove) self.save()
def getLeaders(self, version_): """ Gets leaders. """ if not version_ in self.versions: self._log("get-leaders").error( "getLeaders() called, version %s unknown", version_) raise InstallException("Internal error detected in getLeaders()") return self.versions[version_].get(self.kTokenLeaders)
def getSubPkgs(self, version_): """ Gets subpkgs related to this version """ if not version_ in self.versions: self._log("get-subpkgs").error( "getSubPkgs() called, version %s unknown", version_) raise InstallException("Internal error detected in getSubPkgs()") return self.versions[version_].get(self.kTokenSubPkgs, [])
def getActiveVersion(self): """Returns the currently active version""" for version_ in self.versions: if self.versions[version_][self.kTokenState] == self.kStateActive: return version_ self._log("get-active-version").error( "getActiveVersion() called, no active version found") raise InstallException("Internal error detected in getActiveVersion()")
def getRpmsToRemoveOnRemoval(self, version_): """ Gets RPMs to remove. If none, returns an empty list """ if not version_ in self.versions: self._log("get-rpms-to-remove").error( "getRpmsToRemoveOnRemoval() called, version %s unknown", version_) raise InstallException( "Internal error detected in getRpmsToRemoveOnRemoval()") return self.versions[version_].get(self.kTokenRpmsToRemove, [])
def getPilotData(self, version_): """ Gets pilot data. If none, returns None """ if not version_ in self.versions: self._log("get-pilot-data").error( "getPilotData() called, version %s unknown", version_) raise InstallException("Internal error detected in getPilotData()") data = self.versions[version_].get(self.kTokenPilotData) self._log("get-pilot-data").info( "getPilotData(version=%s) returning '%s'", version_, data) return data
def getSwitchType(self, version_): """ Gets switch type. If none, returns None """ if not version_ in self.versions: self._log("get-switch-type").error( "getSwitchType() called, version %s unknown", version_) raise InstallException( "Internal error detected in getSwitchType()") switchType = self.versions[version_].get(self.kTokenSwitchType) self._log("get-switch-type").info( "getSwitchType(version=%s) returning '%s'", version_, switchType) return switchType
def getInstallDirection(self, version_): """ Gets install direction. If none, returns None """ if not version_ in self.versions: self._log("get-install-direction").error( "getInstallDirection() called, version %s unknown", version_) raise InstallException( "Internal error detected in getInstallDirection()") installDirection = self.versions[version_].get( self.kTokenInstallDirection) self._log("get-install-direction").info( "getInstallDirection(version=%s) returning '%s'", version_, installDirection) return installDirection
def setPilotData(self, version_, pilotData): """ Sets pilot data for a given version. If pilotData==None, removes the pilot data """ if not version_ in self.versions: self._log("set-pilot-data").error( "setPilotData() called, version %s unknown", version_) raise InstallException("Internal error detected in setPilotData()") self.versions[version_][self.kTokenPilotData] = pilotData if pilotData is None: del self.versions[version_][self.kTokenPilotData] self._log("set-pilot-data").info( "setPilotData(version=%s) called, pilotData set to='%s'", version_, pilotData) self.save()
def setPilotName(self, version_, pilotName): """ Sets pilot name for a given version. If pilotName==None, removes the pilot name""" if not version_ in self.versions: self._log("set-pilot-name").error( "setPilotName() called, version %s unknown", version_) raise InstallException("Internal error detected in setPilotName()") self.versions[version_][self.kTokenPilotName] = pilotName if pilotName is None: del self.versions[version_][self.kTokenPilotName] self._log("set-pilot-name").info( "setPilotName() called, version %s has pilotName=%s", version_, pilotName) self.save()
def setActiveVersion(self, version_): """Changes ready->active and active->on-disk""" self._log("set-active-version").info( "setActiveVersion(version_=%s) called", version_) if version_ not in self.versions: self._log("set-active-version").error( "setActiveVersion() called, version %s not found", version_) raise InstallException( "Internal error detected in setActiveVersion()") if self.versions[version_][self.kTokenState] != self.kStateReady: self._log("set-active-version").error( "setActiveVersion() called, version %s not ready, it is %s", version_, self.versions[version_][self.kTokenState]) raise InstallException( "Internal error detected in setActiveVersion()") curActive = self.getActiveVersion() self.versions[version_][self.kTokenState] = self.kStateActive self.versions[curActive][self.kTokenState] = self.kStateOnDisk self._log("set-active-version").info( "setActiveVersion() called, version %s is now active, prev one was %s", version_, curActive) self.save()
def setSwitchType(self, version_, switchType): """ Sets switch type for a given version. If switchType==None, removes the information """ if not version_ in self.versions: self._log("set-switch-type").error( "setSwitchType() called, version %s unknown", version_) raise InstallException( "Internal error detected in setSwitchType()") self.versions[version_][self.kTokenSwitchType] = switchType if switchType is None: del self.versions[version_][self.kTokenSwitchType] self._log("set-switch-type").info( "setSwitchType(version=%s) called, switchType set to='%s'", version_, switchType) self.save()
def setInstallDirection(self, version_, installDirection): """ Sets install direction for a given version (upgrade or downgrade). If installDirection==None, removes the information """ if not version_ in self.versions: self._log("set-install-direction").error( "setInstallDirection() called, version %s unknown", version_) raise InstallException( "Internal error detected in setInstallDirection()") self.versions[version_][self.kTokenInstallDirection] = installDirection if installDirection is None: del self.versions[version_][self.kTokenInstallDirection] self._log("set-install-direction").info( "setInstallDirection(version=%s) called, installDirection set to='%s'", version_, installDirection) self.save()
def setLeaders(self, version_, leaders): """ Sets leaders for a given version. leaders is a dict with 'prepare' and 'switch' entries, mapping them to a full package name of the leader """ if not version_ in self.versions: self._log("set-leaders").error( "setLeaders() called, version %s unknown", version_) raise InstallException("Internal error detected in setLeaders()") self.versions[version_][self.kTokenLeaders] = leaders self._log("set-leaders").info( "setLeaders() called, version %s has leaders=%s", version_, leaders) self.save()
def setReadyVersion(self, version_): """Changes on-disk->ready""" self._log("set-active-version").info( "setReadyVersion(version_=%s) called", version_) if version_ not in self.versions: self._log("set-ready-version").error( "setReadyVersion() called, version %s not found", version_) raise InstallException( "Internal error detected in setReadyVersion()") curReady = self.getReadyVersion() if curReady == version_: self._log("set-ready-version").info( "setReadyVersion(%s) called, version is already ready, nothing to do ", version_) return if curReady != None: self._log("set-ready-version").error( "setReadyVersion(%s) called, found a different ready version %s", version_, curReady) raise InstallException( "Internal error detected in setReadyVersion()") curState = self.versions[version_][self.kTokenState] if curState != self.kStateOnDisk: self._log("set-ready-version").error( "setReadyVersion() called, version %s not on disk, it is '%s'", version_, curState) raise InstallException( "Internal error detected in setReadyVersion()") self.versions[version_][self.kTokenState] = self.kStateReady self._log("set-active-version").info( "setReadyVersion() called, version %s is now ready", version_) self.save()
def setRpmsToRemoveOnRemoval(self, version_, rpmsToRemove): """ Sets RPMs to remove for a given version. Prev RPMs to remove are forgotten """ if not version_ in self.versions: self._log("set-rpms-to-remove").error( "setRpmsToRemoveOnRemoval() called, version %s unknown", version_) raise InstallException( "Internal error detected in setRpmsToRemoveOnRemoval()") self.versions[version_][self.kTokenRpmsToRemove] = rpmsToRemove if (rpmsToRemove is None) or (len(rpmsToRemove) == 0): del self.versions[version_][self.kTokenRpmsToRemove] self._log("set-rpms-to-remove").info( "setRpmsToRemoveOnRemoval() called, version %s has rpmsToRemove=%s", version_, rpmsToRemove) self.save()
def addSubPkgs(self, version_, subPkgsToAdd): """ Adds subpkgs to a version """ if not version_ in self.versions: self._log("add-subpkgs").error( "addSubPkgs() called, version %s unknown", version_) raise InstallException("Internal error detected in addSubPkgs()") # Version must have some sub packages already subPkgs = self.versions[version_][self.kTokenSubPkgs] for sb in subPkgsToAdd: if not sb in subPkgs: subPkgs.append(sb) self._log("add-subpkgs").info( "addSubPkgs(version=%s) called, sub-pkgs now are set to='%s'", version_, subPkgs) self.save()
def setVersionStateOnDisk(self, version_): """Changes version state to on-disk""" if version_ not in self.versions: self._log("set-version-state-ondisk").error( "setVersionStateOnDisk() called, version %s not found", version_) raise InstallException( "Internal error detected in setVersionStateOnDisk()") curState = self.versions[version_][self.kTokenState] self._log("set-version-state-ondisk").info( "setVersionStateOnDisk() called, version %s current state is '%s'", version_, curState) if curState == self.kStateOnDisk: return self.versions[version_][self.kTokenState] = self.kStateOnDisk self._log("set-version-state-ondisk").info( "setVersionStateOnDisk() called, version %s is now on-disk", version_) self.save()
def raiseException(self, msg): """Raises an exception to abort current pilot operation with an error""" self._log("raise-exception").info("raiseException() called, msg = %s", msg) raise InstallException(msg)
def _doPrepare(self): self._log("prepare").info("prepare() called") # Do not allow running this command after 'switch' self.raiseIfPendingRestart() fileArg = self._options.file if fileArg == None: self._log("missing-file").error("file option is missing") a.infra.process.processFatal("Missing file option") self._log("prepare").info("prepare got file: '%s'", fileArg) fileNormalized = self._normalizeFile( fileArg, normalize=not self._options.keepFileName) self._log("prepare").info("prepare normalized file: '%s'", fileNormalized) if not os.path.exists(fileNormalized): self._log("prepare").info("prepare: file '%s' does not exist", fileNormalized) printError("File does not exist") return 1 print("This may take some time, please wait") readyVersionAndBuild = self._installManager.getReadyVersion() self._log("prepare").info("Ready version+build is '%s'", readyVersionAndBuild) if readyVersionAndBuild != None: self._log("prepare").info("Canceling ready") self._installManager.cancel(readyVersionAndBuild[0], readyVersionAndBuild[1]) self._log("prepare").info("Calling removeVersionAndSubPkgs()") self._installManager.removeVersionAndSubPkgs( readyVersionAndBuild[0], readyVersionAndBuild[1]) self._log("prepare").info("Calling removeUnneededVersionsFromDisk()") self._installManager.removeUnneededVersionsFromDisk() if self._installSameVersion: # Patch: If --install-same-version is specified, we do the following things to allow it: # 1. Check that indeed prepared version is the same as the active version # 2. Rename the current version from 'v-b' to 'v-99999999'. This is done by changing the state file. # 3. Create a fake pilot for the fake build (ln -s pilot-qb-2.6.0.0-21037 /opt/qb/rpms/pilot-qb-2.6.0.0-99999) # Make sure that indeed we are installing the same version (newVersion, newBuild) = self._installManager.isPackageValid(fileNormalized) (activeVersion, activeBuild) = self._installManager.getActiveVersionAndBuild() if (newVersion != activeVersion) or (newBuild != activeBuild): msg="prepare(): --install-same-version used, but current version = %s-%s != package file version = %s-%s" \ % (activeVersion, activeBuild, newVersion, newBuild) self._log("prepare").error(msg) raise InstallException(msg) # Change name of active version fakeVersionAndBuild = self._installManager.combineVersion( activeVersion, a.sys.install.install_manager.kFakeBuildNumber) self._log("prepare").info("Changing active version name to %s", fakeVersionAndBuild) self._installManager.getStateManager( ).patchChangeNameOfActiveVersion(fakeVersionAndBuild) # Create fake pilot for fake build newVersionAndBuild = self._installManager.combineVersion( activeVersion, activeBuild) existingPilotName = self._installManager.calcPilotName( newVersionAndBuild) fakePilotName = self._installManager.calcPilotName( fakeVersionAndBuild) fakePilotDirName = os.path.join(self._rpmsDir, fakePilotName) self._log("prepare").info("Creating symlink %s -> %s", fakePilotDirName, existingPilotName) if os.path.lexists(fakePilotDirName): os.remove(fakePilotDirName) os.symlink(existingPilotName, fakePilotDirName) self._log("prepare").info("Calling addSubPkgs(%s)", fileNormalized) (version_, build) = self._installManager.addSubPkgs(fileNormalized) self._log("prepare").info("setting pilot hints to '%s'", self._pilotHints) self._installManager.setPilotHints(self._pilotHints) self._log("prepare").info( "Calling prepare(%s, %s, usePilotVersion=%s)", version_, build, self._options.usePilotVersion) try: self._installManager.prepare( version_, build, usePilotVersion=self._options.usePilotVersion) except: exc = sys.exc_info() self._log("prepare").error( "prepare() caused exception: %s, %s, tb=%s", exc[0], exc[1], traceback.format_tb(exc[2])) if os.path.exists(self._debugFlagFileDontCleanOnError): self._log("prepare").info( "prepare() failed, %s exists, not removing sub-packages", self._debugFlagFileDontCleanOnError) removeSubPackages = False else: removeSubPackages = True self._log("prepare").info( "prepare() failed, calling removeVersionAndSubPkgs(%s, %s)", version_, build) self._installManager.removeVersionAndSubPkgs( version_, build, removeSubPackages=removeSubPackages) self._log("prepare").info("removeVersionAndSubPkgs() done") raise self._log("prepare").info("prepare() done") return 0
def raiseIfPendingRestart(self): if self._installManager.isPendingRestart(): raise InstallException( "'switch' command was executed, further install commands cannot be executed until system restarts" )
def add(self, r2pmFile=None, httpRepo=None, packageName=None): """ Adds sub-packages, either from a r2pm file or from an http repo. To install from file: r2pmFile : file name To install from an http repo: httpRepo : repo address packageName : Name of package containing the sub-packages Returns a tuple (subPkgs, subPkgstoRemove). subPkgs: list of sub-pkgs included in this version. subPkgstoRemove: list of new sub-pkgs (Replaced sub-pkgs are not included in that list). These sub-pkgs will be removed if 'prepare' operation is canceled """ self._log("add-called").info( "add() called, r2pmFile=%s, httpRepo=%s, packageName=%s", r2pmFile, httpRepo, packageName) # Check that our input makes sense if (r2pmFile == None) == (httpRepo == None): msg = "add(): bad parameters, must use either r2pmFile or httpRepo" self._log("add-called-bad").error(msg) raise InstallException(msg) if r2pmFile != None: self._raiseIfNotAbsPath(r2pmFile, "r2pmFile") else: if packageName == None: msg = "add(): bad parameters, httpRepo must come with packageName" self._log("add-called-bad").error(msg) raise InstallException(msg) # Clean the temp dir and create it if not self.useFakeChrootMode: # In ut fakechroot mode we do not remove this, because this dir has chroot soft links self._cleanTempDir() self.utils.runCommandRaiseIfFail("mkdir -p " + self.subPkgTempDir) # Import RPM public keys # In unit tests, it is impossible to get keys from outside of the chroot. Instead, the test does rpm --import # in this chroot for us. if not self.useFakeChrootMode: rpm = Rpm(self._log) rpm.setRoot(self.subPkgTempDir) for keyFile in os.listdir(self.rpmKeysDir): rpm.doImport(os.path.join(self.rpmKeysDir, keyFile)) # Check space - must have at least 4GB free availableSize = self.utils.getAvailableSize(self.subPkgTempDir) if availableSize < 4e9: raise InstallException( "Internal error: Not enough space on system disk") # Read all existing sub-pkgs oldInfoDict = self._readInfoFiles(self.infoDir) self._log("add-sub-pkg").info("add(): Found old sub-pkgs %s", oldInfoDict) oldSubPkgs = oldInfoDict.keys() # Create temp dir for yum (for config file and such) if not self.useFakeChrootMode: yumTempDir = os.path.join(self.subPkgTempDir, "tmp") else: yumTempDir = "/tmp" # Extract r2pm into temp dir try: if r2pmFile != None: # Install from file removeFile = False if not self.useFakeChrootMode: r2pmNameToYum = r2pmFile # In CentOS6.2, package files must end with '.rpm' if not r2pmNameToYum.endswith('.rpm'): r2pmNameToYum = os.path.join(self.subPkgTempDir, 'package.rpm') self._log("add-sub-pkg-copy").info( "add(): Copying %s to %s to have a file name that ends with .rpm", r2pmFile, r2pmNameToYum) self.utils.runCommandRaiseIfFail( "cp -f %s %s" % (r2pmFile, r2pmNameToYum)) removeFile = True else: self.utils.runCommandRaiseIfFail("cp " + r2pmFile + " " + self.subPkgTempDir) r2pmNameToYum = "/" + os.path.basename(r2pmFile) yum = Yum(self._log, yumTempDir) yum.setRoot(self.subPkgTempDir, useFakeChrootMode=self.useFakeChrootMode) yum.doLocalInstall(r2pmNameToYum) if removeFile: self._log("add-sub-pkg-remove").info( "add(): Removing file that was copied") self.utils.runCommandRaiseIfFail("rm -f %s" % r2pmNameToYum) else: # Install from http repo yum = Yum(self._log, yumTempDir) yum.setRoot(self.subPkgTempDir, useFakeChrootMode=self.useFakeChrootMode) yum.addHttpRepo("network", httpRepo) yum.doInstall(packageName) # Now, move/replace new sub-pkgs into subPkgDir. # We do this according to a very specific sequence, so that in case we abort in the middle (power failure or whatever), # A call to TBD() will restore things the way they were before this operation # Todo(orens): TBD -> Real function # Sequence is: # 1. Copy all existing sub-packages to self.subPkgTempDir, except for those found there already (i.e. new copy # is better tahn old copy) # 2. Rename self.subPkgDir with a '.tmp' suffix # 3. Rename self.subPkgTempDir to become self.subPkgDir # 4. Remove self.subPkgDir + '.tmp' # System is always stable, excelt for the split-second between 2 and 3. # Read list of new sub-packages newInfoDict = self._readInfoFiles( os.path.join(self.subPkgTempDir, "info")) self._log("add-sub-pkg").info("add(): Found new sub-pkgs %s", newInfoDict) newSubPkgs = newInfoDict.keys() # Sanity-check the new info: Make sure new sub-pkgs have all the data we need in their .info files for subPkg in newSubPkgs: info = newInfoDict[subPkg] if not 'dir' in info: self._log("add-bad-info-dir").error( "add(): sub-pkg %s info does not have 'dir'", subPkg) return None infoDirPath = os.path.join(self.subPkgTempDir, info['dir']) if not os.path.isdir(infoDirPath): self._log("add-missing-dir").error( "add(): sub-pkg %s info has 'dir'->%s, does not exist", subPkg, infoDirPath) return None if not 'name' in info: self._log("add-bad-info-name").error( "add(): sub-pkg %s info does not have 'name'", subPkg) return None if info['name'] != subPkg: self._log("add-bad-name").error( "add(): sub-pkg %s info has 'name'=%s, should be identical", subPkg, info['name']) return None # Step 1: Copy all old sub-packages, which are not found in the new dir, to the new dir for subPkg in oldSubPkgs: if subPkg not in newSubPkgs: oldInfoFile = self._getInfoFileName(self.subPkgDir, subPkg) newInfoFile = self._getInfoFileName( self.subPkgTempDir, subPkg) oldSubPkgDir = os.path.join(self.subPkgDir, oldInfoDict[subPkg]['dir']) newSubPkgDir = os.path.join(self.subPkgTempDir, oldInfoDict[subPkg]['dir']) if os.path.exists(newSubPkgDir): self._log("add-bad-name").error( "add(): old sub-pkg %s not found in new sub-packages, but %s exists", subPkg, newSubPkgDir) return None self.utils.runCommandRaiseIfFail( "cp -vpf %s %s" % (oldInfoFile, newInfoFile)) self.utils.runCommandRaiseIfFail( "cp -vrpf %s %s" % (oldSubPkgDir, newSubPkgDir)) # Steps 2-4: Copy all old sub-packages, which are not found in the new dir, to the new dir tmpOldName = self.subPkgDir + '.tmp' self.utils.runCommandRaiseIfFail("mv -vf %s %s" % (self.subPkgDir, tmpOldName)) self.utils.runCommandRaiseIfFail( "mv -vf %s %s" % (self.subPkgTempDir, self.subPkgDir)) self.utils.runCommandRaiseIfFail("rm -vrf %s" % (tmpOldName)) finally: # Remove the install-temp directory, no sense in leaving it here self._cleanTempDir() # oldInfoDict.keys() holds the list of subPkgs before the install. Let's find out what was added. newInfoDict = self._readInfoFiles(self.infoDir) # Sorting makes it easy on unit tests :-) addedSubPkgs = sorted( list(set(newInfoDict.keys()) - set(oldInfoDict.keys()))) return (sorted(newSubPkgs), addedSubPkgs)
def load(self): """ Loads state from file. If file does not exist or invalid, raises InstallException """ self._log("load-called").info("load() called, reading state from %s", self._stateFile) if not os.path.exists(self._stateFile): self._log("load-no-file").error( "load() called, no file '%s' found", self._stateFile) raise InstallException("State file not found: %s" % self._stateFile) dict_ = a.infra.format.json.readFromFile(self._log, self._stateFile) if not self.kTokenVersions in dict_: self._log("load-invalid-text").error("load() could not find '%s'", self.kTokenVersions) raise InstallException("State file is invalid: %s " % self._stateFile) versions = dict_[self.kTokenVersions] # Parse versions into newVersions newVersions = {} numActive = 0 numReady = 0 for version_ in versions: versionInfo = versions[version_] # state is checked thorrowly if not self.kTokenState in versionInfo: self._log("load-invalid-version").error( "load() could not find state for version '%s'", version_) raise InstallException("State file is invalid: %s " % self._stateFile) state = versionInfo[self.kTokenState] if (state != self.kStateActive) and ( state != self.kStateReady) and (state != self.kStateOnDisk): self._log("load-invalid-state").error( "load() got invalid state '%s' for version '%s'", state, version_) raise InstallException("State file is invalid: %s " % self._stateFile) newVersions[version_] = {self.kTokenState: state} newVersionInfo = newVersions[version_] if state == self.kStateActive: numActive += 1 if state == self.kStateReady: numReady += 1 # Other data is simple copied if self.kTokenPilotName in versionInfo: newVersionInfo[self.kTokenPilotName] = versionInfo[ self.kTokenPilotName] if self.kTokenPilotData in versionInfo: newVersionInfo[self.kTokenPilotData] = versionInfo[ self.kTokenPilotData] if self.kTokenSwitchType in versionInfo: newVersionInfo[self.kTokenSwitchType] = versionInfo[ self.kTokenSwitchType] if self.kTokenInstallDirection in versionInfo: newVersionInfo[self.kTokenInstallDirection] = versionInfo[ self.kTokenInstallDirection] if self.kTokenSubPkgsToRemove in versionInfo: newVersionInfo[self.kTokenSubPkgsToRemove] = versionInfo[ self.kTokenSubPkgsToRemove] if self.kTokenRpmsToRemove in versionInfo: newVersionInfo[self.kTokenRpmsToRemove] = versionInfo[ self.kTokenRpmsToRemove] if self.kTokenSubPkgs in versionInfo: newVersionInfo[self.kTokenSubPkgs] = versionInfo[ self.kTokenSubPkgs] else: # 2.1.0.0 does not maintain the 'sub-packages' info. Hence, we 'guess' it :-) newVersionInfo[self.kTokenSubPkgs] = ['qb-' + version_] if self.kTokenLeaders in versionInfo: newVersionInfo[self.kTokenLeaders] = versionInfo[ self.kTokenLeaders] else: # 2.1.0.0 does not maintain the 'leaders' info. Hence, we 'guess' it :-) newVersionInfo[self.kTokenLeaders] = { 'prepare': 'qb-leader-prepare-' + version_, 'switch': 'qb-leader-switch-' + version_ } if (numActive != 1) or (numReady > 1): self._log("load-invalid-states").error( "load() found %s active versions, %s ready versions, impossible", numActive, numReady) raise InstallException("State file is invalid: %s " % self._stateFile) # Check 'versionToActivateOnStartup' newVersionToActivate = None if self.kTokenActivateOnStartup in dict_: newVersionToActivate = dict_[self.kTokenActivateOnStartup] if not newVersionToActivate in newVersions: self._log("load-invalid-vta").error( "load() found invalid version to activate = '%s', not in list", newVersionToActivate) raise InstallException("State file is invalid: %s" % self._stateFile) vtaState = newVersions[newVersionToActivate][self.kTokenState] if vtaState != self.kStateReady: self._log("load-invalid-vta").error( "load() found invalid version to activate = '%s', has state '%s', not ready", newVersionToActivate, vtaState) raise InstallException("State file is invalid: %s" % self._stateFile) # Check 'locked' newLocked = False if self.kTokenLocked in dict_: newLocked = True # Now that we are sure that the state we got is valid, we rememebr it self.versions = newVersions self.versionToActivateOnStartup = newVersionToActivate self._locked = newLocked self._log("load-got-state").info( "load() got a new state: versions='%s', versionToActivateOnStartup='%s', locked=%s", self.versions, self.versionToActivateOnStartup, self._locked)