Blame dnf/yum/rpmtrans.py

Packit Service 21c75c
# This program is free software; you can redistribute it and/or modify
Packit Service 21c75c
# it under the terms of the GNU General Public License as published by
Packit Service 21c75c
# the Free Software Foundation; either version 2 of the License, or
Packit Service 21c75c
# (at your option) any later version.
Packit Service 21c75c
#
Packit Service 21c75c
# This program is distributed in the hope that it will be useful,
Packit Service 21c75c
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 21c75c
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 21c75c
# GNU Library General Public License for more details.
Packit Service 21c75c
#
Packit Service 21c75c
# You should have received a copy of the GNU General Public License
Packit Service 21c75c
# along with this program; if not, write to the Free Software
Packit Service 21c75c
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit Service 21c75c
# Copyright 2005 Duke University
Packit Service 21c75c
# Parts Copyright 2007 Red Hat, Inc
Packit Service 21c75c
Packit Service 21c75c
from __future__ import print_function, absolute_import
Packit Service 21c75c
from __future__ import unicode_literals
Packit Service 21c75c
Packit Service 21c75c
import libdnf.transaction
Packit Service 21c75c
Packit Service 21c75c
from dnf.i18n import _, ucd
Packit Service 21c75c
import dnf.callback
Packit Service 21c75c
import dnf.transaction
Packit Service 21c75c
import dnf.util
Packit Service 21c75c
import rpm
Packit Service 21c75c
import os
Packit Service 21c75c
import logging
Packit Service 21c75c
import sys
Packit Service 21c75c
import tempfile
Packit Service 21c75c
import traceback
Packit Service 21c75c
import warnings
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
# TODO: merge w/ libdnf
Packit Service 21c75c
# transaction set states
Packit Service 21c75c
TS_UPDATE = 10
Packit Service 21c75c
TS_INSTALL = 20
Packit Service 21c75c
TS_ERASE = 40
Packit Service 21c75c
TS_OBSOLETED = 50
Packit Service 21c75c
TS_OBSOLETING = 60
Packit Service 21c75c
TS_AVAILABLE = 70
Packit Service 21c75c
TS_UPDATED = 90
Packit Service 21c75c
TS_FAILED = 100
Packit Service 21c75c
Packit Service 21c75c
TS_INSTALL_STATES = [TS_INSTALL, TS_UPDATE, TS_OBSOLETING]
Packit Service 21c75c
TS_REMOVE_STATES = [TS_ERASE, TS_OBSOLETED, TS_UPDATED]
Packit Service 21c75c
Packit Service 21c75c
RPM_ACTIONS_SET = {libdnf.transaction.TransactionItemAction_INSTALL,
Packit Service 21c75c
                   libdnf.transaction.TransactionItemAction_DOWNGRADE,
Packit Service 21c75c
                   libdnf.transaction.TransactionItemAction_DOWNGRADED,
Packit Service 21c75c
                   libdnf.transaction.TransactionItemAction_OBSOLETE,
Packit Service 21c75c
                   libdnf.transaction.TransactionItemAction_OBSOLETED,
Packit Service 21c75c
                   libdnf.transaction.TransactionItemAction_UPGRADE,
Packit Service 21c75c
                   libdnf.transaction.TransactionItemAction_UPGRADED,
Packit Service 21c75c
                   libdnf.transaction.TransactionItemAction_REMOVE,
Packit Service 21c75c
                   libdnf.transaction.TransactionItemAction_REINSTALLED}
Packit Service 21c75c
Packit Service 21c75c
logger = logging.getLogger('dnf')
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def _add_deprecated_action(name):
Packit Service 21c75c
    """
Packit Service 21c75c
    Wrapper to return a deprecated action constant
Packit Service 21c75c
    while printing a deprecation warning.
Packit Service 21c75c
    """
Packit Service 21c75c
    @property
Packit Service 21c75c
    def _func(self):
Packit Service 21c75c
        msg = "%s.%s is deprecated. Use dnf.callback.%s instead." \
Packit Service 21c75c
            % (self.__class__.__name__, name, name)
Packit Service 21c75c
        warnings.warn(msg, DeprecationWarning, stacklevel=2)
