From 0742f00c299a2b5ab231d3ead41bee208e9e4c34 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Thu, 1 Nov 2018 09:08:43 +0100 Subject: [PATCH] docker_container: fix paused and add some tests (#47900) * cleanup is already tested. * Add test for paused. * Add recreate and restart tests. * timeout is a common docker option * Implement paused and fix paused test. * Add changelog. * Improve paused test. (cherry picked from commit 65768b996d8580ec8bb1188ed98471a4456f8938) --- .../47900-docker_container-paused.yml | 2 + .../modules/cloud/docker/docker_container.py | 20 ++ .../docker_container/tasks/tests/options.yml | 171 ++++++++++++++++-- 3 files changed, 177 insertions(+), 16 deletions(-) create mode 100644 changelogs/fragments/47900-docker_container-paused.yml diff --git a/changelogs/fragments/47900-docker_container-paused.yml b/changelogs/fragments/47900-docker_container-paused.yml new file mode 100644 index 00000000000..ae19f6ed859 --- /dev/null +++ b/changelogs/fragments/47900-docker_container-paused.yml @@ -0,0 +1,2 @@ +bugfixes: +- "docker_container - fix ``paused`` option (which never worked)." diff --git a/lib/ansible/modules/cloud/docker/docker_container.py b/lib/ansible/modules/cloud/docker/docker_container.py index 8196d39856f..162d9d34258 100644 --- a/lib/ansible/modules/cloud/docker/docker_container.py +++ b/lib/ansible/modules/cloud/docker/docker_container.py @@ -1284,6 +1284,12 @@ class Container(DockerBaseClass): return True return False + @property + def paused(self): + if self.container and self.container.get('State'): + return self.container['State'].get('Paused', False) + return False + def _compare(self, a, b, compare): ''' Compare values a and b as described in compare. @@ -1853,6 +1859,20 @@ class ContainerManager(DockerBaseClass): self.container_stop(container.Id) container = self._get_container(container.Id) + if state == 'started' and container.paused != self.parameters.paused: + if not self.check_mode: + try: + if self.parameters.paused: + self.client.pause(container=container.Id) + else: + self.client.unpause(container=container.Id) + except Exception as exc: + self.fail("Error %s container %s: %s" % ( + "pausing" if self.parameters.paused else "unpausing", container.Id, str(exc) + )) + self.results['changed'] = True + self.results['actions'].append(dict(set_paused=self.parameters.paused)) + self.facts = container.raw def absent(self): diff --git a/test/integration/targets/docker_container/tasks/tests/options.yml b/test/integration/targets/docker_container/tasks/tests/options.yml index b10c8dab0f1..a8bad442004 100644 --- a/test/integration/targets/docker_container/tasks/tests/options.yml +++ b/test/integration/targets/docker_container/tasks/tests/options.yml @@ -168,12 +168,6 @@ - capabilities_3 is not changed - capabilities_4 is changed -#################################################################### -## cleanup ######################################################### -#################################################################### - -# TODO: - cleanup - #################################################################### ## command ######################################################### #################################################################### @@ -486,7 +480,7 @@ - debug_4 is changed #################################################################### -## detach ########################################################## +## detach, cleanup ################################################# #################################################################### - name: detach without cleanup @@ -2241,7 +2235,69 @@ ## paused ########################################################## #################################################################### -# TODO: - paused +- name: paused + docker_container: + image: alpine:3.8 + command: "/bin/sh -c 'sleep 1s ; yes'" + name: "{{ cname }}" + state: started + paused: yes + stop_timeout: 1 + register: paused_1 + +- pause: + seconds: 2 + +- name: paused (logs) + command: docker logs --tail=20 "{{ cname }}" + register: paused_2 + +- name: paused (idempotent) + docker_container: + image: alpine:3.8 + command: "/bin/sh -c 'sleep 1s ; yes'" + name: "{{ cname }}" + state: started + paused: yes + stop_timeout: 1 + register: paused_3 + +- name: paused (continue) + docker_container: + image: alpine:3.8 + command: "/bin/sh -c 'sleep 1s ; yes'" + name: "{{ cname }}" + state: started + paused: no + stop_timeout: 1 + register: paused_4 + +- pause: + seconds: 2 + +- name: paused (stop) + docker_container: + name: "{{ cname }}" + state: stopped + stop_timeout: 1 + +- name: paused (logs) + command: docker logs --tail=20 "{{ cname }}" + register: paused_5 + +- name: cleanup + docker_container: + name: "{{ cname }}" + state: absent + stop_timeout: 1 + +- assert: + that: + - paused_1 is changed + - paused_2.stdout_lines | length == 0 + - paused_3 is not changed + - paused_4 is changed + - paused_5.stdout_lines | length > 0 #################################################################### ## pid_mode ######################################################## @@ -2470,13 +2526,102 @@ ## recreate ######################################################## #################################################################### -# TODO: - recreate +- name: recreate (created) + docker_container: + image: alpine:3.8 + command: '/bin/sh -v -c "sleep 10m"' + name: "{{ cname }}" + state: present + stop_timeout: 1 + register: recreate_1 + +- name: recreate (created, recreate) + docker_container: + image: alpine:3.8 + command: '/bin/sh -v -c "sleep 10m"' + name: "{{ cname }}" + recreate: yes + state: present + stop_timeout: 1 + register: recreate_2 + +- name: recreate (started) + docker_container: + image: alpine:3.8 + command: '/bin/sh -v -c "sleep 10m"' + name: "{{ cname }}" + state: started + stop_timeout: 1 + register: recreate_3 + +- name: recreate (started, recreate) + docker_container: + image: alpine:3.8 + command: '/bin/sh -v -c "sleep 10m"' + name: "{{ cname }}" + recreate: yes + state: started + stop_timeout: 1 + register: recreate_4 + +- name: cleanup + docker_container: + name: "{{ cname }}" + state: absent + stop_timeout: 1 + +- debug: var=recreate_1 +- debug: var=recreate_2 +- debug: var=recreate_3 +- debug: var=recreate_4 + +- assert: + that: + - recreate_1 is changed + - recreate_2 is changed + - recreate_3 is changed + - recreate_4 is changed + - recreate_1.ansible_facts.docker_container.Id != recreate_2.ansible_facts.docker_container.Id + - recreate_2.ansible_facts.docker_container.Id == recreate_3.ansible_facts.docker_container.Id + - recreate_3.ansible_facts.docker_container.Id != recreate_4.ansible_facts.docker_container.Id #################################################################### ## restart ######################################################### #################################################################### -# TODO: - restart +- name: restart + docker_container: + image: alpine:3.8 + command: '/bin/sh -v -c "sleep 10m"' + name: "{{ cname }}" + state: started + stop_timeout: 1 + register: restart_1 + +- name: restart (restart) + docker_container: + image: alpine:3.8 + command: '/bin/sh -v -c "sleep 10m"' + name: "{{ cname }}" + restart: yes + state: started + stop_timeout: 1 + register: restart_2 + +- name: cleanup + docker_container: + name: "{{ cname }}" + state: absent + stop_timeout: 1 + +- debug: var=restart_1 +- debug: var=restart_2 + +- assert: + that: + - restart_1 is changed + - restart_2 is changed + - restart_1.ansible_facts.docker_container.Id == restart_2.ansible_facts.docker_container.Id #################################################################### ## restart_policy ################################################## @@ -2821,12 +2966,6 @@ - "('version is ' ~ docker_py_version ~'. Minimum version required is 1.10.0') in sysctls_1.msg" when: docker_py_version is version('1.10.0', '<') -#################################################################### -## timeout ######################################################### -#################################################################### - -# TODO: - timeout - #################################################################### ## tmpfs ########################################################### ####################################################################