xuinst
This commit is contained in:
parent
f0de1213f6
commit
e0b15350c1
|
@ -9,9 +9,19 @@ from glob import glob
|
||||||
USER_CONFDIR = '~/etc/deploy'
|
USER_CONFDIR = '~/etc/deploy'
|
||||||
SYSTEM_CONFDIR = '/var/local/deploy'
|
SYSTEM_CONFDIR = '/var/local/deploy'
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Diverses fonctions
|
||||||
|
|
||||||
|
def isseq(t):
|
||||||
|
return isinstance(t, list) or isinstance(t, tuple) or isinstance(t, set)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Base de données
|
# Base de données
|
||||||
|
|
||||||
|
class UNDEFINED(object):
|
||||||
|
__repr__ = __string__ = lambda self: 'UNDEFINED'
|
||||||
|
UNDEFINED = UNDEFINED()
|
||||||
|
|
||||||
class GenericObject(object):
|
class GenericObject(object):
|
||||||
_id = None
|
_id = None
|
||||||
_values = None
|
_values = None
|
||||||
|
@ -19,7 +29,7 @@ class GenericObject(object):
|
||||||
|
|
||||||
def __init__(self, id):
|
def __init__(self, id):
|
||||||
self._id = id
|
self._id = id
|
||||||
self._values = []
|
self._values = set()
|
||||||
self._attrs = {}
|
self._attrs = {}
|
||||||
|
|
||||||
def get_id(self): return self._id
|
def get_id(self): return self._id
|
||||||
|
@ -28,7 +38,7 @@ class GenericObject(object):
|
||||||
def get_values(self): return self._values
|
def get_values(self): return self._values
|
||||||
values = property(get_values)
|
values = property(get_values)
|
||||||
def add_value(self, value):
|
def add_value(self, value):
|
||||||
if value not in self._values: self._values.append(value)
|
self._values.add(value)
|
||||||
|
|
||||||
def get_attrs(self): return self._attrs
|
def get_attrs(self): return self._attrs
|
||||||
attrs = property(get_attrs)
|
attrs = property(get_attrs)
|
||||||
|
@ -133,16 +143,16 @@ class WebappObject(GenericObject):
|
||||||
class GenericLink(object):
|
class GenericLink(object):
|
||||||
_profile = None
|
_profile = None
|
||||||
_ftype = None
|
_ftype = None
|
||||||
_froms = None
|
_fos = None
|
||||||
_ttype = None
|
_ttype = None
|
||||||
_tos = None
|
_tos = None
|
||||||
_attrs = None
|
_attrs = None
|
||||||
|
|
||||||
def __init__(self, ftype, ttype):
|
def __init__(self, ftype, ttype):
|
||||||
self._ftype = ftype
|
self._ftype = ftype
|
||||||
self._froms = []
|
self._fos = set()
|
||||||
self._ttype = ttype
|
self._ttype = ttype
|
||||||
self._tos = []
|
self._tos = set()
|
||||||
self._attrs = {}
|
self._attrs = {}
|
||||||
|
|
||||||
def get_profile(self): return self._profile
|
def get_profile(self): return self._profile
|
||||||
|
@ -151,17 +161,17 @@ class GenericLink(object):
|
||||||
|
|
||||||
def get_ftype(self): return self._ftype
|
def get_ftype(self): return self._ftype
|
||||||
ftype = property(get_ftype)
|
ftype = property(get_ftype)
|
||||||
def get_froms(self): return self._froms
|
def get_fos(self): return self._fos
|
||||||
froms = property(get_froms)
|
fos = property(get_fos)
|
||||||
def add_from(self, fo):
|
def add_fo(self, fo):
|
||||||
if fo not in self._froms: self._froms.append(fo)
|
self._fos.add(fo)
|
||||||
|
|
||||||
def get_ttype(self): return self._ttype
|
def get_ttype(self): return self._ttype
|
||||||
ttype = property(get_ttype)
|
ttype = property(get_ttype)
|
||||||
def get_tos(self): return self._tos
|
def get_tos(self): return self._tos
|
||||||
tos = property(get_tos)
|
tos = property(get_tos)
|
||||||
def add_to(self, to):
|
def add_to(self, to):
|
||||||
if to not in self._tos: self._tos.append(to)
|
self._tos.add(to)
|
||||||
|
|
||||||
def get_attrs(self): return self._attrs
|
def get_attrs(self): return self._attrs
|
||||||
attrs = property(get_attrs)
|
attrs = property(get_attrs)
|
||||||
|
@ -190,11 +200,28 @@ class GenericLink(object):
|
||||||
for value in values:
|
for value in values:
|
||||||
self.modify_attr(name, value, method)
|
self.modify_attr(name, value, method)
|
||||||
|
|
||||||
|
def match_fos(self, fos, match='any'):
|
||||||
|
if not isseq(fos): fos = [fos]
|
||||||
|
for fo in fos:
|
||||||
|
if fo in self._fos: return True
|
||||||
|
return False
|
||||||
|
def match_tos(self, tos, match='any'):
|
||||||
|
if not isseq(tos): tos = [tos]
|
||||||
|
for to in tos:
|
||||||
|
if to in self._tos: return True
|
||||||
|
return False
|
||||||
|
def match_attrs(self, attrs, match='any'):
|
||||||
|
for name, value in attrs.items():
|
||||||
|
values = self._attrs.get(name, None)
|
||||||
|
if values is not None:
|
||||||
|
if value in values: return True
|
||||||
|
return False
|
||||||
|
|
||||||
def _dump_profile(self, indent):
|
def _dump_profile(self, indent):
|
||||||
profile = self.profile or 'ALL'
|
profile = self.profile or 'ALL'
|
||||||
print "%s profile: %s" % (indent, profile)
|
print "%s profile: %s" % (indent, profile)
|
||||||
def _dump_froms(self, indent):
|
def _dump_fos(self, indent):
|
||||||
print "%s from: %s" % (indent, ' '.join(self.froms))
|
print "%s from: %s" % (indent, ' '.join(self.fos))
|
||||||
def _dump_tos(self, indent):
|
def _dump_tos(self, indent):
|
||||||
print "%s to: %s" % (indent, ' '.join(self.tos))
|
print "%s to: %s" % (indent, ' '.join(self.tos))
|
||||||
def _dump_attrs(self, indent):
|
def _dump_attrs(self, indent):
|
||||||
|
@ -208,7 +235,7 @@ class GenericLink(object):
|
||||||
def dump(self, indent=''):
|
def dump(self, indent=''):
|
||||||
print "%slink" % indent
|
print "%slink" % indent
|
||||||
self._dump_profile(indent)
|
self._dump_profile(indent)
|
||||||
self._dump_froms(indent)
|
self._dump_fos(indent)
|
||||||
self._dump_tos(indent)
|
self._dump_tos(indent)
|
||||||
self._dump_attrs(indent)
|
self._dump_attrs(indent)
|
||||||
|
|
||||||
|
@ -219,17 +246,17 @@ class UinstLink(GenericLink):
|
||||||
def dump(self, indent=''):
|
def dump(self, indent=''):
|
||||||
print "%suinst" % indent
|
print "%suinst" % indent
|
||||||
self._dump_profile(indent)
|
self._dump_profile(indent)
|
||||||
self._dump_froms(indent)
|
self._dump_fos(indent)
|
||||||
self._dump_tos(indent)
|
self._dump_tos(indent)
|
||||||
self._dump_attrs(indent)
|
self._dump_attrs(indent)
|
||||||
|
|
||||||
class RuinstLink(GenericLink):
|
class RuinstLink(GenericLink):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(UinstLink, self).__init__('module', 'host')
|
super(RuinstLink, self).__init__('module', 'host')
|
||||||
|
|
||||||
def dump(self, indent=''):
|
def dump(self, indent=''):
|
||||||
print "%suinst" % indent
|
print "%suinst" % indent
|
||||||
self._dump_froms(indent)
|
self._dump_fos(indent)
|
||||||
self._dump_tos(indent)
|
self._dump_tos(indent)
|
||||||
self._dump_attrs(indent)
|
self._dump_attrs(indent)
|
||||||
|
|
||||||
|
@ -244,7 +271,6 @@ class Database(object):
|
||||||
_links_classes = None
|
_links_classes = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._known_profiles = {}
|
|
||||||
self._objects = {}
|
self._objects = {}
|
||||||
self._objects_classes = {}
|
self._objects_classes = {}
|
||||||
self._links = {}
|
self._links = {}
|
||||||
|
@ -297,17 +323,45 @@ class Database(object):
|
||||||
self._objects[otype][id] = object
|
self._objects[otype][id] = object
|
||||||
return object
|
return object
|
||||||
|
|
||||||
def register_link(self, ltype, lclass=None):
|
def register_link(self, ltype, lclass):
|
||||||
if not self._links.has_key(ltype):
|
if not self._links.has_key(ltype):
|
||||||
self._links[ltype] = {}
|
self._links[ltype] = {}
|
||||||
if lclass is None: lclass = GenericLink
|
|
||||||
self._links_classes[ltype] = lclass
|
self._links_classes[ltype] = lclass
|
||||||
def get_known_profiles(self, ltype):
|
def get_known_profiles(self, ltype):
|
||||||
return self._links[ltype].keys()
|
return self._links[ltype].keys()
|
||||||
def get_links(self, ltype, profile=None):
|
def get_links(self, ltype, profile, fo=UNDEFINED, to=UNDEFINED, attrs=UNDEFINED, create=False):
|
||||||
links = self._links.get(ltype, None)
|
if fo is UNDEFINED and to is UNDEFINED and attrs is UNDEFINED:
|
||||||
if links is None: return None
|
raise ValueError("you must set either fo, to ou attrs")
|
||||||
return links.get(profile, None)
|
plinks = self._links.get(ltype, None)
|
||||||
|
if plinks is None: return None
|
||||||
|
links = plinks.get(profile, None)
|
||||||
|
if links is None: links = plinks[profile] = []
|
||||||
|
|
||||||
|
found = None
|
||||||
|
for link in links:
|
||||||
|
if (fo is UNDEFINED or link.match_fos(fo)) \
|
||||||
|
and (to is UNDEFINED or link.match_tos(to)) \
|
||||||
|
and (attrs is UNDEFINED or link.match_attrs(attrs)):
|
||||||
|
if found is None: found = []
|
||||||
|
found.append(link)
|
||||||
|
if found is not None: return found
|
||||||
|
if not create: return None
|
||||||
|
link = self._links_classes[ltype]()
|
||||||
|
if fo is not UNDEFINED:
|
||||||
|
if isseq(fo): fos = fo
|
||||||
|
else: fos = [fo]
|
||||||
|
for fo in fos:
|
||||||
|
link.add_fo(fo)
|
||||||
|
if to is not UNDEFINED:
|
||||||
|
if isseq(to): tos = to
|
||||||
|
else: tos = [to]
|
||||||
|
for to in tos:
|
||||||
|
link.add_to(to)
|
||||||
|
if attrs is not UNDEFINED:
|
||||||
|
for name, value in attrs.items():
|
||||||
|
link.set_attr(name, value)
|
||||||
|
links.append(link)
|
||||||
|
return [link]
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Analyse des fichiers de configuration
|
# Analyse des fichiers de configuration
|
||||||
|
@ -536,13 +590,13 @@ class Parser(object):
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
def reset_group(self, otype):
|
def reset_group(self, otype):
|
||||||
self.groups[otype]['current'] = {}
|
self.groups[otype]['current'] = set()
|
||||||
def reset_group_maybe(self, otype):
|
def reset_group_maybe(self, otype):
|
||||||
if self.groups[otype]['type'] in ('defaults', 'once'):
|
if self.groups[otype]['type'] in ('defaults', 'once'):
|
||||||
self.reset_group(otype)
|
self.reset_group(otype)
|
||||||
self.groups[otype]['type'] = 'once'
|
self.groups[otype]['type'] = 'once'
|
||||||
def add_group(self, otype, id):
|
def add_group(self, otype, id):
|
||||||
self.groups[otype]['current'][id] = True
|
self.groups[otype]['current'].add(id)
|
||||||
|
|
||||||
def handle_group(self, args):
|
def handle_group(self, args):
|
||||||
"""group otype gtype
|
"""group otype gtype
|
||||||
|
@ -558,9 +612,9 @@ class Parser(object):
|
||||||
gtype = args[1:2] and args[1] or 'until'
|
gtype = args[1:2] and args[1] or 'until'
|
||||||
self.groups[otype]['type'] = gtype
|
self.groups[otype]['type'] = gtype
|
||||||
if gtype == 'defaults':
|
if gtype == 'defaults':
|
||||||
self.groups[otype]['current'] = {None: True}
|
self.groups[otype]['current'] = set([None])
|
||||||
elif gtype in ('once', 'until'):
|
elif gtype in ('once', 'until'):
|
||||||
self.groups[otype]['current'] = {}
|
self.groups[otype]['current'] = set()
|
||||||
else:
|
else:
|
||||||
raise ValueError('%s: invalid group type' % gtype)
|
raise ValueError('%s: invalid group type' % gtype)
|
||||||
self.attr_otype = otype
|
self.attr_otype = otype
|
||||||
|
@ -757,32 +811,35 @@ class Parser(object):
|
||||||
profiles = o.profiles or [None]
|
profiles = o.profiles or [None]
|
||||||
for profile in profiles:
|
for profile in profiles:
|
||||||
# préparer la mise à jour du groupe courant
|
# préparer la mise à jour du groupe courant
|
||||||
currentls = self.db.get_link(ltype, profile, fo=self.groups['module']['current'], create=True)
|
currentls = self.db.get_links(ltype, profile, fo=self.groups['module']['current'], create=True)
|
||||||
if profile is not None:
|
if profile is not None:
|
||||||
globall = self.db.get_link(ltype, None, fo=None, create=True)
|
globalls = self.db.get_links(ltype, None, fo=None, create=True)
|
||||||
for currentl in currentls:
|
for currentl in currentls:
|
||||||
|
for globall in globalls:
|
||||||
currentl.merge_attrs(globall)
|
currentl.merge_attrs(globall)
|
||||||
defaultl = self.db.get_link(ltype, profile, fo=None, create=True)
|
defaultls = self.db.get_links(ltype, profile, fo=None, create=True)
|
||||||
for currentl in currentls:
|
for currentl in currentls:
|
||||||
|
for defaultl in defaultls:
|
||||||
currentl.merge_attrs(defaultl)
|
currentl.merge_attrs(defaultl)
|
||||||
|
defaultl = defaultls[0]
|
||||||
# traiter les liens
|
# traiter les liens
|
||||||
for nvs in nvss:
|
for nvs in args:
|
||||||
name, value = split_namev(nvs)
|
name, value, type, method = split_namev(nvs)
|
||||||
if name == defaultl.ttype:
|
if name == defaultl.ttype:
|
||||||
# définir des destinations du lien
|
# définir des destinations du lien
|
||||||
values = split_nlist(nvs)[1]
|
if value is not None:
|
||||||
for host in values:
|
tos = split_nlist(nvs)[1]
|
||||||
|
for to in tos:
|
||||||
for currentl in currentls:
|
for currentl in currentls:
|
||||||
currentl.add_to(host)
|
currentl.add_to(to)
|
||||||
else:
|
else:
|
||||||
# définir un attribut du lien
|
# définir un attribut du lien
|
||||||
name, value, type, method = split_namev(nv)
|
#name, value, type, method = split_namev(nv)
|
||||||
if value is None:
|
if value is None:
|
||||||
method = 'set'
|
method = 'set'
|
||||||
value = '1'
|
value = '1'
|
||||||
elif type == 'path':
|
elif type == 'path':
|
||||||
value = path.expanduser(value)
|
value = path.expanduser(value)
|
||||||
for id in self.groups[otype]['current']:
|
|
||||||
for currentl in currentls:
|
for currentl in currentls:
|
||||||
currentl.modify_attr(name, value, method)
|
currentl.modify_attr(name, value, method)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue