Blame dnf/cli/commands/__init__.py

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
# Written by Seth Vidal
Packit Service 21c75c
Packit Service 21c75c
"""
Packit Service 21c75c
Classes for subcommands of the yum command line interface.
Packit Service 21c75c
"""
Packit Service 21c75c
Packit Service 21c75c
from __future__ import print_function
Packit Service 21c75c
from __future__ import unicode_literals
Packit Service 21c75c
Packit Service 21c75c
from dnf.cli.option_parser import OptionParser
Packit Service 21c75c
from dnf.i18n import _
Packit Service 21c75c
Packit Service 21c75c
import dnf.cli
Packit Service 21c75c
import dnf.exceptions
Packit Service 21c75c
import dnf.pycomp
Packit Service 21c75c
import dnf.util
Packit Service 21c75c
import logging
Packit Service 21c75c
import os
Packit Service 21c75c
Packit Service 21c75c
logger = logging.getLogger('dnf')
Packit Service 21c75c
_RPM_VERIFY = _("To diagnose the problem, try running: '%s'.") % \
Packit Service 21c75c
    'rpm -Va --nofiles --nodigest'
Packit Service 21c75c
_RPM_REBUILDDB = _("You probably have corrupted RPMDB, running '%s'"
Packit Service 21c75c
                   " might fix the issue.") % 'rpm --rebuilddb'
Packit Service 21c75c
Packit Service 21c75c
gpg_msg = \
Packit Service 21c75c
    _("""You have enabled checking of packages via GPG keys. This is a good thing.
Packit Service 21c75c
However, you do not have any GPG public keys installed. You need to download
Packit Service 21c75c
the keys for packages you wish to install and install them.
Packit Service 21c75c
You can do that by running the command:
Packit Service 21c75c
    rpm --import public.gpg.key
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
Alternatively you can specify the url to the key you would like to use
Packit Service 21c75c
for a repository in the 'gpgkey' option in a repository section and {prog}
Packit Service 21c75c
will install it for you.
Packit Service 21c75c
Packit Service 21c75c
For more information contact your distribution or package provider.""")
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def _checkGPGKey(base, cli):
Packit Service 21c75c
    """Verify that there are gpg keys for the enabled repositories in the
Packit Service 21c75c
    rpm database.
Packit Service 21c75c
Packit Service 21c75c
    :param base: a :class:`dnf.Base` object.
Packit Service 21c75c
    :raises: :class:`cli.CliError`
Packit Service 21c75c
    """
Packit Service 21c75c
    if not base.conf.gpgcheck:
Packit Service 21c75c
        return
Packit Service 21c75c
    if not base._gpg_key_check():
Packit Service 21c75c
        for repo in base.repos.iter_enabled():
Packit Service 21c75c
            if (repo.gpgcheck or repo.repo_gpgcheck) and not repo.gpgkey:
Packit Service 21c75c
                logger.critical("\n%s\n", gpg_msg.format(prog=dnf.util.MAIN_PROG_UPPER))
Packit Service 21c75c
                logger.critical(_("Problem repository: %s"), repo)
Packit Service 21c75c
                raise dnf.cli.CliError
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def _checkEnabledRepo(base, possible_local_files=()):
Packit Service 21c75c
    """Verify that there is at least one enabled repo.
Packit Service 21c75c
Packit Service 21c75c
    :param base: a :class:`dnf.Base` object.
Packit Service 21c75c
    :param possible_local_files: the list of strings that could be a local rpms
Packit Service 21c75c
    :raises: :class:`cli.CliError`:
Packit Service 21c75c
    """
Packit Service 21c75c
    if base.repos._any_enabled():
Packit Service 21c75c
        return
Packit Service 21c75c
Packit Service 21c75c
    for lfile in possible_local_files:
Packit Service 21c75c
        if lfile.endswith(".rpm") and os.path.exists(lfile):
Packit Service 21c75c
            return
Packit Service 21c75c
        scheme = dnf.pycomp.urlparse.urlparse(lfile)[0]
Packit Service 21c75c
        if scheme in ('http', 'ftp', 'file', 'https'):
Packit Service 21c75c
            return
Packit Service 21c75c
    msg = _('There are no enabled repositories in "{}".').format('", "'.join(base.conf.reposdir))
Packit Service 21c75c
    raise dnf.cli.CliError(msg)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class Command(object):
Packit Service 21c75c
    """Abstract base class for CLI commands."""
Packit Service 21c75c
Packit Service 21c75c
    aliases = [] # :api
Packit Service 21c75c
    summary = ""  # :api
Packit Service 21c75c
    opts = None
Packit Service 21c75c
Packit Service 21c75c
    def __init__(self, cli):
Packit Service 21c75c
        # :api
Packit Service 21c75c
        self.cli = cli
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def base(self):
Packit Service 21c75c
        # :api
Packit Service 21c75c
        return self.cli.base
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def _basecmd(self):
Packit Service 21c75c
        return self.aliases[0]
Packit Service 21c75c
Packit Service 21c75c
    @property
Packit Service 21c75c
    def output(self):
Packit Service 21c75c
        return self.cli.base.output
Packit Service 21c75c
Packit Service 21c75c
    def set_argparser(self, parser):
Packit Service 21c75c
        """Define command specific options and arguments. #:api"""
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
    def pre_configure(self):
Packit Service 21c75c
        # :api
Packit Service 21c75c
        """Do any command-specific pre-configuration."""
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
    def configure(self):
Packit Service 21c75c
        # :api
Packit Service 21c75c
        """Do any command-specific configuration."""
Packit Service 21c75c
        pass
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
            return (_RPM_VERIFY, _RPM_REBUILDDB)
Packit Service 21c75c
        raise NotImplementedError('error not supported yet: %s' % error)
Packit Service 21c75c
Packit Service 21c75c
    def run(self):
Packit Service 21c75c
        # :api
Packit Service 21c75c
        """Execute the command."""
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
    def run_resolved(self):
Packit Service 21c75c
        """Finalize operation after resolvement"""
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
    def run_transaction(self):
Packit Service 21c75c
        """Finalize operations post-transaction."""
Packit Service 21c75c
        pass
Packit Service 21c75c
Packit Service 21c75c
class InfoCommand(Command):
Packit Service 21c75c
    """A class containing methods needed by the cli to execute the
Packit Service 21c75c
    info command.
Packit Service 21c75c
    """
Packit Service 21c75c
Packit Service 21c75c
    aliases = ('info',)
Packit Service 21c75c
    summary = _('display details about a package or group of packages')
Packit Service 21c75c
    DEFAULT_PKGNARROW = 'all'
Packit Service 21c75c
    pkgnarrows = {'available', 'installed', 'extras', 'updates', 'upgrades',
Packit Service 21c75c
                  'autoremove', 'recent', 'obsoletes', DEFAULT_PKGNARROW}
Packit Service 21c75c
Packit Service 21c75c
    @classmethod
Packit Service 21c75c
    def set_argparser(cls, parser):
Packit Service 21c75c
        narrows = parser.add_mutually_exclusive_group()
Packit Service 21c75c
        narrows.add_argument('--all', dest='_packages_action',
Packit Service 21c75c
                             action='store_const', const='all', default=None,
Packit Service 21c75c
                             help=_("show all packages (default)"))
Packit Service 21c75c
        narrows.add_argument('--available', dest='_packages_action',
Packit Service 21c75c
                             action='store_const', const='available',
Packit Service 21c75c
                             help=_("show only available packages"))
Packit Service 21c75c
        narrows.add_argument('--installed', dest='_packages_action',
Packit Service 21c75c
                             action='store_const', const='installed',
Packit Service 21c75c
                             help=_("show only installed packages"))
Packit Service 21c75c
        narrows.add_argument('--extras', dest='_packages_action',
Packit Service 21c75c
                             action='store_const', const='extras',
Packit Service 21c75c
                             help=_("show only extras packages"))
Packit Service 21c75c
        narrows.add_argument('--updates', dest='_packages_action',
Packit Service 21c75c
                             action='store_const', const='upgrades',
Packit Service 21c75c
                             help=_("show only upgrades packages"))
Packit Service 21c75c
        narrows.add_argument('--upgrades', dest='_packages_action',
Packit Service 21c75c
                             action='store_const', const='upgrades',
Packit Service 21c75c
                             help=_("show only upgrades packages"))
Packit Service 21c75c
        narrows.add_argument('--autoremove', dest='_packages_action',
Packit Service 21c75c
                             action='store_const', const='autoremove',
Packit Service 21c75c
                             help=_("show only autoremove packages"))
Packit Service 21c75c
        narrows.add_argument('--recent', dest='_packages_action',
Packit Service 21c75c
                             action='store_const', const='recent',
Packit Service 21c75c
                             help=_("show only recently changed packages"))
Packit Service 21c75c
        parser.add_argument('packages', nargs='*', metavar=_('PACKAGE'),
Packit Service 21c75c
                            choices=cls.pkgnarrows, default=cls.DEFAULT_PKGNARROW,
Packit Service 21c75c
                            action=OptionParser.PkgNarrowCallback,
Packit Service 21c75c
                            help=_("Package name specification"))
Packit Service 21c75c
Packit Service 21c75c
    def configure(self):
Packit Service 21c75c
        demands = self.cli.demands
Packit Service 21c75c
        demands.sack_activation = True
Packit Service 21c75c
        if self.opts._packages_action:
Packit Service 21c75c
            self.opts.packages_action = self.opts._packages_action
Packit Service 21c75c
        if self.opts.packages_action != 'installed':
Packit Service 21c75c
            demands.available_repos = True
Packit Service 21c75c
        if self.opts.obsoletes:
Packit Service 21c75c
            if self.opts._packages_action:
Packit Service 21c75c
                self.cli._option_conflict("--obsoletes", "--" + self.opts._packages_action)
Packit Service 21c75c
            else:
Packit Service 21c75c
                self.opts.packages_action = 'obsoletes'
Packit Service 21c75c
        if self.opts.packages_action == 'updates':
Packit Service 21c75c
            self.opts.packages_action = 'upgrades'
Packit Service 21c75c
Packit Service 21c75c
    def run(self):
Packit Service 21c75c
        self.cli._populate_update_security_filter(self.opts, self.base.sack.query())
Packit Service 21c75c
        return self.base.output_packages('info', self.opts.packages_action,
Packit Service 21c75c
                                         self.opts.packages)
Packit Service 21c75c
Packit Service 21c75c
class ListCommand(InfoCommand):
Packit Service 21c75c
    """A class containing methods needed by the cli to execute the
Packit Service 21c75c
    list command.
Packit Service 21c75c
    """
Packit Service 21c75c
Packit Service 21c75c
    aliases = ('list', 'ls')
Packit Service 21c75c
    summary = _('list a package or groups of packages')
Packit Service 21c75c
Packit Service 21c75c
    def run(self):
Packit Service 21c75c
        self.cli._populate_update_security_filter(self.opts, self.base.sack.query())
Packit Service 21c75c
        return self.base.output_packages('list', self.opts.packages_action,
Packit Service 21c75c
                                         self.opts.packages)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class ProvidesCommand(Command):
Packit Service 21c75c
    """A class containing methods needed by the cli to execute the
Packit Service 21c75c
    provides command.
Packit Service 21c75c
    """
Packit Service 21c75c
Packit Service 21c75c
    aliases = ('provides', 'whatprovides', 'prov')
