Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ansible hostname task fails with nsenter connection plugin #568

Open
rptaylor opened this issue Jan 24, 2023 · 5 comments
Open

ansible hostname task fails with nsenter connection plugin #568

rptaylor opened this issue Jan 24, 2023 · 5 comments
Labels
not-a-bug This is not a bug, but a problem with the user's environment, a wrong usage, or intended behavior

Comments

@rptaylor
Copy link

rptaylor commented Jan 24, 2023

SUMMARY

The hostname Ansible task fails when using the nsenter connection plugin.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

nsenter connection plugin
https://docs.ansible.com/ansible/latest/collections/community/docker/nsenter_connection.html

ANSIBLE VERSION
# ansible --version
ansible [core 2.12.10]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.10/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.8 (main, Nov 14 2022, 00:00:00) [GCC 12.2.1 20220819 (Red Hat 12.2.1-2)]
  jinja version = 3.0.3
  libyaml = True
# rpm -q ansible
ansible-5.9.0-1.fc36.noarch
COLLECTION VERSION
# ansible-galaxy collection list community.docker

# /usr/lib/python3.10/site-packages/ansible_collections
Collection       Version
---------------- -------
community.docker 2.6.0  

# /root/.ansible/collections/ansible_collections
Collection       Version
---------------- -------
community.docker 3.4.0  
CONFIGURATION
# ansible-config dump --only-changed

OS / ENVIRONMENT

Ansible is running in a privileged podman container that is invoked like this:

sudo podman run --pull=newer --rm -it --pid=host --privileged registry.hub.docker.com/library/fedora:36

It uses nsenter to escape the container and execute the Ansible task on the host.

STEPS TO REPRODUCE

Start a container as described above.
Then dnf install ansible , put an example host name in your inventory and do

# ansible -c community.docker.nsenter -m hostname -a 'name="myhost.example.org"' --check  myhost.example.org
[WARNING]: Platform linux on host myhost.example.org is using the discovered Python interpreter at /usr/libexec/platform-python, but future installation of another Python
interpreter could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.12/reference_appendices/interpreter_discovery.html for more information.
myhost.example.org | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "msg": "Command failed rc=1, out=, err=Could not get property: Connection timed out\n"
}
EXPECTED RESULTS

It should be possible to read or set the hostname. I would be very happy to even have read only access to the hostname, which should not require any special privileges?

ACTUAL RESULTS

Extra verbose output shows:

# ansible -vvv -c community.docker.nsenter -m hostname -a 'name="myhost.example.org"' --check  myhost.example.org
ansible [core 2.12.10]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.10/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.8 (main, Nov 14 2022, 00:00:00) [GCC 12.2.1 20220819 (Red Hat 12.2.1-2)]
  jinja version = 3.0.3
  libyaml = True
Using /etc/ansible/ansible.cfg as config file
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Parsed /etc/ansible/hosts inventory source with ini plugin
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
META: ran handlers
<myhost.example.org> ESTABLISH NSENTER CONNECTION FOR USER: root
<myhost.example.org> EXEC nsenter --ipc --mount --net --pid --uts --preserve-credentials --target=1 -- /bin/sh -c 'echo ~ && sleep 0'
<myhost.example.org> EXEC nsenter --ipc --mount --net --pid --uts --preserve-credentials --target=1 -- /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1674602671.8849206-718043-63878993635491 `" && echo ansible-tmp-1674602671.8849206-718043-63878993635491="` echo /root/.ansible/tmp/ansible-tmp-1674602671.8849206-718043-63878993635491 `" ) && sleep 0'
<myhost.example.org> Attempting python interpreter discovery
<myhost.example.org> EXEC nsenter --ipc --mount --net --pid --uts --preserve-credentials --target=1 -- /bin/sh -c 'echo PLATFORM; uname; echo FOUND; command -v '"'"'python3.10'"'"'; command -v '"'"'python3.9'"'"'; command -v '"'"'python3.8'"'"'; command -v '"'"'python3.7'"'"'; command -v '"'"'python3.6'"'"'; command -v '"'"'python3.5'"'"'; command -v '"'"'/usr/bin/python3'"'"'; command -v '"'"'/usr/libexec/platform-python'"'"'; command -v '"'"'python2.7'"'"'; command -v '"'"'python2.6'"'"'; command -v '"'"'/usr/bin/python'"'"'; command -v '"'"'python'"'"'; echo ENDFOUND && sleep 0'
<myhost.example.org> Python interpreter discovery fallback (pipelining support required for extended interpreter discovery)
Using module file /usr/lib/python3.10/site-packages/ansible/modules/hostname.py
<myhost.example.org> PUT /root/.ansible/tmp/ansible-local-718036pr2p_16a/tmpvdowh4c0 to /root/.ansible/tmp/ansible-tmp-1674602671.8849206-718043-63878993635491/AnsiballZ_hostname.py
<myhost.example.org> EXEC [b'nsenter', b'--ipc', b'--mount', b'--net', b'--pid', b'--uts', b'--preserve-credentials', b'--target=1', b'--', b'tee', b'/root/.ansible/tmp/ansible-tmp-1674602671.8849206-718043-63878993635491/AnsiballZ_hostname.py']
<myhost.example.org> EXEC nsenter --ipc --mount --net --pid --uts --preserve-credentials --target=1 -- /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1674602671.8849206-718043-63878993635491/ /root/.ansible/tmp/ansible-tmp-1674602671.8849206-718043-63878993635491/AnsiballZ_hostname.py && sleep 0'
<myhost.example.org> EXEC nsenter --ipc --mount --net --pid --uts --preserve-credentials --target=1 -- /bin/sh -c '/usr/libexec/platform-python /root/.ansible/tmp/ansible-tmp-1674602671.8849206-718043-63878993635491/AnsiballZ_hostname.py && sleep 0'
<myhost.example.org> EXEC nsenter --ipc --mount --net --pid --uts --preserve-credentials --target=1 -- /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1674602671.8849206-718043-63878993635491/ > /dev/null 2>&1 && sleep 0'
[WARNING]: Platform linux on host myhost.example.org is using the discovered Python interpreter at /usr/libexec/platform-python, but future installation of another Python
interpreter could change the meaning of that path. See https://docs.ansible.com/ansible-core/2.12/reference_appendices/interpreter_discovery.html for more information.
myhost.example.org | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "invocation": {
        "module_args": {
            "name": "myhost.example.org",
            "use": null
        }
    },
    "msg": "Command failed rc=1, out=, err=Could not get property: Connection timed out\n"
}

I can reproduce it with the same nsenter command, or even if I do:

[root@0b9e5c0ea9d4 /]# nsenter -a -t 1
[root@myhost /]# hostnamectl --static
Could not get property: Connection timed out

Of course hostnamectl works fine on the host itself when not run in a container or nsenter.

I also tried running the podman container with --network=host but the result was the same (even though in this case the podman container knows the hostname). In either case, nsenter and hostname -f works, but hostnamectl does not work.

Other Ansible tasks work, only hostname seems to be affected. Maybe something related to permissions in the namespace, but I don't see any other privileges or namespace access that I have not already granted to the podman container.

@rptaylor
Copy link
Author

rptaylor commented Jan 24, 2023

The default hostnamectl-based strategy being used by the hostname module is systemd:
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/hostname_module.html

I also tried generic and redhat but they failed with different errors.
The host is Almalinux 8 and the redhat strategy uses /etc/sysconfig/network which does not contain the hostname anymore.

@rptaylor
Copy link
Author

The sles or solaris strategies might appear to work but I'm not sure if editing /etc/hostname or using /usr/bin/hostname to change hostname is supported on EL8.

@felixfontein
Copy link
Collaborator

I don't think this is a problem with the nsenter connection plugin, but with the hostname module (or maybe even the action of changing the hostname through nsenter in general). There is nothing the nsenter connection plugin can do to improve this situation.

@felixfontein felixfontein added the not-a-bug This is not a bug, but a problem with the user's environment, a wrong usage, or intended behavior label Jan 25, 2023
@rptaylor
Copy link
Author

@felixfontein As that may be, do you know what the cause of the issue is or how the issue could be worked around?

@rptaylor
Copy link
Author

Seems to also affect the timezone task and timedatectl command. Not sure why but it seems these commands can't talk to systemd via the dbus socket when using nsenter.

https://unix.stackexchange.com/questions/639168/why-is-the-uts-namespace-isolation-not-working

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
not-a-bug This is not a bug, but a problem with the user's environment, a wrong usage, or intended behavior
Projects
None yet
Development

No branches or pull requests

2 participants