Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible - how to run a script on a relative path

Tags:

ansible

My question is why can I not use a relative path to specify a bash script to run?

I have a ansible file structure following best practice.

My directory structure for this role is:

.
├── files
│   └── install-watchman.bash
└── tasks
    └── main.yml

and the main.yml includes this:

- name: install Watchman
  shell: "{{ role_path }}/files/install-watchman.bash"

- name: copy from files dir to target home dir
  copy:
    src: files/install-watchman.bash
    dest: /home/vagrant/install-watchman.bash
    owner: vagrant
    group: vagrant
    mode: 0744

- name: install Watchman
  shell: files/install-watchman.bash

I would expect all three commands to work, but in practice the third one fails:

TASK [nodejs : install Watchman] ***********************************************
changed: [machine1]

TASK [nodejs : copy from files dir to target home dir] ********
changed: [machine1]

TASK [nodejs : install Watchman] ***********************************************
fatal: [machine1]: FAILED! => {"changed": true, "cmd": "files/install-watchman.bash", "delta": "0:00:00.002997", "end": "2019-01-27 16:01:50.093530", "msg": "non-zero return code", "rc": 127, "start": "2019-01-27 16:01:50.090533", "stderr": "/bin/sh: 1: files/install-watchman.bash: not found", "stderr_lines": ["/bin/sh: 1: files/install-watchman.bash: not found"], "stdout": "", "stdout_lines": []}
    to retry, use: --limit @/vagrant/ansible/site.retry

(If it helps, this is the version info for ansible:)

vagrant@ubuntu-xenial:~$ ansible --version
ansible 2.7.6
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/vagrant/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.12 (default, Nov 12 2018, 14:36:49) [GCC 5.4.0 20160609]
like image 394
Mazerunner72 Avatar asked Jan 27 '19 16:01

Mazerunner72


2 Answers

I put together a test of this to see: https://github.com/farrellit/ansible-demonstrations/tree/master/shell-cwd

It has convinced me that the short answer is probably, ansible roles' shell tasks will by default have the working directory of the playbook that include that role.

It basically comes down to a role like this ( the rest of that dir is tooling to make it run):

- shell: pwd
  register: shellout
- debug: var=shellout.stdout
- shell: pwd
  args:
    chdir: "{{role_path}}"
  register: shellout2
- debug: var=shellout2.stdout

This has shown:

PLAY [localhost] ***********************************************************************************************************************************************************************************************************************

TASK [shelldir : command] **************************************************************************************************************************************************************************************************************
changed: [127.0.0.1]

TASK [shelldir : debug] ****************************************************************************************************************************************************************************************************************
ok: [127.0.0.1] => {
    "shellout.stdout": "/code"
}

TASK [shelldir : command] **************************************************************************************************************************************************************************************************************
changed: [127.0.0.1]

TASK [shelldir : debug] ****************************************************************************************************************************************************************************************************************
ok: [127.0.0.1] => {
    "shellout2.stdout": "/code/roles/shelldir"
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
127.0.0.1                  : ok=4    changed=2    unreachable=0    failed=0

That the current working directory for roles is not role_path. In my case it is the role of the playbook that invoked the task. It might be something else in the case of an included playbook or tasks file from a different directory (I'll leave that as an exercise for you, if you care). I set that execution to run from /tmp, so I don't think it would matter the current working directory of the shell that ran ansible-playbook.

like image 108
Daniel Farrell Avatar answered Oct 19 '22 12:10

Daniel Farrell


Shell will execute the command on the remote. You have copied the script to /home/vagrant/install-watchman.bash on your remote. Therefore you have to use that location for executing on the remote as well.

- name: install Watchman
  shell: /home/vagrant/install-watchman.bash

a relative path will work as well, if your ansible user is the user "vagrant"

- name: install Watchman
  shell: install-watchman.bash

Side note:

I would recommend to use command instead of shell whenever possible: shell vs command Module

like image 30
Leo Avatar answered Oct 19 '22 12:10

Leo