minimize loading files/plugins

avoids some repetitive loading
 - read config file only once
 - now cache the ini parser per file
 - optimize shell plugin loading

tried to 'optimize' vars_plugins loading but it creates issues with precedence,
probalby due to iterator not being reset, will look into it in subsequent fix/PR

(cherry picked from commit 42912e1ac8)
pull/39358/merge
Brian Coca 7 years ago committed by Brian Coca
parent b595c6254f
commit 18d0fe6b30

@ -0,0 +1,2 @@
bugfixes:
- avoid uneeded reloading of plugin files https://github.com/ansible/ansible/pull/37648

@ -173,7 +173,7 @@ class ConfigManager(object):
self._base_defs = {} self._base_defs = {}
self._plugins = {} self._plugins = {}
self._parser = None self._parsers = {}
self._config_file = conf_file self._config_file = conf_file
self.data = ConfigData() self.data = ConfigData()
@ -214,15 +214,15 @@ class ConfigManager(object):
ftype = get_config_type(cfile) ftype = get_config_type(cfile)
if cfile is not None: if cfile is not None:
if ftype == 'ini': if ftype == 'ini':
self._parser = configparser.ConfigParser() self._parsers[cfile] = configparser.ConfigParser()
try: try:
self._parser.read(cfile) self._parsers[cfile].read(cfile)
except configparser.Error as e: except configparser.Error as e:
raise AnsibleOptionsError("Error reading config file (%s): %s" % (cfile, to_native(e))) raise AnsibleOptionsError("Error reading config file (%s): %s" % (cfile, to_native(e)))
# FIXME: this should eventually handle yaml config files # FIXME: this should eventually handle yaml config files
# elif ftype == 'yaml': # elif ftype == 'yaml':
# with open(cfile, 'rb') as config_stream: # with open(cfile, 'rb') as config_stream:
# self._parser = yaml.safe_load(config_stream) # self._parsers[cfile] = yaml.safe_load(config_stream)
else: else:
raise AnsibleOptionsError("Unsupported configuration file type: %s" % to_native(ftype)) raise AnsibleOptionsError("Unsupported configuration file type: %s" % to_native(ftype))
@ -288,9 +288,8 @@ class ConfigManager(object):
''' Given a config key figure out the actual value and report on the origin of the settings ''' ''' Given a config key figure out the actual value and report on the origin of the settings '''
if cfile is None: if cfile is None:
# use default config
cfile = self._config_file cfile = self._config_file
else:
self._parse_config_file(cfile)
# Note: sources that are lists listed in low to high precedence (last one wins) # Note: sources that are lists listed in low to high precedence (last one wins)
value = None value = None
@ -320,6 +319,9 @@ class ConfigManager(object):
origin = 'env: %s' % origin origin = 'env: %s' % origin
# try config file entries next, if we have one # try config file entries next, if we have one
if self._parsers.get(cfile, None) is None:
self._parse_config_file(cfile)
if value is None and cfile is not None: if value is None and cfile is not None:
ftype = get_config_type(cfile) ftype = get_config_type(cfile)
if ftype and defs[config].get(ftype): if ftype and defs[config].get(ftype):
@ -327,7 +329,7 @@ class ConfigManager(object):
# load from ini config # load from ini config
try: # FIXME: generalize _loop_entries to allow for files also, most of this code is dupe try: # FIXME: generalize _loop_entries to allow for files also, most of this code is dupe
for ini_entry in defs[config]['ini']: for ini_entry in defs[config]['ini']:
temp_value = get_ini_config_value(self._parser, ini_entry) temp_value = get_ini_config_value(self._parsers[cfile], ini_entry)
if temp_value is not None: if temp_value is not None:
value = temp_value value = temp_value
origin = cfile origin = cfile

@ -91,10 +91,15 @@ class ConnectionBase(AnsiblePlugin):
else: else:
shell_type = 'sh' shell_type = 'sh'
shell_filename = os.path.basename(self._play_context.executable) shell_filename = os.path.basename(self._play_context.executable)
for shell in shell_loader.all(): try:
if shell_filename in shell.COMPATIBLE_SHELLS: shell = shell_loader.get(shell_filename)
shell_type = shell.SHELL_FAMILY except Exception:
break shell = None
if shell is None:
for shell in shell_loader.all():
if shell_filename in shell.COMPATIBLE_SHELLS:
break
shell_type = shell.SHELL_FAMILY
self._shell = shell_loader.get(shell_type) self._shell = shell_loader.get(shell_type)
if not self._shell: if not self._shell:

@ -241,6 +241,7 @@ class VariableManager:
inventory_dir = os.path.dirname(inventory_dir) inventory_dir = os.path.dirname(inventory_dir)
for plugin in vars_loader.all(): for plugin in vars_loader.all():
data = combine_vars(data, _get_plugin_vars(plugin, inventory_dir, entities)) data = combine_vars(data, _get_plugin_vars(plugin, inventory_dir, entities))
return data return data
@ -248,6 +249,7 @@ class VariableManager:
''' merges all entities adjacent to play ''' ''' merges all entities adjacent to play '''
data = {} data = {}
for plugin in vars_loader.all(): for plugin in vars_loader.all():
for path in basedirs: for path in basedirs:
data = combine_vars(data, _get_plugin_vars(plugin, path, entities)) data = combine_vars(data, _get_plugin_vars(plugin, path, entities))
return data return data

Loading…
Cancel
Save