diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/Client/Proxy.py | 64 | ||||
-rw-r--r-- | src/lib/Component.py | 28 | ||||
-rw-r--r-- | src/lib/Options.py | 52 | ||||
-rw-r--r-- | src/lib/Server/Admin/Init.py | 26 | ||||
-rw-r--r-- | src/lib/Server/Admin/__init__.py | 25 | ||||
-rw-r--r-- | src/lib/Server/Core.py | 30 | ||||
-rw-r--r-- | src/lib/Server/Plugins/Metadata.py | 4 | ||||
-rw-r--r-- | src/lib/Settings.py | 93 |
8 files changed, 163 insertions, 159 deletions
diff --git a/src/lib/Client/Proxy.py b/src/lib/Client/Proxy.py index 8e34a0fb5..d148748e2 100644 --- a/src/lib/Client/Proxy.py +++ b/src/lib/Client/Proxy.py @@ -6,7 +6,6 @@ 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 @@ -47,39 +46,66 @@ class CobaltComponentError(Exception): class SafeProxy: '''Wrapper for proxy''' - + _retries = 4 _authinfo = () + _components = {} def __init__(self, component, args={}): self.component = component self.log = logging.getLogger(component) - password = settings.COMMUNICATION_PASSWORD - if args['password']: + 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 = args['password'] - - user = settings.COMMUNICATION_USER - if args['user']: + 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 = args['user'] + else: + try: + user = self._cfile.get('communication', 'user') + except: + user = 'root' self._authinfo = (user, password) - self.fingerprint = False - if args['fingerprint']: + if args.has_key('fingerprint'): self.fingerprint = args['fingerprint'] + else: + self.fingerprint = False - address = settings.COMPONENTS_BCFG2 - if args['server']: + _bindaddress = "" + try: + _bindaddress = self._cfile.get('communication', 'bindaddress') + except: + pass + + if args.has_key('server'): address = args['server'] - - # NOT USED - #_bindaddress = "" - #try: - # _bindaddress = self._cfile.get('communication', 'bindaddress') - #except: - # pass + else: + address = self.__get_location(component) + 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 442ea8112..2d6887a67 100644 --- a/src/lib/Component.py +++ b/src/lib/Component.py @@ -7,12 +7,10 @@ from base64 import decodestring import BaseHTTPServer, SimpleXMLRPCServer import Bcfg2.tlslite.errors import Bcfg2.tlslite.api - +import Bcfg2.Options import Bcfg2.Client.Proxy as Proxy from Bcfg2.tlslite.TLSConnection import TLSConnection -from Bcfg2.Settings import settings - log = logging.getLogger('Component') class ComponentInitError(Exception): @@ -149,18 +147,26 @@ class Component(TLSServer, self.logger = logging.getLogger('Component') self.children = [] self.static = True - - location = settings.COMPONENTS_BCFG2 - if settings.COMPONENTS_BCFG2_STATIC: - location = urlparse.urlparse(settings.COMPONENTS_BCFG2)[1].split(':') + options = {'location': Bcfg2.Options.SERVER_LOCATION, + 'static': Bcfg2.Options.SERVER_STATIC, + 'key': Bcfg2.Options.SERVER_KEY, + 'passwd': Bcfg2.Options.SERVER_PASSWORD, + } + opts = Bcfg2.Options.OptionParser(options) + opts.parse([]) + location = opts['location'] + if opts['static']: + location = urlparse.urlparse(location)[1].split(':') location = (location[0], int(location[1])) - if not settings.COMMUNICATION_KEY: - print "No key specified in '%s'" % settings.CONFIG_FILE + print opts + + if not opts['key']: + print "No key specified in '%s'" % setup['configfile'] raise SystemExit, 1 - keyfile = settings.COMMUNICATION_KEY + keyfile = opts['key'] - self.password = settings.COMMUNICATION_PASSWORD + self.password = opts['passwd'] try: TLSServer.__init__(self, location, keyfile, CobaltXMLRPCRequestHandler) diff --git a/src/lib/Options.py b/src/lib/Options.py index 77e5bd718..edf5116e9 100644 --- a/src/lib/Options.py +++ b/src/lib/Options.py @@ -1,7 +1,13 @@ '''Option parsing library for utilities''' __revision__ = '$Revision$' -import getopt, os, sys, ConfigParser +import getopt, os, socket, sys, ConfigParser + +def bool_cook(x): + if x: + return True + else: + return False class OptionFailure(Exception): pass @@ -57,7 +63,10 @@ class Option(object): # processing getopted data optinfo = [opt[1] for opt in opts if opt[0] == self.cmd] if optinfo: - self._value = optinfo[0] + if optinfo[0]: + self._value = optinfo[0] + else: + self._value = True return if self.cmd and self.cmd in rawopts: self._value = rawopts[rawopts.index(self.cmd) + 1] @@ -108,12 +117,45 @@ class OptionSet(dict): val = option.value self[key] = val +list_split = lambda x:x.replace(' ','').split(',') + +CFILE = Option('Specify configuration file', '/etc/bcfg2.conf', cmd='-C', + odesc='<conffile>') +HELP = Option('Print this usage message', False, cmd='-h') +DEBUG = Option("Enable debugging output", False, cmd='-d') +VERBOSE = Option("Enable verbose output", False, cmd='-v') +DAEMON = Option("Daemonize process, storing pid", False, + cmd='-D', odesc="<pidfile>") + +SERVER_REPOSITORY = Option('Server repository path', '/var/lib/bcfg2', + cf=('server', 'repository'), cmd='-Q', + odesc='<repository path>' ) +SERVER_SVN = Option('Server svn support', False, cf=('server', 'svn')) +SERVER_GENERATORS = Option('Server generator list', cf=('server', 'generators'), + default='SSHbase,Cfg,Pkgmgr,Rules', cook=list_split) +SERVER_STRUCTURES = Option('Server structure list', cf=('server', 'structures'), + default='Bundler,Base', cook=list_split) + +SERVER_LOCATION = Option('Server Location', cf=('components', 'bcfg2'), + default=(socket.gethostname(), 0), cmd='-S', + odesc='https://server:port') +SERVER_STATIC = Option('Server runs on static port', cf=('components', 'bcfg2'), + default='', cook=bool_cook) +SERVER_KEY = Option('Path to SSL key', cf=('communication', 'key'), + default=False) +SERVER_PASSWORD = Option('Communication Password', cmd='-x', + cf=('communication', 'password'), default=False) +INSTALL_PREFIX = Option('Installation location', cf=('server', 'prefix'), + default='/usr') +SERVER_PROTOCOL = Option('Server Protocol', cf=('communication', 'procotol'), + default='xmlrpc/ssl') +SENDMAIL_PATH = Option('Path to sendmail', cf=('reports', 'sendmailpath'), + default='/usr/lib/sendmail') + class OptionParser(OptionSet): '''OptionParser bootstraps option parsing, getting the value of the config file''' def __init__(self, args): - self.Bootstrap = OptionSet([('configfile', Option('config file path', - '/etc/bcfg2.conf', - cmd='-C'))]) + self.Bootstrap = OptionSet([('configfile', CFILE)]) self.Bootstrap.parse(sys.argv[1:], do_getopt=False) if self.Bootstrap['configfile'] != Option.cfpath: Option.cfpath = self.Bootstrap['configfile'] diff --git a/src/lib/Server/Admin/Init.py b/src/lib/Server/Admin/Init.py index 0a76f44a7..d057fc1ff 100644 --- a/src/lib/Server/Admin/Init.py +++ b/src/lib/Server/Admin/Init.py @@ -1,7 +1,6 @@ import os, socket import Bcfg2.Server.Admin - -from Bcfg2.Settings import settings +import Bcfg2.Options config = ''' [server] @@ -69,11 +68,19 @@ os_list = [('Redhat/Fedora/RHEL/RHAS/Centos', 'redhat'), class Init(Bcfg2.Server.Admin.Mode): __shorthelp__ = 'bcfg2-admin init' __longhelp__ = __shorthelp__ + '\n\tCompare two client specifications or directories of specifications' + options = {'repo': Bcfg2.Options.SERVER_REPOSITORY, + 'struct': Bcfg2.Options.SERVER_STRUCTURES, + 'gens': Bcfg2.Options.SERVER_GENERATORS, + 'proto': Bcfg2.Options.SERVER_PROTOCOL, + 'sendmail': Bcfg2.Options.SENDMAIL_PATH} + def __call__(self, args): Bcfg2.Server.Admin.Mode.__call__(self, args) - repopath = raw_input( "location of bcfg2 repository [%s]: " % settings.SERVER_REPOSITORY ) + opts = Bcfg2.Options.OptionParser(options) + opts.parse([]) + repopath = raw_input("location of bcfg2 repository [%s]: " % opts['repo']) if repopath == '': - repopath = settings.SERVER_REPOSITORY + repopath = opts['repo'] password = '' while ( password == '' ): password = raw_input( @@ -88,18 +95,15 @@ class Init(Bcfg2.Server.Admin.Mode): prompt += "%d: \n" % (os_list.index(entry) + 1, entry[0]) prompt += ': ' os_sel = os_list[int(raw_input(prompt))-1][1] - self.initializeRepo(repopath, server, password, os_sel) + self.initializeRepo(repopath, server, password, os_sel, opts) print "Repository created successfuly in %s" % (repopath) - def initializeRepo(self, repo, server_uri, password, os_selection): + def initializeRepo(self, repo, server_uri, password, os_selection, opts): '''Setup a new repo''' keypath = os.path.dirname(os.path.abspath(settings.CONFIG_FILE)) confdata = config % ( - repo, - settings.SERVER_STRUCTURES, - settings.SERVER_GENERATORS, - settings.SENDMAIL_PATH, - settings.COMMUNICATION_PROTOCOL, + repo, opts['struct'], opts['gens'], + opts['sendmail'], opts['proto'] password, keypath, server_uri ) diff --git a/src/lib/Server/Admin/__init__.py b/src/lib/Server/Admin/__init__.py index dcab5876f..57b9d2a86 100644 --- a/src/lib/Server/Admin/__init__.py +++ b/src/lib/Server/Admin/__init__.py @@ -4,27 +4,40 @@ __all__ = ['Mode', 'Client', 'Compare', 'Fingerprint', 'Init', 'Minestruct', 'Pull', 'Tidy', 'Viz'] import ConfigParser, lxml.etree, logging -from Bcfg2.Settings import settings class Mode(object): '''Help message has not yet been added for mode''' __shorthelp__ = 'Shorthelp not defined yet' __longhelp__ = 'Longhelp not defined yet' __args__ = [] - - def __init__(self): + def __init__(self, configfile): + self.configfile = configfile + self.__cfp = False self.log = logging.getLogger('Bcfg2.Server.Admin.Mode') - self.repo_path = settings.SERVER_REPOSITORY + + def getCFP(self): + if not self.__cfp: + self.__cfp = ConfigParser.ConfigParser() + self.__cfp.read(self.configfile) + return self.__cfp + + cfp = property(getCFP) def __call__(self, args): - return + if args[0] == 'help': + print self.__longhelp__ + raise SystemExit(0) def errExit(self, emsg): print emsg raise SystemExit(1) + def get_repo_path(self): + '''return repository path''' + return self.cfp.get('server', 'repository') + def load_stats(self, client): - stats = lxml.etree.parse("%s/etc/statistics.xml" % (self.repo_path)) + stats = lxml.etree.parse("%s/etc/statistics.xml" % (self.get_repo_path())) hostent = stats.xpath('//Node[@name="%s"]' % client) if not hostent: self.errExit("Could not find stats for client %s" % (client)) diff --git a/src/lib/Server/Core.py b/src/lib/Server/Core.py index 7e347bc23..56f4087dd 100644 --- a/src/lib/Server/Core.py +++ b/src/lib/Server/Core.py @@ -4,11 +4,12 @@ __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 logging, lxml.etree, os, stat import Bcfg2.Server.Plugins.Metadata +import Bcfg2.Options + logger = logging.getLogger('Bcfg2.Core') def ShouldIgnore(event): @@ -199,9 +200,18 @@ except ImportError: class Core(object): '''The Core object is the container for all Bcfg2 Server logic, and modules''' + options = {'repo': Bcfg2.Options.SERVER_REPOSITORY, + 'svn': Bcfg2.Options.SERVER_SVN, + 'structures': Bcfg2.Options.SERVER_STRUCTURES, + 'generators': Bcfg2.Options.SERVER_GENERATORS, + 'password': Bcfg2.Options.SERVER_PASSWORD} + def __init__(self): object.__init__(self) - self.datastore = settings.SERVER_REPOSITORY + opts = Bcfg2.Options.OptionParser(self.options) + opts.parse([]) + self.datastore = opts['repo'] + self.opts = opts try: self.fam = monitor() except IOError: @@ -213,19 +223,17 @@ class Core(object): self.plugins = {} self.revision = '-1' + self.svn = opts['svn'] try: - if settings.SERVER_SVN: + if self.svn: self.read_svn_revision() except: - settings.SERVER_SVN = False - - self.svn = settings.SERVER_SVN + self.svn = False - mpath = settings.SERVER_REPOSITORY - self.stats = Statistics("%s/etc/statistics.xml" % (mpath)) + self.stats = Statistics("%s/etc/statistics.xml" % (self.datastore)) - structures = settings.SERVER_STRUCTURES - generators = settings.SERVER_GENERATORS + structures = opts['structures'] + generators = opts['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 5f3262ec0..9e991251b 100644 --- a/src/lib/Server/Plugins/Metadata.py +++ b/src/lib/Server/Plugins/Metadata.py @@ -1,8 +1,6 @@ '''This file stores persistent metadata for the BCFG Configuration Repository''' __revision__ = '$Revision$' -from Bcfg2.Settings import settings - import lxml.etree, re, socket, time, sys import Bcfg2.Server.Plugin @@ -69,7 +67,7 @@ class Metadata(Bcfg2.Server.Plugin.Plugin): self.ptimes = {} self.pctime = 0 self.extra = {'groups.xml':[], 'clients.xml':[]} - self.password = settings.COMMUNICATION_PASSWORD + self.password = core.opts['password'] def HandleEvent(self, event): '''Handle update events for data files''' diff --git a/src/lib/Settings.py b/src/lib/Settings.py deleted file mode 100644 index 33a7a0970..000000000 --- a/src/lib/Settings.py +++ /dev/null @@ -1,93 +0,0 @@ -""" -Settings for bcfg2. -FIXME: simplify code! -FIXME: add statistics configuration -""" - -__revision__ = '$Revision$' - -import logging, socket, ConfigParser - -locations = {'communication': [('COMMUNICATION_PROTOCOL', 'protocol'), - ('COMMUNICATION_PASSWORD', 'communication'), - ('COMMUNICATION_KEY', 'key'), - ('COMMUNICATION_USER', 'user')], - 'server': [('SERVER_PREFIX', 'prefix'), - ('SERVER_GENERATORS','generators'), - ('SERVER_REPOSITORY', 'repository'), - ('SERVER_STRUCTURES','structures'), - ('SERVER_SVN', 'svn')], - 'components': [('COMPONENTS_BCFG2', 'bcfg2'), - ('COMPONENTS_BCFG2_STATIC', 'bcfg2')], - 'statistics': [('SENDMAIL_PATH', 'sendmail')]} - -cookers = {'COMPONENTS_BCFG2_STATIC': lambda x:True, - 'SERVER_GENERATORS': lambda x:x.replace(' ','').split(','), - 'SERVER_STRUCTURES': lambda x:x.replace(' ','').split(',')} - -class Settings(object): - - def __init__(self): - self.CONFIG_FILE = '/etc/bcfg2.conf' - - self.SERVER_GENERATORS = ['SSHbase', 'Cfg', 'Pkgmgr', 'Rules'] - self.SERVER_PREFIX = '/usr' - self.SERVER_REPOSITORY = '/var/lib/bcfg2' - self.SERVER_STRUCTURES = ['Bundler', 'Base'] - self.SERVER_SVN = False - - self.COMMUNICATION_KEY = False - self.COMMUNICATION_PASSWORD = 'password' - self.COMMUNICATION_PROTOCOL = 'xmlrpc/ssl' - self.COMMUNICATION_USER = 'root' - - self.COMPONENTS_BCFG2 = (socket.gethostname(), 0) - self.COMPONENTS_BCFG2_STATIC = False - - self.SENDMAIL_PATH = '/usr/sbin/sendmail' - - 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 - - for section in locations: - if cfp.has_section(section): - for key, location in locations[section]: - try: - if key in cookers: - setattr(self, key, cookers[key](cfp.get(section, - location))) - else: - setattr(self, key, cfp.get(section, location)) - except: - pass - -settings = Settings() |