Packit Service 21c75c
        value = getattr(dnf.callback, name)
Packit Service 21c75c
        return value
Packit Service 21c75c
    return _func
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class TransactionDisplay(object):
Packit Service 21c75c
    # :api
Packit Service 21c75c
Packit Service 21c75c
    def __init__(self):
Packit Service 21c75c
        # :api
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
    # use constants from dnf.callback which are the official API
Packit Service 21c75c
    PKG_CLEANUP = _add_deprecated_action("PKG_CLEANUP")
Packit Service 21c75c
    PKG_DOWNGRADE = _add_deprecated_action("PKG_DOWNGRADE")
Packit Service 21c75c
    PKG_REMOVE = _add_deprecated_action("PKG_REMOVE")
Packit Service 21c75c
    PKG_ERASE = PKG_REMOVE
Packit Service 21c75c
    PKG_INSTALL = _add_deprecated_action("PKG_INSTALL")
Packit Service 21c75c
    PKG_OBSOLETE = _add_deprecated_action("PKG_OBSOLETE")
Packit Service 21c75c
    PKG_REINSTALL = _add_deprecated_action("PKG_REINSTALL")
Packit Service 21c75c
    PKG_UPGRADE = _add_deprecated_action("PKG_UPGRADE")
Packit Service 21c75c
    PKG_VERIFY = _add_deprecated_action("PKG_VERIFY")
Packit Service 21c75c
    TRANS_PREPARATION = _add_deprecated_action("TRANS_PREPARATION")
Packit Service 21c75c
    PKG_SCRIPTLET = _add_deprecated_action("PKG_SCRIPTLET")
Packit Service 21c75c
    TRANS_POST = _add_deprecated_action("TRANS_POST")
Packit Service 21c75c
Packit Service 21c75c
    def progress(self, package, action, ti_done, ti_total, ts_done, ts_total):
Packit Service 21c75c
        """Report ongoing progress on a transaction item. :api
Packit Service 21c75c
Packit Service 21c75c
        :param package: a package being processed
Packit Service 21c75c
        :param action: the action being performed
Packit Service 21c75c
        :param ti_done: number of processed bytes of the transaction
Packit Service 21c75c
           item being processed
Packit Service 21c75c
        :param ti_total: total number of bytes of the transaction item
Packit Service 21c75c
           being processed
Packit Service 21c75c
        :param ts_done: number of actions processed in the whole
Packit Service 21c75c
           transaction
Packit Service 21c75c
        :param ts_total: total number of actions in the whole
Packit Service 21c75c
           transaction
Packit Service 21c75c
Packit Service 21c75c
        """
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
    def scriptout(self, msgs):
Packit Service 572e28
        """msgs is the messages that were output (if any)."""
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
    def error(self, message):
Packit Service 21c75c
        """Report an error that occurred during the transaction. :api"""
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
    def filelog(self, package, action):
Packit Service 21c75c
        # check package object type - if it is a string - just output it
Packit Service 21c75c
        """package is the same as in progress() - a package object or simple
Packit Service 21c75c
           string action is also the same as in progress()"""
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
    def verify_tsi_package(self, pkg, count, total):
Packit Service 21c75c
        # TODO: replace with verify_tsi?
Packit Service 21c75c
        self.progress(pkg, dnf.transaction.PKG_VERIFY, 100, 100, count, total)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class ErrorTransactionDisplay(TransactionDisplay):
Packit Service 21c75c
Packit Service 21c75c
    """An RPMTransaction display that prints errors to standard output."""
Packit Service 21c75c
Packit Service 21c75c
    def error(self, message):
Packit Service 21c75c
        super(ErrorTransactionDisplay, self).error(message)
Packit Service 21c75c
        dnf.util._terminal_messenger('print', message, sys.stderr)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 572e28
class LoggingTransactionDisplay(ErrorTransactionDisplay):
Packit Service 21c75c
    '''
Packit Service 21c75c
    Base class for a RPMTransaction display callback class
Packit Service 21c75c
    '''
Packit Service 21c75c
    def __init__(self):
Packit Service 21c75c
        super(LoggingTransactionDisplay, self).__init__()
Packit Service 21c75c
        self.rpm_logger = logging.getLogger('dnf.rpm')
Packit Service 21c75c
Packit Service 21c75c
    def error(self, message):
Packit Service 21c75c
        self.rpm_logger.error(message)
Packit Service 21c75c
Packit Service 21c75c
    def filelog(self, package, action):
Packit Service 21c75c
        action_str = dnf.transaction.FILE_ACTIONS[action]
Packit Service 21c75c
        msg = '%s: %s' % (action_str, package)
Packit Service 21c75c
        self.rpm_logger.log(dnf.logging.SUBDEBUG, msg)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class RPMTransaction(object):
Packit Service 21c75c
    def __init__(self, base, test=False, displays=()):
Packit Service 21c75c
        if not displays:
Packit Service 21c75c
            displays = [ErrorTransactionDisplay()]
Packit Service 21c75c
        self.displays = displays
Packit Service 21c75c
        self.base = base
Packit Service 21c75c
        self.test = test  # are we a test?
Packit Service 21c75c
        self.trans_running = False
Packit Service 21c75c
        self.fd = None
Packit Service 21c75c
        self.total_actions = 0
Packit Service 21c75c
        self.total_installed = 0
Packit Service 21c75c
        self.complete_actions = 0
Packit Service 21c75c
        self.installed_pkg_names = set()
Packit Service 21c75c
        self.total_removed = 0
Packit Service 21c75c
Packit Service 21c75c
        self._setupOutputLogging(base.conf.rpmverbosity)
Packit Service 21c75c
        self._te_list = []
Packit Service 21c75c
        # Index in _te_list of the transaction element being processed (for use
Packit Service 21c75c
        # in callbacks)
Packit Service 21c75c
        self._te_index = 0
Packit Service 21c75c
        self._tsi_cache = None
Packit Service 21c75c
Packit Service 21c75c
    def _setupOutputLogging(self, rpmverbosity="info"):
Packit Service 21c75c
        # UGLY... set up the transaction to record output from scriptlets
Packit Service 21c75c
        io_r = tempfile.NamedTemporaryFile()
Packit Service 21c75c
        self._readpipe = io_r
Packit Service 21c75c
        self._writepipe = open(io_r.name, 'w+b')
Packit Service 21c75c
        self.base._ts.setScriptFd(self._writepipe)
Packit Service 21c75c
        rpmverbosity = {'critical' : 'crit',
Packit Service 21c75c
                        'emergency' : 'emerg',
Packit Service 21c75c
                        'error' : 'err',
Packit Service 21c75c
                        'information' : 'info',
Packit Service 21c75c
                        'warn' : 'warning'}.get(rpmverbosity, rpmverbosity)
Packit Service 21c75c
        rpmverbosity = 'RPMLOG_' + rpmverbosity.upper()
Packit Service 21c75c
        if not hasattr(rpm, rpmverbosity):
Packit Service 21c75c
            rpmverbosity = 'RPMLOG_INFO'
Packit Service 21c75c
        rpm.setVerbosity(getattr(rpm, rpmverbosity))
Packit Service 21c75c
        rpm.setLogFile(self._writepipe)
Packit Service 21c75c
Packit Service 21c75c
    def _shutdownOutputLogging(self):
Packit Service 21c75c
        # reset rpm bits from recording output
Packit Service 21c75c
        rpm.setVerbosity(rpm.RPMLOG_NOTICE)
Packit Service 21c75c
        rpm.setLogFile(sys.stderr)
Packit Service 21c75c
        try:
Packit Service 21c75c
            self._writepipe.close()
Packit Service 21c75c
        except:
Packit Service 21c75c
            pass
Packit Service 21c75c
Packit Service 21c75c
    def _scriptOutput(self):
Packit Service 21c75c
        try:
Packit Service 21c75c
            # XXX ugly workaround of problem which started after upgrading glibc
Packit Service 21c75c
            # from glibc-2.27-32.fc28.x86_64 to glibc-2.28-9.fc29.x86_64
Packit Service 21c75c
            # After this upgrade nothing is read from _readpipe, so every
Packit Service 21c75c
            # posttrans and postun scriptlet output is lost. The problem
Packit Service 21c75c
            # only occurs when using dnf-2, dnf-3 is OK.
Packit Service 21c75c
            # I did not find the root cause of this error yet.
Packit Service 21c75c
            self._readpipe.seek(self._readpipe.tell())
Packit Service 21c75c
            out = self._readpipe.read()
Packit Service 21c75c
            if not out:
Packit Service 21c75c
                return None
Packit Service 21c75c
            return out
Packit Service 21c75c
        except IOError:
Packit Service 21c75c
            pass
Packit Service 21c75c
Packit Service 21c75c
    def messages(self):
Packit Service 21c75c
        messages = self._scriptOutput()
Packit Service 21c75c
        if messages:
Packit Service 21c75c
            for line in messages.splitlines():
Packit Service 21c75c
                yield ucd(line)
Packit Service 21c75c
Packit Service 21c75c
    def _scriptout(self):
Packit Service 21c75c
        msgs = self._scriptOutput()
Packit Service 21c75c
        for display in self.displays:
Packit Service 21c75c
            display.scriptout(msgs)
Packit Service 21c75c
        self.base.history.log_scriptlet_output(msgs)
Packit Service 21c75c
Packit Service 21c75c
    def __del__(self):
Packit Service 21c75c
        self._shutdownOutputLogging()
Packit Service 21c75c
Packit Service 21c75c
    def _extract_cbkey(self, cbkey):
Packit Service 21c75c
        """Obtain the package related to the calling callback."""
Packit Service 21c75c
Packit Service 21c75c
        if hasattr(cbkey, "pkg"):
Packit Service 21c75c
            tsi = cbkey
Packit Service 21c75c
            return [tsi]
Packit Service 21c75c
Packit Service 21c75c
        te = self._te_list[self._te_index]
Packit Service 21c75c
        te_nevra = dnf.util._te_nevra(te)
Packit Service 21c75c
        if self._tsi_cache:
Packit Service 21c75c
            if str(self._tsi_cache[0]) == te_nevra:
Packit Service 21c75c
                return self._tsi_cache
Packit Service 21c75c
        items = []
Packit Service 21c75c
        for tsi in self.base.transaction:
Packit Service 21c75c
            if tsi.action not in RPM_ACTIONS_SET:
Packit Service 21c75c
                # skip REINSTALL in order to return REINSTALLED, or REASON_CHANGE to avoid crash
Packit Service 21c75c
                continue
Packit Service 21c75c
            if str(tsi) == te_nevra:
Packit Service 21c75c
                items.append(tsi)
Packit Service 21c75c
        if items:
Packit Service 21c75c
            self._tsi_cache = items
Packit Service 21c75c
            return items
Packit Service 21c75c
        raise RuntimeError("TransactionItem not found for key: %s" % cbkey)
Packit Service 21c75c
Packit Service 21c75c
    def callback(self, what, amount, total, key, client_data):
Packit Service 21c75c
        try:
Packit Service 21c75c
            if isinstance(key, str):
Packit Service 21c75c
                key = ucd(key)
Packit Service 21c75c
            if what == rpm.RPMCALLBACK_TRANS_START:
Packit Service 21c75c
                self._transStart(total)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_TRANS_STOP:
Packit Service 21c75c
                pass
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_TRANS_PROGRESS:
Packit Service 21c75c
                self._trans_progress(amount, total)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_ELEM_PROGRESS:
Packit Service 21c75c
                # This callback type is issued every time the next transaction
Packit Service 21c75c
                # element is about to be processed by RPM, before any other
Packit Service 21c75c
                # callbacks are issued.  "amount" carries the index of the element.
Packit Service 21c75c
                self._elemProgress(key, amount)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_INST_OPEN_FILE:
Packit Service 21c75c
                return self._instOpenFile(key)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE:
Packit Service 21c75c
                self._instCloseFile(key)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_INST_START:
Packit Service 21c75c
                self._inst_start(key)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_INST_STOP:
Packit Service 21c75c
                self._inst_stop(key)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_INST_PROGRESS:
Packit Service 21c75c
                self._instProgress(amount, total, key)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_UNINST_START:
