Repository: ansible/ansible

Issue:
maven_artifact checksum error when downloading from archiva repository
<!---
Verify first that your issue/request is not already reported on GitHub.
THIS FORM WILL BE READ BY A MACHINE, COMPLETE ALL SECTIONS AS DESCRIBED.
Also test if the latest release, and devel branch are affected too.
ALWAYS add information AFTER (OUTSIDE) these html comments.
Otherwise it may end up being automatically closed by our bot. -->

##### SUMMARY
When we use maven_artifact to download from an archiva repository the md5sum always fail.  The issue is when it check for the md5 the .md5 generated by archiva does not only contail the md5, but the md5 and the filename.  So when the module check the computed md5 of the local file it compare the localmd5 with a string composed "md5  <filename>".  Since ansible 2.6 in order to workaround this issue we add the `verify_checksum: always` which is very bad.  This was not the case in version 2.5.x.   This behavior start with ansible 2.6.0.  

I've also tested with the maven_artifact.py from the devel branch and I was having the same behavior.

##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
<!--- Insert, BELOW THIS COMMENT, the name of the module, plugin, task or feature.
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path-->
maven_artifact

##### ANSIBLE VERSION
<!--- Paste, BELOW THIS COMMENT, verbatim output from "ansible --version" between quotes below -->
```
2.6.1
```

##### CONFIGURATION
<!--- If using Ansible 2.4 or above, paste, BELOW THIS COMMENT, the results of "ansible-config dump --only-changed"
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).-->
Default install from EPEL

##### OS / ENVIRONMENT
<!--- Mention, BELOW THIS COMMENT, the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.-->
CentOS 7.5
CentOS 6.x

##### STEPS TO REPRODUCE
<!--- For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used. -->

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- name: Download Maven artifact
  maven_artifact:
    artifact_id: mymodule
    dest: "/tmp/mymodule/"
    group_id: com/ciename/module
    state: present
    version: "latest"
    extension: jar
    repository_url: "http://archiva.corp.net/archiva/repository/internal/"
    verify_checksum: always
  environment:
    no_proxy: "localhost,127.0.0.1,.corp.net"
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
I'm expecting to have a valid md5sum 

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
Actually the content of remote_md5 is the whole content of the md5 file downloaded from archiva and the remote_url should

<!--- Paste verbatim command output between quotes below -->
```
TASK [myrole: Download Maven MyModule jar] *********************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Cannot retrieve the artifact to destination: Checksum does not match: we computed c3a749e2c090e6ef6b99c2b3268ace5bbut the repository states c3a749e2c090e6ef6b99c2b3268ace5b  my-module-1.0.0.war"}
```



Discussion:
Files identified in the description:
* [lib/ansible/modules/packaging/language/maven_artifact.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/packaging/language/maven_artifact.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @tumbl3w33d @turb
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
To save time, would it be possible to display an example of a xxx.md5 stream returned by Archiva?

(edited: sorry, it is visible in the error log)

I suppose we have to manage those variations in the various Maven implementation...
Hi @turb 

Here is an example of the content of a md5sum from archiva

`
2139c31582e3410c1ccc8414701c46fa  my-module-1.12-20180712.154516-154.jar
`

I've tested it with a simple fix like this and it was working.  But maybe it would break on other maven implementation

```
 def is_invalid_md5(self, file, remote_url):
        if os.path.exists(file):
            local_md5 = self._local_md5(file)
            if self.local:
                parsed_url = urlparse(remote_url)
                remote_md5 = self._local_md5(parsed_url.path)
            else:
                try:
                    remote_md5 = to_text(self._getContent(remote_url + '.md5', "Failed to retrieve MD5", False), errors='strict')
                except UnicodeError as e:
                    return "Cannot retrieve a valid md5 from %s: %s" % (remote_url, to_native(e))
                if(not remote_md5):
                    return "Cannot find md5 from " + remote_url
            remote_md5 = remote_md5.split()[0]
            if local_md5 == remote_md5:
                return None
            else:
                return "Checksum does not match: we computed " + local_md5 + "but the repository states " + remote_md5

        return "Path does not exist: " + file
```

Here is the actual change that I include.  This was against the `devel` branch of `maven_artifact.py` .

`
remote_md5 = remote_md5.split()[0]
`
Looks like good (it will also work with other repos that only return the md5), except `split` will return an empty list if `sep` is not set and `remote_md5` is empty. [See documentation](https://docs.python.org/2/library/string.html).

Once it is fixed (either by setting `sep` or managing the empty return), I think you are ready for a PR ;)

Resolving patch:
diff --git a/lib/ansible/modules/packaging/language/maven_artifact.py b/lib/ansible/modules/packaging/language/maven_artifact.py
--- a/lib/ansible/modules/packaging/language/maven_artifact.py
+++ b/lib/ansible/modules/packaging/language/maven_artifact.py
@@ -434,6 +434,14 @@ def is_invalid_md5(self, file, remote_url):
                     return "Cannot retrieve a valid md5 from %s: %s" % (remote_url, to_native(e))
                 if(not remote_md5):
                     return "Cannot find md5 from " + remote_url
+            try:
+                # Check if remote md5 only contains md5 or md5 + filename
+                _remote_md5 = remote_md5.split(None)[0]
+                remote_md5 = _remote_md5
+                # remote_md5 is empty so we continue and keep original md5 string
+                # This should not happen since we check for remote_md5 before
+            except IndexError as e:
+                pass
             if local_md5 == remote_md5:
                 return None
             else:


Test patch: