Skip to content

Commit 3184aa7

Browse files
committed
add canary test for btrfs on mdadm wipes
Adds a NixOS integration test to verify that the `disk-deactivate` script properly destroys BTRFS filesystems residing on mdadm RAID arrays.
1 parent 669ca49 commit 3184aa7

File tree

2 files changed

+132
-1
lines changed

2 files changed

+132
-1
lines changed

tests/default.nix

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ let
1515
;
1616
};
1717

18+
diskoModule = ../module.nix;
19+
1820
allTestFilenames = builtins.map (lib.removeSuffix ".nix") (
1921
builtins.filter (x: lib.hasSuffix ".nix" x && x != "default.nix") (
2022
lib.attrNames (builtins.readDir ./.)
@@ -30,7 +32,7 @@ let
3032
allCompatibleFilenames = lib.subtractLists incompatibleTests allTestFilenames;
3133

3234
allTests = lib.genAttrs allCompatibleFilenames (
33-
test: import (./. + "/${test}.nix") { inherit diskoLib pkgs; }
35+
test: import (./. + "/${test}.nix") { inherit diskoLib diskoModule pkgs; }
3436
);
3537
in
3638
allTests

tests/mdadm-btrfs-wipe.nix

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
{
2+
pkgs,
3+
diskoModule,
4+
...
5+
}:
6+
let
7+
inherit (pkgs) lib;
8+
9+
diskoConfig = {
10+
disko.devices.disk = {
11+
main = {
12+
device = "/dev/vdb";
13+
type = "disk";
14+
content = {
15+
type = "gpt";
16+
partitions = {
17+
ESP = {
18+
type = "EF00";
19+
size = "500M";
20+
content = {
21+
type = "filesystem";
22+
format = "vfat";
23+
mountpoint = "/boot";
24+
mountOptions = [ "umask=0077" ];
25+
};
26+
};
27+
encryptedSwap = {
28+
size = "100%";
29+
content = {
30+
type = "swap";
31+
randomEncryption = true;
32+
};
33+
};
34+
};
35+
};
36+
};
37+
}
38+
// (lib.genAttrs [ "pool1" "pool2" ] (name: {
39+
type = "disk";
40+
device =
41+
{
42+
pool1 = "/dev/vdc";
43+
pool2 = "/dev/vdd";
44+
}
45+
.${name};
46+
content = {
47+
type = "gpt";
48+
partitions.mdadm = {
49+
size = "100%";
50+
content = {
51+
type = "mdraid";
52+
name = "raid0";
53+
};
54+
};
55+
};
56+
}));
57+
58+
disko.devices.mdadm.raid0 = {
59+
type = "mdadm";
60+
level = 0;
61+
content = {
62+
type = "btrfs";
63+
extraArgs = [ "-f" ];
64+
mountpoint = "/";
65+
};
66+
};
67+
};
68+
in
69+
pkgs.testers.runNixOSTest {
70+
name = "disko-btrfs-mdadm-resurrection";
71+
72+
nodes.machine =
73+
{ config, pkgs, ... }:
74+
{
75+
imports = [
76+
diskoModule
77+
diskoConfig
78+
];
79+
80+
boot.loader.grub.devices = [ "/dev/null" ];
81+
82+
virtualisation.emptyDiskImages = [
83+
4096
84+
4096
85+
4096
86+
];
87+
boot.swraid.enable = true;
88+
environment.systemPackages = with pkgs; [
89+
mdadm
90+
btrfs-progs
91+
cryptsetup
92+
parted
93+
];
94+
};
95+
96+
testScript =
97+
{ nodes, ... }:
98+
let
99+
inherit (nodes.machine.system.build) destroyScript formatScript mountScript;
100+
in
101+
''
102+
machine.wait_for_unit("multi-user.target")
103+
104+
print("Running initial format and mount...")
105+
machine.succeed("${formatScript}")
106+
machine.succeed("${mountScript}")
107+
108+
print("Writing canary file...")
109+
machine.succeed("echo 'I survived the wipe!' > /mnt/canary.txt")
110+
machine.succeed("sync")
111+
112+
machine.succeed("umount -R /mnt")
113+
114+
print("Running the destroy script...")
115+
machine.execute("${destroyScript}")
116+
117+
print("Attempting to reformat and remount...")
118+
machine.execute("${formatScript}")
119+
machine.execute("${mountScript}")
120+
121+
print("Checking if the canary file is still there...")
122+
status, output = machine.execute("cat /mnt/canary.txt")
123+
124+
if status == 0 and "I survived the wipe!" in output:
125+
raise Exception("The canary file survived the Disko wipe process!")
126+
else:
127+
print("Test passed: Data was successfully destroyed.")
128+
'';
129+
}

0 commit comments

Comments
 (0)