diff --git a/changelogs/fragments/476-docker_swarm_service_add_init_option.yml b/changelogs/fragments/476-docker_swarm_service_add_init_option.yml new file mode 100644 index 0000000000..44c7339bba --- /dev/null +++ b/changelogs/fragments/476-docker_swarm_service_add_init_option.yml @@ -0,0 +1,2 @@ +minor_changes: + - "docker_swarm_service - Added support for ``init`` option." diff --git a/plugins/modules/cloud/docker/docker_swarm_service.py b/plugins/modules/cloud/docker/docker_swarm_service.py index 59b4c0830a..4574bf1787 100644 --- a/plugins/modules/cloud/docker/docker_swarm_service.py +++ b/plugins/modules/cloud/docker/docker_swarm_service.py @@ -184,6 +184,12 @@ options: - Service image path and tag. - Corresponds to the C(IMAGE) parameter of C(docker service create). type: str + init: + description: + - Use an init inside each service container to forward signals and reap processes. + - Corresponds to the C(--init) option of C(docker service create). + - Requires API version >= 1.37. + type: bool labels: description: - Dictionary of key value pairs. @@ -1359,6 +1365,7 @@ class DockerService(DockerBaseClass): self.update_max_failure_ratio = None self.update_order = None self.working_dir = None + self.init = None self.docker_api_version = docker_api_version self.docker_py_version = docker_py_version @@ -1413,6 +1420,7 @@ class DockerService(DockerBaseClass): 'update_order': self.update_order, 'user': self.user, 'working_dir': self.working_dir, + 'init': self.init, } @property @@ -1652,6 +1660,7 @@ class DockerService(DockerBaseClass): s.user = ap['user'] s.working_dir = ap['working_dir'] s.read_only = ap['read_only'] + s.init = ap['init'] s.networks = get_docker_networks(ap['networks'], network_ids) @@ -1896,6 +1905,8 @@ class DockerService(DockerBaseClass): differences.add('working_dir', parameter=self.working_dir, active=os.working_dir) if self.force_update: force_update = True + if self.init is not None and self.init != os.init: + differences.add('init', parameter=self.init, active=os.init) return not differences.empty or force_update, differences, needs_rebuild, force_update def has_healthcheck_changed(self, old_publish): @@ -2056,6 +2067,8 @@ class DockerService(DockerBaseClass): container_spec_args['dns_config'] = dns_config if configs is not None: container_spec_args['configs'] = configs + if self.init is not None: + container_spec_args['init'] = self.init return types.ContainerSpec(self.image, **container_spec_args) @@ -2431,6 +2444,8 @@ class DockerServiceManager(object): ds.networks.append(network) ds.service_version = raw_data['Version']['Index'] ds.service_id = raw_data['ID'] + + ds.init = task_template_data['ContainerSpec'].get('Init', False) return ds def update_service(self, name, old_service, new_service): @@ -2835,6 +2850,7 @@ def main(): ), user=dict(type='str'), working_dir=dict(type='str'), + init=dict(type='bool'), ) option_minimal_versions = dict( @@ -2859,6 +2875,7 @@ def main(): read_only=dict(docker_py_version='2.6.0', docker_api_version='1.28'), resolve_image=dict(docker_api_version='1.30', docker_py_version='3.2.0'), rollback_config=dict(docker_py_version='3.5.0', docker_api_version='1.28'), + init=dict(docker_py_version='4.0.0', docker_api_version='1.37'), # specials publish_mode=dict( docker_py_version='3.0.0', diff --git a/tests/integration/targets/docker_swarm_service/tasks/tests/options.yml b/tests/integration/targets/docker_swarm_service/tasks/tests/options.yml index 1f805bacc3..020a74ae2e 100644 --- a/tests/integration/targets/docker_swarm_service/tasks/tests/options.yml +++ b/tests/integration/targets/docker_swarm_service/tasks/tests/options.yml @@ -1829,3 +1829,50 @@ - working_dir_1 is changed - working_dir_2 is not changed - working_dir_3 is changed + +#################################################################### +## init ############################################################ +#################################################################### + +- name: init + docker_swarm_service: + name: "{{ service_name }}" + image: alpine:3.8 + resolve_image: no + init: true + register: init_1 + +- name: init (idempotency) + docker_swarm_service: + name: "{{ service_name }}" + image: alpine:3.8 + resolve_image: no + init: true + register: init_2 + +- name: init (change) + docker_swarm_service: + name: "{{ service_name }}" + image: alpine:3.8 + resolve_image: no + init: false + register: init_3 + +- name: cleanup + docker_swarm_service: + name: "{{ service_name }}" + state: absent + diff: no + +- assert: + that: + - init_1 is changed + - init_2 is not changed + - init_3 is changed + when: docker_api_version is version('1.37', '>=') + +- assert: + that: + - init_1 is failed + - "('version is ' ~ docker_api_version ~'. Minimum version required is 1.37') in hosts_1.msg" + when: docker_api_version is version('1.37', '<') diff --git a/tests/integration/targets/docker_swarm_service/vars/main.yml b/tests/integration/targets/docker_swarm_service/vars/main.yml index 45bef6c4ff..1b1da299ba 100644 --- a/tests/integration/targets/docker_swarm_service/vars/main.yml +++ b/tests/integration/targets/docker_swarm_service/vars/main.yml @@ -51,3 +51,4 @@ service_expected_output: update_parallelism: null user: null working_dir: null + init: null