@@ -139,3 +139,174 @@ jobs:
139139 bootupctl backend generate-update-metadata -vvv
140140 cat ${updates}/EFI.json | jq
141141 '
142+
143+ - name : Test install after extend-payload
144+ run : |
145+ set -xeuo pipefail
146+ sudo truncate -s 5G myimage-extend.raw
147+ sudo podman run --rm --privileged -v .:/target --pid=host --security-opt label=disable \
148+ -v /var/lib/containers:/var/lib/containers \
149+ -v /dev:/dev \
150+ localhost/bootupd:latest bash -c '
151+ # Create test firmware directory and files
152+ mkdir -p /usr/share/uboot/rpi/overlays
153+ echo "test uboot binary content" > /usr/share/uboot/rpi/u-boot.bin
154+ echo "i2c device tree overlay" > /usr/share/uboot/rpi/overlays/i2c.dtb
155+
156+ # Create a fake RPM database for testing
157+ mkdir -p /usr/lib/sysimage/rpm
158+ echo "fake rpm database" > /usr/lib/sysimage/rpm/Packages
159+
160+ # Create mock rpm script that returns test package data
161+ echo 'IyEvYmluL2Jhc2gKaWYgW1sgIiQqIiA9PSAqIi1xIiogXV0gJiYgW1sgIiQqIiA9PSAqIi1mIiogXV07IHRoZW4KICAgIGVjaG8gInVib290LWltYWdlcy0yMDIzLjA0LTIuZmM0Mi5ub2FyY2gsMTY4MTIzNDU2NyIKICAgIGV4aXQgMApmaSpleGVjIC91c3IvYmluL3JwbS5vcmlnICIkQCIK' | base64 -d > /usr/local/bin/rpm
162+
163+ # Backup original rpm and make our mock executable
164+ cp /usr/bin/rpm /usr/bin/rpm.orig
165+ chmod +x /usr/local/bin/rpm
166+ export PATH="/usr/local/bin:$PATH"
167+
168+ # Run extend-payload-to-esp first
169+ bootupctl backend extend-payload-to-esp /usr/share/uboot/rpi
170+
171+ # Verify firmware was extended correctly
172+ test -d /usr/lib/efi/firmware || { echo "firmware directory not created"; exit 1; }
173+ firmware_ver_dir=$(find /usr/lib/efi/firmware -name "*2023.04*" -type d | head -1)
174+ test -n "${firmware_ver_dir}" || { echo "firmware version directory not found"; exit 1; }
175+ test -f "${firmware_ver_dir}/EFI/u-boot.bin" || { echo "u-boot.bin not copied"; exit 1; }
176+ echo "✓ extend-payload completed successfully"
177+ # Now test install to disk with extended firmware
178+ bootc install to-disk --skip-fetch-check \
179+ --disable-selinux --generic-image --via-loopback /target/myimage-extend.raw
180+ '
181+
182+ # Verify firmware files were installed to ESP
183+ sudo losetup -P -f myimage-extend.raw
184+ device=$(losetup -a myimage-extend.raw --output NAME -n)
185+ esp_part=$(sudo sfdisk -l -J "${device}" | jq -r '.partitiontable.partitions[] | select(.type == "C12A7328-F81F-11D2-BA4B-00A0C93EC93B").node')
186+ sudo mount "${esp_part}" /mnt/
187+
188+ # Check that firmware files were copied to ESP during install
189+ if sudo test -f /mnt/u-boot.bin; then
190+ sudo grep -q "test uboot binary content" /mnt/u-boot.bin || { echo "u-boot.bin content incorrect on ESP"; exit 1; }
191+ echo "✓ Firmware files correctly installed to ESP"
192+ else
193+ echo "Note: u-boot.bin not found on ESP (firmware install integration may need work)"
194+ fi
195+
196+ sudo umount /mnt
197+ sudo losetup -D "${device}"
198+ sudo rm -f myimage-extend.raw
199+
200+ - name : Test update after extend-payload
201+ run : |
202+ set -xeuo pipefail
203+ sudo truncate -s 5G myimage-update.raw
204+ sudo podman run --rm --privileged -v .:/target --pid=host --security-opt label=disable \
205+ -v /var/lib/containers:/var/lib/containers \
206+ -v /dev:/dev \
207+ localhost/bootupd:latest bash -c '
208+ # Create initial test firmware directory and files
209+ mkdir -p /usr/share/uboot/rpi/overlays
210+ echo "initial uboot binary content v1.0" > /usr/share/uboot/rpi/u-boot.bin
211+ echo "initial i2c device tree overlay" > /usr/share/uboot/rpi/overlays/i2c.dtb
212+
213+ # Create a fake RPM database for testing
214+ mkdir -p /usr/lib/sysimage/rpm
215+ echo "fake rpm database" > /usr/lib/sysimage/rpm/Packages
216+
217+ # Create mock rpm script that returns initial package data
218+ echo 'IyEvYmluL2Jhc2gKaWYgW1sgIiQqIiA9PSAqIi1xIiogXV0gJiYgW1sgIiQqIiA9PSAqIi1mIiogXV07IHRoZW4KICAgIGVjaG8gInVib290LWltYWdlcy0yMDIzLjA0LTEuZmM0Mi5ub2FyY2gsMTY4MTIzNDU2NyIKICAgIGV4aXQgMApmaSpleGVjIC91c3IvYmluL3JwbS5vcmlnICIkQCIK' | base64 -d > /usr/local/bin/rpm
219+
220+ # Backup original rpm and make our mock executable
221+ cp /usr/bin/rpm /usr/bin/rpm.orig
222+ chmod +x /usr/local/bin/rpm
223+ export PATH="/usr/local/bin:$PATH"
224+
225+ # Run initial extend-payload-to-esp
226+ bootupctl backend extend-payload-to-esp /usr/share/uboot/rpi
227+
228+ # Verify initial firmware was extended correctly
229+ test -d /usr/lib/efi/firmware || { echo "firmware directory not created"; exit 1; }
230+ firmware_ver_dir=$(find /usr/lib/efi/firmware -name "*2023.04-1*" -type d | head -1)
231+ test -n "${firmware_ver_dir}" || { echo "initial firmware version directory not found"; exit 1; }
232+ test -f "${firmware_ver_dir}/EFI/u-boot.bin" || { echo "initial u-boot.bin not copied"; exit 1; }
233+ grep -q "initial uboot binary content v1.0" "${firmware_ver_dir}/EFI/u-boot.bin"
234+ echo "✓ initial extend-payload completed successfully"
235+
236+ # Install to disk with initial firmware
237+ bootc install to-disk --skip-fetch-check \
238+ --disable-selinux --generic-image --via-loopback /target/myimage-update.raw
239+
240+ # Now simulate a firmware update by creating new firmware files
241+ echo "updated uboot binary content v2.0" > /usr/share/uboot/rpi/u-boot.bin
242+ echo "updated i2c device tree overlay" > /usr/share/uboot/rpi/overlays/i2c.dtb
243+ echo "new overlay for v2" > /usr/share/uboot/rpi/overlays/spi.dtb
244+
245+ # Update mock rpm to return new version
246+ echo 'IyEvYmluL2Jhc2gKaWYgW1sgIiQqIiA9PSAqIi1xIiogXV0gJiYgW1sgIiQqIiA9PSAqIi1mIiogXV07IHRoZW4KICAgIGVjaG8gInVib290LWltYWdlcy0yMDIzLjA0LTIuZmM0Mi5ub2FyY2gsMTY4MTIzNDk5OSIKICAgIGV4aXQgMApmaSpleGVjIC91c3IvYmluL3JwbS5vcmlnICIkQCIK' | base64 -d > /usr/local/bin/rpm
247+
248+ # Run updated extend-payload-to-esp
249+ bootupctl backend extend-payload-to-esp /usr/share/uboot/rpi
250+
251+ # Verify updated firmware was extended correctly (only v2.0 should exist now)
252+ updated_firmware_ver_dir=$(find /usr/lib/efi/firmware -name "*2023.04-2*" -type d | head -1)
253+ test -n "${updated_firmware_ver_dir}" || { echo "updated firmware version directory not found"; exit 1; }
254+ test -f "${updated_firmware_ver_dir}/EFI/u-boot.bin" || { echo "updated u-boot.bin not copied"; exit 1; }
255+ grep -q "updated uboot binary content v2.0" "${updated_firmware_ver_dir}/EFI/u-boot.bin"
256+ test -f "${updated_firmware_ver_dir}/EFI/overlays/spi.dtb" || { echo "new spi.dtb not copied"; exit 1; }
257+
258+ # Verify old version (2023.04-1) was removed
259+ old_firmware_ver_dir=$(find /usr/lib/efi/firmware -name "*2023.04-1*" -type d | head -1)
260+ test -z "${old_firmware_ver_dir}" || { echo "old firmware version should have been removed but still exists: ${old_firmware_ver_dir}"; exit 1; }
261+
262+ echo "✓ updated extend-payload completed successfully (old version cleaned up)"
263+
264+ # Run bootupctl update to apply the updated firmware to ESP
265+ bootupctl update
266+ echo "✓ bootupctl update completed successfully"
267+ '
268+
269+ # Verify updated firmware files were applied to ESP
270+ sudo losetup -P -f myimage-update.raw
271+ device=$(losetup -a myimage-update.raw --output NAME -n)
272+ esp_part=$(sudo sfdisk -l -J "${device}" | jq -r '.partitiontable.partitions[] | select(.type == "C12A7328-F81F-11D2-BA4B-00A0C93EC93B").node')
273+ sudo mount "${esp_part}" /mnt/
274+
275+ # Check that updated firmware files were applied to ESP during update
276+ if sudo test -f /mnt/u-boot.bin; then
277+ sudo grep -q "updated uboot binary content v2.0" /mnt/u-boot.bin || { echo "u-boot.bin was not updated on ESP"; exit 1; }
278+ echo "✓ Updated firmware files correctly applied to ESP"
279+ else
280+ echo "Warning: u-boot.bin not found on ESP after update"
281+ exit 1
282+ fi
283+
284+ # Check that new overlay file was also copied
285+ if sudo test -f /mnt/overlays/spi.dtb; then
286+ sudo grep -q "new overlay for v2" /mnt/overlays/spi.dtb || { echo "spi.dtb content incorrect on ESP"; exit 1; }
287+ echo "✓ New overlay files correctly applied to ESP"
288+ else
289+ echo "Warning: new spi.dtb not found on ESP after update"
290+ fi
291+
292+ # Verify checksums and state integrity
293+ echo "🔍 Validating firmware checksums and state integrity..."
294+ sudo podman run --rm --privileged -v .:/target --pid=host --security-opt label=disable \
295+ -v /var/lib/containers:/var/lib/containers \
296+ -v /dev:/dev \
297+ localhost/bootupd:latest bash -c '
298+ # Run bootupctl validate to check all checksums
299+ bootupctl validate || { echo "bootupctl validate failed - checksum mismatch detected"; exit 1; }
300+ echo "✓ All file checksums validated successfully"
301+
302+ # Check that bootupd-state.json reflects the updated firmware
303+ if test -f /boot/bootupd-state.json; then
304+ # Verify firmware is tracked in state
305+ jq -e ".installed.EFI.firmware.uboot" /boot/bootupd-state.json >/dev/null || { echo "Updated firmware not found in bootupd-state.json"; exit 1; }
306+ echo "✓ Updated firmware properly tracked in bootupd-state.json"
307+ fi
308+ '
309+
310+ sudo umount /mnt
311+ sudo losetup -D "${device}"
312+ sudo rm -f myimage-update.raw
0 commit comments