Lineinfile task problem

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

1 Like

Thanks, both of them are great Solutions. I will try them And take you updated. Thanks again