From f7497e75e5d04dd02bc2c3fddd0cc2ad4b5a8b31 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Sun, 10 Feb 2013 13:05:58 -0500 Subject: [PATCH] Able to use "environment: " on any task to pass proxy details and other useful settings. Can be a variable or a dictionary. --- CHANGELOG.md | 1 + lib/ansible/playbook/__init__.py | 2 +- lib/ansible/playbook/task.py | 5 +++-- lib/ansible/runner/__init__.py | 24 ++++++++++++++++++++++-- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c61e918d66d..6a647a104f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ Ansible Changes By Release * block device facts for the setup module * cron module can now also manipulate cron.d files * virtualenv module can now inherit system site packages (or not) +* able to set the environment by setting "environment:" as a dictionary on any task (go proxy support!) 1.0 "Eruption" -- Feb 1 2013 diff --git a/lib/ansible/playbook/__init__.py b/lib/ansible/playbook/__init__.py index 43974ccbffb..0ec03fa526c 100644 --- a/lib/ansible/playbook/__init__.py +++ b/lib/ansible/playbook/__init__.py @@ -273,7 +273,7 @@ class PlayBook(object): conditional=task.only_if, callbacks=self.runner_callbacks, sudo=task.sudo, sudo_user=task.sudo_user, transport=task.transport, sudo_pass=task.sudo_pass, is_playbook=True, - check=self.check, diff=self.diff + check=self.check, diff=self.diff, environment=task.environment ) if task.async_seconds == 0: diff --git a/lib/ansible/playbook/task.py b/lib/ansible/playbook/task.py index 99a557b1e39..1b1f1d9560c 100644 --- a/lib/ansible/playbook/task.py +++ b/lib/ansible/playbook/task.py @@ -27,7 +27,7 @@ class Task(object): 'play', 'notified_by', 'tags', 'register', 'delegate_to', 'first_available_file', 'ignore_errors', 'local_action', 'transport', 'sudo', 'sudo_user', 'sudo_pass', - 'items_lookup_plugin', 'items_lookup_terms' + 'items_lookup_plugin', 'items_lookup_terms', 'environment' ] # to prevent typos and such @@ -35,7 +35,7 @@ class Task(object): 'name', 'action', 'only_if', 'async', 'poll', 'notify', 'first_available_file', 'include', 'tags', 'register', 'ignore_errors', 'delegate_to', 'local_action', 'transport', 'sudo', 'sudo_user', - 'sudo_pass', 'when', 'connection' + 'sudo_pass', 'when', 'connection', 'environment' ] def __init__(self, play, ds, module_vars=None, additional_conditions=None): @@ -80,6 +80,7 @@ class Task(object): self.tags = [ 'all' ] self.register = ds.get('register', None) self.sudo = utils.boolean(ds.get('sudo', play.sudo)) + self.environment = ds.get('environment', {}) if self.sudo: self.sudo_user = ds.get('sudo_user', play.sudo_user) diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index b7e4760615a..634f5727fb7 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -119,7 +119,8 @@ class Runner(object): inventory=None, # reference to Inventory object subset=None, # subset pattern check=False, # don't make any changes, just try to probe for potential changes - diff=False + diff=False, # whether to show diffs for template files that change + environment=None # environment variables (as dict) to use inside the command ): # storage & defaults @@ -149,6 +150,7 @@ class Runner(object): self.sudo = sudo self.sudo_pass = sudo_pass self.is_playbook = is_playbook + self.environment = environment # misc housekeeping if subset and self.inventory._subset is None: @@ -193,6 +195,22 @@ class Runner(object): # ***************************************************** + def _compute_environment_string(self, inject=None): + ''' what environment variables to use when running the command? ''' + + if not self.environment: + return "" + enviro = utils.template(self.basedir, self.environment, inject) + print "DEBUG: vars=%s" % enviro + if type(enviro) != dict: + raise errors.AnsibleError("environment must be a dictionary, recieved %s" % enviro) + result = "" + for (k,v) in enviro.iteritems(): + result = "%s=%s %s" % (k, str(v), result) + return result + + # ***************************************************** + def _execute_module(self, conn, tmp, module_name, args, async_jid=None, async_module=None, async_limit=None, inject=None, persist_files=False): @@ -206,6 +224,8 @@ class Runner(object): (remote_module_path, is_new_style, shebang) = self._copy_module(conn, tmp, module_name, args, inject) + environment_string = self._compute_environment_string(inject) + cmd_mod = "" if self.sudo and self.sudo_user != 'root': # deal with possible umask issues once sudo'ed to other user @@ -234,7 +254,7 @@ class Runner(object): if not shebang: raise errors.AnsibleError("module is missing interpreter line") - cmd = shebang.replace("#!","") + " " + cmd + cmd = " ".join([environment_string, shebang.replace("#!",""), cmd]) if tmp.find("tmp") != -1 and C.DEFAULT_KEEP_REMOTE_FILES != '1' and not persist_files: cmd = cmd + "; rm -rf %s >/dev/null 2>&1" % tmp res = self._low_level_exec_command(conn, cmd, tmp, sudoable=True)