def processPkgs(self, dlpkgs): """Apply the available updates. :param dlpkgs: a list of package objecs to update """ for po in dlpkgs: result, err = self.updd.sigCheckPkg(po) if result == 0: continue elif result == 1: try: self.updd.getKeyForPackage(po) except yum.Errors.YumBaseError as errmsg: self.failed([str(errmsg)]) del self.updd.ts self.updd.initActionTs() # make a new, blank ts to populate self.updd.populateTs(keepold=0) self.updd.ts.check() #required for ordering self.updd.ts.order() # order cb = callback.RPMInstallCallback(output=0) cb.filelog = True cb.tsInfo = self.updd.tsInfo try: self.updd.runTransaction(cb=cb) except yum.Errors.YumBaseError as err: self.failed([str(err)]) self.success()
def installUpdates(self, emit): """Apply the available updates. :param emit: Boolean indicating whether to emit messages about the installation """ # Emit a message that if emit: self.emitInstalling() dlpkgs = [ x.po for x in [ txmbr for txmbr in self.tsInfo.getMembers() if txmbr.ts_state in ("i", "u") ] ] for po in dlpkgs: result, err = self.sigCheckPkg(po) if result == 0: continue elif result == 1: try: self.getKeyForPackage(po) except yum.Errors.YumBaseError as errmsg: self.emitUpdateFailed(errmsg) return False else: self.emitUpdateFailed(err) return False del self.ts self.initActionTs() # make a new, blank ts to populate self.populateTs(keepold=0) self.ts.check() #required for ordering self.ts.order() # order cb = callback.RPMInstallCallback(output=0) cb.filelog = True cb.tsInfo = self.tsInfo try: self.runTransaction(cb=cb) except yum.Errors.YumBaseError as err: self.emitUpdateFailed(err) sys.exit(1) if emit: self.emitInstalled() self.emitMessages()
def doTransaction(self): """takes care of package downloading, checking, user confirmation and actually RUNNING the transaction""" #allow downgrades to support rollbacks self.tsInfo.probFilterFlags.append(RPMPROB_FILTER_OLDPACKAGE) # Check which packages have to be downloaded downloadpkgs = [] do_erase = False for txmbr in self.tsInfo.getMembers(): if txmbr.ts_state in ['i', 'u']: po = txmbr.po if po: downloadpkgs.append(po) elif txmbr.ts_state in ['e']: do_erase = True log.log_debug('Downloading Packages:') problems = self.downloadPkgs(downloadpkgs) if len(problems.keys()) > 0: errstring = '' errstring += 'Error Downloading Packages:\n' for key in problems.keys(): errors = yum.misc.unique(problems[key]) for error in errors: errstring += ' %s: %s\n' % (key, error) raise yum.Errors.YumBaseError, errstring if self.cfg['retrieveOnly']: # We are configured to only download packages (rather than install/update) # # If all we were asked to do was install/update, skip rest of transaction # and return now. # # If all we were asked to do was remove packages, process the transaction. # # If we were asked to do a mixture of install/erase - then we can't do a # complete transaction, and we have to FAIL, rather than execute or show a # success. # if downloadpkgs and do_erase: # FAIL err = 'Mix of install/erase and "retrieveOnly" set - transaction FAILS' log.log_debug(err) raise yumErrors.YumBaseError, err elif downloadpkgs and not do_erase: # download and exit log.log_debug( 'Configured to "retrieveOnly" so skipping package install') return 0 else: # erase-only, continue log.log_debug( 'Configured to "retrieveOnly" but only erase-commands - continuing' ) if self.cache_only: log.log_debug( 'Just pre-caching packages, skipping package install') return 0 # Check GPG signatures if self.gpgsigcheck(downloadpkgs) != 0: return 1 log.log_debug('Running Transaction Test') tsConf = {} for feature in ['diskspacecheck']: # more to come, I'm sure tsConf[feature] = getattr(self.conf, feature) # clean out the ts b/c we have to give it new paths to the rpms del self.ts self.initActionTs() # save our dsCallback out testcb = callback.RPMInstallCallback(output=0) testcb.tsInfo = self.tsInfo dscb = self.dsCallback self.dsCallback = None # dumb, dumb dumb dumb! self.populateTs(keepold=0) # sigh tserrors = self.ts.test(testcb, conf=tsConf) log.log_debug('Finished Transaction Test') if len(tserrors) > 0: errstring = 'Transaction Check Error: ' for descr in tserrors: errstring += ' %s\n' % descr raise yum.Errors.YumBaseError, errstring log.log_debug('Transaction Test Succeeded') del self.ts self.initActionTs() # make a new, blank ts to populate self.populateTs(keepold=0) # populate the ts self.ts.check() #required for ordering self.ts.order() # order # put back our depcheck callback self.dsCallback = dscb log.log_debug('Running Transaction') self.runTransaction(testcb) # close things return 0
class LiveCDYum(yum.YumBase): def __init__(self, releasever=None): """ releasever = optional value to use in replacing $releasever in repos """ yum.YumBase.__init__(self) self.releasever = releasever def doFileLogSetup(self, uid, logfile): # don't do the file log for the livecd as it can lead to open fds # being left and an inability to clean up after ourself pass def close(self): try: os.unlink(self.conf.installroot + "/yum.conf") except: pass yum.YumBase.close(self) def __del__(self): pass def _writeConf(self, confpath, installroot): conf = "[main]\n" conf += "installroot=%s\n" % installroot conf += "cachedir=/var/cache/yum\n" conf += "plugins=0\n" conf += "reposdir=\n" conf += "failovermethod=priority\n" conf += "keepcache=1\n" f = file(confpath, "w+") f.write(conf) f.close() os.chmod(confpath, 0644) def _cleanupRpmdbLocks(self, installroot): # cleans up temporary files left by bdb so that differing # versions of rpm don't cause problems for f in glob.glob(installroot + "/var/lib/rpm/__db*"): os.unlink(f) def setup(self, confpath, installroot): self._writeConf(confpath, installroot) self._cleanupRpmdbLocks(installroot) self.doConfigSetup(fn=confpath, root=installroot) self.conf.cache = 0 self.doTsSetup() self.doRpmDBSetup() self.doRepoSetup() self.doSackSetup() def selectPackage(self, pkg): """Select a given package. Can be specified with name.arch or name*""" return self.install(pattern=pkg) def deselectPackage(self, pkg): """Deselect package. Can be specified as name.arch or name*""" sp = pkg.rsplit(".", 2) txmbrs = [] if len(sp) == 2: txmbrs = self.tsInfo.matchNaevr(name=sp[0], arch=sp[1]) if len(txmbrs) == 0: exact, match, unmatch = yum.packages.parsePackages( self.pkgSack.returnPackages(), [pkg], casematch=1) for p in exact + match: txmbrs.append(p) if len(txmbrs) > 0: for x in txmbrs: self.tsInfo.remove(x.pkgtup) # we also need to remove from the conditionals # dict so that things don't get pulled back in as a result # of them. yes, this is ugly. conditionals should die. for req, pkgs in self.tsInfo.conditionals.iteritems(): if x in pkgs: pkgs.remove(x) self.tsInfo.conditionals[req] = pkgs else: logging.warn("No such package %s to remove" % (pkg, )) def selectGroup(self, grp, include=pykickstart.parser.GROUP_DEFAULT): # default to getting mandatory and default packages from a group # unless we have specific options from kickstart package_types = ['mandatory', 'default'] if include == pykickstart.parser.GROUP_REQUIRED: package_types.remove('default') elif include == pykickstart.parser.GROUP_ALL: package_types.append('optional') yum.YumBase.selectGroup(self, grp, group_package_types=package_types) def addRepository(self, name, url=None, mirrorlist=None): def _varSubstitute(option): # takes a variable and substitutes like yum configs do option = option.replace("$basearch", rpmUtils.arch.getBaseArch()) option = option.replace("$arch", rpmUtils.arch.getCanonArch()) # If the url includes $releasever substitute user's value or # current system's version. if option.find("$releasever") > -1: if self.releasever: option = option.replace("$releasever", self.releasever) else: try: option = option.replace( "$releasever", yum.config._getsysver("/", "redhat-release")) except yum.Errors.YumBaseError: raise CreatorError( "$releasever in repo url, but no releasever set") return option repo = yum.yumRepo.YumRepository(name) if url: repo.baseurl.append(_varSubstitute(url)) if mirrorlist: repo.mirrorlist = _varSubstitute(mirrorlist) conf = yum.config.RepoConf() for k, v in conf.iteritems(): if v or not hasattr(repo, k): repo.setAttribute(k, v) repo.basecachedir = self.conf.cachedir repo.failovermethod = "priority" repo.metadata_expire = 0 repo.mirrorlist_expire = 0 repo.timestamp_check = 0 # disable gpg check??? repo.gpgcheck = 0 repo.enable() repo.setup(0) repo.setCallback(TextProgress()) self.repos.add(repo) return repo def installHasFile(self, file): provides_pkg = self.whatProvides(file, None, None) dlpkgs = map( lambda x: x.po, filter(lambda txmbr: txmbr.ts_state in ("i", "u"), self.tsInfo.getMembers())) for p in dlpkgs: for q in provides_pkg: if (p == q): return True return False def runInstall(self): os.environ["HOME"] = "/" try: (res, resmsg) = self.buildTransaction() except yum.Errors.RepoError, e: raise CreatorError("Unable to download from repo : %s" % (e, )) # Empty transactions are generally fine, we might be rebuilding an # existing image with no packages added if resmsg and resmsg[0].endswith(" - empty transaction"): return res if res != 2: raise CreatorError("Failed to build transaction : %s" % str.join("\n", resmsg)) dlpkgs = map( lambda x: x.po, filter(lambda txmbr: txmbr.ts_state in ("i", "u"), self.tsInfo.getMembers())) self.downloadPkgs(dlpkgs) # FIXME: sigcheck? self.initActionTs() self.populateTs(keepold=0) deps = self.ts.check() if len(deps) != 0: raise CreatorError("Dependency check failed!") rc = self.ts.order() if rc != 0: raise CreatorError("ordering packages for installation failed!") # FIXME: callback should be refactored a little in yum sys.path.append('/usr/share/yum-cli') import yum.misc yum.misc.setup_locale() import callback cb = callback.RPMInstallCallback() cb.tsInfo = self.tsInfo cb.filelog = False ret = self.runTransaction(cb) print "" self._cleanupRpmdbLocks(self.conf.installroot) return ret
def doTransaction(self): """takes care of package downloading, checking, user confirmation and actually RUNNING the transaction""" #allow downgrades to support rollbacks self.tsInfo.probFilterFlags.append(RPMPROB_FILTER_OLDPACKAGE) # Check which packages have to be downloaded downloadpkgs = [] for txmbr in self.tsInfo.getMembers(): if txmbr.ts_state in ['i', 'u']: po = txmbr.po if po: downloadpkgs.append(po) log.log_debug('Downloading Packages:') problems = self.downloadPkgs(downloadpkgs) if len(problems.keys()) > 0: errstring = '' errstring += 'Error Downloading Packages:\n' for key in problems.keys(): errors = yum.misc.unique(problems[key]) for error in errors: errstring += ' %s: %s\n' % (key, error) raise yum.Errors.YumBaseError, errstring if self.cfg['retrieveOnly']: # We are configured to only download packages, so # skip rest of transaction work and return now. log.log_debug( 'Configured to "retrieveOnly" so skipping package install') return 0 if self.cache_only: log.log_debug( 'Just pre-caching packages, skipping package install') return 0 # Check GPG signatures if self.gpgsigcheck(downloadpkgs) != 0: return 1 log.log_debug('Running Transaction Test') tsConf = {} for feature in ['diskspacecheck']: # more to come, I'm sure tsConf[feature] = getattr(self.conf, feature) # clean out the ts b/c we have to give it new paths to the rpms del self.ts self.initActionTs() # save our dsCallback out testcb = callback.RPMInstallCallback(output=0) testcb.tsInfo = self.tsInfo dscb = self.dsCallback self.dsCallback = None # dumb, dumb dumb dumb! self.populateTs(keepold=0) # sigh tserrors = self.ts.test(testcb, conf=tsConf) log.log_debug('Finished Transaction Test') if len(tserrors) > 0: errstring = 'Transaction Check Error: ' for descr in tserrors: errstring += ' %s\n' % descr raise yum.Errors.YumBaseError, errstring log.log_debug('Transaction Test Succeeded') del self.ts self.initActionTs() # make a new, blank ts to populate self.populateTs(keepold=0) # populate the ts self.ts.check() #required for ordering self.ts.order() # order # put back our depcheck callback self.dsCallback = dscb log.log_debug('Running Transaction') self.runTransaction(testcb) # close things return 0
elif result == 1: try: self.getKeyForPackage(po) except yum.Errors.YumBaseError, errmsg: self.emitUpdateFailed(errmsg) return False else: self.emitUpdateFailed(err) return False del self.ts self.initActionTs() # make a new, blank ts to populate self.populateTs(keepold=0) self.ts.check() #required for ordering self.ts.order() # order cb = callback.RPMInstallCallback(output=0) cb.filelog = True cb.tsInfo = self.tsInfo try: self.runTransaction(cb=cb) except yum.Errors.YumBaseError, err: self.emitUpdateFailed(err) sys.exit(1) if emit: self.emitInstalled() self.emitMessages() def updatesCheck(self): """Check to see whether updates are available for any