For context, see freedomofpress/securedrop-workstation#887 and freedomofpress/securedrop-yum-test#48
Unpack RPM and reassemble root image
$ rpm2cpio qubes-template-securedrop-workstation-bullseye-4.0.6-202206302135.noarch.rpm | cpio -idmv
$ cat var/lib/qubes/vm-templates/securedrop-workstation-bullseye/root.img.part.* | tar --sparse -xf - -C .
Mount everything that's necessary to use chroot
and ensure DNS will work. losetup
command will give you a /dev/loop
device, the specific number of which depends on whether you already had loop devices established. The specific number of the loop device is replaced with a ?
in these instructions.
$ sudo su
# losetup -P -f --show root.img
# mount /dev/loop?p3 /mnt
# mount -t proc /proc /mnt/proc/
# mount --rbind /sys /mnt/sys/
# mount --make-rslave /mnt/sys/
# mount --rbind /dev /mnt/dev/
# mount --make-rslave /mnt/dev/
# mv /mnt/etc/resolv.conf /mnt/etc/resolv.conf.bak
# cp /etc/resolv.conf /mnt/etc/
# chroot /mnt/ /bin/bash
# (chroot) mkdir /tmp
# (chroot) mount -t tmpfs tmp tmp
Do the update thing
# (chroot) apt update
# (chroot) DEBIAN_FRONTEND=noninteractive apt upgrade
The upgrade command may have GRUB complain because it wants to update the Master Boot Record, we're doing it manually in the next step, so it can be disregarded. Please note: it's important to install the MBR on the "root" loop device rather than partition 3.
# (chroot) grub-install --target=i386-pc --modules=part_gpt /dev/loop?
Clean up after ourselves, including ensuring that the data of the partition are contiguous blocks at the beginning of the partition (hoping that that will help with compression)
# (chroot) umount tmp
# (chroot) rmdir tmp
# (chroot) mv /etc/resolv.conf.bak /etc/resolv.conf
# (chroot) unset HISTFILE
# (chroot) exit
# umount -R /mnt
# losetup -d /dev/loop?
We're removing the loopback device to ensure that some file system operations succeed. This means we will probably get assigned a new loopback device ID:
# losetup -P -f --show root.img
# e2fsck -f /dev/loop?p3
The filesystem check will probably complain about inodes etc, it's good to fix all of the issues
# resize2fs -p /dev/loop?p3 420000K
resize2fs
will complain that the size is too small, but give you the exact $minimum_block_count
. Use that in the next step
# resize2fs -p /dev/loop?p3 $minimum_block_count
Regrowing after having ensured all the data is one continous blob, after which we zero out empty space
# resize2fs -p /dev/loop?p3
# mount /dev/loop?p3 /mnt
# cat /dev/zero > /mnt/fillitup
# rm /mnt/fillitup
# umount /mnt
# losetup -d /dev/loop?
# exit
This concludes the image operations, we can now move on to packaging. RPM doesn't support large files, so we split up the image into chunks. File names here are important as the SPEC file will expect them to be there
$ tar --sparse --dereference -cf - root.img | split -d -b 1G - var/lib/qubes/vm-templates/securedrop-workstation-bullseye/root.img.part.
Now we create the file build_timestamp_securedrop-workstation-bullseye
, the content of which is a datetime in a "flat" format like 202306141554
. (I'm too lazy to look up the right format args for date
)
And another file called version
with just 4.1
in it.
Now you can take templates.spec
from this gist and run:
$ rpmbuild --target noarch --define "template_name securedrop-workstation-bullseye" --define "DIST f32" -bb templates.spec