I'm trying to get the owner of the first directory passed to Ansible variable source_files
.
We do not have control over the content of Ansible variable source_files
as it is constructed through some OLAM API. I have hard coded it for this example.
Both the files of source_files
variable exists as seen below:
[wluser@mylocalhost ~]$ ls -ltr '/tmp/my private.txt' /tmp/files.sh
-rw-r--r-- 1 wluser mygrp 0 Nov 12 21:52 /tmp/files.sh
-rw-r--r-- 1 wluser mygrp 0 Nov 12 21:52 /tmp/my private.txt
Playbook [wluser@mylocalhost ~]$ cat formatstring.yml
---
- name: "Play 1-Find the details here"
hosts: localhost
any_errors_fatal: True
gather_facts: no
tasks:
- name: Set source_files variable
set_fact:
source_files: "'/tmp/my private.txt','/tmp/files.sh'"
- name: Print source_files
debug:
msg: "source_files: {{ source_files }}"
- name: Loop Print source_files
debug:
msg: "{{ item }}"
loop: "{{ source_files.split(',') }}"
- name: Single Print source_files
debug:
msg: "{{ source_files.split(',')[0] }}"
- name: Get directory owner
ansible.builtin.stat:
path: "{{ tomcat_home_item }}"
register: dir_stat
vars:
tomcat_home_item: "{{ source_files.split(',')[0] | trim }}"
- name: Store directory owner's UID in a variable
set_fact:
owner_uid: "{{ dir_stat.stat.pw_name | default('baduser') }}"
- debug:
msg: "Detected user is: {{ owner_uid }}"
- name: Get directory owner
ansible.builtin.stat:
path: "{{ tomcat_home_item | regex_replace('^\\s*'|'\\s*$', '') }}"
register: dir_stat
vars:
tomcat_home_item: "{{ source_files.split(',')[0] | trim }}"
- name: Store directory owner's UID in a variable
set_fact:
owner_uid: "{{ dir_stat.stat.pw_name | default('baduser') }}"
- debug:
msg: "Detected user is: {{ owner_uid }}"
Output
[wluser@mylocalhost ~]$ ansible-playbook formatstring.yml -vvv
ansible-playbook 2.8.4
config file = /etc/ansible/ansible.cfg
PLAYBOOK: formatstring.yml ****************************************************************************************************
1 plays in formatstring.yml
PLAY [Play 1-Find the details here] *******************************************************************************************
META: ran handlers
TASK [Set source_files variable] **********************************************************************************************
task path: /home/wluser/formatstring.yml:10
Sunday 12 November 2023 22:02:56 -0600 (0:00:00.044) 0:00:00.044 *******
ok: [localhost] => {
"ansible_facts": {
"source_files": "'/tmp/my private.txt','/tmp/files.sh'"
},
"changed": false
}
TASK [Print source_files] *****************************************************************************************************
task path: /home/wluser/formatstring.yml:15
Sunday 12 November 2023 22:02:56 -0600 (0:00:00.018) 0:00:00.062 *******
ok: [localhost] => {
"msg": "source_files: '/tmp/my private.txt','/tmp/files.sh'"
}
TASK [Loop Print source_files] ************************************************************************************************
task path: /home/wluser/formatstring.yml:19
Sunday 12 November 2023 22:02:56 -0600 (0:00:00.017) 0:00:00.080 *******
ok: [localhost] => (item='/tmp/my private.txt') => {
"msg": "'/tmp/my private.txt'"
}
ok: [localhost] => (item='/tmp/files.sh') => {
"msg": "'/tmp/files.sh'"
}
TASK [Single Print source_files] **********************************************************************************************
task path: /home/wluser/formatstring.yml:24
Sunday 12 November 2023 22:02:56 -0600 (0:00:00.033) 0:00:00.114 *******
ok: [localhost] => {
"msg": "'/tmp/my private.txt'"
}
TASK [Get directory owner] ****************************************************************************************************
task path: /home/wluser/formatstring.yml:29
Sunday 12 November 2023 22:02:56 -0600 (0:00:00.023) 0:00:00.137 *******
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: wluser
ok: [localhost] => {
"changed": false,
"invocation": {
"module_args": {
"checksum_algorithm": "sha1",
"follow": false,
"get_attributes": true,
"get_checksum": true,
"get_md5": null,
"get_mime": true,
"path": "'/tmp/my private.txt'"
}
},
"stat": {
"exists": false
}
}
TASK [Store directory owner's UID in a variable] ******************************************************************************
task path: /home/wluser/formatstring.yml:36
Sunday 12 November 2023 22:02:57 -0600 (0:00:00.352) 0:00:00.489 *******
ok: [localhost] => {
"ansible_facts": {
"owner_uid": "baduser"
},
"changed": false
}
TASK [debug] ******************************************************************************************************************
task path: /home/wluser/formatstring.yml:40
Sunday 12 November 2023 22:02:57 -0600 (0:00:00.020) 0:00:00.510 *******
ok: [localhost] => {
"msg": "Detected user is: baduser"
}
TASK [Get directory owner] ****************************************************************************************************
task path: /home/wluser/formatstring.yml:43
Sunday 12 November 2023 22:02:57 -0600 (0:00:00.019) 0:00:00.529 *******
fatal: [localhost]: FAILED! => {
"msg": "template error while templating string: expected token 'name', got 'string'. String: {{ tomcat_home_item | regex_replace('^\\\\s*'|'\\\\s*$', '') }}"
}
NO MORE HOSTS LEFT ************************************************************************************************************
PLAY RECAP ********************************************************************************************************************
localhost : ok=7 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
As you can see, I'm getting baduser
instead of correct user wluser
due to quoting/formatting issues with variable source_files
.
I then attempted to remove the quotes but that got me runtime error.
Can you please suggest how can i get the stats to the file considering the formatting of source_files mentioned initially in the playbook cannot be changed.
How can I get the stats to the file considering the formatting of
source_files
Assuming the output of the ls -ltr
command is correct, as well the content of source_files
. For files
~/test$ ls -ltr 'test file' 'test path' 'test path/test file'
-rw-r--r--. 1 ansible_user users 0 Nov 13 08:00 test file
-rw-r--r--. 1 ansible_user users 0 Nov 13 08:00 test path/test file
test path:
total 0
-rw-r--r--. 1 ansible_user users 0 Nov 13 08:00 test file
a minimal example playbook
```---
- hosts: localhost
become: false
gather_facts: false
vars:
FILE: 'test file'
PATH: 'test path'
tasks:
- set_fact:
SOURCE_FILES: "'test file','test path/test file'"
- stat:
path: 'test file'
register: result
- debug:
msg: "{{ result.stat.path }}"
- stat:
path: "{{ FILE }}"
register: result
- debug:
msg: "{{ result.stat.path }}"
- stat:
path: "{{ PATH }}/{{ FILE }}"
register: result
- debug:
msg: "{{ result.stat.path }}"
- debug:
msg:
- "Content: {{ SOURCE_FILES }}"
- "Type: {{ SOURCE_FILES | type_debug }}"
- "List of files: {{ SOURCE_FILES | split(',') }}"
- stat:
path: "{{ SOURCE_FILES | split(',') | first | replace(\"'\",'') }}"
register: result
- debug:
msg: "{{ result.stat.path }}"
- stat:
path: "{{ SOURCE_FILES | split(',') | last | replace(\"'\",'') }}"
register: result
- debug:
msg: "{{ result.stat.path }}"
will result into an output of
TASK [stat] ******************************************************
ok: [localhost]
TASK [debug] *****************************************************
ok: [localhost] =>
msg: test file
TASK [stat] ******************************************************
ok: [localhost]
TASK [debug] *****************************************************
ok: [localhost] =>
msg: test file
TASK [stat] ******************************************************
ok: [localhost]
TASK [debug] *****************************************************
ok: [localhost] =>
msg: test path/test file
TASK [debug] *****************************************************
ok: [localhost] =>
msg:
- 'Content: ''test file'',''test path/test file'''
- 'Type: AnsibleUnicode'
- 'List of files: [u"''test file''", u"''test path/test file''"]'
TASK [stat] ******************************************************
ok: [localhost]
TASK [debug] *****************************************************
ok: [localhost] =>
msg: test file
TASK [stat] ******************************************************
ok: [localhost]
TASK [debug] *****************************************************
ok: [localhost] =>
msg: test path/test file
If the content of source_files
is a Comma Separated Value (CSV) string with explicit quoted values and quote character single quote (')
(... annot: which it makes non-RFC conform then), to make a list of file names out of it again
,
) via split(',')
single quote (')
for all values via replace(\"'\",'')
Please take not that files can not contain single quote anymore as that would run into an error again. It would fail in example for
~/test$ touch "andrew's.file"
~/test$ ls -al and*
-rw-r--r--. 1 ansible_user users 0 Nov 13 09:30 andrew's.file
-rw-r--r--. 1 ansible_user users 0 Nov 13 09:30 and.yml
Thanks To