Repository: ansible/ansible-modules-core

Issue:
Random line wraps breaking the yum module, disabling updating packages.
<!--- Verify first that your issue/request is not already reported in GitHub -->
##### ISSUE TYPE

<!--- Pick one below and delete the rest: -->
- Bug Report
##### COMPONENT NAME

yum.py file in packaging module
##### ANSIBLE VERSION

<!--- Paste verbatim output from “ansible --version” between quotes below -->

```
ansible 2.2.0
```
##### OS / ENVIRONMENT

Red Hat Enterprise Linux Server release 6.7
##### SUMMARY

Issue lies in the following snippet in yum.py file:

```
rc, out, err = module.run_command(yum_basecmd + ['check-update'])
    if rc == 0 and update_all:
        res['results'].append('Nothing to do here, all packages are up to date')
        return res
    elif rc == 100:
        available_updates = out.split('\n')
        # build update dictionary
        for line in available_updates:
            line = line.split()
            # ignore irrelevant lines
            # FIXME... revisit for something less kludgy
            if '*' in line or len(line) != 3 or '.' not in line[0]:
                continue
            else:
                pkg, version, repo = line
                name, dist = pkg.rsplit('.', 1)
                updates.update({name: {'version': version, 'dist': dist, 'repo': repo}})
```

The run_command in the first line of the snippet executes more or less (with some additional flags) the comman `yum check-update`. When updates exist, it returns code 100. Then there is a splitting by `\n` character, which is supposed to leave array of 3 elements: package name, version and repository. If one of them is too long, there is some line wrapping used and it is followed by an additional `\n` character and this way the whole package gets filtered out by `len(line) != 3` condition. 

This way the ansible claims in the resulting json that

>  "results": ["All packages providing my-package-with-a-very-long-name-and-version are up to date"
##### STEPS TO REPRODUCE

Use the following playbook to UPDATE the existing package, that has a very long version number (eg. a lot of digits).

```
- name: Install my-package-with-a-very-long-name-and-version rpm
  yum: name=my-package-with-a-very-long-name-and-version state=latest
```
##### EXPECTED RESULTS

Detecting the new version of a package and updating it.
##### ACTUAL RESULTS

> "results": ["All packages providing my-package-with-a-very-long-name-and-version are up to date"



Discussion:
<!-- @TheMP: Thanks for filing this bug report! -->

@ansible ping, this issue is waiting for your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_bug_new --->

I've also encountered this issue. When I added some debugging output I see the following...

Where every three lines is raw_line, splitted line, action.

```
    "log": [
        "Loaded plugins: langpacks, product-id, rhnplugin, search-disabled-repos,",
        "['Loaded', 'plugins:', 'langpacks,', 'product-id,', 'rhnplugin,', 'search-disabled-repos,']",
        "Skipped",
        "              : subscription-manager",
        "[':', 'subscription-manager']",
        "Skipped",
        "This system is receiving updates from RHN Classic or Red Hat Satellite.",
        "['This', 'system', 'is', 'receiving', 'updates', 'from', 'RHN', 'Classic', 'or', 'Red', 'Hat', 'Satellite.']",
        "Skipped",
        "",
        "[]",
        "Skipped",
        "very-long-service.noarch       3.1.3.1.0-0.18.SNAPSHOT_3.el7.centos",
        "['very-long-service.noarch', '3.1.3.1.0-0.18.SNAPSHOT_3.el7.centos']",
        "Skipped",
        "                                                    dev-tw-custom-centos7-x86_64",
        "['dev-tw-custom-centos7-x86_64']",
        "Skipped",
        "bash.x86_64                4.2.46-20.el7_2          updates                     ",
        "['bash.x86_64', '4.2.46-20.el7_2', 'updates']",
        "Processed",
```

I'm thinking the use of repoquery --show-duplicates --plugins $spec might be a better approach. 

Reproduced this with devel/

I don't see any way to prevent 'check-update' from line wrapping.

'yum list updates' doesn't wrap, but has some noise in it as well (especially with a LANG set).

'repoquery --pkgnarrow=updates '*''  seems closer
(sample output)

```
[rhel-7.2:src]$ repoquery --pkgnarrow=updates '*'
collectd-0:5.5.2-1.el7.x86_64
collectd-mysql-0:5.5.2-1.el7.x86_64
epel-release-0:7-8.noarch
google-chrome-stable-0:52.0.2743.116-1.x86_64
htop-0:2.0.2-1.el7.x86_64
koji-0:1.10.1-24.2.el7.noarch
pyrpkg-0:1.46-1.el7.noarch
python2-boto-0:2.41.0-1.el7.noarch
python34-0:3.4.3-5.el7.x86_64
python34-debug-0:3.4.3-5.el7.x86_64
python34-devel-0:3.4.3-5.el7.x86_64
python34-libs-0:3.4.3-5.el7.x86_64
python34-test-0:3.4.3-5.el7.x86_64
python34-tkinter-0:3.4.3-5.el7.x86_64
python34-tools-0:3.4.3-5.el7.x86_64
v8-1:3.14.5.10-25.el7.x86_64
v8-devel-1:3.14.5.10-25.el7.x86_64
xfce-polkit-0:0.2-8.el7.x86_64
zanata-cli-bin-0:3.9.1-1.el7.noarch
```

Or likely, with a --queryformat like:

```
[rhel-7.2:src]$ repoquery --pkgnarrow=updates '*' --queryformat '%{NAME}\t%{VERSION}\t%{RELEASE}\t%{repoid}'
collectd    5.5.2   1.el7   epel
collectd-mysql  5.5.2   1.el7   epel
epel-release    7   8   epel
google-chrome-stable    52.0.2743.116   1   google-chrome
htop    2.0.2   1.el7   epel
koji    1.10.1  24.2.el7    rhpkg
pyrpkg  1.46    1.el7   epel
python2-boto    2.41.0  1.el7   epel
python34    3.4.3   5.el7   epel
python34-debug  3.4.3   5.el7   epel
python34-devel  3.4.3   5.el7   epel
python34-libs   3.4.3   5.el7   epel
python34-test   3.4.3   5.el7   epel
python34-tkinter    3.4.3   5.el7   epel
python34-tools  3.4.3   5.el7   epel
rpkg    1.46    1.el7   epel
v8  3.14.5.10   25.el7  epel
v8-devel    3.14.5.10   25.el7  epel
xfce-polkit 0.2 8.el7   epel
zanata-cli-bin  3.9.1   1.el7   epel-zanata
```

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->


Resolving patch:
diff --git a/packaging/os/yum.py b/packaging/os/yum.py
--- a/packaging/os/yum.py
+++ b/packaging/os/yum.py
@@ -796,6 +796,8 @@ def latest(module, items, repoq, yum_basecmd, conf_file, en_repos, dis_repos):
         res['results'].append('Nothing to do here, all packages are up to date')
         return res
     elif rc == 100:
+        # remove incorrect new lines in longer columns in output from yum check-update
+        out=re.sub('\n\W+', ' ', out)
         available_updates = out.split('\n')
         # build update dictionary
         for line in available_updates:


Test patch: