From 4ee4dbe03d24696efa0ccbfcf772ddc55b6a93de Mon Sep 17 00:00:00 2001 From: Daniel Mach <dmach@redhat.com> Date: Thu, 21 Jun 2018 10:01:18 +0200 Subject: [PATCH] Fix code to work with DNF 3 history and transactions. --- python/dnfdaemon/server/__init__.py | 75 ++++++++++++----------------- python/dnfdaemon/server/backend.py | 9 ++-- 2 files changed, 36 insertions(+), 48 deletions(-) diff --git a/python/dnfdaemon/server/__init__.py b/python/dnfdaemon/server/__init__.py index b35383f..a19d2cd 100644 --- a/python/dnfdaemon/server/__init__.py +++ b/python/dnfdaemon/server/__init__.py @@ -54,21 +54,6 @@ FAKE_ATTR = ['downgrades', 'action', 'pkgtags', NONE = json.dumps(None) -_ACTIVE_DCT = { - dnf.transaction.DOWNGRADE: operator.attrgetter('installed'), - dnf.transaction.ERASE: operator.attrgetter('erased'), - dnf.transaction.INSTALL: operator.attrgetter('installed'), - dnf.transaction.REINSTALL: operator.attrgetter('installed'), - dnf.transaction.UPGRADE: operator.attrgetter('installed'), -} - - -def _active_pkg(tsi): - """Return the package from tsi that takes the active role - in the transaction. - """ - return _ACTIVE_DCT[tsi.op_type](tsi) - #------------------------------------------------------------ Callback handlers logger = logging.getLogger('dnfdaemon.common') @@ -255,7 +240,7 @@ class DnfDaemonBase(dbus.service.Object, DownloadCallback): # get the dnf group obj grp = self.base.comps.group_by_pattern(obj.name) if grp: - installed = self.base.history.group.group_installed(grp.id) + installed = True # if grp is not None, it's installed elem = (grp.id, grp.ui_name, grp.ui_description, installed) cat_grps.append(elem) @@ -683,11 +668,13 @@ class DnfDaemonBase(dbus.service.Object, DownloadCallback): tx = self.base.history.old([tid], complete_transactions_only=False) result = [] for pkg in tx[0].packages(): - values = [pkg.name, pkg.epoch, pkg.version, - pkg.release, pkg.arch, pkg.ui_from_repo()] - pkg_id = ",".join(values) - installed = True if pkg.state in dnf.history.INSTALLING_STATES else False - elem = (pkg_id, pkg.state, pkg.state_installed, installed) + pkg_id = self._get_id(pkg) + installed = pkg.action in dnf.transaction.FORWARD_ACTIONS + [dnf.transaction.PKG_REINSTALL] + action_name = pkg.action_name + if action_name == "Upgrade": + # HACK: rename action name due to recent change in DNF 3 + action_name = "Update" + elem = (pkg_id, action_name, installed) result.append(elem) value = json.dumps(result) return value @@ -777,11 +764,7 @@ class DnfDaemonBase(dbus.service.Object, DownloadCallback): def _get_packages_to_download(self): """Get packages to download for the current dnf transaction.""" - to_dnl = [] - for tsi in self.base.transaction: - if tsi.installed: - to_dnl.append(tsi.installed) - return to_dnl + return list(self.base.transaction.install_set) def _build_transaction(self): """Get a list of the current transaction.""" @@ -798,18 +781,27 @@ class DnfDaemonBase(dbus.service.Object, DownloadCallback): tx_list = {} for t in ('downgrade', 'remove', 'install', 'reinstall', 'update'): tx_list[t] = [] + + replaces = {} if self.base.transaction: + # build a reverse mapping to 'replaced_by' + # this is required to achieve reasonable speed for tsi in self.base.transaction: - #print(tsi.op_type, tsi.installed, tsi.erased, tsi.obsoleted) - if tsi.op_type == dnf.transaction.DOWNGRADE: + if tsi.action != dnf.transaction.PKG_OBSOLETED: + continue + for i in tsi._item.getReplacedBy(): + replaces.setdefault(i, set()).add(tsi) + + for tsi in self.base.transaction: + if tsi.action == dnf.transaction.PKG_DOWNGRADE: tx_list['downgrade'].append(tsi) - elif tsi.op_type == dnf.transaction.ERASE: + elif tsi.action == dnf.transaction.PKG_ERASE: tx_list['remove'].append(tsi) - elif tsi.op_type == dnf.transaction.INSTALL: + elif tsi.action == dnf.transaction.PKG_INSTALL: tx_list['install'].append(tsi) - elif tsi.op_type == dnf.transaction.REINSTALL: + elif tsi.action == dnf.transaction.PKG_REINSTALL: tx_list['reinstall'].append(tsi) - elif tsi.op_type == dnf.transaction.UPGRADE: + elif tsi.action == dnf.transaction.PKG_UPGRADE: tx_list['update'].append(tsi) # build action tree for (action, pkglist) in [ @@ -820,16 +812,11 @@ class DnfDaemonBase(dbus.service.Object, DownloadCallback): ('downgrade', tx_list['downgrade'])]: for tsi in pkglist: - po = _active_pkg(tsi) + po = tsi.pkg (n, a, e, v, r) = po.pkgtup size = float(po.size) - # build a list of obsoleted packages - alist = [] - for obs_po in tsi.obsoleted: - alist.append(self._get_id(obs_po)) - if alist: - logger.debug(repr(alist)) - el = (self._get_id(po), size, alist) + obsoletes = [self._get_id(i) for i in replaces.get(tsi._item, [])] + el = (self._get_id(po), size, obsoletes) sublist.append(el) if pkglist: out_list.append([action, sublist]) @@ -1014,9 +1001,11 @@ class DnfDaemonBase(dbus.service.Object, DownloadCallback): def _get_id(self, pkg): """Get a package id from a given package.""" - values = [ - pkg.name, str(pkg.epoch), pkg.version, pkg.release, - pkg.arch, pkg.ui_from_repo] + values = [pkg.name, str(pkg.epoch), pkg.version, pkg.release, pkg.arch] + if callable(pkg.ui_from_repo): + values.append(pkg.ui_from_repo()) + else: + values.append(pkg.ui_from_repo) return ",".join(values) def _get_action(self, po): diff --git a/python/dnfdaemon/server/backend.py b/python/dnfdaemon/server/backend.py index 997a466..4c13ced 100644 --- a/python/dnfdaemon/server/backend.py +++ b/python/dnfdaemon/server/backend.py @@ -314,12 +314,11 @@ class Packages: # return install/upgrade type pkgs from transaction for tsi in self._base.transaction: #print(tsi.op_type, tsi.installed, tsi.erased, tsi.obsoleted) - if tsi.op_type == dnf.transaction.UPGRADE: - pkgs.append(tsi.installed) - elif tsi.op_type == dnf.transaction.INSTALL: - po = tsi.installed + if tsi.action == dnf.transaction.PKG_UPGRADE: + pkgs.append(tsi.pkg) + elif tsi.action == dnf.transaction.PKG_INSTALL: # action is INSTALL, then it should be a installonlypkg - pkgs.append(po) + pkgs.append(tsi.pkg) return pkgs @property -- GitLab