Make bcachefs subvolumes boot-time mount tests pass + more tests
This commit is contained in:

committed by
Jörg Thalheim

parent
d0c543d740
commit
7b63642358
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,3 +4,6 @@ result-*
|
|||||||
|
|
||||||
# Created by the NixOS interactive test driver
|
# Created by the NixOS interactive test driver
|
||||||
.nixos-test-history
|
.nixos-test-history
|
||||||
|
|
||||||
|
# Created by `:bl` in `nix repl`
|
||||||
|
repl-result-out
|
@@ -23,7 +23,7 @@
|
|||||||
content = {
|
content = {
|
||||||
type = "bcachefs";
|
type = "bcachefs";
|
||||||
# This refers to a filesystem in the `bcachefs_filesystems` attrset below.
|
# This refers to a filesystem in the `bcachefs_filesystems` attrset below.
|
||||||
filesystem = "unmounted_subvolumes_in_multi";
|
filesystem = "mounted_subvolumes_in_multi";
|
||||||
label = "group_a.vdb2";
|
label = "group_a.vdb2";
|
||||||
extraFormatArgs = [
|
extraFormatArgs = [
|
||||||
"--discard"
|
"--discard"
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
size = "100%";
|
size = "100%";
|
||||||
content = {
|
content = {
|
||||||
type = "bcachefs";
|
type = "bcachefs";
|
||||||
filesystem = "unmounted_subvolumes_in_multi";
|
filesystem = "mounted_subvolumes_in_multi";
|
||||||
label = "group_a.vdc1";
|
label = "group_a.vdc1";
|
||||||
extraFormatArgs = [
|
extraFormatArgs = [
|
||||||
"--discard"
|
"--discard"
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
size = "100%";
|
size = "100%";
|
||||||
content = {
|
content = {
|
||||||
type = "bcachefs";
|
type = "bcachefs";
|
||||||
filesystem = "unmounted_subvolumes_in_multi";
|
filesystem = "mounted_subvolumes_in_multi";
|
||||||
label = "group_b.vdd1";
|
label = "group_b.vdd1";
|
||||||
extraFormatArgs = [
|
extraFormatArgs = [
|
||||||
"--force"
|
"--force"
|
||||||
@@ -79,87 +79,6 @@
|
|||||||
vde = {
|
vde = {
|
||||||
device = "/dev/vde";
|
device = "/dev/vde";
|
||||||
type = "disk";
|
type = "disk";
|
||||||
content = {
|
|
||||||
type = "gpt";
|
|
||||||
partitions = {
|
|
||||||
vde1 = {
|
|
||||||
size = "100%";
|
|
||||||
content = {
|
|
||||||
type = "bcachefs";
|
|
||||||
filesystem = "mounted_subvolumes_in_multi";
|
|
||||||
label = "group_a.vde1";
|
|
||||||
extraFormatArgs = [
|
|
||||||
"--discard"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
vdf = {
|
|
||||||
device = "/dev/vdf";
|
|
||||||
type = "disk";
|
|
||||||
content = {
|
|
||||||
type = "gpt";
|
|
||||||
partitions = {
|
|
||||||
vdf1 = {
|
|
||||||
size = "100%";
|
|
||||||
content = {
|
|
||||||
type = "bcachefs";
|
|
||||||
filesystem = "mounted_subvolumes_in_multi";
|
|
||||||
label = "group_a.vdf1";
|
|
||||||
extraFormatArgs = [
|
|
||||||
"--discard"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
vdg = {
|
|
||||||
device = "/dev/vdg";
|
|
||||||
type = "disk";
|
|
||||||
content = {
|
|
||||||
type = "gpt";
|
|
||||||
partitions = {
|
|
||||||
vdd1 = {
|
|
||||||
size = "100%";
|
|
||||||
content = {
|
|
||||||
type = "bcachefs";
|
|
||||||
filesystem = "mounted_subvolumes_in_multi";
|
|
||||||
label = "group_b.vdg1";
|
|
||||||
extraFormatArgs = [
|
|
||||||
"--force"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
vdh = {
|
|
||||||
device = "/dev/vdh";
|
|
||||||
type = "disk";
|
|
||||||
content = {
|
|
||||||
type = "gpt";
|
|
||||||
partitions = {
|
|
||||||
vdd1 = {
|
|
||||||
size = "100%";
|
|
||||||
content = {
|
|
||||||
type = "bcachefs";
|
|
||||||
filesystem = "no_reliance_on_external_subvolume";
|
|
||||||
label = "group_a.vdh1";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
vdi = {
|
|
||||||
device = "/dev/vdi";
|
|
||||||
type = "disk";
|
|
||||||
content = {
|
content = {
|
||||||
type = "gpt";
|
type = "gpt";
|
||||||
partitions = {
|
partitions = {
|
||||||
@@ -168,7 +87,7 @@
|
|||||||
content = {
|
content = {
|
||||||
type = "bcachefs";
|
type = "bcachefs";
|
||||||
filesystem = "relies_on_external_subvolume";
|
filesystem = "relies_on_external_subvolume";
|
||||||
label = "group_a.vdi1";
|
label = "group_a.vde1";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -177,72 +96,52 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
bcachefs_filesystems = {
|
bcachefs_filesystems = {
|
||||||
# Example showing unmounted subvolumes in a multi-disk configuration.
|
# Example showing mounted subvolumes in a multi-disk configuration.
|
||||||
unmounted_subvolumes_in_multi = {
|
mounted_subvolumes_in_multi = {
|
||||||
type = "bcachefs_filesystem";
|
type = "bcachefs_filesystem";
|
||||||
passwordFile = "/tmp/secret.key";
|
passwordFile = "/tmp/secret.key";
|
||||||
extraFormatArgs = [
|
extraFormatArgs = [
|
||||||
"--compression=lz4"
|
"--compression=lz4"
|
||||||
"--background_compression=lz4"
|
"--background_compression=lz4"
|
||||||
];
|
];
|
||||||
|
subvolumes = {
|
||||||
|
# Subvolume name is different from mountpoint.
|
||||||
|
"subvolumes/root" = {
|
||||||
|
mountpoint = "/";
|
||||||
|
mountOptions = [
|
||||||
|
"verbose"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
# Subvolume name is the same as the mountpoint.
|
||||||
|
"subvolumes/home" = {
|
||||||
|
mountpoint = "/home";
|
||||||
|
};
|
||||||
|
# Nested subvolume doesn't need a mountpoint as its parent is mounted.
|
||||||
|
"subvolumes/home/user" = {
|
||||||
|
};
|
||||||
|
# Parent is not mounted so the mountpoint must be set.
|
||||||
|
"subvolumes/nix" = {
|
||||||
|
mountpoint = "/nix";
|
||||||
|
};
|
||||||
|
# This subvolume will be created but not mounted.
|
||||||
|
"subvolumes/test" = {
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Example showing a bcachefs filesystem without subvolumes
|
||||||
|
# and which relies on a subvolume in another filesystem being mounted.
|
||||||
|
relies_on_external_subvolume = {
|
||||||
|
type = "bcachefs_filesystem";
|
||||||
|
mountpoint = "/home/Documents";
|
||||||
|
extraFormatArgs = [
|
||||||
|
"--compression=lz4"
|
||||||
|
"--background_compression=lz4"
|
||||||
|
];
|
||||||
mountOptions = [
|
mountOptions = [
|
||||||
"verbose"
|
"verbose"
|
||||||
];
|
];
|
||||||
mountpoint = "/";
|
|
||||||
subvolumes = {
|
|
||||||
"subvolumes/rootfs" = { };
|
|
||||||
"subvolumes/home" = { };
|
|
||||||
"subvolumes/home/user" = { };
|
|
||||||
"subvolumes/nix" = { };
|
|
||||||
"subvolumes/test" = { };
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# # Example showing mounted subvolumes in a multi-disk configuration (not yet working).
|
|
||||||
# mounted_subvolumes_in_multi = {
|
|
||||||
# type = "bcachefs_filesystem";
|
|
||||||
# passwordFile = "/tmp/secret.key";
|
|
||||||
# extraFormatArgs = [
|
|
||||||
# "--compression=lz4"
|
|
||||||
# "--background_compression=lz4"
|
|
||||||
# ];
|
|
||||||
# mountOptions = [
|
|
||||||
# "verbose"
|
|
||||||
# ];
|
|
||||||
# subvolumes = {
|
|
||||||
# # Subvolume name is different from mountpoint
|
|
||||||
# "foo" = {
|
|
||||||
# mountpoint = "/bar";
|
|
||||||
# };
|
|
||||||
# # Subvolume name is the same as the mountpoint
|
|
||||||
# "home" = {
|
|
||||||
# mountpoint = "/home";
|
|
||||||
# };
|
|
||||||
# # Sub(sub)volume doesn't need a mountpoint as its parent is mounted
|
|
||||||
# "home/user" = {
|
|
||||||
# };
|
|
||||||
# # Parent is not mounted so the mountpoint must be set
|
|
||||||
# "nix" = {
|
|
||||||
# mountpoint = "/nix";
|
|
||||||
# };
|
|
||||||
# # This subvolume will be created but not mounted
|
|
||||||
# "test" = {
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
|
|
||||||
# Example showing another bcachefs filesystem.
|
|
||||||
no_reliance_on_external_subvolume = {
|
|
||||||
type = "bcachefs_filesystem";
|
|
||||||
mountpoint = "/sometestdir";
|
|
||||||
};
|
|
||||||
|
|
||||||
# # Example showing another bcachefs filesystem that relies on a subvolume
|
|
||||||
# # in another filesystem being mounted (not yet working).
|
|
||||||
# relies_on_external_subvolume = {
|
|
||||||
# type = "bcachefs_filesystem";
|
|
||||||
# mountpoint = "/home/somedir/vdf1";
|
|
||||||
# };
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -113,10 +113,7 @@
|
|||||||
mountpoint = lib.mkOption {
|
mountpoint = lib.mkOption {
|
||||||
type = lib.types.nullOr diskoLib.optionTypes.absolute-pathname;
|
type = lib.types.nullOr diskoLib.optionTypes.absolute-pathname;
|
||||||
default = null;
|
default = null;
|
||||||
description = ''
|
description = "Path to mount the subvolume to.";
|
||||||
Path to mount the subvolume to.
|
|
||||||
DO NOT USE. Currently not working.
|
|
||||||
'';
|
|
||||||
example = "/";
|
example = "/";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -126,7 +123,19 @@
|
|||||||
default = { };
|
default = { };
|
||||||
description = "List of subvolumes to define.";
|
description = "List of subvolumes to define.";
|
||||||
example = {
|
example = {
|
||||||
"subvolumes/home" = { };
|
"subvolumes/root" = {
|
||||||
|
mountpoint = "/";
|
||||||
|
extraFormatArgs = [
|
||||||
|
"--compression=lz4"
|
||||||
|
"--background_compression=lz4"
|
||||||
|
];
|
||||||
|
mountOptions = [
|
||||||
|
"verbose"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"subvolumes/home" = {
|
||||||
|
mountpoint = "/home";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
_parent = lib.mkOption {
|
_parent = lib.mkOption {
|
||||||
@@ -291,7 +300,6 @@
|
|||||||
_config = lib.mkOption {
|
_config = lib.mkOption {
|
||||||
internal = true;
|
internal = true;
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
# @todo Check that this implementation is correct:
|
|
||||||
default =
|
default =
|
||||||
(lib.optional (config.mountpoint != null) {
|
(lib.optional (config.mountpoint != null) {
|
||||||
fileSystems.${config.mountpoint} = {
|
fileSystems.${config.mountpoint} = {
|
||||||
|
@@ -7,39 +7,120 @@ diskoLib.testLib.makeDiskoTest {
|
|||||||
name = "bcachefs";
|
name = "bcachefs";
|
||||||
disko-config = ../example/bcachefs.nix;
|
disko-config = ../example/bcachefs.nix;
|
||||||
enableOCR = true;
|
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 = ''
|
extraTestScript = ''
|
||||||
machine.succeed("mountpoint /");
|
|
||||||
# @todo Verify all devices are part of the filesystem.
|
|
||||||
# @todo Check device labels and group assignments.
|
|
||||||
# Verify mount options were applied.
|
|
||||||
machine.succeed("mount | grep ' / ' | grep -q 'compression=lz4'");
|
|
||||||
machine.succeed("mount | grep ' / ' | grep -q 'background_compression=lz4'");
|
|
||||||
# @todo Verify mountpoint dependency order was respected.
|
|
||||||
# @todo Add tests for subvolumes.
|
|
||||||
# Print debug information.
|
# Print debug information.
|
||||||
|
machine.succeed("ls -la /subvolumes >&2");
|
||||||
machine.succeed("lsblk >&2");
|
machine.succeed("lsblk >&2");
|
||||||
machine.succeed("lsblk -f >&2");
|
machine.succeed("lsblk -f >&2");
|
||||||
machine.succeed("mount >&2");
|
machine.succeed("mount >&2");
|
||||||
'';
|
machine.succeed("bcachefs show-super /dev/vda2 >&2");
|
||||||
# extraSystemConfig = { pkgs, ... }: {
|
machine.succeed("bcachefs show-super /dev/vdd1 >&2");
|
||||||
# # @todo Do we need to add any attributes here?
|
machine.succeed("findmnt --json >&2");
|
||||||
# boot = {
|
|
||||||
# supportedFilesystems = [ "bcachefs" ];
|
# Verify subvolume structure.
|
||||||
# initrd = {
|
machine.succeed("test -d /subvolumes/root");
|
||||||
# supportedFilesystems = [ "bcachefs" ];
|
machine.succeed("test -d /subvolumes/home");
|
||||||
# # systemd.enable = false;
|
machine.succeed("test -d /subvolumes/home/user");
|
||||||
# };
|
machine.succeed("test -d /subvolumes/nix");
|
||||||
# };
|
machine.succeed("test -d /subvolumes/test");
|
||||||
# environment.systemPackages = [
|
machine.fail("test -d /subvolumes/non-existent");
|
||||||
# pkgs.bcachefs-tools
|
|
||||||
# pkgs.util-linux
|
# Verify existence of mountpoints.
|
||||||
# ];
|
machine.succeed("mountpoint /");
|
||||||
# };
|
machine.succeed("mountpoint /home");
|
||||||
# extraInstallerConfig = {
|
machine.succeed("mountpoint /nix");
|
||||||
# # @todo Do we need to add any attributes here?
|
machine.succeed("mountpoint /home/Documents");
|
||||||
# };
|
machine.fail("mountpoint /non-existent");
|
||||||
bootCommands = ''
|
|
||||||
machine.wait_for_text("enter passphrase for");
|
# Verify device membership and labels.
|
||||||
machine.send_chars("secretsecret\n");
|
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 'Label:' | grep -q 'vdb2'");
|
||||||
|
machine.succeed("bcachefs show-super /dev/vda2 | grep 'Label:' | grep -q 'vdc1'");
|
||||||
|
machine.succeed("bcachefs show-super /dev/vda2 | grep 'Label:' | grep -q 'vdd1'");
|
||||||
|
machine.succeed("bcachefs show-super /dev/vdd1 | grep 'Label:' | grep -q 'vde1'");
|
||||||
|
machine.fail("bcachefs show-super /dev/vda2 | grep 'Label:' | grep -q 'non-existent'");
|
||||||
|
|
||||||
|
# @todo Verify format arguments.
|
||||||
|
|
||||||
|
# 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 --json \
|
||||||
|
| jq -e ' \
|
||||||
|
.filesystems[] \
|
||||||
|
| .. \
|
||||||
|
| select(.target? == "/home/Documents") \
|
||||||
|
| .options \
|
||||||
|
| split(",") \
|
||||||
|
| contains(["verbose"]) \
|
||||||
|
'
|
||||||
|
""");
|
||||||
|
|
||||||
|
machine.fail("""
|
||||||
|
findmnt --json \
|
||||||
|
| jq -e ' \
|
||||||
|
.filesystems[] \
|
||||||
|
| select(.target == "/") \
|
||||||
|
| .options \
|
||||||
|
| split(",") \
|
||||||
|
| contains(["non-existent"]) \
|
||||||
|
'
|
||||||
|
""");
|
||||||
|
|
||||||
|
# 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 --json \
|
||||||
|
| jq -e ' \
|
||||||
|
.filesystems[] \
|
||||||
|
| .. \
|
||||||
|
| select(.target? == "/home/Documents") \
|
||||||
|
| .source \
|
||||||
|
| contains("/dev/vdd1") \
|
||||||
|
'
|
||||||
|
""");
|
||||||
|
|
||||||
|
machine.fail("""
|
||||||
|
findmnt --json \
|
||||||
|
| jq -e ' \
|
||||||
|
.filesystems[] \
|
||||||
|
| select(.target == "/") \
|
||||||
|
| .source | split(":") \
|
||||||
|
| contains(["/dev/non-existent"]) \
|
||||||
|
'
|
||||||
|
""");
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user