151 lines
7.2 KiB
YAML
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"
|