diff options
| author | Michal Minar <miminar@redhat.com> | 2013-07-30 14:24:49 +0200 |
|---|---|---|
| committer | Michal Minar <miminar@redhat.com> | 2013-07-30 15:23:35 +0200 |
| commit | 2a2bc8a4e9498024c8a85ce2813e7d0f9c5677a0 (patch) | |
| tree | 1eaab563e14fd7f11880b540417eb2a879536bb8 /src/python/lmi/common/BaseConfiguration.py | |
| parent | 3026b7f6476743d862e6caa7816c56017108ee6d (diff) | |
| download | openlmi-providers-2a2bc8a4e9498024c8a85ce2813e7d0f9c5677a0.tar.gz openlmi-providers-2a2bc8a4e9498024c8a85ce2813e7d0f9c5677a0.tar.xz openlmi-providers-2a2bc8a4e9498024c8a85ce2813e7d0f9c5677a0.zip | |
openlmi-python: split python package
Split the openlmi-python package to 2:
* openlmi-python-base
- lmi namespace
- functionality for any OpenLMI related python code
- contains packages 'lmi' and 'lmi.base'
* openlmi-python-providers
- common functionality for OpenLMI providers
- contains 'lmi.providers'
Diffstat (limited to 'src/python/lmi/common/BaseConfiguration.py')
| -rw-r--r-- | src/python/lmi/common/BaseConfiguration.py | 267 |
1 files changed, 0 insertions, 267 deletions
diff --git a/src/python/lmi/common/BaseConfiguration.py b/src/python/lmi/common/BaseConfiguration.py deleted file mode 100644 index f54de03..0000000 --- a/src/python/lmi/common/BaseConfiguration.py +++ /dev/null @@ -1,267 +0,0 @@ -# Copyright (C) 2012 Red Hat, Inc. All rights reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -# -# Authors: Jan Safranek <jsafrane@redhat.com> -# Authors: Michal Minar <miminar@redhat.com> -# -*- coding: utf-8 -*- -""" -Module for BaseConfiguration class. - -BaseConfiguration --------------------- - -.. autoclass:: BaseConfiguration - :members: - -""" - -import ConfigParser -import logging -import os -import socket -from lmi.common.singletonmixin import Singleton - -def convert_value(section, option, convert_func, value): - """ - Return result of application of ``convert_func`` on value. - If the conversion failes, error is logged and ValueError is raised. - - :param section: (``str``) Section of configuration file. Used for - error message. - :param option: (``str``) Option of configuration file. Used for - error message. - :param convert_func: (``type``) Conversion function to apply on passed - value. - :param value: (``basestring``) Value to convert. - """ - if not isinstance(value, basestring): - raise TypeError("value must be a string") - try: - if convert_func is bool: - return value.lower() in ('1', 'y', 'yes', 'on', 'true') - if convert_func is str and isinstance(value, unicode): - return value.encode('utf-8') - if convert_func is unicode and isinstance(value, str): - return value.decode('utf-8') - return convert_func(value) - except ValueError as exc: - logging.getLogger(__name__).error( - 'failed to convert value of "[%s]%s: %s', section, option, - exc) - raise - -class BaseConfiguration(Singleton): - """ - OpenLMI configuration file. By default, it resides in - /etc/openlmi/${provider_prefix}/${provider_prefix}.conf. - - There should be only one instance of this class. - """ - - CONFIG_DIRECTORY_TEMPLATE = '/etc/openlmi/%(provider_prefix)s/' - CONFIG_FILE_PATH_TEMPLATE = \ - CONFIG_DIRECTORY_TEMPLATE + '%(provider_prefix)s.conf' - - PERSISTENT_PATH_TEMPLATE = '/var/lib/openlmi-%(provider_prefix)s/' - SETTINGS_DIR = 'settings/' - - DEFAULT_OPTIONS = { - 'Namespace' : 'root/cimv2', - 'SystemClassName' : 'Linux_ComputerSystem', - # Default logging level - "Level" : "ERROR", - 'DebugBlivet' : 'false', - 'Stderr' : 'false', - } - - @classmethod - def provider_prefix(cls): - """ - This is responsibility of a subclass. - - :rtype: (``string`) Prefix of providers in lowercase. For example - configuration class for storage providers would return "storage". - - Result is used to construct configuration paths. - """ - raise NotImplementedError - - @classmethod - def default_options(cls): - """ :rtype: (``dict``) Dictionary of default values. """ - return cls.DEFAULT_OPTIONS - - @classmethod - def config_directory(cls): - """ Base directory with configuration settings. """ - return cls.CONFIG_DIRECTORY_TEMPLATE % { - 'provider_prefix' : cls.provider_prefix() } - - @classmethod - def persistent_path(cls): - """ Base directory with persistent settings. """ - return cls.PERSISTENT_PATH_TEMPLATE % { - 'provider_prefix': cls.provider_prefix() } - - @classmethod - def config_file_path(cls): - """ File path of configuration file. """ - return cls.CONFIG_FILE_PATH_TEMPLATE % { - 'provider_prefix' : cls.provider_prefix() } - - @classmethod - def mandatory_sections(cls): - """ - Return list of sections, that must be present in configuration - file. If not present, they will be created in memory. - """ - return ['Log', 'CIM'] - - def __init__(self): - """ Initialize and load a configuration file.""" - self._listeners = set() - self.config = ConfigParser.SafeConfigParser( - defaults=self.default_options()) - self.load() - - def add_listener(self, callback): - """ - Add a callback, which will be called when configuration is updated. - The callback will be called with instance of this class as - parameter: - callback(config) - """ - self._listeners.add(callback) - - def remove_listener(self, callback): - """ - Remove previously registered callback. - """ - - self._listeners.remove(callback) - - def _call_listeners(self): - """ - Call all listeners that configuration has updated. - """ - for callback in self._listeners: - callback(self) - - def load(self): - """ - Load configuration from config file path. - The file does not need to exist. - """ - self.config.read(self.config_file_path()) - for section in self.mandatory_sections(): - if not self.config.has_section(section): - self.config.add_section(section) - self._call_listeners() - - @property - def namespace(self): - """ Return namespace of OpenLMI provider. """ - return self.config.get('CIM', 'Namespace') - - @property - def system_class_name(self): - """ Return SystemClassName of OpenLMI provider. """ - return self.config.get('CIM', 'SystemClassName') - - @property - def system_name(self): - """ Return SystemName of OpenLMI provider. """ - return socket.getfqdn() - - @property - def logging_level(self): - """ Return name of logging level in lower case. """ - return self.config.get('Log', 'Level').lower() - - @property - def stderr(self): - """ Return True if logging to stderr is enabled. """ - return self.config.getboolean('Log', 'Stderr') - - def file_path(self, section, option): - """ - Return absolute file path for requested option. - Relative path is converted to absolute one with config's directory - as a prefix. - """ - path = self.config.get(section, option) - if not os.path.isabs(path): - path = os.path.join(self.config_directory(), path) - return path - - def get_safe(self, section, option, convert=str, fallback=None, - *args, **kwargs): - """ - Get the configuration option value as specified type in a safe way. - Value is searched in this order: - config_file -> defaults_dict -> fallback - - :param section: (``str``) Section name of option. - :param option: (``str``) Option name. - :param convert: (``type``) Is a conversion function for obtained - value. If the value could not be converted, error message is - generated and ``fallback`` is returned. This function is not - applied to ``fallback`` value. Supported values are: - str, unicode, int ,float, long, bool - - :param fallback: Value returned, when section or option does not - exists and no default value is given, or when the obtained value - could not be converted by supplied function. - - All the other parameters are passed to the ``SafeConfigParser.get()`` - method. - """ - if not isinstance(section, basestring): - raise TypeError('section must be a string') - if not isinstance(option, basestring): - raise TypeError("option must be a string") - if not convert in (str, unicode, int, float, long, bool): - raise ValueError("unsupported type for conversion: %s:", - getattr(convert, '__name__', 'unknown')) - if ( not self.config.has_option(section, option) - and not option.lower() in self.default_options()): - logging.getLogger(__name__).warn( - 'no option value and no default supplied for "[%s]%s"', - section, option) - return fallback - try: - value = self.config.get(section, option, *args, **kwargs) - except ConfigParser.Error as exc: - logging.getLogger(__name__).error( - 'failed to get value of "[%s]%s": %s', section, option, - exc) - return fallback - try: - # first try to convert value from config - return convert_value(section, option, convert, value) - except ValueError as exc: - logging.getLogger(__name__).error( - 'failed to convert value of "[%s]%s: %s', section, option, - exc) - # if it failes, try the value from defaults - if ( option.lower() in self.default_options() - and self.default_options()[option.lower()] != value): - try: - return convert_value(section, option, convert, - self.default_options()[option.lower()]) - except ValueError: - pass # error is already logged, no more options left - return fallback |
