Repository: ansible/ansible-modules-core

Issue:
A working check if local file is installed

apt: deb="file.deb" always changed
using ansible 1.9.4



Discussion:

[module: packaging/os/apt.py]

@drzraf Thanks for submitting this bug report. You might want to consider giving us the following additional information to help the module maintainer identify the issue: https://github.com/ansible/ansible/blob/devel/ISSUE_TEMPLATE.md

@mgwilliams thanks in advance for taking a look at this bug report and for your ongoing work in maintaining this module. 

This is because of 

pkg = apt.debfile.DebPackage(deb_file)

apt.debfile.DebPackage is useless, compare_to_version_in_cache does not work, and it provides no classes to return a version number, or even the package name. Going to work on getting name and version from dpkg and then checking version with apt_pkg


Resolving patch:
diff --git a/packaging/os/apt.py b/packaging/os/apt.py
--- a/packaging/os/apt.py
+++ b/packaging/os/apt.py
@@ -468,6 +468,14 @@ def install(m, pkgspec, cache, upgrade=False, default_release=None,
     else:
         return (True, dict(changed=False))
 
+def get_field_of_deb(m, deb_file, field="Version"):
+    cmd_dpkg = m.get_bin_path("dpkg", True)
+    cmd = cmd_dpkg + " --field %s %s" % (deb_file, field)
+    rc, stdout, stderr = m.run_command(cmd)
+    if rc != 0:
+        m.fail_json(msg="%s failed" % cmd, stdout=stdout, stderr=stderr)
+    return stdout.strip('\n')
+
 def install_deb(m, debs, cache, force, install_recommends, allow_unauthenticated, dpkg_options):
     changed=False
     deps_to_install = []
@@ -475,10 +483,17 @@ def install_deb(m, debs, cache, force, install_recommends, allow_unauthenticated
     for deb_file in debs.split(','):
         try:
             pkg = apt.debfile.DebPackage(deb_file)
-
-            # Check if it's already installed
-            if pkg.compare_to_version_in_cache() == pkg.VERSION_SAME:
-                continue
+            pkg_name = get_field_of_deb(m, deb_file, "Package")
+            pkg_version = get_field_of_deb(m, deb_file, "Version")
+            try:
+                installed_pkg = apt.Cache()[pkg_name]
+                installed_version = installed_pkg.installed.version
+                if package_version_compare(pkg_version, installed_version) == 0:
+                    # Does not need to down-/upgrade, move on to next package
+                    continue
+            except Exception, e:
+                # Must not be installed, continue with installation
+                pass
             # Check if package is installable
             if not pkg.check() and not force:
                 m.fail_json(msg=pkg._failure_string)
@@ -658,7 +673,7 @@ def main():
             cache_valid_time = dict(type='int'),
             purge = dict(default=False, type='bool'),
             package = dict(default=None, aliases=['pkg', 'name'], type='list'),
-            deb = dict(default=None),
+            deb = dict(default=None, type='path'),
             default_release = dict(default=None, aliases=['default-release']),
             install_recommends = dict(default=None, aliases=['install-recommends'], type='bool'),
             force = dict(default='no', type='bool'),


Test patch: