def _getScriptContent(self, action): pkgDirName = PackageUtil.getPkgNameVersion(self._pkg) if not pkgDirName: Log.cout(Log.ERROR, 'Get pkg %s dir name failed' % self._pkg) return None self._ainstActivePkg = self._ainstRoot.getRootVarAinstDir('active') + self._pkg.name if not self._isActive(self._ainstActivePkg, pkgDirName): Log.cout(Log.ERROR, 'Package %s is not active' % self._pkg) return None self._ainstPkgDir = self._ainstRoot.getRootVarAinstDir('packages') + pkgDirName aicfFile = self._ainstPkgDir + '/ainst/' + self._pkg.name + '.aicf' if not file_util.isFile(aicfFile): return None 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' % self._pkg) return None if not aicfInfo.scripts.has_key(action): Log.cout(Log.ERROR, 'Pkg %s has no %s script' % (self._pkg, action)) return None return aicfInfo.scripts[action]
def init(self): if self._inited: return True, None if not self._root: return False, None markFilePath = self._root + '/' + self._ainstRootMarkFile initTrace = [] if not file_util.isDir(self._root): if not file_util.makeDir(self._root): self.clearInit(initTrace) return False, None initTrace.append(self._root) if not file_util.writeToFile(markFilePath, ''): self.clearInit(initTrace) return False, None initTrace.append(markFilePath) else: if not file_util.isFile(markFilePath): subDirs = file_util.listDir(self._root) if subDirs and len(subDirs) > 0: self.clearInit(initTrace) return False, None if not file_util.writeToFile(markFilePath, ''): self.clearInit(initTrace) return False, None initTrace.append(markFilePath) if not self._initRoot(initTrace): return False, None os.environ[self._installRootEnvKey] = self._root self._inited = True return True, initTrace
def _recoverSettings(self): if not self._tmpSettingPath: return True if not file_util.isFile(self._tmpSettingPath) or\ not file_util.move(self._tmpSettingPath, self._settingPath): return False return True
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 _generateConfigToRoot(self, rpmFileInfoList, aicfInfo, settingMap, confSet): configGenerator = ConfigGenerator() if aicfInfo: for path, configInfo in aicfInfo.configs.iteritems(): srcConfigPath = self._ainstPkgDir + '/' + path destConfigPath = self._ainstRoot.getRoot() + '/' + path if not file_util.isFile(srcConfigPath): Log.cout( Log.ERROR, 'Config file %s is not exists in pkg' % srcConfigPath) return False if not file_util.remove(destConfigPath): Log.cout(Log.ERROR, 'Remove path %s failed in pkg' % destConfigPath) return False if not configGenerator.generateConfig( srcConfigPath, destConfigPath, configInfo.mode, configInfo.noReplace, settingMap): Log.cout(Log.ERROR, 'Generate Config file %s failed' % path) return False confSet.add(path) for rpmFileInfo in rpmFileInfoList: if rpmFileInfo.isConfigFile(): path = rpmFileInfo.relativePath if path in confSet: continue srcConfigPath = self._ainstPkgDir + '/' + path destConfigPath = self._ainstRoot.getRoot() + '/' + path if not file_util.isFile(srcConfigPath): Log.cout( Log.ERROR, 'Config file %s is not exists in pkg' % srcConfigPath) return False if not configGenerator.generateConfig(srcConfigPath, destConfigPath): Log.cout(Log.ERROR, 'Generate Config file %s failed' % path) return False confSet.add(path) return True
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 _removeSettings(self): if not file_util.isFile(self._settingPath): return True tmpPath = self._ainstRoot.getRootVarAinstDir('tmp') +\ self._pkg.name + self._settingTmpSuffix if not file_util.remove(tmpPath) or\ not file_util.move(self._settingPath, tmpPath): return False self._tmpSettingPath = tmpPath return True
def _unlinkPkgFromRoot(self, rpmFileInfoList, unlinkList, rmdirList, confDict): if self._aicfInfo: for path in self._aicfInfo.configs.keys(): destConfigPath = self._ainstRoot.getRoot() + '/' + path if file_util.isFile(destConfigPath): tmpDirName = self._ainstRoot.getRootVarAinstDir('tmp') tmpPath = tmpDirName + '/' + os.path.basename(destConfigPath) + '.tmp' if not file_util.move(destConfigPath, tmpPath): return False confDict[path] = (tmpPath, destConfigPath) dirName = os.path.dirname(destConfigPath) + '/' if not self._removeDir(dirName, rmdirList): return False for rpmFileInfo in rpmFileInfoList: srcPath = self._ainstPkgDir + '/' + rpmFileInfo.relativePath destPath = self._ainstRoot.getRoot() + '/' + rpmFileInfo.relativePath if rpmFileInfo.isDir: if not self._removeDir(destPath, rmdirList, False): return False elif not rpmFileInfo.isConfigFile(): if not file_util.remove(destPath): return False unlinkList.append((srcPath, destPath)) if not self._removeDir(os.path.dirname(destPath) + '/', rmdirList): return False else: if confDict.has_key(rpmFileInfo.relativePath): continue if file_util.isFile(destPath): dirName = self._ainstRoot.getRootVarAinstDir('tmp') tmpPath = dirName + os.path.basename(destPath) + '.tmp' if not file_util.move(destPath, tmpPath): return False confDict[rpmFileInfo.relativePath] = (tmpPath, destPath) if not self._removeDir(os.path.dirname(destPath) + '/', rmdirList): return False return True
def load(self, path): if not file_util.isFile(path): Log.cout(Log.DEBUG, 'Root info file %s is not exists' % path) return RootInfo() content = file_util.readFromFile(path) if content is None: Log.cout(Log.ERROR, 'Read root info file %s failed' % path) return None rootInfo = RootInfo() lines = content.split('\n') for line in lines: line = line.strip() if line == '': continue rootInfo.installRootSet.add(line) return rootInfo
def buildActivePkgSack(self): sack = PackageSack() ainstRoot = AinstRoot(self._installRoot) if not ainstRoot.isValidAinstRoot(): Log.cout(Log.DEBUG, '%s is invalid ainst root' % self._installRoot) return None reader = AinstRootReader(ainstRoot) activePkgMetas = reader.getActivePkgMetas() if activePkgMetas is None: Log.cout(Log.DEBUG, 'Get active meta of %s failed' % self._installRoot) return None for pkgName, rpmPath, aicfPath in activePkgMetas: aicfInfo = None if file_util.isFile(aicfPath): aicfInfo = AicfParser().parse(aicfPath) header = rpmutils.readRpmHeader(rpmPath) if header: repo = FakeRepository(self._installRoot, True) pkg = AinstRpmPackage(header, repo, aicfInfo) sack.addPackageObject(pkg) return sack
def checkRoot(self): if not self._root: return False if not file_util.isFile(self._root + '/' + self._ainstRootMarkFile): return False for name in self._rootDirs: if not file_util.isDir(self._rootDirs[name]): return False for name in self._rootVarDirs: if not file_util.isDir(self._rootVarDirs[name]): return False for name in self._rootVarAinstDirs: if not file_util.isDir(self._rootVarAinstDirs[name]): return False initRootState = self._rootVarAinstDirs['save'] + 'root-state-0' if not file_util.exists(initRootState): return False os.environ[self._installRootEnvKey] = self._root return True
def convert(self, rpmFilePath): if not file_util.isFile(rpmFilePath): Log.cout(Log.ERROR, 'Rpm file [%s] not existed' % rpmFilePath) return None rpmHeader = rpmutils.readRpmHeader(rpmFilePath) if rpmHeader is None: Log.cout(Log.ERROR, 'Read rpm header failed: [%s]' % rpmFilePath) return None rpmHeaderReader = RpmHeaderReader(rpmHeader) fileList = rpmHeaderReader.getFiles() rpmFileInfoList = [] if len(fileList) == 0: Log.cout(Log.INFO, 'Rpm filelist has no file') return rpmFileInfoList firstPath = rpmHeaderReader.getDirNameByIndex(fileList[0][2]) + fileList[0][1] if stat.S_ISDIR(fileList[0][3]): firstPath += '/' for fileObj in fileList: dirName = rpmHeaderReader.getDirNameByIndex(fileObj[2]) path = dirName + fileObj[1] isDir = stat.S_ISDIR(fileObj[3]) if isDir: path = path + '/' if not path.startswith('/'): Log.cout(Log.ERROR, 'Rpm file has illegal prefix: %s' % path) return None path = path[len('/'):] if (path == '' or path.startswith('ainst/') or path.startswith('usr/ainst/') or path.startswith('usr/local/ainst/')): continue rpmFileInfo = RpmFileInfo(fileObj[1], isDir, path, fileObj[0]) rpmFileInfoList.append(rpmFileInfo) return rpmFileInfoList
def execute(self): Log.cout(Log.INFO, 'Deactivate pkg %s ...' % self._pkg) if self._dryrun: return True if self._executed: return False self._executed = True if not self._ainstRoot.checkRoot(): Log.cout(Log.ERROR, 'Check ainst root failed') return False pkgDirName = PackageUtil.getPkgNameVersion(self._pkg) if not pkgDirName: Log.cout(Log.ERROR, 'Get pkg %s dir name failed' % self._pkg) return False self._ainstActivePkg = self._ainstRoot.getRootVarAinstDir('active') + self._pkg.name self._ainstPkgDir = self._ainstRoot.getRootVarAinstDir('packages') + pkgDirName if not self._isActive(self._ainstActivePkg, pkgDirName): Log.cout(Log.INFO, 'Package %s is always deactive' % self._pkg) return True ainstDirPath = self._ainstPkgDir + '/ainst/' self._ainstPathEnv = {self._ainstDirKey : ainstDirPath} aicfFile = ainstDirPath + self._pkg.name + '.aicf' if file_util.isFile(aicfFile): self._aicfInfo = AicfParser().parse(aicfFile) if not self._aicfInfo or not AicfInfoWrapper().removeConfigPrefix(self._aicfInfo) \ or not self._checkAicfInfo(self._aicfInfo): Log.cout(Log.ERROR, 'Aicf info of pkg %s is illegal' % self._pkg) return False #calc settings settingPath = self._ainstRoot.getRootVarAinstDir('settings') + self._pkg.name settings = SettingStreamer().parse(settingPath) if settings is None: Log.cout(Log.ERROR, 'Parse settings of pkg %s failed' % self._pkg) return False useSettings = self._mergeSettings(settings, self._cliSettings) self._settingsEnv = self._generateSettingsEnv(useSettings) self._processStopScript() if not self._processScriptByName('pre-deactivate'): self.undo() return False #get rpm file infos bakRpmFile = self._ainstPkgDir + self._ainstRoot.getBackRpmPath() rpmFileInfoList = RpmFileWrapper().convert(bakRpmFile) if rpmFileInfoList is None: Log.cout(Log.ERROR, 'Get rpm file info failed: %s', bakRpmFile) self.undo() return False ret, self._lastActivePkg = self._unSymlinkFromActive(self._ainstActivePkg) if not ret: Log.cout(Log.ERROR, 'UnsymLink pkg %s dir from active failed' % self._pkg) self.undo() return False if not self._unlinkPkgFromRoot(rpmFileInfoList, self._unlinkList, self._rmdirList, self._confDict): Log.cout(Log.ERROR, 'Unink pkg %s dir from root failed' % self._pkg) self.undo() return False if not self._removeCrontabFile(): Log.cout(Log.ERROR, 'Remove crontab file of pkg %s failed' % self._pkg) self.undo() return False self._modifyDb = self._removeFileFromDb() if not self._modifyDb: Log.cout(Log.ERROR, 'Modify db failed') self.undo() return False if not self._processScriptByName('post-deactivate'): self.undo() return False self._success = True Log.cout(Log.DEBUG, 'Deactivate pkg %s success' % self._pkg) return True
def execute(self): Log.cout(Log.INFO, 'Activate pkg %s ...' % self._pkg) if self._dryrun: return True if self._executed: return False self._executed = True if not self._ainstRoot.checkRoot(): Log.cout(Log.ERROR, 'Check ainst root failed') return False pkgDirName = PackageUtil.getPkgNameVersion(self._pkg) if not pkgDirName: Log.cout(Log.ERROR, 'Get pkg %s dir name failed' % self._pkg) return False #get active dir and package dir self._ainstActivePkg = self._ainstRoot.getRootVarAinstDir( 'active') + self._pkg.name if self._isActive(self._ainstActivePkg, pkgDirName): Log.cout(Log.INFO, 'Package %s is always active' % self._pkg) return True self._ainstPkgDir = self._ainstRoot.getRootVarAinstDir( 'packages') + pkgDirName if not file_util.isDir(self._ainstPkgDir): Log.cout(Log.ERROR, 'Package %s is not installed' % self._pkg) return False #get aicf info ainstDirPath = self._ainstPkgDir + '/ainst/' self._ainstPathEnv = {self._ainstDirKey: ainstDirPath} aicfFile = ainstDirPath + self._pkg.name + '.aicf' if file_util.isFile(aicfFile): self._aicfInfo = AicfParser().parse(aicfFile) if not self._aicfInfo or not AicfInfoWrapper().removeConfigPrefix(self._aicfInfo) \ or not self._checkAicfInfo(self._aicfInfo): Log.cout(Log.ERROR, 'Aicf info of pkg %s is illegal' % self._pkg) return False #calc settings settingPath = self._ainstRoot.getRootVarAinstDir( 'settings') + self._pkg.name backSettings = SettingStreamer().parse(settingPath) if backSettings is None: Log.cout(Log.ERROR, 'Parse settings of pkg %s failed' % self._pkg) return False useSettings = {} useSettings.update(backSettings) self._mergeSettings(useSettings, self._aicfInfo, self._cliSettings, self._unsetKeySet) self._settingsEnv = self._generateSettingsEnv(useSettings) #get rpm file infos bakRpmFile = self._ainstPkgDir + self._ainstRoot.getBackRpmPath() rpmFileInfoList = RpmFileWrapper().convert(bakRpmFile) if rpmFileInfoList is None: Log.cout(Log.ERROR, 'Get rpm file info failed: %s', bakRpmFile) return False if not self._processScriptByName('pre-activate'): return False #link common files and makedir if needed if not self._linkPkgToRoot(rpmFileInfoList, self._linkList, self._mkdirList): Log.cout(Log.ERROR, 'Link pkg %s dir to root failed' % self._pkg) self.undo() return False #generate a new config file and copy to root dir self._exportToEnv(self._ainstPathEnv) self._exportToEnv(self._settingsEnv) settingMap = {} settingMap.update(useSettings) settingMap[self._ainstRoot.getInstallRootEnvKey( )] = self._ainstRoot.getRoot() settingMap.update(self._ainstPathEnv) ret = self._generateConfigToRoot(rpmFileInfoList, self._aicfInfo, settingMap, self._confSet) self._removeFromEnv(self._settingsEnv) self._removeFromEnv(self._ainstPathEnv) if not ret: Log.cout(Log.ERROR, 'Generate config of pkg %s failed' % self._pkg) self.undo() return False #seralize to setting files if len(useSettings) > 0: if not SettingStreamer().dump(useSettings, settingPath): Log.cout(Log.ERROR, 'Save settings of pkg %s failed' % self._pkg) self.undo() return False self._backSettings = backSettings self._modifyDb = self._addFileToDb() if not self._modifyDb: Log.cout(Log.ERROR, 'Modify db failed') self.undo() return False if not self._generateCrontabFile(): Log.cout(Log.ERROR, 'Generate crontab failed') self.undo() return False #do symbol link from package dir to active dir relativePkgPath = self._getActiveRelativePath(pkgDirName) self._linkToActive, self._lastActivePkg = self._symLinkToActive( relativePkgPath, self._ainstActivePkg) if not self._linkToActive: Log.cout(Log.ERROR, 'SymLink pkg %s dir to active failed' % self._pkg) self.undo() return False if not self._processScriptByName('post-activate'): self.undo() return False self._processStartScript(useSettings) self._success = True Log.cout(Log.DEBUG, 'Activate pkg %s success' % self._pkg) return True
def isValidAinstRoot(self): return file_util.isFile(self._root + '/' + self._ainstRootMarkFile)