From 6b6cc7318534b9a84df53773a9f86d7904b88ffe Mon Sep 17 00:00:00 2001 From: Kienan Stewart Date: Mon, 12 Jun 2023 15:38:32 -0400 Subject: [PATCH] ansible: Add playbook for Debian major version upgrades Useful when recreating the node from scratch isn't a quick option Change-Id: I5ebd413604a0f0f48474c205ae88a8a7bf99c2ee --- .../ansible/playbooks/debian-upgrade.yml | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 automation/ansible/playbooks/debian-upgrade.yml diff --git a/automation/ansible/playbooks/debian-upgrade.yml b/automation/ansible/playbooks/debian-upgrade.yml new file mode 100644 index 0000000..6e6ce6d --- /dev/null +++ b/automation/ansible/playbooks/debian-upgrade.yml @@ -0,0 +1,172 @@ +--- +- name: Set next release + hosts: all + tasks: + - debug: + msg: "{{lookup('vars', ansible_distribution+'_releases', default=[])}}" + - debug: + msg: "{{ansible_distribution_release}}" + - set_fact: + release_index: "{{lookup('ansible.utils.index_of', data=lookup('vars', ansible_distribution+'_releases', default=[]), test='eq', value=ansible_distribution_release)}}" + # If there is not a next release available (as defined below in Debian_releasess + # or Ubuntu_releases), the execution of the playbook will fail at this step. + - set_fact: + next_release: "{{lookup('vars', ansible_distribution+'_releases')[release_index|int + 1]}}" + - debug: + msg: "{{next_release}}" + vars: + # 'stable' releases ordered from oldest to newest + Debian_releases: + - buster + - bullseye + - bookworm + Ubuntu_releases: + - xenial + - bionic + - focal + - jammy +- name: Run any outstanding upgrades + hosts: all + tasks: + - apt: + update_cache: true + - apt: + upgrade: dist + - apt: + autoremove: true + purge: true +- name: Pre-upgrade backups + hosts: all + tasks: + - name: Check if /etc is a git repo + register: etckeeper + command: + cmd: test -d /etc/.git + ignore_errors: true + - name: Tag etc configuration + when: etckeeper.rc == 0 + block: + - command: + chdir: /etc + argv: + - git + - tag + - "pre-{{next_release}}" + - command: + chdir: /etc + cmd: 'git gc --prune' + - name: Backup package state + block: + - shell: + cmd: "tar czf /var/backups/pre-{{next_release}}-backup.tgz /etc /var/lib/dpkg /var/lib/apt/extended_states" + # Mitogen doesn't seem to work with the 'archive' module, since tarfile is + # "present in the Mitogent importer blacklist", so a shell command is used + # here instead + warn: false + - shell: + cmd: "dpkg --get-selections '*' > /var/backups/dpkg-selections-pre-{{next_release}}.txt" + - file: + path: "{{item}}" + mode: '0600' + with_items: + - "/var/backups/pre-{{next_release}}-backup.tgz" + - "/var/backups/dpkg-selections-pre-{{next_release}}.txt" +- name: Debian major version upgrade + hosts: all + when: ansible_distribution == 'Debian' + vars: + apt_noninteractive_environment: + DEBIAN_FRONTEND: noninteractive + APT_LISTCHANGES_FRONTEND: mail + tasks: + # @TODO: Remove pins + # @TODO: Should 3rd party sources be removed? + # @TODO: Ensure kernel package is installed + # @TODO: Should a 2nd sshd be started on a non-standard port in case of failure? + - name: dpkg audit + command: + cmd: 'dpkg --audit' + - name: show holds + command: + cmd: 'apt-mark showhold' + - name: remove all holds + command: + cmd: "apt-mark unhold '*'" + - name: Replace release in apt sources.list + replace: + regexp: "{{ansible_distribution_release}}" + replace: "{{next_release}}" + path: /etc/apt/sources.list + - name: Replace release in apt sources.list.d + shell: + cmd: "sed -i 's/{{ansible_distribution_release}}/{{next_release}}/' /etc/apt/sources.list.d/*" + warn: false + ignore_errors: true + - apt: + update_cache: true + # @TODO: Check required disk space and available disk space + - name: Download packages + command: + cmd: 'apt-get -y -d upgrade' + warn: false + environment: "{{apt_noninteractive_environment}}" + - name: Minimal upgrade run + command: + cmd: 'apt upgrade -y --without-new-pkgs' + warn: false + environment: "{{apt_noninteractive_environment}}" + - name: Full upgrade run + command: + cmd: 'apt full-upgrade -y' + warn: false + environment: "{{apt_noninteractive_environment}}" + # @TODO: reconfigure grub if installed + # `dpkg-reconfigure grub-pc` on many systems, but not all + # @TODO: Our instances often have an OS version identifier, + # it would be handy to do a replace in /etc/hostname + # before rebooting + - name: Reboot + command: /usr/sbin/reboot + async: 0 + poll: 0 + ignore_errors: true + register: last_result + - name: wait for the server to reboot + local_action: wait_for host={{ inventory_hostname }} + port=22 + delay=1 + timeout=300 + state=started + when: last_result.changed + become: false + - name: Purge configuration of removed packages + command: + cmd: "apt -y purge '~c'" + warn: false + environment: "{{apt_noninteractive_environment}}" + - name: Purge obsolete packages + command: + cmd: "apt -y purge '~o'" + warn: false + environment: "{{apt_noninteractive_environment}}" +- name: Ubuntu major version upgrade + hosts: all + when: ansible_distribution == 'Ubuntu' + tasks: + - name: Do release upgrade + command: + cmd: 'do-release-upgrade -m server --frontend=DistUpgradeViewNonInteractive' +- name: Post-upgrade tasks + hosts: all + tasks: + - name: Mark rsyslog as auto + when: next_release == 'bookworm' + command: + cmd: 'apt-mark auto rsyslog' + - name: Autoremove any packages + apt: + autoremove: true + purge: true + - name: Clean apt cache + apt: + autoclean: true -- 2.34.1