From 09e690fd7c303466179cdf417f50de64875a9657 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Tue, 3 Apr 2012 20:20:55 -0400 Subject: [PATCH 1/3] Indentation error causing forks to not be parallel. Ahem :) --- lib/ansible/runner.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py index 0218ea2406e..4e4fd255731 100755 --- a/lib/ansible/runner.py +++ b/lib/ansible/runner.py @@ -75,7 +75,7 @@ class Runner(object): remote_port=C.DEFAULT_REMOTE_PORT, background=0, basedir=None, setup_cache=None, transport='paramiko', conditional='True', groups={}, callbacks=None, verbose=False, debug=False, sudo=False, extra_vars=None): - + if setup_cache is None: setup_cache = {} if basedir is None: @@ -637,13 +637,13 @@ class Runner(object): prc.start() workers.append(prc) - try: - for worker in workers: - worker.join() - except KeyboardInterrupt: - for worker in workers: - worker.terminate() - worker.join() + try: + for worker in workers: + worker.join() + except KeyboardInterrupt: + for worker in workers: + worker.terminate() + worker.join() results = [] while not result_queue.empty(): From edd5baad8b7d79c6e79be6f15a53ed9339ee32a3 Mon Sep 17 00:00:00 2001 From: Jeroen Hoekx Date: Wed, 4 Apr 2012 13:36:21 +0200 Subject: [PATCH 2/3] Refactor _transfer_argsfile to generic string transfer function. --- lib/ansible/runner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py index 4e4fd255731..1a874a4afb5 100755 --- a/lib/ansible/runner.py +++ b/lib/ansible/runner.py @@ -267,7 +267,7 @@ class Runner(object): # ***************************************************** - def _transfer_argsfile(self, conn, tmp, args_str): + def _transfer_str(self, conn, tmp, name, args_str): ''' transfer arguments as a single file to be fed to the module. ''' args_fd, args_file = tempfile.mkstemp() @@ -276,7 +276,7 @@ class Runner(object): args_fo.flush() args_fo.close() - args_remote = os.path.join(tmp, 'arguments') + args_remote = os.path.join(tmp, name) conn.put_file(args_file, args_remote) os.unlink(args_file) @@ -355,7 +355,7 @@ class Runner(object): module_name_tail = remote_module_path.split("/")[-1] client_executed_str = "%s %s" % (module_name_tail, args.strip()) - argsfile = self._transfer_argsfile(conn, tmp, args) + argsfile = self._transfer_str(conn, tmp, 'arguments', args) if async_jid is None: cmd = "%s %s" % (remote_module_path, argsfile) else: From ab86726a1599e6496cd3bf2f94b715ec1ba461d5 Mon Sep 17 00:00:00 2001 From: Jeroen Hoekx Date: Wed, 4 Apr 2012 13:38:21 +0200 Subject: [PATCH 3/3] Introduce per task variables and push them to templates. --- lib/ansible/playbook.py | 18 +++++++++++++----- lib/ansible/runner.py | 13 +++++++++++-- library/template | 15 ++++++++++++++- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/lib/ansible/playbook.py b/lib/ansible/playbook.py index a74847cd9b6..0eb0e4d685c 100755 --- a/lib/ansible/playbook.py +++ b/lib/ansible/playbook.py @@ -113,14 +113,19 @@ class PlayBook(object): # include: some.yml a=2 b=3 c=4 include_tokens = task['include'].split() path = utils.path_dwim(dirname, include_tokens[0]) - inject_vars = self._get_vars(play, dirname) + play_vars = self._get_vars(play, dirname) + include_vars = {} for i,x in enumerate(include_tokens): if x.find("=") != -1: (k,v) = x.split("=") - inject_vars[k] = v + include_vars[k] = v + inject_vars = play_vars.copy() + inject_vars.update(include_vars) included = utils.template_from_file(path, inject_vars) included = utils.parse_yaml(included) for x in included: + if len(include_vars): + x["vars"] = include_vars new_tasks.append(x) # ***************************************************** @@ -266,7 +271,7 @@ class PlayBook(object): # ***************************************************** - def _run_module(self, pattern, host_list, module, args, remote_user, + def _run_module(self, pattern, host_list, module, args, vars, remote_user, async_seconds, async_poll_interval, only_if, sudo): ''' run a particular module step in a playbook ''' @@ -277,7 +282,7 @@ class PlayBook(object): module_args=args, host_list=hosts, forks=self.forks, remote_pass=self.remote_pass, module_path=self.module_path, timeout=self.timeout, remote_user=remote_user, - remote_port=self.remote_port, + remote_port=self.remote_port, module_vars=vars, setup_cache=SETUP_CACHE, basedir=self.basedir, conditional=only_if, callbacks=self.runner_callbacks, extra_vars=self.extra_vars, debug=self.debug, sudo=sudo @@ -309,6 +314,9 @@ class PlayBook(object): module_name = tokens[0] module_args = tokens[1] + # include task specific vars + module_vars = task.get('vars') + # tasks can be direct (run on all nodes matching # the pattern) or conditional, where they ran # as the result of a change handler on a subset @@ -319,7 +327,7 @@ class PlayBook(object): # load up an appropriate ansible runner to # run the task in parallel results = self._run_module(pattern, host_list, module_name, - module_args, remote_user, async_seconds, + module_args, module_vars, remote_user, async_seconds, async_poll_interval, only_if, sudo) self.stats.compute(results) diff --git a/lib/ansible/runner.py b/lib/ansible/runner.py index 1a874a4afb5..b2cf3518b99 100755 --- a/lib/ansible/runner.py +++ b/lib/ansible/runner.py @@ -74,7 +74,7 @@ class Runner(object): remote_user=C.DEFAULT_REMOTE_USER, remote_pass=C.DEFAULT_REMOTE_PASS, remote_port=C.DEFAULT_REMOTE_PORT, background=0, basedir=None, setup_cache=None, transport='paramiko', conditional='True', groups={}, callbacks=None, verbose=False, - debug=False, sudo=False, extra_vars=None): + debug=False, sudo=False, extra_vars=None, module_vars=None): if setup_cache is None: setup_cache = {} @@ -101,6 +101,7 @@ class Runner(object): self.forks = int(forks) self.pattern = pattern self.module_args = module_args + self.module_vars = module_vars self.extra_vars = extra_vars self.timeout = timeout self.debug = debug @@ -498,8 +499,16 @@ class Runner(object): # install the template module template_module = self._transfer_module(conn, tmp, 'template') + # transfer module vars + if self.module_vars: + vars = utils.bigjson(self.module_vars) + vars_path = self._transfer_str(conn, tmp, 'module_vars', vars) + vars_arg=" vars=%s"%(vars_path) + else: + vars_arg="" + # run the template module - args = "src=%s dest=%s metadata=%s" % (temppath, dest, metadata) + args = "src=%s dest=%s metadata=%s%s" % (temppath, dest, metadata, vars_arg) (result1, err, executed) = self._execute_module(conn, tmp, template_module, args) (host, ok, data, err) = self._return_from_module(conn, host, result1, err, executed) diff --git a/library/template b/library/template index 3421f497ccc..0b13422d5ab 100755 --- a/library/template +++ b/library/template @@ -48,7 +48,7 @@ for x in items: source = params['src'] dest = params['dest'] metadata = params.get('metadata', '/etc/ansible/setup') - +module_vars = params.get('vars') # raise an error if there is no template metadata if not os.path.exists(metadata): @@ -71,6 +71,19 @@ except: }) sys.exit(1) +if module_vars: + try: + f = open(module_vars) + vars = json.loads(f.read()) + data.update(vars) + f.close() + except: + print json.dumps({ + "failed" : 1, + "msg" : "Failed to parse/load %s." % module_vars + }) + sys.exit(1) + if not os.path.exists(source): print json.dumps({ "failed" : 1,