summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToshio Kuratomi <toshio@fedoraproject.org>2016-01-20 09:04:44 -0800
committerToshio Kuratomi <toshio@fedoraproject.org>2016-01-20 09:04:44 -0800
commit4c7cbab8c0c0acf33c0994e869fd469bd886ce56 (patch)
treed15bb1c79290ff70ec30eaa94375402ba7c2603d
parente3a6accc1d25298c981bdef4e5412e3573730d0c (diff)
downloadansible-run_command-env-rework.tar.gz
rework run_command's env setting to not change os.environ for the rest of the module.run_command-env-rework
New param to run_command to modify the environment for just this invocation. Documentation and comment adjustments.
-rw-r--r--lib/ansible/module_utils/basic.py64
1 files changed, 37 insertions, 27 deletions
diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py
index b420f18e6e..dc16a16b04 100644
--- a/lib/ansible/module_utils/basic.py
+++ b/lib/ansible/module_utils/basic.py
@@ -546,11 +546,10 @@ class AnsibleModule(object):
if no_log_object:
self.no_log_values.update(return_values(no_log_object))
- # check the locale as set by the current environment, and
- # reset to LANG=C if it's an invalid/unavailable locale
+ # check the locale as set by the current environment, and reset to
+ # a known valid (LANG=C) if it's an invalid/unavailable locale
self._check_locale()
-
self._check_arguments(check_invalid_arguments)
# check exclusive early
@@ -1094,7 +1093,6 @@ class AnsibleModule(object):
# as it would be returned by locale.getdefaultlocale()
locale.setlocale(locale.LC_ALL, '')
except locale.Error:
- e = get_exception()
# fallback to the 'C' locale, which may cause unicode
# issues but is preferable to simply failing because
# of an unknown locale
@@ -1757,25 +1755,29 @@ class AnsibleModule(object):
# rename might not preserve context
self.set_context_if_different(dest, context, False)
- def run_command(self, args, check_rc=False, close_fds=True, executable=None, data=None, binary_data=False, path_prefix=None, cwd=None, use_unsafe_shell=False, prompt_regex=None):
+ def run_command(self, args, check_rc=False, close_fds=True, executable=None, data=None, binary_data=False, path_prefix=None, cwd=None, use_unsafe_shell=False, prompt_regex=None, environ_update=None):
'''
Execute a command, returns rc, stdout, and stderr.
- args is the command to run
- If args is a list, the command will be run with shell=False.
- If args is a string and use_unsafe_shell=False it will split args to a list and run with shell=False
- If args is a string and use_unsafe_shell=True it run with shell=True.
- Other arguments:
- - check_rc (boolean) Whether to call fail_json in case of
- non zero RC. Default is False.
- - close_fds (boolean) See documentation for subprocess.Popen().
- Default is True.
- - executable (string) See documentation for subprocess.Popen().
- Default is None.
- - prompt_regex (string) A regex string (not a compiled regex) which
- can be used to detect prompts in the stdout
- which would otherwise cause the execution
- to hang (especially if no input data is
- specified)
+
+ :arg args: is the command to run
+ * If args is a list, the command will be run with shell=False.
+ * If args is a string and use_unsafe_shell=False it will split args to a list and run with shell=False
+ * If args is a string and use_unsafe_shell=True it runs with shell=True.
+ :kw check_rc: Whether to call fail_json in case of non zero RC.
+ Default False
+ :kw close_fds: See documentation for subprocess.Popen(). Default True
+ :kw executable: See documentation for subprocess.Popen(). Default None
+ :kw data: If given, information to write to the stdin of the command
+ :kw binary_data: If False, append a newline to the data. Default False
+ :kw path_prefix: If given, additional path to find the command in.
+ This adds to the PATH environment vairable so helper commands in
+ the same directory can also be found
+ :kw cwd: iIf given, working directory to run the command inside
+ :kw use_unsafe_shell: See `args` parameter. Default False
+ :kw prompt_regex: Regex string (not a compiled regex) which can be
+ used to detect prompts in the stdout which would otherwise cause
+ the execution to hang (especially if no input data is specified)
+ :kwarg environ_update: dictionary to *update* os.environ with
'''
shell = False
@@ -1806,10 +1808,15 @@ class AnsibleModule(object):
msg = None
st_in = None
- # Set a temporary env path if a prefix is passed
- env=os.environ
+ # Manipulate the environ we'll send to the new process
+ old_env_vals = {}
+ if environ_update:
+ for key, val in environ_update.items():
+ old_env_vals = os.environ[key]
+ os.environ[key] = val
if path_prefix:
- env['PATH']="%s:%s" % (path_prefix, env['PATH'])
+ old_env_vals['PATH'] = os.environ['PATH']
+ os.environ['PATH'] = "%s:%s" % (path_prefix, os.environ['PATH'])
# create a printable version of the command for use
# in reporting later, which strips out things like
@@ -1851,11 +1858,10 @@ class AnsibleModule(object):
close_fds=close_fds,
stdin=st_in,
stdout=subprocess.PIPE,
- stderr=subprocess.PIPE
+ stderr=subprocess.PIPE,
+ env=os.environ,
)
- if path_prefix:
- kwargs['env'] = env
if cwd and os.path.isdir(cwd):
kwargs['cwd'] = cwd
@@ -1934,6 +1940,10 @@ class AnsibleModule(object):
except:
self.fail_json(rc=257, msg=traceback.format_exc(), cmd=clean_args)
+ # Restore env settings
+ for key, val in old_env_vals.items():
+ os.environ[key] = val
+
if rc != 0 and check_rc:
msg = heuristic_log_sanitize(stderr.rstrip(), self.no_log_values)
self.fail_json(cmd=clean_args, rc=rc, stdout=stdout, stderr=stderr, msg=msg)