I'm trying to pass the content of a text file I have in the local folder to an Ansible shell command and for whatever reason, I can't and I'm sure its something silly that I'm missing.
Any help would be really appreciated
Here is the ansible line:
- name: Connect K8s cluster to Shipa
shell: shipa cluster-add {{ cluster_name }} --addr $(< {{ cluster_name }}.txt) --cacert {{ cluster_name }}.crt --pool {{ cluster_name }} --ingress-service-type=LoadBalancer
args:
executable: /bin/bash
no_log: False
Whenever I run this, this is what I get in the log:
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "shipa cluster-add scale2 --addr $(< scale2.txt) --cacert scale2.crt --pool scale2 --ingress-service-type=LoadBalancer", "delta": "0:00:00.096162", "end": "2020-04-30 21:32:54.245781", "msg": "non-zero return code", "rc": 1, "start": "2020-04-30 21:32:54.149619", "stderr": "Error: 500 Internal Server Error: parse \"https://\\x1b[0;33mhttps://192.196.192.156\\x1b[0m\": net/url: invalid control character in URL", "stderr_lines": ["Error: 500 Internal Server Error: parse \"https://\\x1b[0;33mhttps://192.196.192.156\\x1b[0m\": net/url: invalid control character in URL"], "stdout": "", "stdout_lines": []}
Here is the content of the file:
# cat scale2.txt
https://192.196.192.156
Here is what Im trying to pass in the command:
shipa cluster-add scale2 --addr https://192.196.192.156 --cacert scale2.crt --pool scale2 --ingress-service-type=LoadBalancer
EDIT:
I also tried the following:
- name: Get K8s cluster address
shell: kubectl cluster-info | grep 'Kubernetes master' | awk '/http/ {print $NF}'
args:
executable: /bin/bash
register: cluster_address
no_log: False
- debug: var=cluster_address
- name: Save to file
copy:
content: "{{ ''.join(cluster_address.stdout_lines) | replace('\\u001b[0;33m', '')| replace('\\u001b[0m', '') }}"
dest: "cluster_address.json"
- name: Connect K8s cluster to Shipa
shell: shipa cluster-add {{ cluster_name }} --addr {{ lookup('file', 'cluster_address.json') }} --cacert {{ cluster_name }}.crt --pool {{ cluster_name }} --ingress-service-type=LoadBalancer
args:
executable: /bin/bash
no_log: False
But it saves the following content to the file:
# vi cluster_address.json
^[[0;33mhttps://192.192.56.192^[[0m
Here is the output of the ansible execution:
TASK [debug] **********************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"cluster_address": {
"changed": true,
"cmd": "kubectl cluster-info | grep 'Kubernetes master' | awk '/http/ {print $NF}'",
"delta": "0:00:00.144193",
"end": "2020-04-30 22:54:21.970460",
"failed": false,
"rc": 0,
"start": "2020-04-30 22:54:21.826267",
"stderr": "",
"stderr_lines": [],
"stdout": "\u001b[0;33mhttps://192.192.56.192\u001b[0m",
"stdout_lines": [
"\u001b[0;33mhttps://192.192.56.192\u001b[0m"
]
}
}
TASK [Save to file] ***************************************************************************************************************************************************************************************************************************
changed: [localhost]
TASK [Connect K8s cluster to Shipa] ***********************************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "shipa cluster-add scale1 --addr \u001b[0;33mhttps://192.192.56.192\u001b[0m --cacert scale1.crt --pool scale1 --ingress-service-type=LoadBalancer", "delta": "0:00:00.106936", "end": "2020-04-30 22:54:23.213485", "msg": "non-zero return code", "rc": 127, "start": "2020-04-30 22:54:23.106549", "stderr": "Error: 400 Bad Request: either default or a list of pools must be set\n/bin/bash: 33mhttps://192.192.56.192\u001b[0m: No such file or directory", "stderr_lines": ["Error: 400 Bad Request: either default or a list of pools must be set", "/bin/bash: 33mhttps://192.192.56.192\u001b[0m: No such file or directory"], "stdout": "", "stdout_lines": []}
You can disable the fancy terminal output by setting the TERM to dumb
- shell: kubectl cluster-info | awk '/Kubernetes master/ {print $NF}'
environment:
TERM: dumb
register: cluster_info
- set_fact:
cluster_addr: '{{ cluster_info.stdout | trim }}'
then, separately, you don't need to use the file lookup for a value that you have in a jinja2 variable already:
- name: Connect K8s cluster to Shipa
command: shipa cluster-add {{ cluster_name }} --addr {{ cluster_addr }} --cacert {{ cluster_name }}.crt --pool {{ cluster_name }} --ingress-service-type=LoadBalancer
args:
executable: /bin/bash
Related
I took volumes 'in-use' of OpenStack instance and filtered those volume ids into a file from which it has to make a backup
shell: openstack volume list | grep 'in-use' | awk '{print $2}' > /home/volumeid
shell: openstack volume backup create {{ item }}
with_items:
- /home/volumeid
error shows like
**failed: [controller2] (item=volumeid) => {"ansible_loop_var": "item", "changed": true, "cmd": "openstack volume backup create volumeid", "delta": "0:00:03.682611", "end": "2022-09-26 12:01:59.961613", "item": "volumeid", "msg": "non-zero return code", "rc": 1, "start": "2022-09-26 12:01:56.279002", "stderr": "No volume with a name or ID of 'volumeid' exists.", "stderr_lines": ["No volume with a name or ID of 'volumeid' exists."], "stdout": "", "stdout_lines": []}
failed: [controller1] (item=volumeid) => {"ansible_loop_var": "item", "changed": true, "cmd": "openstack volume backup create volumeid", "delta": "0:00:04.020051", "end": "2022-09-26 12:02:00.280130", "item": "volumeid", "msg": "non-zero return code", "rc": 1, "start": "2022-09-26 12:01:56.260079", "stderr": "No volume with a name or ID of 'volumeid' exists.", "stderr_lines": ["No volume with a name or ID of 'volumeid' exists."], "stdout": "", "stdout_lines": []}**
Can someone say how to create the volume backup from that file (which has volume ids) in the ansible playbook?
Currently, you are supplying only one element to the with_items, that is, /home/volumeid, meaning your loop will iterate only once for the file name and not its contents.
You need to use the file lookup if you are on localhost or the slurp module on the remote host. Example:
For the localhost:
- name: Show the volume id from the file
debug:
msg: "{{ item }}"
loop: "{{ lookup('file', '/home/volumeid').splitlines() }}"
For the remote host:
- name: Alternate if the file is on remote host
ansible.builtin.slurp:
src: /home/volumeid
register: vol_data
- name: Show the volume id from the file
debug:
msg: "{{ item }}"
loop: "{{ (vol_data['content'] | b64decode).splitlines() }}"
Just one line shell command:
openstack volume list --status in-use -c ID -f value | xargs -n1 openstack volume backup create
One advice, don't use the hardcode command like this grep 'in-use' or awk '{print $2}', openstack has it's optional arguments and output formatters, check it by openstack command [sub command] -h.
I'm using https://github.com/kubernetes-sigs/kubespray
Is there a way to know exactly which command the following Ansible code will execute on the remote server?
- name: ensure docker packages are installed
package:
name: "{{ docker_package_info.pkgs }}"
state: "{{ docker_package_info.state | default('present') }}"
module_defaults:
apt:
update_cache: true
dnf:
enablerepo: "{{ docker_package_info.enablerepo | default(omit) }}"
yum:
enablerepo: "{{ docker_package_info.enablerepo | default(omit) }}"
zypper:
update_cache: true
register: docker_task_result
until: docker_task_result is succeeded
retries: 4
delay: "{{ retry_stagger | d(3) }}"
notify: restart docker
when:
- not ansible_os_family in ["Flatcar Container Linux by Kinvolk"]
- not is_ostree
- docker_package_info.pkgs|length > 0
I'm getting the following error in RHEL8. I want to run manually docker-ce on the relevant VM and check the error.
{"attempts": 4, "changed": true, "cmd": "set -o pipefail && /usr/bin/docker ps -aq | xargs -r docker rm -fv", "delta": "0:00:00.008934", "end": "2021-07-16 18:46:54.009010", "msg": "non-zero return code", "rc": 127, "start": "2021-07-16 18:46:54.000076", "stderr": "/bin/bash: /usr/bin/docker: No such file or directory", "stderr_lines": ["/bin/bash: /usr/bin/docker: No such file or directory"], "stdout": "", "stdout_lines": []}
Thanks,
I have written the following ansible playbook to find the disk failure on the raid
- name: checking raid status
shell: "cat /proc/mdstat | grep nvme"
register: "array_check"
- debug:
msg: "{{ array_check.stdout_lines }}"
Following is the output I got
"msg": [
"md0 : active raid1 nvme0n1p1[0] nvme1n1p1[1]",
"md2 : active raid1 nvme1n1p3[1](F) nvme0n1p3[0]",
"md1 : active raid1 nvme1n1p2[1] nvme0n1p2[0]"
]
I want to extract the disk name which is failed from the register variable array_check.
How do I do this in the ansible? Can I use set_fact module in ansible? Can I use grep, awk, sed command on the register variable array_check
This is the playbook I am using to check the health status of a drive using smartctl
- name: checking the smartctl logs
shell: "smartctl -H /dev/{{ item }}"
with_items:
- nvme0
- nvme1
And I am facing the following error
(item=nvme0) => {"changed": true, "cmd": "smartctl -H /dev/nvme0", "delta": "0:00:00.090760", "end": "2019-09-05 11:21:17.035173", "failed": true, "item": "nvme0", "rc": 127, "start": "2019-09-05 11:21:16.944413", "stderr": "/bin/sh: 1: smartctl: not found", "stdout": "", "stdout_lines": [], "warnings": []}
(item=nvme1) => {"changed": true, "cmd": "smartctl -H /dev/nvme1", "delta": "0:00:00.086596", "end": "2019-09-05 11:21:17.654036", "failed": true, "item": "nvme1", "rc": 127, "start": "2019-09-05 11:21:17.567440", "stderr": "/bin/sh: 1: smartctl: not found", "stdout": "", "stdout_lines": [], "warnings": []}
The desired output should be something like this,
=== START OF SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED
Below is the complete playbook including the logic to execute multiple commands in a single task using with_items,
---
- hosts: raid_host
remote_user: ansible
become: yes
become_method: sudo
tasks:
- name: checking raid status
shell: "cat /proc/mdstat | grep 'F' | cut -d' ' -f6 | cut -d'[' -f1"
register: "array_check"
- debug:
msg: "{{ array_check.stdout_lines }}"
- name: checking the samrtctl logs for the drive
shell: "/usr/sbin/smartctl -H /dev/{{ item }} | tail -2|awk -F' ' '{print $6}'"
with_items:
- "nvme0"
- "nvme1"
register: "smartctl_status"
- name: Create directory for python files
file: path=/home/vuser/test/
state=directory
owner={{ user }}
group={{ user }}
mode=755
- name: Copy python file over
copy:
src=sample.py
dest=/home/vuser/test/sample.py
owner={{ user }}
group={{ user }}
mode=777
- name: Execute script
command: python sample.py
args:
chdir: /home/vuser/test/
ignore_errors: yes
error
fatal: [n]: FAILED! => {"changed": true, "cmd": ["python", "sample.py"], "delta": "0:00:00.003200", "end": "2019-07-18 13:57:40.213252", "msg": "non-zero return code", "rc": 1, "start": "2019-07-18 13:57:40.221132", "stderr": "", "stderr_lines": [], "stdout": "1", "stdout_lines": ["1"]}
not able to figure out, help would be appreciated
Change the indent like below and remove ignore_errors.
- name: Execute script
command: python sample.py
args:
chdir: /home/vuser/test/
register: cat_contents
- name: Print contents
debug:
msg: "{{ cat_contents.stdout }}"
- name: Create directory for python files
file: path=/home/vuser/test/
state=directory
owner={{ user }}
group={{ user }}
mode=755
- name: Copy python file over
copy:
src=/home/vuser/sample.py
dest=/home/vuser/test/
owner={{ user }}
group={{ user }}
mode=777
- name: Execute script
command: python sample.py
args:
chdir: /home/vuser/test/
The sample.py is copied correctly in the destination folder at the node1 at dest=/home/vuser/test/
but the I get this error after I have done the change also
fatal: [node1]: FAILED! => {"changed": true, "cmd": ["python", "sample.py"], "delta": "0:00:00.002113", "end": "2019-07-19 10:59:53.7535351", "msg": "non-zero return code", "rc": 1, "start": "2019-07-19 10:59:53.358678548", "stderr": "", "stderr_lines": [], "stdout": "hello world", "stdout_lines": ["hello world"]}
While provisioning via Vagrant and Ansible I keep running into this issue.
TASK [postgresql : Create extensions] ******************************************
failed: [myapp] (item=postgresql_extensions) => {"changed": true, "cmd": "psql myapp -c 'CREATE EXTENSION IF NOT EXISTS postgresql_extensions;'", "delta": "0:00:00.037786", "end": "2017-04-01 08:37:34.805325", "failed": true, "item": "postgresql_extensions", "rc": 1, "start": "2017-04-01 08:37:34.767539", "stderr": "ERROR: could not open extension control file \"/usr/share/postgresql/9.3/extension/postgresql_extensions.control\": No such file or directory", "stdout": "", "stdout_lines": [], "warnings": []}
I'm using a railsbox.io generated playbook.
Turns out that railsbox.io is still using a deprecated syntax in the task.
- name: Create extensions
sudo_user: '{{ postgresql_admin_user }}'
shell: "psql {{ postgresql_db_name }} -c 'CREATE EXTENSION IF NOT EXISTS {{ item }};'"
with_items: postgresql_extensions
when: postgresql_extensions
The last line should use full jinja2 syntax.
when: '{{postgresql_extensions}}'