Repository: ansible/ansible-modules-core

Issue:
docker_container detach does not detach the container
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME

docker_container
##### ANSIBLE VERSION

```
2016-06-13 devel
```
##### OS / ENVIRONMENT

Ubuntu 16.04
##### SUMMARY

Using "detach: yes" in docker_container should make the task wait until the container exits. Right now, container is being detached.
##### STEPS TO REPRODUCE

Example playbook:

```

---
- hosts: localhost
  tasks:
    - docker_container:
        name: test
        image: alpine
        detach: no
        command: sleep 10
        state: started
```
##### EXPECTED RESULTS

Task should wait until container exits.
##### ACTUAL RESULTS

```
Using module file /usr/local/lib/python2.7/dist-packages/ansible-2.2.0-py2.7.egg/ansible/modules/core/cloud/docker/docker_container.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1465842105.3-126236234110097 `" && echo ansible-tmp-1465842105.3-126236234110097="` echo $HOME/.ansible/tmp/ansible-tmp-1465842105.3-126236234110097 `" ) && sleep 0'
<127.0.0.1> PUT /tmp/tmpk4FzCY TO /root/.ansible/tmp/ansible-tmp-1465842105.3-126236234110097/docker_container.py
<127.0.0.1> EXEC /bin/sh -c 'chmod -R u+x /root/.ansible/tmp/ansible-tmp-1465842105.3-126236234110097/ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1465842105.3-126236234110097/docker_container.py; rm -rf "/root/.ansible/tmp/ansible-tmp-1465842105.3-126236234110097/" > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {"ansible_facts": {"ansible_docker_container": {"AppArmorProfile": "", "Args": ["10"], "Config": {"AttachStderr": true, "AttachStdin": false, "AttachStdout": true, "Cmd": ["sleep", "10"], "Domainname": "", "Entrypoint": null, "Env": null, "Hostname": "2f9dd8422ed6", "Image": "alpine", "Labels": {}, "OnBuild": null, "OpenStdin": false, "StdinOnce": false, "Tty": false, "User": "", "Volumes": null, "WorkingDir": ""}, "Created": "2016-06-13T18:20:52.984461312Z", "Driver": "aufs", "ExecIDs": null, "GraphDriver": {"Data": null, "Name": "aufs"}, "HostConfig": {"Binds": [], "BlkioDeviceReadBps": null, "BlkioDeviceReadIOps": null, "BlkioDeviceWriteBps": null, "BlkioDeviceWriteIOps": null, "BlkioWeight": 0, "BlkioWeightDevice": null, "CapAdd": null, "CapDrop": null, "CgroupParent": "", "ConsoleSize": [0, 0], "ContainerIDFile": "", "CpuPeriod": 0, "CpuQuota": 0, "CpuShares": 0, "CpusetCpus": "", "CpusetMems": "", "Devices": null, "Dns": null, "DnsOptions": null, "DnsSearch": null, "ExtraHosts": null, "GroupAdd": null, "IpcMode": "", "Isolation": "", "KernelMemory": 0, "Links": null, "LogConfig": {"Config": {}, "Type": "json-file"}, "Memory": 0, "MemoryReservation": 0, "MemorySwap": 0, "MemorySwappiness": -1, "NetworkMode": "default", "OomKillDisable": false, "OomScoreAdj": 0, "PidMode": "", "PidsLimit": 0, "PortBindings": null, "Privileged": false, "PublishAllPorts": false, "ReadonlyRootfs": false, "RestartPolicy": {"MaximumRetryCount": 0, "Name": ""}, "SecurityOpt": null, "ShmSize": 67108864, "UTSMode": "", "Ulimits": null, "VolumeDriver": "", "VolumesFrom": null}, "HostnamePath": "/var/lib/docker/containers/2f9dd8422ed6e760a1f681a1cb6de5174cc6a7581873647346392ab1157da758/hostname", "HostsPath": "/var/lib/docker/containers/2f9dd8422ed6e760a1f681a1cb6de5174cc6a7581873647346392ab1157da758/hosts", "Id": "2f9dd8422ed6e760a1f681a1cb6de5174cc6a7581873647346392ab1157da758", "Image": "sha256:f70c828098f57d1f3fc678402c23450097aa4ee6963aa22913c0b10375ce366e", "LogPath": "/var/lib/docker/containers/2f9dd8422ed6e760a1f681a1cb6de5174cc6a7581873647346392ab1157da758/2f9dd8422ed6e760a1f681a1cb6de5174cc6a7581873647346392ab1157da758-json.log", "MountLabel": "", "Mounts": [], "Name": "/test", "NetworkSettings": {"Bridge": "", "EndpointID": "b18d81d97fc033823cea50989c612b6d6f73768b2077c1ad24695599ca074dee", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "HairpinMode": false, "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "Networks": {"bridge": {"Aliases": null, "EndpointID": "b18d81d97fc033823cea50989c612b6d6f73768b2077c1ad24695599ca074dee", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAMConfig": null, "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "Links": null, "MacAddress": "02:42:ac:11:00:02", "NetworkID": "6b9daf56b1b816a38ae07474bc5fb19d8fc7b669534ccfd9559b9106825e0797"}}, "Ports": {}, "SandboxID": "2e64539721d802b4665935565f31c2479c419fa386f2923c006205aeb4fb6608", "SandboxKey": "/var/run/docker/netns/2e64539721d8", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null}, "Path": "sleep", "ProcessLabel": "", "ResolvConfPath": "/var/lib/docker/containers/2f9dd8422ed6e760a1f681a1cb6de5174cc6a7581873647346392ab1157da758/resolv.conf", "RestartCount": 0, "State": {"Dead": false, "Error": "", "ExitCode": 0, "FinishedAt": "2016-06-13T18:21:03.501679288Z", "OOMKilled": false, "Paused": false, "Pid": 27174, "Restarting": false, "Running": true, "StartedAt": "2016-06-13T18:21:45.965094911Z", "Status": "running"}}}, "changed": true, "invocation": {"module_args": {"api_version": null, "blkio_weight": null, "cacert_path": null, "capabilities": null, "cert_path": null, "command": "sleep 10", "cpu_period": null, "cpu_quota": null, "cpu_shares": null, "cpuset_cpus": null, "cpuset_mems": null, "debug": false, "detach": false, "devices": null, "dns_opts": null, "dns_search_domains": null, "dns_servers": null, "docker_host": null, "entrypoint": null, "env": null, "env_file": null, "etc_hosts": null, "exposed_ports": null, "filter_logger": false, "force_kill": false, "groups": null, "hostname": null, "image": "alpine", "interactive": false, "ipc_mode": null, "keep_volumes": true, "kernel_memory": null, "key_path": null, "kill_signal": null, "labels": null, "links": null, "log_driver": "json-file", "log_options": null, "mac_address": null, "memory": "0", "memory_reservation": null, "memory_swap": null, "memory_swappiness": null, "name": "test", "network_mode": null, "networks": null, "oom_killer": null, "paused": false, "pid_mode": null, "privileged": false, "published_ports": null, "pull": false, "purge_networks": null, "read_only": false, "recreate": false, "restart": false, "restart_policy": null, "restart_retries": 0, "security_opts": null, "shm_size": null, "ssl_version": null, "state": "started", "stop_signal": null, "stop_timeout": null, "timeout": null, "tls": null, "tls_hostname": null, "tls_verify": null, "trust_image_content": false, "tty": false, "ulimits": null, "user": null, "uts": null, "volume_driver": null, "volumes": null, "volumes_from": null}, "module_name": "docker_container"}}
```



Discussion:
confirmed with simple test
`ansible -m docker_container -a 'name=test1 image=ansible/ansible:centos7 detach=no command="sleep 100" state=started' localhost`


Resolving patch:
diff --git a/cloud/docker/docker_container.py b/cloud/docker/docker_container.py
--- a/cloud/docker/docker_container.py
+++ b/cloud/docker/docker_container.py
@@ -802,7 +802,6 @@ def create_parameters(self):
             tty='tty',
             ports='ports',
             environment='env',
-            dns='dns_servers',
             name='name',
             entrypoint='entrypoint',
             cpu_shares='cpu_shares',
@@ -1645,8 +1644,8 @@ def absent(self):
                 self.container_stop(container.Id)
             self.container_remove(container.Id)
 
-    def fail(self, msg):
-        self.client.module.fail_json(msg=msg)
+    def fail(self, msg, **kwargs):
+        self.client.module.fail_json(msg=msg, **kwargs)
 
     def _get_container(self, container):
         '''
@@ -1774,6 +1773,13 @@ def container_start(self, container_id):
                 self.client.start(container=container_id)
             except Exception as exc:
                 self.fail("Error starting container %s: %s" % (container_id, str(exc)))
+
+            if not self.parameters.detach:
+                status = self.client.wait(container_id)
+                if status != 0:
+                    output = self.client.logs(container_id, stdout=True, stderr=True, stream=False, timestamps=False)
+                    self.fail(output, status=status)
+
         return self._get_container(container_id)
 
     def container_remove(self, container_id, link=False, force=False):


Test patch: