From 3afdb28209853364f61447ace191f648622bab24 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Tue, 23 Oct 2018 08:51:24 +0200 Subject: [PATCH] docker_container: fix interaction of detach:no with auto_remove:yes (#47396) * Behave better if auto_remove and output_logs are combined. Warn if output cannot be retrieved because of auto_remove. * Add tests. * Added changelog. --- ...6-docker_container-detach-auto-remove.yaml | 2 + .../modules/cloud/docker/docker_container.py | 26 ++++++---- .../docker_container/tasks/tests/options.yml | 51 ++++++++++++++++++- 3 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 changelogs/fragments/47396-docker_container-detach-auto-remove.yaml diff --git a/changelogs/fragments/47396-docker_container-detach-auto-remove.yaml b/changelogs/fragments/47396-docker_container-detach-auto-remove.yaml new file mode 100644 index 00000000000..182604b70f8 --- /dev/null +++ b/changelogs/fragments/47396-docker_container-detach-auto-remove.yaml @@ -0,0 +1,2 @@ +bugfixes: +- "docker_container - fix behavior of ``detach: yes`` if ``auto_remove: yes`` is specified." diff --git a/lib/ansible/modules/cloud/docker/docker_container.py b/lib/ansible/modules/cloud/docker/docker_container.py index 040a510f851..85d99dd350e 100644 --- a/lib/ansible/modules/cloud/docker/docker_container.py +++ b/lib/ansible/modules/cloud/docker/docker_container.py @@ -2211,20 +2211,25 @@ class ContainerManager(DockerBaseClass): status = self.client.wait(container_id)['StatusCode'] else: status = self.client.wait(container_id) - config = self.client.inspect_container(container_id) - logging_driver = config['HostConfig']['LogConfig']['Type'] - - if logging_driver == 'json-file' or logging_driver == 'journald': - output = self.client.logs(container_id, stdout=True, stderr=True, stream=False, timestamps=False) + if self.parameters.auto_remove: + output = "Cannot retrieve result as auto_remove is enabled" if self.parameters.output_logs: - self._output_logs(msg=output) + self.client.module.warn('Cannot output_logs if auto_remove is enabled!') else: - output = "Result logged using `%s` driver" % logging_driver + config = self.client.inspect_container(container_id) + logging_driver = config['HostConfig']['LogConfig']['Type'] + + if logging_driver == 'json-file' or logging_driver == 'journald': + output = self.client.logs(container_id, stdout=True, stderr=True, stream=False, timestamps=False) + if self.parameters.output_logs: + self._output_logs(msg=output) + else: + output = "Result logged using `%s` driver" % logging_driver if status != 0: self.fail(output, status=status) if self.parameters.cleanup: - self.container_remove(container_id, force=True) + self.container_remove(container_id, force=True, ignore_failure=self.parameters.auto_remove) insp = self._get_container(container_id) if insp.raw: insp.raw['Output'] = output @@ -2233,7 +2238,7 @@ class ContainerManager(DockerBaseClass): return insp return self._get_container(container_id) - def container_remove(self, container_id, link=False, force=False): + def container_remove(self, container_id, link=False, force=False, ignore_failure=False): volume_state = (not self.parameters.keep_volumes) self.log("remove container container:%s v:%s link:%s force%s" % (container_id, volume_state, link, force)) self.results['actions'].append(dict(removed=container_id, volume_state=volume_state, link=link, force=force)) @@ -2243,7 +2248,8 @@ class ContainerManager(DockerBaseClass): try: response = self.client.remove_container(container_id, v=volume_state, link=link, force=force) except Exception as exc: - self.fail("Error removing container %s: %s" % (container_id, str(exc))) + if not ignore_failure: + self.fail("Error removing container %s: %s" % (container_id, str(exc))) return response def container_update(self, container_id, update_parameters): diff --git a/test/integration/targets/docker_container/tasks/tests/options.yml b/test/integration/targets/docker_container/tasks/tests/options.yml index 9d3dc90809b..54bf2d0d8e5 100644 --- a/test/integration/targets/docker_container/tasks/tests/options.yml +++ b/test/integration/targets/docker_container/tasks/tests/options.yml @@ -480,7 +480,56 @@ ## detach ########################################################## #################################################################### -# TODO: - detach +- name: detach without cleanup + docker_container: + name: "{{ cname }}" + image: hello-world + detach: no + register: detach_no_cleanup + +- name: cleanup + docker_container: + name: "{{ cname }}" + state: absent + register: detach_no_cleanup_cleanup + +- name: detach with cleanup + docker_container: + name: "{{ cname }}" + image: hello-world + detach: no + cleanup: yes + register: detach_cleanup + +- name: cleanup (unnecessary) + docker_container: + name: "{{ cname }}" + state: absent + register: detach_cleanup_cleanup + +- name: detach with auto_remove and cleanup + docker_container: + name: "{{ cname }}" + image: hello-world + detach: no + auto_remove: yes + cleanup: yes + register: detach_auto_remove + +- name: cleanup (unnecessary) + docker_container: + name: "{{ cname }}" + state: absent + register: detach_auto_remove_cleanup + +- assert: + that: + - "'Hello from Docker!' in detach_no_cleanup.ansible_facts.docker_container.Output" + - detach_no_cleanup_cleanup is changed + - "'Hello from Docker!' in detach_cleanup.ansible_facts.docker_container.Output" + - detach_cleanup_cleanup is not changed + - "'Cannot retrieve result as auto_remove is enabled' == detach_auto_remove.ansible_facts.docker_container.Output" + - detach_auto_remove_cleanup is not changed #################################################################### ## devices #########################################################