début de travail sur les liens

This commit is contained in:
Jephté Clain 2017-06-16 00:36:36 +04:00
parent 02c5f91b78
commit 8e48af9373
1 changed files with 171 additions and 19 deletions

View File

@ -52,7 +52,7 @@ class GenericObject(object):
elif method == 'reset': self.reset_attr(name, value)
elif method == 'add': self.add_attr(name, value)
elif method == 'del': self.del_attr(name, value)
def copy_attrs(self, other, method='set'):
def merge_attrs(self, other, method='set'):
for name, values in other.attrs.items():
for value in values:
self.modify_attr(name, value, method)
@ -130,29 +130,131 @@ class WebappObject(GenericObject):
self._dump_values(indent, 'webapps')
self._dump_attrs(indent)
class GenericLink(object):
_profile = None
_ftype = None
_froms = None
_ttype = None
_tos = None
_attrs = None
def __init__(self, ftype, ttype):
self._ftype = ftype
self._froms = []
self._ttype = ttype
self._tos = []
self._attrs = {}
def get_profile(self): return self._profile
def set_profile(self): self._profile = profile
profile = property(get_profile, set_profile)
def get_ftype(self): return self._ftype
ftype = property(get_ftype)
def get_froms(self): return self._froms
froms = property(get_froms)
def add_from(self, fo):
if fo not in self._froms: self._froms.append(fo)
def get_ttype(self): return self._ttype
ttype = property(get_ttype)
def get_tos(self): return self._tos
tos = property(get_tos)
def add_to(self, to):
if to not in self._tos: self._tos.append(to)
def get_attrs(self): return self._attrs
attrs = property(get_attrs)
def get_attr(self, name): return self._attrs.get(name, None)
def set_attr(self, name, value):
if name not in self._attrs: self._attrs[name] = []
if value not in self._attrs[name]: self._attrs[name].append(value)
def reset_attr(self, name, value=None):
if name in self._attrs: del self._attrs[name]
if value is not None: self.set_attr(name, value)
def add_attr(self, name, value):
if name not in self._attrs: self._attrs[name] = []
self._attrs[name].append(value)
def del_attr(self, name, value):
if name not in self._attrs: return
self._attrs[name].remove(value)
if not self._attrs[name]: del self._attrs[name]
def modify_attr(self, name, value, method='set'):
if method == 'set': self.set_attr(name, value)
elif method == 'reset': self.reset_attr(name, value)
elif method == 'add': self.add_attr(name, value)
elif method == 'del': self.del_attr(name, value)
def merge_attrs(self, other, method='set'):
for name, values in other.attrs.items():
for value in values:
self.modify_attr(name, value, method)
def _dump_profile(self, indent):
profile = self.profile or 'ALL'
print "%s profile: %s" % (indent, profile)
def _dump_froms(self, indent):
print "%s from: %s" % (indent, ' '.join(self.froms))
def _dump_tos(self, indent):
print "%s to: %s" % (indent, ' '.join(self.tos))
def _dump_attrs(self, indent):
if self.attrs:
print "%s attrs:" % indent
for name, values in self.attrs.items():
if len(values) == 1:
print "%s %s=%s" % (indent, name, repr(values[0]))
else:
print "%s %s=(%s)" % (indent, name, ', '.join(map(repr, values)))
def dump(self, indent=''):
print "%slink" % indent
self._dump_profile(indent)
self._dump_froms(indent)
self._dump_tos(indent)
self._dump_attrs(indent)
class UinstLink(GenericLink):
def __init__(self):
super(UinstLink, self).__init__('module', 'host')
def dump(self, indent=''):
print "%suinst" % indent
self._dump_profile(indent)
self._dump_froms(indent)
self._dump_tos(indent)
self._dump_attrs(indent)
class RuinstLink(GenericLink):
def __init__(self):
super(UinstLink, self).__init__('module', 'host')
def dump(self, indent=''):
print "%suinst" % indent
self._dump_froms(indent)
self._dump_tos(indent)
self._dump_attrs(indent)
class Database(object):
_known_profiles = None
_default_profile = None
_default_domain = None
_objects = None
_objects_classes = None
_links = None
_links_classes = None
def __init__(self):
self._known_profiles = {}
self._objects = {}
self._objects_classes = {}
def get_known_profiles(self):
return self._known_profiles.keys()
known_profiles = property(get_known_profiles)
self._links = {}
self._links_classes = {}
def has_default_profile(self):
return self._default_profile is not None
def get_default_profile(self):
return self._default_profile
def set_default_profile(self, profile):
if profile: self._known_profiles[profile] = True
self._default_profile = profile or None
default_profile = property(get_default_profile, set_default_profile)
@ -180,7 +282,6 @@ class Database(object):
objects = self._objects.get(otype, None)
if objects is None: return None
return [objects[id] for id in objects if id is not None]
objects = property(get_objects)
def has_object(self, otype, id):
objects = self._objects.get(otype, None)
if objects is None: return False
@ -196,6 +297,18 @@ class Database(object):
self._objects[otype][id] = object
return object
def register_link(self, ltype, lclass=None):
if not self._links.has_key(ltype):
self._links[ltype] = {}
if lclass is None: lclass = GenericLink
self._links_classes[ltype] = lclass
def get_known_profiles(self, ltype):
return self._links[ltype].keys()
def get_links(self, ltype, profile=None):
links = self._links.get(ltype, None)
if links is None: return None
return links.get(profile, None)
################################################################################
# Analyse des fichiers de configuration
@ -538,27 +651,29 @@ class Parser(object):
if name:
o = self.db.get_object('host', name)
if host: o.add_value(host)
o.copy_attrs(defaulto)
o.merge_attrs(defaulto)
if dir is not None: o.set_attr('dir', dir)
self.add_group('host', name)
else:
id = HostObject.genid(host)
o = self.db.get_object('host', id)
o.add_value(host)
o.copy_attrs(defaulto)
o.merge_attrs(defaulto)
if dir is not None: o.set_attr('dir', dir)
self.add_group('host', id)
ib = HostObject.genib(id)
o = self.db.get_object('host', ib)
o.add_value(host)
o.copy_attrs(defaulto)
o.merge_attrs(defaulto)
if dir is not None: o.set_attr('dir', dir)
self.add_group('host', ib)
############################################################################
def __setup_uinst(self):
self.db.register_object('module', ModuleObject)
self.db.register_link('uinst', UinstLink)
self.db.register_link('ruinst', RuinstLink)
self.db.get_object('module', None)
self.groups['module'] = {}
self.handle_group(['module', 'defaults'])
@ -618,7 +733,7 @@ class Parser(object):
if name:
o = self.db.get_object('module', name)
if module: o.add_value(module)
o.copy_attrs(defaulto)
o.merge_attrs(defaulto)
if dir is not None: o.set_attr('dir', dir)
if modulep is not None: o.set_attr('path', modulep)
self.add_group('module', name)
@ -626,13 +741,50 @@ class Parser(object):
id = ModuleObject.genid(module)
o = self.db.get_object('module', id)
if module: o.add_value(module)
o.copy_attrs(defaulto)
o.merge_attrs(defaulto)
if dir is not None: o.set_attr('dir', dir)
if modulep is not None: o.set_attr('path', modulep)
self.add_group('module', id)
def handle_xuinst(self, cmd, *args):
pass
def handle_xuinst(self, ltype, *args):
"""uinst -p profile attrs*
ruinst -p profile attrs*
"""
AP = ArgumentParser()
AP.add_argument('-p', '--profile', action='append', dest='profiles')
AP.add_argument('nvss', nargs=REMAINDER)
o = AP.parse_args(args)
profiles = o.profiles or [None]
for profile in profiles:
# préparer la mise à jour du groupe courant
currentls = self.db.get_link(ltype, profile, fo=self.groups['module']['current'], create=True)
if profile is not None:
globall = self.db.get_link(ltype, None, fo=None, create=True)
for currentl in currentls:
currentl.merge_attrs(globall)
defaultl = self.db.get_link(ltype, profile, fo=None, create=True)
for currentl in currentls:
currentl.merge_attrs(defaultl)
# traiter les liens
for nvs in nvss:
name, value = split_namev(nvs)
if name == defaultl.ttype:
# définir des destinations du lien
values = split_nlist(nvs)[1]
for host in values:
for currentl in currentls:
currentl.add_to(host)
else:
# définir un attribut du lien
name, value, type, method = split_namev(nv)
if value is None:
method = 'set'
value = '1'
elif type == 'path':
value = path.expanduser(value)
for id in self.groups[otype]['current']:
for currentl in currentls:
currentl.modify_attr(name, value, method)
############################################################################
def __setup_woinst(self):
@ -697,7 +849,7 @@ class Parser(object):
if name:
o = self.db.get_object('wobundle', name)
if wobundle: o.add_value(wobundle)
o.copy_attrs(defaulto)
o.merge_attrs(defaulto)
if dir is not None: o.set_attr('dir', dir)
if wobundlep is not None: o.set_attr('path', wobundlep)
self.add_group('wobundle', name)
@ -705,7 +857,7 @@ class Parser(object):
id = WobundleObject.genid(wobundle)
o = self.db.get_object('wobundle', id)
if wobundle: o.add_value(wobundle)
o.copy_attrs(defaulto)
o.merge_attrs(defaulto)
if dir is not None: o.set_attr('dir', dir)
if wobundlep is not None: o.set_attr('path', wobundlep)
self.add_group('wobundle', id)
@ -774,7 +926,7 @@ class Parser(object):
if name:
o = self.db.get_object('webapp', name)
if webapp: o.add_value(webapp)
o.copy_attrs(defaulto)
o.merge_attrs(defaulto)
if dir is not None: o.set_attr('dir', dir)
if webappp is not None: o.set_attr('path', webappp)
self.add_group('webapp', name)
@ -782,7 +934,7 @@ class Parser(object):
id = WebappObject.genid(webapp)
o = self.db.get_object('webapp', id)
if webapp: o.add_value(webapp)
o.copy_attrs(defaulto)
o.merge_attrs(defaulto)
if dir is not None: o.set_attr('dir', dir)
if webappp is not None: o.set_attr('path', webappp)
self.add_group('webapp', id)