|
|
@ -119,9 +119,71 @@ class Play(object):
|
|
|
|
|
|
|
|
|
|
|
|
# *************************************************
|
|
|
|
# *************************************************
|
|
|
|
|
|
|
|
|
|
|
|
def _load_roles(self, roles, ds):
|
|
|
|
def _get_role_path(self, role):
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
Returns the path on disk to the directory containing
|
|
|
|
|
|
|
|
the role directories like tasks, templates, etc. Also
|
|
|
|
|
|
|
|
returns any variables that were included with the role
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
orig_path = template(self.basedir,role,self.vars)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
role_vars = {}
|
|
|
|
|
|
|
|
if type(orig_path) == dict:
|
|
|
|
|
|
|
|
# what, not a path?
|
|
|
|
|
|
|
|
role_name = orig_path.get('role', None)
|
|
|
|
|
|
|
|
if role_name is None:
|
|
|
|
|
|
|
|
raise errors.AnsibleError("expected a role name in dictionary: %s" % orig_path)
|
|
|
|
|
|
|
|
role_vars = orig_path
|
|
|
|
|
|
|
|
orig_path = role_name
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
path = utils.path_dwim(self.basedir, os.path.join('roles', orig_path))
|
|
|
|
|
|
|
|
if not os.path.isdir(path) and not orig_path.startswith(".") and not orig_path.startswith("/"):
|
|
|
|
|
|
|
|
path2 = utils.path_dwim(self.basedir, orig_path)
|
|
|
|
|
|
|
|
if not os.path.isdir(path2):
|
|
|
|
|
|
|
|
raise errors.AnsibleError("cannot find role in %s or %s" % (path, path2))
|
|
|
|
|
|
|
|
path = path2
|
|
|
|
|
|
|
|
elif not os.path.isdir(path):
|
|
|
|
|
|
|
|
raise errors.AnsibleError("cannot find role in %s" % (path))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (path, role_vars)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _build_role_dependencies(self, roles, dep_stack, passed_vars={}, level=0):
|
|
|
|
|
|
|
|
# this number is arbitrary, but it seems sane
|
|
|
|
|
|
|
|
if level > 20:
|
|
|
|
|
|
|
|
raise errors.AnsibleError("too many levels of recursion while resolving role dependencies")
|
|
|
|
|
|
|
|
for role in roles:
|
|
|
|
|
|
|
|
role_path,role_vars = self._get_role_path(role)
|
|
|
|
|
|
|
|
# the meta directory contains the yaml that should
|
|
|
|
|
|
|
|
# hold the list of dependencies (if any)
|
|
|
|
|
|
|
|
meta = self._resolve_main(utils.path_dwim(self.basedir, os.path.join(role_path, 'meta')))
|
|
|
|
|
|
|
|
if os.path.isfile(meta):
|
|
|
|
|
|
|
|
data = utils.parse_yaml_from_file(meta)
|
|
|
|
|
|
|
|
if data:
|
|
|
|
|
|
|
|
dependencies = data.get('dependencies',[])
|
|
|
|
|
|
|
|
for dep in dependencies:
|
|
|
|
|
|
|
|
(dep_path,dep_vars) = self._get_role_path(dep)
|
|
|
|
|
|
|
|
vars = self._resolve_main(utils.path_dwim(self.basedir, os.path.join(dep_path, 'vars')))
|
|
|
|
|
|
|
|
vars_data = {}
|
|
|
|
|
|
|
|
if os.path.isfile(vars):
|
|
|
|
|
|
|
|
vars_data = utils.parse_yaml_from_file(vars)
|
|
|
|
|
|
|
|
dep_vars.update(role_vars)
|
|
|
|
|
|
|
|
for k in passed_vars.keys():
|
|
|
|
|
|
|
|
if not k in dep_vars:
|
|
|
|
|
|
|
|
dep_vars[k] = passed_vars[k]
|
|
|
|
|
|
|
|
for k in vars_data.keys():
|
|
|
|
|
|
|
|
if not k in dep_vars:
|
|
|
|
|
|
|
|
dep_vars[k] = vars_data[k]
|
|
|
|
|
|
|
|
if 'role' in dep_vars:
|
|
|
|
|
|
|
|
del dep_vars['role']
|
|
|
|
|
|
|
|
self._build_role_dependencies([dep], dep_stack, passed_vars=dep_vars, level=level+1)
|
|
|
|
|
|
|
|
dep_stack.append([dep,dep_path,dep_vars])
|
|
|
|
|
|
|
|
# only add the current role when we're at the top level,
|
|
|
|
|
|
|
|
# otherwise we'll end up in a recursive loop
|
|
|
|
|
|
|
|
if level == 0:
|
|
|
|
|
|
|
|
dep_stack.append([role,role_path,role_vars])
|
|
|
|
|
|
|
|
return dep_stack
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _load_roles(self, roles, ds):
|
|
|
|
# a role is a name that auto-includes the following if they exist
|
|
|
|
# a role is a name that auto-includes the following if they exist
|
|
|
|
# <rolename>/tasks/main.yml
|
|
|
|
# <rolename>/tasks/main.yml
|
|
|
|
# <rolename>/handlers/main.yml
|
|
|
|
# <rolename>/handlers/main.yml
|
|
|
@ -147,52 +209,35 @@ class Play(object):
|
|
|
|
# flush handlers after pre_tasks
|
|
|
|
# flush handlers after pre_tasks
|
|
|
|
new_tasks.append(dict(meta='flush_handlers'))
|
|
|
|
new_tasks.append(dict(meta='flush_handlers'))
|
|
|
|
|
|
|
|
|
|
|
|
# variables if the role was parameterized (i.e. given as a hash)
|
|
|
|
roles = self._build_role_dependencies(roles, [], self.vars)
|
|
|
|
has_dict = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for role_path in roles:
|
|
|
|
|
|
|
|
orig_path = template(self.basedir,role_path,self.vars)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if type(orig_path) == dict:
|
|
|
|
|
|
|
|
# what, not a path?
|
|
|
|
|
|
|
|
role_name = orig_path.get('role', None)
|
|
|
|
|
|
|
|
if role_name is None:
|
|
|
|
|
|
|
|
raise errors.AnsibleError("expected a role name in dictionary: %s" % orig_path)
|
|
|
|
|
|
|
|
has_dict = orig_path
|
|
|
|
|
|
|
|
orig_path = role_name
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for role,role_path,role_vars in roles:
|
|
|
|
# special vars must be extracted from the dict to the included tasks
|
|
|
|
# special vars must be extracted from the dict to the included tasks
|
|
|
|
special_keys = [ "sudo", "sudo_user", "when", "with_items" ]
|
|
|
|
special_keys = [ "sudo", "sudo_user", "when", "with_items" ]
|
|
|
|
special_vars = {}
|
|
|
|
special_vars = {}
|
|
|
|
for k in special_keys:
|
|
|
|
for k in special_keys:
|
|
|
|
if k in has_dict:
|
|
|
|
if k in role_vars:
|
|
|
|
special_vars[k] = has_dict[k]
|
|
|
|
special_vars[k] = role_vars[k]
|
|
|
|
|
|
|
|
|
|
|
|
path = utils.path_dwim(self.basedir, os.path.join('roles', orig_path))
|
|
|
|
task_basepath = utils.path_dwim(self.basedir, os.path.join(role_path, 'tasks'))
|
|
|
|
if not os.path.isdir(path) and not orig_path.startswith(".") and not orig_path.startswith("/"):
|
|
|
|
handler_basepath = utils.path_dwim(self.basedir, os.path.join(role_path, 'handlers'))
|
|
|
|
path2 = utils.path_dwim(self.basedir, orig_path)
|
|
|
|
vars_basepath = utils.path_dwim(self.basedir, os.path.join(role_path, 'vars'))
|
|
|
|
if not os.path.isdir(path2):
|
|
|
|
|
|
|
|
raise errors.AnsibleError("cannot find role in %s or %s" % (path, path2))
|
|
|
|
|
|
|
|
path = path2
|
|
|
|
|
|
|
|
elif not os.path.isdir(path):
|
|
|
|
|
|
|
|
raise errors.AnsibleError("cannot find role in %s" % (path))
|
|
|
|
|
|
|
|
task_basepath = utils.path_dwim(self.basedir, os.path.join(path, 'tasks'))
|
|
|
|
|
|
|
|
handler_basepath = utils.path_dwim(self.basedir, os.path.join(path, 'handlers'))
|
|
|
|
|
|
|
|
vars_basepath = utils.path_dwim(self.basedir, os.path.join(path, 'vars'))
|
|
|
|
|
|
|
|
task = self._resolve_main(task_basepath)
|
|
|
|
task = self._resolve_main(task_basepath)
|
|
|
|
handler = self._resolve_main(handler_basepath)
|
|
|
|
handler = self._resolve_main(handler_basepath)
|
|
|
|
vars_file = self._resolve_main(vars_basepath)
|
|
|
|
vars_file = self._resolve_main(vars_basepath)
|
|
|
|
library = utils.path_dwim(self.basedir, os.path.join(path, 'library'))
|
|
|
|
library = utils.path_dwim(self.basedir, os.path.join(role_path, 'library'))
|
|
|
|
|
|
|
|
|
|
|
|
if not os.path.isfile(task) and not os.path.isfile(handler) and not os.path.isfile(vars_file) and not os.path.isdir(library):
|
|
|
|
if not os.path.isfile(task) and not os.path.isfile(handler) and not os.path.isfile(vars_file) and not os.path.isdir(library):
|
|
|
|
raise errors.AnsibleError("found role at %s, but cannot find %s or %s or %s or %s" % (path, task, handler, vars_file, library))
|
|
|
|
raise errors.AnsibleError("found role at %s, but cannot find %s or %s or %s or %s" % (role_path, task, handler, vars_file, library))
|
|
|
|
if os.path.isfile(task):
|
|
|
|
if os.path.isfile(task):
|
|
|
|
nt = dict(include=pipes.quote(task), vars=has_dict)
|
|
|
|
nt = dict(include=pipes.quote(task), vars=role_vars)
|
|
|
|
for k in special_keys:
|
|
|
|
for k in special_keys:
|
|
|
|
if k in special_vars:
|
|
|
|
if k in special_vars:
|
|
|
|
nt[k] = special_vars[k]
|
|
|
|
nt[k] = special_vars[k]
|
|
|
|
new_tasks.append(nt)
|
|
|
|
new_tasks.append(nt)
|
|
|
|
if os.path.isfile(handler):
|
|
|
|
if os.path.isfile(handler):
|
|
|
|
nt = dict(include=pipes.quote(handler), vars=has_dict)
|
|
|
|
nt = dict(include=pipes.quote(handler), vars=role_vars)
|
|
|
|
for k in special_keys:
|
|
|
|
for k in special_keys:
|
|
|
|
if k in special_vars:
|
|
|
|
if k in special_vars:
|
|
|
|
nt[k] = special_vars[k]
|
|
|
|
nt[k] = special_vars[k]
|
|
|
@ -202,10 +247,9 @@ class Play(object):
|
|
|
|
if os.path.isdir(library):
|
|
|
|
if os.path.isdir(library):
|
|
|
|
utils.plugins.module_finder.add_directory(library)
|
|
|
|
utils.plugins.module_finder.add_directory(library)
|
|
|
|
|
|
|
|
|
|
|
|
tasks = ds.get('tasks', None)
|
|
|
|
tasks = ds.get('tasks', None)
|
|
|
|
post_tasks = ds.get('post_tasks', None)
|
|
|
|
post_tasks = ds.get('post_tasks', None)
|
|
|
|
|
|
|
|
handlers = ds.get('handlers', None)
|
|
|
|
handlers = ds.get('handlers', None)
|
|
|
|
|
|
|
|
vars_files = ds.get('vars_files', None)
|
|
|
|
vars_files = ds.get('vars_files', None)
|
|
|
|
|
|
|
|
|
|
|
|
if type(tasks) != list:
|
|
|
|
if type(tasks) != list:
|
|
|
@ -223,8 +267,10 @@ class Play(object):
|
|
|
|
new_tasks.extend(post_tasks)
|
|
|
|
new_tasks.extend(post_tasks)
|
|
|
|
# flush handlers after post tasks
|
|
|
|
# flush handlers after post tasks
|
|
|
|
new_tasks.append(dict(meta='flush_handlers'))
|
|
|
|
new_tasks.append(dict(meta='flush_handlers'))
|
|
|
|
|
|
|
|
|
|
|
|
new_handlers.extend(handlers)
|
|
|
|
new_handlers.extend(handlers)
|
|
|
|
new_vars_files.extend(vars_files)
|
|
|
|
new_vars_files.extend(vars_files)
|
|
|
|
|
|
|
|
|
|
|
|
ds['tasks'] = new_tasks
|
|
|
|
ds['tasks'] = new_tasks
|
|
|
|
ds['handlers'] = new_handlers
|
|
|
|
ds['handlers'] = new_handlers
|
|
|
|
ds['vars_files'] = new_vars_files
|
|
|
|
ds['vars_files'] = new_vars_files
|
|
|
|