Example #1
0
 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()
Example #2
0
    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)))
Example #3
0
    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)
Example #4
0
    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()
Example #5
0
    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])