community.libvirt icon indicating copy to clipboard operation
community.libvirt copied to clipboard

Problem with file paths when using ansible.builtin.copy module

Open antonc42 opened this issue 2 years ago • 1 comments
trafficstars

SUMMARY

Almost all Ansible operations appear to use the unresolved path to the Ansible temp directory '~/.ansible/tmp'. However, the ansible.builtin.copy module appears to resolve this path to '/root/.ansible/tmp' when looking for the source file. The underlying problem is that when I examined the filesystem on the VM, it appears that the community.libvirt.libvirt_qemu connection plugin is copying all files in the temp directory to '/~/.ansible/tmp'. The tilde is not being resolved to the homedir of the user and instead ends up in a '/~' directory at the root of the filesystem.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

community.libvirt.libvirt_qemu connection plugin

ANSIBLE VERSION
ansible [core 2.15.4]
  config file = /home/user/ansible-dir/ansible.cfg
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/user/ansible-dir/.venv/lib/python3.11/site-packages/ansible
  ansible collection location = /home/user/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/user/ansible-dir/.venv/bin/ansible
  python version = 3.11.5 (main, Aug 25 2023, 13:19:50) [GCC 11.4.0] (/home/user/ansible-dir/.venv/bin/python)
  jinja version = 3.1.2
  libyaml = True
COLLECTION VERSION
# /home/user/ansible-dir/.venv/lib/python3.11/site-packages/ansible_collections
Collection        Version
----------------- -------
community.libvirt 1.2.0  
CONFIGURATION
CONFIG_FILE() = /home/user/ansible-dir/ansible.cfg
DEFAULT_HOST_LIST(/home/user/ansible-dir/ansible.cfg) = ['/home/user/ansible-dir/inventory.yml']
DEFAULT_KEEP_REMOTE_FILES(env: ANSIBLE_KEEP_REMOTE_FILES) = False
EDITOR(env: EDITOR) = /home/user/bin/vim
OS / ENVIRONMENT

Target OS: Ubuntu 22.04 Server

STEPS TO REPRODUCE
ansible -i local-libvirt-inventory.yml --become all -m copy -a 'src=srcfile dest=/path/to/dest/file'
EXPECTED RESULTS

The local file is copied to the libvirt host.

ACTUAL RESULTS

The file is not copied. When examining the filesystem in the libvirt VM, I found that the directory '/root/.ansible/tmp' doesn't exist. It is located at '/~/.ansible/tmp' instead.

libvirt-host | FAILED! => {
    "changed": false,
    "checksum": "fac0b7e52fc298c5c5feb6b7673f74e2306aba6e",
    "msg": "Source /root/.ansible/tmp/ansible-tmp-1695394376.1436307-368511-193439908275987/source not found"
}

antonc42 avatar Sep 22 '23 18:09 antonc42

@antonc42 hi, thanks for posting this issue. I've been trying to replicate it and didn't have luck with various versions of ansible and python on Fedora and CentOS. I spun up an Ubuntu 22.05 host and was able to replicate the issue.

After some digging, I think this is related to Ubuntu's use of dash as the default for /bin/sh on the guest. Are you able to try with bash and see if you have any different result?

Should be able to just set Use dash as the default system shell to no and retry without your patch.

sudo dpkg-reconfigure dash

Let me know how you go!

csmart avatar Jan 27 '24 10:01 csmart

Sorry for the late reply. I kinda lost track of this.

I just tried your suggestion on a Ubuntu 24.04 guest and it didn't fix the problem. I still saw the same weird /~ directory being created.

antonc42 avatar Aug 13 '24 19:08 antonc42

Apparently the dpkg-reconfigure method no longer works starting with Ubuntu 22.10 and Debian 12.

I think this is a safe method to change the /bin/sh symlink on the guest VM to bash (taken from here):

sudo su -c 'pushd /bin && ln -s bash sh.bash && mv sh.bash sh && popd'

Another way to solve this would be to set the default executable to /bin/bash in the Ansible config or env var. That would not require changing anything on the guest VM.

Once the shell was set properly, then everything worked as expected.

antonc42 avatar Aug 14 '24 16:08 antonc42

I don't think automatically changing the default shell system-wide is an acceptable solution to the problem. This can have system-wide side effects and easily can break people's machines.

leegarrett avatar Aug 14 '24 19:08 leegarrett

@leegarrett You could try the second solution of changing the Ansible default executable setting. That doesn't change the default shell on the Ansible controller or on the remote. It just sets Ansible to use /bin/bash instead of /bin/sh when executing commands on the remote machine. That should probably be the default if Ansible is going to use bash-specific features like tilde expansion.

In ansible.cfg:

[defaults]
executable = /bin/bash

antonc42 avatar Aug 14 '24 20:08 antonc42