From 0d20cbba52aaa71510fb5724863f9ea778e0f96d Mon Sep 17 00:00:00 2001 From: Narayan Desai Date: Sat, 30 Oct 2004 15:07:47 +0000 Subject: change name and switch to calling Generator.__init__ from __setup__ (Logical change 1.136) git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@610 ce84e21b-d406-0410-9b95-82705330c041 --- src/lib/Server/Generators/cfg.py | 227 --------------------------------------- 1 file changed, 227 deletions(-) delete mode 100644 src/lib/Server/Generators/cfg.py diff --git a/src/lib/Server/Generators/cfg.py b/src/lib/Server/Generators/cfg.py deleted file mode 100644 index 2f3d312d2..000000000 --- a/src/lib/Server/Generators/cfg.py +++ /dev/null @@ -1,227 +0,0 @@ -'''This module implements a config file repository''' -__revision__ = '$Revision$' - -from binascii import b2a_base64 -from os import stat -from re import compile as regcompile -from stat import S_ISDIR, ST_MODE -from syslog import syslog, LOG_INFO - -from Bcfg2.Server.Generator import Generator, DirectoryBacked, FileBacked -from Bcfg2.Server.Metadata import Metadata - -class CfgFileException(Exception): - '''Raised for repository errors''' - pass - -class FileEntry(FileBacked): - '''The File Entry class pertains to the config files contained in a particular directory. - This includes :info, all base files and deltas''' - - def __init__(self, name, metadata): - FileBacked.__init__(self, name) - self.metadata = metadata - - def Applies(self, other): - '''redirect to metadata.Applies''' - return self.metadata.Applies(other) - - def __cmp__(self, other): - '''figure out if self is more or less specific than other''' - return self.metadata.__cmp__(other.metadata) - -class ConfigFileEntry(object): - '''ConfigFileEntry is a repository entry for a single file, containing - all data for all clients.''' - mx = regcompile("(^(?P.*)(\.((B(?P\d+)_(?P\S+))|(A(?P\d+)_(?P\S+))|(I(?P\d+)_(?P\S+))|(I(?P\d+)_(?P\S+))|(H_(?P\S+)))(\.(?Pcat|udiff))?)?$)") - info = regcompile('^owner:(\s)*(?P\w+)|group:(\s)*(?P\w+)|perms:(\s)*(?P\w+)|encoding:(\s)*(?P\w+)|(?Pparanoid(\s)*)$') - - def __init__(self, path): - object.__init__(self) - self.path = path - self.basefiles = [] - self.deltas = [] - self.encoding = 'ascii' - self.owner = 'root' - self.group = 'root' - self.perms = '0644' - self.paranoid = False - - def read_info(self, filename): - '''read in :info metadata''' - for line in open(filename).readlines(): - match = self.info.match(line) - if not match: - continue - else: - mgd = match.groupdict() - if mgd['owner']: - self.owner = mgd['owner'] - elif mgd['group']: - self.group = mgd['group'] - elif mgd['encoding']: - self.encoding = mgd['encoding'] - elif mgd['perms']: - self.perms = mgd['perms'] - if len(self.perms) == 3: - self.perms = "0%s" % (self.perms) - elif mgd['paranoid']: - self.paranoid = True - - def AddEntry(self, name): - '''add new file additions for a single cf file''' - if name[-5:] == ':info': - return self.read_info(name) - - g = self.mx.match(name) - if g == None: - print "match failed for file name %s" % (name) - return - - data = {} - for attr in ['bundle', 'attr', 'hostname', 'class']: - if g.group(attr) != None: - data[attr] = g.group(attr) - if data == {}: - all = True - else: - all = False - # metadata args (global, image, classes, bundles, attributes, hostname) - arg = (all, data.get('image', None)) - for mtype in ['class', 'bundle', 'attr']: - arg = arg + (data.get(mtype, []),) - arg = arg + (data.get('hostname', None),) - m = apply(Metadata, arg) - if g.group("op") != None: - self.deltas.append(FileEntry(name, m)) - # need to sort here - else: - self.basefiles.append(FileEntry(name, m)) - # need to sort here - - def HandleEvent(self, event): - '''Handle FAM updates''' - action = event.code2str() - if event.filename[-5:] == ':info': - return self.read_info(event.filename) - for l in [self.basefiles, self.deltas]: - for entry in l: - if entry.name.split('/')[-1] == event.filename: - if action == 'changed': - entry.HandleEvent(event) - elif action == 'deleted': - l.remove(entry) - else: - print "unhandled action %s" % (action) - - def GetConfigFile(self, entry, metadata): - '''Fetch config file from repository''' - name = entry.attrib['name'] - filedata = "" - # first find basefile - try: - basefile = [x for x in self.basefiles if x.Applies(metadata)][0] - except IndexError: - raise CfgFileException, ('basefile', name) - filedata += basefile.data - - # find applicable deltas - deltas = [x for x in self.deltas if x.Applies(metadata)] - # filter for more specific - for delta in deltas: - pass - # apply diffs, etc - entry.attrib.update({'owner':self.owner, 'group':self.group, - 'perms':self.perms, 'encoding':self.encoding}) - if self.paranoid: - entry.attrib['paranoid'] = 'true' - if self.encoding == 'base64': - entry.text = b2a_base64(filedata) - else: - entry.text = filedata - -class ConfigFileRepository(DirectoryBacked): - '''This class implements repos and all change handling''' - - def __init__(self, name, fam): - self.name = name - self.fam = fam - self.entries = {} - self.provides = {} - self.famID = {} - self.directories = [] - self.AddDirectoryMonitor(self.name) - # eventually flush fam events here so that all entries built here - # ready to go - - def AddDirectoryMonitor(self, name): - '''Add new directory to FAM structures''' - if name not in self.directories: - try: - stat(name) - except OSError: - print "Failed to open %s" % (name) - return - reqid = self.fam.AddMonitor(name, self) - self.famID[reqid] = name - self.directories.append(name) - - def AddEntry(self, name): - '''Add new entry to FAM structures''' - try: - sdata = stat(name)[ST_MODE] - except OSError: - return - - if S_ISDIR(sdata): - self.AddDirectoryMonitor(name) - else: - # file entries shouldn't contain path-to-repo - shortname = '/'+ '/'.join(name[len(self.name)+1:].split('/')[:-1]) - if not self.entries.has_key(shortname): - self.entries[shortname] = ConfigFileEntry(shortname) - self.provides[shortname] = self.entries[shortname].GetConfigFile - self.entries[shortname].AddEntry(name) - #self.entries[shortname].HandleEvent() - - def HandleEvent(self, event): - '''Handle FAM updates''' - action = event.code2str() - if event.filename[0] != '/': - filename = "%s/%s" % (self.famID[event.requestID], event.filename) - else: - filename = event.filename - if action == 'exists': - if filename != self.name: - self.AddEntry(filename) - elif action == 'created': - self.AddEntry(filename) - elif action == 'changed': - # pass the event down the chain to the ConfigFileEntry - configfile = filename[len(self.name):-(len(event.filename)+1)] - if event.filename == ':info': - event.filename = filename - if self.entries.has_key(configfile): - self.entries[configfile].HandleEvent(event) - else: - syslog(LOG_INFO, "Ignoring event for %s"%(configfile)) - elif action == 'deleted': - configfile = filename[len(self.name):-(len(event.filename)+1)] - self.entries[configfile].HandleEvent(event) - elif action in ['endExist']: - pass - else: - print "Got unknown event %s %s %s" % (event.requestID, event.code2str(), event.filename) - -class cfg(Generator): - '''This generator manages the configuration file repository for bcfg2''' - __name__ = 'cfg' - __version__ = '$Id$' - __author__ = 'bcfg-dev@mcs.anl.gov' - __provides__ = {} - - def __setup__(self): - self.repo = ConfigFileRepository(self.data, self.core.fam) - self.__provides__['ConfigFile'] = self.repo.provides - - -- cgit v1.2.3-1-g7c22