diff options
author | Michael DeHaan <michael.dehaan@gmail.com> | 2014-03-12 17:22:59 -0400 |
---|---|---|
committer | Michael DeHaan <michael@ansibleworks.com> | 2014-03-12 18:04:18 -0400 |
commit | e6b05da55b21736228183e42c3206be3d2815183 (patch) | |
tree | deb3898da6d944d885538778431cd2cc71cea972 | |
parent | 67387375187b1ca9ff95a886a403dbeef169f6de (diff) | |
download | ansible-e6b05da55b21736228183e42c3206be3d2815183.tar.gz |
More shell updates
Conflicts:
library/system/debconf
-rw-r--r-- | library/system/cron | 18 | ||||
-rw-r--r-- | library/system/debconf | 169 | ||||
-rw-r--r-- | library/system/hostname | 2 | ||||
-rw-r--r-- | library/system/lvg | 8 |
4 files changed, 184 insertions, 13 deletions
diff --git a/library/system/cron b/library/system/cron index 39727b4c76..15c21fb157 100644 --- a/library/system/cron +++ b/library/system/cron @@ -145,6 +145,7 @@ import os import re import tempfile import platform +import pipes CRONCMD = "/usr/bin/crontab" @@ -190,7 +191,8 @@ class CronTab(object): except: raise CronTabError("Unexpected error:", sys.exc_info()[0]) else: - (rc, out, err) = self.module.run_command(self._read_user_execute()) + # using safely quoted shell for now, but this really should be two non-shell calls instead. FIXME + (rc, out, err) = self.module.run_command(self._read_user_execute(), use_unsafe_shell=True) if rc != 0 and rc != 1: # 1 can mean that there are no jobs. raise CronTabError("Unable to read crontab") @@ -235,8 +237,8 @@ class CronTab(object): # Add the entire crontab back to the user crontab if not self.cron_file: - # os.system(self._write_execute(path)) - (rc, out, err) = self.module.run_command(self._write_execute(path)) + # quoting shell args for now but really this should be two non-shell calls. FIXME + (rc, out, err) = self.module.run_command(self._write_execute(path), use_unsafe_shell=True) os.unlink(path) if rc != 0: @@ -350,9 +352,9 @@ class CronTab(object): user = '' if self.user: if platform.system() == 'SunOS': - return "su '%s' -c '%s -l'" % (self.user, CRONCMD) + return "su %s -c '%s -l'" % (pipes.quote(self.user), pipes.quote(CRONCMD)) else: - user = '-u %s' % self.user + user = '-u %s' % pipes.quote(self.user) return "%s %s %s" % (CRONCMD , user, '-l') def _write_execute(self, path): @@ -362,10 +364,10 @@ class CronTab(object): user = '' if self.user: if platform.system() == 'SunOS': - return "chown %s %s ; su '%s' -c '%s %s'" % (self.user, path, self.user, CRONCMD, path) + return "chown %s %s ; su '%s' -c '%s %s'" % (pipes.quote(self.user), pipes.quote(path), pipes.quote(self.user), CRONCMD, pipes.quote(path)) else: - user = '-u %s' % self.user - return "%s %s %s" % (CRONCMD , user, path) + user = '-u %s' % pipes.quote(self.user) + return "%s %s %s" % (CRONCMD , user, pipes.quote(path)) diff --git a/library/system/debconf b/library/system/debconf new file mode 100644 index 0000000000..244561973d --- /dev/null +++ b/library/system/debconf @@ -0,0 +1,169 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +""" +Ansible module to configure .deb packages. +(c) 2014, Brian Coca <briancoca+ansible@gmail.com> + +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 <http://www.gnu.org/licenses/>. +""" + +DOCUMENTATION = ''' +--- +module: debconf +short_description: Configure a .deb package +description: + - Configure a .deb package using debconf-set-selections. Or just query + existing selections. +version_added: "1.6" +notes: + - This module requires the command line debconf tools. + - A number of questions have to be answered (depending on the package). + Use 'debconf-show <package>' on any Debian or derivative with the package + installed to see questions/settings available. +options: + name: + description: + - Name of package to configure. + required: true + default: null + aliases: ['pkg'] + question: + description: + - A debconf configuration setting + required: false + default: null + aliases: ['setting', 'selection'] + vtype: + description: + - The type of the value supplied + required: false + default: null + choices: [string, boolean, select, multiselect, note, text, password, title] + aliases: [] + value: + description: + - Value to set the configuration to + required: false + default: null + aliases: ['answer'] + unseen: + description: + - Do not set 'seen' flag when pre-seeding + required: false + default: False + aliases: [] +author: Brian Coca + +''' + +EXAMPLES = ''' +# Set default locale to fr_FR.UTF-8 +debconf: name=locales question='locales/default_environment_locale' value=fr_FR.UTF-8 + +# set to generate locales: +debconf: name=locales question='locales/locales_to_be_generated value='en_US.UTF-8 UTF-8, fr_FR.UTF-8 UTF-8' + +# Accept oracle license +debconf: name='oracle-java7-installer' question='shared/accepted-oracle-license-v1-1' value='true' vtype='select' + +# Specifying package you can register/return the list of questions and current values +debconf: name='tzdata' +''' + +import pipes + +def get_selections(module, pkg): + cmd = [module.get_bin_path('debconf-show', True), pkg] + rc, out, err = module.run_command(' '.join(cmd)) + + if rc != 0: + module.fail_json(msg=err) + + selections = {} + + for line in out.splitlines(): + (key, value) = line.split(':') + selections[ key.strip('*').strip() ] = value.strip() + + return selections + + +def set_selection(module, pkg, question, vtype, value, unseen): + + data = ' '.join([ question, vtype, value ]) + + setsel = module.get_bin_path('debconf-set-selections', True) + cmd = ["echo '%s %s' |" % (pipes.quote(pkg), pipes.quote(data)), setsel] + if unseen: + cmd.append('-u') + + return module.run_command(' '.join(cmd), use_unsafe_shell=True) + +def main(): + + module = AnsibleModule( + argument_spec = dict( + name = dict(required=True, aliases=['pkg'], type='str'), + question = dict(required=False, aliases=['setting', 'selection'], type='str'), + vtype = dict(required=False, type='str', choices=['string', 'boolean', 'select', 'multiselect', 'note', 'text', 'password', 'title']), + value= dict(required=False, type='str'), + unseen = dict(required=False, type='bool'), + ), + required_together = ( ['question','vtype', 'value'],), + supports_check_mode=True, + ) + + #TODO: enable passing array of optionas and/or debconf file from get-selections dump + pkg = module.params["name"] + question = module.params["question"] + vtype = module.params["vtype"] + value = module.params["value"] + unseen = module.params["unseen"] + + prev = get_selections(module, pkg) + diff = '' + + changed = False + msg = "" + + if question is not None: + if vtype is None or value is None: + module.fail_json(msg="when supliying a question you must supply a valide vtype and value") + + if not question in prev or prev[question] != value: + changed = True + + if changed: + if not module.check_mode: + rc, msg, e = set_selection(module, pkg, question, vtype, value, unseen) + if rc: + module.fail_json(msg=e) + + curr = { question: value } + if question in prev: + prev = {question: prev[question]} + else: + prev[question] = '' + + module.exit_json(changed=changed, msg=msg, current=curr, previous=prev) + + module.exit_json(changed=changed, msg=msg, current=prev) + +# import module snippets +from ansible.module_utils.basic import * + +main() diff --git a/library/system/hostname b/library/system/hostname index 781bdcd08a..cca2364b61 100644 --- a/library/system/hostname +++ b/library/system/hostname @@ -286,7 +286,7 @@ class FedoraStrategy(GenericStrategy): def get_permanent_hostname(self): cmd = 'hostnamectl status | awk \'/^ *Static hostname:/{printf("%s", $3)}\'' - rc, out, err = self.module.run_command(cmd) + rc, out, err = self.module.run_command(cmd, use_unsafe_shell=True) if rc != 0: self.module.fail_json(msg="Command failed rc=%d, out=%s, err=%s" % (rc, out, err)) diff --git a/library/system/lvg b/library/system/lvg index 4e24b25a5c..bc4709e3b1 100644 --- a/library/system/lvg +++ b/library/system/lvg @@ -162,13 +162,13 @@ def main(): ### create PV pvcreate_cmd = module.get_bin_path('pvcreate', True) for current_dev in dev_list: - rc,_,err = module.run_command("%s %s"%(pvcreate_cmd,current_dev)) + rc,_,err = module.run_command("%s %s" % (pvcreate_cmd,current_dev)) if rc == 0: changed = True else: - module.fail_json(msg="Creating physical volume '%s' failed"%current_dev, rc=rc, err=err) + module.fail_json(msg="Creating physical volume '%s' failed" % current_dev, rc=rc, err=err) vgcreate_cmd = module.get_bin_path('vgcreate') - rc,_,err = module.run_command("%s -s %s %s %s"%(vgcreate_cmd, pesize, vg, dev_string)) + rc,_,err = module.run_command("%s -s %s %s %s" % (vgcreate_cmd, pesize, vg, dev_string)) if rc == 0: changed = True else: @@ -210,7 +210,7 @@ def main(): module.fail_json(msg="Creating physical volume '%s' failed"%current_dev, rc=rc, err=err) ### add PV to our VG vgextend_cmd = module.get_bin_path('vgextend', True) - rc,_,err = module.run_command("%s %s %s"%(vgextend_cmd, vg, devs_to_add_string)) + rc,_,err = module.run_command("%s %s %s" % (vgextend_cmd, vg, devs_to_add_string)) if rc == 0: changed = True else: |