Repository: ansible/ansible

Issue:
Installing package groups using "state: latest" with yum module is not idempotent
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and devel branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
 - Bug Report

##### COMPONENT NAME
<!---
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
-->
yum_module
##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.4.3.0
  config file = /Users/username/.ansible.cfg
  configured module search path = [u'/Users/username/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python2.7/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.13 (default, Mar 13 2017, 14:30:52) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]
```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste 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_BECOME_ASK_PASS(/Users/username/.ansible.cfg) = True
DEFAULT_GATHERING(/Users/username/.ansible.cfg) = smart
DEFAULT_HOST_LIST(/Users/username/.ansible.cfg) = [u'/Users/username/Git/mw-ansible-defaults/inventory/hosts']
DEFAULT_REMOTE_TMP(/Users/username/.ansible.cfg) = /tmp/.ansible-${USER}/tmp
DEFAULT_VAULT_PASSWORD_FILE(/Users/username/.ansible.cfg) = /Users/username/.ansible/vaultpass
HOST_KEY_CHECKING(/Users/username/.ansible.cfg) = False
```

##### 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.
-->
Source: Mac OS 10.13.2 and Ansible Tower (RHEL 7.4)
Dest: RHEL 7.4 and RHEL 6.9

##### SUMMARY
<!--- Explain the problem briefly -->
When using the yum module to install and update a package group (using `state: latest`), the task always returns as changed, even if nothing changed on the system. This task should be idempotent if nothing changes on the host. 

##### 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.
-->
The process to reproduce is to run the very simple playbook below twice on a RHEL host which hasn't previously installed the "Development tools" package group or run the very simple playbook once on a RHEL host which already has the "Development tools" package group installed.

<!--- Paste example playbooks or commands between quotes below -->
```yaml
---
- hosts: <insert inventory group name>
  tasks:
    - name: Demonstrate yum groupinstall bug
      yum:
        name: "@development"
        state: latest
```

<!--- 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 would expect for the first run to result in "changed" and the second run would result in "ok".
##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
Instead, the first run results in "changed" and the second run results in "changed" even though nothing changed on the second run. Because of the length, I only included the second run's output since that demonstrates the bug. Because of the concern of inadvertent information disclosure, I was only able to run the command with `-vv`. 
<!--- Paste verbatim command output between quotes below -->
```
ansible-playbook 2.4.3.0
  config file = /Users/username/.ansible.cfg
  configured module search path = [u'/Users/username/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python2.7/site-packages/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 2.7.13 (default, Mar 13 2017, 14:30:52) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]
Using /Users/username/.ansible.cfg as config file
SUDO password:

PLAYBOOK: mw_bug.yml *************************************************************************************************************************************************************************************************************************
1 plays in mw_bug.yml

PLAY [web] ***********************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [host.example.com]
META: ran handlers

TASK [Demonstrate yum groupinstall bug] ******************************************************************************************************************************************************************************************************
task path: /Users/username/Git/mw-ansible-webhosting/mw_bug.yml:4
changed: [host.example.com] => {"changed": true, "msg": "Warning: Group development does not have any packages.\n", "rc": 0, "results": ["Loaded plugins: enabled_repos_upload, package_upload, product-id, search-\n              : disabled-repos, security\nSetting up Install Process\nPackage flex-2.5.35-9.el6.x86_64 already installed and latest version\nPackage gcc-4.4.7-18.el6.x86_64 already installed and latest version\nPackage autoconf-2.63-5.1.el6.noarch already installed and latest version\nPackage redhat-rpm-config-9.0.3-51.el6.noarch already installed and latest version\nPackage rpm-build-4.8.0-55.el6.x86_64 already installed and latest version\nPackage 1:make-3.81-23.el6.x86_64 already installed and latest version\nPackage 1:pkgconfig-0.23-9.1.el6.x86_64 already installed and latest version\nPackage gettext-0.17-18.el6.x86_64 already installed and latest version\nPackage patch-2.6-6.el6.x86_64 already installed and latest version\nPackage bison-2.4.1-5.el6.x86_64 already installed and latest version\nPackage libtool-2.2.6-15.5.el6.x86_64 already installed and latest version\nPackage automake-1.11.1-4.el6.noarch already installed and latest version\nPackage gcc-c++-4.4.7-18.el6.x86_64 already installed and latest version\nPackage binutils-2.20.51.0.2-5.47.el6_9.1.x86_64 already installed and latest version\nPackage byacc-1.9.20070509-7.el6.x86_64 already installed and latest version\nPackage indent-2.2.10-7.el6.x86_64 already installed and latest version\nPackage systemtap-2.9-7.el6.x86_64 already installed and latest version\nPackage diffstat-1.51-2.el6.x86_64 already installed and latest version\nPackage elfutils-0.164-2.el6.x86_64 already installed and latest version\nPackage 1:doxygen-1.6.1-6.el6.x86_64 already installed and latest version\nPackage cvs-1.11.23-16.el6.x86_64 already installed and latest version\nPackage rcs-5.7-37.el6.x86_64 already installed and latest version\nPackage subversion-1.6.11-15.el6_7.x86_64 already installed and latest version\nPackage gcc-gfortran-4.4.7-18.el6.x86_64 already installed and latest version\nPackage patchutils-0.3.1-3.1.el6.x86_64 already installed and latest version\nPackage intltool-0.41.0-1.1.el6.noarch already installed and latest version\nPackage ctags-5.8-2.el6.x86_64 already installed and latest version\nPackage git-1.7.1-9.el6_9.x86_64 already installed and latest version\nPackage cscope-15.6-7.el6.x86_64 already installed and latest version\nPackage swig-1.3.40-6.el6.x86_64 already installed and latest version\nNothing to do\nUploading Enabled Repositories Report\nLoaded plugins: product-id\n"]}
META: ran handlers
META: ran handlers

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
host.example.com    : ok=2    changed=1    unreachable=0    failed=0
```


Discussion:
Files identified in the description:
* [lib/ansible/modules/packaging/os/yum.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/packaging/os/yum.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 @Akasurde @berenddeschouwer @mkrizek @verm666
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/lib/ansible/modules/packaging/os/yum.py b/lib/ansible/modules/packaging/os/yum.py
--- a/lib/ansible/modules/packaging/os/yum.py
+++ b/lib/ansible/modules/packaging/os/yum.py
@@ -770,7 +770,7 @@ def exec_install(module, items, action, pkgs, res, yum_basecmd):
     res['msg'] += err
     res['changed'] = True
 
-    if ('Nothing to do' in out and rc == 0) or ('does not have any packages to install' in err):
+    if ('Nothing to do' in out and rc == 0) or ('does not have any packages' in err):
         res['changed'] = False
 
     if rc != 0:


Test patch: