disk-deactivate: wipe raid arrays before stopping them (#1248)

Closes #1247

## How to test
1. Go to $TMP: `cd "$(mktemp -d)"`
2. Get [the
gist](https://gist.github.com/kmein/9644e65ab8218a4b57c35cb9290b86ad):
`wget
https://gist.githubusercontent.com/kmein/9644e65ab8218a4b57c35cb9290b86ad/raw/3ec76f6a142abb1f4ea3764563a8843984b300d4/flake.nix`
3. See it fail: `nix build` (output: _Exception: The canary file
survived the Disko wipe process!_)
4. Switch the branch: `sed -i
's#github:nix-community/disko#github:kmein/disko?ref=fix/mdadm-destroy#'
flake.nix`
5. Watch it work: `nix build`
This commit is contained in:
lassulus
2026-04-19 15:46:07 +00:00
committed by GitHub
2 changed files with 131 additions and 0 deletions
+1
View File
@@ -60,6 +60,7 @@ def deactivate:
] ]
elif (.type | contains("raid")) then elif (.type | contains("raid")) then
[ [
"wipefs --all -f \(.path | shellquote)",
"mdadm --stop \(.name | shellquote)" "mdadm --stop \(.name | shellquote)"
] ]
else else
+130
View File
@@ -0,0 +1,130 @@
{
pkgs,
...
}:
let
inherit (pkgs) lib;
diskoModule = ../module.nix;
diskoConfig = {
disko.devices.disk = {
main = {
device = "/dev/vdb";
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = {
type = "EF00";
size = "500M";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
encryptedSwap = {
size = "100%";
content = {
type = "swap";
randomEncryption = true;
};
};
};
};
};
}
// (lib.genAttrs [ "pool1" "pool2" ] (name: {
type = "disk";
device =
{
pool1 = "/dev/vdc";
pool2 = "/dev/vdd";
}
.${name};
content = {
type = "gpt";
partitions.mdadm = {
size = "100%";
content = {
type = "mdraid";
name = "raid0";
};
};
};
}));
disko.devices.mdadm.raid0 = {
type = "mdadm";
level = 0;
content = {
type = "btrfs";
extraArgs = [ "-f" ];
mountpoint = "/";
};
};
};
in
pkgs.testers.runNixOSTest {
name = "disko-btrfs-mdadm-resurrection";
nodes.machine =
{ config, pkgs, ... }:
{
imports = [
diskoModule
diskoConfig
];
boot.loader.grub.devices = [ "/dev/null" ];
virtualisation.emptyDiskImages = [
4096
4096
4096
];
boot.swraid.enable = true;
environment.systemPackages = with pkgs; [
mdadm
btrfs-progs
cryptsetup
parted
];
};
testScript =
{ nodes, ... }:
let
inherit (nodes.machine.system.build) destroyScript formatScript mountScript;
in
''
machine.wait_for_unit("multi-user.target")
print("Running initial format and mount...")
machine.succeed("${formatScript}")
machine.succeed("${mountScript}")
print("Writing canary file...")
machine.succeed("echo 'I survived the wipe!' > /mnt/canary.txt")
machine.succeed("sync")
machine.succeed("umount -R /mnt")
print("Running the destroy script...")
machine.execute("${destroyScript}")
print("Attempting to reformat and remount...")
machine.execute("${formatScript}")
machine.execute("${mountScript}")
print("Checking if the canary file is still there...")
status, output = machine.execute("cat /mnt/canary.txt")
if status == 0 and "I survived the wipe!" in output:
raise Exception("The canary file survived the Disko wipe process!")
else:
print("Test passed: Data was successfully destroyed.")
'';
}