Cannot import module from ~/.ansible/plugins/module_utils

Hello,
I develop the modules for comware5.

They run, when are in ansible standard directoriу, for my installation it is /usr/local/Cellar/ansible/2.8.0/libexec/lib/python3.7/site-packages/ansible/

I’ve tried to move them in other directories - in ~/.ansible

at running time of ansible-playbook now I’ve got error:

File “/usr/local/Cellar/ansible/2.8.0/libexec/lib/python3.7/imp.py”, line 171, in load_source
module = _load(spec)
File “”, line 696, in _load
File “”, line 677, in _load_unlocked
File “”, line 728, in exec_module
File “”, line 219, in _call_with_frames_removed
File “/Users/modest/.ansible/plugins/action/comware5_config.py”, line 18, in
from ansible.module_utils.network.comware5.comware5 import comware5_provider_spec
ModuleNotFoundError: No module named ‘ansible.module_utils.network.comware5’

In ansible module I’ve got the string:

from ansible.module_utils.network.comware5.comware5 import comware5_provider_spec

The ansible.conf file is empty.

bob@Mac:~/.ansible$ ansible-config dump| grep MODULE_UTILS_PATH
DEFAULT_MODULE_UTILS_PATH(default) = [‘/Users/bob/.ansible/plugins/module_utils’, ‘/usr/share/ansible/plugins/module_utils’]

bob@Mac:~/.ansible$ uname -a
Darwin Mac.local 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64

bob@Mac:~/.ansible$ tree
.
├── cp
├── modules
│ └── network
│ └── comware5
│ ├── init.py
│ ├── comware5_command.py
│ └── comware5_config.py
├── pc
├── plugins
│ ├── action
│ │ ├── comware5.py
│ │ ├── comware5_config.py
│ │ └── comware5_template.py
│ ├── cliconf
│ │ └── comware5.py
│ ├── doc_fragments
│ │ └── comware5.py
│ ├── module_utils
│ │ ├── init.py
│ │ ├── comware5.py
│ │ └── network
│ │ ├── init.py
│ │ └── comware5
│ │ ├── init.py
│ │ └── comware5.py
│ ├── netconf
│ │ └── comware5.py
│ └── terminal
│ └── comware5.py
└── tmp

15 directories, 15 files
bob@Mac:~/.ansible$

Could you please give me advice, why ansible can not import module from DEFAULT_MODULE_UTILS_PATH?
Where can be my mistake?

Regards,
Modest

bob@Mac:~/.ansible$ ansible --version
ansible 2.8.0
config file = /Users/bob/Work/Ansible/lab/ansible.cfg
configured module search path = [‘/Users/bob/.ansible/plugins/modules’, ‘/usr/share/ansible/plugins/modules’]
ansible python module location = /usr/local/Cellar/ansible/2.8.0/libexec/lib/python3.7/site-packages/ansible
executable location = /usr/local/bin/ansible
python version = 3.7.3 (default, Mar 27 2019, 09:23:15) [Clang 10.0.1 (clang-1001.0.46.3)]

In the pdb I’ve got:

(Pdb) sys.meta_path
[<ansible.utils.collection_loader.AnsibleCollectionLoader object at 0x11010b518>, <class ‘_frozen_importlib.BuiltinImporter’>, <class ‘_frozen_importlib.FrozenImporter’>, <class ‘_frozen_importlib_external.PathFinder’>, <ansible.module_utils.six._SixMetaPathImporter object at 0x10f677438>, <six._SixMetaPathImporter object at 0x11014cc50>, <urllib3.packages.six._SixMetaPathImporter object at 0x110e9c780>]

(Pdb) p sys.path
[‘/usr/local/Cellar/ansible/2.8.0/libexec/bin’, ‘/usr/local/Cellar/ansible/2.8.0/libexec/lib/python37.zip’, ‘/usr/local/Cellar/ansible/2.8.0/libexec/lib/python3.7’, ‘/usr/local/Cellar/ansible/2.8.0/libexec/lib/python3.7/lib-dynload’, ‘/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7’, ‘/usr/local/Cellar/ansible/2.8.0/libexec/lib/python3.7/site-packages’]

Regards,
Modest

If in the code I change

from ansible.module_utils.network.comware5.comware5 import comware5_provider_spec

to

from ansible.module_utils.network import comware5_provider_spec

The ansible-playbook ends with:

File “/Users/bob/.ansible/plugins/action/comware5_config.py”, line 18, in
from ansible.module_utils.network import comware5_provider_spec
ImportError: cannot import name ‘comware5_provider_spec’ from ‘ansible.module_utils.network’ (/usr/local/Cellar/ansible/2.8.0/libexec/lib/python3.7/site-packages/ansible/module_utils/network/init.py)

Does this mean, that ansible doesn’t use $DEFAULT_MODULE_UTILS_PATH? that is

DEFAULT_MODULE_UTILS_PATH(default) = [‘/Users/bob/.ansible/plugins/module_utils’, ‘/usr/share/ansible/plugins/module_utils’]

Hello.

I was able to solve problem.

It seems, the rule from documentation "The ansible.module_utils namespace is not a plain Python package: it is constructed dynamically for each task invocation, by extracting imports and resolving those matching the namespace against a search path derived from the active configuration. " is not working for action plugins.

It will be very useful, if information about this point was in ansible documentation too.

Regards,
Modest Sokolov

Action plugins can reference ansible.module_utils but only for ones in the base Ansible package. Module can take advantage of the lookup path as it is built for you automatically and sent across to the remote host.

Feel free to raise a PR to the Ansible docs at https://github.com/ansible/ansible/tree/devel/docs/docsite/rst if you want to clarify it further https://github.com/ansible/ansible/tree/devel/docs/docsite/rst.

Thanks

Jordan

Jordan, thanks a lot.

https://github.com/ansible/ansible/issues/58490

пт, 28 июн. 2019 г. в 01:20, Jordan Borean <jborean93@gmail.com>: