Repository: ansible/ansible-modules-core

Issue:
yum module install URL reports changed in --check
##### Issue Type:

Bug Report
##### Ansible Version:

1.9.1
##### Ansible Configuration:

Nothing
##### Environment:

Centos 6
##### Summary:

`yum` module always reports as changed in check mode (`--check`) when installing an RPM from a URL.
##### Steps To Reproduce:

Here is a short play:

```

---
- hosts: all
  gather_facts: no
  tasks:
    - yum: name=http://nginx.org/packages/rhel/6/noarch/RPMS/nginx-release-rhel-6-0.el6.ngx.noarch.rpm state=present
```

If you run it regularly everything is fine (since `nginx-release` was installed before):

```
$ ansible-playbook -i test_hosts yum.yml        

PLAY [all] ******************************************************************** 

TASK: [yum name=http://nginx.org/packages/rhel/6/noarch/RPMS/nginx-release-rhel-6-0.el6.ngx.noarch.rpm state=present] *** 
ok: [pg-01]

PLAY RECAP ******************************************************************** 
pg-01                      : ok=1    changed=0    unreachable=0    failed=0   
```

But if you run it in check mode, it reports as changed:

```
$ ansible-playbook -i test_hosts yum.yml -C

PLAY [all] ******************************************************************** 

TASK: [yum name=http://nginx.org/packages/rhel/6/noarch/RPMS/nginx-release-rhel-6-0.el6.ngx.noarch.rpm state=present] *** 
changed: [pg-01]

PLAY RECAP ******************************************************************** 
pg-01                      : ok=1    changed=1    unreachable=0    failed=0
```
##### Expected Results:

Idempotency should work in check mode as well.
##### Actual Results:

Idempotency doesn't work in check mode.



Discussion:
+1 I've noticed this issue as well.


Resolving patch:
diff --git a/packaging/os/yum.py b/packaging/os/yum.py
--- a/packaging/os/yum.py
+++ b/packaging/os/yum.py
@@ -482,6 +482,19 @@ def local_nvra(module, path):
                             header[rpm.RPMTAG_RELEASE],
                             header[rpm.RPMTAG_ARCH])
     
+def local_name(module, path):
+    """return package name of a local rpm passed in"""
+
+    ts = rpm.TransactionSet()
+    ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
+    fd = os.open(path, os.O_RDONLY)
+    try:
+        header = ts.hdrFromFdno(fd)
+    finally:
+        os.close(fd)
+
+    return header[rpm.RPMTAG_NAME]
+    
 def pkg_to_dict(pkgstr):
 
     if pkgstr.strip():
@@ -556,33 +569,34 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
                 res['msg'] += "No Package file matching '%s' found on system" % spec
                 module.fail_json(**res)
 
-            nvra = local_nvra(module, spec)
+            pkg_name = local_name(module, spec)
             # look for them in the rpmdb
-            if is_installed(module, repoq, nvra, conf_file, en_repos=en_repos, dis_repos=dis_repos):
+            if is_installed(module, repoq, pkg_name, conf_file, en_repos=en_repos, dis_repos=dis_repos):
                 # if they are there, skip it
                 continue
             pkg = spec
 
         # URL
         elif '://' in spec:
-            pkg = spec
-            # Check if Enterprise Linux 5 or less, as yum on those versions do not support installing via url
-            distribution_version = get_distribution_version()
-            distribution = platform.dist()
-            if distribution[0] == "redhat" and LooseVersion(distribution_version) < LooseVersion("6"):
-                package = os.path.join(tempdir, str(pkg.rsplit('/', 1)[1]))
-                try:
-                    rsp, info = fetch_url(module, pkg)
-                    f = open(package, 'w')
+            # download package so that we can check if it's already installed
+            package = os.path.join(tempdir, str(spec.rsplit('/', 1)[1]))
+            try:
+                rsp, info = fetch_url(module, spec)
+                f = open(package, 'w')
+                data = rsp.read(BUFSIZE)
+                while data:
+                    f.write(data)
                     data = rsp.read(BUFSIZE)
-                    while data:
-                        f.write(data)
-                        data = rsp.read(BUFSIZE)
-                    f.close()
-                    pkg = package
-                except Exception, e:
-                    shutil.rmtree(tempdir)
-                    module.fail_json(msg="Failure downloading %s, %s" % (spec, e))
+                f.close()
+            except Exception, e:
+                shutil.rmtree(tempdir)
+                module.fail_json(msg="Failure downloading %s, %s" % (spec, e))
+
+            pkg_name = local_name(module, package)
+            if is_installed(module, repoq, pkg_name, conf_file, en_repos=en_repos, dis_repos=dis_repos):
+                # if it's there, skip it
+                continue
+            pkg = package
 
         #groups :(
         elif spec.startswith('@'):


Test patch: