Files
toallab-automation/roles/oatakan.windows_update/tasks/updates-with-retry.yml

150 lines
5.5 KiB
YAML

---
- name: update over multiple reboots
block:
- block:
- name: set reject list
set_fact:
_reject_list: "{{ (win_update_reject_list | default([])) + (failed_kb | default([])) }}"
when: (win_update_reject_list | length) or (failed_kb | length)
- name: install all windows updates
win_updates:
server_selection: "{{ win_update_server_selection }}"
category_names: "{{ win_update_category_names }}"
reject_list: "{{ _reject_list | default(omit) }}"
accept_list: "{{ win_update_accept_list | default(omit) }}"
reboot: false
async: 7200
poll: 0
register: installed_updates_async
- name: wait for updates to finish
async_status:
jid: "{{ installed_updates_async.ansible_job_id }}"
register: installed_updates
until: installed_updates.finished
retries: "{{ install_updates_retry_limit }}"
delay: 30
- name: reboot the system if required
win_reboot:
reboot_timeout: 7200
when: installed_updates.reboot_required
rescue:
- name: ensure there is connection
wait_for_connection:
delay: 60
sleep: 10
timeout: 600
# see https://learn.microsoft.com/en-us/sharepoint/troubleshoot/administration/800703fa-illegal-operation-error
# error code 0x800703FA happens with some updates when user is not logged in
# add the registry key to disable forcefully unloading users registry at user logoff
- include_tasks: force_user_registry.yml
vars:
task_state: present
when:
- installed_updates is defined
- installed_updates is failed
- installed_updates.msg is defined
- ('0x800703FA' in installed_updates.msg)
- name: reboot the system to recover from a failed update
win_reboot:
reboot_timeout: 7200
- name: set failed KB to skip
set_fact:
failed_kb: "{{ failed_kb|default([]) + [installed_updates.msg | regex_replace('^.*\\((KB.*)\\).*','\\1')] }}"
when:
- installed_updates.msg is defined
- ('Failed' in installed_updates.msg)
- ('KB' in installed_updates.msg)
- name: fail to retry
fail:
msg: "There are failed updates: {{ failed_kb | join(' ') }}"
when:
- failed_kb is defined
- failed_kb | length > 0
- name: wait for system to be responsive after update
wait_for_connection:
delay: 60
sleep: 10
timeout: 600
- block:
- name: work on any skipped KB
win_updates:
server_selection: "{{ win_update_server_selection }}"
category_names: "{{ win_update_category_names }}"
reject_list: "{{ win_update_reject_list | default(omit) }}"
accept_list: "{{ failed_kb | default(omit) }}"
reboot: false
async: 7200
poll: 0
register: installed_updates_retry_skipped_async
- name: wait for updates to finish
async_status:
jid: "{{ installed_updates_retry_skipped_async.ansible_job_id }}"
register: installed_updates_retry_skipped
until: installed_updates_retry_skipped.finished
retries: "{{ install_updates_retry_limit }}"
delay: 30
- name: reboot the system if required
win_reboot:
reboot_timeout: 7200
when: installed_updates_retry_skipped.reboot_required
when:
- failed_kb is defined
- failed_kb | length > 0
- name: check for missing updates
win_updates:
server_selection: "{{ win_update_server_selection }}"
category_names: "{{ win_update_category_names }}"
reject_list: "{{ win_update_reject_list | default(omit) }}"
state: searched
register: missing_updates
- debug:
msg: "{{ _msg.split('\n')[:-1] }}"
vars:
_msg: |
{{ inventory_hostname }} has {{ missing_updates.found_update_count }} updates still missing.
{% for update in updates %}
- {{ update.title }}
{% endfor %}
updates: "{{ (missing_updates.updates.values() | list) if (missing_updates.updates is mapping) else (missing_updates.updates) }}"
when: missing_updates.updates is defined
- name: still more updates - need to retry
fail:
msg: >
'{{ inventory_hostname }} has {{ missing_updates.found_update_count }} updates still missing.
{{ (update_retry_limit | int) - (update_retry_count | int) }} more retries left'
when:
- missing_updates.found_update_count > 0
- ((update_retry_limit | int) - (update_retry_count | int) > 0)
rescue:
- name: set update count
set_fact:
update_retry_count: '{{ update_retry_count | default(0) | int + 1 }}'
- debug:
msg: "Still more updates ({{ current_update_count }}) remaining - retrying... ({{ update_retry_count }}/{{ update_retry_limit }})"
vars:
current_update_count: "{{ missing_updates.found_update_count | default(installed_updates.found_update_count) | default('-') }}"
- name: ensure system is reachable
wait_for_connection:
sleep: 10
timeout: 600
- include_tasks: updates-with-retry.yml
when: ((update_retry_limit | int) - (update_retry_count | int) > 0)