Repository: ansible/ansible-modules-core

Issue:
Yum upgrade using local RPM does nothing
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME

yum
##### ANSIBLE VERSION

```
ansible 2.1.0.0
```
##### CONFIGURATION
##### OS / ENVIRONMENT

N/A
##### SUMMARY

When using the yum module to upgrade (my-rpm-1.0 -> my-rpm-1.1) an already installed RPM from a local rpm file, I get the following output:

```
my.host.net | SUCCESS => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "conf_file": null, 
            "disable_gpg_check": false, 
            "disablerepo": null, 
            "enablerepo": null, 
            "exclude": null, 
            "install_repoquery": true, 
            "list": null, 
            "name": [
                "/tmp/my-rpm.rpm"
            ], 
            "state": "present", 
            "update_cache": false, 
            "validate_certs": true
        }, 
        "module_name": "yum"
    }, 
    "msg": "", 
    "rc": 0, 
    "results": []
}
```

No changes were made and installed RPM is still the old version.

This bug was caused by commit c8222bc8db31c4b46645912c0f13c1632333eae4 fixing issue #1452.  At packaging/os/yum.py:576, when getting the package name for localpkg, the call to local_nvra was switched to local_name.  As a result, when deciding if an install is necessary, instead of comparing the rpm name-version-release-arch only the name is compared.
##### STEPS TO REPRODUCE
1. Get two rpms of different version for the same package
2. Place them in /tmp/v1.rpm and /tmp/v2.rpm on the target host
3. Run: ansible <target-host> -m yum -a "name=/tmp/v1.rpm state=present"
4. Run: ansible <target-host> -m yum -a "name=/tmp/v2.rpm state=present"
5. Run on target host: rpm -q <package name>
##### EXPECTED RESULTS

rpm -q should show the higher version number
##### ACTUAL RESULTS

rpm -q shows the lower version number



Discussion:

Resolving patch:
diff --git a/packaging/os/yum.py b/packaging/os/yum.py
--- a/packaging/os/yum.py
+++ b/packaging/os/yum.py
@@ -219,6 +219,25 @@ def ensure_yum_utils(module):
 
     return repoquerybin
 
+def fetch_rpm_from_url(spec, module=None):
+    # download package so that we can query it
+    tempdir = tempfile.mkdtemp()
+    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)
+        f.close()
+    except Exception:
+        e = get_exception()
+        shutil.rmtree(tempdir)
+        if module:
+            module.fail_json(msg="Failure downloading %s, %s" % (spec, e))
+    return package
+
 def po_to_nevra(po):
 
     if hasattr(po, 'ui_nevra'):
@@ -384,6 +403,13 @@ def what_provides(module, repoq, req_spec, conf_file,  qf=def_qf, en_repos=None,
     if dis_repos is None:
         dis_repos = []
 
+    if req_spec.endswith('.rpm') and '://' not in req_spec:
+        return req_spec
+
+    elif '://' in req_spec:
+        local_path = fetch_rpm_from_url(req_spec, module=module)
+        return local_path
+
     if not repoq:
 
         pkgs = []
@@ -574,6 +600,8 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
                 module.fail_json(**res)
 
             pkg_name = local_name(module, spec)
+            pkg_nevra = local_nvra(module, spec)
+
             # look for them in the rpmdb
             if is_installed(module, repoq, pkg_name, conf_file, en_repos=en_repos, dis_repos=dis_repos):
                 # if they are there, skip it
@@ -583,20 +611,7 @@ def install(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
         # URL
         elif '://' in spec:
             # 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)
-                f.close()
-            except Exception:
-                e = get_exception()
-                shutil.rmtree(tempdir)
-                module.fail_json(msg="Failure downloading %s, %s" % (spec, e))
-
+            package = fetch_rpm_from_url(spec, module=module)
             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


Test patch: