@ -4,6 +4,7 @@
"""
Ansible module to manage symbolic link alternatives .
( c ) 2014 , Gabe Mulley < gabe . mulley @gmail.com >
( c ) 2015 , David Wittman < dwittman @gmail.com >
This file is part of Ansible
@ -26,7 +27,7 @@ DOCUMENTATION = '''
module : alternatives
short_description : Manages alternative programs for common commands
description :
- Manages symbolic links using the ' update-alternatives ' tool provided on debian - like systems .
- Manages symbolic links using the ' update-alternatives ' tool
- Useful when multiple programs are installed but provide similar functionality ( e . g . different editors ) .
version_added : " 1.6 "
options :
@ -41,6 +42,7 @@ options:
link :
description :
- The path to the symbolic link that should point to the real executable .
- This option is required on RHEL - based distributions
required : false
requirements : [ update - alternatives ]
'''
@ -55,12 +57,14 @@ EXAMPLES = '''
DEFAULT_LINK_PRIORITY = 50
import re
def main ( ) :
module = AnsibleModule (
argument_spec = dict (
name = dict ( required = True ) ,
path = dict ( required = True ) ,
path = dict ( required = True ) ,
link = dict ( required = False ) ,
) ,
supports_check_mode = True ,
@ -71,78 +75,55 @@ def main():
path = params [ ' path ' ]
link = params [ ' link ' ]
UPDATE_ALTERNATIVES = module . get_bin_path ( ' update-alternatives ' , True )
UPDATE_ALTERNATIVES = module . get_bin_path ( ' update-alternatives ' , True )
current_path = None
all_alternatives = [ ]
os_family = None
( rc , query_output , query_error ) = module . run_command (
[ UPDATE_ALTERNATIVES , ' --query ' , name ]
# Run `update-alternatives --display <name>` to find existing alternatives
( rc , display_output , _ ) = module . run_command (
[ UPDATE_ALTERNATIVES , ' --display ' , name ]
)
# Gather the current setting and all alternatives from the query output.
# Query output should look something like this on Debian systems:
# Name: java
# Link: /usr/bin/java
# Slaves:
# java.1.gz /usr/share/man/man1/java.1.gz
# Status: manual
# Best: /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
# Value: /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java
# Alternative: /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java
# Priority: 1061
# Slaves:
# java.1.gz /usr/lib/jvm/java-6-openjdk-amd64/jre/man/man1/java.1.gz
# Alternative: /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
# Priority: 1071
# Slaves:
# java.1.gz /usr/lib/jvm/java-7-openjdk-amd64/jre/man/man1/java.1.gz
if rc == 0 :
os_family = " Debian "
for line in query_output . splitlines ( ) :
split_line = line . split ( ' : ' )
if len ( split_line ) == 2 :
key = split_line [ 0 ]
value = split_line [ 1 ] . strip ( )
if key == ' Value ' :
current_path = value
elif key == ' Alternative ' :
all_alternatives . append ( value )
elif key == ' Link ' and not link :
link = value
elif rc == 2 :
os_family = " RedHat "
# This is the version of update-alternatives that is shipped with
# chkconfig on RedHat-based systems. Try again with the right options.
( rc , query_output , query_error ) = module . run_command (
[ UPDATE_ALTERNATIVES , ' --list ' ]
)
for line in query_output . splitlines ( ) :
line_name , line_mode , line_path = line . strip ( ) . split ( " \t " )
if line_name != name :
continue
current_path = line_path
break
# Alternatives already exist for this link group
# Parse the output to determine the current path of the symlink and
# available alternatives
current_path_regex = re . compile ( r ' ^ \ s*link currently points to (.*)$ ' ,
re . MULTILINE )
alternative_regex = re . compile ( r ' ^( \ /.*) \ s- \ spriority ' , re . MULTILINE )
current_path = current_path_regex . search ( display_output ) . group ( 1 )
all_alternatives = alternative_regex . findall ( display_output )
if not link :
# Read the current symlink target from `update-alternatives --query`
# in case we need to install the new alternative before setting it.
#
# This is only compatible on Debian-based systems, as the other
# alternatives don't have --query available
rc , query_output , _ = module . run_command (
[ UPDATE_ALTERNATIVES , ' --query ' , name ]
)
if rc == 0 :
for line in query_output . splitlines ( ) :
if line . startswith ( ' Link: ' ) :
link = line . split ( ) [ 1 ]
break
if current_path != path :
if module . check_mode :
module . exit_json ( changed = True , current_path = current_path )
try :
# install the requested path if necessary
# (unsupported on the RedHat version)
if path not in all_alternatives and os_family == " Debian " :
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 " )
if path not in all_alternatives :
if not link :
module . fail_json ( msg = " Needed to install the alternative, but unable to do so as we are missing the link " )
module . run_command (
[ UPDATE_ALTERNATIVES , ' --install ' , link , name , path , str ( DEFAULT_LINK_PRIORITY ) ] ,
check_rc = True
)
# select the requested path
module . run_command (
@ -151,7 +132,7 @@ def main():
)
module . exit_json ( changed = True )
except subprocess . CalledProcessError , cpe :
except subprocess . CalledProcessError as cpe :
module . fail_json ( msg = str ( dir ( cpe ) ) )
else :
module . exit_json ( changed = False )