def _hcmd_redo(self, extcmds): old = self._history_get_transaction(extcmds) data = serialize_transaction(old) self.replay = TransactionReplay( self.base, data=data, ignore_installed=True, ignore_extras=True, skip_unavailable=self.opts.skip_unavailable) self.replay.run()
def run(self): vcmd = self.opts.transactions_action if vcmd == 'replay': self.replay = TransactionReplay( self.base, filename=self.opts.transaction_filename, ignore_installed=self.opts.ignore_installed, ignore_extras=self.opts.ignore_extras, skip_unavailable=self.opts.skip_unavailable) self.replay.run() else: tids, merged_tids = self._args2transaction_ids() if vcmd == 'list' and (tids or not self.opts.transactions): self.output.historyListCmd(tids, reverse=self.opts.reverse) elif vcmd == 'info' and (tids or not self.opts.transactions): self.output.historyInfoCmd(tids, self.opts.transactions, merged_tids) elif vcmd == 'undo': self._hcmd_undo(tids) elif vcmd == 'redo': self._hcmd_redo(tids) elif vcmd == 'rollback': self._hcmd_rollback(tids) elif vcmd == 'userinstalled': self._hcmd_userinstalled() elif vcmd == 'store': tid = self._history_get_transaction(tids) data = serialize_transaction(tid) try: filename = self.opts.output if self.opts.output is not None else "transaction.json" # it is absolutely possible for both assumeyes and assumeno to be True, go figure if (self.base.conf.assumeno or not self.base.conf.assumeyes ) and os.path.isfile(filename): msg = _("{} exists, overwrite?").format(filename) if self.base.conf.assumeno or not self.base.output.userconfirm( msg='\n{} [y/N]: '.format(msg), defaultyes_msg='\n{} [Y/n]: '.format(msg)): print( _("Not overwriting {}, exiting.").format( filename)) return with open(filename, "w") as f: json.dump(data, f, indent=4, sort_keys=True) f.write("\n") print(_("Transaction saved to {}.").format(filename)) except OSError as e: raise dnf.cli.CliError( _('Error storing transaction: {}').format(str(e)))
def transaction_download(self): transaction = self.base.history.get_current() if not transaction.packages(): logger.info( _("The system-upgrade transaction is empty, your system is already up-to-date." )) return data = serialize_transaction(transaction) try: with open(self.transaction_file, "w") as f: json.dump(data, f, indent=4, sort_keys=True) f.write("\n") print(_("Transaction saved to {}.").format(self.transaction_file)) except OSError as e: raise dnf.cli.CliError( _('Error storing transaction: {}').format(str(e))) # Okay! Write out the state so the upgrade can use it. system_ver = dnf.rpm.detect_releasever(self.base.conf.installroot) with self.state as state: state.download_status = 'complete' state.state_version = STATE_VERSION state.distro_sync = self.opts.distro_sync state.gpgcheck = self.base.conf.gpgcheck state.gpgcheck_repos = [ repo.id for repo in self.base.repos.values() if repo.gpgcheck ] state.repo_gpgcheck_repos = [ repo.id for repo in self.base.repos.values() if repo.repo_gpgcheck ] state.system_releasever = system_ver state.target_releasever = self.base.conf.releasever state.module_platform_id = self.base.conf.module_platform_id state.enable_disable_repos = self.opts.repos_ed state.destdir = self.base.conf.destdir state.upgrade_command = self.opts.command msg = DOWNLOAD_FINISHED_MSG.format(command=self.opts.command) logger.info(msg) self.log_status(_("Download finished."), DOWNLOAD_FINISHED_ID)
def _revert_transaction(self, trans): action_map = { "Install": "Removed", "Removed": "Install", "Upgrade": "Downgraded", "Upgraded": "Downgrade", "Downgrade": "Upgraded", "Downgraded": "Upgrade", "Reinstalled": "Reinstall", "Reinstall": "Reinstalled", "Obsoleted": "Install", "Obsolete": "Obsoleted", } data = serialize_transaction(trans) # revert actions in the serialized transaction data to perform rollback/undo for content_type in ("rpms", "groups", "environments"): for ti in data.get(content_type, []): ti["action"] = action_map[ti["action"]] if ti["action"] == "Install" and ti.get("reason", None) == "clean": ti["reason"] = "dependency" if ti.get("repo_id") == hawkey.SYSTEM_REPO_NAME: # erase repo_id, because it's not possible to perform forward actions from the @System repo ti["repo_id"] = None self.replay = TransactionReplay( self.base, data=data, ignore_installed=True, ignore_extras=True, skip_unavailable=self.opts.skip_unavailable) self.replay.run()
def run(self): vcmd = self.opts.transactions_action ret = None if vcmd == 'replay': self.base.read_comps(arch_filter=True) self.replay = TransactionReplay( self.base, self.opts.transaction_filename, ignore_installed = self.opts.ignore_installed, ignore_extras = self.opts.ignore_extras, skip_unavailable = self.opts.skip_unavailable ) self.replay.run() else: tids, merged_tids = self._args2transaction_ids() if vcmd == 'list' and (tids or not self.opts.transactions): ret = self.output.historyListCmd(tids, reverse=self.opts.reverse) elif vcmd == 'info' and (tids or not self.opts.transactions): ret = self.output.historyInfoCmd(tids, self.opts.transactions, merged_tids) elif vcmd == 'undo': ret = self._hcmd_undo(tids) elif vcmd == 'redo': ret = self._hcmd_redo(tids) elif vcmd == 'rollback': ret = self._hcmd_rollback(tids) elif vcmd == 'userinstalled': ret = self._hcmd_userinstalled() elif vcmd == 'store': print( "Warning: The stored transaction format is considered unstable and may " "change at any time. It will work if the same version of dnf is used to " "store and replay (or between versions as long as it stays the same).", file=sys.stderr ) transactions = self.output.history.old(tids) if not transactions: raise dnf.cli.CliError(_('Transaction ID "{id}" not found.').format(id=tids[0])) data = serialize_transaction(transactions[0]) try: filename = self.opts.output if self.opts.output is not None else "transaction.json" # it is absolutely possible for both assumeyes and assumeno to be True, go figure if (self.base.conf.assumeno or not self.base.conf.assumeyes) and os.path.isfile(filename): msg = _("{} exists, overwrite?").format(filename) if self.base.conf.assumeno or not self.base.output.userconfirm( msg='\n{} [y/N]: '.format(msg), defaultyes_msg='\n{} [Y/n]: '.format(msg)): print(_("Not overwriting {}, exiting.").format(filename)) return with open(filename, "w") as f: json.dump(data, f, indent=4, sort_keys=True) f.write("\n") print(_("Transaction saved to {}.").format(filename)) except OSError as e: raise dnf.cli.CliError(_('Error storing transaction: {}').format(str(e))) if ret is None: return (code, strs) = ret if code == 2: self.cli.demands.resolving = True elif code != 0: raise dnf.exceptions.Error(strs[0])