better systemd service support
This commit is contained in:
parent
20f329d433
commit
9c1589ca53
45 changed files with 496 additions and 120 deletions
|
@ -28,15 +28,13 @@ from os.path import basename
|
|||
from typing import Tuple
|
||||
|
||||
from rougail.i18n import _
|
||||
from rougail.utils import normalize_family
|
||||
from rougail.utils import normalize_family, valid_variable_family_name
|
||||
from rougail.error import DictConsistencyError
|
||||
# a object's attribute has some annotations
|
||||
# that shall not be present in the exported (flatened) XML
|
||||
ERASED_ATTRIBUTES = ('redefine', 'exists', 'optional', 'remove_check', 'namespace',
|
||||
'remove_condition', 'path', 'instance_mode', 'index',
|
||||
'level', 'remove_fill', 'xmlfiles', 'type', 'reflector_name',
|
||||
'reflector_object',)
|
||||
ALLOW_ATTRIBUT_NOT_MANAGE = ['file']
|
||||
ERASED_ATTRIBUTES = ('redefine', 'namespace', 'xmlfiles', 'disabled', 'name', 'manage')
|
||||
ERASED_ATTRIBUTES2 = ('redefine', 'namespace', 'xmlfiles')
|
||||
ALLOW_ATTRIBUT_NOT_MANAGE = ['file', 'engine', 'target']
|
||||
|
||||
|
||||
class Annotator:
|
||||
|
@ -72,6 +70,7 @@ class Annotator:
|
|||
self.objectspace.space.services.doc = 'services'
|
||||
self.objectspace.space.services.path = 'services'
|
||||
for service_name, service in self.objectspace.space.services.service.items():
|
||||
valid_variable_family_name(service_name, service.xmlfiles)
|
||||
activate_obj = self._generate_element('boolean',
|
||||
None,
|
||||
None,
|
||||
|
@ -88,29 +87,34 @@ class Annotator:
|
|||
values,
|
||||
[]).append(activate_obj)
|
||||
continue
|
||||
if not isinstance(values, (dict, list)) or elttype in ERASED_ATTRIBUTES:
|
||||
if elttype in ERASED_ATTRIBUTES:
|
||||
continue
|
||||
if not service.manage and elttype not in ALLOW_ATTRIBUT_NOT_MANAGE:
|
||||
msg = _(f'unmanage service cannot have "{elttype}"')
|
||||
raise DictConsistencyError(msg, 66, service.xmlfiles)
|
||||
if elttype != 'ip':
|
||||
eltname = elttype + 's'
|
||||
if isinstance(values, (dict, list)):
|
||||
if elttype != 'ip':
|
||||
eltname = elttype + 's'
|
||||
else:
|
||||
eltname = elttype
|
||||
path = '.'.join(['services', normalize_family(service_name), eltname])
|
||||
family = self._gen_family(eltname,
|
||||
path,
|
||||
service.xmlfiles,
|
||||
with_informations=False,
|
||||
)
|
||||
if isinstance(values, dict):
|
||||
values = list(values.values())
|
||||
family.family = self.make_group_from_elts(service_name,
|
||||
elttype,
|
||||
values,
|
||||
path,
|
||||
)
|
||||
setattr(service, elttype, family)
|
||||
else:
|
||||
eltname = elttype
|
||||
path = '.'.join(['services', normalize_family(service_name), eltname])
|
||||
family = self._gen_family(eltname,
|
||||
path,
|
||||
service.xmlfiles,
|
||||
with_informations=False,
|
||||
)
|
||||
if isinstance(values, dict):
|
||||
values = list(values.values())
|
||||
family.family = self.make_group_from_elts(service_name,
|
||||
elttype,
|
||||
values,
|
||||
path,
|
||||
)
|
||||
setattr(service, elttype, family)
|
||||
if not hasattr(service, 'information'):
|
||||
service.information = self.objectspace.information(service.xmlfiles)
|
||||
setattr(service.information, elttype, values)
|
||||
manage = self._generate_element('boolean',
|
||||
None,
|
||||
None,
|
||||
|
@ -157,7 +161,7 @@ class Annotator:
|
|||
'.'.join([subpath, 'activate']),
|
||||
)
|
||||
for key in dir(elt):
|
||||
if key.startswith('_') or key.endswith('_type') or key in ERASED_ATTRIBUTES:
|
||||
if key.startswith('_') or key.endswith('_type') or key in ERASED_ATTRIBUTES2:
|
||||
continue
|
||||
value = getattr(elt, key)
|
||||
if key == listname:
|
||||
|
|
|
@ -51,6 +51,9 @@
|
|||
<!ATTLIST service manage (True|False) "True">
|
||||
<!ATTLIST service servicelist CDATA #IMPLIED>
|
||||
<!ATTLIST service disabled (True|False) "False">
|
||||
<!ATTLIST service engine (none|creole|jinja2) #IMPLIED>
|
||||
<!ATTLIST service target CDATA #IMPLIED>
|
||||
<!ATTLIST service type (service|mount) "service">
|
||||
|
||||
<!ELEMENT ip (#PCDATA)>
|
||||
<!ATTLIST ip iplist CDATA #IMPLIED>
|
||||
|
|
|
@ -255,6 +255,7 @@ class RougailBaseTemplate:
|
|||
filevar: Dict,
|
||||
type_: str,
|
||||
service_name: str,
|
||||
service_type: str,
|
||||
) -> None:
|
||||
"""Run templatisation on one file
|
||||
"""
|
||||
|
@ -275,10 +276,11 @@ class RougailBaseTemplate:
|
|||
var = variable[idx]
|
||||
else:
|
||||
var = None
|
||||
func = f'_instance_{type_}'
|
||||
func = f'get_data_{type_}'
|
||||
data = getattr(self, func)(filevar,
|
||||
filename,
|
||||
service_name,
|
||||
service_type,
|
||||
variable,
|
||||
idx,
|
||||
)
|
||||
|
@ -319,10 +321,26 @@ class RougailBaseTemplate:
|
|||
for included in (True, False):
|
||||
for service_obj in await self.config.option('services').list('all'):
|
||||
service_name = await service_obj.option.name()
|
||||
service_type = await service_obj.information.get('type', 'service')
|
||||
if await service_obj.option('activate').value.get() is False:
|
||||
if included is False:
|
||||
self.desactive_service(service_name)
|
||||
self.desactive_service(service_name, service_type)
|
||||
continue
|
||||
if not included:
|
||||
engine = await service_obj.information.get('engine', None)
|
||||
if engine:
|
||||
self.instance_file({'engine': engine},
|
||||
'service',
|
||||
service_name,
|
||||
service_type,
|
||||
)
|
||||
target_name = await service_obj.information.get('target', None)
|
||||
if target_name:
|
||||
self.target_service(service_name,
|
||||
target_name,
|
||||
service_type,
|
||||
engine is None,
|
||||
)
|
||||
for fills in await service_obj.list('optiondescription'):
|
||||
type_ = await fills.option.name()
|
||||
for fill_obj in await fills.list('all'):
|
||||
|
@ -335,10 +353,14 @@ class RougailBaseTemplate:
|
|||
elif included is True:
|
||||
continue
|
||||
if fill['activate']:
|
||||
self.instance_file(fill, type_, service_name)
|
||||
self.instance_file(fill,
|
||||
type_,
|
||||
service_name,
|
||||
service_type,
|
||||
)
|
||||
else:
|
||||
self.log.debug(_("Instantiation of file '{filename}' disabled"))
|
||||
self.post_instance_service(service_name)
|
||||
self.post_instance_service(service_name, service_type)
|
||||
self.post_instance()
|
||||
chdir(ori_dir)
|
||||
|
||||
|
@ -356,29 +378,42 @@ class RougailBaseTemplate:
|
|||
dico[key] = await obj.information.get(key, default_value)
|
||||
|
||||
def desactive_service(self,
|
||||
service_name: str,
|
||||
*args,
|
||||
):
|
||||
raise NotImplementedError(_('cannot desactivate a service'))
|
||||
|
||||
def post_instance_service(self, service_name): # pragma: no cover
|
||||
def target_service(self,
|
||||
service_name: str,
|
||||
*args,
|
||||
):
|
||||
raise NotImplementedError(_('cannot use target for the service {service_name}'))
|
||||
|
||||
def post_instance_service(self,
|
||||
*args,
|
||||
): # pragma: no cover
|
||||
pass
|
||||
|
||||
def post_instance(self): # pragma: no cover
|
||||
pass
|
||||
|
||||
def _instance_ip(self,
|
||||
*args,
|
||||
) -> None: # pragma: no cover
|
||||
def get_data_ip(self,
|
||||
*args,
|
||||
) -> None: # pragma: no cover
|
||||
raise NotImplementedError(_('cannot instanciate this service type ip'))
|
||||
|
||||
def _instance_files(self,
|
||||
*args,
|
||||
) -> None: # pragma: no cover
|
||||
def get_data_files(self,
|
||||
*args,
|
||||
) -> None: # pragma: no cover
|
||||
raise NotImplementedError(_('cannot instanciate this service type file'))
|
||||
|
||||
def _instance_overrides(self,
|
||||
*args,
|
||||
) -> None: # pragma: no cover
|
||||
def get_data_service(self,
|
||||
*args,
|
||||
) -> None: # pragma: no cover
|
||||
raise NotImplementedError(_('cannot instanciate this service'))
|
||||
|
||||
def get_data_overrides(self,
|
||||
*args,
|
||||
) -> None: # pragma: no cover
|
||||
raise NotImplementedError(_('cannot instanciate this service type override'))
|
||||
|
||||
async def load_variables(self,
|
||||
|
|
|
@ -38,9 +38,13 @@ IPAddressDeny=any
|
|||
"""
|
||||
|
||||
|
||||
ROUGAIL_TMPL_TEMPLATE = """%def display(%%file, %%filename)
|
||||
ROUGAIL_DEST = '/usr/local/lib'
|
||||
ROUGAIL_GLOBAL_SYSTEMD_FILE = '/usr/lib/systemd/system'
|
||||
|
||||
|
||||
ROUGAIL_TMPL_TEMPLATE = f"""%def display(%%file, %%filename)
|
||||
%if %%filename.startswith('/etc/') or %%filename.startswith('/var/') or %%filename.startswith('/srv/')
|
||||
C %%filename %%file.mode %%file.owner %%file.group - /usr/local/lib%%filename
|
||||
C %%filename %%file.mode %%file.owner %%file.group - {ROUGAIL_DEST}%%filename
|
||||
z %%filename - - - - -
|
||||
%end if
|
||||
%end def
|
||||
|
@ -70,13 +74,14 @@ class RougailSystemdTemplate(RougailBaseTemplate):
|
|||
self.ip_per_service = None
|
||||
super().__init__(config, rougailconfig)
|
||||
|
||||
def _instance_files(self,
|
||||
filevar: Dict,
|
||||
destfile: str,
|
||||
service_name: str,
|
||||
variable,
|
||||
idx: int,
|
||||
) -> tuple:
|
||||
def get_data_files(self,
|
||||
filevar: Dict,
|
||||
destfile: str,
|
||||
service_name: str,
|
||||
service_type: str,
|
||||
variable,
|
||||
idx: int,
|
||||
) -> tuple:
|
||||
source = filevar['source']
|
||||
if not isfile(source): # pragma: no cover
|
||||
raise FileNotFound(_(f"File {source} does not exist."))
|
||||
|
@ -88,27 +93,30 @@ class RougailSystemdTemplate(RougailBaseTemplate):
|
|||
var = None
|
||||
return tmp_file, None, destfile, var
|
||||
|
||||
def _instance_overrides(self,
|
||||
filevar: Dict,
|
||||
destfile,
|
||||
service_name: str,
|
||||
*args,
|
||||
) -> tuple:
|
||||
def get_data_overrides(self,
|
||||
filevar: Dict,
|
||||
destfile,
|
||||
service_name: str,
|
||||
service_type: str,
|
||||
*args,
|
||||
) -> tuple:
|
||||
source = filevar['source']
|
||||
if not isfile(source): # pragma: no cover
|
||||
raise FileNotFound(_(f"File {source} does not exist."))
|
||||
tmp_file = join(self.tmp_dir, source)
|
||||
service_name = filevar['name']
|
||||
return tmp_file, None, f'/systemd/system/{service_name}.service.d/rougail.conf', None
|
||||
destfile = f'/systemd/system/{service_name}.{service_type}.d/rougail.conf'
|
||||
return tmp_file, None, destfile, None
|
||||
|
||||
def _instance_ip(self,
|
||||
filevar: Dict,
|
||||
ip,
|
||||
service_name: str,
|
||||
var: Any,
|
||||
idx: int,
|
||||
*args,
|
||||
) -> tuple:
|
||||
def get_data_ip(self,
|
||||
filevar: Dict,
|
||||
ip,
|
||||
service_name: str,
|
||||
service_type: str,
|
||||
var: Any,
|
||||
idx: int,
|
||||
*args,
|
||||
) -> tuple:
|
||||
if self.ip_per_service is None:
|
||||
self.ip_per_service = []
|
||||
if 'netmask' in filevar:
|
||||
|
@ -120,19 +128,49 @@ class RougailSystemdTemplate(RougailBaseTemplate):
|
|||
elif ip:
|
||||
self.ip_per_service.append(ip)
|
||||
|
||||
def get_data_service(self,
|
||||
servicevar: Dict,
|
||||
info,
|
||||
service_name: str,
|
||||
service_type: str,
|
||||
*args,
|
||||
):
|
||||
filename = f'{service_name}.{service_type}'
|
||||
tmp_file = join(self.tmp_dir, filename)
|
||||
var = None
|
||||
destfile = f'/systemd/system/{filename}'
|
||||
return tmp_file, None, destfile, var
|
||||
|
||||
|
||||
def desactive_service(self,
|
||||
service_name: str,
|
||||
service_type: str,
|
||||
):
|
||||
filename = f'{self.destinations_dir}/systemd/system/{service_name}.service'
|
||||
filename = f'{self.destinations_dir}/systemd/system/{service_name}.{service_type}'
|
||||
makedirs(dirname(filename), exist_ok=True)
|
||||
symlink('/dev/null', filename)
|
||||
|
||||
def target_service(self,
|
||||
service_name: str,
|
||||
target_name: str,
|
||||
service_type: str,
|
||||
global_service: str,
|
||||
):
|
||||
filename = f'{self.destinations_dir}/systemd/system/{target_name}.target.wants/{service_name}.{service_type}'
|
||||
makedirs(dirname(filename), exist_ok=True)
|
||||
if global_service:
|
||||
source_filename = f'{ROUGAIL_GLOBAL_SYSTEMD_FILE}/{service_name}.{service_type}'
|
||||
else:
|
||||
source_filename = f'{ROUGAIL_DEST}/systemd/system/{service_name}.{service_type}'
|
||||
symlink(source_filename, filename)
|
||||
|
||||
def post_instance_service(self,
|
||||
service_name: str,
|
||||
service_type: str,
|
||||
) -> None: # pragma: no cover
|
||||
if self.ip_per_service is None:
|
||||
return
|
||||
destfile = f'/systemd/system/{service_name}.service.d/rougail_ip.conf'
|
||||
destfile = f'/systemd/system/{service_name}.{service_type}.d/rougail_ip.conf'
|
||||
destfilename = join(self.destinations_dir, destfile[1:])
|
||||
makedirs(dirname(destfilename), exist_ok=True)
|
||||
self.log.info(_(f"creole processing: '{destfilename}'"))
|
||||
|
|
|
@ -144,6 +144,63 @@ class RougailUpgrade:
|
|||
value.text = choices[0]
|
||||
variable.attrib['mandatory'] = 'True'
|
||||
|
||||
# convert group to leadership
|
||||
groups = []
|
||||
if constraints is not None:
|
||||
for constraint in constraints:
|
||||
if constraint.tag == 'group':
|
||||
constraints.remove(constraint)
|
||||
groups.append(constraint)
|
||||
for group in groups:
|
||||
if group.attrib['leader'] in paths:
|
||||
leader_obj = paths[group.attrib['leader']]
|
||||
#FIXME name peut avoir "." il faut le virer
|
||||
#FIXME si extra c'est un follower !
|
||||
if 'name' in group.attrib:
|
||||
grpname = group.attrib['name']
|
||||
if 'description' in group.attrib:
|
||||
description = group.attrib['description']
|
||||
else:
|
||||
description = grpname
|
||||
else:
|
||||
grpname = leader_obj['variable'].attrib['name']
|
||||
if '.' in grpname:
|
||||
grpname = grpname.rsplit('.', 1)[-1]
|
||||
if 'description' in group.attrib:
|
||||
description = group.attrib['description']
|
||||
elif 'description' in leader_obj['variable'].attrib:
|
||||
description = leader_obj['variable'].attrib['description']
|
||||
else:
|
||||
description = grpname
|
||||
family = SubElement(leader_obj['parent'], 'family', name=grpname, description=description, leadership="True")
|
||||
leader_obj['parent'].remove(leader_obj['variable'])
|
||||
family.append(leader_obj['variable'])
|
||||
else:
|
||||
# append in group
|
||||
follower = next(iter(group))
|
||||
leader_name = group.attrib['leader']
|
||||
if '.' in leader_name:
|
||||
leader_path = leader_name.rsplit('.', 1)[0]
|
||||
follower_path = leader_path + '.' + follower.text
|
||||
else:
|
||||
follower_path = follower.text
|
||||
obj = paths[follower_path]
|
||||
family = SubElement(obj['parent'], 'family', name=leader_name, leadership="True")
|
||||
grpname = leader_name
|
||||
for follower in group:
|
||||
leader_name = group.attrib['leader']
|
||||
if '.' in leader_name:
|
||||
leader_path = leader_name.rsplit('.', 1)[0]
|
||||
follower_path = leader_path + '.' + follower.text
|
||||
else:
|
||||
follower_path = follower.text
|
||||
follower_obj = paths[follower_path]
|
||||
follower_obj['parent'].remove(follower_obj['variable'])
|
||||
family.append(follower_obj['variable'])
|
||||
if '.' in follower_path:
|
||||
new_path = follower_path.rsplit('.', 1)[0] + '.' + grpname + '.' + follower_path.rsplit('.', 1)[1]
|
||||
paths[new_path] = paths[follower_path]
|
||||
|
||||
# convert choice option
|
||||
valid_enums = []
|
||||
if constraints is not None:
|
||||
|
@ -207,58 +264,6 @@ class RougailUpgrade:
|
|||
for target in targets:
|
||||
if 'remove_choice' not in target.attrib or target.attrib['remove_choice'] != 'True':
|
||||
target.attrib['type'] = 'choice'
|
||||
# convert group to leadership
|
||||
groups = []
|
||||
if constraints is not None:
|
||||
for constraint in constraints:
|
||||
if constraint.tag == 'group':
|
||||
constraints.remove(constraint)
|
||||
groups.append(constraint)
|
||||
for group in groups:
|
||||
if group.attrib['leader'] in paths:
|
||||
leader_obj = paths[group.attrib['leader']]
|
||||
#FIXME name peut avoir "." il faut le virer
|
||||
#FIXME si extra c'est un follower !
|
||||
if 'name' in group.attrib:
|
||||
name = group.attrib['name']
|
||||
if 'description' in group.attrib:
|
||||
description = group.attrib['description']
|
||||
else:
|
||||
description = name
|
||||
else:
|
||||
name = leader_obj['variable'].attrib['name']
|
||||
if '.' in name:
|
||||
name = name.rsplit('.', 1)[-1]
|
||||
if 'description' in group.attrib:
|
||||
description = group.attrib['description']
|
||||
elif 'description' in leader_obj['variable'].attrib:
|
||||
description = leader_obj['variable'].attrib['description']
|
||||
else:
|
||||
description = name
|
||||
family = SubElement(leader_obj['parent'], 'family', name=name, description=description, leadership="True")
|
||||
leader_obj['parent'].remove(leader_obj['variable'])
|
||||
family.append(leader_obj['variable'])
|
||||
else:
|
||||
# append in group
|
||||
follower = next(iter(group))
|
||||
leader_name = group.attrib['leader']
|
||||
if '.' in leader_name:
|
||||
leader_path = leader_name.rsplit('.', 1)[0]
|
||||
follower_path = leader_path + '.' + follower.text
|
||||
else:
|
||||
follower_path = follower.text
|
||||
obj = paths[follower_path]
|
||||
family = SubElement(obj['parent'], 'family', name=leader_name, leadership="True")
|
||||
for follower in group:
|
||||
leader_name = group.attrib['leader']
|
||||
if '.' in leader_name:
|
||||
leader_path = leader_name.rsplit('.', 1)[0]
|
||||
follower_path = leader_path + '.' + follower.text
|
||||
else:
|
||||
follower_path = follower.text
|
||||
follower_obj = paths[follower_path]
|
||||
follower_obj['parent'].remove(follower_obj['variable'])
|
||||
family.append(follower_obj['variable'])
|
||||
return root
|
||||
|
||||
def _get_path_variables(self, variables, is_variable_namespace, path, dico=None):
|
||||
|
|
14
tests/dictionaries/70service_engine/00-base.xml
Normal file
14
tests/dictionaries/70service_engine/00-base.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<rougail version="0.10">
|
||||
<services>
|
||||
<service name="testsrv" engine="creole">
|
||||
</service>
|
||||
</services>
|
||||
<variables>
|
||||
<family name="general" description="général">
|
||||
<variable name="mode_conteneur_actif" type="string" description="No change" hidden="True">
|
||||
<value>oui</value>
|
||||
</variable>
|
||||
</family>
|
||||
</variables>
|
||||
</rougail>
|
0
tests/dictionaries/70service_engine/__init__.py
Normal file
0
tests/dictionaries/70service_engine/__init__.py
Normal file
14
tests/dictionaries/70service_engine/makedict/after.json
Normal file
14
tests/dictionaries/70service_engine/makedict/after.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"rougail.general.mode_conteneur_actif": {
|
||||
"owner": "default",
|
||||
"value": "oui"
|
||||
},
|
||||
"services.testsrv.activate": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
},
|
||||
"services.testsrv.manage": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
}
|
||||
}
|
5
tests/dictionaries/70service_engine/makedict/base.json
Normal file
5
tests/dictionaries/70service_engine/makedict/base.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"rougail.general.mode_conteneur_actif": "oui",
|
||||
"services.testsrv.activate": true,
|
||||
"services.testsrv.manage": true
|
||||
}
|
14
tests/dictionaries/70service_engine/makedict/before.json
Normal file
14
tests/dictionaries/70service_engine/makedict/before.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"rougail.general.mode_conteneur_actif": {
|
||||
"owner": "default",
|
||||
"value": "oui"
|
||||
},
|
||||
"services.testsrv.activate": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
},
|
||||
"services.testsrv.manage": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
oui
|
22
tests/dictionaries/70service_engine/tiramisu/base.py
Normal file
22
tests/dictionaries/70service_engine/tiramisu/base.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
from importlib.machinery import SourceFileLoader
|
||||
from importlib.util import spec_from_loader, module_from_spec
|
||||
loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py')
|
||||
spec = spec_from_loader(loader.name, loader)
|
||||
func = module_from_spec(spec)
|
||||
loader.exec_module(func)
|
||||
for key, value in dict(locals()).items():
|
||||
if key != ['SourceFileLoader', 'func']:
|
||||
setattr(func, key, value)
|
||||
try:
|
||||
from tiramisu3 import *
|
||||
except:
|
||||
from tiramisu import *
|
||||
option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="oui", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"}))
|
||||
option_2 = OptionDescription(name="general", doc="général", children=[option_3], properties=frozenset({"normal"}))
|
||||
option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2])
|
||||
option_6 = BoolOption(name="activate", doc="activate", default=True)
|
||||
option_7 = BoolOption(name="manage", doc="manage", default=True)
|
||||
option_5 = OptionDescription(name="testsrv", doc="testsrv", children=[option_6, option_7])
|
||||
option_5.impl_set_information('engine', "creole")
|
||||
option_4 = OptionDescription(name="services", doc="services", children=[option_5], properties=frozenset({"hidden"}))
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_4])
|
1
tests/dictionaries/70service_engine/tmpl/testsrv.service
Normal file
1
tests/dictionaries/70service_engine/tmpl/testsrv.service
Normal file
|
@ -0,0 +1 @@
|
|||
%%mode_conteneur_actif
|
13
tests/dictionaries/70service_mount/00-base.xml
Normal file
13
tests/dictionaries/70service_mount/00-base.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<rougail version="0.10">
|
||||
<services>
|
||||
<service name="testsrv" type="mount" engine="creole"/>
|
||||
</services>
|
||||
<variables>
|
||||
<family name="general" description="général">
|
||||
<variable name="mode_conteneur_actif" type="string" description="No change" hidden="True">
|
||||
<value>oui</value>
|
||||
</variable>
|
||||
</family>
|
||||
</variables>
|
||||
</rougail>
|
0
tests/dictionaries/70service_mount/__init__.py
Normal file
0
tests/dictionaries/70service_mount/__init__.py
Normal file
14
tests/dictionaries/70service_mount/makedict/after.json
Normal file
14
tests/dictionaries/70service_mount/makedict/after.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"rougail.general.mode_conteneur_actif": {
|
||||
"owner": "default",
|
||||
"value": "oui"
|
||||
},
|
||||
"services.testsrv.activate": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
},
|
||||
"services.testsrv.manage": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
}
|
||||
}
|
5
tests/dictionaries/70service_mount/makedict/base.json
Normal file
5
tests/dictionaries/70service_mount/makedict/base.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"rougail.general.mode_conteneur_actif": "oui",
|
||||
"services.testsrv.activate": true,
|
||||
"services.testsrv.manage": true
|
||||
}
|
14
tests/dictionaries/70service_mount/makedict/before.json
Normal file
14
tests/dictionaries/70service_mount/makedict/before.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"rougail.general.mode_conteneur_actif": {
|
||||
"owner": "default",
|
||||
"value": "oui"
|
||||
},
|
||||
"services.testsrv.activate": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
},
|
||||
"services.testsrv.manage": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
oui
|
23
tests/dictionaries/70service_mount/tiramisu/base.py
Normal file
23
tests/dictionaries/70service_mount/tiramisu/base.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
from importlib.machinery import SourceFileLoader
|
||||
from importlib.util import spec_from_loader, module_from_spec
|
||||
loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py')
|
||||
spec = spec_from_loader(loader.name, loader)
|
||||
func = module_from_spec(spec)
|
||||
loader.exec_module(func)
|
||||
for key, value in dict(locals()).items():
|
||||
if key != ['SourceFileLoader', 'func']:
|
||||
setattr(func, key, value)
|
||||
try:
|
||||
from tiramisu3 import *
|
||||
except:
|
||||
from tiramisu import *
|
||||
option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="oui", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"}))
|
||||
option_2 = OptionDescription(name="general", doc="général", children=[option_3], properties=frozenset({"normal"}))
|
||||
option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2])
|
||||
option_6 = BoolOption(name="activate", doc="activate", default=True)
|
||||
option_7 = BoolOption(name="manage", doc="manage", default=True)
|
||||
option_5 = OptionDescription(name="testsrv", doc="testsrv", children=[option_6, option_7])
|
||||
option_5.impl_set_information('type', "mount")
|
||||
option_5.impl_set_information('engine', "creole")
|
||||
option_4 = OptionDescription(name="services", doc="services", children=[option_5], properties=frozenset({"hidden"}))
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_4])
|
1
tests/dictionaries/70service_mount/tmpl/testsrv.mount
Normal file
1
tests/dictionaries/70service_mount/tmpl/testsrv.mount
Normal file
|
@ -0,0 +1 @@
|
|||
%%mode_conteneur_actif
|
13
tests/dictionaries/70service_target/00-base.xml
Normal file
13
tests/dictionaries/70service_target/00-base.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<rougail version="0.10">
|
||||
<services>
|
||||
<service name="testsrv" target="test"/>
|
||||
</services>
|
||||
<variables>
|
||||
<family name="general" description="général">
|
||||
<variable name="mode_conteneur_actif" type="string" description="No change" hidden="True">
|
||||
<value>oui</value>
|
||||
</variable>
|
||||
</family>
|
||||
</variables>
|
||||
</rougail>
|
0
tests/dictionaries/70service_target/__init__.py
Normal file
0
tests/dictionaries/70service_target/__init__.py
Normal file
14
tests/dictionaries/70service_target/makedict/after.json
Normal file
14
tests/dictionaries/70service_target/makedict/after.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"rougail.general.mode_conteneur_actif": {
|
||||
"owner": "default",
|
||||
"value": "oui"
|
||||
},
|
||||
"services.testsrv.activate": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
},
|
||||
"services.testsrv.manage": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
}
|
||||
}
|
5
tests/dictionaries/70service_target/makedict/base.json
Normal file
5
tests/dictionaries/70service_target/makedict/base.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"rougail.general.mode_conteneur_actif": "oui",
|
||||
"services.testsrv.activate": true,
|
||||
"services.testsrv.manage": true
|
||||
}
|
14
tests/dictionaries/70service_target/makedict/before.json
Normal file
14
tests/dictionaries/70service_target/makedict/before.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"rougail.general.mode_conteneur_actif": {
|
||||
"owner": "default",
|
||||
"value": "oui"
|
||||
},
|
||||
"services.testsrv.activate": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
},
|
||||
"services.testsrv.manage": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
/usr/lib/systemd/system/testsrv.service
|
22
tests/dictionaries/70service_target/tiramisu/base.py
Normal file
22
tests/dictionaries/70service_target/tiramisu/base.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
from importlib.machinery import SourceFileLoader
|
||||
from importlib.util import spec_from_loader, module_from_spec
|
||||
loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py')
|
||||
spec = spec_from_loader(loader.name, loader)
|
||||
func = module_from_spec(spec)
|
||||
loader.exec_module(func)
|
||||
for key, value in dict(locals()).items():
|
||||
if key != ['SourceFileLoader', 'func']:
|
||||
setattr(func, key, value)
|
||||
try:
|
||||
from tiramisu3 import *
|
||||
except:
|
||||
from tiramisu import *
|
||||
option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="oui", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"}))
|
||||
option_2 = OptionDescription(name="general", doc="général", children=[option_3], properties=frozenset({"normal"}))
|
||||
option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2])
|
||||
option_6 = BoolOption(name="activate", doc="activate", default=True)
|
||||
option_7 = BoolOption(name="manage", doc="manage", default=True)
|
||||
option_5 = OptionDescription(name="testsrv", doc="testsrv", children=[option_6, option_7])
|
||||
option_5.impl_set_information('target', "test")
|
||||
option_4 = OptionDescription(name="services", doc="services", children=[option_5], properties=frozenset({"hidden"}))
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_4])
|
13
tests/dictionaries/70service_target_engine/00-base.xml
Normal file
13
tests/dictionaries/70service_target_engine/00-base.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<rougail version="0.10">
|
||||
<services>
|
||||
<service name="testsrv" target="test" engine="none"/>
|
||||
</services>
|
||||
<variables>
|
||||
<family name="general" description="général">
|
||||
<variable name="mode_conteneur_actif" type="string" description="No change" hidden="True">
|
||||
<value>oui</value>
|
||||
</variable>
|
||||
</family>
|
||||
</variables>
|
||||
</rougail>
|
0
tests/dictionaries/70service_target_engine/__init__.py
Normal file
0
tests/dictionaries/70service_target_engine/__init__.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"rougail.general.mode_conteneur_actif": {
|
||||
"owner": "default",
|
||||
"value": "oui"
|
||||
},
|
||||
"services.testsrv.activate": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
},
|
||||
"services.testsrv.manage": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"rougail.general.mode_conteneur_actif": "oui",
|
||||
"services.testsrv.activate": true,
|
||||
"services.testsrv.manage": true
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"rougail.general.mode_conteneur_actif": {
|
||||
"owner": "default",
|
||||
"value": "oui"
|
||||
},
|
||||
"services.testsrv.activate": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
},
|
||||
"services.testsrv.manage": {
|
||||
"owner": "default",
|
||||
"value": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
/usr/local/lib/systemd/system/testsrv.service
|
|
@ -0,0 +1 @@
|
|||
%%mode_conteneur_actif
|
23
tests/dictionaries/70service_target_engine/tiramisu/base.py
Normal file
23
tests/dictionaries/70service_target_engine/tiramisu/base.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
from importlib.machinery import SourceFileLoader
|
||||
from importlib.util import spec_from_loader, module_from_spec
|
||||
loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py')
|
||||
spec = spec_from_loader(loader.name, loader)
|
||||
func = module_from_spec(spec)
|
||||
loader.exec_module(func)
|
||||
for key, value in dict(locals()).items():
|
||||
if key != ['SourceFileLoader', 'func']:
|
||||
setattr(func, key, value)
|
||||
try:
|
||||
from tiramisu3 import *
|
||||
except:
|
||||
from tiramisu import *
|
||||
option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="oui", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"}))
|
||||
option_2 = OptionDescription(name="general", doc="général", children=[option_3], properties=frozenset({"normal"}))
|
||||
option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2])
|
||||
option_6 = BoolOption(name="activate", doc="activate", default=True)
|
||||
option_7 = BoolOption(name="manage", doc="manage", default=True)
|
||||
option_5 = OptionDescription(name="testsrv", doc="testsrv", children=[option_6, option_7])
|
||||
option_5.impl_set_information('target', "test")
|
||||
option_5.impl_set_information('engine', "none")
|
||||
option_4 = OptionDescription(name="services", doc="services", children=[option_5], properties=frozenset({"hidden"}))
|
||||
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1, option_4])
|
|
@ -0,0 +1 @@
|
|||
%%mode_conteneur_actif
|
6
tests/dictionaries/80wrong_service_name/00-base.xml
Normal file
6
tests/dictionaries/80wrong_service_name/00-base.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<rougail version="0.10">
|
||||
<services>
|
||||
<service name="testsrv.mount"/>
|
||||
</services>
|
||||
</rougail>
|
0
tests/dictionaries/80wrong_service_name/__init__.py
Normal file
0
tests/dictionaries/80wrong_service_name/__init__.py
Normal file
0
tests/dictionaries/80wrong_service_name/errno_76
Normal file
0
tests/dictionaries/80wrong_service_name/errno_76
Normal file
|
@ -1,4 +1,4 @@
|
|||
from os import listdir, mkdir
|
||||
from os import listdir, mkdir, readlink
|
||||
from os.path import join, isdir, isfile, islink
|
||||
from shutil import rmtree
|
||||
from pytest import fixture, mark
|
||||
|
@ -82,7 +82,9 @@ async def test_dictionary(test_dir):
|
|||
assert list_templates == list_results
|
||||
for result in list_results:
|
||||
template_file = join(dest_dir, result)
|
||||
if islink(template_file) and islink(join(test_dir, 'result', result)):
|
||||
assert islink(template_file) == islink(join(test_dir, 'result', result))
|
||||
if islink(template_file):
|
||||
assert readlink(template_file) == readlink(join(test_dir, 'result', result))
|
||||
continue
|
||||
if not isfile(template_file):
|
||||
raise Exception(f'{template_file} is not generated')
|
||||
|
|
Loading…
Reference in a new issue