def _shutdownOutputLogging(self): # reset rpm bits from reording output rpm.setVerbosity(rpm.RPMLOG_NOTICE) rpm.setLogFile(sys.stderr) try: self._writepipe.close() except: pass
def __enter__(self): for handler in rpm_logger.handlers: if isinstance(handler, logging.FileHandler): rpm.setLogFile(handler.stream) break else: self.sink = open('/dev/null', 'w') rpm.setLogFile(self.sink)
def closepipe(self): log.debug("closing log pipe") rpm.setVerbosity(rpm.RPMLOG_WARNING) rpm.setLogFile(None) if self.ts: self.ts.scriptFd = None self.logpipe.close() os.remove(self.logpipe.name) self.logpipe = None
def openpipe(self): log.debug("creating log pipe") pipefile = tempfile.mktemp(prefix='rpm-log-pipe.') os.mkfifo(pipefile, 0600) log.debug("starting logging thread") pipethread = Thread(target=pipelogger, name='pipelogger', args=(pipefile,)) pipethread.daemon = True pipethread.start() log.debug("opening log pipe") pipe = open(pipefile, 'w') rpm.setLogFile(pipe) return pipe
def _setupOutputLogging(self, rpmverbosity="info"): # UGLY... set up the transaction to record output from scriptlets io_r = tempfile.NamedTemporaryFile() self._readpipe = io_r self._writepipe = open(io_r.name, 'w+b') self.base.ts.setScriptFd(self._writepipe) rpmverbosity = {'critical' : 'crit', 'emergency' : 'emerg', 'error' : 'err', 'information' : 'info', 'warn' : 'warning'}.get(rpmverbosity, rpmverbosity) rpmverbosity = 'RPMLOG_' + rpmverbosity.upper() if not hasattr(rpm, rpmverbosity): rpmverbosity = 'RPMLOG_INFO' rpm.setVerbosity(getattr(rpm, rpmverbosity)) rpm.setLogFile(self._writepipe)
def parse_spec(spec_file): """Simple wrapper around rpm.spec that catches errors printed to stdout :param spec_file: spec file name :returns: rpm.spec object instance :raises: ValueError in case parsing failed """ with NamedTemporaryFile(mode="w+") as tmplog: # rpm will print errors to stdout if logfile is not set rpm.setLogFile(tmplog) try: rpm.spec(spec_file) except ValueError as exc: # re-raise errors with rpm output appended to message raise ValueError(str(exc) + open(tmplog.name, 'r').read())
def _setupOutputLogging(self, rpmverbosity="info"): # UGLY... set up the transaction to record output from scriptlets io_r = tempfile.NamedTemporaryFile() self._readpipe = io_r self._writepipe = open(io_r.name, "w+b") self.base.ts.setScriptFd(self._writepipe) rpmverbosity = { "critical": "crit", "emergency": "emerg", "error": "err", "information": "info", "warn": "warning", }.get(rpmverbosity, rpmverbosity) rpmverbosity = "RPMLOG_" + rpmverbosity.upper() if not hasattr(rpm, rpmverbosity): rpmverbosity = "RPMLOG_INFO" rpm.setVerbosity(getattr(rpm, rpmverbosity)) rpm.setLogFile(self._writepipe)
def parse_spec(spec_file, keep_config=False): """Simple wrapper around rpm.spec that catches errors printed to stdout :param spec_file: spec file name :param keep_config: If set to True, does not call rpm.reloadConfig() This can be used to preserve the internal rpm state with any custom macros or definitions. :returns: rpm.spec object instance :raises: ValueError in case parsing failed """ if not keep_config: rpm.reloadConfig() with NamedTemporaryFile(mode="w+") as tmplog: # rpm will print errors to stdout if logfile is not set rpm.setLogFile(tmplog) try: spec = rpm.spec(spec_file) except ValueError as exc: # re-raise errors with rpm output appended to message raise ValueError(str(exc) + open(tmplog.name, 'r').read()) return spec
def hostActionInstallPackages(context): # since big RPM files may have to be downloaded, we must first change the # cache dir to one that's actually on the disk (ie, /mnt/sysimage/tmp) # instead of the ramdisk (ie, /tmp) cacher = getCacher() cacheDir = os.path.join(consts.HOST_ROOT, 'tmp/') if cacher.getCacheLocation() != cacheDir: assert os.path.exists(consts.HOST_ROOT) if not os.path.exists(cacheDir): os.makedirs(cacheDir) cacher.setCacheLocation(cacheDir, 'orphan') pkg = Packages(uiHook=context.cb) pkg.initializeDB() pkg.readPackages() rpmLog = open("/var/log/rpm.log", 'a+') try: # rpm.setVerbosity(rpm.RPMLOG_DEBUG) pkg.ts.scriptFd = rpmLog.fileno() rpm.setLogFile(rpmLog) pkg.installPackages() finally: rpmLog.flush() rpmLog.seek(0) log.debug("BEGIN rpm log ----") for line in rpmLog: log.debug("rpm: %s" % line.rstrip('\n')) log.debug("END rpm log ----") rpm.setLogFile(open("/dev/null", 'w+')) rpmLog.close() ts = getTransactionSet() ts.closeDB() # XXX - this should be removed after we switch to a 64 bit rpm workarounds.rebuildRpmDb()
def doApply(self, fileDict, justDatabase = False, noScripts = False): # force the nss modules to be loaded from outside of any chroot pwd.getpwall() # Create lockdir early since RPM 4.3.3-32 won't do it. util.mkdirChain(os.path.join(self.root, 'var/lock/rpm')) ts = rpm.TransactionSet(self.root, rpm._RPMVSF_NOSIGNATURES) installNvras = set() removeNvras = set([(trv.troveInfo.capsule.rpm.name(), trv.troveInfo.capsule.rpm.version(), trv.troveInfo.capsule.rpm.release(), trv.troveInfo.capsule.rpm.arch()) for trv in self.removes]) self._CheckRPMDBContents(removeNvras, ts, 'RPM database missing packages for removal: ') tsFlags = 0 if justDatabase: tsFlags |= rpm.RPMTRANS_FLAG_JUSTDB if noScripts: tsFlags |= rpm.RPMTRANS_FLAG_NOSCRIPTS ts.setFlags(tsFlags) # we use a pretty heavy hammer ts.setProbFilter(rpm.RPMPROB_FILTER_IGNOREOS | rpm.RPMPROB_FILTER_IGNOREARCH | rpm.RPMPROB_FILTER_REPLACEPKG | rpm.RPMPROB_FILTER_REPLACENEWFILES | rpm.RPMPROB_FILTER_REPLACEOLDFILES | rpm.RPMPROB_FILTER_OLDPACKAGE) for troveCs, (pathId, path, fileId, sha1) in self.installs: localPath = fileDict[(pathId, fileId)] fd = os.open(localPath, os.O_RDONLY) hdr = ts.hdrFromFdno(fd) installNvras.add( (hdr['name'], hdr['version'], hdr['release'], hdr['arch'])) os.close(fd) ts.addInstall(hdr, (hdr, localPath), "i") hasTransaction = True if (rpm.__dict__.has_key('RPMTAG_LONGARCHIVESIZE') and rpm.RPMTAG_LONGARCHIVESIZE in hdr.keys()): thisSize = hdr[rpm.RPMTAG_LONGARCHIVESIZE] else: thisSize = hdr[rpm.RPMTAG_ARCHIVESIZE] self.fsJob.addToRestoreSize(thisSize) # don't remove RPMs if we have another reference to that RPM # in the conary database # # by the time we get here, the erase items have already been # removed from the local database, so see if anything left needs # these nevra's # if we're installing the same nvra we're removing, don't remove # that nvra after installing it. that would be silly, and it just # makes our database ops more expensive anyway removeNvras -= installNvras # look for things with the same name afterInstall = set(self.db.findByNames( [ x.getName() for x in self.removes ])) # but not things we're just now installing afterInstall -= set( x[0].getNewNameVersionFlavor() for x in self.installs ) # now find the RPMs those previously installed items need neededNvras = set((trv.troveInfo.capsule.rpm.name(), trv.troveInfo.capsule.rpm.version(), trv.troveInfo.capsule.rpm.release(), trv.troveInfo.capsule.rpm.arch()) for trv in self.db.iterTroves(afterInstall) if trv.troveInfo.capsule.type() == trove._TROVECAPSULE_TYPE_RPM) # and don't remove those things removeNvras -= neededNvras for nvra in removeNvras: ts.addErase("%s-%s-%s.%s" % nvra) ts.check() ts.order() # record RPM's chosen transaction ordering for future debugging orderedKeys = [] # We must use getKeys() rather than iterating over ts to avoid # a refcounting bug in RPM's python bindings transactionKeys = ts.getKeys() # ts.getKeys() returns *either* a list of te's *or* None. if transactionKeys is not None: for te in transactionKeys: if te is not None: # install has a header; erase is an entry of None h = te[0] orderedKeys.append("%s-%s-%s.%s" %( h['name'], h['version'], h['release'], h['arch'])) if orderedKeys: log.syslog('RPM install order: ' + ' '.join(orderedKeys)) # redirect RPM messages into a temporary file; we harvest them from # there and send them on to the callback via the rpm callback tmpfd, tmpPath = tempfile.mkstemp() writeFile = os.fdopen(tmpfd, "w+") readFile = os.open(tmpPath, os.O_RDONLY) rpm.setLogFile(writeFile) cb = Callback(self.callback, self.fsJob.getRestoreSize(), readFile) probs = ts.run(cb, '') unpackFailures = set((h['name'], h['version'], h['release'], h['arch']) for h in cb.unpackFailures) # flush the RPM log del cb writeFile.close() os.close(readFile) if probs: raise ValueError(str(probs)) # CNY-3488: it's potentially harmful to enforce this here self._CheckRPMDBContents(installNvras, ts, 'RPM failed to install requested packages: ', unpackFailures=unpackFailures, enforceUnpackFailures=False)
import tempfile import gbp.log from gbp.rpm.policy import RpmPkgPolicy try: # Try to load special RPM lib to be used for GBP (only) librpm = __import__(RpmPkgPolicy.python_rpmlib_module_name) except ImportError: gbp.log.warn("Failed to import '%s' as rpm python module, using host's " "default rpm library instead" % RpmPkgPolicy.python_rpmlib_module_name) import rpm as librpm # Module initialization _rpmlog = tempfile.NamedTemporaryFile(prefix='gbp_rpmlog') _rpmlogfd = _rpmlog.file librpm.setVerbosity(librpm.RPMLOG_INFO) librpm.setLogFile(_rpmlogfd) def get_librpm_log(truncate=True): """Get rpmlib log output""" _rpmlogfd.seek(0) log = [line.strip() for line in _rpmlogfd.readlines()] if truncate: _rpmlogfd.truncate(0) return log
def runTransaction(self, mainwin): def transactionErrors(errs): d = PirutDetailsDialog(mainwin, gtk.MESSAGE_ERROR, buttons=[('gtk-ok', 0)], text=_("Error updating software")) d.format_secondary_text( _("There were errors encountered in " "trying to update the software " "you selected")) d.set_details("%s" % '\n'.join(map(lambda x: x[0], errs.value))) d.run() d.destroy() def blacklistRemoveWarning(pkgs): d = PirutDetailsDialog(mainwin, gtk.MESSAGE_WARNING, buttons=[('gtk-cancel', gtk.RESPONSE_CANCEL), (_("_Remove anyway"), gtk.RESPONSE_OK, 'gtk-ok')], text=_("Removing critical software")) d.format_secondary_text( _("Some of the software which you are " "removing is either critical software " "for system functionality or required " "by such software. Are you sure you " "want to continue?")) txt = "" for po in pkgs: txt += "%s\n" % (po, ) d.set_details(txt) rc = d.run() d.destroy() return rc def kernelRemoveWarning(pkgs): d = PirutDetailsDialog(mainwin, gtk.MESSAGE_WARNING, buttons=[('gtk-cancel', gtk.RESPONSE_CANCEL), (_("_Remove anyway"), gtk.RESPONSE_OK, 'gtk-ok')], text=_("Removing critical software")) d.format_secondary_text( _("Removing this could leave you with " "no kernels and thus lead to a " "non-bootable system. Are you sure " "you want to continue?")) rc = d.run() d.destroy() return rc # FIXME: does this belong here? blacked = [] for txmbr in self.tsInfo.removed: if (txmbr.po.returnSimple('name') in remove_blacklist and len( self.tsInfo.matchNaevr(name=txmbr.po.returnSimple('name'))) == 1): blacked.append(txmbr.po) if len(blacked) > 0: rc = blacklistRemoveWarning(blacked) if rc != gtk.RESPONSE_OK: raise PirutError 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 # set up the transaction to record output from scriptlets # this is pretty ugly... rpm.setVerbosity(rpm.RPMLOG_INFO) (r, w) = os.pipe() rf = os.fdopen(r, 'r') wf = os.fdopen(w, 'w') self.ts.ts.scriptFd = wf.fileno() rpm.setLogFile(wf) tsprog = Progress.PirutTransactionCallback(_("Updating software"), mainwin) tsprog.setReadPipe(rf) tsprog.show() tsprog.set_markup("<i>%s</i>" % (_("Preparing transaction"))) try: tserrors = yum.YumBase.runTransaction( self, yum.rpmtrans.RPMTransaction(self, display=tsprog)) except (yum.Errors.YumBaseError, PirutError), err: rpm.setLogFile(sys.stderr) rpm.setVerbosity(rpm.RPMLOG_NOTICE) wf.close() tsprog.destroy() # FIXME: these errors are actually pretty bad and should be # formatted better transactionErrors(err) raise PirutError
def install(self): """ Install the payload. """ from yum.Errors import PackageSackError, RepoError, YumBaseError logger.info("preparing transaction") logger.debug("initialize transaction set") with _yum_lock: self._yum.initActionTs() if rpmUtils and rpmUtils.arch.isMultiLibArch(): self._yum.ts.ts.setColor(3) logger.debug("populate transaction set") try: # uses dsCallback.transactionPopulation self._yum.populateTs(keepold=0) except RepoError as e: logger.error("error populating transaction: %s" % e) exn = PayloadInstallError(str(e)) #if errorHandler.cb(exn) == ERROR_RAISE: raise exn logger.debug("check transaction set") self._yum.ts.check() logger.debug("order transaction set") self._yum.ts.order() self._yum.ts.clean() # Write scriptlet output to a file to be logged later script_log = tempfile.NamedTemporaryFile(delete=False) self._yum.ts.ts.scriptFd = script_log.fileno() rpm.setLogFile(script_log) #@UndefinedVariable # create the install callback rpmcb = RPMCallback(self._yum, script_log, self.progress, upgrade=False) if self.flags.testing: self._yum.ts.setFlags(rpm.RPMTRANS_FLAG_TEST) #@UndefinedVariable logger.info("running transaction") self.progress.send_step() try: self._yum.runTransaction(cb=rpmcb) except PackageSackError as e: logger.error("error running transaction: %s" % e) exn = PayloadInstallError(str(e)) #if errorHandler.cb(exn) == ERROR_RAISE: raise exn except YumBaseError as e: logger.error("error [2] running transaction: %s" % e) for error in e.errors: logger.error("%s" % error[0]) exn = PayloadInstallError(str(e)) #if errorHandler.cb(exn) == ERROR_RAISE: raise exn else: logger.info("transaction complete") self.progress.send_step() finally: self._yum.ts.close() iutil.resetRpmDb() script_log.close() # log the contents of the scriptlet logfile logger.info("==== start rpm scriptlet logs ====") with open(script_log.name) as f: for l in f: logger.info(l) logger.info("==== end rpm scriptlet logs ====") os.unlink(script_log.name)
def __enter__(self): self.sink = open('/dev/null', 'w') rpm.setLogFile(self.sink)
def run(self, callback): self.check() _TS.order() rpm.setLogFile(sx.logger.logger_stream()) _TS.run(self.run_callback, callback) self.clear()
try: tserrors = yum.YumBase.runTransaction( self, yum.rpmtrans.RPMTransaction(self, display=tsprog)) except (yum.Errors.YumBaseError, PirutError), err: rpm.setLogFile(sys.stderr) rpm.setVerbosity(rpm.RPMLOG_NOTICE) wf.close() tsprog.destroy() # FIXME: these errors are actually pretty bad and should be # formatted better transactionErrors(err) raise PirutError # reset rpm bits and get the output rpm.setLogFile(sys.stderr) rpm.setVerbosity(rpm.RPMLOG_NOTICE) del self.ts wf.close() tsprog.destroy() return tsprog.getOutput() def applyChanges(self, mainwin, downloadonly=False): """Apply all of the packaging changes requested.""" # do depsolve. determine if we've added anything or not. self.checkDeps(mainwin) self.depDetails(mainwin) # download and verify packages dlpkgs = self.downloadPackages(mainwin)