diff --git a/src/rougail/config.py b/src/rougail/config.py index b4c84a375..2c2524c46 100644 --- a/src/rougail/config.py +++ b/src/rougail/config.py @@ -52,6 +52,7 @@ RougailConfig = {'dictionaries_dir': [join(ROUGAILROOT, 'dictionaries')], 'systemd_tmpfile_factory_dir': '/usr/local/lib', 'systemd_tmpfile_directory': '/tmpfiles.d', 'systemd_tmpfile_file': '0rougail.conf', + 'systemd_tmpfile_delete_before_create': False, 'variable_namespace': 'rougail', 'variable_namespace_description': 'Rougail', 'auto_freeze_variable': 'server_deployed', diff --git a/src/rougail/template/systemd.py b/src/rougail/template/systemd.py index 4730bf4b9..8d7f9cd82 100644 --- a/src/rougail/template/systemd.py +++ b/src/rougail/template/systemd.py @@ -56,6 +56,9 @@ class RougailSystemdTemplate(RougailBaseTemplate): tmp_local_dir = (f"%%filename.startswith('{local_dir}')" for local_dir in LOCAL_DIR) self.rougail_tmpl_template += '%if ' + ' or '.join(tmp_local_dir) self.rougail_tmpl_template += f""" +%if {self.rougailconfig['systemd_tmpfile_delete_before_create']} +r %%filename +%end if C %%filename %%file.mode %%file.owner %%file.group - {self.rougailconfig['systemd_tmpfile_factory_dir']}%%filename %end if %end def diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/__init__.py b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/file_tmpfiles_delete_before_create b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/file_tmpfiles_delete_before_create new file mode 100644 index 000000000..e69de29bb diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/makedict/after.json b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/makedict/after.json new file mode 100644 index 000000000..c63a8561a --- /dev/null +++ b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/makedict/after.json @@ -0,0 +1,38 @@ +{ + "rougail.general.mode_conteneur_actif": { + "owner": "default", + "value": "non" + }, + "services.test_service.files.file.name": { + "owner": "default", + "value": "/etc/file" + }, + "services.test_service.files.file.source": { + "owner": "default", + "value": "file" + }, + "services.test_service.files.file.activate": { + "owner": "default", + "value": true + }, + "services.test_service.files.file2.name": { + "owner": "default", + "value": "/etc/file2" + }, + "services.test_service.files.file2.source": { + "owner": "default", + "value": "file2" + }, + "services.test_service.files.file2.activate": { + "owner": "default", + "value": true + }, + "services.test_service.activate": { + "owner": "default", + "value": true + }, + "services.test_service.manage": { + "owner": "default", + "value": true + } +} diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/makedict/base.json b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/makedict/base.json new file mode 100644 index 000000000..3524da356 --- /dev/null +++ b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/makedict/base.json @@ -0,0 +1,11 @@ +{ + "rougail.general.mode_conteneur_actif": "non", + "services.test_service.files.file.name": "/etc/file", + "services.test_service.files.file.source": "file", + "services.test_service.files.file.activate": true, + "services.test_service.files.file2.name": "/etc/file2", + "services.test_service.files.file2.source": "file2", + "services.test_service.files.file2.activate": true, + "services.test_service.activate": true, + "services.test_service.manage": true +} diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/makedict/before.json b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/makedict/before.json new file mode 100644 index 000000000..c63a8561a --- /dev/null +++ b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/makedict/before.json @@ -0,0 +1,38 @@ +{ + "rougail.general.mode_conteneur_actif": { + "owner": "default", + "value": "non" + }, + "services.test_service.files.file.name": { + "owner": "default", + "value": "/etc/file" + }, + "services.test_service.files.file.source": { + "owner": "default", + "value": "file" + }, + "services.test_service.files.file.activate": { + "owner": "default", + "value": true + }, + "services.test_service.files.file2.name": { + "owner": "default", + "value": "/etc/file2" + }, + "services.test_service.files.file2.source": { + "owner": "default", + "value": "file2" + }, + "services.test_service.files.file2.activate": { + "owner": "default", + "value": true + }, + "services.test_service.activate": { + "owner": "default", + "value": true + }, + "services.test_service.manage": { + "owner": "default", + "value": true + } +} diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/result/etc/file b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/result/etc/file new file mode 100644 index 000000000..4089fbcce --- /dev/null +++ b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/result/etc/file @@ -0,0 +1,2 @@ +non +non diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/result/etc/file2 b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/result/etc/file2 new file mode 100644 index 000000000..4089fbcce --- /dev/null +++ b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/result/etc/file2 @@ -0,0 +1,2 @@ +non +non diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/result/tmpfiles.d/0rougail.conf b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/result/tmpfiles.d/0rougail.conf new file mode 100644 index 000000000..c58c2d0c8 --- /dev/null +++ b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/result/tmpfiles.d/0rougail.conf @@ -0,0 +1,4 @@ +r /etc/file +C /etc/file 0644 root root - /usr/local/lib/etc/file +r /etc/file2 +C /etc/file2 0644 root root - /usr/local/lib/etc/file2 diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/tiramisu/base.py b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/tiramisu/base.py new file mode 100644 index 000000000..a3a4809df --- /dev/null +++ b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/tiramisu/base.py @@ -0,0 +1,39 @@ +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries/../eosfunc/test.py') +try: + from tiramisu3 import * +except: + from tiramisu import * +option_2 = StrOption(name="mode_conteneur_actif", doc="Description", default="non", properties=frozenset({"mandatory", "normal"})) +optiondescription_1 = OptionDescription(name="general", doc="general", children=[option_2], properties=frozenset({"normal"})) +optiondescription_14 = OptionDescription(name="rougail", doc="Rougail", children=[optiondescription_1]) +option_7 = FilenameOption(name="name", doc="name", default="/etc/file") +option_8 = StrOption(name="source", doc="source", default="file") +option_6 = BoolOption(name="activate", doc="activate", default=True) +optiondescription_5 = OptionDescription(name="file", doc="file", children=[option_7, option_8, option_6]) +option_11 = FilenameOption(name="name", doc="name", default="/etc/file2") +option_12 = StrOption(name="source", doc="source", default="file2") +option_10 = BoolOption(name="activate", doc="activate", default=True) +optiondescription_9 = OptionDescription(name="file2", doc="file2", children=[option_11, option_12, option_10]) +optiondescription_9.impl_set_information('engine', "jinja") +optiondescription_4 = OptionDescription(name="files", doc="files", children=[optiondescription_5, optiondescription_9]) +option_3 = BoolOption(name="activate", doc="activate", default=True) +option_13 = BoolOption(name="manage", doc="manage", default=True) +optiondescription_16 = OptionDescription(name="test_service", doc="test.service", children=[optiondescription_4, option_3, option_13]) +optiondescription_16.impl_set_information('type', "service") +optiondescription_15 = OptionDescription(name="services", doc="services", children=[optiondescription_16], properties=frozenset({"hidden"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_14, optiondescription_15]) diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/tiramisu/multi.py b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/tiramisu/multi.py new file mode 100644 index 000000000..38efb411c --- /dev/null +++ b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/tiramisu/multi.py @@ -0,0 +1,59 @@ +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries/../eosfunc/test.py') +try: + from tiramisu3 import * +except: + from tiramisu import * +option_2 = StrOption(name="mode_conteneur_actif", doc="Description", default="non", properties=frozenset({"mandatory", "normal"})) +optiondescription_1 = OptionDescription(name="general", doc="general", children=[option_2], properties=frozenset({"normal"})) +optiondescription_28 = OptionDescription(name="rougail", doc="Rougail", children=[optiondescription_1]) +option_9 = FilenameOption(name="name", doc="name", default="/etc/file") +option_10 = StrOption(name="source", doc="source", default="file") +option_8 = BoolOption(name="activate", doc="activate", default=True) +optiondescription_7 = OptionDescription(name="file", doc="file", children=[option_9, option_10, option_8]) +option_13 = FilenameOption(name="name", doc="name", default="/etc/file2") +option_14 = StrOption(name="source", doc="source", default="file2") +option_12 = BoolOption(name="activate", doc="activate", default=True) +optiondescription_11 = OptionDescription(name="file2", doc="file2", children=[option_13, option_14, option_12]) +optiondescription_11.impl_set_information('engine', "jinja") +optiondescription_6 = OptionDescription(name="files", doc="files", children=[optiondescription_7, optiondescription_11]) +option_5 = BoolOption(name="activate", doc="activate", default=True) +option_15 = BoolOption(name="manage", doc="manage", default=True) +optiondescription_30 = OptionDescription(name="test_service", doc="test.service", children=[optiondescription_6, option_5, option_15]) +optiondescription_30.impl_set_information('type', "service") +optiondescription_29 = OptionDescription(name="services", doc="services", children=[optiondescription_30], properties=frozenset({"hidden"})) +optiondescription_27 = OptionDescription(name="1", doc="1", children=[optiondescription_28, optiondescription_29]) +option_4 = StrOption(name="mode_conteneur_actif", doc="Description", default="non", properties=frozenset({"mandatory", "normal"})) +optiondescription_3 = OptionDescription(name="general", doc="general", children=[option_4], properties=frozenset({"normal"})) +optiondescription_32 = OptionDescription(name="rougail", doc="Rougail", children=[optiondescription_3]) +option_20 = FilenameOption(name="name", doc="name", default="/etc/file") +option_21 = StrOption(name="source", doc="source", default="file") +option_19 = BoolOption(name="activate", doc="activate", default=True) +optiondescription_18 = OptionDescription(name="file", doc="file", children=[option_20, option_21, option_19]) +option_24 = FilenameOption(name="name", doc="name", default="/etc/file2") +option_25 = StrOption(name="source", doc="source", default="file2") +option_23 = BoolOption(name="activate", doc="activate", default=True) +optiondescription_22 = OptionDescription(name="file2", doc="file2", children=[option_24, option_25, option_23]) +optiondescription_22.impl_set_information('engine', "jinja") +optiondescription_17 = OptionDescription(name="files", doc="files", children=[optiondescription_18, optiondescription_22]) +option_16 = BoolOption(name="activate", doc="activate", default=True) +option_26 = BoolOption(name="manage", doc="manage", default=True) +optiondescription_34 = OptionDescription(name="test_service", doc="test.service", children=[optiondescription_17, option_16, option_26]) +optiondescription_34.impl_set_information('type', "service") +optiondescription_33 = OptionDescription(name="services", doc="services", children=[optiondescription_34], properties=frozenset({"hidden"})) +optiondescription_31 = OptionDescription(name="2", doc="2", children=[optiondescription_32, optiondescription_33]) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_27, optiondescription_31]) diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/tmpl/file b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/tmpl/file new file mode 100644 index 000000000..27ff6834c --- /dev/null +++ b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/tmpl/file @@ -0,0 +1,2 @@ +%%mode_conteneur_actif +%%rougail.general.mode_conteneur_actif diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/tmpl/file2 b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/tmpl/file2 new file mode 100644 index 000000000..6d214113d --- /dev/null +++ b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/tmpl/file2 @@ -0,0 +1,2 @@ +{{ mode_conteneur_actif }} +{{ rougail.general.mode_conteneur_actif }} diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/xml/00-base.xml b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/xml/00-base.xml new file mode 100644 index 000000000..4f0a28e6c --- /dev/null +++ b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/xml/00-base.xml @@ -0,0 +1,16 @@ + + + + + /etc/file + /etc/file2 + + + + + + non + + + + diff --git a/tests/dictionaries/01base_file_tmpfiles_delete_before_create/yml/00-base.yml b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/yml/00-base.yml new file mode 100644 index 000000000..66a3404f9 --- /dev/null +++ b/tests/dictionaries/01base_file_tmpfiles_delete_before_create/yml/00-base.yml @@ -0,0 +1,18 @@ +version: '0.10' +services: +- service: + - name: test + file: + - text: /etc/file + - engine: jinja + text: /etc/file2 +variables: +- family: + - name: general + variables: + - variable: + - name: mode_conteneur_actif + type: string + description: Description + value: + - text: non diff --git a/tests/test_3_template.py b/tests/test_3_template.py index 3e860a38f..5941770f2 100644 --- a/tests/test_3_template.py +++ b/tests/test_3_template.py @@ -71,6 +71,10 @@ async def template(test_dir, filename, root, engine_name): RougailConfig['systemd_tmpfile_factory_dir'] = '/test/new/file' else: RougailConfig['systemd_tmpfile_factory_dir'] = '/usr/local/lib' + if isfile(join(test_dir, 'file_tmpfiles_delete_before_create')): + RougailConfig['systemd_tmpfile_delete_before_create'] = True + else: + RougailConfig['systemd_tmpfile_delete_before_create'] = False if engine_name == 'base': engine = RougailBaseTemplate(config) else: