|
Packit Service |
21c75c |
# Copyright 2006 Duke University
|
|
Packit Service |
21c75c |
# Copyright (C) 2012-2016 Red Hat, Inc.
|
|
Packit Service |
21c75c |
#
|
|
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 |
|
|
Packit Service |
21c75c |
from __future__ import absolute_import
|
|
Packit Service |
21c75c |
from __future__ import print_function
|
|
Packit Service |
21c75c |
from __future__ import unicode_literals
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
import libdnf
|
|
Packit Service |
2bb387 |
import hawkey
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
from dnf.i18n import _, ucd
|
|
Packit Service |
21c75c |
from dnf.cli import commands
|
|
Packit Service |
21c75c |
from dnf.transaction_sr import TransactionReplay, serialize_transaction
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
import dnf.cli
|
|
Packit Service |
21c75c |
import dnf.exceptions
|
|
Packit Service |
21c75c |
import dnf.transaction
|
|
Packit Service |
21c75c |
import dnf.util
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
import json
|
|
Packit Service |
21c75c |
import logging
|
|
Packit Service |
21c75c |
import os
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
logger = logging.getLogger('dnf')
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
class HistoryCommand(commands.Command):
|
|
Packit Service |
21c75c |
"""A class containing methods needed by the cli to execute the
|
|
Packit Service |
21c75c |
history command.
|
|
Packit Service |
21c75c |
"""
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
aliases = ('history', 'hist')
|
|
Packit Service |
21c75c |
summary = _('display, or use, the transaction history')
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
_CMDS = ['list', 'info', 'redo', 'replay', 'rollback', 'store', 'undo', 'userinstalled']
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
def __init__(self, *args, **kw):
|
|
Packit Service |
21c75c |
super(HistoryCommand, self).__init__(*args, **kw)
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
self._require_one_transaction_id = False
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
@staticmethod
|
|
Packit Service |
21c75c |
def set_argparser(parser):
|
|
Packit Service |
21c75c |
parser.add_argument('transactions_action', nargs='?', metavar="COMMAND",
|
|
Packit Service |
21c75c |
help="Available commands: {} (default), {}".format(
|
|
Packit Service |
21c75c |
HistoryCommand._CMDS[0],
|
|
Packit Service |
21c75c |
", ".join(HistoryCommand._CMDS[1:])))
|
|
Packit Service |
21c75c |
parser.add_argument('--reverse', action='store_true',
|
|
Packit Service |
21c75c |
help="display history list output reversed")
|
|
Packit Service |
21c75c |
parser.add_argument("-o", "--output", default=None,
|
|
Packit Service |
21c75c |
help=_("For the store command, file path to store the transaction to"))
|
|
Packit Service |
21c75c |
parser.add_argument("--ignore-installed", action="store_true",
|
|
Packit Service |
21c75c |
help=_("For the replay command, don't check for installed packages matching "
|
|
Packit Service |
21c75c |
"those in transaction"))
|
|
Packit Service |
21c75c |
parser.add_argument("--ignore-extras", action="store_true",
|
|
Packit Service |
21c75c |
help=_("For the replay command, don't check for extra packages pulled "
|
|
Packit Service |
21c75c |
"into the transaction"))
|
|
Packit Service |
21c75c |
parser.add_argument("--skip-unavailable", action="store_true",
|
|
Packit Service |
21c75c |
help=_("For the replay command, skip packages that are not available or have "
|
|
Packit Service |
21c75c |
"missing dependencies"))
|
|
Packit Service |
21c75c |
parser.add_argument('transactions', nargs='*', metavar="TRANSACTION",
|
|
Packit Service |
21c75c |
help="For commands working with history transactions, "
|
|
Packit Service |
21c75c |
"Transaction ID (<number>, 'last' or 'last-<number>' "
|
|
Packit Service |
21c75c |
"for one transaction, <transaction-id>..<transaction-id> "
|
|
Packit Service |
21c75c |
"for a range)")
|
|
Packit Service |
21c75c |
parser.add_argument('transaction_filename', nargs='?', metavar="TRANSACTION_FILE",
|
|
Packit Service |
21c75c |
help="For the replay command, path to the stored "
|
|
Packit Service |
21c75c |
"transaction file to replay")
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
def configure(self):
|
|
Packit Service |
21c75c |
if not self.opts.transactions_action:
|
|
Packit Service |
21c75c |
# no positional argument given
|
|
Packit Service |
21c75c |
self.opts.transactions_action = self._CMDS[0]
|
|
Packit Service |
21c75c |
elif self.opts.transactions_action not in self._CMDS:
|
|
Packit Service |
21c75c |
# first positional argument is not a command
|
|
Packit Service |
21c75c |
self.opts.transactions.insert(0, self.opts.transactions_action)
|
|
Packit Service |
21c75c |
self.opts.transactions_action = self._CMDS[0]
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
self._require_one_transaction_id_msg = _("Found more than one transaction ID.\n"
|
|
Packit Service |
21c75c |
"'{}' requires one transaction ID or package name."
|
|
Packit Service |
21c75c |
).format(self.opts.transactions_action)
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
demands = self.cli.demands
|
|
Packit Service |
21c75c |
if self.opts.transactions_action == 'replay':
|
|
Packit Service |
21c75c |
if not self.opts.transactions:
|
|
Packit Service |
21c75c |
raise dnf.cli.CliError(_('No transaction file name given.'))
|
|
Packit Service |
21c75c |
if len(self.opts.transactions) > 1:
|
|
Packit Service |
21c75c |
raise dnf.cli.CliError(_('More than one argument given as transaction file name.'))
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
# in case of replay, copy over the file name to it's appropriate variable
|
|
Packit Service |
21c75c |
# (the arg parser can't distinguish here)
|
|
Packit Service |
21c75c |
self.opts.transaction_filename = os.path.abspath(self.opts.transactions[0])
|
|
Packit Service |
21c75c |
self.opts.transactions = []
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
demands.available_repos = True
|
|
Packit Service |
21c75c |
demands.resolving = True
|
|
Packit Service |
21c75c |
demands.root_user = True
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
# Override configuration options that affect how the transaction is resolved
|
|
Packit Service |
21c75c |
self.base.conf.clean_requirements_on_remove = False
|
|
Packit Service |
21c75c |
self.base.conf.install_weak_deps = False
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
dnf.cli.commands._checkGPGKey(self.base, self.cli)
|
|
Packit Service |
21c75c |
elif self.opts.transactions_action == 'store':
|
|
Packit Service |
21c75c |
self._require_one_transaction_id = True
|
|
Packit Service |
21c75c |
if not self.opts.transactions:
|
|
Packit Service |
21c75c |
raise dnf.cli.CliError(_('No transaction ID or package name given.'))
|
|
Packit Service |
21c75c |
elif self.opts.transactions_action in ['redo', 'undo', 'rollback']:
|
|
Packit Service |
2bb387 |
demands.available_repos = True
|
|
Packit Service |
2bb387 |
demands.resolving = True
|
|
Packit Service |
2bb387 |
demands.root_user = True
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
21c75c |
self._require_one_transaction_id = True
|
|
Packit Service |
21c75c |
if not self.opts.transactions:
|
|
Packit Service |
21c75c |
msg = _('No transaction ID or package name given.')
|
|
Packit Service |
21c75c |
logger.critical(msg)
|
|
Packit Service |
21c75c |
raise dnf.cli.CliError(msg)
|
|
Packit Service |
21c75c |
elif len(self.opts.transactions) > 1:
|
|
Packit Service |
21c75c |
logger.critical(self._require_one_transaction_id_msg)
|
|
Packit Service |
21c75c |
raise dnf.cli.CliError(self._require_one_transaction_id_msg)
|
|
Packit Service |
21c75c |
demands.available_repos = True
|
|
Packit Service |
21c75c |
dnf.cli.commands._checkGPGKey(self.base, self.cli)
|
|
Packit Service |
21c75c |
else:
|
|
Packit Service |
21c75c |
demands.fresh_metadata = False
|
|
Packit Service |
21c75c |
demands.sack_activation = True
|
|
Packit Service |
21c75c |
if self.base.history.path != ":memory:" and not os.access(self.base.history.path, os.R_OK):
|
|
Packit Service |
21c75c |
msg = _("You don't have access to the history DB: %s" % self.base.history.path)
|
|
Packit Service |
21c75c |
logger.critical(msg)
|
|
Packit Service |
21c75c |
raise dnf.cli.CliError(msg)
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
def get_error_output(self, error):
|
|
Packit Service |
21c75c |
"""Get suggestions for resolving the given error."""
|
|
Packit Service |
21c75c |
if isinstance(error, dnf.exceptions.TransactionCheckError):
|
|
Packit Service |
21c75c |
if self.opts.transactions_action == 'undo':
|
|
Packit Service |
21c75c |
id_, = self.opts.transactions
|
|
Packit Service |
21c75c |
return (_('Cannot undo transaction %s, doing so would result '
|
|
Packit Service |
21c75c |
'in an inconsistent package database.') % id_,)
|
|
Packit Service |
21c75c |
elif self.opts.transactions_action == 'rollback':
|
|
Packit Service |
21c75c |
id_, = (self.opts.transactions if self.opts.transactions[0] != 'force'
|
|
Packit Service |
21c75c |
else self.opts.transactions[1:])
|
|
Packit Service |
21c75c |
return (_('Cannot rollback transaction %s, doing so would '
|
|
Packit Service |
21c75c |
'result in an inconsistent package database.') % id_,)
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
return dnf.cli.commands.Command.get_error_output(self, error)
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
def _hcmd_redo(self, extcmds):
|
|
Packit Service |
2bb387 |
old = self._history_get_transaction(extcmds)
|
|
Packit Service |
2bb387 |
data = serialize_transaction(old)
|
|
Packit Service |
2bb387 |
self.replay = TransactionReplay(
|
|
Packit Service |
2bb387 |
self.base,
|
|
Packit Service |
2bb387 |
data=data,
|
|
Packit Service |
2bb387 |
ignore_installed=True,
|
|
Packit Service |
2bb387 |
ignore_extras=True,
|
|
Packit Service |
2bb387 |
skip_unavailable=self.opts.skip_unavailable
|
|
Packit Service |
2bb387 |
)
|
|
Packit Service |
2bb387 |
self.replay.run()
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
2bb387 |
def _history_get_transactions(self, extcmds):
|
|
Packit Service |
2bb387 |
if not extcmds:
|
|
Packit Service |
2bb387 |
raise dnf.cli.CliError(_('No transaction ID given'))
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
2bb387 |
old = self.base.history.old(extcmds)
|
|
Packit Service |
2bb387 |
if not old:
|
|
Packit Service |
2bb387 |
raise dnf.cli.CliError(_('Transaction ID "{0}" not found.').format(extcmds[0]))
|
|
Packit Service |
2bb387 |
return old
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
2bb387 |
def _history_get_transaction(self, extcmds):
|
|
Packit Service |
2bb387 |
old = self._history_get_transactions(extcmds)
|
|
Packit Service |
2bb387 |
if len(old) > 1:
|
|
Packit Service |
2bb387 |
raise dnf.cli.CliError(_('Found more than one transaction ID!'))
|
|
Packit Service |
2bb387 |
return old[0]
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
def _hcmd_undo(self, extcmds):
|
|
Packit Service |
2bb387 |
old = self._history_get_transaction(extcmds)
|
|
Packit Service |
2bb387 |
self._revert_transaction(old)
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
def _hcmd_rollback(self, extcmds):
|
|
Packit Service |
2bb387 |
old = self._history_get_transaction(extcmds)
|
|
Packit Service |
2bb387 |
last = self.base.history.last()
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
2bb387 |
merged_trans = None
|
|
Packit Service |
2bb387 |
if old.tid != last.tid:
|
|
Packit Service |
2bb387 |
# history.old([]) returns all transactions and we don't want that
|
|
Packit Service |
2bb387 |
# so skip merging the transactions when trying to rollback to the last transaction
|
|
Packit Service |
2bb387 |
# which is the current system state and rollback is not applicable
|
|
Packit Service |
2bb387 |
for trans in self.base.history.old(list(range(old.tid + 1, last.tid + 1))):
|
|
Packit Service |
2bb387 |
if trans.altered_lt_rpmdb:
|
|
Packit Service |
2bb387 |
logger.warning(_('Transaction history is incomplete, before %u.'), trans.tid)
|
|
Packit Service |
2bb387 |
elif trans.altered_gt_rpmdb:
|
|
Packit Service |
2bb387 |
logger.warning(_('Transaction history is incomplete, after %u.'), trans.tid)
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
2bb387 |
if merged_trans is None:
|
|
Packit Service |
2bb387 |
merged_trans = dnf.db.history.MergedTransactionWrapper(trans)
|
|
Packit Service |
2bb387 |
else:
|
|
Packit Service |
2bb387 |
merged_trans.merge(trans)
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
2bb387 |
self._revert_transaction(merged_trans)
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
2bb387 |
def _revert_transaction(self, trans):
|
|
Packit Service |
2bb387 |
action_map = {
|
|
Packit Service |
2bb387 |
"Install": "Removed",
|
|
Packit Service |
2bb387 |
"Removed": "Install",
|
|
Packit Service |
2bb387 |
"Upgrade": "Downgraded",
|
|
Packit Service |
2bb387 |
"Upgraded": "Downgrade",
|
|
Packit Service |
2bb387 |
"Downgrade": "Upgraded",
|
|
Packit Service |
2bb387 |
"Downgraded": "Upgrade",
|
|
Packit Service |
2bb387 |
"Reinstalled": "Reinstall",
|
|
Packit Service |
2bb387 |
"Reinstall": "Reinstalled",
|
|
Packit Service |
2bb387 |
"Obsoleted": "Install",
|
|
Packit Service |
2bb387 |
"Obsolete": "Obsoleted",
|
|
Packit Service |
2bb387 |
}
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
2bb387 |
data = serialize_transaction(trans)
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
2bb387 |
# revert actions in the serialized transaction data to perform rollback/undo
|
|
Packit Service |
2bb387 |
for content_type in ("rpms", "groups", "environments"):
|
|
Packit Service |
2bb387 |
for ti in data.get(content_type, []):
|
|
Packit Service |
2bb387 |
ti["action"] = action_map[ti["action"]]
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
2bb387 |
if ti["action"] == "Install" and ti.get("reason", None) == "clean":
|
|
Packit Service |
2bb387 |
ti["reason"] = "dependency"
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
2bb387 |
if ti.get("repo_id") == hawkey.SYSTEM_REPO_NAME:
|
|
Packit Service |
2bb387 |
# erase repo_id, because it's not possible to perform forward actions from the @System repo
|
|
Packit Service |
2bb387 |
ti["repo_id"] = None
|
|
Packit Service |
2bb387 |
|
|
Packit Service |
2bb387 |
self.replay = TransactionReplay(
|
|
Packit Service |
2bb387 |
self.base,
|
|
Packit Service |
2bb387 |
data=data,
|
|
Packit Service |
2bb387 |
ignore_installed=True,
|
|
Packit Service |
2bb387 |
ignore_extras=True,
|
|
Packit Service |
2bb387 |
skip_unavailable=self.opts.skip_unavailable
|
|
Packit Service |
2bb387 |
)
|
|
Packit Service |
2bb387 |
self.replay.run()
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
def _hcmd_userinstalled(self):
|
|
Packit Service |
21c75c |
"""Execute history userinstalled command."""
|
|
Packit Service |
21c75c |
pkgs = tuple(self.base.iter_userinstalled())
|
|
Packit Service |
2bb387 |
n_listed = self.output.listPkgs(pkgs, 'Packages installed by user', 'nevra')
|
|
Packit Service |
2bb387 |
if n_listed == 0:
|
|
Packit Service |
2bb387 |
raise dnf.cli.CliError(_('No packages to list'))
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
def _args2transaction_ids(self):
|
|
Packit Service |
21c75c |
"""Convert commandline arguments to transaction ids"""
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
def str2transaction_id(s):
|
|
Packit Service |
21c75c |
if s == 'last':
|
|
Packit Service |
21c75c |
s = '0'
|
|
Packit Service |
21c75c |
elif s.startswith('last-'):
|
|
Packit Service |
21c75c |
s = s[4:]
|
|
Packit Service |
21c75c |
transaction_id = int(s)
|
|
Packit Service |
21c75c |
if transaction_id <= 0:
|
|
Packit Service |
21c75c |
transaction_id += self.output.history.last().tid
|
|
Packit Service |
21c75c |
return transaction_id
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
tids = set()
|
|
Packit Service |
21c75c |
merged_tids = set()
|
|
Packit Service |
21c75c |
for t in self.opts.transactions:
|
|
Packit Service |
21c75c |
if '..' in t:
|
|
Packit Service |
21c75c |
try:
|
|
Packit Service |
21c75c |
begin_transaction_id, end_transaction_id = t.split('..', 2)
|
|
Packit Service |
21c75c |
except ValueError:
|
|
Packit Service |
21c75c |
logger.critical(
|
|
Packit Service |
21c75c |
_("Invalid transaction ID range definition '{}'.\n"
|
|
Packit Service |
21c75c |
"Use '<transaction-id>..<transaction-id>'."
|
|
Packit Service |
21c75c |
).format(t))
|
|
Packit Service |
21c75c |
raise dnf.cli.CliError
|
|
Packit Service |
21c75c |
cant_convert_msg = _("Can't convert '{}' to transaction ID.\n"
|
|
Packit Service |
21c75c |
"Use '<number>', 'last', 'last-<number>'.")
|
|
Packit Service |
21c75c |
try:
|
|
Packit Service |
21c75c |
begin_transaction_id = str2transaction_id(begin_transaction_id)
|
|
Packit Service |
21c75c |
except ValueError:
|
|
Packit Service |
21c75c |
logger.critical(_(cant_convert_msg).format(begin_transaction_id))
|
|
Packit Service |
21c75c |
raise dnf.cli.CliError
|
|
Packit Service |
21c75c |
try:
|
|
Packit Service |
21c75c |
end_transaction_id = str2transaction_id(end_transaction_id)
|
|
Packit Service |
21c75c |
except ValueError:
|
|
Packit Service |
21c75c |
logger.critical(_(cant_convert_msg).format(end_transaction_id))
|
|
Packit Service |
21c75c |
raise dnf.cli.CliError
|
|
Packit Service |
21c75c |
if self._require_one_transaction_id and begin_transaction_id != end_transaction_id:
|
|
Packit Service |
21c75c |
logger.critical(self._require_one_transaction_id_msg)
|
|
Packit Service |
21c75c |
raise dnf.cli.CliError
|
|
Packit Service |
21c75c |
if begin_transaction_id > end_transaction_id:
|
|
Packit Service |
21c75c |
begin_transaction_id, end_transaction_id = \
|
|
Packit Service |
21c75c |
end_transaction_id, begin_transaction_id
|
|
Packit Service |
21c75c |
merged_tids.add((begin_transaction_id, end_transaction_id))
|
|
Packit Service |
21c75c |
tids.update(range(begin_transaction_id, end_transaction_id + 1))
|
|
Packit Service |
21c75c |
else:
|
|
Packit Service |
21c75c |
try:
|
|
Packit Service |
21c75c |
tids.add(str2transaction_id(t))
|
|
Packit Service |
21c75c |
except ValueError:
|
|
Packit Service |
21c75c |
# not a transaction id, assume it's package name
|
|
Packit Service |
21c75c |
transact_ids_from_pkgname = self.output.history.search([t])
|
|
Packit Service |
21c75c |
if transact_ids_from_pkgname:
|
|
Packit Service |
21c75c |
tids.update(transact_ids_from_pkgname)
|
|
Packit Service |
21c75c |
else:
|
|
Packit Service |
21c75c |
msg = _("No transaction which manipulates package '{}' was found."
|
|
Packit Service |
21c75c |
).format(t)
|
|
Packit Service |
21c75c |
if self._require_one_transaction_id:
|
|
Packit Service |
21c75c |
logger.critical(msg)
|
|
Packit Service |
21c75c |
raise dnf.cli.CliError
|
|
Packit Service |
21c75c |
else:
|
|
Packit Service |
21c75c |
logger.info(msg)
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
return sorted(tids, reverse=True), merged_tids
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
def run(self):
|
|
Packit Service |
21c75c |
vcmd = self.opts.transactions_action
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
if vcmd == 'replay':
|
|
Packit Service |
21c75c |
self.replay = TransactionReplay(
|
|
Packit Service |
21c75c |
self.base,
|
|
Packit Service |
2bb387 |
filename=self.opts.transaction_filename,
|
|
Packit Service |
21c75c |
ignore_installed = self.opts.ignore_installed,
|
|
Packit Service |
21c75c |
ignore_extras = self.opts.ignore_extras,
|
|
Packit Service |
21c75c |
skip_unavailable = self.opts.skip_unavailable
|
|
Packit Service |
21c75c |
)
|
|
Packit Service |
21c75c |
self.replay.run()
|
|
Packit Service |
21c75c |
else:
|
|
Packit Service |
21c75c |
tids, merged_tids = self._args2transaction_ids()
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
if vcmd == 'list' and (tids or not self.opts.transactions):
|
|
Packit Service |
2bb387 |
self.output.historyListCmd(tids, reverse=self.opts.reverse)
|
|
Packit Service |
21c75c |
elif vcmd == 'info' and (tids or not self.opts.transactions):
|
|
Packit Service |
2bb387 |
self.output.historyInfoCmd(tids, self.opts.transactions, merged_tids)
|
|
Packit Service |
21c75c |
elif vcmd == 'undo':
|
|
Packit Service |
2bb387 |
self._hcmd_undo(tids)
|
|
Packit Service |
21c75c |
elif vcmd == 'redo':
|
|
Packit Service |
2bb387 |
self._hcmd_redo(tids)
|
|
Packit Service |
21c75c |
elif vcmd == 'rollback':
|
|
Packit Service |
2bb387 |
self._hcmd_rollback(tids)
|
|
Packit Service |
21c75c |
elif vcmd == 'userinstalled':
|
|
Packit Service |
2bb387 |
self._hcmd_userinstalled()
|
|
Packit Service |
21c75c |
elif vcmd == 'store':
|
|
Packit Service |
2bb387 |
tid = self._history_get_transaction(tids)
|
|
Packit Service |
2bb387 |
data = serialize_transaction(tid)
|
|
Packit Service |
21c75c |
try:
|
|
Packit Service |
21c75c |
filename = self.opts.output if self.opts.output is not None else "transaction.json"
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
# it is absolutely possible for both assumeyes and assumeno to be True, go figure
|
|
Packit Service |
21c75c |
if (self.base.conf.assumeno or not self.base.conf.assumeyes) and os.path.isfile(filename):
|
|
Packit Service |
21c75c |
msg = _("{} exists, overwrite?").format(filename)
|
|
Packit Service |
21c75c |
if self.base.conf.assumeno or not self.base.output.userconfirm(
|
|
Packit Service |
21c75c |
msg='\n{} [y/N]: '.format(msg), defaultyes_msg='\n{} [Y/n]: '.format(msg)):
|
|
Packit Service |
21c75c |
print(_("Not overwriting {}, exiting.").format(filename))
|
|
Packit Service |
21c75c |
return
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
with open(filename, "w") as f:
|
|
Packit Service |
21c75c |
json.dump(data, f, indent=4, sort_keys=True)
|
|
Packit Service |
21c75c |
f.write("\n")
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
print(_("Transaction saved to {}.").format(filename))
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
except OSError as e:
|
|
Packit Service |
21c75c |
raise dnf.cli.CliError(_('Error storing transaction: {}').format(str(e)))
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
def run_resolved(self):
|
|
Packit Service |
2bb387 |
if self.opts.transactions_action not in ("replay", "redo", "rollback", "undo"):
|
|
Packit Service |
21c75c |
return
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
self.replay.post_transaction()
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
def run_transaction(self):
|
|
Packit Service |
2bb387 |
if self.opts.transactions_action not in ("replay", "redo", "rollback", "undo"):
|
|
Packit Service |
21c75c |
return
|
|
Packit Service |
21c75c |
|
|
Packit Service |
21c75c |
warnings = self.replay.get_warnings()
|
|
Packit Service |
21c75c |
if warnings:
|
|
Packit Service |
21c75c |
logger.log(
|
|
Packit Service |
21c75c |
dnf.logging.WARNING,
|
|
Packit Service |
2bb387 |
_("Warning, the following problems occurred while running a transaction:")
|
|
Packit Service |
21c75c |
)
|
|
Packit Service |
21c75c |
for w in warnings:
|
|
Packit Service |
21c75c |
logger.log(dnf.logging.WARNING, " " + w)
|