1516N/A#!/usr/bin/python
26N/A#
26N/A# CDDL HEADER START
26N/A#
26N/A# The contents of this file are subject to the terms of the
26N/A# Common Development and Distribution License (the "License").
26N/A# You may not use this file except in compliance with the License.
26N/A#
26N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
26N/A# or http://www.opensolaris.org/os/licensing.
26N/A# See the License for the specific language governing permissions
26N/A# and limitations under the License.
26N/A#
26N/A# When distributing Covered Code, include this CDDL HEADER in each
26N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
26N/A# If applicable, add the following below this CDDL HEADER, with the
26N/A# fields enclosed by brackets "[]" replaced with your own identifying
26N/A# information: Portions Copyright [yyyy] [name of copyright owner]
26N/A#
26N/A# CDDL HEADER END
26N/A#
26N/A
2466N/A#
3351N/A# Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
2466N/A#
26N/A
2828N/A# Missing docstring; pylint: disable=C0111
2693N/A
1431N/Aimport logging
1218N/Aimport os
1431N/Aimport sys
1218N/A
576N/A__all__ = ["global_settings"]
576N/A
1431N/Aclass _LogFilter(logging.Filter):
1431N/A def __init__(self, max_level=logging.CRITICAL):
1431N/A logging.Filter.__init__(self)
1431N/A self.max_level = max_level
1431N/A
1431N/A def filter(self, record):
1431N/A return record.levelno <= self.max_level
1431N/A
2466N/A
2466N/Aclass _StreamHandler(logging.StreamHandler):
2466N/A """Simple subclass to ignore exceptions raised during logging output."""
2466N/A
2466N/A def handleError(self, record):
2466N/A # Ignore exceptions raised during output to stdout/stderr.
2466N/A return
2466N/A
2466N/A
576N/Aclass GlobalSettings(object):
576N/A """ This class defines settings which are global
576N/A to the client instance """
576N/A
576N/A def __init__(self):
576N/A object.__init__(self)
1431N/A self.__info_log_handler = None
1431N/A self.__error_log_handler = None
1431N/A self.__verbose = False
2690N/A
2693N/A #
2693N/A # These properties allow the client to describe how it
2693N/A # has been asked to behave with respect to output. This
2693N/A # allows subprocess invocations (e.g. for linked images) to
2693N/A # discover from the global settings how they are expected
2693N/A # to behave.
2693N/A #
2693N/A self.client_output_verbose = 0
2693N/A self.client_output_quiet = False
2693N/A self.client_output_parsable_version = None
3351N/A self.client_no_network_cache = False
2693N/A
2690N/A # runid, used by the pkg.1 client and the linked image
2690N/A # subsystem when when generating temporary files.
2690N/A self.client_runid = os.getpid()
2690N/A
2690N/A # file descriptor used by ProgressTracker classes when running
2690N/A # "pkg remote" to indicate progress back to the parent/client
2690N/A # process.
2690N/A self.client_output_progfd = None
2690N/A
2690N/A # concurrency value used for linked image recursion
2896N/A self.client_concurrency_set = False
2690N/A self.client_concurrency_default = 1
2690N/A self.client_concurrency = self.client_concurrency_default
2690N/A try:
2690N/A self.client_concurrency = int(os.environ.get(
2690N/A "PKG_CONCURRENCY",
2690N/A self.client_concurrency_default))
2896N/A if "PKG_CONCURRENCY" in os.environ:
2896N/A self.client_concurrency_set = True
2690N/A # remove PKG_CONCURRENCY from the environment so child
2690N/A # processes don't inherit it.
2690N/A os.environ.pop("PKG_CONCURRENCY", None)
2690N/A except ValueError:
2690N/A pass
2690N/A
696N/A self.client_name = None
2092N/A self.client_args = sys.argv[:]
1448N/A # Default maximum number of redirects received before
1448N/A # aborting a connection.
1448N/A self.pkg_client_max_redirect_default = 5
1448N/A # Default number of retries per-host
1218N/A self.pkg_client_max_timeout_default = 4
1448N/A # Default number of seconds to give up if not connected
1218N/A self.pkg_client_connect_timeout_default = 60
1448N/A # Default number of seconds beneath low-speed limit before
1448N/A # giving up.
1218N/A self.pkg_client_lowspeed_timeout_default = 30
1218N/A # Minimum bytes/sec before client thinks about giving up
1218N/A # on connection.
1218N/A self.pkg_client_lowspeed_limit = 1024
1448N/A # Maximum number of transient errors before we abort an
1448N/A # endpoint.
1448N/A self.pkg_client_max_consecutive_error_default = 4
2678N/A
3356N/A # The location within the image of the cache for pkg.sysrepo(8)
2678N/A self.sysrepo_pub_cache_path = \
2678N/A "var/cache/pkg/sysrepo_pub_cache.dat"
2678N/A
1218N/A try:
1218N/A # Maximum number of timeouts before client gives up.
1218N/A self.PKG_CLIENT_MAX_TIMEOUT = int(os.environ.get(
1218N/A "PKG_CLIENT_MAX_TIMEOUT",
1218N/A self.pkg_client_max_timeout_default))
1218N/A except ValueError:
1218N/A self.PKG_CLIENT_MAX_TIMEOUT = \
1218N/A self.pkg_client_max_timeout_default
1218N/A try:
1218N/A # Number of seconds trying to connect before client
1218N/A # aborts.
1218N/A self.PKG_CLIENT_CONNECT_TIMEOUT = int(os.environ.get(
1218N/A "PKG_CLIENT_CONNECT_TIMEOUT",
1218N/A self.pkg_client_connect_timeout_default))
1218N/A except ValueError:
1218N/A self.PKG_CLIENT_CONNECT_TIMEOUT = \
1218N/A self.pkg_client_connect_timeout_default
1218N/A try:
1218N/A # Number of seconds below lowspeed limit before
1218N/A # transaction is aborted.
1218N/A self.PKG_CLIENT_LOWSPEED_TIMEOUT = int(os.environ.get(
1218N/A "PKG_CLIENT_LOWSPEED_TIMEOUT",
1218N/A self.pkg_client_lowspeed_timeout_default))
1218N/A except ValueError:
1218N/A self.PKG_CLIENT_LOWSPEED_TIMEOUT = \
1218N/A self.pkg_client_lowspeed_timeout_default
1448N/A try:
1448N/A # Number of transient errors before transaction
1448N/A # is aborted.
1448N/A self.PKG_CLIENT_MAX_CONSECUTIVE_ERROR = int(
1448N/A os.environ.get("PKG_CLIENT_MAX_CONSECUTIVE_ERROR",
1448N/A self.pkg_client_max_consecutive_error_default))
1448N/A except ValueError:
1448N/A self.PKG_CLIENT_MAX_CONSECUTIVE_ERROR = \
1448N/A self.pkg_client_max_consecutive_error_default
1448N/A try:
1448N/A # Number of redirects before a connection is
1448N/A # aborted.
1448N/A self.PKG_CLIENT_MAX_REDIRECT = int(
1448N/A os.environ.get("PKG_CLIENT_MAX_REDIRECT",
1448N/A self.pkg_client_max_redirect_default))
1448N/A except ValueError:
1448N/A self.PKG_CLIENT_MAX_REDIRECT = \
1448N/A self.pkg_client_max_redirect_default
1431N/A self.reset_logging()
1431N/A
1431N/A def __get_error_log_handler(self):
1431N/A return self.__error_log_handler
1431N/A
1431N/A def __get_info_log_handler(self):
1431N/A return self.__info_log_handler
1431N/A
1431N/A def __get_verbose(self):
1431N/A return self.__verbose
1431N/A
1431N/A def __set_error_log_handler(self, val):
1431N/A logger = logging.getLogger("pkg")
1431N/A if self.__error_log_handler:
1431N/A logger.removeHandler(self.__error_log_handler)
1431N/A self.__error_log_handler = val
1431N/A if val:
1431N/A logger.addHandler(val)
1431N/A
1431N/A def __set_info_log_handler(self, val):
1431N/A logger = logging.getLogger("pkg")
1431N/A if self.__info_log_handler:
1431N/A logger.removeHandler(self.__info_log_handler)
1431N/A self.__info_log_handler = val
1431N/A if val:
1431N/A logger.addHandler(val)
1431N/A
1431N/A def __set_verbose(self, val):
1431N/A if self.__info_log_handler:
1431N/A if val:
1431N/A level = logging.DEBUG
1431N/A else:
1431N/A level = logging.INFO
1431N/A self.__info_log_handler.setLevel(level)
1431N/A self.__verbose = val
1431N/A
1431N/A @property
1431N/A def logger(self):
2828N/A # Method could be a function; pylint: disable=R0201
1431N/A return logging.getLogger("pkg")
1431N/A
1431N/A def reset_logging(self):
1431N/A """Resets client logging to its default state. This will cause
1431N/A all logging.INFO entries to go to sys.stdout, and all entries of
1431N/A logging.WARNING or higher to go to sys.stderr."""
1431N/A
1431N/A logger = logging.getLogger("pkg")
1431N/A logger.setLevel(logging.DEBUG)
1431N/A
1431N/A # Don't pass messages that are rejected to the root logger.
1431N/A logger.propagate = 0
1431N/A
1431N/A # By default, log all informational messages, but not warnings
1431N/A # and above to stdout.
2466N/A info_h = _StreamHandler(sys.stdout)
1431N/A
1431N/A # Minimum logging level for informational messages.
1431N/A if self.verbose:
1431N/A info_h.setLevel(logging.DEBUG)
1431N/A else:
1431N/A info_h.setLevel(logging.INFO)
1431N/A
1431N/A log_fmt = logging.Formatter()
1431N/A
1431N/A # Enforce maximum logging level for informational messages.
1431N/A info_f = _LogFilter(logging.INFO)
1431N/A info_h.addFilter(info_f)
1431N/A info_h.setFormatter(log_fmt)
1431N/A logger.addHandler(info_h)
1431N/A
1431N/A # By default, log all warnings and above to stderr.
2466N/A error_h = _StreamHandler(sys.stderr)
1431N/A error_h.setFormatter(log_fmt)
1431N/A error_h.setLevel(logging.WARNING)
1431N/A logger.addHandler(error_h)
1431N/A
1431N/A # Stash the handles so they can be removed later.
1431N/A self.info_log_handler = info_h
1431N/A self.error_log_handler = error_h
1431N/A
1431N/A error_log_handler = property(__get_error_log_handler,
1431N/A __set_error_log_handler)
1431N/A
1431N/A info_log_handler = property(__get_info_log_handler,
1431N/A __set_info_log_handler)
1431N/A
1431N/A verbose = property(__get_verbose, __set_verbose)
576N/A
1448N/A
576N/Aglobal_settings = GlobalSettings()