Packit Service 21c75c
    summary = _('find what package provides the given value')
Packit Service 21c75c
Packit Service 21c75c
    @staticmethod
Packit Service 21c75c
    def set_argparser(parser):
Packit Service 21c75c
        parser.add_argument('dependency', nargs='+', metavar=_('PROVIDE'),
Packit Service 21c75c
                            help=_("Provide specification to search for"))
Packit Service 21c75c
Packit Service 21c75c
    def configure(self):
Packit Service 21c75c
        demands = self.cli.demands
Packit Service 21c75c
        demands.available_repos = True
Packit Service 21c75c
        demands.fresh_metadata = False
Packit Service 21c75c
        demands.sack_activation = True
Packit Service 21c75c
Packit Service 21c75c
    def run(self):
Packit Service 21c75c
        logger.debug(_("Searching Packages: "))
Packit Service 21c75c
        return self.base.provides(self.opts.dependency)
Packit Service 21c75c
Packit Service 21c75c
class CheckUpdateCommand(Command):
Packit Service 21c75c
    """A class containing methods needed by the cli to execute the
Packit Service 21c75c
    check-update command.
Packit Service 21c75c
    """
Packit Service 21c75c
Packit Service 21c75c
    aliases = ('check-update', 'check-upgrade')
Packit Service 21c75c
    summary = _('check for available package upgrades')
Packit Service 21c75c
Packit Service 21c75c
    @staticmethod
Packit Service 21c75c
    def set_argparser(parser):
Packit Service 21c75c
        parser.add_argument('--changelogs', dest='changelogs',
Packit Service 21c75c
                            default=False, action='store_true',
Packit Service 21c75c
                            help=_('show changelogs before update'))
Packit Service 21c75c
        parser.add_argument('packages', nargs='*', metavar=_('PACKAGE'))
Packit Service 21c75c
Packit Service 21c75c
    def configure(self):
Packit Service 21c75c
        demands = self.cli.demands
Packit Service 21c75c
        demands.sack_activation = True
Packit Service 21c75c
        demands.available_repos = True
Packit Service 21c75c
        demands.plugin_filtering_enabled = True
Packit Service 21c75c
        if self.opts.changelogs:
Packit Service 21c75c
            demands.changelogs = True
Packit Service 21c75c
        _checkEnabledRepo(self.base)
Packit Service 21c75c
Packit Service 21c75c
    def run(self):
Packit Service 21c75c
        query = self.base.sack.query().filterm(upgrades_by_priority=True)
Packit Service 21c75c
        if self.base.conf.obsoletes:
Packit Service 21c75c
            obsoleted = query.union(self.base.sack.query().installed())
Packit Service 21c75c
            obsoletes = self.base.sack.query().filter(obsoletes=obsoleted)
Packit Service 21c75c
            query = query.union(obsoletes)
Packit Service 21c75c
        self.cli._populate_update_security_filter(self.opts, query, cmp_type="gte")
Packit Service 21c75c
Packit Service 21c75c
        found = self.base.check_updates(self.opts.packages, print_=True,
Packit Service 21c75c
                                        changelogs=self.opts.changelogs)
Packit Service 21c75c
        if found:
Packit Service 21c75c
            self.cli.demands.success_exit_status = 100
Packit Service 21c75c
Packit Service 21c75c
        if self.base.conf.autocheck_running_kernel:
Packit Service 21c75c
            self.cli._check_running_kernel()
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class RepoPkgsCommand(Command):
Packit Service 21c75c
    """Implementation of the repository-packages command."""
Packit Service 21c75c
Packit Service 21c75c
    class CheckUpdateSubCommand(Command):
Packit Service 21c75c
        """Implementation of the info sub-command."""
Packit Service 21c75c
Packit Service 21c75c
        aliases = ('check-update',)
Packit Service 21c75c
Packit Service 21c75c
        def configure(self):
Packit Service 21c75c
            demands = self.cli.demands
Packit Service 21c75c
            demands.available_repos = True
Packit Service 21c75c
            demands.sack_activation = True
Packit Service 21c75c
Packit Service 21c75c
        def run_on_repo(self):
Packit Service 21c75c
            """Execute the command with respect to given arguments *cli_args*."""
Packit Service 21c75c
            found = self.base.check_updates(self.opts.pkg_specs,
Packit Service 21c75c
                                            self.reponame, print_=True)
Packit Service 21c75c
            if found:
Packit Service 21c75c
                self.cli.demands.success_exit_status = 100
Packit Service 21c75c
Packit Service 21c75c
    class InfoSubCommand(Command):
Packit Service 21c75c
        """Implementation of the info sub-command."""
Packit Service 21c75c
Packit Service 21c75c
        aliases = ('info',)
Packit Service 21c75c
Packit Service 21c75c
        def configure(self):
Packit Service 21c75c
            demands = self.cli.demands
Packit Service 21c75c
            demands.sack_activation = True
Packit Service 21c75c
            if self.opts._pkg_specs_action:
Packit Service 21c75c
                self.opts.pkg_specs_action = self.opts._pkg_specs_action
Packit Service 21c75c
            if self.opts.pkg_specs_action != 'installed':
Packit Service 21c75c
                demands.available_repos = True
Packit Service 21c75c
            if self.opts.obsoletes:
Packit Service 21c75c
                if self.opts._pkg_specs_action:
Packit Service 21c75c
                    self.cli._option_conflict("--obsoletes", "--" + self.opts._pkg_specs_action)
Packit Service 21c75c
                else:
Packit Service 21c75c
                    self.opts.pkg_specs_action = 'obsoletes'
Packit Service 21c75c
Packit Service 21c75c
        def run_on_repo(self):
Packit Service 21c75c
            """Execute the command with respect to given arguments *cli_args*."""
Packit Service 21c75c
            self.cli._populate_update_security_filter(self.opts, self.base.sack.query())
Packit Service 21c75c
            self.base.output_packages('info', self.opts.pkg_specs_action,
Packit Service 21c75c
                                      self.opts.pkg_specs, self.reponame)
Packit Service 21c75c
Packit Service 21c75c
    class InstallSubCommand(Command):
Packit Service 21c75c
        """Implementation of the install sub-command."""
Packit Service 21c75c
Packit Service 21c75c
        aliases = ('install',)
Packit Service 21c75c
Packit Service 21c75c
        def configure(self):
Packit Service 21c75c
            demands = self.cli.demands
Packit Service 21c75c
            demands.available_repos = True
Packit Service 21c75c
            demands.sack_activation = True
Packit Service 21c75c
            demands.resolving = True
Packit Service 21c75c
            demands.root_user = True
Packit Service 21c75c
Packit Service 21c75c
        def run_on_repo(self):
Packit Service 21c75c
            self.cli._populate_update_security_filter(self.opts, self.base.sack.query())
Packit Service 21c75c
            """Execute the command with respect to given arguments *cli_args*."""
Packit Service 21c75c
            _checkGPGKey(self.base, self.cli)
Packit Service 21c75c
Packit Service 21c75c
            done = False
Packit Service 21c75c
Packit Service 21c75c
            if not self.opts.pkg_specs:
Packit Service 21c75c
                # Install all packages.
Packit Service 21c75c
                try:
Packit Service 21c75c
                    self.base.install('*', self.reponame)
Packit Service 21c75c
                except dnf.exceptions.MarkingError:
Packit Service 21c75c
                    logger.info(_('No package available.'))
Packit Service 21c75c
                else:
Packit Service 21c75c
                    done = True
Packit Service 21c75c
            else:
Packit Service 21c75c
                # Install packages.
Packit Service 21c75c
                for pkg_spec in self.opts.pkg_specs:
Packit Service 21c75c
                    try:
Packit Service 21c75c
                        self.base.install(pkg_spec, self.reponame)
Packit Service 21c75c
                    except dnf.exceptions.MarkingError as e:
Packit Service 21c75c
                        msg = '{}: {}'.format(e.value, self.base.output.term.bold(pkg_spec))
Packit Service 21c75c
                        logger.info(msg)
Packit Service 21c75c
                    else:
Packit Service 21c75c
                        done = True
Packit Service 21c75c
Packit Service 21c75c
            if not done:
Packit Service 21c75c
                raise dnf.exceptions.Error(_('No packages marked for install.'))
Packit Service 21c75c
Packit Service 21c75c
    class ListSubCommand(InfoSubCommand):
Packit Service 21c75c
        """Implementation of the list sub-command."""
Packit Service 21c75c
Packit Service 21c75c
        aliases = ('list',)
Packit Service 21c75c
Packit Service 21c75c
        def run_on_repo(self):
Packit Service 21c75c
            """Execute the command with respect to given arguments *cli_args*."""
Packit Service 21c75c
            self.cli._populate_update_security_filter(self.opts, self.base.sack.query())
Packit Service 21c75c
            self.base.output_packages('list', self.opts.pkg_specs_action,
Packit Service 21c75c
                                      self.opts.pkg_specs, self.reponame)
Packit Service 21c75c
Packit Service 21c75c
    class MoveToSubCommand(Command):
Packit Service 21c75c
        """Implementation of the move-to sub-command."""
Packit Service 21c75c
Packit Service 21c75c
        aliases = ('move-to',)
Packit Service 21c75c
Packit Service 21c75c
        def configure(self):
Packit Service 21c75c
            demands = self.cli.demands
Packit Service 21c75c
            demands.sack_activation = True
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
        def run_on_repo(self):
Packit Service 21c75c
            """Execute the command with respect to given arguments *cli_args*."""
Packit Service 21c75c
            _checkGPGKey(self.base, self.cli)
Packit Service 21c75c
Packit Service 21c75c
            done = False
Packit Service 21c75c
Packit Service 21c75c
            if not self.opts.pkg_specs:
Packit Service 21c75c
                # Reinstall all packages.
Packit Service 21c75c
                try:
Packit Service 21c75c
                    self.base.reinstall('*', new_reponame=self.reponame)
Packit Service 21c75c
                except dnf.exceptions.PackagesNotInstalledError:
Packit Service 21c75c
                    logger.info(_('No package installed.'))
Packit Service 21c75c
                except dnf.exceptions.PackagesNotAvailableError:
Packit Service 21c75c
                    logger.info(_('No package available.'))
Packit Service 21c75c
                except dnf.exceptions.MarkingError:
Packit Service 21c75c
                    assert False, 'Only the above marking errors are expected.'
Packit Service 21c75c
                else:
Packit Service 21c75c
                    done = True
Packit Service 21c75c
            else:
Packit Service 21c75c
                # Reinstall packages.
Packit Service 21c75c
                for pkg_spec in self.opts.pkg_specs:
Packit Service 21c75c
                    try:
Packit Service 21c75c
                        self.base.reinstall(pkg_spec, new_reponame=self.reponame)
Packit Service 21c75c
                    except dnf.exceptions.PackagesNotInstalledError:
Packit Service 21c75c
                        msg = _('No match for argument: %s')
Packit Service 21c75c
                        logger.info(msg, pkg_spec)
Packit Service 21c75c
                    except dnf.exceptions.PackagesNotAvailableError as err:
Packit Service 21c75c
                        for pkg in err.packages:
Packit Service 21c75c
                            xmsg = ''
Packit Service 21c75c
                            pkgrepo = self.base.history.repo(pkg)
Packit Service 21c75c
                            if pkgrepo:
Packit Service 21c75c
                                xmsg = _(' (from %s)') % pkgrepo
