def _checkInstall(self, pkg, context, pkgQueue, depth): Log.cout(Log.DEBUG, self._outputTrace(depth, "checkInstall(%s)" % pkg)) if depth > self.MAX_DEPTH: return error.ERROR_INSTALL context.ts.setOperation(pkg, INSTALL) context.excludes.exclude(pkg) if not pkg.installed(): ret = self._checkConflictAndProvide(pkg, context, pkgQueue, depth) if ret != error.ERROR_NONE: return ret requireDict = ResolverHelper.getAndMergeRequires(pkg) for name, requires in requireDict.items(): prvpkgs = self._getByProvides(requires, context) prvpkg = self._getBestInstalledProvide(pkg, prvpkgs, context) if not prvpkg: return error.ERROR_NONE if prvpkg is pkg: continue if context.excludes.excluded(prvpkg): self._addDependency(pkg, prvpkg, context, 'install') continue if self.getInstallDir(prvpkg) == self.installRoot: ret = self._checkInstall(prvpkg, context, pkgQueue, depth + 1) if ret != error.ERROR_NONE: Log.cout(Log.ERROR, 'Check install package %s failed' % prvpkg) return ret self._addDependency(pkg, prvpkg, context, 'install') return error.ERROR_NONE
def _getMetaFile(self, repoMdObj, metaName, fileName): if not repoMdObj.repoMdDatas.has_key(metaName): return False metaObj = repoMdObj.repoMdDatas[metaName] destTmpFile = self._getRepoDataDir() + '/' + \ metaObj.locationHref.split('/')[-1] metaUrl = self.repoConfig.baseurl + '/' + metaObj.locationHref # uncompressTmpFile = '.'.join(destTmpFile.split('.')[:-1]) + '.tmp' uncompressTmpFile = self._getRepoDataDir() + '/' + \ fileName + '.tmp' if not file_util.remove(destTmpFile) or\ not file_util.remove(uncompressTmpFile): return False if not self.fileFetcher.fetch(metaUrl, destTmpFile) or\ not file_util.chmod(destTmpFile, 0666): return False try: if destTmpFile.split('.')[-1] == 'bz2': f = bz2.BZ2File(destTmpFile) else: f = gzip.open(destTmpFile) if not file_util.writeToFile(uncompressTmpFile, f.read()) or\ not file_util.chmod(uncompressTmpFile, 0666): f.close() return False f.close() except Exception: Log.cout(Log.ERROR, 'decompress %s failed' % destTmpFile) return False return self._checkSumValid(metaObj, uncompressTmpFile)
def _queue(self, pkgQueue, context, depth): if len(pkgQueue) == 0: return error.ERROR_NONE Log.cout(Log.DEBUG, self._outputTrace(depth, "queue")) ret = error.ERROR_NONE while True: tmpQueue, hasSuccess = list(), False while len(pkgQueue) > 0: item = pkgQueue.pop(0) if item[0] == INSTALL: ret = self._handleInstallItem(pkgQueue, item, context, depth) elif item[0] == REMOVE: ret = self._handleRemoveItem(pkgQueue,item, context, depth) if ret == error.ERROR_NONE: hasSuccess = True elif ret == error.ERROR_EXCLUSIVE_DEPS: tmpQueue.append(item) else: opt = 'Handle' if item[0] == INSTALL: opt = 'Install' elif item[0] == REMOVE: opt = 'Remove' content = self._outputTrace(depth, '%s pkg %s failed' % (opt, item[1])) Log.cout(Log.ERROR, content) return ret if len(tmpQueue) == 0: return error.ERROR_NONE if not hasSuccess: return error.ERROR_EXCLUSIVE_DEPS pkgQueue.extend(tmpQueue) return ret
def _doFetch(self, url): socket.setdefaulttimeout(self.timeout) try: request = urllib2.Request(url) response = urllib2.urlopen(request) chunked = self._isChunked(response) content = '' if not chunked: length = int(response.info().getheader('Content-Length')) if length > self.maxFileLength: return FetchError.FETCH_TOO_LARGE, None content = response.read() else: length = 0 while True: line = response.readline(self.lineLength) if not line: break content += line length += len(line) if length > self.maxFileLength: return FetchError.FETCH_TOO_LARGE, None response.close() return FetchError.FETCH_SUCCESS, content except Exception, e: Log.cout(Log.ERROR, 'Fetch failed: %s' % e) if hasattr(e, 'reason'): if str(e.reason) == 'timed out': return FetchError.FETCH_TIMEOUT, None return FetchError.FETCH_OTHER_ERROR, None
def _killRemoteCmd(self, host, executorPath, cmdStr, remoteUser, remoteSudo): pathIndex = cmdStr.find(executorPath) if pathIndex == -1: return False rawCmd = cmdStr[pathIndex:] rawCmd = ' '.join(rawCmd.split()) Log.cout(Log.INFO, 'kill ainst2 process on the remote host %s ...' % host) cmd = 'ssh %s@%s ps -efw | grep \'%s\' | grep -v \'ssh %s@%s\' | grep -v grep'\ % (remoteUser, host, rawCmd, remoteUser, host) out, err, code = process.runRedirected(cmd, self._killTimeout) if code != 0: Log.cout(Log.ERROR, 'get remote pid failed') return False pidList = [] contentList = out.split('\n') for content in contentList: if not content or not content.strip(): continue items = content.split() pidList.append(items[1]) if not pidList: return True pidSet = set(pidList) index = 0 while index < len(pidList): subPidList = self._getSubPidList(remoteUser, host, pidList[index]) for subPid in subPidList: if subPid not in pidSet: pidList.append(subPid) pidSet.add(subPid) index += 1 return self._killRemotePid(pidList, remoteUser, host, remoteSudo)
def _check(self, pkg, context, pkgQueue, depth): Log.cout(Log.DEBUG, self._outputTrace(depth, 'check(%s)' % pkg)) ts, excludes = context.ts, context.excludes ret = error.ERROR_NONE context.checkedPkgs.add(pkg) requireDict = ResolverHelper.getAndMergeRequires(pkg) #May be need sort this require. items = self._sortRequireByName(requireDict) for name, requires in items: prvpkgs = self._getByProvides(requires, context) if pkg in prvpkgs: continue prvpkgs = ResolverHelper.filterPkgByRequires(prvpkgs, requireDict) prvpkg = self._getBestInstalledProvide(pkg, prvpkgs, context) if prvpkg is not None: ret = self._doCheck(prvpkg, context, pkgQueue, depth) if ret != error.ERROR_NONE: return ret if self._needUpgradeLocalProvide(pkg, name, prvpkg, context): self._upgradeLocalProvide(pkg, requires, prvpkgs, context, pkgQueue) continue if context.initOperation == CHECK: return error.ERROR_CHECK prvpkgs = self._filterAndSortPackages(prvpkgs, pkg) pkgQueue.append((INSTALL, pkg, requires, prvpkgs)) return error.ERROR_NONE
def iterate(self): outdegrees, depDict = dict(), dict() for package in self.preDict: prerequisites = self.preDict[package] if package not in outdegrees: outdegrees[package] = 0 for prerequisite in prerequisites: if prerequisite is not None: outdegrees[package] += 1 if prerequisite not in outdegrees: outdegrees[prerequisite] = 0 depDict.setdefault(prerequisite, set()).add(package) stack = [x for x in outdegrees if outdegrees[x] == 0] count = 0 while len(stack) > 0: package = stack.pop(0) count = count + 1 yield package for dependent in depDict.get(package, []): outdegrees[dependent] -= 1 if outdegrees[dependent] <= 0: stack.append(dependent) if count != len(outdegrees): printDegreees = dict() for pkg in outdegrees: if outdegrees[pkg] != 0: printDegreees[pkg] = outdegrees[pkg] Log.cout(Log.DEBUG, printDegreees) raise DependencyGraph.CycleDependencyException, "cycle dependent"
def readLink(path): try: if isLink(path): return os.readlink(path) except Exception, e: Log.cout(Log.DEBUG, 'readlink %s failed: %s' % (path, e)) return None
def writeToFp(fp, content): try: fp.write(content) fp.flush() except Exception, e: Log.cout(Log.DEBUG, 'Write to fp failed: %s' % e) return False
def buildMultiRootContext(self, installRoots, ainstConf, useRepo=False, repos=[]): repoSack = None if useRepo: repoSack = self._initRepos(ainstConf, repos) if repoSack is None: return None rootSack = None localSack = MultiPackageSack() for installRoot in installRoots: if installRoot == '/': rootSack = RPMDBPackageSack('/') else: sack = AinstPackageSackBuilder( installRoot).buildActivePkgSack() if sack is None: Log.cout( Log.DEBUG, 'Build active pkg sack of %s failed' % installRoot) continue localSack.addPackageSack(installRoot, sack) return AinstMultiRootContext(rootSack, localSack, repoSack)
def _onMakeCacheSuccess(self, cacheType): cachecookie = self._getRepoDataDir() + '/' + 'cachecookie' if not file_util.remove(cachecookie) or\ not file_util.writeToFile(cachecookie, '') or\ not file_util.chmod(cachecookie, 0666): Log.cout(Log.ERROR, 'Re-touch cachecookie failed') return False
def readLink(path): try: if isLink(path): return os.readlink(path) except Exception, e: Log.cout(Log.DEBUG, 'readlink %s failed: %s' % (path, e)) return None
def _doFetch(self, url): socket.setdefaulttimeout(self.timeout) try: request = urllib2.Request(url) response = urllib2.urlopen(request) chunked = self._isChunked(response) content = '' if not chunked: length = int(response.info().getheader('Content-Length')) if length > self.maxFileLength: return FetchError.FETCH_TOO_LARGE, None content = response.read() else: length = 0 while True: line = response.readline(self.lineLength) if not line: break content += line length += len(line) if length > self.maxFileLength: return FetchError.FETCH_TOO_LARGE, None response.close() return FetchError.FETCH_SUCCESS, content except Exception, e: Log.cout(Log.ERROR, 'Fetch failed: %s' % e) if hasattr(e, 'reason'): if str(e.reason) == 'timed out': return FetchError.FETCH_TIMEOUT, None return FetchError.FETCH_OTHER_ERROR, None
def writeToFp(fp, content): try: fp.write(content) fp.flush() except Exception, e: Log.cout(Log.DEBUG, 'Write to fp failed: %s' % e) return False
def _generateConfigToRoot(self, ainstPkgDir, aicfInfo, settingMap, confDict): if aicfInfo: for path, configInfo in aicfInfo.configs.iteritems(): srcConfigPath = ainstPkgDir + '/' + path destConfigPath = self._ainstRoot.getRoot() + '/' + path if not file_util.isFile(srcConfigPath): Log.cout(Log.ERROR, 'Config file %s is not exists' % srcConfigPath) return False if not file_util.exists(destConfigPath): Log.cout(Log.ERROR, 'Dest config file %s is not exists' % destConfigPath) return False tmpDirName = self._ainstRoot.getRootVarAinstDir('tmp') tmpPath = tmpDirName + '/' + os.path.basename(destConfigPath) + '.tmp.set' if not file_util.move(destConfigPath, tmpPath): Log.cout(Log.ERROR, 'Backup config file %s failed' % destConfigPath) return False confDict[path] = (tmpPath, destConfigPath) configGenerator = ConfigGenerator() if not configGenerator.generateConfig(srcConfigPath, destConfigPath, configInfo.mode, configInfo.noReplace, settingMap): Log.cout(Log.ERROR, 'Generate Config file %s failed' % path) return False else: Log.cout(Log.DEBUG, 'No aicf file, so no config will be changed') return True
def _doHandleSameProvidePkg(self, pkg, context, pkgQueue, depth): """ If installed package with same name and can not coexist, we need to remove old package. """ ts, excludes = context.ts, context.excludes for provide in pkg.provides: providers = self._getByProvide(Provide(name=provide.name), context) installedPkgs = [] for package in providers: if package is pkg: continue if not ts.installed(package): excludes.exclude(package) else: installedPkgs.append(package) for package in installedPkgs: coexists, notSatisfiedPkgs = self.coexists(pkg, provide, package, context) if coexists: continue if not self._checkSamePkgWithOption(pkg, package, context, depth): return error.ERROR_INSTALL, None ret = self._remove(package, context, pkgQueue, depth + 1) if ret != error.ERROR_NONE: logInfo = self._outputTrace(depth, 'Handle same provide between %s and %s failed' % (pkg, package)) Log.cout(Log.ERROR, logInfo) return ret, notSatisfiedPkgs self._addDependency(pkg, package, context, 'remove') return error.ERROR_NONE, None
def _generateConfigByExpand(self, srcPath, destPath, noReplace, settings): content = file_util.readFromFile(srcPath) if content is None: Log.cout(Log.ERROR, 'Read config file %s failed' % srcPath) return False replacer = KeyValueReplacer(settings) content = replacer.replace(content) return file_util.writeToFile(destPath, content)
def makeCache(self, cacheParam): repoStorage = self._getRepoStorage(self._ainstConf, cacheParam.repos) if repoStorage is None: Log.cout(Log.ERROR, 'Get repo storage failed') return OperatorRet.OPERATE_FAILED if not repoStorage.makeCache(): Log.cout(Log.ERROR, 'RepoStorage makeCache failed') return OperatorRet.OPERATE_FAILED return OperatorRet.OPERATE_SUCCESS
def _generateConfigByTemplate(self, srcPath, destPath, noReplace, settings): out, err, code = process.runRedirected(srcPath) if code != 0: Log.cout(Log.ERROR, 'Generat template config file %s failed: %s' % (destPath, err)) return False if not file_util.writeToFile(destPath, out): Log.cout(Log.ERROR, 'Write config file to %s failed' % destPath) return False return True
def _checkMetaFile(self, repoMd, metaName, fileName): metaFile = self._getRepoDataDir() + '/' + fileName if not file_util.exists(metaFile): return False if not repoMd.repoMdDatas.has_key(metaName): Log.cout(Log.ERROR, '%s not found in repomd.xml' % metaName) return False metaObj = repoMd.repoMdDatas[metaName] return self._checkSumValid(metaObj, metaFile)
def getDirNameByIndex(self, index): if not self._header: Log.cout(Log.ERROR, 'Get dir name failed') return None dirListLength = len(self._getDirs()) if index > dirListLength: Log.cout(Log.ERROR, 'Get dir name failed') return None return self._getDirs()[index]
def makeCache(self, cacheParam): repoStorage = self._getRepoStorage(self._ainstConf, cacheParam.repos) if repoStorage is None: Log.cout(Log.ERROR, 'Get repo storage failed') return OperatorRet.OPERATE_FAILED if not repoStorage.makeCache(): Log.cout(Log.ERROR, 'RepoStorage makeCache failed') return OperatorRet.OPERATE_FAILED return OperatorRet.OPERATE_SUCCESS
def rpm2dir(rpmPath, destDir, timeout=600): currentWorkdir = os.getcwd() if not file_util.isDir(destDir) and not file_util.makeDir(destDir): Log.cout(Log.ERROR, 'Make rpm dir %s failed' % destDir) return False try: os.chdir(destDir) except OSError, e: return False
def rpm2dir(rpmPath, destDir, timeout=600): currentWorkdir = os.getcwd() if not file_util.isDir(destDir) and not file_util.makeDir(destDir): Log.cout(Log.ERROR, 'Make rpm dir %s failed' % destDir) return False try: os.chdir(destDir) except OSError, e: return False
def _selectInstallPkgs(self, context, pkgs): installPkgs = [] for pkg in pkgs: installPkg = self._selectPkg(context, pkg) if installPkg == None: Log.cout(Log.ERROR, 'No packages %s available. Abort Installation.' % pkg) return None installPkgs.append(installPkg) return installPkgs
def _checkMetaFile(self, repoMd, metaName, fileName): metaFile = self._getRepoDataDir() + '/' + fileName if not file_util.exists(metaFile): return False if not repoMd.repoMdDatas.has_key(metaName): Log.cout(Log.ERROR, '%s not found in repomd.xml' % metaName) return False metaObj = repoMd.repoMdDatas[metaName] return self._checkSumValid(metaObj, metaFile)
def dump(self, rootInfo, path): content = '' for installRoot in rootInfo.installRootSet: content += installRoot + '\n' preUmask = os.umask(0) ret = file_util.writeToFile(path, content) os.umask(preUmask) if not ret: Log.cout(Log.ERROR, 'Dump to [%s] failed' % path) return ret
def writeToFile(fileName, content, flags='w', mode=0777): fout = None try: fout = open(fileName, flags, mode) fout.write(content) except Exception, e: if fout in locals(): fout.close() Log.cout(Log.DEBUG, 'Write to %s failed: %s' % (fileName, e)) return False
def _selectInstallPkgs(self, context, pkgs): installPkgs = [] for pkg in pkgs: installPkg = self._selectPkg(context, pkg) if installPkg == None: Log.cout(Log.ERROR, 'No packages %s available. Abort Installation.' % pkg) return None installPkgs.append(installPkg) return installPkgs
def listDir(dirPath): dirs = [] if not isDir(dirPath): Log.cout(Log.DEBUG, 'List dir %s failed' % dirPath) return None try: dirs = os.listdir(dirPath) except Exception, e: Log.cout(Log.DEBUG, 'List dir %s failed: %s' % (dirPath, e)) return None
def _initRepos(self, ainstConf, repos): if not ainstConf: Log.cout(Log.ERROR, "Ainst config is None") return None repoStorage = self._initRepoStorage(ainstConf) if not repoStorage: Log.cout(Log.ERROR, "Repo storage init failed") return None repoStorage.processDisableEnable(repos) return repoStorage.getPackageSack()
def _initInstallRootRepos(self, repoSack, installRoot): if installRoot == "/": return True builder = AinstPackageSackBuilder(installRoot) sack = builder.buildInstalledPkgRepoSack() if sack is None: Log.cout(Log.DEBUG, "Build install pkg sack of %s failed" % installRoot) return False repoSack.addPackageSack(self.installRootRepoPrefix + installRoot, sack) return True
def buildLocalRemoveContext(self, installRoot): if installRoot == "/": return None builder = AinstPackageSackBuilder(installRoot) sack = builder.buildInstalledPkgSack() if sack is None: Log.cout(Log.DEBUG, "Build install pkg sack of %s failed" % installRoot) return None rootSack = RPMDBPackageSack("/") return AinstContextImpl(installRoot, None, rootSack, sack)
def _getAicfInfo(self, ainstPkgDir, pkg): aicfFile = ainstPkgDir + '/ainst/' + pkg.name + '.aicf' if file_util.isFile(aicfFile): aicfInfo = AicfParser().parse(aicfFile) if not aicfInfo or not AicfInfoWrapper().removeConfigPrefix(aicfInfo) \ or not self._checkAicfInfo(aicfInfo): Log.cout(Log.ERROR, 'Aicf info of pkg %s is illegal' % pkg.name) return False, None return True, aicfInfo return True, None
def load(self, path): rootInfoDb = self._getDb(path) if not rootInfoDb: Log.cout(Log.ERROR, 'Get root info db failed') return None rootInfo = RootInfo() rootInfo.installRootSet = set(rootInfoDb.getKeys()) rootInfoDb.close() return rootInfo
def load(self, path): rootInfoDb = self._getDb(path) if not rootInfoDb: Log.cout(Log.ERROR, 'Get root info db failed') return None rootInfo = RootInfo() rootInfo.installRootSet = set(rootInfoDb.getKeys()) rootInfoDb.close() return rootInfo
def dump(self, rootInfo, path): content = '' for installRoot in rootInfo.installRootSet: content += installRoot + '\n' preUmask = os.umask(0) ret = file_util.writeToFile(path, content) os.umask(preUmask) if not ret: Log.cout(Log.ERROR, 'Dump to [%s] failed' % path) return ret
def listDir(dirPath): dirs = [] if not isDir(dirPath): Log.cout(Log.DEBUG, 'List dir %s failed' % dirPath) return None try: dirs = os.listdir(dirPath) except Exception, e: Log.cout(Log.DEBUG, 'List dir %s failed: %s' % (dirPath, e)) return None
def _checkAicfInfo(self, aicfInfo): if not aicfInfo: return False for config in aicfInfo.configs.values(): items = config.destPath.split('/') if len(items) < 2 or not self._ainstRoot.isInRootDir(items[0]): Log.cout(Log.ERROR, 'Invalid file path %s' % config.destPath) return False return True
def writeToFile(fileName, content, flags='w', mode=0777): fout = None try: fout = open(fileName, flags, mode) fout.write(content) except Exception, e: if fout in locals(): fout.close() Log.cout(Log.DEBUG, 'Write to %s failed: %s' % (fileName, e)) return False
def _initRepos(self, ainstConf, repos): if not ainstConf: Log.cout(Log.ERROR, 'Ainst config is None') return None repoStorage = self._initRepoStorage(ainstConf) if not repoStorage: Log.cout(Log.ERROR, 'Repo storage init failed') return None repoStorage.processDisableEnable(repos) return repoStorage.getPackageSack()
def _checkAicfInfo(self, aicfInfo): if not aicfInfo: return False for config in aicfInfo.configs.values(): items = config.destPath.split('/') if len(items) < 2 or not self._ainstRoot.isInRootDir(items[0]): Log.cout(Log.ERROR, 'Invalid file path %s' % config.destPath) return False return True
def fetch(self, srcUrl, destFile): content = '' for i in range(self.tryTimes): ret, content = self._doFetch(srcUrl) if ret != FetchError.FETCH_TIMEOUT: break if ret != FetchError.FETCH_SUCCESS: err = FetchError.getErrorString(ret) Log.cout(Log.ERROR, 'Fetch [%s] failed: %s' % (srcUrl, err)) return False return file_util.writeToFile(destFile, content)
def fetch(self, srcUrl, destFile): content = '' for i in range(self.tryTimes): ret, content = self._doFetch(srcUrl) if ret != FetchError.FETCH_TIMEOUT: break if ret != FetchError.FETCH_SUCCESS: err = FetchError.getErrorString(ret) Log.cout(Log.ERROR, 'Fetch [%s] failed: %s' % (srcUrl, err)) return False return file_util.writeToFile(destFile, content)
def remove(path): try: if isLink(path): os.remove(path) elif isFile(path) and exists(path): os.remove(path) elif isDir(path): shutil.rmtree(path) except Exception, e: Log.cout(Log.DEBUG, 'Remove %s failed: %s' % (path, e)) return False
def _processScriptByName(self, scriptName): if not self._noExecute and self._aicfInfo and \ self._aicfInfo.scripts.has_key(scriptName): scriptContent = self._aicfInfo.scripts[scriptName] self._exportToEnv(self._ainstPathEnv) ret = self._processScript(scriptContent) self._removeFromEnv(self._ainstPathEnv) if not ret: Log.cout(Log.ERROR, 'Process %s script failed' % scriptName) return False return True
def _initInstallRootRepos(self, repoSack, installRoot): if installRoot == '/': return True builder = AinstPackageSackBuilder(installRoot) sack = builder.buildInstalledPkgRepoSack() if sack is None: Log.cout(Log.DEBUG, 'Build install pkg sack of %s failed' % installRoot) return False repoSack.addPackageSack(self.installRootRepoPrefix + installRoot, sack) return True
def moveAllSubDir(src, dest): try: if not isDir(src): return False ret = os.listdir(src) for subDir in ret: if not move(src + '/' + subDir, dest + '/' + subDir): return False except Exception, e: Log.cout(Log.DEBUG, 'Move all subdir from %s to %s failed: %s' % (src, dest, e)) return False
def buildLocalRemoveContext(self, installRoot): if installRoot == '/': return None builder = AinstPackageSackBuilder(installRoot) sack = builder.buildInstalledPkgSack() if sack is None: Log.cout(Log.DEBUG, 'Build install pkg sack of %s failed' % installRoot) return None rootSack = RPMDBPackageSack('/') return AinstContextImpl(installRoot, None, rootSack, sack)
def _processScriptByName(self, scriptName): if not self._noExecute and self._aicfInfo and \ self._aicfInfo.scripts.has_key(scriptName): scriptContent = self._aicfInfo.scripts[scriptName] self._exportToEnv(self._ainstPathEnv) ret = self._processScript(scriptContent) self._removeFromEnv(self._ainstPathEnv) if not ret: Log.cout(Log.ERROR, 'Process %s script failed' % scriptName) return False return True