170 lines
6.6 KiB
YAML

---
- name: Get list of upgradable packages (for reporting)
ansible.builtin.shell: |
apt list --upgradable 2>/dev/null | grep -v "WARNING" | tail -n +2 | wc -l
args:
executable: /bin/bash
register: maintenance_upgradable_count
changed_when: false
- name: Display packages to be upgraded
ansible.builtin.debug:
msg: |
📦 Package Upgrade Summary:
- Total packages to upgrade: {{ maintenance_upgradable_count.stdout | default('0') }}
- Upgrade type: {{ maintenance_upgrade_type }}
- Max retries: {{ maintenance_apt_retries }}
- Retry delay: {{ maintenance_apt_retry_delay }}s
when: ansible_debug_output | default(false) | bool
- name: Show upgradable packages (first 10)
ansible.builtin.shell: |
apt list --upgradable 2>/dev/null | grep -v "WARNING" | head -10
args:
executable: /bin/bash
register: maintenance_upgradable_packages_preview
changed_when: false
when: maintenance_upgradable_count.stdout | int > 0
- name: Display upgradable packages
ansible.builtin.debug:
msg: |
📋 Packages to upgrade:
{{ maintenance_upgradable_packages_preview.stdout_lines | join('\n') }}
when:
- maintenance_upgradable_count.stdout | int > 0
- ansible_debug_output | default(false) | bool
- maintenance_upgradable_packages_preview.stdout_lines is defined
- name: Update apt cache with retries
ansible.builtin.apt:
update_cache: "{{ maintenance_update_cache }}"
cache_valid_time: "{{ maintenance_cache_valid_time }}"
retries: "{{ maintenance_apt_retries }}"
delay: "{{ maintenance_cache_retry_delay }}"
register: maintenance_apt_update_result
until: maintenance_apt_update_result is succeeded
when: maintenance_update_cache | bool
- name: Fix broken packages if any
ansible.builtin.command:
cmd: apt-get --fix-broken install -y # noqa command-instead-of-module
become: true
changed_when: false
failed_when: false
when: maintenance_fix_broken | bool
- name: Upgrade packages with retries and verbose output
ansible.builtin.apt:
upgrade: "{{ maintenance_upgrade_type }}"
force_apt_get: true
update_cache: false # Already updated above
environment:
DEBIAN_FRONTEND: noninteractive
APT_LISTCHANGES_FRONTEND: none
retries: "{{ maintenance_apt_retries }}"
delay: "{{ maintenance_apt_retry_delay }}"
register: maintenance_apt_upgrade_result
until: maintenance_apt_upgrade_result is succeeded
ignore_errors: true
async: "{{ maintenance_bulk_upgrade_timeout }}"
poll: "{{ maintenance_bulk_poll_interval }}"
no_log: "{{ not (ansible_debug_output | default(false) | bool) }}"
when: maintenance_upgrade_packages | bool
- name: Fallback to individual package upgrades if full upgrade failed
when:
- maintenance_apt_upgrade_result is failed
- maintenance_individual_upgrade_fallback | bool
block:
- name: Display fallback message
ansible.builtin.debug:
msg: |
⚠️ Bulk upgrade failed, trying individual package upgrades...
This may take longer but is more reliable for problematic packages.
- name: Get list of upgradable packages for individual upgrade
ansible.builtin.shell: |
apt list --upgradable 2>/dev/null | grep -v "WARNING" | tail -n +2 | cut -d'/' -f1
args:
executable: /bin/bash
register: maintenance_upgradable_packages_fallback
changed_when: false
- name: Display packages for individual upgrade
ansible.builtin.debug:
msg: |
🔄 Attempting individual upgrade for {{ maintenance_upgradable_packages_fallback.stdout_lines | length }} packages:
{{ maintenance_upgradable_packages_fallback.stdout_lines | join(', ') }}
when: maintenance_upgradable_packages_fallback.stdout_lines | length > 0
- name: Upgrade packages individually with progress
ansible.builtin.apt:
name: "{{ item }}"
state: latest # noqa package-latest - This is intentional for maintenance upgrades
force_apt_get: true
environment:
DEBIAN_FRONTEND: noninteractive
APT_LISTCHANGES_FRONTEND: none
loop: "{{ maintenance_upgradable_packages_fallback.stdout_lines | default([]) }}"
loop_control:
label: "📦 Upgrading {{ item }} ({{ ansible_loop.index }}/{{ ansible_loop.length }})"
retries: 2
delay: 10
ignore_errors: true
async: "{{ maintenance_individual_timeout }}"
poll: "{{ maintenance_individual_poll_interval }}"
no_log: "{{ not (ansible_debug_output | default(false) | bool) }}"
register: maintenance_individual_upgrade_results
when: maintenance_upgradable_packages_fallback.stdout_lines | length > 0
- name: Summary of individual upgrades
ansible.builtin.debug:
msg: |
📊 Individual Upgrade Results:
- Total attempted: {{ maintenance_individual_upgrade_results.results | length | default(0) }}
- Successful: {{ maintenance_individual_upgrade_results.results | selectattr('changed', 'equalto', true) | list | length | default(0) }}
- Failed: {{ maintenance_individual_upgrade_results.results | selectattr('failed', 'equalto', true) | list | length | default(0) }}
when:
- maintenance_individual_upgrade_results is defined
- maintenance_individual_upgrade_results.results is defined
- name: Autoremove unused packages
ansible.builtin.apt:
autoremove: true
purge: true
retries: 2
delay: 5
when: maintenance_autoremove | bool
- name: Clean apt cache
ansible.builtin.apt:
autoclean: true
when: maintenance_autoclean | bool
- name: Check if reboot is required
ansible.builtin.stat:
path: /var/run/reboot-required
register: maintenance_reboot_required
when: maintenance_check_reboot | bool
- name: Display maintenance summary
ansible.builtin.debug:
msg: |
Maintenance Summary:
- Cache update: {{ 'Completed' if maintenance_apt_update_result is succeeded else 'Skipped/Failed' }}
- Package upgrade: {{ 'Completed' if maintenance_apt_upgrade_result is succeeded else 'Failed (fallback may have run)' }}
- Reboot required: {{ 'Yes' if (maintenance_reboot_required.stat.exists | default(false)) else 'No' }}
when: ansible_debug_output | default(false) | bool
- name: Reboot if required
ansible.builtin.reboot:
msg: "Reboot triggered by Ansible after system maintenance."
reboot_timeout: "{{ maintenance_reboot_timeout }}"
pre_reboot_delay: "{{ maintenance_pre_reboot_delay }}"
when:
- maintenance_check_reboot | bool
- maintenance_allow_reboot | bool
- maintenance_reboot_required.stat.exists | default(false)
- not (skip_reboot | default(false) | bool)