New to ansible, are there quirks around symlinks and the builtin file module? Potentially related to the need for older python?

I am new to ansible and am adapting some EOL software to work on a non-target platform. This is a very old application, but I have a business requirement to get it working on a newer OS. At this point, it requires Python 2.7, which is likely the source of my headaches, but I’m not sure if there’s a way to work through it. I have been on an ansible learning journey for some time, and even if I can’t solve this specific issue, I’m interested in trying to understand why it doesn’t work because from what I see/understand, it should. The specific ansible playbook I’m looking at is here:

https://github.com/PaloAltoNetworks/minemeld-ansible/blob/master/roles/minemeld/tasks/main.yml

Specifically, the following is giving me errors:

set permissions after install

  • name: minemeld directory permissions
    file: path=“{{main_directory}}” state=directory recurse=yes owner=minemeld group=minemeld mode=“{{file_permissions}}”

I am getting the following error output on that step:

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: OSError: [Errno 95] Operation not supported: ‘/opt/minemeld/www/webui/node_modules/gulp-useref/node_modules/.bin/strip-bom’
fatal: [127.0.0.1]: FAILED! => {“changed”: false, “module_stderr”: "Traceback (most recent call last):
File "/root/.ansible/tmp/ansible-tmp-1655840506.6-201342-88045696314185/AnsiballZ_file.py", line 100, in
_ansiballz_main()
File "/root/.ansible/tmp/ansible-tmp-1655840506.6-201342-88045696314185/AnsiballZ_file.py", line 92, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/root/.ansible/tmp/ansible-tmp-1655840506.6-201342-88045696314185/AnsiballZ_file.py", line 41, in invoke_module
run_name=‘main’, alter_sys=True)
File "/usr/lib/python2.7/runpy.py", line 188, in run_module
fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 82, in _run_module_code
mod_name, mod_fname, mod_loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/tmp/ansible_file_payload_QSceSb/ansible_file_payload.zip/ansible/modules/file.py", line 966, in
File "/tmp/ansible_file_payload_QSceSb/ansible_file_payload.zip/ansible/modules/file.py", line 952, in main
File "/tmp/ansible_file_payload_QSceSb/ansible_file_payload.zip/ansible/modules/file.py", line 672, in ensure_directory
File "/tmp/ansible_file_payload_QSceSb/ansible_file_payload.zip/ansible/modules/file.py", line 354, in recursive_set_attributes
File "/tmp/ansible_file_payload_QSceSb/ansible_file_payload.zip/ansible/module_utils/basic.py", line 1170, in set_fs_attributes_if_different
File "/tmp/ansible_file_payload_QSceSb/ansible_file_payload.zip/ansible/module_utils/basic.py", line 926, in set_mode_if_different
OSError: [Errno 95] Operation not supported: ‘/opt/minemeld/www/webui/node_modules/gulp-useref/node_modules/.bin/strip-bom’
", “module_stdout”: “”, “msg”: “MODULE FAILURE
See stdout/stderr for the exact error”, “rc”: 1}

This is the error I am getting when ansible tries to do anything to a symlink. That directory is the following:

ls -as1l /opt/minemeld/www/webui/node_modules/gulp-useref/node_modules/.bin/

total 8
4 drwxrwxr-x 2 minemeld minemeld 4096 Jun 21 20:13 .
4 drwxrwxr-x 19 minemeld minemeld 4096 Jun 21 20:13 …
0 lrwxrwxrwx 1 root root 20 Jun 21 20:13 mkdirp → …/mkdirp/bin/cmd.js
0 lrwxrwxrwx 1 minemeld minemeld 19 Jun 21 20:13 strip-bom → …/strip-bom/cli.js

I have modified the playbook to change follow=no, to no improvement. I am running the playbook as root for testing, and there are no strange mounts like NFS or CIFS, it’s just the native filesystem.

This is an ubuntu 22.04 server, and the python/ansible environment looks like this:

ansible-playbook --version

[DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the controller starting with Ansible 2.12. Current version: 2.7.18 (default, Mar 12 2022, 06:24:29) [GCC 11.2.0]. This feature will be
removed from ansible-core in version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
/usr/local/lib/python2.7/dist-packages/ansible/parsing/vault/init.py:44: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in the next release.
from cryptography.exceptions import InvalidSignature
ansible-playbook [core 2.11.12]
config file = None
configured module search path = [u’/root/.ansible/plugins/modules’, u’/usr/share/ansible/plugins/modules’]
ansible python module location = /usr/local/lib/python2.7/dist-packages/ansible
ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/local/bin/ansible-playbook
python version = 2.7.18 (default, Mar 12 2022, 06:24:29) [GCC 11.2.0]
jinja version = 2.11.3
libyaml = True

Any help or information is appreciated; I think there is a solution to getting the app running using docker, but I’m still curious as to why this step in ansible (or any step around copying/modifying symlinks) is failing.

First, the requirements on the controller (machine you execute ansible
from) and the target are different, even 2.13 still supports
pytyhon2.7 on the targets.

That you got 'MODULE FAILURE' normally means a bug in the module, but
before you open a ticket i would test with the latest version. From
the error it seems it is trying to change the permissions on the
symlink itself which is normally a no-op/not supported, depending on
the filesystem and OS.

for dealing with symlinks the default should be 'follow', but in any
case you can control this in your play
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html#parameter-follow

Thanks for the reply (here and on reddit.) This is totally local for now while I dev it, so the controller is the target.

I tried the playbook with the default, and with “follow=no” and got the same behavior.

I’m trying to install a newer ansible; that being said, I’m not finding which one I should use? This page has 2 links to version requirements, but the links appear to be dead as of the time I’m writing: https://docs.ansible.com/ansible/latest/dev_guide/developing_python_3.html#minimum-version-of-python-3-x-and-python-2-x

Looking here, it seems I should go with 2.12 or 2.13: https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html

That being said, neither are an option for how it’s currently available:

pip install ansible-core==2.13

DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
ERROR: Could not find a version that satisfies the requirement ansible-core==2.13 (from versions: 0.0.1a1, 2.11.0b1, 2.11.0b2, 2.11.0b3, 2.11.0b4, 2.11.0rc1, 2.11.0rc2, 2.11.0, 2.11.1rc1, 2.11.1, 2.11.2rc1, 2.11.2, 2.11.3rc1, 2.11.3, 2.11.4rc1, 2.11.4, 2.11.5rc1, 2.11.5, 2.11.6rc1, 2.11.6, 2.11.7rc1, 2.11.7, 2.11.8rc1, 2.11.8, 2.11.9rc1, 2.11.9, 2.11.10rc1, 2.11.10, 2.11.11rc1, 2.11.11, 2.11.12rc1, 2.11.12)
ERROR: No matching distribution found for ansible-core==2.13

Looking around, I don’t see a way to explicitly specify the “community” or not release, unless just “ansible” points to the community release? The version numbers make it seem like that’s the case:

pip install ansible==6.0

DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
ERROR: Could not find a version that satisfies the requirement ansible==6.0 (from versions: 1.0, 1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 1.3.0, 1.3.1, 1.3.2, 1.3.3, 1.3.4, 1.4, 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.5, 1.5.1, 1.5.2, 1.5.3, 1.5.4, 1.5.5, 1.6, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.6.5, 1.6.6, 1.6.7, 1.6.8, 1.6.9, 1.6.10, 1.7, 1.7.1, 1.7.2, 1.8, 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.9.0.1, 1.9.1, 1.9.2, 1.9.3, 1.9.4, 1.9.5, 1.9.6, 2.0.0.0, 2.0.0.1, 2.0.0.2, 2.0.1.0, 2.0.2.0, 2.1.0.0, 2.1.1.0, 2.1.2.0, 2.1.3.0, 2.1.4.0, 2.1.5.0, 2.1.6.0, 2.2.0.0, 2.2.1.0, 2.2.2.0, 2.2.3.0, 2.3.0.0, 2.3.1.0, 2.3.2.0, 2.3.3.0, 2.4.0.0, 2.4.1.0, 2.4.2.0, 2.4.3.0, 2.4.4.0, 2.4.5.0, 2.4.6.0, 2.5.0a1, 2.5.0b1, 2.5.0b2, 2.5.0rc1, 2.5.0rc2, 2.5.0rc3, 2.5.0, 2.5.1, 2.5.2, 2.5.3, 2.5.4, 2.5.5, 2.5.6, 2.5.7, 2.5.8, 2.5.9, 2.5.10, 2.5.11, 2.5.12, 2.5.13, 2.5.14, 2.5.15, 2.6.0a1, 2.6.0a2, 2.6.0rc1, 2.6.0rc2, 2.6.0rc3, 2.6.0rc4, 2.6.0rc5, 2.6.0, 2.6.1, 2.6.2, 2.6.3, 2.6.4, 2.6.5, 2.6.6, 2.6.7, 2.6.8, 2.6.9, 2.6.10, 2.6.11, 2.6.12, 2.6.13, 2.6.14, 2.6.15, 2.6.16, 2.6.17, 2.6.18, 2.6.19, 2.6.20, 2.7.0.dev0, 2.7.0a1, 2.7.0b1, 2.7.0rc1, 2.7.0rc2, 2.7.0rc3, 2.7.0rc4, 2.7.0, 2.7.1, 2.7.2, 2.7.3, 2.7.4, 2.7.5, 2.7.6, 2.7.7, 2.7.8, 2.7.9, 2.7.10, 2.7.11, 2.7.12, 2.7.13, 2.7.14, 2.7.15, 2.7.16, 2.7.17, 2.7.18, 2.8.0a1, 2.8.0b1, 2.8.0rc1, 2.8.0rc2, 2.8.0rc3, 2.8.0, 2.8.1, 2.8.2, 2.8.3, 2.8.4, 2.8.5, 2.8.6, 2.8.7, 2.8.8, 2.8.9, 2.8.10, 2.8.11, 2.8.12, 2.8.13, 2.8.14, 2.8.15, 2.8.16rc1, 2.8.16, 2.8.17rc1, 2.8.17, 2.8.18rc1, 2.8.18, 2.8.19rc1, 2.8.19, 2.8.20rc1, 2.8.20, 2.9.0b1, 2.9.0rc1, 2.9.0rc2, 2.9.0rc3, 2.9.0rc4, 2.9.0rc5, 2.9.0, 2.9.1, 2.9.2, 2.9.3, 2.9.4, 2.9.5, 2.9.6, 2.9.7, 2.9.8, 2.9.9, 2.9.10, 2.9.11, 2.9.12, 2.9.13, 2.9.14rc1, 2.9.14, 2.9.15rc1, 2.9.15, 2.9.16rc1, 2.9.16, 2.9.17rc1, 2.9.17, 2.9.18rc1, 2.9.18, 2.9.19rc1, 2.9.19, 2.9.20rc1, 2.9.20, 2.9.21rc1, 2.9.21, 2.9.22rc1, 2.9.22, 2.9.23rc1, 2.9.23, 2.9.24rc1, 2.9.24, 2.9.25rc1, 2.9.25, 2.9.26rc1, 2.9.26, 2.9.27rc1, 2.9.27, 2.10.0a1, 2.10.0a2, 2.10.0a3, 2.10.0a4, 2.10.0a5, 2.10.0a6, 2.10.0a7, 2.10.0a8, 2.10.0a9, 2.10.0b1, 2.10.0b2, 2.10.0rc1, 2.10.0, 2.10.1, 2.10.2, 2.10.3, 2.10.4, 2.10.5, 2.10.6, 2.10.7, 3.0.0b1, 3.0.0rc1, 3.0.0, 3.1.0, 3.2.0, 3.3.0, 3.4.0, 4.0.0a1, 4.0.0a2, 4.0.0a3, 4.0.0a4, 4.0.0b1, 4.0.0b2, 4.0.0rc1, 4.0.0, 4.1.0, 4.2.0, 4.3.0, 4.4.0, 4.5.0, 4.6.0, 4.7.0, 4.8.0, 4.9.0, 4.10.0, 5.0.0a1, 5.0.0a2, 5.0.0a3, 5.0.0b1, 5.0.0b2, 5.0.0rc1)
ERROR: No matching distribution found for ansible==6.0

It seems that I’m on 5 rc1 at the latest if I go that route for something still technically supported/current. It seems I can also go with a ppa for 5.9 here: https://launchpad.net/~ansible/+archive/ubuntu/ansible. I’ll play with these, then report back.

set follow=yes to avoid setting permissions on the symlink itself, if
you still get an error you probably don't have permissions to set it
on the file either.