From ac8950fd36d89765fadb9f3e80f101bafb188386 Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Mon, 11 Aug 2014 19:21:39 -0500 Subject: [PATCH] Set special vars in play.vars rather than load_vars Also refactors playbook loading code relating to vars in playbooks to a sub-function. Fixes #8534 --- lib/ansible/playbook/__init__.py | 36 +++++++++++++++++++++----------- lib/ansible/playbook/play.py | 9 +++++--- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/lib/ansible/playbook/__init__.py b/lib/ansible/playbook/__init__.py index 6c31461bc9..c2e9cadb27 100644 --- a/lib/ansible/playbook/__init__.py +++ b/lib/ansible/playbook/__init__.py @@ -226,12 +226,34 @@ class PlayBook(object): # ***************************************************** + def _extend_play_vars(self, play, vars={}): + ''' + Extends the given play's variables with the additional specified vars. + ''' + + if 'vars' not in play or not play['vars']: + # someone left out or put an empty "vars:" entry in their playbook + return vars.copy() + + play_vars = None + if isinstance(play_vars, dict): + play_vars = play['vars'].copy() + play_vars.update(vars) + elif isinstance(play_vars, list): + # nobody should really do this, but handle vars: a=1 b=2 + play_vars = play['vars'][:] + play_vars.extend([{k:v} for k,v in vars.iteritems()]) + + return play_vars + + # ***************************************************** + def _load_playbook_from_file(self, path, vars={}, vars_files=[]): ''' run top level error checking on playbooks and allow them to include other playbooks. ''' - playbook_data = utils.parse_yaml_from_file(path, vault_password=self.vault_password) + playbook_data = utils.parse_yaml_from_file(path, vault_password=self.vault_password) accumulated_plays = [] play_basedirs = [] @@ -258,17 +280,7 @@ class PlayBook(object): for p in plays: # support for parameterized play includes works by passing # those variables along to the subservient play - if 'vars' not in p: - p['vars'] = {} - if isinstance(p['vars'], dict): - p['vars'].update(play_vars) - elif isinstance(p['vars'], list): - # nobody should really do this, but handle vars: a=1 b=2 - p['vars'].extend([{k:v} for k,v in play_vars.iteritems()]) - elif p['vars'] == None: - # someone specified an empty 'vars:', so reset - # it to the vars we currently have - p['vars'] = play_vars.copy() + p['vars'] = self._extend_play_vars(p, play_vars) # now add in the vars_files p['vars_files'] = utils.list_union(p.get('vars_files', []), play_vars_files) diff --git a/lib/ansible/playbook/play.py b/lib/ansible/playbook/play.py index a600af8b8d..ed8a6e672e 100644 --- a/lib/ansible/playbook/play.py +++ b/lib/ansible/playbook/play.py @@ -76,6 +76,12 @@ class Play(object): elif type(self.tags) != list: self.tags = [] + # make sure we have some special internal variables set + if self.playbook.inventory.basedir() is not None: + self.vars['inventory_dir'] = self.playbook.inventory.basedir() + if self.playbook.inventory.src() is not None: + self.vars['inventory_file'] = self.playbook.inventory.src() + # We first load the vars files from the datastructure # so we have the default variables to pass into the roles self.vars_files = ds.get('vars_files', []) @@ -148,13 +154,10 @@ class Play(object): load_vars = {} load_vars['role_names'] = ds.get('role_names',[]) load_vars['playbook_dir'] = self.basedir - if self.playbook.inventory.basedir() is not None: - load_vars['inventory_dir'] = self.playbook.inventory.basedir() self._tasks = self._load_tasks(self._ds.get('tasks', []), load_vars) self._handlers = self._load_tasks(self._ds.get('handlers', []), load_vars) - # apply any missing tags to role tasks self._late_merge_role_tags()