ansible-lint
ansible-lint copied to clipboard
ansible-lint fails when linting a collection installed within ansible-compat cache
Summary
When running molecule==4.0.1 within a collection that has a galaxy.yml file, it will install the collection in to ~/.cache/ansible-compat.
Before being installed into that directory everything works well.
After the collection is installed into ~/.cache/ansible-compat directory if you run ansible-lint it will error out after hitting a permission issue in _mockings.py library.
Issue was introduced from ansible-lint 6.0.0 onwards.
I know where the code that causes the issue is, but havent had the time to get to understand the library yet. Happy to try and make the fix if you can point me in the right direction.
Issue Type
- Bug Report
Ansible and Ansible Lint details
ansible --version
ansible [core 2.13.3]
config file = /Users/jstenhouse/.ansible.cfg
configured module search path = ['/Users/jstenhouse/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /Users/jstenhouse/alpha/infra/ansible/collections/ansible_collections/nvidia/cuda/.venv/lib/python3.10/site-packages/ansible
ansible collection location = /Users/jstenhouse/alpha/infra/ansible/collections
executable location = /Users/jstenhouse/alpha/infra/ansible/collections/ansible_collections/nvidia/cuda/.venv/bin/ansible
python version = 3.10.6 (main, Aug 11 2022, 13:47:18) [Clang 12.0.0 (clang-1200.0.32.29)]
jinja version = 3.1.2
libyaml = True
ansible-lint --version
ansible-lint 6.5.2 using ansible 2.13.3
- ansible installation method: pip
- ansible-lint installation method: pip
OS / ENVIRONMENT
MacOS 10.15.7
STEPS TO REPRODUCE
cd to a collection with a galaxy.yml file and then run the following
ansible-galaxy collection install -v --force -p ~/.cache/ansible-compat/e636c9/collections .
ansible-lint playbooks/image.yml
Where playbook has something similar to this
---
- hosts: all
become: true
gather_facts: false
roles:
- namespace.collection.role_name
Desired Behavior
yamllint to execute successfully
Actual Behavior
when running with ansible-lint 5.4.0 we see success
$ ansible-lint --version
ansible-lint 5.4.0 using ansible 2.13.3
$ ansible-galaxy collection install -v --force -p ~/.cache/ansible-compat/e636c9/collections .
Using /Users/jstenhouse/.ansible.cfg as config file
Starting galaxy collection install process
[WARNING]: The specified collections path '/Users/jstenhouse/.cache/ansible-compat/e636c9/collections' is not part of the configured Ansible collections
paths '/Users/jstenhouse/alpha/infra/ansible/collections'. The installed collection won't be picked up in an Ansible run.
Process install dependency map
Starting collection install process
Installing 'nvidia.cuda:1.0.0' to '/Users/jstenhouse/.cache/ansible-compat/e636c9/collections/ansible_collections/nvidia/cuda'
Created collection for nvidia.cuda:1.0.0 at /Users/jstenhouse/.cache/ansible-compat/e636c9/collections/ansible_collections/nvidia/cuda
nvidia.cuda:1.0.0 was installed successfully
(.venv) jstenhouse cuda ((HEAD detached at FETCH_HEAD))
$ ansible-lint playbooks/cuda-image.yml
(.venv) jstenhouse cuda ((HEAD detached at FETCH_HEAD))
$ echo $?
0
When running with ansible-lint 6.5.2
$ ansible-lint --version
ansible-lint 6.5.2 using ansible 2.13.3
$ ansible-galaxy collection install -v --force -p ~/.cache/ansible-compat/e636c9/collections .
Using /Users/jstenhouse/.ansible.cfg as config file
Starting galaxy collection install process
[WARNING]: The specified collections path '/Users/jstenhouse/.cache/ansible-compat/e636c9/collections' is not part of the configured Ansible collections
paths '/Users/jstenhouse/alpha/infra/ansible/collections'. The installed collection won't be picked up in an Ansible run.
Process install dependency map
Starting collection install process
Installing 'nvidia.cuda:1.0.0' to '/Users/jstenhouse/.cache/ansible-compat/e636c9/collections/ansible_collections/nvidia/cuda'
Created collection for nvidia.cuda:1.0.0 at /Users/jstenhouse/.cache/ansible-compat/e636c9/collections/ansible_collections/nvidia/cuda
nvidia.cuda:1.0.0 was installed successfully
(.venv) jstenhouse cuda ((HEAD detached at FETCH_HEAD))
$ ansible-lint playbooks/cuda-image.yml
Traceback (most recent call last):
File "/Users/jstenhouse/alpha/infra/ansible/collections/ansible_collections/nvidia/cuda/.venv/lib/python3.10/site-packages/ansiblelint/_mockings.py", line 99, in _perform_mockings
if os.readlink(link_path) != target:
OSError: [Errno 22] Invalid argument: '/Users/jstenhouse/.cache/ansible-compat/e636c9/collections/ansible_collections/nvidia/cuda'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/jstenhouse/alpha/infra/ansible/collections/ansible_collections/nvidia/cuda/.venv/bin/ansible-lint", line 8, in <module>
sys.exit(_run_cli_entrypoint())
File "/Users/jstenhouse/alpha/infra/ansible/collections/ansible_collections/nvidia/cuda/.venv/lib/python3.10/site-packages/ansiblelint/__main__.py", line 297, in _run_cli_entrypoint
sys.exit(main(sys.argv))
File "/Users/jstenhouse/alpha/infra/ansible/collections/ansible_collections/nvidia/cuda/.venv/lib/python3.10/site-packages/ansiblelint/__main__.py", line 189, in main
app = get_app(offline=options.offline)
File "/Users/jstenhouse/alpha/infra/ansible/collections/ansible_collections/nvidia/cuda/.venv/lib/python3.10/site-packages/ansiblelint/app.py", line 260, in get_app
_perform_mockings()
File "/Users/jstenhouse/alpha/infra/ansible/collections/ansible_collections/nvidia/cuda/.venv/lib/python3.10/site-packages/ansiblelint/_mockings.py", line 103, in _perform_mockings
link_path.unlink(missing_ok=True)
File "/usr/local/Cellar/[email protected]/3.10.6_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/pathlib.py", line 1206, in unlink
self._accessor.unlink(self)
PermissionError: [Errno 1] Operation not permitted: '/Users/jstenhouse/.cache/ansible-compat/e636c9/collections/ansible_collections/nvidia/cuda'
I am running into the same issue here, it makes it a little bit painful to use the ansible-lint pre-commit stuff.
I think perhaps the problem is that ansible-lint and molecule have two different ways of 'fake' installing collections. ansible-lint does a symbolic link in order to point to the latest code, molecule installs it in an 'isolated' enviroment, but they somehow end up using the same path.. if they could use conflicting paths, that would solve things..
https://github.com/ansible/ansible-lint/blob/76317f12f58101f77f3543a653c211f2a4dd2c57/src/ansiblelint/main.py#L36 https://github.com/ansible/ansible-lint/blob/76317f12f58101f77f3543a653c211f2a4dd2c57/src/ansiblelint/main.py#L108 https://github.com/ansible/ansible-lint/blob/d9cc363e8a767bd239ffe9bce87a0c50d50e2199/src/ansiblelint/app.py#L257
if I see this correctly, there's no way to actually flip/change the cache_dir..
the code that generates the hash/path = https://github.com/ansible/ansible-compat/blob/2140084a6926b6eb911a5ab962e7f0164915620d/src/ansible_compat/prerun.py