From 2ea8c2f9afb57206ba61ef4aa89d30198269b2ab Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 17 Jun 2026 14:15:33 -0400 Subject: [PATCH] feat(ansible): bundled system_update maintenance playbook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New maintenance/system_update.yml: cross-distro OS package upgrade (apt + dnf/yum) with two run-form flags: - restart_services: restart every service that needs it after the upgrade (Debian via needrestart -r a, installed if missing; RHEL via needs-restarting -s → systemctl try-restart). - reboot_if_required: reboot the host only when a reboot is actually pending (Debian /var/run/reboot-required; RHEL needs-restarting -r). Never reboots otherwise. Tagged steward:category=maintenance and steward:confirm=true (significant / reboot-capable), so it shows in the run UI with the confirm gate and both flags as fill-in fields. No code changes — auto-discovered from the builtin source. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../bundled/maintenance/system_update.yml | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 steward/ansible/bundled/maintenance/system_update.yml diff --git a/steward/ansible/bundled/maintenance/system_update.yml b/steward/ansible/bundled/maintenance/system_update.yml new file mode 100644 index 0000000..f94bebe --- /dev/null +++ b/steward/ansible/bundled/maintenance/system_update.yml @@ -0,0 +1,82 @@ +--- +# description: Update all OS packages; optionally restart affected services and reboot if one is pending. +# steward:category: maintenance +# steward:confirm: true +# +# Cross-distro (apt / dnf-yum). Flags (set in the run form): +# restart_services=true after the upgrade, restart every service that needs +# it (Debian: needrestart -r a; installed if missing). +# reboot_if_required=true reboot the host only if the update flagged a pending +# reboot (Debian: /var/run/reboot-required; +# RHEL: needs-restarting -r). Never reboots otherwise. +- name: System package update + hosts: all + become: true + gather_facts: true + vars: + restart_services: false + reboot_if_required: false + tasks: + # ── Debian / Ubuntu ────────────────────────────────────────────────────── + - name: Upgrade all packages (apt) + ansible.builtin.apt: + update_cache: true + upgrade: dist + autoremove: true + when: ansible_pkg_mgr == "apt" + + - name: Ensure needrestart is present (apt, for service restarts) + ansible.builtin.apt: + name: needrestart + state: present + when: + - restart_services | bool + - ansible_pkg_mgr == "apt" + + - name: Restart services that need it (apt / needrestart) + ansible.builtin.command: needrestart -r a + register: needrestart_run + changed_when: needrestart_run.rc == 0 + failed_when: false + when: + - restart_services | bool + - ansible_pkg_mgr == "apt" + + # ── RHEL / Fedora ───────────────────────────────────────────────────────── + - name: Upgrade all packages (dnf/yum) + ansible.builtin.dnf: + name: "*" + state: latest + when: ansible_pkg_mgr in ("dnf", "yum") + + - name: Restart services that need it (dnf / needs-restarting) + ansible.builtin.shell: needs-restarting -s | xargs -r -n1 systemctl try-restart + register: rhel_restart + changed_when: rhel_restart.rc == 0 + failed_when: false + when: + - restart_services | bool + - ansible_pkg_mgr in ("dnf", "yum") + + # ── Reboot only if one is pending ───────────────────────────────────────── + - name: Check pending reboot (Debian) + ansible.builtin.stat: + path: /var/run/reboot-required + register: deb_reboot + when: ansible_pkg_mgr == "apt" + + - name: Check pending reboot (RHEL) + ansible.builtin.command: needs-restarting -r + register: rhel_reboot + changed_when: false + failed_when: false + when: ansible_pkg_mgr in ("dnf", "yum") + + - name: Reboot if required + ansible.builtin.reboot: + msg: "Reboot triggered by Steward system_update" + reboot_timeout: 900 + when: + - reboot_if_required | bool + - (ansible_pkg_mgr == "apt" and deb_reboot.stat.exists) + or (ansible_pkg_mgr in ("dnf", "yum") and (rhel_reboot.rc | default(0)) != 0)