diff --git a/roles/upgrade/tasks/main.yml b/roles/upgrade/tasks/main.yml index f9114b3..f93a2f8 100644 --- a/roles/upgrade/tasks/main.yml +++ b/roles/upgrade/tasks/main.yml @@ -1,14 +1,59 @@ --- # roles/upgrade/tasks/main.yml +# +# Async pattern: Tailscale may restart during upgrade, dropping SSH. +# Fire and forget → poll status with unreachable tolerance + retries. - name: Upgrade all packages (Alpine) community.general.apk: upgrade: true update_cache: true + async: 3600 + poll: 0 + register: alpine_upgrade + # By default async job return change: true + # Force adapting the change condition for idempotency + changed_when: false when: ansible_facts['os_family'] == "Alpine" +- name: Wait for Alpine upgrade + ansible.builtin.async_status: + jid: "{{ alpine_upgrade.ansible_job_id }}" + register: alpine_result + until: alpine_result.finished + retries: 60 + delay: 10 + # By default async job return change: true + # Force adapting the change condition for idempotency + changed_when: alpine_result.changed | default(false) + ignore_unreachable: true + when: + - ansible_facts['os_family'] == "Alpine" + - alpine_upgrade.ansible_job_id is defined + - name: Upgrade all packages (Debian) ansible.builtin.apt: upgrade: full update_cache: true + async: 3600 + poll: 0 + register: debian_upgrade + # By default async job return change: true + # Force adapting the change condition for idempotency + changed_when: false when: ansible_facts['os_family'] == "Debian" + +- name: Wait for Debian upgrade + ansible.builtin.async_status: + jid: "{{ debian_upgrade.ansible_job_id }}" + register: debian_result + until: debian_result.finished + retries: 60 + delay: 10 + # By default async job return change: true + # Force adapting the change condition for idempotency + changed_when: debian_result.changed | default(false) + ignore_unreachable: true + when: + - ansible_facts['os_family'] == "Debian" + - debian_upgrade.ansible_job_id is defined