Repository: ansible/ansible-modules-extras

Issue:
Alternatives module: "'NoneType' object has no attribute 'startswith'"
##### Issue Type:

Bug Report
##### Ansible Version:

1.7.2
##### Environment:
- Centos 5.5 (python 2.4.3 & python 2.6.8)
- Centos 6.5 (python 2.6.6)
##### Summary:

Alternatives module generates invalid python code on Centos 5 & 6
The error seems to be more related to the version of python than the OS as I get the same Centos 6 error on Centos 5 when specifying `ansible_python_interpreter` in the `/etc/ansible/hosts`
##### Steps To Reproduce:

```
    - yum: name=java-1.6.0-openjdk-devel state=installed
    - alternatives: name=java path=/usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/java
```
##### Expected Results:

Install java 1.6 and then configures the alternatives to point /usr/bin/java to the 1.6 version 
##### Actual Results:

```
fatal: [Centos6] => failed to parse: Traceback (most recent call last):
  File "/tmp/.ansible/tmp/ansible-tmp-1412275620.84-98969527997889/alternatives", line 1486, in <module>
    main()
  File "/tmp/.ansible/tmp/ansible-tmp-1412275620.84-98969527997889/alternatives", line 122, in main
    check_rc=True
  File "/tmp/.ansible/tmp/ansible-tmp-1412275620.84-98969527997889/alternatives", line 1339, in run_command
    args = [ os.path.expandvars(os.path.expanduser(x)) for x in args ]
  File "/usr/lib64/python2.6/posixpath.py", line 251, in expanduser
    if not path.startswith('~'):
AttributeError: 'NoneType' object has no attribute 'startswith'

failed: [Centos5] => {"failed": true, "parsed": false}
invalid output was: Traceback (most recent call last):
  File "/tmp/.ansible/tmp/ansible-tmp-1412275620.83-139068779696675/alternatives", line 1486, in ?
    main()
  File "/tmp/.ansible/tmp/ansible-tmp-1412275620.83-139068779696675/alternatives", line 132, in main
    except subprocess.CalledProcessError, cpe:
AttributeError: 'module' object has no attribute 'CalledProcessError'


FATAL: all hosts have already failed -- aborting
```

When using python26 on Centos5:

```
fatal: [Centos5] => failed to parse: Traceback (most recent call last):
  File "/tmp/.ansible/tmp/ansible-tmp-1412275580.11-200946814475830/alternatives", line 1486, in <module>
    main()
  File "/tmp/.ansible/tmp/ansible-tmp-1412275580.11-200946814475830/alternatives", line 122, in main
    check_rc=True
  File "/tmp/.ansible/tmp/ansible-tmp-1412275580.11-200946814475830/alternatives", line 1339, in run_command
    args = [ os.path.expandvars(os.path.expanduser(x)) for x in args ]
  File "/usr/lib64/python2.6/posixpath.py", line 251, in expanduser
    if not path.startswith('~'):
AttributeError: 'NoneType' object has no attribute 'startswith'
```

I also get the same `No module named yum` as reported in [this question](https://groups.google.com/forum/#!msg/ansible-project/yNWKzV5F-QU/e-vkWJKf6tQJ)



Discussion:
This looks like a duplicate of https://github.com/ansible/ansible/issues/7414

Specifying the link solves the problem:

```
 - alternatives: name=java path=/usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/java link=/usr/bin/java
```

However, the patch ansible/ansible@cbea442ec217725cb101cffc96be563cd5f585f0 doesn't seems to have resolved the problem cc @jimi-c


Resolving patch:
diff --git a/system/alternatives.py b/system/alternatives.py
--- a/system/alternatives.py
+++ b/system/alternatives.py
@@ -136,10 +136,13 @@ def main():
             # install the requested path if necessary
             # (unsupported on the RedHat version)
             if path not in all_alternatives and os_family == "Debian":
-                module.run_command(
-                    [UPDATE_ALTERNATIVES, '--install', link, name, path, str(DEFAULT_LINK_PRIORITY)],
-                    check_rc=True
-                )
+                if link:
+                    module.run_command(
+                        [UPDATE_ALTERNATIVES, '--install', link, name, path, str(DEFAULT_LINK_PRIORITY)],
+                        check_rc=True
+                    )
+                else:
+                    module.fail_json("Needed to install the alternative, but unable to do so, as we are missking the link")
 
             # select the requested path
             module.run_command(


Test patch: