From f5faf8211d4d693b5f0795cdad2d0a318efe36f9 Mon Sep 17 00:00:00 2001 From: Hannes Ljungberg Date: Fri, 8 Mar 2019 09:34:49 +0100 Subject: [PATCH] docker_swarm_service: Add read_only option (#53482) * Add read_only option * Add changelog fragment * Add version_added * Fix broken test --- ...docker_swarm_service-read_only_option.yaml | 2 + .../cloud/docker/docker_swarm_service.py | 17 ++++++ .../tasks/tests/options.yml | 52 +++++++++++++++++++ .../docker_swarm_service/vars/main.yml | 1 + 4 files changed, 72 insertions(+) create mode 100644 changelogs/fragments/53482-docker_swarm_service-read_only_option.yaml diff --git a/changelogs/fragments/53482-docker_swarm_service-read_only_option.yaml b/changelogs/fragments/53482-docker_swarm_service-read_only_option.yaml new file mode 100644 index 00000000000..504953c293c --- /dev/null +++ b/changelogs/fragments/53482-docker_swarm_service-read_only_option.yaml @@ -0,0 +1,2 @@ +bugfixes: + - "docker_swarm_service - Added support for ``read_only`` parameter." diff --git a/lib/ansible/modules/cloud/docker/docker_swarm_service.py b/lib/ansible/modules/cloud/docker/docker_swarm_service.py index 7d63c4e913e..e7464d3feb9 100644 --- a/lib/ansible/modules/cloud/docker/docker_swarm_service.py +++ b/lib/ansible/modules/cloud/docker/docker_swarm_service.py @@ -470,6 +470,12 @@ options: choices: - ingress - host + read_only: + description: + - Mount the containers root filesystem as read only. + - Corresponds to the C(--read-only) option of C(docker service create). + type: bool + version_added: "2.8" replicas: description: - Number of containers instantiated in the service. Valid only if I(mode) is C(replicated). @@ -747,6 +753,7 @@ swarm_service: } ], "publish": null, + "read_only": null, "replicas": 1, "reserve_cpu": 0.25, "reserve_memory": 20971520, @@ -1055,6 +1062,7 @@ class DockerService(DockerBaseClass): self.replicas = -1 self.service_id = False self.service_version = False + self.read_only = None self.restart_policy = None self.restart_policy_attempts = None self.restart_policy_delay = None @@ -1103,6 +1111,7 @@ class DockerService(DockerBaseClass): 'stop_signal': self.stop_signal, 'limit_cpu': self.limit_cpu, 'limit_memory': self.limit_memory, + 'read_only': self.read_only, 'reserve_cpu': self.reserve_cpu, 'reserve_memory': self.reserve_memory, 'restart_policy_delay': self.restart_policy_delay, @@ -1307,6 +1316,7 @@ class DockerService(DockerBaseClass): s.stop_signal = ap['stop_signal'] s.user = ap['user'] s.working_dir = ap['working_dir'] + s.read_only = ap['read_only'] s.command = ap['command'] if isinstance(s.command, string_types): @@ -1482,6 +1492,8 @@ class DockerService(DockerBaseClass): differences.add('stop_grace_period', parameter=self.stop_grace_period, active=os.stop_grace_period) if self.has_publish_changed(os.publish): differences.add('publish', parameter=self.publish, active=os.publish) + if self.read_only is not None and self.read_only != os.read_only: + differences.add('read_only', parameter=self.read_only, active=os.read_only) if self.restart_policy is not None and self.restart_policy != os.restart_policy: differences.add('restart_policy', parameter=self.restart_policy, active=os.restart_policy) if self.restart_policy_attempts is not None and self.restart_policy_attempts != os.restart_policy_attempts: @@ -1645,6 +1657,8 @@ class DockerService(DockerBaseClass): container_spec_args['hostname'] = self.hostname if self.hosts is not None: container_spec_args['hosts'] = self.hosts + if self.read_only is not None: + container_spec_args['read_only'] = self.read_only if self.stop_grace_period is not None: container_spec_args['stop_grace_period'] = self.stop_grace_period if self.stop_signal is not None: @@ -1837,6 +1851,7 @@ class DockerServiceManager(object): ds.stop_grace_period = task_template_data['ContainerSpec'].get('StopGracePeriod') ds.stop_signal = task_template_data['ContainerSpec'].get('StopSignal') ds.working_dir = task_template_data['ContainerSpec'].get('Dir') + ds.read_only = task_template_data['ContainerSpec'].get('ReadOnly') healthcheck_data = task_template_data['ContainerSpec'].get('Healthcheck') if healthcheck_data: @@ -2243,6 +2258,7 @@ def main(): )), limit_cpu=dict(type='float', removed_in_version='2.12'), limit_memory=dict(type='str', removed_in_version='2.12'), + read_only=dict(type='bool'), reservations=dict(type='dict', options=dict( cpus=dict(type='float'), memory=dict(type='str'), @@ -2309,6 +2325,7 @@ def main(): update_order=dict(docker_py_version='2.7.0', docker_api_version='1.29'), stop_signal=dict(docker_py_version='2.6.0', docker_api_version='1.28'), publish=dict(docker_py_version='3.0.0', docker_api_version='1.25'), + read_only=dict(docker_py_version='2.6.0', docker_api_version='1.28'), # specials publish_mode=dict( docker_py_version='3.0.0', diff --git a/test/integration/targets/docker_swarm_service/tasks/tests/options.yml b/test/integration/targets/docker_swarm_service/tasks/tests/options.yml index 4d4af367767..97bd1244040 100644 --- a/test/integration/targets/docker_swarm_service/tasks/tests/options.yml +++ b/test/integration/targets/docker_swarm_service/tasks/tests/options.yml @@ -1820,6 +1820,58 @@ - "'Minimum version required' in publish_1.msg" when: docker_api_version is version('1.25', '<') or docker_py_version is version('3.0.0', '<') +################################################################### +## read_only ###################################################### +################################################################### + +- name: read_only + docker_swarm_service: + name: "{{ service_name }}" + image: alpine:3.8 + resolve_image: no + command: '/bin/sh -v -c "sleep 10m"' + read_only: true + register: read_only_1 + ignore_errors: yes + +- name: read_only (idempotency) + docker_swarm_service: + name: "{{ service_name }}" + image: alpine:3.8 + resolve_image: no + command: '/bin/sh -v -c "sleep 10m"' + read_only: true + register: read_only_2 + ignore_errors: yes + +- name: read_only (change) + docker_swarm_service: + name: "{{ service_name }}" + image: alpine:3.8 + resolve_image: no + command: '/bin/sh -v -c "sleep 10m"' + read_only: false + register: read_only_3 + ignore_errors: yes + +- name: cleanup + docker_swarm_service: + name: "{{ service_name }}" + state: absent + diff: no + +- assert: + that: + - read_only_1 is changed + - read_only_2 is not changed + - read_only_3 is changed + when: docker_api_version is version('1.28', '>=') and docker_py_version is version('2.6.0', '>=') +- assert: + that: + - read_only_1 is failed + - "'Minimum version required' in read_only_1.msg" + when: docker_api_version is version('1.28', '<') or docker_py_version is version('2.6.0', '<') + ################################################################### ## replicas ####################################################### ################################################################### diff --git a/test/integration/targets/docker_swarm_service/vars/main.yml b/test/integration/targets/docker_swarm_service/vars/main.yml index fd8c6932f39..d1908648921 100644 --- a/test/integration/targets/docker_swarm_service/vars/main.yml +++ b/test/integration/targets/docker_swarm_service/vars/main.yml @@ -33,6 +33,7 @@ service_expected_output: publish: - {mode: null, protocol: tcp, published_port: 60001, target_port: 60001} - {mode: null, protocol: udp, published_port: 60001, target_port: 60001} + read_only: null replicas: null reserve_cpu: null reserve_memory: null