service: Template file improvements

This commit is contained in:
uumas
2026-09-21 05:50:50 +03:00
parent e980ee0bfc
commit bb9026bb6a
5 changed files with 126 additions and 106 deletions

View File

@@ -163,9 +163,7 @@ argument_specs:
- Mount source. - Mount source.
- If mount type is volume, name of the volume. - If mount type is volume, name of the volume.
- If mount type is bind, host path to bind mount inside the container. - If mount type is bind, host path to bind mount inside the container.
- >- - If mount type is template, the name of the template file, must end in .j2.
If mount type is template and template_directory is false, the name of the template file, must end in .j2.
If template_directory is true, this is the destination directory
- If mount type is copy, name of the file or directory to copy. Directory name must end in /. - If mount type is copy, name of the file or directory to copy. Directory name must end in /.
type: str type: str
required: true required: true
@@ -337,6 +335,7 @@ argument_specs:
host <service database type> on the default port. host <service database type> on the default port.
- The database user will be <service name> - The database user will be <service name>
- The password will be accessible as secret at /run/secrets/<service database type> - The password will be accessible as secret at /run/secrets/<service database type>
- A postgres url is accessible as secret at /run/secrets/postgres-url
- > - >
The password will also be available as the The password will also be available as the
service_podman_secrets['<service name>-<service database type>'] variable. service_podman_secrets['<service name>-<service database type>'] variable.

View File

@@ -13,28 +13,29 @@
- name: Create service template mount directories - name: Create service template mount directories
ansible.builtin.file: ansible.builtin.file:
path: "{{ _service_host_directory }}/mounts/{{ item }}" path: "{{ item }}"
state: directory state: directory
mode: "0700" mode: "0700"
loop: "{{ _service_all_template_mount_directories }}" loop: "{{ _service_all_template_mount_host_files | map('dirname') | unique }}"
- name: Template files for template mounts - name: Template files for template mounts
ansible.builtin.template: ansible.builtin.template:
src: "{{ item[0].source }}" src: "{{ item.source }}"
dest: "{{ item[1] }}" dest: "{{ item.hostfile }}"
mode: "{{ item[0].mode | default('0644') }}" mode: "{{ item.mode | default('0644') }}"
validate: "{{ validate if item[0].template_validate_command is defined else omit }}" validate: "{{ validate if item.template_validate_command is defined else omit }}"
notify: >- notify: >-
{{ 'Reload' if service_container_reload_method != 'none' else 'Restart' }} {{ 'Reload' if service_container_reload_method != 'none' else 'Restart' }}
container service {{ service_name }} container service {{ service_name }}
loop: "{{ _service_all_template_mounts | zip(_service_all_template_mount_host_files) }}" loop: "{{ _service_all_template_mounts_full }}"
vars: vars:
validate: >- validate: "{{ _service_template_validate_command }}"
podman run --rm
-v %s:{{ item[0].destination }}:ro - name: Ensure no legacy templated files present
--entrypoint {{ item[0].template_validate_command.split(' ', 1)[0] }} ansible.builtin.file:
{{ service_container_image }} path: "{{ _service_host_directory }}/mounts/{{ item.source | regex_replace('\\.j2$', '') }}"
{{ item[0].template_validate_command.split(' ', 1)[1] }} state: absent
loop: "{{ _service_all_template_mounts_full }}"
- name: Copy files for copy mounts - name: Copy files for copy mounts
ansible.builtin.copy: ansible.builtin.copy:

View File

@@ -26,39 +26,54 @@ _service_container_bind_mounts: >-
([ _service_container_socket_mount ] if _service_native_socket else []) ([ _service_container_socket_mount ] if _service_native_socket else [])
}} }}
_service_template_mounts_withdefaults: >- _service_template_mounts_hostfiles: >-
{{
_service_template_mounts
| map(attribute='destination')
| map('dirname')
| map('replace', '/', '_')
| map('regex_replace', '^', _service_host_directory ~ '/mounts/')
| zip(
_service_template_mounts
| map(attribute='destination')
| map('basename')
)
| map('path_join')
| map('community.general.dict_kv', 'hostfile')
}}
_service_template_mounts_full: >-
{{ {{
([{'readonly': true, 'template_directory': false}] * _service_template_mounts | length) ([{'readonly': true, 'template_directory': false}] * _service_template_mounts | length)
| zip(_service_template_mounts) | zip(
_service_template_mounts,
_service_template_mounts_hostfiles
)
| map('combine') | map('combine')
}} }}
_service_template_mounts_plain: "{{ _service_template_mounts_withdefaults | rejectattr('template_directory') }}" _service_template_mounts_plain: "{{ _service_template_mounts_full | rejectattr('template_directory') }}"
_service_container_template_mounts_plain: >- _service_container_template_mounts_plain: >-
{{ {{
_service_template_mounts_plain _service_template_mounts_plain
| community.general.remove_keys(['mode', 'template_validate_command', 'template_directory']) | community.general.remove_keys(['mode', 'template_validate_command', 'template_directory', 'hostfile'])
| zip( | zip(
_service_template_mounts_plain _service_template_mounts_plain
| map(attribute='source') | map(attribute='hostfile')
| map('regex_replace', '\.j2$', '')
| map('regex_replace', '^', _service_host_directory ~ '/mounts/')
| map('community.general.dict_kv', 'source'), | map('community.general.dict_kv', 'source'),
([{'type': 'bind'}] * _service_template_mounts | length) ([{'type': 'bind'}] * _service_template_mounts_plain | length)
) | ) |
map('combine') map('combine')
}} }}
_service_template_mounts_directory: "{{ _service_template_mounts_withdefaults | selectattr('template_directory') }}" _service_template_mounts_directory: "{{ _service_template_mounts_full | selectattr('template_directory') }}"
_service_container_template_mounts_directory: >- _service_container_template_mounts_directory: >-
{{ {{
_service_template_mounts_directory _service_template_mounts_directory
| community.general.remove_keys(['mode', 'template_validate_command', 'template_directory']) | community.general.remove_keys(['mode', 'template_validate_command', 'template_directory', 'hostfile'])
| zip( | zip(
_service_template_mounts_directory _service_template_mounts_directory
| map(attribute='destination') | map(attribute='hostfile')
| map('replace', '/', '_') | map('dirname')
| map('regex_replace', '^', _service_host_directory ~ '/mounts/')
| map('community.general.dict_kv', 'source'), | map('community.general.dict_kv', 'source'),
([{'type': 'bind'}] * _service_template_mounts | length) ([{'type': 'bind'}] * _service_template_mounts_directory | length)
) )
| map('combine') | map('combine')
| unique | unique
@@ -93,57 +108,38 @@ _service_container_mounts: >-
_service_all_template_mounts: >- _service_all_template_mounts: >-
{{ {{
( (
_service_template_mounts + _service_template_mounts
( + (
_service_additional_containers | _service_additional_containers
map(attribute='mounts', default=[]) | | map(attribute='mounts', default=[])
flatten | flatten
) )
) | )
selectattr('type', '==', 'template') | | selectattr('type', '==', 'template')
unique
}}
_service_all_template_mounts_withdefaults: >-
{{
([{'readonly': true, 'template_directory': false}] * _service_all_template_mounts | length)
| zip(_service_all_template_mounts)
| map('combine')
}}
_service_all_template_mounts_plain: "{{ _service_all_template_mounts_withdefaults | rejectattr('template_directory') }}"
_service_all_template_mounts_directory: "{{ _service_all_template_mounts_withdefaults | selectattr('template_directory') }}"
_service_all_template_mount_directories: >-
{{
(
_service_all_template_mounts_plain
| map(attribute='source')
| map('dirname')
| unique | unique
| select('!=', '')
) + (
_service_all_template_mounts_directory
| map(attribute='destination')
| map('replace', '/', '_')
)
}} }}
_service_all_template_mount_host_files: >- _service_all_template_mount_host_files: >-
{{ {{
( _service_all_template_mounts
_service_all_template_mounts_plain
| map(attribute='source')
| map('regex_replace', '\.j2$', '')
| map('regex_replace', '^', _service_host_directory ~ '/mounts/')
) + (
_service_all_template_mounts_directory
| map(attribute='destination') | map(attribute='destination')
| map('dirname')
| map('replace', '/', '_') | map('replace', '/', '_')
| map('regex_replace', '^', _service_host_directory ~ '/mounts/') | map('regex_replace', '^', _service_host_directory ~ '/mounts/')
| zip( | zip(
_service_all_template_mounts_directory _service_all_template_mounts
| map(attribute='source') | map(attribute='destination')
| map('regex_replace', '\.j2$', '') | map('basename')
) | map('path_join')
) )
| map('path_join')
}}
_service_all_template_mounts_full: >-
{{
([{'readonly': true, 'template_directory': false}] * _service_all_template_mounts | length)
| zip(
_service_all_template_mounts,
_service_all_template_mount_host_files | map('community.general.dict_kv', 'hostfile')
)
| map('combine')
}} }}
_service_all_copy_mounts: >- _service_all_copy_mounts: >-
@@ -161,7 +157,7 @@ _service_all_copy_mounts: >-
}} }}
_service_all_copy_mount_host_files: >- _service_all_copy_mount_host_files: >-
{{ {{
_service_all_copy_mounts | _service_all_copy_mounts
map(attribute='source') | | map(attribute='source')
map('regex_replace', '^', _service_host_directory ~ '/mounts/') | map('regex_replace', '^', _service_host_directory ~ '/mounts/')
}} }}

View File

@@ -0,0 +1,24 @@
---
_service_template_validate_secrets: >-
{{
_service_container_secrets
| map(attribute='name')
| zip(
_service_container_secrets
| community.general.remove_keys(['name', 'value', 'length'])
| map('items')
| map('map', 'join', '=')
| map('join', ',')
)
| map('join', ',')
| map('regex_replace', '^', '--secret ')
| join(' ')
}}
_service_template_validate_command: >-
podman run --rm
-v %s:{{ item.destination }}:ro
--entrypoint {{ item.template_validate_command.split(' ', 1)[0] }}
{{ _service_template_validate_secrets }}
{{ service_container_image }}
{{ item.template_validate_command.split(' ', 1)[1] }}