diff options
author | Robert Gogolok <gogo@cs.uni-sb.de> | 2007-12-30 19:26:51 +0000 |
---|---|---|
committer | Robert Gogolok <gogo@cs.uni-sb.de> | 2007-12-30 19:26:51 +0000 |
commit | e8c9ba57d10d174c79ac1aae9b53661ee8464d0f (patch) | |
tree | 65cb5f7b0c699e6c97eb365ec83c76155a023f7e /src/lib | |
parent | 73ba22f7e519694dbf7010810de69b3b845f634f (diff) | |
download | bcfg2-e8c9ba57d10d174c79ac1aae9b53661ee8464d0f.tar.gz bcfg2-e8c9ba57d10d174c79ac1aae9b53661ee8464d0f.tar.bz2 bcfg2-e8c9ba57d10d174c79ac1aae9b53661ee8464d0f.zip |
Settings class to remove redundant code for parsing config file.
If a module wants to access bcfg2 settings:
from Bcfg2.Settings import settings
git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@4131 ce84e21b-d406-0410-9b95-82705330c041
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/Client/Proxy.py | 62 | ||||
-rw-r--r-- | src/lib/Component.py | 39 | ||||
-rw-r--r-- | src/lib/Options.py | 25 | ||||
-rw-r--r-- | src/lib/Server/Admin/__init__.py | 2 | ||||
-rw-r--r-- | src/lib/Server/Core.py | 23 | ||||
-rw-r--r-- | src/lib/Server/Plugins/Metadata.py | 6 | ||||
-rw-r--r-- | src/lib/Settings.py | 145 |
7 files changed, 196 insertions, 106 deletions
diff --git a/src/lib/Client/Proxy.py b/src/lib/Client/Proxy.py index b56ccbfa5..8e34a0fb5 100644 --- a/src/lib/Client/Proxy.py +++ b/src/lib/Client/Proxy.py @@ -6,6 +6,7 @@ from Bcfg2.tlslite.integration.XMLRPCTransport import XMLRPCTransport from Bcfg2.tlslite.integration.HTTPTLSConnection import HTTPTLSConnection from Bcfg2.tlslite.TLSConnection import TLSConnection import Bcfg2.tlslite.errors +from Bcfg2.Settings import settings #FIXME need to reimplement _binadaddress support for XMLRPCTransport @@ -49,63 +50,36 @@ class SafeProxy: _retries = 4 _authinfo = () - _components = {} def __init__(self, component, args={}): self.component = component self.log = logging.getLogger(component) - if args.has_key('server'): - # processing from command line args - self._components[component] = args['server'] - else: - if args.has_key('setup'): - # processing from specified config file - _cfpath = args['setup'] - else: - _cfpath = '/etc/bcfg2.conf' - self._cfile = ConfigParser.ConfigParser() - self._cfile.read([_cfpath]) - try: - self._components = self._cfile._sections['components'] - except: - self.log.error("%s doesn't contain a valid components section" % (_cfpath)) - raise SystemExit, 1 - if args.has_key('password'): - # get passwd from cmdline + password = settings.COMMUNICATION_PASSWORD + if args['password']: password = args['password'] - else: - try: - password = self._cfile.get('communication', 'password') - except: - self.log.error("%s doesn't contain a valid password" % (_cfpath)) - raise SystemExit, 1 - if args.has_key('user'): + + user = settings.COMMUNICATION_USER + if args['user']: user = args['user'] - else: - try: - user = self._cfile.get('communication', 'user') - except: - user = 'root' self._authinfo = (user, password) - if args.has_key('fingerprint'): + self.fingerprint = False + if args['fingerprint']: self.fingerprint = args['fingerprint'] - else: - self.fingerprint = False - _bindaddress = "" - try: - _bindaddress = self._cfile.get('communication', 'bindaddress') - except: - pass - - if args.has_key('server'): + address = settings.COMPONENTS_BCFG2 + if args['server']: address = args['server'] - else: - address = self.__get_location(component) - + + # NOT USED + #_bindaddress = "" + #try: + # _bindaddress = self._cfile.get('communication', 'bindaddress') + #except: + # pass try: + # NOT USED # if _bindaddress != "": # self.log.info("Binding client to address %s" % _bindaddress) # self.proxy = xmlrpclib.ServerProxy(address, transport=Bcfg2SafeTransport()) diff --git a/src/lib/Component.py b/src/lib/Component.py index a6f3e9aa2..442ea8112 100644 --- a/src/lib/Component.py +++ b/src/lib/Component.py @@ -3,6 +3,7 @@ __revision__ = '$Revision$' import atexit, logging, select, signal, socket, sys, time, urlparse, xmlrpclib, cPickle, ConfigParser, os from base64 import decodestring + import BaseHTTPServer, SimpleXMLRPCServer import Bcfg2.tlslite.errors import Bcfg2.tlslite.api @@ -10,6 +11,8 @@ import Bcfg2.tlslite.api import Bcfg2.Client.Proxy as Proxy from Bcfg2.tlslite.TLSConnection import TLSConnection +from Bcfg2.Settings import settings + log = logging.getLogger('Component') class ComponentInitError(Exception): @@ -144,34 +147,20 @@ class Component(TLSServer, signal.signal(signal.SIGINT, self.start_shutdown) signal.signal(signal.SIGTERM, self.start_shutdown) self.logger = logging.getLogger('Component') - self.cfile = ConfigParser.ConfigParser() self.children = [] - if setup['configfile']: - cfilename = setup['configfile'] - else: - cfilename = '/etc/bcfg2.conf' - self.cfile.read([cfilename]) - if not self.cfile.has_section('communication'): - print "Configfile missing communication section" - raise SystemExit, 1 - self.static = False - if not self.cfile.has_section('components'): - print "Configfile missing components section" - raise SystemExit, 1 - if self.cfile._sections['components'].has_key(self.__name__): - self.static = True - location = urlparse.urlparse(self.cfile.get('components', self.__name__))[1].split(':') + self.static = True + + location = settings.COMPONENTS_BCFG2 + if settings.COMPONENTS_BCFG2_STATIC: + location = urlparse.urlparse(settings.COMPONENTS_BCFG2)[1].split(':') location = (location[0], int(location[1])) - else: - location = (socket.gethostname(), 0) - try: - keyfile = self.cfile.get('communication', 'key') - #keyfile = '/tmp/keys/server.pkey' - except ConfigParser.NoOptionError: - print "No key specified in cobalt.conf" + + if not settings.COMMUNICATION_KEY: + print "No key specified in '%s'" % settings.CONFIG_FILE raise SystemExit, 1 + keyfile = settings.COMMUNICATION_KEY - self.password = self.cfile.get('communication', 'password') + self.password = settings.COMMUNICATION_PASSWORD try: TLSServer.__init__(self, location, keyfile, CobaltXMLRPCRequestHandler) @@ -182,7 +171,7 @@ class Component(TLSServer, self.logger.error("Failed to parse key" % (keyfile)) raise ComponentInitError except: - self.logger.error("Failed to load ssl key %s" % (keyfile), exc_info=1) + self.logger.error("Failed to load ssl key '%s'" % (keyfile), exc_info=1) raise ComponentInitError try: SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self) diff --git a/src/lib/Options.py b/src/lib/Options.py index 4c97b1ca5..aab329f4d 100644 --- a/src/lib/Options.py +++ b/src/lib/Options.py @@ -2,20 +2,15 @@ __revision__ = '$Revision$' import getopt, os, sys, ConfigParser -# (option, env, cfpath, default value, option desc, boolean, arg desc) -# ((option, arg desc, opt desc), env, cfpath, default, boolean) -bootstrap = {'configfile': (('-C', '<configfile>', 'Path to config file'), - 'BCFG2_CONF', False, '/etc/bcfg2.conf', False)} class OptionFailure(Exception): pass class BasicOptionParser: '''Basic OptionParser takes input from command line arguments, environment variables, and defaults''' - def __init__(self, name, optionspec, configfile=False, dogetopt=False): + def __init__(self, name, optionspec, dogetopt=False): self.name = name self.dogetopt = dogetopt - self.configfile = configfile self.optionspec = optionspec if dogetopt: self.shortopt = '' @@ -52,13 +47,6 @@ class BasicOptionParser: print "%s Usage:" % (self.name) print self.helpmsg raise SystemExit, 1 - if self.configfile: - cf = ConfigParser.ConfigParser() - try: - cf.readfp(open(self.configfile)) - except Exception, e: - print "Failed to read configfile: %s\n%s\n" % (self.configfile, e) - raise SystemExit, 1 for key, (option, envvar, cfpath, default, boolean) in self.optionspec.iteritems(): if self.dogetopt: optinfo = [opt[1] for opt in opts if opt[0] == option[0]] @@ -77,19 +65,10 @@ class BasicOptionParser: if envvar and os.environ.has_key(envvar): ret[key] = os.environ[envvar] continue - if self.configfile and cfpath: - try: - value = apply(cf.get, cfpath) - ret[key] = value - continue - except: - pass ret[key] = default return ret class OptionParser(BasicOptionParser): '''OptionParser bootstraps option parsing, getting the value of the config file''' def __init__(self, name, ospec): - # first find the cf file - cfpath = BasicOptionParser('bootstrap', bootstrap).parse()['configfile'] - BasicOptionParser.__init__(self, name, ospec, cfpath, dogetopt=True) + BasicOptionParser.__init__(self, name, ospec, dogetopt=True) diff --git a/src/lib/Server/Admin/__init__.py b/src/lib/Server/Admin/__init__.py index d059e0a1d..57b9d2a86 100644 --- a/src/lib/Server/Admin/__init__.py +++ b/src/lib/Server/Admin/__init__.py @@ -1,4 +1,4 @@ -__revision__ = '$Revision: $' +__revision__ = '$Revision$' __all__ = ['Mode', 'Client', 'Compare', 'Fingerprint', 'Init', 'Minestruct', 'Pull', 'Tidy', 'Viz'] diff --git a/src/lib/Server/Core.py b/src/lib/Server/Core.py index 76cbb8073..7e347bc23 100644 --- a/src/lib/Server/Core.py +++ b/src/lib/Server/Core.py @@ -4,6 +4,7 @@ __revision__ = '$Revision$' from time import time from Bcfg2.Server.Plugin import PluginInitError, PluginExecutionError from Bcfg2.Server.Statistics import Statistics +from Bcfg2.Settings import settings import logging, lxml.etree, os, stat, ConfigParser import Bcfg2.Server.Plugins.Metadata @@ -198,11 +199,9 @@ except ImportError: class Core(object): '''The Core object is the container for all Bcfg2 Server logic, and modules''' - def __init__(self, setup, configfile): + def __init__(self): object.__init__(self) - self.cfile = ConfigParser.ConfigParser() - self.cfile.read([configfile]) - self.datastore = self.cfile.get('server','repository') + self.datastore = settings.SERVER_REPOSITORY try: self.fam = monitor() except IOError: @@ -211,20 +210,22 @@ class Core(object): self.generators = [] self.structures = [] self.cron = {} - self.setup = setup self.plugins = {} self.revision = '-1' + try: - self.svn = self.cfile.get('server', 'svn') == 'yes' - self.read_svn_revision() + if settings.SERVER_SVN: + self.read_svn_revision() except: - self.svn = False + settings.SERVER_SVN = False + + self.svn = settings.SERVER_SVN - mpath = self.cfile.get('server','repository') + mpath = settings.SERVER_REPOSITORY self.stats = Statistics("%s/etc/statistics.xml" % (mpath)) - structures = self.cfile.get('server', 'structures').replace(' ', '').split(',') - generators = self.cfile.get('server', 'generators').replace(' ', '').split(',') + structures = settings.SERVER_STRUCTURES + generators = settings.SERVER_GENERATORS [data.remove('') for data in [structures, generators] if '' in data] for plugin in structures + generators + ['Metadata']: diff --git a/src/lib/Server/Plugins/Metadata.py b/src/lib/Server/Plugins/Metadata.py index ce9d18f7a..5f3262ec0 100644 --- a/src/lib/Server/Plugins/Metadata.py +++ b/src/lib/Server/Plugins/Metadata.py @@ -1,7 +1,9 @@ '''This file stores persistent metadata for the BCFG Configuration Repository''' __revision__ = '$Revision$' -import lxml.etree, re, socket, time, sys, ConfigParser +from Bcfg2.Settings import settings + +import lxml.etree, re, socket, time, sys import Bcfg2.Server.Plugin class MetadataConsistencyError(Exception): @@ -67,7 +69,7 @@ class Metadata(Bcfg2.Server.Plugin.Plugin): self.ptimes = {} self.pctime = 0 self.extra = {'groups.xml':[], 'clients.xml':[]} - self.password = core.cfile.get('communication', 'password') + self.password = settings.COMMUNICATION_PASSWORD def HandleEvent(self, event): '''Handle update events for data files''' diff --git a/src/lib/Settings.py b/src/lib/Settings.py new file mode 100644 index 000000000..4a47c6f8d --- /dev/null +++ b/src/lib/Settings.py @@ -0,0 +1,145 @@ +""" +Settings for bcfg2. +FIXME: simplify code! +FIXME: add statistics configuration +""" + +__revision__ = '$Revision$' + +import logging, socket, ConfigParser + +class Settings(object): + + def __init__(self): + self.CONFIG_FILE = self.default_config_file() + + self.SERVER_GENERATORS = self.default_server_generators() + self.SERVER_REPOSITORY = self.default_server_repository() + self.SERVER_STRUCTURES = self.default_server_structures() + self.SERVER_SVN = self.default_server_svn() + + self.COMMUNICATION_KEY = self.default_communication_key() + self.COMMUNICATION_PASSWORD = self.default_communication_password() + self.COMMUNICATION_PROTOCOL = self.default_communication_protocol() + self.COMMUNICATION_USER = self.default_communication_user() + + self.COMPONENTS_BCFG2 = self.default_components_bcfg2() + self.COMPONENTS_BCFG2_STATIC = self.default_components_bcfg2_static() + + + def __getattr__(self, name): + print "name = %s\n" % name + if name == '__members__': + return self.name() + return getattr(self, name) + + def read_config_file(self, filename): + + logger = logging.getLogger('bcfg2 settings') + + # set config file + if not filename: + logger.info("No config file given. Trying default config file '%s'." % self.CONFIG_FILE) + else: + logger.debug("Trying user specified config file '%s'." % filename) + self.CONFIG_FILE = filename + + # open config file + try: + cf = open(self.CONFIG_FILE) + except IOError: + logger.info("Skipping not accessable config file '%s'." % self.CONFIG_FILE) + return + + # parse config file + cfp = ConfigParser.ConfigParser() + try: + cfp.readfp(cf) + except Exception, e: + logger.error("Content of config file '%s' is not valid. Correct it!\n%s\n" % (self.CONFIG_FILE, e)) + raise SystemExit, 1 + # communication config + if cfp.has_section('communication'): + try: + self.COMMUNICATION_PROTOCOL = cfp.get('communication','protocol') + except: + pass + try: + self.COMMUNICATION_PASSWORD = cfp.get('communication','password') + except: + pass + try: + self.COMMUNICATION_KEY = cfp.get('communication','key') + except: + pass + try: + self.COMMUNICATION_USER = cfp.get('communication','user') + except: + pass + # components config + if cfp.has_section('components'): + try: + self.COMPONENTS_BCFG2 = cfp.get('components', 'bcfg2') + self.COMPONENTS_BCFG2_STATIC = True + except: + pass + # server config + if cfp.has_section('server'): + try: + self.SERVER_GENERATORS = cfp.get('server','generators').replace(' ','').split(',') + except: + pass + try: + self.SERVER_REPOSITORY = cfp.get('server','repository') + except: + pass + try: + self.SERVER_STRUCTURES = cfp.get('server','structures').replace(' ','').split(',') + except: + pass + try: + self.SERVER_SVN = cfp.get('server','svn') + except: + pass + + return + + def default_config_file(self): + return '/etc/bcfg2.conf' + + def default_server_generators(self): + return ['SSHbase', 'Cfg', 'Pkgmgr', 'Rules'] + + def default_server_structures(self): + return ['Bundler', 'Base'] + + def default_server_repository(self): + return '/var/lib/bcfg2/' + + def default_communication_key(self): + return False + + def default_communication_password(self): + return 'password' + + def default_communication_protocol(self): + return 'xmlrpc/ssl' + + def default_communication_user(self): + return 'root' + + def default_components_bcfg2(self): + return (socket.gethostname(), 0) + + def default_components_bcfg2_static(self): + return False + + def default_sendmail_path(self): + return '/usr/sbin/sendmail' + + def default_server_svn(self): + return None + + + +settings = Settings() |