From cde765a81208f110af350184b62eca0084870bb5 Mon Sep 17 00:00:00 2001 From: Daniel Mach Date: Thu, 19 Nov 2020 09:50:15 +0100 Subject: [PATCH] history: Support operations on modules Also fix comps operations. =changelog= msg: Support history operations on modules type: enhancement resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1571725 --- dnf/base.py | 45 ++++++++++++++++++++++++++++++++++++++++++--- dnf/cli/output.py | 2 +- dnf/transaction.py | 3 +++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/dnf/base.py b/dnf/base.py index 3cf9022a7a..f2279c8a79 100644 --- a/dnf/base.py +++ b/dnf/base.py @@ -798,11 +798,17 @@ def do_transaction(self, display=()): display = \ [dnf.yum.rpmtrans.LoggingTransactionDisplay()] + list(display) + # save changed stream states into history database + modules_changed = self._moduleContainer.saveHistory(self.history._swdb) + + # save module states on disk right before entering rpm transaction, + # because we want system in recoverable state if transaction gets interrupted + self._moduleContainer.save() + self._moduleContainer.updateFailSafeData() + if not self.transaction: # packages are not changed, but comps and modules changes need to be committed - self._moduleContainer.save() - self._moduleContainer.updateFailSafeData() - if self._history and (self._history.group or self._history.env): + if self._history and (self._history.group or self._history.env or modules_changed): cmdline = None if hasattr(self, 'args') and self.args: cmdline = ' '.join(self.args) @@ -2219,6 +2225,7 @@ def _history_undo_operations(self, operations, first_trans, rollback=False, stri :param rollback: True if transaction is performing a rollback :param strict: if True, raise an exception on any errors """ + module_base = dnf.module.module_base.ModuleBase(self) # map actions to their opposites action_map = { @@ -2234,9 +2241,17 @@ def _history_undo_operations(self, operations, first_trans, rollback=False, stri libdnf.transaction.TransactionItemAction_UPGRADE: None, libdnf.transaction.TransactionItemAction_UPGRADED: libdnf.transaction.TransactionItemAction_DOWNGRADE, libdnf.transaction.TransactionItemAction_REASON_CHANGE: None, + + libdnf.transaction.TransactionItemAction_ENABLE_OUT: libdnf.transaction.TransactionItemAction_ENABLE, + libdnf.transaction.TransactionItemAction_ENABLE: None, + libdnf.transaction.TransactionItemAction_DISABLE_OUT: libdnf.transaction.TransactionItemAction_DISABLE, + libdnf.transaction.TransactionItemAction_DISABLE: None, + libdnf.transaction.TransactionItemAction_RESET_OUT: libdnf.transaction.TransactionItemAction_RESET, + libdnf.transaction.TransactionItemAction_RESET: None, } failed = False + for ti in operations.packages(): try: action = action_map[ti.action] @@ -2246,6 +2261,30 @@ def _history_undo_operations(self, operations, first_trans, rollback=False, stri if action is None: continue + if action == libdnf.transaction.TransactionItemAction_ENABLE: + module_base.enable([str(ti)]) + continue + + if action == libdnf.transaction.TransactionItemAction_DISABLE: + module_base.disable([str(ti)]) + continue + + if action == libdnf.transaction.TransactionItemAction_RESET: + module_base.reset([str(ti)]) + continue + + if ti._item.getCompsGroupItem() or ti._item.getCompsEnvironmentItem(): + if action == libdnf.transaction.TransactionItemAction_REMOVE: + if ti._item.getCompsGroupItem(): + self.read_comps(arch_filter=True) + self.group_remove(str(ti).lstrip("@")) + elif ti._item.getCompsEnvironmentItem(): + self.read_comps(arch_filter=True) + self.env_group_remove([str(ti).lstrip("@")]) + else: + self.install_specs([str(ti)], []) + continue + if action == libdnf.transaction.TransactionItemAction_REMOVE: query = self.sack.query().installed().filterm(nevra_strict=str(ti)) if not query: diff --git a/dnf/cli/output.py b/dnf/cli/output.py index 51d6829ca6..ab25b6c622 100644 --- a/dnf/cli/output.py +++ b/dnf/cli/output.py @@ -1564,7 +1564,7 @@ def _history_uiactions(self, hpkgs): actions_short = set() count = 0 for pkg in hpkgs: - if pkg.action in (libdnf.transaction.TransactionItemAction_UPGRADED, libdnf.transaction.TransactionItemAction_DOWNGRADED): + if pkg.action != libdnf.transaction.TransactionItemAction_REMOVE and pkg.action in dnf.transaction.BACKWARD_ACTIONS: # skip states we don't want to display in user input continue actions.add(pkg.action_name) diff --git a/dnf/transaction.py b/dnf/transaction.py index 9c9063353d..a1582f39a7 100644 --- a/dnf/transaction.py +++ b/dnf/transaction.py @@ -70,6 +70,9 @@ libdnf.transaction.TransactionItemAction_OBSOLETED, libdnf.transaction.TransactionItemAction_UPGRADED, libdnf.transaction.TransactionItemAction_REMOVE, + libdnf.transaction.TransactionItemAction_ENABLE_OUT, + libdnf.transaction.TransactionItemAction_DISABLE_OUT, + libdnf.transaction.TransactionItemAction_RESET_OUT, # TODO: REINSTALLED may and may not belong here; the same NEVRA is in FORWARD_ACTIONS already # libdnf.transaction.TransactionItemAction_REINSTALLED, ]