From 2639c5e87228e16810d263ee9fd043ab39966081 Mon Sep 17 00:00:00 2001 From: Damien Date: Mon, 1 Jun 2026 10:55:15 +0200 Subject: [PATCH 1/2] Add upgrade tasks for Alpine and Debian systems --- roles/upgrade/tasks/main.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/roles/upgrade/tasks/main.yml b/roles/upgrade/tasks/main.yml index e69de29..f9114b3 100644 --- a/roles/upgrade/tasks/main.yml +++ b/roles/upgrade/tasks/main.yml @@ -0,0 +1,14 @@ +--- +# roles/upgrade/tasks/main.yml + +- name: Upgrade all packages (Alpine) + community.general.apk: + upgrade: true + update_cache: true + when: ansible_facts['os_family'] == "Alpine" + +- name: Upgrade all packages (Debian) + ansible.builtin.apt: + upgrade: full + update_cache: true + when: ansible_facts['os_family'] == "Debian" From 5d567d15367d9f36999724021cc6f7aeb94b7bea Mon Sep 17 00:00:00 2001 From: Damien Date: Mon, 1 Jun 2026 11:27:27 +0200 Subject: [PATCH 2/2] Add async pattern for package upgrades with unreachable tolerance --- roles/upgrade/tasks/main.yml | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) 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