mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Support import of playbooks in other directories
Previously, importing a playbook in a different directory didn't work because all of the relative paths were resolved relative to the top-level playbook. This patch resolves relative paths on a per-play level instead of relative to the directory of the top-level playbook. Also removes the dirname argument from the Play._get_vars method since this argument wasn't used in the metho dbody.
This commit is contained in:
parent
565f336182
commit
b9e100a506
2 changed files with 22 additions and 16 deletions
|
@ -112,7 +112,7 @@ class PlayBook(object):
|
||||||
self.global_vars.update(self.inventory.get_group_variables('all'))
|
self.global_vars.update(self.inventory.get_group_variables('all'))
|
||||||
|
|
||||||
self.basedir = os.path.dirname(playbook)
|
self.basedir = os.path.dirname(playbook)
|
||||||
self.playbook = self._load_playbook_from_file(playbook)
|
(self.playbook, self.play_basedirs) = self._load_playbook_from_file(playbook)
|
||||||
self.module_path = self.module_path + os.pathsep + os.path.join(self.basedir, "library")
|
self.module_path = self.module_path + os.pathsep + os.path.join(self.basedir, "library")
|
||||||
|
|
||||||
# *****************************************************
|
# *****************************************************
|
||||||
|
@ -124,6 +124,7 @@ class PlayBook(object):
|
||||||
|
|
||||||
playbook_data = utils.parse_yaml_from_file(path)
|
playbook_data = utils.parse_yaml_from_file(path)
|
||||||
accumulated_plays = []
|
accumulated_plays = []
|
||||||
|
play_basedirs = []
|
||||||
|
|
||||||
if type(playbook_data) != list:
|
if type(playbook_data) != list:
|
||||||
raise errors.AnsibleError("parse error: playbooks must be formatted as a YAML list")
|
raise errors.AnsibleError("parse error: playbooks must be formatted as a YAML list")
|
||||||
|
@ -134,13 +135,17 @@ class PlayBook(object):
|
||||||
if 'include' in play:
|
if 'include' in play:
|
||||||
if len(play.keys()) == 1:
|
if len(play.keys()) == 1:
|
||||||
included_path = utils.path_dwim(self.basedir, play['include'])
|
included_path = utils.path_dwim(self.basedir, play['include'])
|
||||||
accumulated_plays.extend(self._load_playbook_from_file(included_path))
|
(plays, basedirs) = self._load_playbook_from_file(included_path)
|
||||||
|
accumulated_plays.extend(plays)
|
||||||
|
play_basedirs.extend(basedirs)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise errors.AnsibleError("parse error: top level includes cannot be used with other directives: %s" % play)
|
raise errors.AnsibleError("parse error: top level includes cannot be used with other directives: %s" % play)
|
||||||
else:
|
else:
|
||||||
accumulated_plays.append(play)
|
accumulated_plays.append(play)
|
||||||
|
play_basedirs.append(os.path.dirname(path))
|
||||||
|
|
||||||
return accumulated_plays
|
return (accumulated_plays, play_basedirs)
|
||||||
|
|
||||||
# *****************************************************
|
# *****************************************************
|
||||||
|
|
||||||
|
@ -152,8 +157,8 @@ class PlayBook(object):
|
||||||
|
|
||||||
# loop through all patterns and run them
|
# loop through all patterns and run them
|
||||||
self.callbacks.on_start()
|
self.callbacks.on_start()
|
||||||
for play_ds in self.playbook:
|
for (play_ds, play_basedir) in zip(self.playbook, self.play_basedirs):
|
||||||
play = Play(self,play_ds)
|
play = Play(self, play_ds, play_basedir)
|
||||||
matched_tags, unmatched_tags = play.compare_tags(self.only_tags)
|
matched_tags, unmatched_tags = play.compare_tags(self.only_tags)
|
||||||
matched_tags_all = matched_tags_all | matched_tags
|
matched_tags_all = matched_tags_all | matched_tags
|
||||||
unmatched_tags_all = unmatched_tags_all | unmatched_tags
|
unmatched_tags_all = unmatched_tags_all | unmatched_tags
|
||||||
|
@ -166,8 +171,8 @@ class PlayBook(object):
|
||||||
# if the playbook is invoked with --tags that don't exist at all in the playbooks
|
# if the playbook is invoked with --tags that don't exist at all in the playbooks
|
||||||
# then we need to raise an error so that the user can correct the arguments.
|
# then we need to raise an error so that the user can correct the arguments.
|
||||||
unknown_tags = set(self.only_tags) - (matched_tags_all | unmatched_tags_all)
|
unknown_tags = set(self.only_tags) - (matched_tags_all | unmatched_tags_all)
|
||||||
unknown_tags.discard('all')
|
unknown_tags.discard('all')
|
||||||
|
|
||||||
if len(unknown_tags) > 0:
|
if len(unknown_tags) > 0:
|
||||||
unmatched_tags_all.discard('all')
|
unmatched_tags_all.discard('all')
|
||||||
msg = 'tag(s) not found in playbook: %s. possible values: %s'
|
msg = 'tag(s) not found in playbook: %s. possible values: %s'
|
||||||
|
@ -215,7 +220,7 @@ class PlayBook(object):
|
||||||
timeout=self.timeout, remote_user=task.play.remote_user,
|
timeout=self.timeout, remote_user=task.play.remote_user,
|
||||||
remote_port=task.play.remote_port, module_vars=task.module_vars,
|
remote_port=task.play.remote_port, module_vars=task.module_vars,
|
||||||
private_key_file=self.private_key_file,
|
private_key_file=self.private_key_file,
|
||||||
setup_cache=self.SETUP_CACHE, basedir=self.basedir,
|
setup_cache=self.SETUP_CACHE, basedir=task.play.basedir,
|
||||||
conditional=task.only_if, callbacks=self.runner_callbacks,
|
conditional=task.only_if, callbacks=self.runner_callbacks,
|
||||||
sudo=task.play.sudo, sudo_user=task.play.sudo_user,
|
sudo=task.play.sudo, sudo_user=task.play.sudo_user,
|
||||||
transport=task.play.transport, sudo_pass=self.sudo_pass, is_playbook=True
|
transport=task.play.transport, sudo_pass=self.sudo_pass, is_playbook=True
|
||||||
|
|
|
@ -29,7 +29,8 @@ class Play(object):
|
||||||
'hosts', 'name', 'vars', 'vars_prompt', 'vars_files',
|
'hosts', 'name', 'vars', 'vars_prompt', 'vars_files',
|
||||||
'handlers', 'remote_user', 'remote_port',
|
'handlers', 'remote_user', 'remote_port',
|
||||||
'sudo', 'sudo_user', 'transport', 'playbook',
|
'sudo', 'sudo_user', 'transport', 'playbook',
|
||||||
'tags', 'gather_facts', 'serial', '_ds', '_handlers', '_tasks'
|
'tags', 'gather_facts', 'serial', '_ds', '_handlers', '_tasks',
|
||||||
|
'basedir'
|
||||||
]
|
]
|
||||||
|
|
||||||
# to catch typos and so forth -- these are userland names
|
# to catch typos and so forth -- these are userland names
|
||||||
|
@ -42,7 +43,7 @@ class Play(object):
|
||||||
|
|
||||||
# *************************************************
|
# *************************************************
|
||||||
|
|
||||||
def __init__(self, playbook, ds):
|
def __init__(self, playbook, ds, basedir):
|
||||||
''' constructor loads from a play datastructure '''
|
''' constructor loads from a play datastructure '''
|
||||||
|
|
||||||
for x in ds.keys():
|
for x in ds.keys():
|
||||||
|
@ -57,15 +58,15 @@ class Play(object):
|
||||||
elif isinstance(hosts, list):
|
elif isinstance(hosts, list):
|
||||||
hosts = ';'.join(hosts)
|
hosts = ';'.join(hosts)
|
||||||
hosts = utils.template(hosts, playbook.extra_vars)
|
hosts = utils.template(hosts, playbook.extra_vars)
|
||||||
|
|
||||||
self._ds = ds
|
self._ds = ds
|
||||||
self.playbook = playbook
|
self.playbook = playbook
|
||||||
|
self.basedir = basedir
|
||||||
self.hosts = hosts
|
self.hosts = hosts
|
||||||
self.name = ds.get('name', self.hosts)
|
self.name = ds.get('name', self.hosts)
|
||||||
self.vars = ds.get('vars', {})
|
self.vars = ds.get('vars', {})
|
||||||
self.vars_files = ds.get('vars_files', [])
|
self.vars_files = ds.get('vars_files', [])
|
||||||
self.vars_prompt = ds.get('vars_prompt', {})
|
self.vars_prompt = ds.get('vars_prompt', {})
|
||||||
self.vars = self._get_vars(self.playbook.basedir)
|
self.vars = self._get_vars()
|
||||||
self._tasks = ds.get('tasks', [])
|
self._tasks = ds.get('tasks', [])
|
||||||
self._handlers = ds.get('handlers', [])
|
self._handlers = ds.get('handlers', [])
|
||||||
self.remote_user = utils.template(ds.get('user', self.playbook.remote_user), playbook.extra_vars)
|
self.remote_user = utils.template(ds.get('user', self.playbook.remote_user), playbook.extra_vars)
|
||||||
|
@ -107,7 +108,7 @@ class Play(object):
|
||||||
(k,v) = t.split("=", 1)
|
(k,v) = t.split("=", 1)
|
||||||
task_vars[k] = utils.template(v, task_vars)
|
task_vars[k] = utils.template(v, task_vars)
|
||||||
include_file = utils.template(tokens[0], task_vars)
|
include_file = utils.template(tokens[0], task_vars)
|
||||||
data = utils.parse_yaml_from_file(utils.path_dwim(self.playbook.basedir, include_file))
|
data = utils.parse_yaml_from_file(utils.path_dwim(self.basedir, include_file))
|
||||||
elif type(x) == dict:
|
elif type(x) == dict:
|
||||||
data = [x]
|
data = [x]
|
||||||
else:
|
else:
|
||||||
|
@ -135,7 +136,7 @@ class Play(object):
|
||||||
|
|
||||||
# *************************************************
|
# *************************************************
|
||||||
|
|
||||||
def _get_vars(self, dirname):
|
def _get_vars(self):
|
||||||
''' load the vars section from a play, accounting for all sorts of variable features
|
''' load the vars section from a play, accounting for all sorts of variable features
|
||||||
including loading from yaml files, prompting, and conditional includes of the first
|
including loading from yaml files, prompting, and conditional includes of the first
|
||||||
file found in a list. '''
|
file found in a list. '''
|
||||||
|
@ -264,7 +265,7 @@ class Play(object):
|
||||||
filename3 = filename2
|
filename3 = filename2
|
||||||
if host is not None:
|
if host is not None:
|
||||||
filename3 = utils.template(filename2, self.playbook.SETUP_CACHE[host])
|
filename3 = utils.template(filename2, self.playbook.SETUP_CACHE[host])
|
||||||
filename4 = utils.path_dwim(self.playbook.basedir, filename3)
|
filename4 = utils.path_dwim(self.basedir, filename3)
|
||||||
sequence.append(filename4)
|
sequence.append(filename4)
|
||||||
if os.path.exists(filename4):
|
if os.path.exists(filename4):
|
||||||
found = True
|
found = True
|
||||||
|
@ -297,7 +298,7 @@ class Play(object):
|
||||||
filename3 = filename2
|
filename3 = filename2
|
||||||
if host is not None:
|
if host is not None:
|
||||||
filename3 = utils.template(filename2, self.playbook.SETUP_CACHE[host])
|
filename3 = utils.template(filename2, self.playbook.SETUP_CACHE[host])
|
||||||
filename4 = utils.path_dwim(self.playbook.basedir, filename3)
|
filename4 = utils.path_dwim(self.basedir, filename3)
|
||||||
if self._has_vars_in(filename4):
|
if self._has_vars_in(filename4):
|
||||||
return
|
return
|
||||||
new_vars = utils.parse_yaml_from_file(filename4)
|
new_vars = utils.parse_yaml_from_file(filename4)
|
||||||
|
|
Loading…
Reference in a new issue