@ -322,6 +322,8 @@ class PluginLoader:
acr = AnsibleCollectionRef . from_fqcr ( fq_name , plugin_type )
acr = AnsibleCollectionRef . from_fqcr ( fq_name , plugin_type )
n_resource = to_native ( acr . resource , errors = ' strict ' )
n_resource = to_native ( acr . resource , errors = ' strict ' )
# we want this before the extension is added
full_name = ' {0} . {1} ' . format ( acr . n_python_package_name , n_resource )
if extension :
if extension :
n_resource + = extension
n_resource + = extension
@ -336,10 +338,10 @@ class PluginLoader:
if hasattr ( pkg , ' __loader__ ' ) and isinstance ( pkg . __loader__ , AnsibleFlatMapLoader ) :
if hasattr ( pkg , ' __loader__ ' ) and isinstance ( pkg . __loader__ , AnsibleFlatMapLoader ) :
try :
try :
file_path = pkg . __loader__ . find_file ( n_resource )
file_path = pkg . __loader__ . find_file ( n_resource )
return to_text( file_path )
return full_name, to_text( file_path )
except IOError :
except IOError :
# this loader already takes care of extensionless files, so if we didn't find it, just bail
# this loader already takes care of extensionless files, so if we didn't find it, just bail
return None
return None , None
pkg_path = os . path . dirname ( pkg . __file__ )
pkg_path = os . path . dirname ( pkg . __file__ )
@ -347,27 +349,31 @@ class PluginLoader:
# FIXME: and is file or file link or ...
# FIXME: and is file or file link or ...
if os . path . exists ( n_resource_path ) :
if os . path . exists ( n_resource_path ) :
return to_text( n_resource_path )
return full_name, to_text( n_resource_path )
# look for any matching extension in the package location (sans filter)
# look for any matching extension in the package location (sans filter)
ext_blacklist = [ ' .pyc ' , ' .pyo ' ]
ext_blacklist = [ ' .pyc ' , ' .pyo ' ]
found_files = [ f for f in glob . iglob ( os . path . join ( pkg_path , n_resource ) + ' .* ' ) if os . path . isfile ( f ) and os . path . splitext ( f ) [ 1 ] not in ext_blacklist ]
found_files = [ f for f in glob . iglob ( os . path . join ( pkg_path , n_resource ) + ' .* ' ) if os . path . isfile ( f ) and os . path . splitext ( f ) [ 1 ] not in ext_blacklist ]
if not found_files :
if not found_files :
return None
return None , None
if len ( found_files ) > 1 :
if len ( found_files ) > 1 :
# TODO: warn?
# TODO: warn?
pass
pass
return to_text( found_files [ 0 ] )
return full_name, to_text( found_files [ 0 ] )
def find_plugin ( self , name , mod_type = ' ' , ignore_deprecated = False , check_aliases = False , collection_list = None ) :
def find_plugin ( self , name , mod_type = ' ' , ignore_deprecated = False , check_aliases = False , collection_list = None ) :
''' Find a plugin named name '''
''' Find a plugin named name '''
return self . find_plugin_with_name ( name , mod_type , ignore_deprecated , check_aliases , collection_list ) [ 1 ]
def find_plugin_with_name ( self , name , mod_type = ' ' , ignore_deprecated = False , check_aliases = False , collection_list = None ) :
''' Find a plugin named name '''
global _PLUGIN_FILTERS
global _PLUGIN_FILTERS
if name in _PLUGIN_FILTERS [ self . package ] :
if name in _PLUGIN_FILTERS [ self . package ] :
return None
return None , None
if mod_type :
if mod_type :
suffix = mod_type
suffix = mod_type
@ -392,22 +398,23 @@ class PluginLoader:
# 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
# just pass the raw name to the old lookup function to check in all the usual locations
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 :
p = self . _find_fq_plugin ( candidate_name , suffix )
full_name, p = self . _find_fq_plugin ( candidate_name , suffix )
if p :
if p :
return p
return full_name, p
except Exception as ex :
except Exception as ex :
errors . append ( to_native ( ex ) )
errors . append ( to_native ( ex ) )
if errors :
if errors :
display . debug ( msg = ' plugin lookup for {0} failed; errors: {1} ' . format ( name , ' ; ' . join ( errors ) ) )
display . debug ( msg = ' plugin lookup for {0} failed; errors: {1} ' . format ( name , ' ; ' . join ( errors ) ) )
return None
return None , None
# if we got here, there's no collection list and it's not an FQ name, so do legacy lookup
# if we got here, there's no collection list and it's not an FQ name, so do legacy lookup
return 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 ) :
@ -501,7 +508,10 @@ class PluginLoader:
def _load_module_source ( self , name , path ) :
def _load_module_source ( self , name , path ) :
# avoid collisions across plugins
# avoid collisions across plugins
full_name = ' . ' . join ( [ self . package , name ] )
if name . startswith ( ' ansible_collections. ' ) :
full_name = name
else :
full_name = ' . ' . join ( [ self . package , name ] )
if full_name in sys . modules :
if full_name in sys . modules :
# Avoids double loading, See https://github.com/ansible/ansible/issues/13110
# Avoids double loading, See https://github.com/ansible/ansible/issues/13110
@ -534,7 +544,7 @@ class PluginLoader:
collection_list = kwargs . pop ( ' collection_list ' , None )
collection_list = kwargs . pop ( ' collection_list ' , None )
if name in self . aliases :
if name in self . aliases :
name = self . aliases [ name ]
name = self . aliases [ name ]
path = self . find_plugin ( name , collection_list = collection_list )
name, path = self . find_plugin _with_name ( name , collection_list = collection_list )
if path is None :
if path is None :
return None
return None