Blame dnf/cli/main.py

Packit 6f3914
# Copyright 2005 Duke University
Packit 6f3914
# Copyright (C) 2012-2016 Red Hat, Inc.
Packit 6f3914
#
Packit 6f3914
# This program is free software; you can redistribute it and/or modify
Packit 6f3914
# it under the terms of the GNU General Public License as published by
Packit 6f3914
# the Free Software Foundation; either version 2 of the License, or
Packit 6f3914
# (at your option) any later version.
Packit 6f3914
#
Packit 6f3914
# This program is distributed in the hope that it will be useful,
Packit 6f3914
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6f3914
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 6f3914
# GNU Library General Public License for more details.
Packit 6f3914
#
Packit 6f3914
# You should have received a copy of the GNU General Public License
Packit 6f3914
# along with this program; if not, write to the Free Software
Packit 6f3914
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit 6f3914
Packit 6f3914
"""
Packit 6f3914
Entrance point for the yum command line interface.
Packit 6f3914
"""
Packit 6f3914
Packit 6f3914
from __future__ import print_function
Packit 6f3914
from __future__ import absolute_import
Packit 6f3914
from __future__ import unicode_literals
Packit 6f3914
from dnf.conf import Conf
Packit 6f3914
from dnf.cli.cli import Cli
Packit 6f3914
from dnf.cli.option_parser import OptionParser
Packit 6f3914
from dnf.i18n import ucd
Packit 6f3914
from dnf.cli.utils import show_lock_owner
Packit 6f3914
from dnf.i18n import _
Packit 6f3914
Packit 6f3914
import dnf.cli
Packit 6f3914
import dnf.cli.cli
Packit 6f3914
import dnf.cli.option_parser
Packit 6f3914
import dnf.exceptions
Packit 6f3914
import dnf.i18n
Packit 6f3914
import dnf.logging
Packit 6f3914
import dnf.util
Packit 6f3914
import errno
Packit 6f3914
import logging
Packit 6f3914
import os
Packit 6f3914
import os.path
Packit 6f3914
import sys
Packit 6f3914
Packit 6f3914
logger = logging.getLogger("dnf")
Packit 6f3914
Packit 6f3914
Packit 6f3914
def ex_IOError(e):
Packit 6f3914
    logger.log(dnf.logging.SUBDEBUG, '', exc_info=True)
Packit 6f3914
    logger.critical(ucd(e))
Packit 6f3914
    return 1
Packit 6f3914
Packit 6f3914
Packit 6f3914
def ex_Error(e):
Packit 6f3914
    logger.log(dnf.logging.SUBDEBUG, '', exc_info=True)
Packit 6f3914
    if e.value is not None:
Packit 6f3914
        logger.critical(_('Error: %s'), ucd(e))
Packit 6f3914
    return 1
Packit 6f3914
Packit 6f3914
Packit 6f3914
def main(args, conf_class=Conf, cli_class=Cli, option_parser_class=OptionParser):
Packit 6f3914
    try:
Packit 6f3914
        dnf.i18n.setup_stdout()
Packit 6f3914
        with dnf.cli.cli.BaseCli(conf_class()) as base:
Packit 6f3914
            return _main(base, args, cli_class, option_parser_class)
Packit 6f3914
    except dnf.exceptions.ProcessLockError as e:
Packit 6f3914
        logger.critical(e.value)
Packit 6f3914
        show_lock_owner(e.pid)
Packit 6f3914
        return 200
Packit 6f3914
    except dnf.exceptions.LockError as e:
Packit 6f3914
        logger.critical(e.value)
Packit 6f3914
        return 200
Packit 6f3914
    except dnf.exceptions.DepsolveError as e:
Packit 6f3914
        return 1
Packit 6f3914
    except dnf.exceptions.Error as e:
Packit 6f3914
        return ex_Error(e)
Packit 6f3914
    except IOError as e:
Packit 6f3914
        return ex_IOError(e)
Packit 6f3914
    except KeyboardInterrupt as e:
Packit 6f3914
        logger.critical('{}: {}'.format(type(e).__name__, _("Terminated.")))
Packit 6f3914
        return 1
Packit 6f3914
Packit 6f3914
Packit 6f3914
def _main(base, args, cli_class, option_parser):
Packit 6f3914
    """Run the dnf program from a command line interface."""
Packit 6f3914
Packit 6f3914
    # our core object for the cli
Packit 6f3914
    base._logging._presetup()
Packit 6f3914
    cli = cli_class(base)
Packit 6f3914
Packit 6f3914
    # do our cli parsing and config file setup
Packit 6f3914
    # also sanity check the things being passed on the cli
Packit 6f3914
    try:
Packit 6f3914
        cli.configure(list(map(ucd, args)), option_parser())
Packit 6f3914
    except (IOError, OSError) as e:
Packit 6f3914
        return ex_IOError(e)
Packit 6f3914
Packit 6f3914
    return cli_run(cli, base)
Packit 6f3914
Packit 6f3914
Packit 6f3914
def cli_run(cli, base):
Packit 6f3914
    # Try to open the current directory to see if we have
Packit 6f3914
    # read and execute access. If not, chdir to /
Packit 6f3914
    try:
Packit 6f3914
        f = open(".")
Packit 6f3914
    except IOError as e:
Packit 6f3914
        if e.errno == errno.EACCES:
Packit 6f3914
            logger.critical(_('No read/execute access in current directory, moving to /'))
Packit 6f3914
            os.chdir("/")
Packit 6f3914
    else:
Packit 6f3914
        f.close()
Packit 6f3914
Packit 6f3914
    try:
Packit 6f3914
        cli.run()
Packit 6f3914
    except dnf.exceptions.LockError:
Packit 6f3914
        raise
Packit 6f3914
    except (IOError, OSError) as e:
Packit 6f3914
        return ex_IOError(e)
Packit 6f3914
Packit 6f3914
    if cli.demands.resolving:
Packit 6f3914
        try:
Packit 6f3914
            ret = resolving(cli, base)
Packit 6f3914
        except dnf.exceptions.DepsolveError as e:
Packit 6f3914
            ex_Error(e)
Packit 6f3914
            msg = ""
Packit 6f3914
            if not cli.demands.allow_erasing and base._goal.problem_conflicts(available=True):
Packit 6f3914
                msg += _("try to add '{}' to command line to replace conflicting "
Packit 6f3914
                         "packages").format("--allowerasing")
Packit 6f3914
            if cli.base.conf.strict:
Packit 6f3914
                if not msg:
Packit 6f3914
                    msg += _("try to add '{}' to skip uninstallable packages").format(
Packit 6f3914
                        "--skip-broken")
Packit 6f3914
                else:
Packit 6f3914
                    msg += _(" or '{}' to skip uninstallable packages").format("--skip-broken")
Packit 6f3914
            if cli.base.conf.best:
Packit 6f3914
                prio = cli.base.conf._get_priority("best")
Packit 6f3914
                if prio <= dnf.conf.PRIO_MAINCONFIG:
Packit 6f3914
                    if not msg:
Packit 6f3914
                        msg += _("try to add '{}' to use not only best candidate packages").format(
Packit 6f3914
                            "--nobest")
Packit 6f3914
                    else:
Packit 6f3914
                        msg += _(" or '{}' to use not only best candidate packages").format(
Packit 6f3914
                            "--nobest")
Packit 6f3914
            if msg:
Packit 6f3914
                logger.info("({})".format(msg))
Packit 6f3914
            raise
Packit 6f3914
        if ret:
Packit 6f3914
            return ret
Packit 6f3914
Packit 6f3914
    cli.command.run_transaction()
Packit 6f3914
    return cli.demands.success_exit_status
Packit 6f3914
Packit 6f3914
Packit 6f3914
def resolving(cli, base):
Packit 6f3914
    """Perform the depsolve, download and RPM transaction stage."""
Packit 6f3914
Packit 6f3914
    if base.transaction is None:
Packit 6f3914
        base.resolve(cli.demands.allow_erasing)
Packit 6f3914
        logger.info(_('Dependencies resolved.'))
Packit 6f3914
Packit 6f3914
    # Run the transaction
Packit 6f3914
    displays = []
Packit 6f3914
    if cli.demands.transaction_display is not None:
Packit 6f3914
        displays.append(cli.demands.transaction_display)
Packit 6f3914
    try:
Packit 6f3914
        base.do_transaction(display=displays)
Packit 6f3914
    except dnf.cli.CliError as exc:
Packit 6f3914
        logger.error(ucd(exc))
Packit 6f3914
        return 1
Packit 6f3914
    except dnf.exceptions.TransactionCheckError as err:
Packit 6f3914
        for msg in cli.command.get_error_output(err):
Packit 6f3914
            logger.critical(msg)
Packit 6f3914
        return 1
Packit 6f3914
    except IOError as e:
Packit 6f3914
        return ex_IOError(e)
Packit 6f3914
    else:
Packit 6f3914
        logger.info(_('Complete!'))
Packit 6f3914
    return 0
Packit 6f3914
Packit 6f3914
Packit 6f3914
def user_main(args, exit_code=False):
Packit 6f3914
    """Call one of the multiple main() functions based on environment variables.
Packit 6f3914
Packit 6f3914
    :param args: command line arguments passed into yum
Packit 6f3914
    :param exit_code: if *exit_code* is True, this function will exit
Packit 6f3914
       python with its exit code when it has finished executing.
Packit 6f3914
       Otherwise, it will return its exit code.
Packit 6f3914
    :return: the exit code from dnf.yum execution
Packit 6f3914
    """
Packit 6f3914
Packit 6f3914
    errcode = main(args)
Packit 6f3914
    if exit_code:
Packit 6f3914
        sys.exit(errcode)
Packit 6f3914
    return errcode
Packit 6f3914
Packit 6f3914
Packit 6f3914
if __name__ == "__main__":
Packit 6f3914
    user_main(sys.argv[1:], exit_code=True)