Пример #1
0
 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)
Пример #3
0
 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
Пример #4
0
 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
Пример #5
0
 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)
Пример #6
0
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())
Пример #7
0
 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
Пример #9
0
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()
Пример #10
0
    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)
Пример #11
0
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

Пример #12
0
    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
Пример #13
0
    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)
Пример #14
0
 def __enter__(self):
     self.sink = open('/dev/null', 'w')
     rpm.setLogFile(self.sink)
Пример #15
0
 def run(self, callback):
     self.check()
     _TS.order()
     rpm.setLogFile(sx.logger.logger_stream())
     _TS.run(self.run_callback, callback)
     self.clear()
Пример #16
0
 def __enter__(self):
     self.sink = open('/dev/null', 'w')
     rpm.setLogFile(self.sink)
Пример #17
0
        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)