diff --git a/salt/modules/cmdmod.py b/salt/modules/cmdmod.py index 3ea1f272f0..2aa26974ba 100644 --- a/salt/modules/cmdmod.py +++ b/salt/modules/cmdmod.py @@ -53,6 +53,19 @@ def __virtual__(): return __virtualname__ +def _check_cb(cb_): + ''' + If the callback is None or is not callable, return a lambda that returns + the value passed. + ''' + if cb_ is not None: + if hasattr(cb_, '__call__'): + return cb_ + else: + log.error('log_callback is not callable, ignoring') + return lambda x: x + + def _python_shell_default(python_shell, __pub_jid): ''' Set python_shell default based on remote execution and __opts__['cmd_safe'] @@ -200,6 +213,7 @@ def _run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, output_loglevel='debug', + log_callback=None, runas=None, shell=DEFAULT_SHELL, python_shell=False, @@ -225,6 +239,8 @@ def _run(cmd, 'Check to ensure that the shell <{0}> is valid for this user.' .format(shell)) + log_callback = _check_cb(log_callback) + # Set the default working directory to the home directory of the user # salt-minion is running as. Defaults to home directory of user under which # the minion is running. @@ -331,11 +347,12 @@ def _run(cmd, # Always log the shell commands at INFO unless quiet logging is # requested. The command output is what will be controlled by the # 'loglevel' parameter. - log.info( + msg = ( 'Executing command {0!r} {1}in directory {2!r}'.format( cmd, 'as user {0!r} '.format(runas) if runas else '', cwd ) ) + log.info(log_callback(msg)) if reset_system_locale is True: if not salt.utils.is_windows(): @@ -442,7 +459,8 @@ def _run(cmd, if timeout: to = ' (timeout: {0}s)'.format(timeout) if _check_loglevel(output_loglevel) is not None: - log.debug('Running {0} in VT{1}'.format(cmd, to)) + msg = 'Running {0} in VT{1}'.format(cmd, to) + log.debug(log_callback(msg)) stdout, stderr = '', '' now = time.time() if timeout: @@ -540,6 +558,7 @@ def _run_quiet(cmd, stdin=stdin, stderr=subprocess.STDOUT, output_loglevel='quiet', + log_callback=None, shell=shell, python_shell=python_shell, env=env, @@ -578,6 +597,7 @@ def _run_all_quiet(cmd, python_shell=python_shell, env=env, output_loglevel='quiet', + log_callback=None, template=template, umask=umask, timeout=timeout, @@ -599,6 +619,7 @@ def run(cmd, rstrip=True, umask=None, output_loglevel='debug', + log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, @@ -676,6 +697,7 @@ def run(cmd, rstrip=rstrip, umask=umask, output_loglevel=output_loglevel, + log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, @@ -684,6 +706,8 @@ def run(cmd, pillar_override=kwargs.get('pillar'), use_vt=use_vt) + log_callback = _check_cb(log_callback) + if 'pid' in ret and '__pub_jid' in kwargs: # Stuff the child pid in the JID file try: @@ -710,11 +734,12 @@ def run(cmd, if not ignore_retcode and ret['retcode'] != 0: if lvl < LOG_LEVELS['error']: lvl = LOG_LEVELS['error'] - log.error( + msg = ( 'Command {0!r} failed with return code: {1}' .format(cmd, ret['retcode']) ) - log.log(lvl, 'output: {0}'.format(ret['stdout'])) + log.error(log_callback(msg)) + log.log(lvl, 'output: {0}'.format(log_callback(ret['stdout']))) return ret['stdout'] @@ -729,6 +754,7 @@ def shell(cmd, rstrip=True, umask=None, output_loglevel='debug', + log_callback=None, quiet=False, timeout=None, reset_system_locale=True, @@ -803,6 +829,7 @@ def shell(cmd, rstrip=rstrip, umask=umask, output_loglevel=output_loglevel, + log_callback=log_callback, quiet=quiet, timeout=timeout, reset_system_locale=reset_system_locale, @@ -825,6 +852,7 @@ def run_stdout(cmd, rstrip=True, umask=None, output_loglevel='debug', + log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, @@ -873,6 +901,7 @@ def run_stdout(cmd, rstrip=rstrip, umask=umask, output_loglevel=output_loglevel, + log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, @@ -881,19 +910,22 @@ def run_stdout(cmd, pillar_override=kwargs.get('pillar'), use_vt=use_vt) + log_callback = _check_cb(log_callback) + lvl = _check_loglevel(output_loglevel) if lvl is not None: if not ignore_retcode and ret['retcode'] != 0: if lvl < LOG_LEVELS['error']: lvl = LOG_LEVELS['error'] - log.error( + msg = ( 'Command {0!r} failed with return code: {1}' .format(cmd, ret['retcode']) ) + log.error(log_callback(msg)) if ret['stdout']: - log.log(lvl, 'stdout: {0}'.format(ret['stdout'])) + log.log(lvl, 'stdout: {0}'.format(log_callback(ret['stdout']))) if ret['stderr']: - log.log(lvl, 'stderr: {0}'.format(ret['stderr'])) + log.log(lvl, 'stderr: {0}'.format(log_callback(ret['stderr']))) if ret['retcode']: log.log(lvl, 'retcode: {0}'.format(ret['retcode'])) return ret['stdout'] @@ -911,6 +943,7 @@ def run_stderr(cmd, rstrip=True, umask=None, output_loglevel='debug', + log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, @@ -959,6 +992,7 @@ def run_stderr(cmd, rstrip=rstrip, umask=umask, output_loglevel=output_loglevel, + log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, @@ -967,19 +1001,22 @@ def run_stderr(cmd, pillarenv=kwargs.get('pillarenv'), pillar_override=kwargs.get('pillar')) + log_callback = _check_cb(log_callback) + lvl = _check_loglevel(output_loglevel) if lvl is not None: if not ignore_retcode and ret['retcode'] != 0: if lvl < LOG_LEVELS['error']: lvl = LOG_LEVELS['error'] - log.error( + msg = ( 'Command {0!r} failed with return code: {1}' .format(cmd, ret['retcode']) ) + log.error(log_callback(msg)) if ret['stdout']: - log.log(lvl, 'stdout: {0}'.format(ret['stdout'])) + log.log(lvl, 'stdout: {0}'.format(log_callback(ret['stdout']))) if ret['stderr']: - log.log(lvl, 'stderr: {0}'.format(ret['stderr'])) + log.log(lvl, 'stderr: {0}'.format(log_callback(ret['stderr']))) if ret['retcode']: log.log(lvl, 'retcode: {0}'.format(ret['retcode'])) return ret['stderr'] @@ -997,6 +1034,7 @@ def run_all(cmd, rstrip=True, umask=None, output_loglevel='debug', + log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, @@ -1045,6 +1083,7 @@ def run_all(cmd, rstrip=rstrip, umask=umask, output_loglevel=output_loglevel, + log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, @@ -1053,19 +1092,22 @@ def run_all(cmd, pillar_override=kwargs.get('pillar'), use_vt=use_vt) + log_callback = _check_cb(log_callback) + lvl = _check_loglevel(output_loglevel) if lvl is not None: if not ignore_retcode and ret['retcode'] != 0: if lvl < LOG_LEVELS['error']: lvl = LOG_LEVELS['error'] - log.error( + msg = ( 'Command {0!r} failed with return code: {1}' .format(cmd, ret['retcode']) ) + log.error(log_callback(msg)) if ret['stdout']: - log.log(lvl, 'stdout: {0}'.format(ret['stdout'])) + log.log(lvl, 'stdout: {0}'.format(log_callback(ret['stdout']))) if ret['stderr']: - log.log(lvl, 'stderr: {0}'.format(ret['stderr'])) + log.log(lvl, 'stderr: {0}'.format(log_callback(ret['stderr']))) if ret['retcode']: log.log(lvl, 'retcode: {0}'.format(ret['retcode'])) return ret @@ -1082,6 +1124,7 @@ def retcode(cmd, template=None, umask=None, output_loglevel='debug', + log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, @@ -1132,6 +1175,7 @@ def retcode(cmd, template=template, umask=umask, output_loglevel=output_loglevel, + log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, @@ -1140,16 +1184,19 @@ def retcode(cmd, pillar_override=kwargs.get('pillar'), use_vt=use_vt) + log_callback = _check_cb(log_callback) + lvl = _check_loglevel(output_loglevel) if lvl is not None: if not ignore_retcode and ret['retcode'] != 0: if lvl < LOG_LEVELS['error']: lvl = LOG_LEVELS['error'] - log.error( + msg = ( 'Command {0!r} failed with return code: {1}' .format(cmd, ret['retcode']) ) - log.log(lvl, 'output: {0}'.format(ret['stdout'])) + log.error(log_callback(msg)) + log.log(lvl, 'output: {0}'.format(log_callback(ret['stdout']))) return ret['retcode'] @@ -1164,6 +1211,7 @@ def _retcode_quiet(cmd, template=None, umask=None, output_loglevel='quiet', + log_callback=None, timeout=None, reset_system_locale=True, ignore_retcode=False, @@ -1185,6 +1233,7 @@ def _retcode_quiet(cmd, template=template, umask=umask, output_loglevel=output_loglevel, + log_callback=log_callback, timeout=timeout, reset_system_locale=reset_system_locale, ignore_retcode=ignore_retcode, @@ -1204,6 +1253,7 @@ def script(source, template=None, umask=None, output_loglevel='debug', + log_callback=None, quiet=False, timeout=None, reset_system_locale=True, @@ -1292,6 +1342,7 @@ def script(source, cwd=cwd, stdin=stdin, output_loglevel=output_loglevel, + log_callback=log_callback, runas=runas, shell=shell, python_shell=python_shell, @@ -1322,6 +1373,7 @@ def script_retcode(source, __env__=None, saltenv='base', output_loglevel='debug', + log_callback=None, use_vt=False, **kwargs): ''' @@ -1367,6 +1419,7 @@ def script_retcode(source, __env__=__env__, saltenv=saltenv, output_loglevel=output_loglevel, + log_callback=log_callback, use_vt=use_vt, **kwargs)['retcode'] @@ -1489,6 +1542,7 @@ def run_chroot(root, rstrip=True, umask=None, output_loglevel='quiet', + log_callback=None, quiet=False, timeout=None, reset_system_locale=True, @@ -1551,6 +1605,7 @@ def run_chroot(root, rstrip=rstrip, umask=umask, output_loglevel=output_loglevel, + log_callback=log_callback, quiet=quiet, timeout=timeout, reset_system_locale=reset_system_locale,