Packit Service 21c75c
                            msg = _('Installed package %s%s not available.')
Packit Service 21c75c
                            logger.info(msg, self.output.term.bold(pkg), xmsg)
Packit Service 21c75c
                    except dnf.exceptions.MarkingError:
Packit Service 21c75c
                        assert False, \
Packit Service 21c75c
                               'Only the above marking errors are expected.'
Packit Service 21c75c
                    else:
Packit Service 21c75c
                        done = True
Packit Service 21c75c
Packit Service 21c75c
            if not done:
Packit Service 21c75c
                raise dnf.exceptions.Error(_('Nothing to do.'))
Packit Service 21c75c
Packit Service 21c75c
    class ReinstallOldSubCommand(Command):
Packit Service 21c75c
        """Implementation of the reinstall-old sub-command."""
Packit Service 21c75c
Packit Service 21c75c
        aliases = ('reinstall-old',)
Packit Service 21c75c
Packit Service 21c75c
        def configure(self):
Packit Service 21c75c
            demands = self.cli.demands
Packit Service 21c75c
            demands.sack_activation = True
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
        def run_on_repo(self):
Packit Service 21c75c
            """Execute the command with respect to given arguments *cli_args*."""
Packit Service 21c75c
            _checkGPGKey(self.base, self.cli)
Packit Service 21c75c
Packit Service 21c75c
            done = False
Packit Service 21c75c
Packit Service 21c75c
            if not self.opts.pkg_specs:
Packit Service 21c75c
                # Reinstall all packages.
Packit Service 21c75c
                try:
Packit Service 21c75c
                    self.base.reinstall('*', self.reponame, self.reponame)
Packit Service 21c75c
                except dnf.exceptions.PackagesNotInstalledError:
Packit Service 21c75c
                    msg = _('No package installed from the repository.')
Packit Service 21c75c
                    logger.info(msg)
Packit Service 21c75c
                except dnf.exceptions.PackagesNotAvailableError:
Packit Service 21c75c
                    logger.info(_('No package available.'))
Packit Service 21c75c
                except dnf.exceptions.MarkingError:
Packit Service 21c75c
                    assert False, 'Only the above marking errors are expected.'
Packit Service 21c75c
                else:
Packit Service 21c75c
                    done = True
Packit Service 21c75c
            else:
Packit Service 21c75c
                # Reinstall packages.
Packit Service 21c75c
                for pkg_spec in self.opts.pkg_specs:
Packit Service 21c75c
                    try:
Packit Service 21c75c
                        self.base.reinstall(pkg_spec, self.reponame,
Packit Service 21c75c
                                            self.reponame)
Packit Service 21c75c
                    except dnf.exceptions.PackagesNotInstalledError:
Packit Service 21c75c
                        msg = _('No match for argument: %s')
Packit Service 21c75c
                        logger.info(msg, pkg_spec)
Packit Service 21c75c
                    except dnf.exceptions.PackagesNotAvailableError as err:
Packit Service 21c75c
                        for pkg in err.packages:
Packit Service 21c75c
                            xmsg = ''
Packit Service 21c75c
                            pkgrepo = self.base.history.repo(pkg)
Packit Service 21c75c
                            if pkgrepo:
Packit Service 21c75c
                                xmsg = _(' (from %s)') % pkgrepo
Packit Service 21c75c
                            msg = _('Installed package %s%s not available.')
Packit Service 21c75c
                            logger.info(msg, self.output.term.bold(pkg), xmsg)
Packit Service 21c75c
                    except dnf.exceptions.MarkingError:
Packit Service 21c75c
                        assert False, \
Packit Service 21c75c
                               'Only the above marking errors are expected.'
Packit Service 21c75c
                    else:
Packit Service 21c75c
                        done = True
Packit Service 21c75c
Packit Service 21c75c
            if not done:
Packit Service 21c75c
                raise dnf.exceptions.Error(_('Nothing to do.'))
Packit Service 21c75c
Packit Service 21c75c
    class ReinstallSubCommand(Command):
Packit Service 21c75c
        """Implementation of the reinstall sub-command."""
Packit Service 21c75c
Packit Service 21c75c
        aliases = ('reinstall',)
Packit Service 21c75c
Packit Service 21c75c
        def __init__(self, cli):
Packit Service 21c75c
            """Initialize the command."""
Packit Service 21c75c
            super(RepoPkgsCommand.ReinstallSubCommand, self).__init__(cli)
Packit Service 21c75c
            self.wrapped_commands = (RepoPkgsCommand.ReinstallOldSubCommand(cli),
Packit Service 21c75c
                                     RepoPkgsCommand.MoveToSubCommand(cli))
Packit Service 21c75c
Packit Service 21c75c
        def configure(self):
Packit Service 21c75c
            self.cli.demands.available_repos = True
Packit Service 21c75c
            for command in self.wrapped_commands:
Packit Service 21c75c
                command.opts = self.opts
Packit Service 21c75c
                command.reponame = self.reponame
Packit Service 21c75c
                command.configure()
Packit Service 21c75c
Packit Service 21c75c
        def run_on_repo(self):
Packit Service 21c75c
            """Execute the command with respect to given arguments *cli_args*."""
Packit Service 21c75c
            _checkGPGKey(self.base, self.cli)
Packit Service 21c75c
            for command in self.wrapped_commands:
Packit Service 21c75c
                try:
Packit Service 21c75c
                    command.run_on_repo()
Packit Service 21c75c
                except dnf.exceptions.Error:
Packit Service 21c75c
                    continue
Packit Service 21c75c
                else:
Packit Service 21c75c
                    break
Packit Service 21c75c
            else:
Packit Service 21c75c
                raise dnf.exceptions.Error(_('No packages marked for reinstall.'))
Packit Service 21c75c
Packit Service 21c75c
    class RemoveOrDistroSyncSubCommand(Command):
