Hello, I wrote a playbook to check if linux VM had new kernel downloaded and have to be rebooted to set them.
So in the top of the tasks of the playbook I put the “needs restarting -r” command, and if it says yes, the following tasks execute the reboot of the VM. If it instead says no, the following tasks will not be executed because they have all a when condition on “if the VM has to be rebooted”.
After this I have to know which VM of the inventory list has been rebooted, so I put a lineinfile task after the reboot task, for write in a file a hostname/ip for every VM it contacts at this point of the playbook. But when it write the hostname/IP of the VM in the file, it doesn’t work every time, infact some times, the list in the file reports some VM minus of the realm ones it rebooted.
I think it is due to the contemporary attempt to write to the file, because the ssh connection to the VM are in parallel.
I put the throttle option to 2 in the lineinfile task, but it seems not to work.
Any suggestions?
Thanks.
Hi @Marianna_Buffa
Not sure I am visualizing your situation. Could you provide excerpts of your code?
Cheers
Hello, Here the tasks I’ve described before in my playbook.
-
name: yum install pkg
yum:
name: yum-utils
state: present -
name: needs-restarting -r
shell: ‘needs-restarting -r’
register: needs_restarting_output
ignore_errors: true -
name: mostra needs_restarting_output
debug:
var: needs_restarting_output.stdout -
name: check kernel word - la trova
debug:
msg: ‘kernel nuovo da installare’
when: needs_restarting_output.stdout.find(‘kernel’) != -1 #se != -1 allora la trova -
name: cancella file kernel_update.txt
file:
path: /var/lib/awx/projects/playbook/vm/kernel-update/kernel_update.txt
state: absent
when: needs_restarting_output.stdout.find(‘kernel’) != -1 #se != -1 allora la trova
delegate_to: localhost
ignore_errors: true -
name: crea file kernel_update.txt
file:
path: /var/lib/awx/projects/playbook/vm/kernel-update/kernel_update.txt
state: touch
when: needs_restarting_output.stdout.find(‘kernel’) != -1 #se != -1 allora la trova
delegate_to: localhost -
name: attende creazione file /var/lib/awx/projects/playbook/vm/kernel-update/kernel_update.txt
wait_for:
path: /var/lib/awx/projects/playbook/vm/kernel-update/kernel_update.txt
state: present
delay: 10
timeout: 30
when: needs_restarting_output.stdout.find(‘kernel’) != -1 #se != -1 allora la trova
delegate_to: localhost -
name: popola file kernel_update.txt
lineinfile:
#line: ‘{{ host_ip }} {{ ansible_hostname }}’
line: ‘{{ ansible_default_ipv4.address }} {{ ansible_hostname }}’
path: /var/lib/awx/projects/playbook/vm/kernel-update/kernel_update.txt
when: needs_restarting_output.stdout.find(‘kernel’) != -1 #se != -1 allora la trova
delegate_to: localhost -
name: reboot vm
reboot:
reboot_timeout: 3600
test_command: w
when: needs_restarting_output.stdout.find(‘kernel’) != -1 #se != -1 allora la trova
At the end I added a task to send me a mail with attached the file
kernel_update.txt
I think you may be having problems posting your code. Twice it looks like you are posting code, but I can see nothing. Can you check that you are posting correctly, preferably with the preformatted text
format in the editor?
I update the post with the code. Sorry.
I suggest you don’t use line in file to create your report, but use a pattern with the assemble module: ansible.builtin.assemble module – Assemble configuration files from fragments — Ansible Community Documentation
- name: Create a directory for all the lines on the control node
ansible.builtin.file:
path: server_report
state: directory
delegate_to: localhost
- name: Render one file per line on the control node
ansible.builtin.copy:
dest: server_report/line_for_{{ inventory_hostname }}
content: >
"{{ ansible_default_ipv4.address }} {{ ansible_hostname }}"
delegate_to: localhost
when: needs_restarting_output.stdout.find(‘kernel’) != -1
- name: Assemble the pieces together
ansible.builtin.assemble:
src: server_report
dest: kernel_update.txt
delegate_to: localhost
run_once: true
I would take a bit of a different approach by using the return code as opposed to looking for a string/line and build an in memory inventory.
- name: Build dynamic inventory
ansible.builtin.add_host:
hostname: "{{ ansible_hostname }}"
groups: reboot_group
when: needs_restarting_output['rc'] | int == 1
- name: Create a list
ansible.builtin.copy:
content: |
{% for host in groups['reboot_group'] %}
{{ hostvars[host]['ansible_facts']['eth0']['ipv4']['address'] }} {{ hostvars['host']['ansible_facts']['hostname'] }}
{% endfor %}
dest: /tmp/destfile
delegate_to: localhost
run_once: true
when: groups['reboot_group'] is defined
Thanks, both of them are great Solutions. I will try them And take you updated. Thanks again