#!/usr/bin/env python # Contributed by gogo '''TODO''' __revision__ = '$Revision: 221 $' import logging, lxml.etree, Bcfg2.Logging, Bcfg2.Server.Core, Bcfg2.Server.Metadata, Bcfg2.Server.Plugin import sys,os,time,errno from optparse import OptionParser def buildConfiguration(core, client): '''Build client configuration.''' return core.BuildConfiguration(client) def write_siggi_entry(user, group, permission, path): '''Write an entry to the configfiles.siggi file which is needed by siggi.''' f = open(outputdir + '/configfiles.siggi', 'a') f.write("%s,%s,%s,%s\n" % (user, group, permission, path)) f.close() logger.info("Wrote siggi entry." ) class ConfigFileNotBuild(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) def handleConfigFileEntry(cfg): '''Store file content of an ... entry in the appropriate directory under the output directory.''' name = cfg.get('name') permission = cfg.get('perms').rjust(4,'0') user = cfg.get('owner') group = cfg.get('group') logger.info("\nHandling ConfigFile entry %s >>>" % name) # directory creation logger.info("Creating directory %s" % ( os.path.dirname(outputdir + name)) ) try: os.makedirs(os.path.dirname(outputdir + name)) except OSError,err: if err.errno != errno.EEXIST: raise except: logger.error("Fatal error during directory creation!") raise # write config file f = open(outputdir + name, "w" ) try: f.write(cfg.text) except: # plugin throw an exception and therefore there is no content => None raise ConfigFileNotBuild(name) f.close() # write siggi entry try: write_siggi_entry(user, group, permission, name) except: logger.error("Writing entry to configfiles.siggi failed!") raise logger.info("<<<") if __name__ == '__main__': Bcfg2.Logging.setup_logging('export-config-AMS', to_syslog=False) logger = logging.getLogger('export-config-AMS') # parse command line options, arguments parser = OptionParser(usage = "%prog [options] client outputdir", version = __revision__) parser.add_option("-c", "--config-file", action="store", dest="configfile", help="Use given bcfg2.conf file, default: /etc/bcfg2.conf") parser.add_option("-f", "--fam-steps", action="store", dest="famsteps", type = "int", help="How many times to handle fam events, default: 10") parser.set_defaults(famsteps = 10, configfile="/etc/bcfg2.conf") (options, args) = parser.parse_args() # ensure client hostname is given if len(args) != 2: parser.error("incorrect number of arguments.") client = args[0] outputdir = args[1] # stop if output directory exists if os.path.exists(outputdir): logger.error("Output directory already exists, won't override!") raise SystemExit, 1 logger.info("Generating configuration for %s" % client) # load Bcfg2 Core try: logger.debug("Trying to load core...") bcore = Bcfg2.Server.Core.Core({}, options.configfile) except Bcfg2.Server.Core.CoreInitError, msg: logger.error("Core load failed because %s" % msg) raise SystemExit, 1 else: logger.debug("Core loaded.") # FAM service handling for i in range(options.famsteps): logger.info("FAM service handling: %s to go..." % str(options.famsteps - i) ) bcore.fam.Service() time.sleep(0.5) # get configuration for client try: client_config = buildConfiguration( bcore, client) except: logger.error("Building client configuration failed. Exiting...") raise SystemExit, 1 # client could be without a group, not listed in client.xml ... if client_config.tag == 'error': logger.error("Building client configuration failed. Exiting...") raise SystemExit, 1 # handle entries for configfile in [cfile for cfile in client_config.findall(".//ConfigFile")]: try: handleConfigFileEntry(configfile) except ConfigFileNotBuild, e: logger.error("Error: Plugin failed to generate file content for ConfigFile %s !" % e) raise SystemExit, 1 except: raise SystemExit, 1