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):
|
||||
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']:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue