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:
parent
3ec7919694
commit
4210b7c9ad
1 changed files with 44 additions and 89 deletions
|
@ -52,9 +52,6 @@ else:
|
||||||
def debug(msg, color=None):
|
def debug(msg, color=None):
|
||||||
pass
|
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
|
# Dico nom de fichier -> code
|
||||||
includes = {}
|
includes = {}
|
||||||
|
|
||||||
|
@ -69,65 +66,11 @@ def include(env, incfile):
|
||||||
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:
|
||||||
return pygen.load(filename)
|
return pygen.load(filename, os.path.dirname(filename) + "/." + os.path.basename(filename) + ".COMPILED")
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
logger.error('Python compilation error: %s: %s' % (str(e.__class__).split('.', 2)[1], str(e)))
|
logger.error('Python compilation error: %s: %s' % (str(e.__class__).split('.', 2)[1], str(e)))
|
||||||
return None
|
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 PythonProperties(Bcfg2.Server.Plugin.SingleXMLFileBacked):
|
||||||
'''Class for Python properties'''
|
'''Class for Python properties'''
|
||||||
def Index(self):
|
def Index(self):
|
||||||
|
@ -153,8 +96,8 @@ class Python(Bcfg2.Server.Plugin.Plugin):
|
||||||
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
|
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
|
||||||
# Les entrées pour bcfg2
|
# Les entrées pour bcfg2
|
||||||
self.Entries['ConfigFile'] = {}
|
self.Entries['ConfigFile'] = {}
|
||||||
# Nos entrées pour nous (dico de PythonFile)
|
# Correspondance entrée ConfigFile -> code
|
||||||
self.entries = {}
|
self.codes = {}
|
||||||
# Dico ID de requête GAM -> Dossier surveillé
|
# Dico ID de requête GAM -> Dossier surveillé
|
||||||
self.handles = {}
|
self.handles = {}
|
||||||
# Le dossier qui contient les fichiers à inclure
|
# 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")
|
self.logger.info("Failed to read properties file; Python properties disabled")
|
||||||
|
|
||||||
def BuildEntry(self, entry, metadata):
|
def BuildEntry(self, entry, metadata):
|
||||||
'''Dispatch fetch calls to the correct object'''
|
'''Construit le fichier'''
|
||||||
self.entries[entry.get('name')].BuildFile(entry, metadata)
|
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):
|
def HandleEvent(self, event):
|
||||||
'''Traitement des événements de FAM'''
|
'''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()
|
action = event.code2str()
|
||||||
debug("event received: action=%s filename=%s requestID=%s" %
|
debug("event received: action=%s filename=%s requestID=%s" %
|
||||||
(action, event.filename, event.requestID), 'purple')
|
(action, event.filename, event.requestID), 'purple')
|
||||||
|
|
||||||
if event.filename[0] == '/' or event.filename.endswith(".pyc"):
|
path = self.handles[event.requestID] + "/" + event.filename
|
||||||
# Rien d'intéressant
|
|
||||||
return
|
|
||||||
|
|
||||||
hdle_path = self.handles[event.requestID]
|
|
||||||
path = hdle_path + "/" + event.filename
|
|
||||||
debug("absolute filename: %s" % path, 'yellow')
|
debug("absolute filename: %s" % path, 'yellow')
|
||||||
|
|
||||||
if path.startswith(self.include):
|
if path.startswith(self.include):
|
||||||
if posixpath.isfile(path) and path.endswith(".py"):
|
if posixpath.isfile(path):
|
||||||
# Les fichiers d'includes...
|
# Les fichiers d'includes...
|
||||||
identifier = path[len(self.include)+1:-3]
|
identifier = path[len(self.include)+1:-3]
|
||||||
if action in ['exists', 'created', 'changed']:
|
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']:
|
elif posixpath.isdir(path) and action in ['exists', 'created']:
|
||||||
self.AddDirectoryMonitor(path)
|
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
|
# Le nom du dossier est le nom du fichier du fichier de
|
||||||
# configuration à générer
|
# configuration à générer
|
||||||
identifier = hdle_path[len(self.data):]
|
identifier = path[len(self.data):]
|
||||||
if action in ['exists', 'created']:
|
if action in ['exists', 'created']:
|
||||||
if not self.entries.has_key(identifier):
|
debug("adding config file: %s" % identifier, 'green')
|
||||||
entry = PythonFile(identifier, self.properties)
|
self.codes[identifier] = load_file(path)
|
||||||
entry.file_count = 1
|
self.Entries['ConfigFile'][identifier] = self.BuildEntry
|
||||||
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)
|
|
||||||
elif action == 'changed':
|
elif action == 'changed':
|
||||||
self.entries[identifier].Changed(path, event)
|
self.codes[identifier] = load_file(path)
|
||||||
elif action == 'deleted':
|
elif action == 'deleted':
|
||||||
entry = self.entries[identifier]
|
debug("deleting config file: %s" % identifier, 'red')
|
||||||
entry.Deleted(path, event)
|
del self.codes[identifier]
|
||||||
entry.file_count -= 1
|
del self.Entries['ConfigFile'][identifier]
|
||||||
if not entry.file_count:
|
|
||||||
debug("deleting config file: %s" % identifier, 'red')
|
|
||||||
del self.entries[identifier]
|
|
||||||
del self.Entries['ConfigFile'][identifier]
|
|
||||||
|
|
||||||
elif posixpath.isdir(path):
|
elif posixpath.isdir(path):
|
||||||
if action in ['exists', 'created']:
|
if action in ['exists', 'created']:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue