Repository: ansible/ansible

Issue:
apt module uses  apt-get --autoremove even if autoremove=no
##### ISSUE TYPE
 - Bug Report
##### COMPONENT NAME
apt
##### ANSIBLE VERSION
```
ansible 2.4.0.0 (detached HEAD 3c805f85bc) last updated 2017/09/18 18:23:57 (GMT +300)
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/vashik/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/vashik/opt/ansible/lib/ansible
  executable location = /home/vashik/opt/ansible/bin/ansible
  python version = 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]
```

##### CONFIGURATION
<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

##### OS / ENVIRONMENT
<!---
Mention 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.
-->
Debian Jessie

##### SUMMARY
If aptitude is missing apt module falls back to using apt-get but uses an option --autoremove that some versions of apt-get do not understood

##### 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.
-->
Set up a minimal Debian Jessie system, it won't have aptitude installed.
Try to apply updates using apt module on it.

<!--- Paste example playbooks or commands between quotes below -->
```bash
ansible -i target-host-name, target-host-name -m apt -sa 'upgrade=yes update_cache=yes autoclean=no autoremove=no' -vv
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
Apt module does not use --autoremove when autoremove=no
Apt module has default value no for autoremove
Apt module does not try to use --autoremove when apt-get does not support it 
##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->


<!--- Paste verbatim command output between quotes below -->
```
target-host-name | FAILED! => {
    "changed": false,
    "failed": true,
    "msg": "'/usr/bin/apt-get upgrade --with-new-pkgs --autoremove' failed: E: Command line option --autoremove is not understood\n",
    "rc": 100,
    "stdout": "",
    "stdout_lines": []
}
```



Discussion:
cc @mgwilliams
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Yeah this looks problematic.
```
def upgrade(m, mode="yes", force=False, default_release=None,
            use_apt_get=False,
            dpkg_options=expand_dpkg_options(DPKG_OPTIONS)):
    if m.check_mode:
        check_arg = '--simulate'
    else:
        check_arg = ''

    apt_cmd = None
    prompt_regex = None
    if mode == "dist" or (mode == "full" and use_apt_get):
        # apt-get dist-upgrade
        apt_cmd = APT_GET_CMD
        upgrade_command = "dist-upgrade"
    elif mode == "full" and not use_apt_get:
        # aptitude full-upgrade
        apt_cmd = APTITUDE_CMD
        upgrade_command = "full-upgrade"
    else:
        if use_apt_get:
            apt_cmd = APT_GET_CMD
            upgrade_command = "upgrade --with-new-pkgs --autoremove"
        else:
            # aptitude safe-upgrade # mode=yes # default
            apt_cmd = APTITUDE_CMD
            upgrade_command = "safe-upgrade"
            prompt_regex = r"(^Do you want to ignore this warning and proceed anyway\?|^\*\*\*.*\[default=.*\])"
```

Resolving patch:
diff --git a/lib/ansible/modules/packaging/os/apt.py b/lib/ansible/modules/packaging/os/apt.py
--- a/lib/ansible/modules/packaging/os/apt.py
+++ b/lib/ansible/modules/packaging/os/apt.py
@@ -722,7 +722,13 @@ def cleanup(m, purge=False, force=False, operation=None,
 
 def upgrade(m, mode="yes", force=False, default_release=None,
             use_apt_get=False,
-            dpkg_options=expand_dpkg_options(DPKG_OPTIONS)):
+            dpkg_options=expand_dpkg_options(DPKG_OPTIONS), autoremove=None):
+
+    if autoremove:
+        autoremove = '--auto-remove'
+    else:
+        autoremove = ''
+
     if m.check_mode:
         check_arg = '--simulate'
     else:
@@ -741,7 +747,7 @@ def upgrade(m, mode="yes", force=False, default_release=None,
     else:
         if use_apt_get:
             apt_cmd = APT_GET_CMD
-            upgrade_command = "upgrade --with-new-pkgs --autoremove"
+            upgrade_command = "upgrade --with-new-pkgs %s" % (autoremove)
         else:
             # aptitude safe-upgrade # mode=yes # default
             apt_cmd = APTITUDE_CMD
@@ -975,7 +981,7 @@ def main():
         force_yes = p['force']
 
         if p['upgrade']:
-            upgrade(module, p['upgrade'], force_yes, p['default_release'], use_apt_get, dpkg_options)
+            upgrade(module, p['upgrade'], force_yes, p['default_release'], use_apt_get, dpkg_options, autoremove)
 
         if p['deb']:
             if p['state'] != 'present':
@@ -995,7 +1001,7 @@ def main():
         if latest and all_installed:
             if packages:
                 module.fail_json(msg='unable to install additional packages when ugrading all installed packages')
-            upgrade(module, 'yes', force_yes, p['default_release'], use_apt_get, dpkg_options)
+            upgrade(module, 'yes', force_yes, p['default_release'], use_apt_get, dpkg_options, autoremove)
 
         if packages:
             for package in packages:


Test patch: