Blame dnf/cli/commands/install.py

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