| 19 May 2024 |
matthewcroughan | Yeah, that's the way | 13:38:26 |
matthewcroughan | literalExpression "''${foo}" is the way | 13:38:40 |
lassulus | in " ${ is escaped with \ | 13:40:00 |
lassulus | but in '' this would be correct | 13:40:24 |
matthewcroughan | Huzzah! I have had disko produce a raspberry pi 4 bootable image for me :) | 14:13:27 |
matthewcroughan | with bcachefs as the FS | 14:13:41 |
matthewcroughan | that took foreeeeever | 14:13:46 |
matthewcroughan | [matthew@corpo:~]$ df -T
Filesystem Type 1K-blocks Used Available Use% Mounted on
devtmpfs devtmpfs 398268 0 398268 0% /dev
tmpfs tmpfs 3982668 0 3982668 0% /dev/shm
tmpfs tmpfs 1991336 8212 1983124 1% /run
tmpfs tmpfs 3982668 2220 3980448 1% /run/wrappers
/dev/disk/by-partlabel/disk-disk1-root bcachefs 9438577 4322971 5036905 47% /
/dev/mmcblk1p2 vfat 30634 23028 7606 76% /firmware
/dev/mmcblk1p1 ext4 90333 78055 5110 94% /boot
tmpfs tmpfs 796532 4 796528 1% /run/user/1000
| 14:14:10 |
lassulus | forever in writing the code or forever in running it? | 14:14:23 |
matthewcroughan | writing code | 14:14:28 |
matthewcroughan | Because the Pi is so weird | 14:14:37 |
matthewcroughan | pi3 would require even more changes to do this, because it doesn't support gpt only | 14:14:48 |
matthewcroughan | And that's where we were last time I came in here asking about Pi booting | 14:15:00 |
matthewcroughan | {
disko.extraPostVM = ''
${pkgs.zstd}/bin/zstd --compress $out/*raw
rm $out/*raw
'';
disko.devices = {
disk = {
disk1 = {
imageSize = "10G";
type = "disk";
device = "/dev/mmcblk0";
postCreateHook = ''
lsblk
sgdisk -A 1:set:2 /dev/vda
'';
content = {
type = "gpt";
partitions = {
firmware = {
size = "30M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/firmware";
postMountHook = toString (pkgs.writeScript "postMountHook.sh" ''
(cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf *.dtb /mnt/firmware/)
cp ${pkgs.ubootRaspberryPi4_64bit}/u-boot.bin /mnt/firmware/u-boot-rpi4.bin
cp ${configTxt} /mnt/firmware/config.txt
'');
};
};
boot = {
size = "100M";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/boot";
};
};
root = {
name = "root";
size = "100%";
content = {
type = "filesystem";
format = "bcachefs";
mountpoint = "/";
};
};
};
};
};
};
};
}
| 14:15:54 |
matthewcroughan | something like this does everything | 14:15:59 |
matthewcroughan | now the only remaining problem is resize on first boot | 14:16:18 |
matthewcroughan | This is what the sd-image module in nixpkgs does:
boot.postBootCommands = lib.mkIf config.sdImage.expandOnBoot ''
# On the first boot do some maintenance tasks
if [ -f /nix-path-registration ]; then
set -euo pipefail
set -x
# Figure out device names for the boot device and root filesystem.
rootPart=$(${pkgs.util-linux}/bin/findmnt -n -o SOURCE /)
bootDevice=$(lsblk -npo PKNAME $rootPart)
partNum=$(lsblk -npo MAJ:MIN $rootPart | ${pkgs.gawk}/bin/awk -F: '{print $2}')
# Resize the root partition and the filesystem to fit the disk
echo ",+," | sfdisk -N$partNum --no-reread $bootDevice
${pkgs.parted}/bin/partprobe
${pkgs.e2fsprogs}/bin/resize2fs $rootPart
# Register the contents of the initial Nix store
${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration
# nixos-rebuild also requires a "system" profile and an /etc/NIXOS tag.
touch /etc/NIXOS
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
# Prevents this from running on later boots.
rm -f /nix-path-registration
fi
'';
};
| 14:19:21 |
matthewcroughan | I suppose I'll just copy this into my disko.nix | 14:19:30 |
matthewcroughan | Ah and instead of e2fsprogs I need ${bcachefs-tools}/bin/bcachefs resize $rootpart | 14:45:07 |
matthewcroughan | * Ah and instead of e2fsprogs I need ${bcachefs-tools}/bin/bcachefs resize $rootPart | 14:45:09 |
matthewcroughan | It feels like disko should help with resizing on first boot, but curious what you think lassulus | 14:45:35 |
matthewcroughan | feels like disko already knows a lot of the info that would help here | 14:46:00 |
lassulus | hmm, resizing is not really delcarative? :D and not sure what the interface would look like | 14:46:11 |
matthewcroughan | systemd-repart has a really nice setup | 14:46:41 |
matthewcroughan |
systemd-repart (mostly) operates in a purely incremental mode: it only grows existing and adds new partitions; it does not shrink, delete or move existing partitions. The service is intended to be run on every boot, but when it detects that the partition table already matches the installed repart.
| 14:46:46 |
matthewcroughan | Which more or less sound exactly like disko's philosophy, and some of the goals you have for your own incremental mode | 14:47:09 |
matthewcroughan | This ended up being the final disko.nix for a pi to boot using bcachefs | 17:54:42 |
matthewcroughan | {
boot.postBootCommands = ''
# On the first boot, resize the disk
if [ -f /disko-first-boot ]; then
set -euo pipefail
set -x
# Figure out device names for the boot device and root filesystem.
rootPart=$(${pkgs.util-linux}/bin/findmnt -n -o SOURCE /)
bootDevice=$(lsblk -npo PKNAME $rootPart)
partNum=$(lsblk -npo MAJ:MIN $rootPart | ${pkgs.gawk}/bin/awk -F: '{print $2}')
# Resize the root partition and the filesystem to fit the disk
echo ",+," | sfdisk -N$partNum --no-reread $bootDevice
${pkgs.parted}/bin/partprobe
${pkgs.bcachefs-tools}/bin/bcachefs device resize $rootPart
# Prevents this from running on later boots.
rm -f /disko-first-boot
fi
'';
disko = {
extraPostVM = ''
${pkgs.zstd}/bin/zstd --compress $out/*raw
rm $out/*raw
'';
devices = {
disk = {
disk1 = {
imageSize = "10G";
type = "disk";
device = "/dev/mmcblk0";
postCreateHook = ''
lsblk
sgdisk -A 1:set:2 /dev/vda
'';
content = {
type = "gpt";
partitions = {
firmware = {
size = "30M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/firmware";
postMountHook = toString (pkgs.writeScript "postMountHook.sh" ''
(cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf *.dtb /mnt/firmware/)
cp ${pkgs.ubootRaspberryPi4_64bit}/u-boot.bin /mnt/firmware/u-boot-rpi4.bin
cp ${configTxt} /mnt/firmware/config.txt
'');
};
};
boot = {
size = "100M";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/boot";
};
};
root = {
name = "root";
size = "100%";
content = {
type = "filesystem";
format = "bcachefs";
mountpoint = "/";
postMountHook = toString (pkgs.writeScript "postMountHook.sh" ''
touch /mnt/disko-first-boot
'');
};
};
};
};
};
};
};
};
}
| 17:54:46 |
matthewcroughan | hmm.. disko won't quite work for riscv due to its architecture, will it? | 18:37:30 |
matthewcroughan | This same problem would be solved by running the vmTools on the hostPlatform, and allowing it to do binfmt, instead of treating the VM performing the disk partitioning/formatting as something that needs to run on the native platform | 18:38:17 |