Optimizations in mod_args parsing
* Make it less likely that we have to identify all the modules during a playbook run. PluginLoader is optimized to look for modules one directory at a time. If we find a module before we've examined all the directories we never have to touch the other directories. Reordering this conditional makes it so tasks which don't have a module file will not force us to examine all the module directories before moving on to other sources of task actions. * Change several variables we consult to see if a task is in a certain category from lists/tuples to frozensets. These are static lists which we only do containment tests on so frozensets should be faster
This commit is contained in:
parent
1f824bd620
commit
9890ce47e8
1 changed files with 20 additions and 9 deletions
|
@ -28,12 +28,16 @@ from ansible.template import Templar
|
||||||
|
|
||||||
|
|
||||||
# For filtering out modules correctly below
|
# For filtering out modules correctly below
|
||||||
RAW_PARAM_MODULES = ([
|
FREEFORM_ACTIONS = frozenset((
|
||||||
'command',
|
'command',
|
||||||
'win_command',
|
'win_command',
|
||||||
'shell',
|
'shell',
|
||||||
'win_shell',
|
'win_shell',
|
||||||
'script',
|
'script',
|
||||||
|
'raw'
|
||||||
|
))
|
||||||
|
|
||||||
|
RAW_PARAM_MODULES = FREEFORM_ACTIONS.union((
|
||||||
'include',
|
'include',
|
||||||
'include_vars',
|
'include_vars',
|
||||||
'include_tasks',
|
'include_tasks',
|
||||||
|
@ -43,9 +47,17 @@ RAW_PARAM_MODULES = ([
|
||||||
'add_host',
|
'add_host',
|
||||||
'group_by',
|
'group_by',
|
||||||
'set_fact',
|
'set_fact',
|
||||||
'raw',
|
|
||||||
'meta',
|
'meta',
|
||||||
])
|
))
|
||||||
|
|
||||||
|
BUILTIN_TASKS = frozenset((
|
||||||
|
'meta',
|
||||||
|
'include',
|
||||||
|
'include_tasks',
|
||||||
|
'include_role',
|
||||||
|
'import_tasks',
|
||||||
|
'import_role'
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
class ModuleArgsParser:
|
class ModuleArgsParser:
|
||||||
|
@ -158,7 +170,7 @@ class ModuleArgsParser:
|
||||||
|
|
||||||
# only internal variables can start with an underscore, so
|
# only internal variables can start with an underscore, so
|
||||||
# we don't allow users to set them directly in arguments
|
# we don't allow users to set them directly in arguments
|
||||||
if args and action not in ('command', 'win_command', 'shell', 'win_shell', 'script', 'raw'):
|
if args and action not in FREEFORM_ACTIONS:
|
||||||
for arg in args:
|
for arg in args:
|
||||||
arg = to_text(arg)
|
arg = to_text(arg)
|
||||||
if arg.startswith('_ansible_'):
|
if arg.startswith('_ansible_'):
|
||||||
|
@ -189,7 +201,7 @@ class ModuleArgsParser:
|
||||||
args = thing
|
args = thing
|
||||||
elif isinstance(thing, string_types):
|
elif isinstance(thing, string_types):
|
||||||
# form is like: copy: src=a dest=b
|
# form is like: copy: src=a dest=b
|
||||||
check_raw = action in ('command', 'win_command', 'shell', 'win_shell', 'script', 'raw')
|
check_raw = action in FREEFORM_ACTIONS
|
||||||
args = parse_kv(thing, check_raw=check_raw)
|
args = parse_kv(thing, check_raw=check_raw)
|
||||||
elif thing is None:
|
elif thing is None:
|
||||||
# this can happen with modules which take no params, like ping:
|
# this can happen with modules which take no params, like ping:
|
||||||
|
@ -214,21 +226,20 @@ class ModuleArgsParser:
|
||||||
action = None
|
action = None
|
||||||
args = None
|
args = None
|
||||||
|
|
||||||
actions_allowing_raw = ('command', 'win_command', 'shell', 'win_shell', 'script', 'raw')
|
|
||||||
if isinstance(thing, dict):
|
if isinstance(thing, dict):
|
||||||
# form is like: action: { module: 'copy', src: 'a', dest: 'b' }
|
# form is like: action: { module: 'copy', src: 'a', dest: 'b' }
|
||||||
thing = thing.copy()
|
thing = thing.copy()
|
||||||
if 'module' in thing:
|
if 'module' in thing:
|
||||||
action, module_args = self._split_module_string(thing['module'])
|
action, module_args = self._split_module_string(thing['module'])
|
||||||
args = thing.copy()
|
args = thing.copy()
|
||||||
check_raw = action in actions_allowing_raw
|
check_raw = action in FREEFORM_ACTIONS
|
||||||
args.update(parse_kv(module_args, check_raw=check_raw))
|
args.update(parse_kv(module_args, check_raw=check_raw))
|
||||||
del args['module']
|
del args['module']
|
||||||
|
|
||||||
elif isinstance(thing, string_types):
|
elif isinstance(thing, string_types):
|
||||||
# form is like: action: copy src=a dest=b
|
# form is like: action: copy src=a dest=b
|
||||||
(action, args) = self._split_module_string(thing)
|
(action, args) = self._split_module_string(thing)
|
||||||
check_raw = action in actions_allowing_raw
|
check_raw = action in FREEFORM_ACTIONS
|
||||||
args = parse_kv(args, check_raw=check_raw)
|
args = parse_kv(args, check_raw=check_raw)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -275,7 +286,7 @@ class ModuleArgsParser:
|
||||||
|
|
||||||
# walk the input dictionary to see we recognize a module name
|
# walk the input dictionary to see we recognize a module name
|
||||||
for (item, value) in iteritems(self._task_ds):
|
for (item, value) in iteritems(self._task_ds):
|
||||||
if item in module_loader or item in action_loader or item in ['meta', 'include', 'include_tasks', 'include_role', 'import_tasks', 'import_role']:
|
if item in BUILTIN_TASKS or item in action_loader or item in module_loader:
|
||||||
# finding more than one module name is a problem
|
# finding more than one module name is a problem
|
||||||
if action is not None:
|
if action is not None:
|
||||||
raise AnsibleParserError("conflicting action statements: %s, %s" % (action, item), obj=self._task_ds)
|
raise AnsibleParserError("conflicting action statements: %s, %s" % (action, item), obj=self._task_ds)
|
||||||
|
|
Loading…
Reference in a new issue