Blame dnf/cli/commands/install.py

Packit Service 21c75c
# install.py
Packit Service 21c75c
# Install CLI command.
Packit Service 21c75c
#
Packit Service 21c75c
# Copyright (C) 2014-2016 Red Hat, Inc.
Packit Service 21c75c
#
Packit Service 21c75c
# This copyrighted material is made available to anyone wishing to use,
Packit Service 21c75c
# modify, copy, or redistribute it subject to the terms and conditions of
Packit Service 21c75c
# the GNU General Public License v.2, or (at your option) any later version.
Packit Service 21c75c
# This program is distributed in the hope that it will be useful, but WITHOUT
Packit Service 21c75c
# ANY WARRANTY expressed or implied, including the implied warranties of
Packit Service 21c75c
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit Service 21c75c
# Public License for more details.  You should have received a copy of the
Packit Service 21c75c
# GNU General Public License along with this program; if not, write to the
Packit Service 21c75c
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 21c75c
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
Packit Service 21c75c
# source code or documentation are not subject to the GNU General Public
Packit Service 21c75c
# License and may only be used or replicated with the express permission of
Packit Service 21c75c
# Red Hat, Inc.
Packit Service 21c75c
#
Packit Service 21c75c
Packit Service 21c75c
from __future__ import absolute_import
Packit Service 21c75c
from __future__ import unicode_literals
Packit Service 21c75c
Packit Service 21c75c
import logging
Packit Service 21c75c
from itertools import chain
Packit Service 21c75c
Packit Service 21c75c
import hawkey
Packit Service 21c75c
Packit Service 21c75c
import dnf.exceptions
Packit Service 21c75c
from dnf.cli import commands
Packit Service 21c75c
from dnf.cli.option_parser import OptionParser
Packit Service 21c75c
from dnf.i18n import _
Packit Service 21c75c
Packit Service 21c75c
logger = logging.getLogger('dnf')
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
class InstallCommand(commands.Command):
Packit Service 21c75c
    """A class containing methods needed by the cli to execute the
Packit Service 21c75c
    install command.
Packit Service 21c75c
    """
Packit Service 21c75c
    nevra_forms = {'install-n': hawkey.FORM_NAME,
Packit Service 21c75c
                   'install-na': hawkey.FORM_NA,
Packit Service 21c75c
                   'install-nevra': hawkey.FORM_NEVRA}
Packit Service 21c75c
    alternatives_provide = 'alternative-for({})'
Packit Service 21c75c
Packit Service 21c75c
    aliases = ('install', 'localinstall', 'in') + tuple(nevra_forms.keys())
Packit Service 21c75c
    summary = _('install a package or packages on your system')
Packit Service 21c75c
Packit Service 21c75c
    @staticmethod
Packit Service 21c75c
    def set_argparser(parser):
Packit Service 21c75c
        parser.add_argument('package', nargs='+', metavar=_('PACKAGE'),
Packit Service 21c75c
                            action=OptionParser.ParseSpecGroupFileCallback,
Packit Service 21c75c
                            help=_('Package to install'))
Packit Service 21c75c
Packit Service 21c75c
    def configure(self):
Packit Service 21c75c
        """Verify that conditions are met so that this command can run.
Packit Service 21c75c
        That there are enabled repositories with gpg keys, and that
Packit Service 21c75c
        this command is called with appropriate arguments.
Packit Service 21c75c
        """
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
        commands._checkGPGKey(self.base, self.cli)
Packit Service 21c75c
        if not self.opts.filenames:
Packit Service 21c75c
            commands._checkEnabledRepo(self.base)
Packit Service 21c75c
Packit Service 21c75c
    def run(self):
Packit Service 21c75c
        err_pkgs = []
Packit Service 21c75c
        errs = []
Packit Service 21c75c
        error_module_specs = []
Packit Service 21c75c
Packit Service 21c75c
        nevra_forms = self._get_nevra_forms_from_command()
Packit Service 21c75c
Packit Service 21c75c
        self.cli._populate_update_security_filter(self.opts, self.base.sack.query())
Packit Service 21c75c
        if self.opts.command == 'localinstall' and (self.opts.grp_specs or self.opts.pkg_specs):
Packit Service 21c75c
            self._log_not_valid_rpm_file_paths(self.opts.grp_specs)
Packit Service 21c75c
            if self.base.conf.strict:
Packit Service 21c75c
                raise dnf.exceptions.Error(_('Nothing to do.'))
Packit Service 21c75c
        skipped_grp_specs = []
Packit Service 21c75c
        if self.opts.grp_specs and self.opts.command != 'localinstall':
Packit Service 21c75c
            if dnf.base.WITH_MODULES:
Packit Service 21c75c
                try:
Packit Service 21c75c
                    module_base = dnf.module.module_base.ModuleBase(self.base)
Packit Service 21c75c
                    module_base.install(self.opts.grp_specs, strict=self.base.conf.strict)
Packit Service 21c75c
                except dnf.exceptions.MarkingErrors as e:
Packit Service 21c75c
                    if e.no_match_group_specs:
Packit Service 21c75c
                        for e_spec in e.no_match_group_specs:
Packit Service 21c75c
                            skipped_grp_specs.append(e_spec)
Packit Service 21c75c
                    if e.error_group_specs:
Packit Service 21c75c
                        for e_spec in e.error_group_specs:
Packit Service 21c75c
                            error_module_specs.append("@" + e_spec)
Packit Service 21c75c
                    module_depsolv_errors = e.module_depsolv_errors
Packit Service 21c75c
                    if module_depsolv_errors:
