Blame dnf/cli/main.py

Packit Service 21c75c
# Copyright 2005 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
"""
Packit Service 21c75c
Entrance point for 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 absolute_import
Packit Service 21c75c
from __future__ import unicode_literals
Packit Service 21c75c
from dnf.conf import Conf
Packit Service 21c75c
from dnf.cli.cli import Cli
Packit Service 21c75c
from dnf.cli.option_parser import OptionParser
Packit Service 21c75c
from dnf.i18n import ucd
Packit Service 21c75c
from dnf.cli.utils import show_lock_owner
Packit Service 21c75c
from dnf.i18n import _
Packit Service 21c75c
Packit Service 21c75c
import dnf.cli
Packit Service 21c75c
import dnf.cli.cli
Packit Service 21c75c
import dnf.cli.option_parser
Packit Service 21c75c
import dnf.exceptions
Packit Service 21c75c
import dnf.i18n
Packit Service 21c75c
import dnf.logging
Packit Service 21c75c
import dnf.util
Packit Service 21c75c
import errno
Packit Service 21c75c
import hawkey
Packit Service 21c75c
import libdnf.error
Packit Service 21c75c
import logging
Packit Service 21c75c
import os
Packit Service 21c75c
import os.path
Packit Service 21c75c
import sys
Packit Service 21c75c
Packit Service 21c75c
logger = logging.getLogger("dnf")
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def ex_IOError(e):
Packit Service 21c75c
    logger.log(dnf.logging.SUBDEBUG, '', exc_info=True)
Packit Service 21c75c
    logger.critical(ucd(e))
Packit Service 21c75c
    return 1
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def ex_Error(e):
Packit Service 21c75c
    logger.log(dnf.logging.SUBDEBUG, '', exc_info=True)
Packit Service 21c75c
    if e.value is not None:
Packit Service 21c75c
        logger.critical(_('Error: %s'), ucd(e))
Packit Service 21c75c
    return 1
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def main(args, conf_class=Conf, cli_class=Cli, option_parser_class=OptionParser):
Packit Service 21c75c
    try:
Packit Service 21c75c
        dnf.i18n.setup_stdout()
Packit Service 21c75c
        with dnf.cli.cli.BaseCli(conf_class()) as base:
Packit Service 21c75c
            return _main(base, args, cli_class, option_parser_class)
Packit Service 21c75c
    except dnf.exceptions.ProcessLockError as e:
Packit Service 21c75c
        logger.critical(e.value)
Packit Service 21c75c
        show_lock_owner(e.pid)
Packit Service 21c75c
        return 200
Packit Service 21c75c
    except dnf.exceptions.LockError as e:
Packit Service 21c75c
        logger.critical(e.value)
Packit Service 21c75c
        return 200
Packit Service 21c75c
    except dnf.exceptions.DepsolveError as e:
Packit Service 21c75c
        return 1
Packit Service 21c75c
    except dnf.exceptions.Error as e:
Packit Service 21c75c
        return ex_Error(e)
Packit Service 21c75c
    except hawkey.Exception as e:
Packit Service 21c75c
        logger.critical(_('Error: %s'), ucd(e))
Packit Service 21c75c
        return 1
Packit Service 21c75c
    except libdnf.error.Error as e:
Packit Service 21c75c
        logger.critical(_('Error: %s'), ucd(e))
Packit Service 21c75c
        return 1
Packit Service 21c75c
    except IOError as e:
Packit Service 21c75c
        return ex_IOError(e)
Packit Service 21c75c
    except KeyboardInterrupt as e:
Packit Service 21c75c
        logger.critical('{}: {}'.format(type(e).__name__, _("Terminated.")))
Packit Service 21c75c
        return 1
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def _main(base, args, cli_class, option_parser):
Packit Service 21c75c
    """Run the dnf program from a command line interface."""
Packit Service 21c75c
Packit Service 21c75c
    # our core object for the cli
Packit Service 21c75c
    base._logging._presetup()
Packit Service 21c75c
    cli = cli_class(base)
Packit Service 21c75c
Packit Service 21c75c
    # do our cli parsing and config file setup
Packit Service 21c75c
    # also sanity check the things being passed on the cli
Packit Service 21c75c
    try:
Packit Service 21c75c
        cli.configure(list(map(ucd, args)), option_parser())
Packit Service 21c75c
    except (IOError, OSError) as e:
Packit Service 21c75c
        return ex_IOError(e)
Packit Service 21c75c
Packit Service 21c75c
    return cli_run(cli, base)
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def cli_run(cli, base):
Packit Service 21c75c
    # Try to open the current directory to see if we have
Packit Service 21c75c
    # read and execute access. If not, chdir to /
Packit Service 21c75c
    try:
Packit Service 21c75c
        f = open(".")
Packit Service 21c75c
    except IOError as e:
Packit Service 21c75c
        if e.errno == errno.EACCES:
Packit Service 21c75c
            logger.critical(_('No read/execute access in current directory, moving to /'))
Packit Service 21c75c
            os.chdir("/")
Packit Service 21c75c
    else:
Packit Service 21c75c
        f.close()
Packit Service 21c75c
Packit Service 21c75c
    try:
Packit Service 21c75c
        cli.run()
Packit Service 21c75c
    except dnf.exceptions.LockError:
Packit Service 21c75c
        raise
Packit Service 21c75c
    except (IOError, OSError) as e:
Packit Service 21c75c
        return ex_IOError(e)
Packit Service 21c75c
Packit Service 21c75c
    if cli.demands.resolving:
Packit Service 21c75c
        try:
Packit Service 21c75c
            ret = resolving(cli, base)
Packit Service 21c75c
        except dnf.exceptions.DepsolveError as e:
Packit Service 21c75c
            ex_Error(e)
Packit Service 21c75c
            msg = ""
Packit Service 21c75c
            if not cli.demands.allow_erasing and base._goal.problem_conflicts(available=True):
Packit Service 21c75c
                msg += _("try to add '{}' to command line to replace conflicting "
Packit Service 21c75c
                         "packages").format("--allowerasing")
Packit Service 21c75c
            if cli.base.conf.strict:
Packit Service 21c75c
                if not msg:
Packit Service 21c75c
                    msg += _("try to add '{}' to skip uninstallable packages").format(
Packit Service 21c75c
                        "--skip-broken")
Packit Service 21c75c
                else:
Packit Service 21c75c
                    msg += _(" or '{}' to skip uninstallable packages").format("--skip-broken")
Packit Service 21c75c
            if cli.base.conf.best:
Packit Service 21c75c
                prio = cli.base.conf._get_priority("best")
Packit Service 21c75c
                if prio <= dnf.conf.PRIO_MAINCONFIG:
Packit Service 21c75c
                    if not msg:
Packit Service 21c75c
                        msg += _("try to add '{}' to use not only best candidate packages").format(
Packit Service 21c75c
                            "--nobest")
Packit Service 21c75c
                    else:
Packit Service 21c75c
                        msg += _(" or '{}' to use not only best candidate packages").format(
Packit Service 21c75c
                            "--nobest")
Packit Service 21c75c
            if msg:
Packit Service 21c75c
                logger.info("({})".format(msg))
Packit Service 21c75c
            raise
Packit Service 21c75c
        if ret:
Packit Service 21c75c
            return ret
Packit Service 21c75c
Packit Service 21c75c
    cli.command.run_transaction()
Packit Service 21c75c
    return cli.demands.success_exit_status
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def resolving(cli, base):
Packit Service 21c75c
    """Perform the depsolve, download and RPM transaction stage."""
Packit Service 21c75c
Packit Service 21c75c
    if base.transaction is None:
Packit Service 21c75c
        base.resolve(cli.demands.allow_erasing)
Packit Service 21c75c
        logger.info(_('Dependencies resolved.'))
Packit Service 21c75c
Packit Service 21c75c
    cli.command.run_resolved()
Packit Service 21c75c
Packit Service 21c75c
    # Run the transaction
Packit Service 21c75c
    displays = []
Packit Service 21c75c
    if cli.demands.transaction_display is not None:
Packit Service 21c75c
        displays.append(cli.demands.transaction_display)
Packit Service 21c75c
    try:
Packit Service 21c75c
        base.do_transaction(display=displays)
Packit Service 21c75c
    except dnf.cli.CliError as exc:
Packit Service 21c75c
        logger.error(ucd(exc))
Packit Service 21c75c
        return 1
Packit Service 21c75c
    except dnf.exceptions.TransactionCheckError as err:
Packit Service 21c75c
        for msg in cli.command.get_error_output(err):
Packit Service 21c75c
            logger.critical(msg)
Packit Service 21c75c
        return 1
Packit Service 21c75c
    except IOError as e:
Packit Service 21c75c
        return ex_IOError(e)
Packit Service 21c75c
    else:
Packit Service 21c75c
        logger.info(_('Complete!'))
Packit Service 21c75c
    return 0
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
def user_main(args, exit_code=False):
Packit Service 21c75c
    """Call one of the multiple main() functions based on environment variables.
Packit Service 21c75c
Packit Service 21c75c
    :param args: command line arguments passed into yum
Packit Service 21c75c
    :param exit_code: if *exit_code* is True, this function will exit
Packit Service 21c75c
       python with its exit code when it has finished executing.
Packit Service 21c75c
       Otherwise, it will return its exit code.
Packit Service 21c75c
    :return: the exit code from dnf.yum execution
Packit Service 21c75c
    """
Packit Service 21c75c
Packit Service 21c75c
    errcode = main(args)
Packit Service 21c75c
    if exit_code:
Packit Service 21c75c
        sys.exit(errcode)
Packit Service 21c75c
    return errcode
Packit Service 21c75c
Packit Service 21c75c
Packit Service 21c75c
if __name__ == "__main__":
Packit Service 21c75c
    user_main(sys.argv[1:], exit_code=True)