diff --git a/flake.lock b/flake.lock index 3da7b960..6e297252 100644 --- a/flake.lock +++ b/flake.lock @@ -2,17 +2,17 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1748856973, - "narHash": "sha256-RlTsJUvvr8ErjPBsiwrGbbHYW8XbB/oek0Gi78XdWKg=", - "owner": "NixOS", + "lastModified": 1749157517, + "narHash": "sha256-IKIcS2laxS7xxgz/AYbd+LfHHwBQZVSFLGTrDxnUDxQ=", + "owner": "chetgurevitch", "repo": "nixpkgs", - "rev": "e4b09e47ace7d87de083786b404bf232eb6c89d8", + "rev": "6f3ced85c7355e9711a5457d825d5f3e80a1bdf4", "type": "github" }, "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", + "owner": "chetgurevitch", "repo": "nixpkgs", + "rev": "6f3ced85c7355e9711a5457d825d5f3e80a1bdf4", "type": "github" } }, diff --git a/flake.nix b/flake.nix index cc2ee860..00e549df 100644 --- a/flake.nix +++ b/flake.nix @@ -4,7 +4,9 @@ # FIXME: in future we don't want lock here to give precedence to a USB live-installer's registry, # but garnix currently does not allow this. #inputs.nixpkgs.url = "nixpkgs"; - inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + # @todo This needs to be reverted once https://github.com/NixOS/nixpkgs/pull/414391 is merged. + inputs.nixpkgs.url = "github:chetgurevitch/nixpkgs/6f3ced85c7355e9711a5457d825d5f3e80a1bdf4"; + # inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; outputs = { self, nixpkgs, ... }: diff --git a/lib/types/bcachefs_filesystem.nix b/lib/types/bcachefs_filesystem.nix index 970717b5..8a453672 100644 --- a/lib/types/bcachefs_filesystem.nix +++ b/lib/types/bcachefs_filesystem.nix @@ -194,9 +194,10 @@ ${lib.optionalString ( config.passwordFile != null ) ''bcachefs unlock -k session "/dev/disk/by-uuid/${config.uuid}" < "${config.passwordFile}";''} - bcachefs mount \ + mount \ + -t bcachefs \ -o "${lib.concatStringsSep "," (lib.unique ([ "X-mount.mkdir" ] ++ config.mountOptions))}" \ - UUID="${config.uuid}" \ + "/dev/disk/by-uuid/${config.uuid}" \ "$MNTPOINT"; trap 'umount "$MNTPOINT"; rm -rf "$MNTPOINT"; rm -rf "$TEMPDIR";' EXIT; SUBVOL_ABS_PATH="$MNTPOINT/${subvolume.name}"; @@ -230,7 +231,8 @@ ${lib.optionalString ( config.passwordFile != null ) ''bcachefs unlock -k session "/dev/disk/by-uuid/${config.uuid}" < "${config.passwordFile}";''} - bcachefs mount \ + mount \ + -t bcachefs \ -o "${ lib.concatStringsSep "," ( lib.unique ( @@ -242,7 +244,7 @@ ) ) }" \ - UUID="${config.uuid}" \ + "/dev/disk/by-uuid/${config.uuid}" \ "${rootMountPoint}${subvolume.mountpoint}"; fi; ''; @@ -261,9 +263,10 @@ ${lib.optionalString ( config.passwordFile != null ) ''bcachefs unlock -k session "/dev/disk/by-uuid/${config.uuid}" < "${config.passwordFile}";''} - bcachefs mount \ + mount \ + -t bcachefs \ -o "${lib.concatStringsSep "," (lib.unique ([ "X-mount.mkdir" ] ++ config.mountOptions))}" \ - UUID="${config.uuid}" \ + "/dev/disk/by-uuid/${config.uuid}" \ "${rootMountPoint}${config.mountpoint}"; fi; ''; diff --git a/tests/bcachefs.nix b/tests/bcachefs.nix index dbe0e7e1..74e09d6d 100644 --- a/tests/bcachefs.nix +++ b/tests/bcachefs.nix @@ -2,125 +2,140 @@ pkgs ? import { }, diskoLib ? pkgs.callPackage ../lib { }, }: -diskoLib.testLib.makeDiskoTest { - inherit pkgs; - name = "bcachefs"; - disko-config = ../example/bcachefs.nix; - enableOCR = true; - bootCommands = '' - machine.wait_for_text("enter passphrase for /"); - machine.send_chars("secretsecret\n"); - machine.wait_for_text("enter passphrase for /home"); - machine.send_chars("secretsecret\n"); - machine.wait_for_text("enter passphrase for /nix"); - machine.send_chars("secretsecret\n"); - ''; - extraSystemConfig = { - environment.systemPackages = [ - pkgs.jq - ]; - }; - extraTestScript = '' - # Print debug information. - machine.succeed("ls -la /subvolumes >&2"); - machine.succeed("lsblk >&2"); - machine.succeed("lsblk -f >&2"); - machine.succeed("mount >&2"); - machine.succeed("bcachefs show-super /dev/vda2 >&2"); - machine.succeed("bcachefs show-super /dev/vdd1 >&2"); - machine.succeed("findmnt --json >&2"); +let + diskoTest = diskoLib.testLib.makeDiskoTest { + inherit pkgs; + name = "bcachefs"; + disko-config = ../example/bcachefs.nix; + enableOCR = true; + bootCommands = '' + machine.wait_for_text("enter passphrase for /"); + machine.send_chars("secretsecret\n"); + machine.wait_for_text("enter passphrase for /home"); + machine.send_chars("secretsecret\n"); + machine.wait_for_text("enter passphrase for /nix"); + machine.send_chars("secretsecret\n"); + ''; + extraInstallerConfig = { + boot = { + kernelPackages = pkgs.linuxPackages_testing; + }; + environment.systemPackages = [ + pkgs.bcachefs-tools + ]; + }; + extraSystemConfig = { + environment.systemPackages = [ + pkgs.jq + ]; + }; + extraTestScript = '' + # Print debug information. + machine.succeed("uname -a >&2"); + machine.succeed("ls -la / >&2"); + machine.succeed("lsblk >&2"); + machine.succeed("lsblk -f >&2"); + machine.succeed("mount >&2"); + machine.succeed("bcachefs show-super /dev/vda2 >&2"); + machine.succeed("bcachefs show-super /dev/vdd1 >&2"); + machine.succeed("findmnt -J >&2"); - # Verify subvolume structure. - machine.succeed("test -d /subvolumes/root"); - machine.succeed("test -d /subvolumes/home"); - machine.succeed("test -d /subvolumes/home/user"); - machine.succeed("test -d /subvolumes/nix"); - machine.succeed("test -d /subvolumes/test"); - machine.fail("test -d /subvolumes/non-existent"); + # Verify existence of mountpoints. + machine.succeed("mountpoint /"); + machine.succeed("mountpoint /home"); + machine.succeed("mountpoint /nix"); + machine.succeed("mountpoint /home/Documents"); + machine.fail("mountpoint /non-existent"); - # Verify existence of mountpoints. - machine.succeed("mountpoint /"); - machine.succeed("mountpoint /home"); - machine.succeed("mountpoint /nix"); - machine.succeed("mountpoint /home/Documents"); - machine.fail("mountpoint /non-existent"); + # Verify device membership and labels. + machine.succeed("bcachefs show-super /dev/vda2 | grep 'Devices:' | grep -q '3'"); + machine.succeed("bcachefs show-super /dev/vdd1 | grep 'Devices:' | grep -q '1'"); + machine.succeed("bcachefs show-super /dev/vda2 | grep -qE '^[[:space:]]+Label:[[:space:]]+vdb2[[:space:]]\([[:digit:]]+\)'"); + machine.succeed("bcachefs show-super /dev/vda2 | grep -qE '^[[:space:]]+Label:[[:space:]]+vdc1[[:space:]]\([[:digit:]]+\)'"); + machine.succeed("bcachefs show-super /dev/vda2 | grep -qE '^[[:space:]]+Label:[[:space:]]+vdd1[[:space:]]\([[:digit:]]+\)'"); + machine.succeed("bcachefs show-super /dev/vdd1 | grep -qE '^[[:space:]]+Label:[[:space:]]+vde1[[:space:]]\([[:digit:]]+\)'"); + machine.fail("bcachefs show-super /dev/vda2 | grep 'Label:' | grep -q 'non-existent'"); - # Verify device membership and labels. - machine.succeed("bcachefs show-super /dev/vda2 | grep 'Devices:' | grep -q '3'"); - machine.succeed("bcachefs show-super /dev/vdd1 | grep 'Devices:' | grep -q '1'"); - machine.succeed("bcachefs show-super /dev/vda2 | grep -qE '^[[:space:]]+Label:[[:space:]]+vdb2[[:space:]]\([[:digit:]]+\)'"); - machine.succeed("bcachefs show-super /dev/vda2 | grep -qE '^[[:space:]]+Label:[[:space:]]+vdc1[[:space:]]\([[:digit:]]+\)'"); - machine.succeed("bcachefs show-super /dev/vda2 | grep -qE '^[[:space:]]+Label:[[:space:]]+vdd1[[:space:]]\([[:digit:]]+\)'"); - machine.succeed("bcachefs show-super /dev/vdd1 | grep -qE '^[[:space:]]+Label:[[:space:]]+vde1[[:space:]]\([[:digit:]]+\)'"); - machine.fail("bcachefs show-super /dev/vda2 | grep 'Label:' | grep -q 'non-existent'"); + # @todo Verify format arguments. - # @todo Verify format arguments. + # Verify mount options from configuration. + machine.succeed(""" + findmnt -J \ + | jq -e ' \ + .filesystems[] \ + | select(.target == "/") \ + | .options \ + | split(",") \ + | contains(["verbose", "compression=lz4", "background_compression=lz4"]) \ + ' + """); - # Verify mount options from configuration. - machine.succeed(""" - findmnt --json \ - | jq -e ' \ - .filesystems[] \ - | select(.target == "/") \ - | .options \ - | split(",") \ - | contains(["verbose", "compression=lz4", "background_compression=lz4"]) \ - ' - """); + machine.succeed(""" + findmnt -J \ + | jq -e ' \ + .filesystems[] \ + | .. \ + | select(.target? == "/home/Documents") \ + | .options \ + | split(",") \ + | contains(["verbose"]) \ + ' + """); - machine.succeed(""" - findmnt --json \ - | jq -e ' \ - .filesystems[] \ - | .. \ - | select(.target? == "/home/Documents") \ - | .options \ - | split(",") \ - | contains(["verbose"]) \ - ' - """); + machine.fail(""" + findmnt -J \ + | jq -e ' \ + .filesystems[] \ + | select(.target == "/") \ + | .options \ + | split(",") \ + | contains(["non-existent"]) \ + ' + """); - machine.fail(""" - findmnt --json \ - | jq -e ' \ - .filesystems[] \ - | select(.target == "/") \ - | .options \ - | split(",") \ - | contains(["non-existent"]) \ - ' - """); + # Verify device composition of filesystems. + machine.succeed(""" + findmnt -J \ + | jq -e ' \ + .filesystems[] \ + | select(.target == "/") \ + | .source \ + | contains("/dev/vda2") \ + and contains("/dev/vdb1") \ + and contains("/dev/vdc1") \ + and contains("[/subvolumes/root]") \ + ' + """); - # Verify device composition of filesystems. - machine.succeed(""" - findmnt --json \ - | jq -e ' \ - .filesystems[] \ - | select(.target == "/") \ - | .source | split(":") \ - | contains(["/dev/vda2", "/dev/vdb1", "/dev/vdc1"]) \ - ' - """); + machine.succeed(""" + findmnt -J \ + | jq -e ' \ + .filesystems[] \ + | .. \ + | select(.target? == "/home/Documents") \ + | .source \ + | contains("/dev/vdd1") \ + ' + """); - machine.succeed(""" - findmnt --json \ - | jq -e ' \ - .filesystems[] \ - | .. \ - | select(.target? == "/home/Documents") \ - | .source \ - | contains("/dev/disk/by-uuid/64e50034-ebe2-eaf8-1f93-cf56266a8d86") \ - ' - """); - - machine.fail(""" - findmnt --json \ - | jq -e ' \ - .filesystems[] \ - | select(.target == "/") \ - | .source | split(":") \ - | contains(["/dev/non-existent"]) \ - ' - """); + machine.fail(""" + findmnt -J \ + | jq -e ' \ + .filesystems[] \ + | select(.target == "/") \ + | .source \ + | contains(["/dev/non-existent"]) \ + ' + """); + ''; + }; +in +pkgs.lib.attrsets.recursiveUpdate diskoTest { + nodes.machine.boot.initrd.extraUtilsCommands = '' + ${diskoTest.nodes.machine.boot.initrd.extraUtilsCommands} + # Copy tools for bcachefs + copy_bin_and_libs ${pkgs.lib.getOutput "mount" pkgs.util-linux}/bin/mount + copy_bin_and_libs ${pkgs.bcachefs-tools}/bin/bcachefs + copy_bin_and_libs ${pkgs.bcachefs-tools}/bin/mount.bcachefs ''; }