Packit Service 21c75c
        """Implementation of the remove-or-distro-sync sub-command."""
Packit Service 21c75c
Packit Service 21c75c
        aliases = ('remove-or-distro-sync',)
Packit Service 21c75c
Packit Service 21c75c
        def configure(self):
Packit Service 21c75c
            demands = self.cli.demands
Packit Service 21c75c
            demands.available_repos = True
Packit Service 21c75c
            demands.sack_activation = True
Packit Service 21c75c
            demands.resolving = True
Packit Service 21c75c
            demands.root_user = True
Packit Service 21c75c
Packit Service 21c75c
        def _replace(self, pkg_spec, reponame):
Packit Service 21c75c
            """Synchronize a package with another repository or remove it."""
Packit Service 21c75c
            self.cli.base.sack.disable_repo(reponame)
Packit Service 21c75c
Packit Service 21c75c
            subject = dnf.subject.Subject(pkg_spec)
Packit Service 21c75c
            matches = subject.get_best_query(self.cli.base.sack)
Packit Service 21c75c
            history = self.cli.base.history
Packit Service 21c75c
            installed = [
Packit Service 21c75c
                pkg for pkg in matches.installed()
Packit Service 21c75c
                if history.repo(pkg) == reponame]
Packit Service 21c75c
            if not installed:
Packit Service 21c75c
                raise dnf.exceptions.PackagesNotInstalledError(
Packit Service 21c75c
                    'no package matched', pkg_spec)
Packit Service 21c75c
            available = matches.available()
Packit Service 21c75c
            clean_deps = self.cli.base.conf.clean_requirements_on_remove
Packit Service 21c75c
            for package in installed:
Packit Service 21c75c
                if available.filter(name=package.name, arch=package.arch):
Packit Service 21c75c
                    self.cli.base._goal.distupgrade(package)
Packit Service 21c75c
                else:
Packit Service 21c75c
                    self.cli.base._goal.erase(package, clean_deps=clean_deps)
Packit Service 21c75c
Packit Service 21c75c
        def run_on_repo(self):
Packit Service 21c75c
            """Execute the command with respect to given arguments *cli_args*."""
Packit Service 21c75c
            _checkGPGKey(self.base, self.cli)
Packit Service 21c75c
Packit Service 21c75c
            done = False
Packit Service 21c75c
Packit Service 21c75c
            if not self.opts.pkg_specs:
Packit Service 21c75c
                # Sync all packages.
Packit Service 21c75c
                try:
Packit Service 21c75c
                    self._replace('*', self.reponame)
Packit Service 21c75c
                except dnf.exceptions.PackagesNotInstalledError:
Packit Service 21c75c
                    msg = _('No package installed from the repository.')
Packit Service 21c75c
                    logger.info(msg)
Packit Service 21c75c
                else:
Packit Service 21c75c
                    done = True
Packit Service 21c75c
            else:
Packit Service 21c75c
                # Reinstall packages.
Packit Service 21c75c
                for pkg_spec in self.opts.pkg_specs:
Packit Service 21c75c
                    try:
Packit Service 21c75c
                        self._replace(pkg_spec, self.reponame)
Packit Service 21c75c
                    except dnf.exceptions.PackagesNotInstalledError:
Packit Service 21c75c
                        msg = _('No match for argument: %s')
Packit Service 21c75c
                        logger.info(msg, pkg_spec)
Packit Service 21c75c
                    else:
Packit Service 21c75c
                        done = True
Packit Service 21c75c
Packit Service 21c75c
            if not done:
Packit Service 21c75c
                raise dnf.exceptions.Error(_('Nothing to do.'))
Packit Service 21c75c
Packit Service 21c75c
    class RemoveOrReinstallSubCommand(Command):
Packit Service 21c75c
        """Implementation of the remove-or-reinstall sub-command."""
Packit Service 21c75c
Packit Service 21c75c
        aliases = ('remove-or-reinstall',)
Packit Service 21c75c
Packit Service 21c75c
        def configure(self):
Packit Service 21c75c
            demands = self.cli.demands
Packit Service 21c75c
            demands.sack_activation = True
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
        def run_on_repo(self):
Packit Service 21c75c
            """Execute the command with respect to given arguments *cli_args*."""
Packit Service 21c75c
            _checkGPGKey(self.base, self.cli)
Packit Service 21c75c
Packit Service 21c75c
            done = False
Packit Service 21c75c
Packit Service 21c75c
            if not self.opts.pkg_specs:
Packit Service 21c75c
                # Reinstall all packages.
Packit Service 21c75c
                try:
Packit Service 21c75c
                    self.base.reinstall('*', old_reponame=self.reponame,
Packit Service 21c75c
                                        new_reponame_neq=self.reponame,
Packit Service 21c75c
                                        remove_na=True)
Packit Service 21c75c
                except dnf.exceptions.PackagesNotInstalledError:
Packit Service 21c75c
                    msg = _('No package installed from the repository.')
Packit Service 21c75c
                    logger.info(msg)
Packit Service 21c75c
                except dnf.exceptions.MarkingError:
Packit Service 21c75c
                    assert False, 'Only the above marking error is expected.'
Packit Service 21c75c
                else:
Packit Service 21c75c
                    done = True
Packit Service 21c75c
            else:
Packit Service 21c75c
                # Reinstall packages.
Packit Service 21c75c
                for pkg_spec in self.opts.pkg_specs:
Packit Service 21c75c
                    try:
Packit Service 21c75c
                        self.base.reinstall(
Packit Service 21c75c
                            pkg_spec, old_reponame=self.reponame,
Packit Service 21c75c
                            new_reponame_neq=self.reponame, remove_na=True)
Packit Service 21c75c
                    except dnf.exceptions.PackagesNotInstalledError:
Packit Service 21c75c
                        msg = _('No match for argument: %s')
Packit Service 21c75c
                        logger.info(msg, pkg_spec)
Packit Service 21c75c
                    except dnf.exceptions.MarkingError:
Packit Service 21c75c
                        assert False, 'Only the above marking error is expected.'
Packit Service 21c75c
                    else:
Packit Service 21c75c
                        done = True
Packit Service 21c75c
Packit Service 21c75c
            if not done:
Packit Service 21c75c
                raise dnf.exceptions.Error(_('Nothing to do.'))
Packit Service 21c75c
Packit Service 21c75c
    class RemoveSubCommand(Command):
Packit Service 21c75c
        """Implementation of the remove sub-command."""
Packit Service 21c75c
Packit Service 21c75c
        aliases = ('remove',)
Packit Service 21c75c
Packit Service 21c75c
        def configure(self):
Packit Service 21c75c
            demands = self.cli.demands
Packit Service 21c75c
            demands.sack_activation = True
Packit Service 21c75c
            demands.allow_erasing = True
Packit Service 21c75c
            demands.available_repos = False
Packit Service 21c75c
            demands.resolving = True
Packit Service 21c75c
            demands.root_user = True
Packit Service 21c75c
Packit Service 21c75c
        def run_on_repo(self):
Packit Service 21c75c
            """Execute the command with respect to given arguments *cli_args*."""
Packit Service 21c75c
Packit Service 21c75c
            done = False
Packit Service 21c75c
Packit Service 21c75c
            if not self.opts.pkg_specs:
Packit Service 21c75c
                # Remove all packages.
Packit Service 21c75c
                try:
Packit Service 21c75c
                    self.base.remove('*', self.reponame)
Packit Service 21c75c
                except dnf.exceptions.MarkingError:
Packit Service 21c75c
                    msg = _('No package installed from the repository.')
Packit Service 21c75c
                    logger.info(msg)
Packit Service 21c75c
                else:
Packit Service 21c75c
                    done = True
Packit Service 21c75c
            else:
Packit Service 21c75c
                # Remove packages.
Packit Service 21c75c
                for pkg_spec in self.opts.pkg_specs:
Packit Service 21c75c
                    try:
Packit Service 21c75c
                        self.base.remove(pkg_spec, self.reponame)
Packit Service 21c75c
                    except dnf.exceptions.MarkingError as e:
Packit Service 21c75c
                        logger.info(str(e))
Packit Service 21c75c
                    else:
Packit Service 21c75c
                        done = True
Packit Service 21c75c
Packit Service 21c75c
            if not done:
Packit Service 21c75c
                logger.warning(_('No packages marked for removal.'))
Packit Service 21c75c
Packit Service 21c75c
    class UpgradeSubCommand(Command):
Packit Service 21c75c
        """Implementation of the upgrade sub-command."""
Packit Service 21c75c
Packit Service 21c75c
        aliases = ('upgrade', 'upgrade-to')
Packit Service 21c75c
Packit Service 21c75c
        def configure(self):
Packit Service 21c75c
            demands = self.cli.demands
Packit Service 21c75c
            demands.sack_activation = True
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
        def run_on_repo(self):
Packit Service 21c75c
            """Execute the command with respect to given arguments *cli_args*."""
Packit Service 21c75c
            _checkGPGKey(self.base, self.cli)
Packit Service 21c75c
Packit Service 21c75c
            done = False
Packit Service 21c75c
Packit Service 21c75c
            if not self.opts.pkg_specs:
Packit Service 21c75c
                # Update all packages.
Packit Service 21c75c
                self.base.upgrade_all(self.reponame)
Packit Service 21c75c
                done = True
Packit Service 21c75c
            else:
Packit Service 21c75c
                # Update packages.
Packit Service 21c75c
                for pkg_spec in self.opts.pkg_specs:
Packit Service 21c75c
                    try:
Packit Service 21c75c
                        self.base.upgrade(pkg_spec, self.reponame)
Packit Service 21c75c
                    except dnf.exceptions.MarkingError:
Packit Service 21c75c
                        logger.info(_('No match for argument: %s'), pkg_spec)
Packit Service 21c75c
                    else:
Packit Service 21c75c
                        done = True
Packit Service 21c75c
Packit Service 21c75c
            if not done:
Packit Service 21c75c
                raise dnf.exceptions.Error(_('No packages marked for upgrade.'))
Packit Service 21c75c
Packit Service 21c75c
    SUBCMDS = {CheckUpdateSubCommand, InfoSubCommand, InstallSubCommand,
Packit Service 21c75c
               ListSubCommand, MoveToSubCommand, ReinstallOldSubCommand,
Packit Service 21c75c
               ReinstallSubCommand, RemoveOrDistroSyncSubCommand,
Packit Service 21c75c
               RemoveOrReinstallSubCommand, RemoveSubCommand,
Packit Service 21c75c
               UpgradeSubCommand}
Packit Service 21c75c
Packit Service 21c75c
    aliases = ('repository-packages',
Packit Service 21c75c
               'repo-pkgs', 'repo-packages', 'repository-pkgs')
Packit Service 21c75c
    summary = _('run commands on top of all packages in given repository')
Packit Service 21c75c
Packit Service 21c75c
    def __init__(self, cli):
Packit Service 21c75c
        """Initialize the command."""
Packit Service 21c75c
        super(RepoPkgsCommand, self).__init__(cli)
Packit Service 21c75c
        subcmd_objs = (subcmd(cli) for subcmd in self.SUBCMDS)
Packit Service 21c75c
        self.subcmd = None
Packit Service 21c75c
        self._subcmd_name2obj = {
Packit Service 21c75c
            alias: subcmd for subcmd in subcmd_objs for alias in subcmd.aliases}
Packit Service 21c75c
Packit Service 21c75c
    def set_argparser(self, parser):
Packit Service 21c75c
        narrows = parser.add_mutually_exclusive_group()
Packit Service 21c75c
        narrows.add_argument('--all', dest='_pkg_specs_action',
Packit Service 21c75c
                             action='store_const', const='all', default=None,
Packit Service 21c75c
                             help=_("show all packages (default)"))
Packit Service 21c75c
        narrows.add_argument('--available', dest='_pkg_specs_action',
Packit Service 21c75c
                             action='store_const', const='available',
Packit Service 21c75c
                             help=_("show only available packages"))
Packit Service 21c75c
        narrows.add_argument('--installed', dest='_pkg_specs_action',
Packit Service 21c75c
                             action='store_const', const='installed',
Packit Service 21c75c
                             help=_("show only installed packages"))
Packit Service 21c75c
        narrows.add_argument('--extras', dest='_pkg_specs_action',
Packit Service 21c75c
                             action='store_const', const='extras',
Packit Service 21c75c
                             help=_("show only extras packages"))
Packit Service 21c75c
        narrows.add_argument('--updates', dest='_pkg_specs_action',
Packit Service 21c75c
                             action='store_const', const='upgrades',
Packit Service 21c75c
                             help=_("show only upgrades packages"))
Packit Service 21c75c
        narrows.add_argument('--upgrades', dest='_pkg_specs_action',
Packit Service 21c75c
                             action='store_const', const='upgrades',
Packit Service 21c75c
                             help=_("show only upgrades packages"))
Packit Service 21c75c
        narrows.add_argument('--autoremove', dest='_pkg_specs_action',
Packit Service 21c75c
                             action='store_const', const='autoremove',
Packit Service 21c75c
                             help=_("show only autoremove packages"))
Packit Service 21c75c
        narrows.add_argument('--recent', dest='_pkg_specs_action',
Packit Service 21c75c
                             action='store_const', const='recent',
Packit Service 21c75c
                             help=_("show only recently changed packages"))
Packit Service 21c75c
Packit Service 21c75c
        parser.add_argument(
Packit Service 21c75c
            'reponame', nargs=1, action=OptionParser._RepoCallbackEnable,
Packit Service 21c75c
            metavar=_('REPOID'), help=_("Repository ID"))
Packit Service 21c75c
        subcommand_choices = [subcmd.aliases[0] for subcmd in self.SUBCMDS]
Packit Service 21c75c
        subcommand_choices_all = [alias for subcmd in self.SUBCMDS for alias in subcmd.aliases]
Packit Service 21c75c
        parser.add_argument('subcmd', nargs=1, metavar="SUBCOMMAND",
Packit Service 21c75c
                            choices=subcommand_choices_all, help=", ".join(subcommand_choices))
Packit Service 21c75c
        DEFAULT_PKGNARROW = 'all'
Packit Service 21c75c
        pkgnarrows = {DEFAULT_PKGNARROW, 'installed', 'available',
Packit Service 21c75c
                      'autoremove', 'extras', 'obsoletes', 'recent',
Packit Service 21c75c
                      'upgrades'}
Packit Service 21c75c
        parser.add_argument('pkg_specs', nargs='*', metavar=_('PACKAGE'),
Packit Service 21c75c
                            choices=pkgnarrows, default=DEFAULT_PKGNARROW,
Packit Service 21c75c
                            action=OptionParser.PkgNarrowCallback,
Packit Service 21c75c
                            help=_("Package specification"))
Packit Service 21c75c
Packit Service 21c75c
    def configure(self):
Packit Service 21c75c
        """Verify whether the command can run with given arguments."""
Packit Service 21c75c
        # Check sub-command.
Packit Service 21c75c
        try:
Packit Service 21c75c
            self.subcmd = self._subcmd_name2obj[self.opts.subcmd[0]]
Packit Service 21c75c
        except (dnf.cli.CliError, KeyError) as e:
Packit Service 21c75c
            self.cli.optparser.print_usage()
Packit Service 21c75c
            raise dnf.cli.CliError
Packit Service 21c75c
        self.subcmd.opts = self.opts
Packit Service 21c75c
        self.subcmd.reponame = self.opts.reponame[0]
Packit Service 21c75c
        self.subcmd.configure()
Packit Service 21c75c
Packit Service 21c75c
    def run(self):
Packit Service 21c75c
        """Execute the command with respect to given arguments *extcmds*."""
Packit Service 21c75c
        self.subcmd.run_on_repo()
Packit Service 21c75c
Packit Service 21c75c
class HelpCommand(Command):
Packit Service 21c75c
    """A class containing methods needed by the cli to execute the
Packit Service 21c75c
    help command.
Packit Service 21c75c
    """
Packit Service 21c75c
Packit Service 21c75c
    aliases = ('help',)
Packit Service 21c75c
    summary = _('display a helpful usage message')
Packit Service 21c75c
Packit Service 21c75c
    @staticmethod
Packit Service 21c75c
    def set_argparser(parser):
Packit Service 21c75c
        parser.add_argument('cmd', nargs='?', metavar=_('COMMAND'),
Packit Service 21c75c
                            help=_("{prog} command to get help for").format(
Packit Service 21c75c
                                prog=dnf.util.MAIN_PROG_UPPER))
Packit Service 21c75c
Packit Service 21c75c
    def run(self):
Packit Service 21c75c
        if (not self.opts.cmd
Packit Service 21c75c
                or self.opts.cmd not in self.cli.cli_commands):
Packit Service 21c75c
            self.cli.optparser.print_help()
Packit Service 21c75c
        else:
Packit Service 21c75c
            command = self.cli.cli_commands[self.opts.cmd]
Packit Service 21c75c
            self.cli.optparser.print_help(command(self))