diff options
Diffstat (limited to 'library/system/sysctl')
-rw-r--r-- | library/system/sysctl | 334 |
1 files changed, 0 insertions, 334 deletions
diff --git a/library/system/sysctl b/library/system/sysctl deleted file mode 100644 index acf6395f07..0000000000 --- a/library/system/sysctl +++ /dev/null @@ -1,334 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2012, David "DaviXX" CHANIAL <david.chanial@gmail.com> -# (c) 2014, James Tanner <tanner.jc@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: sysctl -short_description: Manage entries in sysctl.conf. -description: - - This module manipulates sysctl entries and optionally performs a C(/sbin/sysctl -p) after changing them. -version_added: "1.0" -options: - name: - description: - - The dot-separated path (aka I(key)) specifying the sysctl variable. - required: true - default: null - aliases: [ 'key' ] - value: - description: - - Desired value of the sysctl key. - required: false - default: null - aliases: [ 'val' ] - state: - description: - - Whether the entry should be present or absent in the sysctl file. - choices: [ "present", "absent" ] - default: present - ignoreerrors: - description: - - Use this option to ignore errors about unknown keys. - choices: [ "yes", "no" ] - default: no - reload: - description: - - If C(yes), performs a I(/sbin/sysctl -p) if the C(sysctl_file) is - updated. If C(no), does not reload I(sysctl) even if the - C(sysctl_file) is updated. - choices: [ "yes", "no" ] - default: "yes" - sysctl_file: - description: - - Specifies the absolute path to C(sysctl.conf), if not C(/etc/sysctl.conf). - required: false - default: /etc/sysctl.conf - sysctl_set: - description: - - Verify token value with the sysctl command and set with -w if necessary - choices: [ "yes", "no" ] - required: false - version_added: 1.5 - default: False -notes: [] -requirements: [] -author: David "DaviXX" CHANIAL <david.chanial@gmail.com> -''' - -EXAMPLES = ''' -# Set vm.swappiness to 5 in /etc/sysctl.conf -- sysctl: name=vm.swappiness value=5 state=present - -# Remove kernel.panic entry from /etc/sysctl.conf -- sysctl: name=kernel.panic state=absent sysctl_file=/etc/sysctl.conf - -# Set kernel.panic to 3 in /tmp/test_sysctl.conf -- sysctl: name=kernel.panic value=3 sysctl_file=/tmp/test_sysctl.conf reload=no - -# Set ip fowarding on in /proc and do not reload the sysctl file -- sysctl: name="net.ipv4.ip_forward" value=1 sysctl_set=yes - -# Set ip forwarding on in /proc and in the sysctl file and reload if necessary -- sysctl: name="net.ipv4.ip_forward" value=1 sysctl_set=yes state=present reload=yes -''' - -# ============================================================== - -import os -import tempfile -import re - -class SysctlModule(object): - - def __init__(self, module): - self.module = module - self.args = self.module.params - - self.sysctl_cmd = self.module.get_bin_path('sysctl', required=True) - self.sysctl_file = self.args['sysctl_file'] - - self.proc_value = None # current token value in proc fs - self.file_value = None # current token value in file - self.file_lines = [] # all lines in the file - self.file_values = {} # dict of token values - - self.changed = False # will change occur - self.set_proc = False # does sysctl need to set value - self.write_file = False # does the sysctl file need to be reloaded - - self.process() - - # ============================================================== - # LOGIC - # ============================================================== - - def process(self): - - # Whitespace is bad - self.args['name'] = self.args['name'].strip() - self.args['value'] = self._parse_value(self.args['value']) - - thisname = self.args['name'] - - # get the current proc fs value - self.proc_value = self.get_token_curr_value(thisname) - - # get the currect sysctl file value - self.read_sysctl_file() - if thisname not in self.file_values: - self.file_values[thisname] = None - - # update file contents with desired token/value - self.fix_lines() - - # what do we need to do now? - if self.file_values[thisname] is None and self.args['state'] == "present": - self.changed = True - self.write_file = True - elif self.file_values[thisname] is None and self.args['state'] == "absent": - self.changed = False - elif self.file_values[thisname] != self.args['value']: - self.changed = True - self.write_file = True - - # use the sysctl command or not? - if self.args['sysctl_set']: - if self.proc_value is None: - self.changed = True - elif not self._values_is_equal(self.proc_value, self.args['value']): - self.changed = True - self.set_proc = True - - # Do the work - if not self.module.check_mode: - if self.write_file: - self.write_sysctl() - if self.write_file and self.args['reload']: - self.reload_sysctl() - if self.set_proc: - self.set_token_value(self.args['name'], self.args['value']) - - def _values_is_equal(self, a, b): - """Expects two string values. It will split the string by whitespace - and compare each value. It will return True if both lists are the same, - contain the same elements and the same order.""" - if a is None or b is None: - return False - - a = a.split() - b = b.split() - - if len(a) != len(b): - return False - - return len([i for i, j in zip(a, b) if i == j]) == len(a) - - def _parse_value(self, value): - if value is None: - return '' - elif value.lower() in BOOLEANS_TRUE: - return '1' - elif value.lower() in BOOLEANS_FALSE: - return '0' - else: - return value.strip() - - # ============================================================== - # SYSCTL COMMAND MANAGEMENT - # ============================================================== - - # Use the sysctl command to find the current value - def get_token_curr_value(self, token): - thiscmd = "%s -e -n %s" % (self.sysctl_cmd, token) - rc,out,err = self.module.run_command(thiscmd) - if rc != 0: - return None - else: - return out - - # Use the sysctl command to set the current value - def set_token_value(self, token, value): - if len(value.split()) > 0: - value = '"' + value + '"' - thiscmd = "%s -w %s=%s" % (self.sysctl_cmd, token, value) - rc,out,err = self.module.run_command(thiscmd) - if rc != 0: - self.module.fail_json(msg='setting %s failed: %s' % (token, out + err)) - else: - return rc - - # Run sysctl -p - def reload_sysctl(self): - # do it - if get_platform().lower() == 'freebsd': - # freebsd doesn't support -p, so reload the sysctl service - rc,out,err = self.module.run_command('/etc/rc.d/sysctl reload') - else: - # system supports reloading via the -p flag to sysctl, so we'll use that - sysctl_args = [self.sysctl_cmd, '-p', self.sysctl_file] - if self.args['ignoreerrors']: - sysctl_args.insert(1, '-e') - - rc,out,err = self.module.run_command(sysctl_args) - - if rc != 0: - self.module.fail_json(msg="Failed to reload sysctl: %s" % str(out) + str(err)) - - # ============================================================== - # SYSCTL FILE MANAGEMENT - # ============================================================== - - # Get the token value from the sysctl file - def read_sysctl_file(self): - - lines = [] - if os.path.isfile(self.sysctl_file): - try: - f = open(self.sysctl_file, "r") - lines = f.readlines() - f.close() - except IOError, e: - self.module.fail_json(msg="Failed to open %s: %s" % (self.sysctl_file, str(e))) - - for line in lines: - line = line.strip() - self.file_lines.append(line) - - # don't split empty lines or comments - if not line or line.startswith("#"): - continue - - k, v = line.split('=',1) - k = k.strip() - v = v.strip() - self.file_values[k] = v.strip() - - # Fix the value in the sysctl file content - def fix_lines(self): - checked = [] - self.fixed_lines = [] - for line in self.file_lines: - if not line.strip() or line.strip().startswith("#"): - self.fixed_lines.append(line) - continue - tmpline = line.strip() - k, v = line.split('=',1) - k = k.strip() - v = v.strip() - if k not in checked: - checked.append(k) - if k == self.args['name']: - if self.args['state'] == "present": - new_line = "%s = %s\n" % (k, self.args['value']) - self.fixed_lines.append(new_line) - else: - new_line = "%s = %s\n" % (k, v) - self.fixed_lines.append(new_line) - - if self.args['name'] not in checked and self.args['state'] == "present": - new_line = "%s=%s\n" % (self.args['name'], self.args['value']) - self.fixed_lines.append(new_line) - - # Completely rewrite the sysctl file - def write_sysctl(self): - # open a tmp file - fd, tmp_path = tempfile.mkstemp('.conf', '.ansible_m_sysctl_', os.path.dirname(self.sysctl_file)) - f = open(tmp_path,"w") - try: - for l in self.fixed_lines: - f.write(l.strip() + "\n") - except IOError, e: - self.module.fail_json(msg="Failed to write to file %s: %s" % (tmp_path, str(e))) - f.flush() - f.close() - - # replace the real one - self.module.atomic_move(tmp_path, self.sysctl_file) - - -# ============================================================== -# main - -def main(): - - # defining module - module = AnsibleModule( - argument_spec = dict( - name = dict(aliases=['key'], required=True), - value = dict(aliases=['val'], required=False), - state = dict(default='present', choices=['present', 'absent']), - reload = dict(default=True, type='bool'), - sysctl_set = dict(default=False, type='bool'), - ignoreerrors = dict(default=False, type='bool'), - sysctl_file = dict(default='/etc/sysctl.conf') - ), - supports_check_mode=True - ) - - result = SysctlModule(module) - - module.exit_json(changed=result.changed) - sys.exit(0) - -# import module snippets -from ansible.module_utils.basic import * -main() |