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
script python'''
__all__ = ["Python"]
import logging, lxml.etree, posixpath, re, os, sys
from cStringIO import StringIO
import Bcfg2.Server.Plugin
@ -56,7 +58,12 @@ _monitored_files = ["info.xml", "gen.py"]
# Dico nom de fichier -> code
includes = {}
def dump(env, incfile):
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):
@ -75,17 +82,6 @@ class PythonFile:
self.code = None
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):
'''Traitement des créations de fichier'''
if event.filename == "gen.py":
@ -107,18 +103,21 @@ class PythonFile:
self.code = None
else:
self.info = None
return self.code or self.info
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
@ -192,12 +191,15 @@ class Python(Bcfg2.Server.Plugin.Plugin):
if path.startswith(self.include):
if posixpath.isfile(path) and path.endswith(".py"):
# Les fichiers d'includes...
identifier = path[len(self.include)+1:-3]
if action in ['exists', 'created', 'changed']:
debug("adding include file: %s" % event.filename[:-3], 'green')
includes[event.filename[:-3]] = load_file(path)
debug("adding include file: %s" % identifier, 'green')
includes[identifier] = load_file(path)
elif action == 'deleted':
debug("deleting include file: %s" % event.filename[:-3], 'red')
del includes[event.filename[:-3]]
debug("deleting include file: %s" % identifier, 'red')
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:
# 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):]
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] = PythonFile(identifier, self.properties)
self.entries[identifier] = entry
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':
self.entries[identifier].Changed(path, event)
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')
del self.entries[identifier]
del self.Entries['ConfigFile'][identifier]