From 4210b7c9ade4091999cec5dc079a3bc764d56463 Mon Sep 17 00:00:00 2001 From: Jeremie Dimino Date: Tue, 18 Dec 2007 23:07:29 +0100 Subject: [PATCH] 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 --- bcfg2/plugins/Python.py | 133 +++++++++++++--------------------------- 1 file changed, 44 insertions(+), 89 deletions(-) diff --git a/bcfg2/plugins/Python.py b/bcfg2/plugins/Python.py index 39b5ab33..6a19a76f 100644 --- a/bcfg2/plugins/Python.py +++ b/bcfg2/plugins/Python.py @@ -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']: