diff --git a/roles/service/meta/argument_specs.yaml b/roles/service/meta/argument_specs.yaml index a3d0687..ab3d361 100644 --- a/roles/service/meta/argument_specs.yaml +++ b/roles/service/meta/argument_specs.yaml @@ -163,7 +163,9 @@ argument_specs: - Mount source. - 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 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 /. type: str required: true @@ -220,9 +222,18 @@ argument_specs: Command used to verify templated file validity. Will be run in a temporary container using the same container image as the main service. File will be available in the same place as in the service container (destination). - Only applicable if mount type is template + Only applicable if mount type is template. type: str required: false + template_directory: + description: >- + Whether to create a directory and mount it at the destination file's parent directory. + This is required for container to see templated file changes without restart. + Only applicable if mount type is template. + type: bool + required: false + default: false + service_container_devices: description: List of devices to be added inside the service main container. type: list diff --git a/roles/service/vars/main/mounts.yaml b/roles/service/vars/main/mounts.yaml index c87398b..c6fe041 100644 --- a/roles/service/vars/main/mounts.yaml +++ b/roles/service/vars/main/mounts.yaml @@ -25,21 +25,45 @@ _service_container_bind_mounts: >- service_container_mounts | selectattr('type', '==', 'bind') + ([ _service_container_socket_mount ] if _service_native_socket else []) }} -_service_container_template_mounts: >- + +_service_template_mounts_withdefaults: >- {{ - ([{'readonly': true}] * _service_template_mounts | length) | - zip( - _service_template_mounts | - community.general.remove_keys(['mode', 'template_validate_command']), - _service_template_mounts | - map(attribute='source') | - map('regex_replace', '\.j2$', '') | - map('regex_replace', '^', _service_host_directory ~ '/mounts/') | - map('community.general.dict_kv', 'source'), + ([{'readonly': true, 'template_directory': false}] * _service_template_mounts | length) + | zip(_service_template_mounts) + | map('combine') + }} +_service_template_mounts_plain: "{{ _service_template_mounts_withdefaults | rejectattr('template_directory') }}" +_service_container_template_mounts_plain: >- + {{ + _service_template_mounts_plain + | community.general.remove_keys(['mode', 'template_validate_command', 'template_directory']) + | zip( + _service_template_mounts_plain + | map(attribute='source') + | map('regex_replace', '\.j2$', '') + | map('regex_replace', '^', _service_host_directory ~ '/mounts/') + | map('community.general.dict_kv', 'source'), ([{'type': 'bind'}] * _service_template_mounts | length) ) | map('combine') }} +_service_template_mounts_directory: "{{ _service_template_mounts_withdefaults | selectattr('template_directory') }}" +_service_container_template_mounts_directory: >- + {{ + _service_template_mounts_directory + | community.general.remove_keys(['mode', 'template_validate_command', 'template_directory']) + | zip( + _service_template_mounts_directory + | map(attribute='destination') + | map('replace', '/', '_') + | map('regex_replace', '^', _service_host_directory ~ '/mounts/') + | map('community.general.dict_kv', 'source'), + ([{'type': 'bind'}] * _service_template_mounts | length) + ) + | map('combine') + | unique + }} + _service_container_copy_mounts: >- {{ ([{'readonly': true}] * _service_copy_mounts | length) | @@ -58,10 +82,11 @@ _service_container_copy_mounts: >- _service_container_mounts: >- {{ - _service_container_volume_mounts + - _service_container_bind_mounts + - _service_container_template_mounts + - _service_container_copy_mounts + _service_container_volume_mounts + + _service_container_bind_mounts + + _service_container_template_mounts_plain + + _service_container_template_mounts_directory + + _service_container_copy_mounts }} @@ -78,20 +103,47 @@ _service_all_template_mounts: >- 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 | - map(attribute='source') | - map('dirname') | - unique | - select('!=', '') + ( + _service_all_template_mounts_plain + | map(attribute='source') + | map('dirname') + | unique + | select('!=', '') + ) + ( + _service_all_template_mounts_directory + | map(attribute='destination') + | map('replace', '/', '_') + ) }} _service_all_template_mount_host_files: >- {{ - _service_all_template_mounts | - map(attribute='source') | - map('regex_replace', '\.j2$', '') | - map('regex_replace', '^', _service_host_directory ~ '/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('replace', '/', '_') + | map('regex_replace', '^', _service_host_directory ~ '/mounts/') + | zip( + _service_all_template_mounts_directory + | map(attribute='source') + | map('regex_replace', '\.j2$', '') + ) | map('path_join') + ) + }} _service_all_copy_mounts: >-