Packit Service 21c75c
                self._uninst_start(key)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_UNINST_STOP:
Packit Service 21c75c
                self._unInstStop(key)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_UNINST_PROGRESS:
Packit Service 21c75c
                self._uninst_progress(amount, total, key)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_CPIO_ERROR:
Packit Service 21c75c
                self._cpioError(key)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_UNPACK_ERROR:
Packit Service 21c75c
                self._unpackError(key)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_SCRIPT_ERROR:
Packit Service 21c75c
                self._scriptError(amount, total, key)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_SCRIPT_START:
Packit Service 21c75c
                self._script_start(key)
Packit Service 21c75c
            elif what == rpm.RPMCALLBACK_SCRIPT_STOP:
Packit Service 21c75c
                self._scriptStop()
Packit Service 21c75c
        except Exception:
Packit Service 21c75c
            exc_type, exc_value, exc_traceback = sys.exc_info()
Packit Service 21c75c
            except_list = traceback.format_exception(exc_type, exc_value, exc_traceback)
Packit Service 21c75c
            logger.critical(''.join(except_list))
Packit Service 21c75c
Packit Service 21c75c
    def _transStart(self, total):
Packit Service 21c75c
        self.total_actions = total
Packit Service 21c75c
        if self.test: return
Packit Service 21c75c
        self.trans_running = True
Packit Service 21c75c
        self._te_list = list(self.base._ts)
Packit Service 21c75c
Packit Service 21c75c
    def _trans_progress(self, amount, total):
Packit Service 21c75c
        action = dnf.transaction.TRANS_PREPARATION
Packit Service 21c75c
        for display in self.displays:
Packit Service 21c75c
            display.progress('', action, amount + 1, total, 1, 1)
Packit Service 21c75c
Packit Service 21c75c
    def _elemProgress(self, key, index):
Packit Service 21c75c
        self._te_index = index
Packit Service 21c75c
        self.complete_actions += 1
Packit Service 21c75c
        if not self.test:
Packit Service 21c75c
            transaction_list = self._extract_cbkey(key)
Packit Service 21c75c
            for display in self.displays:
Packit Service 21c75c
                display.filelog(transaction_list[0].pkg, transaction_list[0].action)
Packit Service 21c75c
Packit Service 21c75c
    def _instOpenFile(self, key):
Packit Service 21c75c
        self.lastmsg = None
Packit Service 21c75c
        transaction_list = self._extract_cbkey(key)
Packit Service 21c75c
        pkg = transaction_list[0].pkg
Packit Service 21c75c
        rpmloc = pkg.localPkg()
Packit Service 21c75c
        try:
Packit Service 21c75c
            self.fd = open(rpmloc)
Packit Service 21c75c
        except IOError as e:
Packit Service 21c75c
            for display in self.displays:
Packit Service 21c75c
                display.error("Error: Cannot open file %s: %s" % (rpmloc, e))
Packit Service 21c75c
        else:
Packit Service 21c75c
            if self.trans_running:
Packit Service 21c75c
                self.total_installed += 1
Packit Service 21c75c
                self.installed_pkg_names.add(pkg.name)
Packit Service 21c75c
            return self.fd.fileno()
Packit Service 21c75c
Packit Service 21c75c
    def _instCloseFile(self, key):
Packit Service 21c75c
        self.fd.close()
Packit Service 21c75c
        self.fd = None
Packit Service 21c75c
Packit Service 21c75c
    def _inst_start(self, key):
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
    def _inst_stop(self, key):
Packit Service 21c75c
        if self.test or not self.trans_running:
Packit Service 21c75c
            return
Packit Service 21c75c
Packit Service 21c75c
        self._scriptout()
Packit Service 21c75c
Packit Service 21c75c
        if self.complete_actions == self.total_actions:
Packit Service 21c75c
            # RPM doesn't explicitly report when post-trans phase starts
Packit Service 21c75c
            action = dnf.transaction.TRANS_POST
Packit Service 21c75c
            for display in self.displays:
Packit Service 21c75c
                display.progress(None, action, None, None, None, None)
Packit Service 21c75c
Packit Service 21c75c
    def _instProgress(self, amount, total, key):
Packit Service 21c75c
        transaction_list = self._extract_cbkey(key)
Packit Service 21c75c
        pkg = transaction_list[0].pkg
Packit Service 21c75c
        action = transaction_list[0].action
Packit Service 21c75c
        for display in self.displays:
Packit Service 21c75c
            display.progress(pkg, action, amount, total, self.complete_actions, self.total_actions)
Packit Service 21c75c
Packit Service 21c75c
    def _uninst_start(self, key):
Packit Service 21c75c
        self.total_removed += 1
Packit Service 21c75c
Packit Service 21c75c
    def _uninst_progress(self, amount, total, key):
Packit Service 21c75c
        transaction_list = self._extract_cbkey(key)
Packit Service 21c75c
        pkg = transaction_list[0].pkg
Packit Service 21c75c
        action = transaction_list[0].action
Packit Service 21c75c
        for display in self.displays:
Packit Service 21c75c
            display.progress(pkg, action, amount, total, self.complete_actions, self.total_actions)
Packit Service 21c75c
Packit Service 21c75c
    def _unInstStop(self, key):
Packit Service 21c75c
        if self.test:
Packit Service 21c75c
            return
Packit Service 21c75c
Packit Service 21c75c
        self._scriptout()
Packit Service 21c75c
Packit Service 21c75c
    def _cpioError(self, key):
Packit Service 21c75c
        transaction_list = self._extract_cbkey(key)
Packit Service 21c75c
        msg = "Error in cpio payload of rpm package %s" % transaction_list[0].pkg
Packit Service 21c75c
        for display in self.displays:
Packit Service 21c75c
            display.error(msg)
Packit Service 21c75c
Packit Service 21c75c
    def _unpackError(self, key):
Packit Service 21c75c
        transaction_list = self._extract_cbkey(key)
Packit Service 21c75c
        msg = "Error unpacking rpm package %s" % transaction_list[0].pkg
Packit Service 21c75c
        for display in self.displays:
Packit Service 21c75c
            display.error(msg)
Packit Service 21c75c
Packit Service 21c75c
    def _scriptError(self, amount, total, key):
Packit Service 21c75c
        # "amount" carries the failed scriptlet tag,
Packit Service 21c75c
        # "total" carries fatal/non-fatal status
Packit Service 21c75c
        scriptlet_name = rpm.tagnames.get(amount, "<unknown>")
Packit Service 21c75c
Packit Service 21c75c
        transaction_list = self._extract_cbkey(key)
Packit Service 21c75c
        name = transaction_list[0].pkg.name
Packit Service 21c75c
Packit Service 21c75c
        msg = ("Error in %s scriptlet in rpm package %s" % (scriptlet_name, name))
Packit Service 21c75c
Packit Service 21c75c
        for display in self.displays:
Packit Service 21c75c
            display.error(msg)
Packit Service 21c75c
Packit Service 21c75c
    def _script_start(self, key):
Packit Service 21c75c
        # TODO: this doesn't fit into libdnf TransactionItem use cases
Packit Service 21c75c
        action = dnf.transaction.PKG_SCRIPTLET
Packit Service 21c75c
        if key is None and self._te_list == []:
Packit Service 21c75c
            pkg = 'None'
Packit Service 21c75c
        else:
Packit Service 21c75c
            transaction_list = self._extract_cbkey(key)
Packit Service 21c75c
            pkg = transaction_list[0].pkg
Packit Service 21c75c
        complete = self.complete_actions if self.total_actions != 0 and self.complete_actions != 0 \
Packit Service 21c75c
            else 1
Packit Service 21c75c
        total = self.total_actions if self.total_actions != 0 and self.complete_actions != 0 else 1
Packit Service 21c75c
        for display in self.displays:
Packit Service 21c75c
            display.progress(pkg, action, 100, 100, complete, total)
Packit Service 21c75c
Packit Service 21c75c
    def _scriptStop(self):
Packit Service 21c75c
        self._scriptout()
Packit Service 21c75c
Packit Service 21c75c
    def verify_tsi_package(self, pkg, count, total):
Packit Service 21c75c
        for display in self.displays:
Packit Service 21c75c
            display.verify_tsi_package(pkg, count, total)