Ameliorations.

- Meilleurs gestion des evenements sur les fichiers
- Gestion des inclusions multiples dans les scripts

darcs-hash:20071218042641-af139-4c4ba1698a4af5367419262e1bf8080be6c3aa20.gz
This commit is contained in:
Jeremie Dimino 2007-12-18 05:26:41 +01:00
parent 1ce640fa74
commit 3ec7919694

View file

@ -22,6 +22,8 @@
''' Plugin pour bcfg2 pour générer des fichiers de conf en prenant la sortie d'un ''' Plugin pour bcfg2 pour générer des fichiers de conf en prenant la sortie d'un
script python''' script python'''
__all__ = ["Python"]
import logging, lxml.etree, posixpath, re, os, sys import logging, lxml.etree, posixpath, re, os, sys
from cStringIO import StringIO from cStringIO import StringIO
import Bcfg2.Server.Plugin import Bcfg2.Server.Plugin
@ -56,9 +58,14 @@ _monitored_files = ["info.xml", "gen.py"]
# Dico nom de fichier -> code # Dico nom de fichier -> code
includes = {} includes = {}
def include(env, incfile): def dump(env, incfile):
exec(includes[incfile], env) exec(includes[incfile], env)
def include(env, incfile):
if not incfile in env.included:
env.included.add(incfile)
exec(includes[incfile], env)
def load_file(filename): def load_file(filename):
'''Charge un script et affiche un message d'erreur en cas d'exception''' '''Charge un script et affiche un message d'erreur en cas d'exception'''
try: try:
@ -75,17 +82,6 @@ class PythonFile:
self.code = None self.code = None
self.properties = properties self.properties = properties
def HandleEvent(self, event):
'''Handle all fs events for this template'''
if event.filename == 'gen.py':
self.code = load_file(self.name + '/' + event.filename)
elif event.filename == 'info.xml':
if not self.info:
self.info = Bcfg2.Server.Plugin.XMLSrc(os.path.join(self.name[1:], event.filename), True)
self.info.HandleEvent(event)
else:
logger.info('Ignoring event for %s' % event.filename)
def Created(self, path, event): def Created(self, path, event):
'''Traitement des créations de fichier''' '''Traitement des créations de fichier'''
if event.filename == "gen.py": if event.filename == "gen.py":
@ -107,18 +103,21 @@ class PythonFile:
self.code = None self.code = None
else: else:
self.info = None self.info = None
return self.code or self.info
def BuildFile(self, entry, metadata): def BuildFile(self, entry, metadata):
'''Build literal file information''' '''Build literal file information'''
fname = entry.get('realname', entry.get('name')) fname = entry.get('realname', entry.get('name'))
debug("building config file: %s" % fname, 'blue')
try: try:
env = pygen.Environment() env = pygen.Environment()
env["metadata"] = metadata env["metadata"] = metadata
env["properties"] = self.properties env["properties"] = self.properties
env["include"] = lambda incfile: include(env, incfile) env["include"] = lambda incfile: include(env, incfile)
env["dump"] = lambda incfile: dump(env, incfile)
env.included = set([])
include(env, "common") include(env, "common")
entry.text = pygen.generate(self.code, env) entry.text = pygen.generate(self.code, env)
debug(entry.text)
except Exception, e: except Exception, e:
logger.error('Python exec error: %s: %s' % (str(e.__class__).split('.', 2)[1], str(e))) logger.error('Python exec error: %s: %s' % (str(e.__class__).split('.', 2)[1], str(e)))
raise Bcfg2.Server.Plugin.PluginExecutionError raise Bcfg2.Server.Plugin.PluginExecutionError
@ -192,12 +191,15 @@ class Python(Bcfg2.Server.Plugin.Plugin):
if path.startswith(self.include): if path.startswith(self.include):
if posixpath.isfile(path) and path.endswith(".py"): if posixpath.isfile(path) and path.endswith(".py"):
# Les fichiers d'includes... # Les fichiers d'includes...
identifier = path[len(self.include)+1:-3]
if action in ['exists', 'created', 'changed']: if action in ['exists', 'created', 'changed']:
debug("adding include file: %s" % event.filename[:-3], 'green') debug("adding include file: %s" % identifier, 'green')
includes[event.filename[:-3]] = load_file(path) includes[identifier] = load_file(path)
elif action == 'deleted': elif action == 'deleted':
debug("deleting include file: %s" % event.filename[:-3], 'red') debug("deleting include file: %s" % identifier, 'red')
del includes[event.filename[:-3]] del includes[identifier]
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) and event.filename in _monitored_files:
# Le nom du dossier est le nom du fichier du fichier de # Le nom du dossier est le nom du fichier du fichier de
@ -205,14 +207,22 @@ class Python(Bcfg2.Server.Plugin.Plugin):
identifier = hdle_path[len(self.data):] identifier = hdle_path[len(self.data):]
if action in ['exists', 'created']: if action in ['exists', 'created']:
if not self.entries.has_key(identifier): if not self.entries.has_key(identifier):
entry = PythonFile(identifier, self.properties)
entry.file_count = 1
debug("adding config file: %s" % identifier, 'green') debug("adding config file: %s" % identifier, 'green')
self.entries[identifier] = PythonFile(identifier, self.properties) self.entries[identifier] = entry
self.Entries['ConfigFile'][identifier] = self.BuildEntry self.Entries['ConfigFile'][identifier] = self.BuildEntry
self.entries[identifier].Created(path, event) else:
entry = self.entries[identifier]
entry.file_count += 1
entry.Created(path, event)
elif action == 'changed': elif action == 'changed':
self.entries[identifier].Changed(path, event) self.entries[identifier].Changed(path, event)
elif action == 'deleted': elif action == 'deleted':
if self.entries[identifier].Deleted(path, event): entry = self.entries[identifier]
entry.Deleted(path, event)
entry.file_count -= 1
if not entry.file_count:
debug("deleting config file: %s" % identifier, 'red') debug("deleting config file: %s" % identifier, 'red')
del self.entries[identifier] del self.entries[identifier]
del self.Entries['ConfigFile'][identifier] del self.Entries['ConfigFile'][identifier]