Abandon de la philosophie un dossier par fichier.

On fait tout passer par l'environment du script, c'est plus pratique.

darcs-hash:20071218220729-af139-64bf7eda6339a5ecea06402607b5541362db243d.gz
This commit is contained in:
Jeremie Dimino 2007-12-18 23:07:29 +01:00
parent 3ec7919694
commit 4210b7c9ad

View file

@ -52,9 +52,6 @@ else:
def debug(msg, color=None):
pass
# Les fichiers qui sont surveillés par le plugin dans les dossier /etc/../machin.cf/
_monitored_files = ["info.xml", "gen.py"]
# Dico nom de fichier -> code
includes = {}
@ -69,65 +66,11 @@ def include(env, incfile):
def load_file(filename):
'''Charge un script et affiche un message d'erreur en cas d'exception'''
try:
return pygen.load(filename)
return pygen.load(filename, os.path.dirname(filename) + "/." + os.path.basename(filename) + ".COMPILED")
except Exception, e:
logger.error('Python compilation error: %s: %s' % (str(e.__class__).split('.', 2)[1], str(e)))
return None
class PythonFile:
'''Template file creates Python template structures for the loaded file'''
def __init__(self, name, properties):
self.name = name
self.info = None
self.code = None
self.properties = properties
def Created(self, path, event):
'''Traitement des créations de fichier'''
if event.filename == "gen.py":
self.code = load_file(path)
else:
self.info = Bcfg2.Server.Plugin.XMLSrc(path, True)
self.info.HandleEvent(event)
def Changed(self, path, event):
'''Traitement des modifications de fichier'''
if event.filename == "gen.py":
self.code = load_file(path)
else:
self.info.HandleEvent(event)
def Deleted(self, path, event):
'''Traitement des suppressions de fichier'''
if event.filename == "gen.py":
self.code = None
else:
self.info = None
def BuildFile(self, entry, metadata):
'''Build literal file information'''
fname = entry.get('realname', entry.get('name'))
debug("building config file: %s" % fname, 'blue')
try:
env = pygen.Environment()
env["metadata"] = metadata
env["properties"] = self.properties
env["include"] = lambda incfile: include(env, incfile)
env["dump"] = lambda incfile: dump(env, incfile)
env.included = set([])
include(env, "common")
entry.text = pygen.generate(self.code, env)
debug(entry.text)
except Exception, e:
logger.error('Python exec error: %s: %s' % (str(e.__class__).split('.', 2)[1], str(e)))
raise Bcfg2.Server.Plugin.PluginExecutionError
if self.info:
mdata = {}
self.info.pnode.Match(metadata, mdata)
mdata = mdata['Info'][None]
[entry.attrib.__setitem__(key, value)
for (key, value) in mdata.iteritems()]
class PythonProperties(Bcfg2.Server.Plugin.SingleXMLFileBacked):
'''Class for Python properties'''
def Index(self):
@ -153,8 +96,8 @@ class Python(Bcfg2.Server.Plugin.Plugin):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
# Les entrées pour bcfg2
self.Entries['ConfigFile'] = {}
# Nos entrées pour nous (dico de PythonFile)
self.entries = {}
# Correspondance entrée ConfigFile -> code
self.codes = {}
# Dico ID de requête GAM -> Dossier surveillé
self.handles = {}
# Le dossier qui contient les fichiers à inclure
@ -171,25 +114,48 @@ class Python(Bcfg2.Server.Plugin.Plugin):
self.logger.info("Failed to read properties file; Python properties disabled")
def BuildEntry(self, entry, metadata):
'''Dispatch fetch calls to the correct object'''
self.entries[entry.get('name')].BuildFile(entry, metadata)
'''Construit le fichier'''
code = self.codes[entry.get('name')]
fname = entry.get('realname', entry.get('name'))
debug("building config file: %s" % fname, 'blue')
env = pygen.Environment()
env["metadata"] = metadata
env["properties"] = self.properties
env["include"] = lambda incfile: include(env, incfile)
env["dump"] = lambda incfile: dump(env, incfile)
env["info"] = { 'owner': 'root',
'group': 'root',
'perms': 0644 }
env.included = set([])
try:
include(env, "common")
entry.text = pygen.generate(code, env)
debug(entry.text)
except Exception, e:
logger.error('Python exec error: %s: %s' % (str(e.__class__).split('.', 2)[1], str(e)))
raise Bcfg2.Server.Plugin.PluginExecutionError
entry.attrib['owner'] = env["info"]['owner']
entry.attrib['group'] = env["info"]['group']
entry.attrib['perms'] = oct(env["info"]['perms'])
def HandleEvent(self, event):
'''Traitement des événements de FAM'''
# On passe les fichiers ennuyeux
if event.filename[0] == '/' \
or event.filename.endswith(".COMPILED") \
or event.filename.endswith("~") \
or event.filename.startswith(".#"):
return
action = event.code2str()
debug("event received: action=%s filename=%s requestID=%s" %
(action, event.filename, event.requestID), 'purple')
if event.filename[0] == '/' or event.filename.endswith(".pyc"):
# Rien d'intéressant
return
hdle_path = self.handles[event.requestID]
path = hdle_path + "/" + event.filename
path = self.handles[event.requestID] + "/" + event.filename
debug("absolute filename: %s" % path, 'yellow')
if path.startswith(self.include):
if posixpath.isfile(path) and path.endswith(".py"):
if posixpath.isfile(path):
# Les fichiers d'includes...
identifier = path[len(self.include)+1:-3]
if action in ['exists', 'created', 'changed']:
@ -201,31 +167,20 @@ class Python(Bcfg2.Server.Plugin.Plugin):
elif posixpath.isdir(path) and action in ['exists', 'created']:
self.AddDirectoryMonitor(path)
elif posixpath.isfile(path) and event.filename in _monitored_files:
elif posixpath.isfile(path):
# Le nom du dossier est le nom du fichier du fichier de
# configuration à générer
identifier = hdle_path[len(self.data):]
identifier = path[len(self.data):]
if action in ['exists', 'created']:
if not self.entries.has_key(identifier):
entry = PythonFile(identifier, self.properties)
entry.file_count = 1
debug("adding config file: %s" % identifier, 'green')
self.entries[identifier] = entry
self.Entries['ConfigFile'][identifier] = self.BuildEntry
else:
entry = self.entries[identifier]
entry.file_count += 1
entry.Created(path, event)
debug("adding config file: %s" % identifier, 'green')
self.codes[identifier] = load_file(path)
self.Entries['ConfigFile'][identifier] = self.BuildEntry
elif action == 'changed':
self.entries[identifier].Changed(path, event)
self.codes[identifier] = load_file(path)
elif action == 'deleted':
entry = self.entries[identifier]
entry.Deleted(path, event)
entry.file_count -= 1
if not entry.file_count:
debug("deleting config file: %s" % identifier, 'red')
del self.entries[identifier]
del self.Entries['ConfigFile'][identifier]
debug("deleting config file: %s" % identifier, 'red')
del self.codes[identifier]
del self.Entries['ConfigFile'][identifier]
elif posixpath.isdir(path):
if action in ['exists', 'created']: