@ -271,19 +271,15 @@ class PluginLoader:
# PLUGIN_PATHS_CACHE, and MODULE_CACHE. Since those three dicts key
# PLUGIN_PATHS_CACHE, and MODULE_CACHE. Since those three dicts key
# on the class_name and neither regular modules nor powershell modules
# on the class_name and neither regular modules nor powershell modules
# would have class_names, they would not work as written.
# would have class_names, they would not work as written.
reordered_paths = [ ]
#
win_dirs = [ ]
# The expected sort order is paths in the order in 'ret' with paths ending in '/windows' at the end,
# also in the original order they were found in 'ret'.
for path in ret :
# The .sort() method is guaranteed to be stable, so original order is preserved.
if path . endswith ( ' windows ' ) :
ret . sort ( key = lambda p : p . endswith ( ' /windows ' ) )
win_dirs . append ( path )
else :
reordered_paths . append ( path )
reordered_paths . extend ( win_dirs )
# cache and return the result
# cache and return the result
self . _paths = re ordered_pa ths
self . _paths = ret
return re ordered_pa ths
return ret
def _load_config_defs ( self , name , module , path ) :
def _load_config_defs ( self , name , module , path ) :
''' Reads plugin docs to find configuration setting definitions, to push to config manager for later use '''
''' Reads plugin docs to find configuration setting definitions, to push to config manager for later use '''
@ -317,6 +313,10 @@ class PluginLoader:
display . debug ( ' Added %s to loader search path ' % ( directory ) )
display . debug ( ' Added %s to loader search path ' % ( directory ) )
def _find_fq_plugin ( self , fq_name , extension ) :
def _find_fq_plugin ( self , fq_name , extension ) :
""" Search builtin paths to find a plugin. No external paths are searched,
meaning plugins inside roles inside collections will be ignored .
"""
plugin_type = AnsibleCollectionRef . legacy_plugin_dir_to_plugin_type ( self . subdir )
plugin_type = AnsibleCollectionRef . legacy_plugin_dir_to_plugin_type ( self . subdir )
acr = AnsibleCollectionRef . from_fqcr ( fq_name , plugin_type )
acr = AnsibleCollectionRef . from_fqcr ( fq_name , plugin_type )
@ -397,10 +397,12 @@ class PluginLoader:
try :
try :
# HACK: refactor this properly
# HACK: refactor this properly
if candidate_name . startswith ( ' ansible.legacy ' ) :
if candidate_name . startswith ( ' ansible.legacy ' ) :
# just pass the raw name to the old lookup function to check in all the usual locations
# 'ansible.legacy' refers to the plugin finding behavior used before collections existed.
# They need to search 'library' and the various '*_plugins' directories in order to find the file.
full_name = name
full_name = name
p = self . _find_plugin_legacy ( name . replace ( ' ansible.legacy. ' , ' ' , 1 ) , ignore_deprecated , check_aliases , suffix )
p = self . _find_plugin_legacy ( name . replace ( ' ansible.legacy. ' , ' ' , 1 ) , ignore_deprecated , check_aliases , suffix )
else :
else :
# 'ansible.builtin' should be handled here. This means only internal, or builtin, paths are searched.
full_name , p = self . _find_fq_plugin ( candidate_name , suffix )
full_name , p = self . _find_fq_plugin ( candidate_name , suffix )
if p :
if p :
return full_name , p
return full_name , p
@ -417,6 +419,9 @@ class PluginLoader:
return name , self . _find_plugin_legacy ( name , ignore_deprecated , check_aliases , suffix )
return name , self . _find_plugin_legacy ( name , ignore_deprecated , check_aliases , suffix )
def _find_plugin_legacy ( self , name , ignore_deprecated = False , check_aliases = False , suffix = None ) :
def _find_plugin_legacy ( self , name , ignore_deprecated = False , check_aliases = False , suffix = None ) :
""" Search library and various *_plugins paths in order to find the file.
This was behavior prior to the existence of collections .
"""
if check_aliases :
if check_aliases :
name = self . aliases . get ( name , name )
name = self . aliases . get ( name , name )