Repository: ansible/ansible-modules-core

Issue:
docker_image often fails to push with docker-py 1.10.x
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME

docker_image module
##### ANSIBLE VERSION

```
ansible 2.2.0 (devel 07a76bece1) last updated 2016/09/16 16:50:58 (GMT -700)
  lib/ansible/modules/core: (detached HEAD 488f082761) last updated 2016/09/16 16:51:07 (GMT -700)
  lib/ansible/modules/extras: (detached HEAD 24da3602c6) last updated 2016/09/16 16:51:07 (GMT -700)
  config file = /Users/rmendes/github/roles/roles-docker/docker_new_image/tests/ansible.cfg
  configured module search path = Default w/o overrides
```
##### CONFIGURATION

Our inventory is dictionary based so:

```
hash_behaviour=merge
```

This is on a completely rebuilt laptop with one virtualenv and no docker-py at the system level.

```
pip freeze
-e git+https://github.com/ansible/ansible.git@07a76bece15d2568d7ea76e77266190652a0beec#egg=ansible
backports.ssl-match-hostname==3.5.0.1
cffi==1.8.3
cryptography==1.5
-e git+https://github.com/docker/docker-py.git@6b7a828400f46ea81374bc5764d8aa81bf38f6f7#egg=docker_py
docker-pycreds==0.2.1
enum34==1.1.6
idna==2.1
ipaddress==1.0.17
Jinja2==2.8
MarkupSafe==0.23
paramiko==2.0.2
py2-ipaddress==3.4.1
pyasn1==0.1.9
pycparser==2.14
pycrypto==2.6.1
PyYAML==3.12
requests==2.10.0
six==1.10.0
websocket-client==0.37.0
```
##### OS / ENVIRONMENT

OS X El Capitan
##### SUMMARY

Image pushes often fail with what looks like a JSON handling issue.
##### STEPS TO REPRODUCE

```

---

- name: push image
  hosts: localhost
  connection: local
  gather_facts: False

  tasks:

    - name: push new image
      docker_image:
        name: "test-image-3"
        repository: "127.0.0.1:5000/test-image-3"
        tag: "role-test"
        pull: False
        push: True
        state: present
```

<!--- You can also paste gist.github.com links for larger files -->
##### EXPECTED RESULTS

Image is successfully pushed.
##### ACTUAL RESULTS

I discovered this in a role I was testing. 4/5 times I ran the role tests I got a failure like the one shown. 1/5 it worked like it should.

```
fatal: [test-image-3]: FAILED! => {
    "changed": false,
    "failed": true,
    "invocation": {
        "module_args": {
            "api_version": null,
            "archive_path": null,
            "buildargs": null,
            "cacert_path": null,
            "cert_path": null,
            "container_limits": null,
            "debug": false,
            "docker_host": null,
            "dockerfile": null,
            "filter_logger": false,
            "force": false,
            "http_timeout": null,
            "key_path": null,
            "load_path": null,
            "name": "test-image-3",
            "nocache": "False",
            "path": null,
            "pull": false,
            "push": true,
            "repository": "127.0.0.1:5000/test-image-3",
            "rm": true,
            "ssl_version": null,
            "state": "present",
            "tag": "role-test",
            "timeout": null,
            "tls": null,
            "tls_hostname": null,
            "tls_verify": null,
            "use_tls": "no"
        },
        "module_name": "ilmn_docker_image"
    },
    "msg": "Error pushing image 127.0.0.1:5000/test-image-3: Extra data: line 2 column 1 - line 3 column 1 (char 64 - 128)"
```

I thought this was a docker-py issue, so I reported it there today. @shin worked with me to show it is ultimately an Ansible issue. That thread is here - docker/docker-py#1222.

Here is what he reported:

Oh, I figured out why you're seeing the issue: https://github.com/ansible/ansible-modules-core/blob/devel/cloud/docker/docker_image.py#L428

Ansible does the decoding of data chunks itself, so it doesn't rely on our JSON parsing code, causing the issue at their level when the API sometimes sends multiple chunks at a time. I'm afraid this is something you'll have to report there, as there's little to be done on our end.



Discussion:
<!-- @rickmendes: Thanks for filing this bug report! -->

@ansible ping, this issue is waiting for your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_bug_new --->


Resolving patch:
diff --git a/cloud/docker/docker_image.py b/cloud/docker/docker_image.py
--- a/cloud/docker/docker_image.py
+++ b/cloud/docker/docker_image.py
@@ -424,8 +424,7 @@ def push_image(self, name, tag=None):
             if not self.check_mode:
                 status = None
                 try:
-                    for line in self.client.push(repository, tag=tag, stream=True):
-                        line = json.loads(line)
+                    for line in self.client.push(repository, tag=tag, stream=True,  decode=True):
                         self.log(line, pretty_print=True)
                         if line.get('errorDetail'):
                             raise Exception(line['errorDetail']['message'])


Test patch: