Files

151 lines
7.2 KiB
YAML

# pfi-pve: no-downtime prep for the PVE 8 → 9 upgrade (Prime 2026-10-04: "drive the ana pve upgrade to proxmox 9").
# scripts/elway infra-ops@10.250.250.31 --playbook playbooks/pfi-pve-pve9-prep.yaml
# Plan + rationale: docs/runbooks/pfi-pve-pve9-upgrade-plan.md. Template: playbooks/esh-nas-pve-pve9-prep.yaml.
# Nothing here reboots or touches a guest. The new kernel, microcode, bootloader and NIC pins all take effect at the
# NEXT boot, which is the planned reboot test on PVE 8, BEFORE any repo switch to trixie.
# - latest 8.4 packages (it is on 8.3.5 / kernel 6.8.12-8; pve8to9 only exists from 8.4);
# - non-free-firmware + intel-microcode;
# - grub-pc → grub-efi-amd64. The box boots UEFI from \EFI\proxmox\grubx64.efi, but the BIOS meta package is the
# one installed, so that EFI binary has not been touched since the 2023-03-30 (PVE 7.4 / bullseye) install. The
# PVE 8→9 wiki's "UEFI systems with root on LVM may fail to boot" fix is exactly this package. The 2023 binary is
# copied to EFI/proxmox-2023/ as a last resort only: once grub-install replaces /boot/grub/x86_64-efi, an old core
# loading new modules can fail (the grub_is_lockdown class), so the real fallback is the tar of /boot/grub;
# - pin every NIC name by MAC. vmbr0 has four ports and only eno8303 has carrier; the two bnxt ports carry an
# `np0/np1` phys_port_name suffix, the class of name the wiki says a new kernel can change.
vars:
stage_dir: /root/pve9-prep-20261004
steps:
- name: back up /etc, the package list and the 2023 EFI binaries
sudo: true
shell: |
set -e
mkdir -p {{ stage_dir }}
tar czf {{ stage_dir }}/etc-before.tar.gz -C / etc 2>/dev/null
dpkg -l > {{ stage_dir }}/dpkg-before.txt
pveversion -v > {{ stage_dir }}/pveversion-before.txt 2>&1
cp -p /etc/network/interfaces {{ stage_dir }}/interfaces.before
cp -p /etc/apt/sources.list {{ stage_dir }}/sources.list.before
cp -a /boot/efi/EFI {{ stage_dir }}/EFI-2023
cp -a /boot/grub {{ stage_dir }}/boot-grub-before
ls -la {{ stage_dir }}
creates: "{{ stage_dir }}/etc-before.tar.gz"
- name: keep the 2023 GRUB bootable from the ESP (EFI/proxmox-2023/)
sudo: true
shell: |
set -e
mkdir -p /boot/efi/EFI/proxmox-2023
cp -p /boot/efi/EFI/proxmox/grubx64.efi /boot/efi/EFI/proxmox-2023/grubx64.efi
md5sum /boot/efi/EFI/proxmox-2023/grubx64.efi
creates: /boot/efi/EFI/proxmox-2023/grubx64.efi
- name: add non-free-firmware to the Debian bookworm lines (for intel-microcode)
sudo: true
shell: sed -i -E '/^deb .*debian(\.org)?(\/debian)? bookworm/{/non-free-firmware/!s/$/ non-free-firmware/}' /etc/apt/sources.list
when: "grep -E '^deb .*debian(\\.org)?(/debian)? bookworm' /etc/apt/sources.list | grep -qv non-free-firmware"
- name: apt update (must be clean)
sudo: true
shell: |
! apt-get update -q 2>&1 | grep -E '^(E|Err):'
changed_when: "false"
- name: latest 8.4 packages (keep local configs)
sudo: true
shell: |
set -o pipefail
DEBIAN_FRONTEND=noninteractive apt-get full-upgrade -y -q \
-o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold 2>&1 | tail -8
pveversion | cat
- name: intel-microcode
sudo: true
shell: DEBIAN_FRONTEND=noninteractive apt-get install -y -q intel-microcode 2>&1 | tail -3
when: "! dpkg-query -W -f='${Status}' intel-microcode 2>/dev/null | grep -q 'install ok installed'"
- name: grub-pc → grub-efi-amd64, with the removable-path copy (EFI/BOOT/BOOTX64.EFI) kept in step
sudo: true
shell: |
set -o pipefail
echo 'grub-efi-amd64 grub2/force_efi_extra_removable boolean true' | debconf-set-selections -v -u
DEBIAN_FRONTEND=noninteractive apt-get install -y -q --no-install-recommends grub-efi-amd64 2>&1 | tail -8
when: "! dpkg-query -W -f='${Status}' grub-efi-amd64 2>/dev/null | grep -q 'install ok installed'"
- name: make sure the ESP binary was actually rewritten (grub-install explicitly if the postinst skipped it)
sudo: true
shell: |
set -e
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=proxmox --force-extra-removable 2>&1 | tail -3
update-grub 2>&1 | tail -3
when: "test \"$(md5sum < /boot/efi/EFI/proxmox/grubx64.efi | cut -d' ' -f1)\" = a4a8d8d1e75eb2dad19c22a8c1065c4c"
- name: pin every NIC name to its MAC (systemd .link; takes effect next boot)
sudo: true
shell: |
set -e
pin() { # name mac
cat > /etc/systemd/network/10-pin-$1.link <<EOF
# Pin $1 by MAC so the PVE 9 / Debian 13 udev cannot rename it.
# See eshpfi playbooks/pfi-pve-pve9-prep.yaml
[Match]
MACAddress=$2
Type=ether
[Link]
Name=$1
EOF
}
pin eno8303 cc:48:3a:1b:c3:d0
pin eno8403 cc:48:3a:1b:c3:d1
pin eno12399np0 00:62:0b:c6:ca:f0
pin eno12409np1 00:62:0b:c6:ca:f1
ls -la /etc/systemd/network/
when: "! test -f /etc/systemd/network/10-pin-eno8303.link"
- name: rebuild the initramfs of the running and the newest kernel so the .link files apply in early boot
sudo: true
shell: |
set -e
new=$(ls /boot/vmlinuz-* | sed 's#/boot/vmlinuz-##' | sort -V | tail -1)
for k in $(uname -r) $new; do update-initramfs -u -k $k 2>&1 | tail -1; done
when: "! lsinitramfs /boot/initrd.img-$(ls /boot/vmlinuz-* | sed 's#/boot/vmlinuz-##' | sort -V | tail -1) | grep -q 10-pin-eno8303.link"
verify:
- name: interfaces file still parses (no live reload)
sudo: true
shell: ifreload -a -s
changed_when: "false"
- name: newest kernel's initramfs carries the uplink pin
sudo: true
shell: lsinitramfs /boot/initrd.img-$(ls /boot/vmlinuz-* | sed 's#/boot/vmlinuz-##' | sort -V | tail -1) | grep -q 10-pin-eno8303.link
changed_when: "false"
- name: grub-efi-amd64 in, grub-pc out, intel-microcode in
sudo: true
shell: |
dpkg-query -W -f='${Status}' grub-efi-amd64 | grep -q 'install ok installed' &&
! dpkg-query -W -f='${Status}' grub-pc 2>/dev/null | grep -q 'install ok installed' &&
dpkg-query -W -f='${Status}' intel-microcode | grep -q 'install ok installed'
changed_when: "false"
- name: ESP carries a NEW grubx64.efi, the removable copy matches it, the 2023 copy is kept
sudo: true
shell: |
set -e
a=$(md5sum < /boot/efi/EFI/proxmox/grubx64.efi | cut -d' ' -f1)
b=$(md5sum < /boot/efi/EFI/BOOT/BOOTX64.EFI | cut -d' ' -f1)
test "$a" != a4a8d8d1e75eb2dad19c22a8c1065c4c
test "$a" = "$b"
test "$(md5sum < /boot/efi/EFI/proxmox-2023/grubx64.efi | cut -d' ' -f1)" = a4a8d8d1e75eb2dad19c22a8c1065c4c
ls -la --time-style=long-iso /boot/efi/EFI/proxmox/ /boot/efi/EFI/BOOT/
changed_when: "false"
- name: firmware boots the proxmox entry first
sudo: true
shell: |
efibootmgr -v | grep -E '^BootOrder|proxmox'
first=$(efibootmgr | sed -n 's/^BootOrder: \([0-9A-F]*\).*/\1/p')
efibootmgr -v | grep -E "^Boot${first}\*? " | grep -qi 'EFI\\proxmox\\grubx64.efi'
changed_when: "false"
- name: pve8to9 --full summary
sudo: true
shell: pve8to9 --full 2>&1 | grep -E '^(FAIL|WARN):|^= SUMMARY|TOTAL|PASSED|SKIPPED|WARNINGS|FAILURES' | cat
changed_when: "false"