From 1cae0a6801e0f9cfdffca020ee79298060e39718 Mon Sep 17 00:00:00 2001 From: Gabe Mulley Date: Sat, 4 Jan 2014 11:33:43 -0500 Subject: [PATCH] add a module for update-alternatives --- library/system/alternatives | 137 ++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100755 library/system/alternatives diff --git a/library/system/alternatives b/library/system/alternatives new file mode 100755 index 0000000000..3cbf4c8315 --- /dev/null +++ b/library/system/alternatives @@ -0,0 +1,137 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +""" +Ansible module to manage symbolic link alternatives. +(c) 2014, Gabe Mulley + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Ansible is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Ansible. If not, see . +""" + +DOCUMENTATION = ''' +--- +module: alternatives +short_description: Manages symbolic links +description: + - Manages symbolic links using the 'update-alternatives' tool provided on debian-like systems. + - Useful when multiple programs are installed but provide similar functionality (e.g. different editors). +version_added: "1.5" +options: + name: + description: + - The generic name of the link. + required: true + path: + description: + - The path to the real executable that the link should point to. + required: true + link: + description: + - The path to the symbolic link that should point to the real executable. + required: false +requirements: [ update-alternatives ] +''' + +EXAMPLES = ''' +- name: correct java version selected + alternatives: name=java path=/usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java + +- name: alternatives link created + alternatives: name=hadoop-conf link=/etc/hadoop/conf path=/etc/hadoop/conf.ansible +''' + +UPDATE_ALTERNATIVES = '/usr/sbin/update-alternatives' +DEFAULT_LINK_PRIORITY = 50 + +def main(): + + module = AnsibleModule( + argument_spec = dict( + name = dict(required=True), + path = dict(required=True), + link = dict(required=False), + ) + ) + + params = module.params + name = params['name'] + path = params['path'] + link = params['link'] + + current_path = None + all_alternatives = [] + + (rc, query_output, query_error) = module.run_command( + [UPDATE_ALTERNATIVES, '--query', name] + ) + + # Gather the current setting and all alternatives from the query output. + # Query output should look something like this: + + # 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: + 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) + + if current_path != path: + try: + # install the requested path if necessary + if path not in all_alternatives: + module.run_command( + [UPDATE_ALTERNATIVES, '--install', link, name, path, str(DEFAULT_LINK_PRIORITY)], + check_rc=True + ) + + # select the requested path + module.run_command( + [UPDATE_ALTERNATIVES, '--set', name, path], + check_rc=True + ) + + module.exit_json(changed=True) + except subprocess.CalledProcessError as cpe: + module.fail_json(msg=str(dir(cpe))) + else: + module.exit_json(changed=False) + + +# import module snippets +from ansible.module_utils.basic import * +main()