Packit Service 21c75c
                        logger.error(dnf.module.module_base.format_modular_solver_errors(
Packit Service 21c75c
                            module_depsolv_errors[0]))
Packit Service 21c75c
            else:
Packit Service 21c75c
                skipped_grp_specs = self.opts.grp_specs
Packit Service 21c75c
        if self.opts.filenames and nevra_forms:
Packit Service 21c75c
            self._inform_not_a_valid_combination(self.opts.filenames)
Packit Service 21c75c
            if self.base.conf.strict:
Packit Service 21c75c
                raise dnf.exceptions.Error(_('Nothing to do.'))
Packit Service 21c75c
        else:
Packit Service 21c75c
            err_pkgs = self._install_files()
Packit Service 21c75c
Packit Service 21c75c
        if skipped_grp_specs and nevra_forms:
Packit Service 21c75c
            self._inform_not_a_valid_combination(skipped_grp_specs)
Packit Service 21c75c
            if self.base.conf.strict:
Packit Service 21c75c
                raise dnf.exceptions.Error(_('Nothing to do.'))
Packit Service 21c75c
        elif skipped_grp_specs and self.opts.command != 'localinstall':
Packit Service 21c75c
            self._install_groups(skipped_grp_specs)
Packit Service 21c75c
Packit Service 21c75c
        if self.opts.command != 'localinstall':
Packit Service 21c75c
            errs = self._install_packages(nevra_forms)
Packit Service 21c75c
Packit Service 21c75c
        if (len(errs) != 0 or len(err_pkgs) != 0 or error_module_specs) and self.base.conf.strict:
Packit Service 21c75c
            raise dnf.exceptions.PackagesNotAvailableError(_("Unable to find a match"),
Packit Service 21c75c
                                                           pkg_spec=' '.join(errs),
Packit Service 21c75c
                                                           packages=err_pkgs)
Packit Service 21c75c
Packit Service 21c75c
    def _get_nevra_forms_from_command(self):
Packit Service 21c75c
        if self.opts.command in self.nevra_forms:
Packit Service 21c75c
            return [self.nevra_forms[self.opts.command]]
Packit Service 21c75c
        else:
Packit Service 21c75c
            return []
Packit Service 21c75c
Packit Service 21c75c
    def _log_not_valid_rpm_file_paths(self, grp_specs):
Packit Service 21c75c
        group_names = map(lambda g: '@' + g, grp_specs)
Packit Service 21c75c
        for pkg in chain(self.opts.pkg_specs, group_names):
Packit Service 21c75c
            msg = _('Not a valid rpm file path: %s')
Packit Service 21c75c
            logger.info(msg, self.base.output.term.bold(pkg))
Packit Service 21c75c
Packit Service 21c75c
    def _inform_not_a_valid_combination(self, forms):
Packit Service 21c75c
        for form in forms:
Packit Service 21c75c
            msg = _('Not a valid form: %s')
Packit Service 21c75c
            logger.warning(msg, self.base.output.term.bold(form))
Packit Service 21c75c
Packit Service 21c75c
    def _install_files(self):
Packit Service 21c75c
        err_pkgs = []
Packit Service 21c75c
        strict = self.base.conf.strict
Packit Service 21c75c
        for pkg in self.base.add_remote_rpms(self.opts.filenames, strict=strict,
Packit Service 21c75c
                                             progress=self.base.output.progress):
Packit Service 21c75c
            try:
Packit Service 21c75c
                self.base.package_install(pkg, strict=strict)
Packit Service 21c75c
            except dnf.exceptions.MarkingError:
Packit Service 21c75c
                msg = _('No match for argument: %s')
Packit Service 21c75c
                logger.info(msg, self.base.output.term.bold(pkg.location))
Packit Service 21c75c
                err_pkgs.append(pkg)
Packit Service 21c75c
Packit Service 21c75c
        return err_pkgs
Packit Service 21c75c
Packit Service 21c75c
    def _install_groups(self, grp_specs):
Packit Service 21c75c
        try:
Packit Service 21c75c
            self.base.env_group_install(grp_specs,
Packit Service 21c75c
                                        tuple(self.base.conf.group_package_types),
Packit Service 21c75c
                                        strict=self.base.conf.strict)
Packit Service 21c75c
        except dnf.exceptions.Error:
Packit Service 21c75c
            if self.base.conf.strict:
Packit Service 21c75c
                raise
Packit Service 21c75c
Packit Service 21c75c
    def _report_alternatives(self, pkg_spec):
Packit Service 21c75c
        query = self.base.sack.query().filterm(
Packit Service 21c75c
            provides=self.alternatives_provide.format(pkg_spec))
Packit Service 21c75c
        if query:
Packit Service 21c75c
            msg = _('There are following alternatives for "{0}": {1}')
Packit Service 21c75c
            logger.info(msg.format(
Packit Service 21c75c
                pkg_spec,
Packit Service 21c75c
                ', '.join(sorted(set([alt.name for alt in query])))))
Packit Service 21c75c
Packit Service 21c75c
    def _install_packages(self, nevra_forms):
Packit Service 21c75c
        errs = []
Packit Service 21c75c
        strict = self.base.conf.strict
Packit Service 21c75c
        for pkg_spec in self.opts.pkg_specs:
Packit Service 21c75c
            try:
Packit Service 21c75c
                self.base.install(pkg_spec, strict=strict, forms=nevra_forms)
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
                self.base._report_icase_hint(pkg_spec)
Packit Service 21c75c
                self._report_alternatives(pkg_spec)
Packit Service 21c75c
                errs.append(pkg_spec)
Packit Service 21c75c
Packit Service 21c75c
        return errs