From 5ef3bf5e8a3cfe09381e94ed40a12a09dfff8f8a Mon Sep 17 00:00:00 2001 From: Tait Clarridge Date: Thu, 13 Nov 2014 21:19:37 -0500 Subject: [PATCH] Fix for cross-platform sysctl with test and custom config location when using systemd >= 207 When using a custom config path for sysctl states, it would fail with an IOError as it was looking for the defaults which also may not exist as shown below: ---------- ID: net.ipv4.tcp_keepalive_intvl Function: sysctl.present Result: False Comment: An exception occurred in this state: Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/salt/state.py", line 1533, in call **cdata['kwargs']) File "/usr/lib/python2.7/site-packages/salt/states/sysctl.py", line 56, in present configured = __salt__['sysctl.show'](config_file=True) File "/usr/lib/python2.7/site-packages/salt/modules/linux_sysctl.py", line 86, in show for line in salt.utils.fopen(config_file_path): File "/usr/lib/python2.7/site-packages/salt/utils/__init__.py", line 1065, in fopen fhandle = open(*args, **kwargs) IOError: [Errno 2] No such file or directory: '/etc/sysctl.d/99-salt.conf' The corresponding state had a config file specified that was ignored. But this would hold true for any minion meeting the systemd conditions and not having 99-salt.conf. Now, for normal highstate runs, the current and configured options are not run unless test is specified and if the configured check returns none, the user will be notified that there was an issue reading the default/specified file. Platforms other than linux also appeared to not have the config_file argument for show() that would have probably (I did not verify) bail out with argument number errors during normal runs. --- salt/modules/darwin_sysctl.py | 2 +- salt/modules/freebsd_sysctl.py | 2 +- salt/modules/linux_sysctl.py | 7 +++---- salt/modules/netbsd_sysctl.py | 5 ++--- salt/modules/openbsd_sysctl.py | 2 +- salt/states/sysctl.py | 10 ++++++++-- 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/salt/modules/darwin_sysctl.py b/salt/modules/darwin_sysctl.py index 80384b4bb5..3532724098 100644 --- a/salt/modules/darwin_sysctl.py +++ b/salt/modules/darwin_sysctl.py @@ -22,7 +22,7 @@ def __virtual__(): return __virtualname__ if __grains__['os'] == 'MacOS' else False -def show(): +def show(config_file=False): ''' Return a list of sysctl parameters for this minion diff --git a/salt/modules/freebsd_sysctl.py b/salt/modules/freebsd_sysctl.py index 1ab99b5976..d866e015a6 100644 --- a/salt/modules/freebsd_sysctl.py +++ b/salt/modules/freebsd_sysctl.py @@ -26,7 +26,7 @@ def _formatfor(name, value, config, tail=''): return '{0}={1}{2}'.format(name, value, tail) -def show(): +def show(config_file=False): ''' Return a list of sysctl parameters for this minion diff --git a/salt/modules/linux_sysctl.py b/salt/modules/linux_sysctl.py index c031420c18..38a0f75411 100644 --- a/salt/modules/linux_sysctl.py +++ b/salt/modules/linux_sysctl.py @@ -35,7 +35,7 @@ def __virtual__(): return __virtualname__ -def default_config(): +def default_config(config): ''' Linux hosts using systemd 207 or later ignore ``/etc/sysctl.conf`` and only load from ``/etc/sysctl.d/*.conf``. This function will do the proper checks @@ -82,9 +82,8 @@ def show(config_file=False): ''' ret = {} if config_file: - config_file_path = default_config() try: - for line in salt.utils.fopen(config_file_path): + for line in salt.utils.fopen(config_file): if not line.startswith('#') and '=' in line: # search if we have some '=' instead of ' = ' separators SPLIT = ' = ' @@ -94,7 +93,7 @@ def show(config_file=False): key = key.strip() value = value.lstrip() ret[key] = value - except OSError: + except OSError, IOError: log.error('Could not open sysctl file') return None else: diff --git a/salt/modules/netbsd_sysctl.py b/salt/modules/netbsd_sysctl.py index 965ac0e6a1..845ebaf591 100644 --- a/salt/modules/netbsd_sysctl.py +++ b/salt/modules/netbsd_sysctl.py @@ -20,7 +20,7 @@ def __virtual__(): return __virtualname__ if __grains__['os'] == 'NetBSD' else False -def show(): +def show(config_file=False): ''' Return a list of sysctl parameters for this minion @@ -96,7 +96,7 @@ def assign(name, value): return ret -def persist(name, value): +def persist(name, value, config='/etc/sysctl.conf'): ''' Assign and persist a simple sysctl parameter for this minion @@ -109,7 +109,6 @@ def persist(name, value): nlines = [] edited = False value = str(value) - config = '/etc/sysctl.conf' with salt.utils.fopen(config, 'r') as ifile: for line in ifile: diff --git a/salt/modules/openbsd_sysctl.py b/salt/modules/openbsd_sysctl.py index 565ad54748..c2d0d3aed2 100644 --- a/salt/modules/openbsd_sysctl.py +++ b/salt/modules/openbsd_sysctl.py @@ -20,7 +20,7 @@ def __virtual__(): return __virtualname__ if __grains__['os'] == 'OpenBSD' else False -def show(): +def show(config_file=False): ''' Return a list of sysctl parameters for this minion diff --git a/salt/states/sysctl.py b/salt/states/sysctl.py index fd554f579e..c8355dbbf3 100644 --- a/salt/states/sysctl.py +++ b/salt/states/sysctl.py @@ -53,9 +53,15 @@ def present(name, value, config=None): else: config = '/etc/sysctl.conf' - current = __salt__['sysctl.show']() - configured = __salt__['sysctl.show'](config_file=True) if __opts__['test']: + current = __salt__['sysctl.show']() + configured = __salt__['sysctl.show'](config_file=config) + if not configured: + ret['result'] = None + ret['comment'] = ( + 'Sysctl option {0} might be changed, we failed to check config file at {1}.\n' + 'The file is either unreadable, or missing.').format(name, config) + return ret if name in current and name not in configured: if re.sub(' +|\t+', ' ', current[name]) != re.sub(' +|\t+', ' ', str(value)): ret['result'] = None