Merge pull request #75 from nix-community/zap2

zap only devices we care about
This commit is contained in:
Jörg Thalheim 2022-12-25 18:25:37 +00:00 committed by GitHub
commit e3527b826d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 114 additions and 32 deletions

View file

@ -17,7 +17,7 @@ in {
create = cfg: types.diskoLib.create (eval cfg).config.devices; create = cfg: types.diskoLib.create (eval cfg).config.devices;
createScript = cfg: pkgs: pkgs.writeScript "disko-create" '' createScript = cfg: pkgs: pkgs.writeScript "disko-create" ''
#!/usr/bin/env bash #!/usr/bin/env bash
export PATH=${lib.makeBinPath (types.diskoLib.packages (eval cfg).config.devices pkgs)} export PATH=${lib.makeBinPath (types.diskoLib.packages (eval cfg).config.devices pkgs)}:$PATH
${types.diskoLib.create (eval cfg).config.devices} ${types.diskoLib.create (eval cfg).config.devices}
''; '';
createScriptNoDeps = cfg: pkgs: pkgs.writeScript "disko-create" '' createScriptNoDeps = cfg: pkgs: pkgs.writeScript "disko-create" ''
@ -27,7 +27,7 @@ in {
mount = cfg: types.diskoLib.mount (eval cfg).config.devices; mount = cfg: types.diskoLib.mount (eval cfg).config.devices;
mountScript = cfg: pkgs: pkgs.writeScript "disko-mount" '' mountScript = cfg: pkgs: pkgs.writeScript "disko-mount" ''
#!/usr/bin/env bash #!/usr/bin/env bash
export PATH=${lib.makeBinPath (types.diskoLib.packages (eval cfg).config.devices pkgs)} export PATH=${lib.makeBinPath (types.diskoLib.packages (eval cfg).config.devices pkgs)}:$PATH
${types.diskoLib.mount (eval cfg).config.devices} ${types.diskoLib.mount (eval cfg).config.devices}
''; '';
mountScriptNoDeps = cfg: pkgs: pkgs.writeScript "disko-mount" '' mountScriptNoDeps = cfg: pkgs: pkgs.writeScript "disko-mount" ''
@ -37,7 +37,7 @@ in {
zapCreateMount = cfg: types.diskoLib.zapCreateMount (eval cfg).config.devices; zapCreateMount = cfg: types.diskoLib.zapCreateMount (eval cfg).config.devices;
zapCreateMountScript = cfg: pkgs: pkgs.writeScript "disko-zap-create-mount" '' zapCreateMountScript = cfg: pkgs: pkgs.writeScript "disko-zap-create-mount" ''
#!/usr/bin/env bash #!/usr/bin/env bash
export PATH=${lib.makeBinPath (types.diskoLib.packages (eval cfg).config.devices pkgs)} export PATH=${lib.makeBinPath (types.diskoLib.packages (eval cfg).config.devices pkgs)}:$PATH
${types.diskoLib.zapCreateMount (eval cfg).config.devices} ${types.diskoLib.zapCreateMount (eval cfg).config.devices}
''; '';
zapCreateMountScriptNoDeps = cfg: pkgs: pkgs.writeScript "disko-zap-create-mount" '' zapCreateMountScriptNoDeps = cfg: pkgs: pkgs.writeScript "disko-zap-create-mount" ''

View file

@ -0,0 +1,6 @@
#!/bin/sh
set -efux
# dependencies: jq util-linux lvm2 mdadm zfs
disk=$1
lsblk --output-all --json | jq -r --arg disk_to_clear "$disk" -f "$(dirname $0)/disk-deactivate.jq"

View file

@ -0,0 +1,77 @@
# since lsblk lacks zfs support, we have to do it this way
def remove:
if .fstype == "zfs_member" then
"zpool destroy -f \(.label)"
elif .fstype == "LVM2_member" then
[
"vg=$(pvs \(.path) --noheadings --options vg_name | grep -o '[a-zA-Z0-9-]*')",
"vgchange -a n \"$vg\"",
"vgremove -f \"$vg\""
]
elif .fstype == "swap" then
"swapoff \(.path)"
elif .fstype == null then
# maybe its zfs
[
# the next line has some horrible escaping
"zpool=$(zdb -l \(.path) | sed -nr $'s/ +name: \\'(.*)\\'/\\\\1/p')",
"if [[ -n \"${zpool}\" ]]; then zpool destroy -f \"$zpool\"; fi",
"unset zpool"
]
else
[]
end
;
def deactivate:
if .type == "disk" then
[
"wipefs --all -f \(.path)"
]
elif .type == "part" then
[
"wipefs --all -f \(.path)"
]
elif .type == "crypt" then
[
"cryptsetup luksClose \(.path)",
"wipefs --all -f \(.path)"
]
elif .type == "lvm" then
(.name | split("-")[0]) as $vgname |
(.name | split("-")[1]) as $lvname |
[
"lvremove -fy \($vgname)/\($lvname)"
]
elif .type == "raid1" then
[
"mdadm --stop \(.name)"
]
else
[]
end
;
def walk:
[
(.mountpoints[] | "umount -R \(.)"),
((.children // []) | map(walk)),
remove,
deactivate
]
;
def init:
"/dev/\(.name)" as $disk |
if $disk == $disk_to_clear then
[
"set -fu",
walk
]
else
[]
end
;
.blockdevices | map(init) | flatten | join("\n")

View file

@ -39,6 +39,9 @@
type = "luks"; type = "luks";
name = "crypted1"; name = "crypted1";
keyFile = "/tmp/secret.key"; keyFile = "/tmp/secret.key";
extraArgs = [
"--iter-time 1"
];
content = { content = {
type = "lvm_pv"; type = "lvm_pv";
vg = "pool"; vg = "pool";
@ -64,6 +67,9 @@
type = "luks"; type = "luks";
name = "crypted2"; name = "crypted2";
keyFile = "/tmp/secret.key"; keyFile = "/tmp/secret.key";
extraArgs = [
"--iter-time 1"
];
content = { content = {
type = "lvm_pv"; type = "lvm_pv";
vg = "pool"; vg = "pool";

View file

@ -25,7 +25,6 @@
start = "100MiB"; start = "100MiB";
end = "-1G"; end = "-1G";
part-type = "primary"; part-type = "primary";
bootable = true;
content = { content = {
type = "filesystem"; type = "filesystem";
format = "ext4"; format = "ext4";
@ -33,12 +32,11 @@
}; };
} }
{ {
name = "root"; name = "swap";
type = "partition"; type = "partition";
start = "-1G"; start = "-1G";
end = "100%"; end = "100%";
part-type = "primary"; part-type = "primary";
bootable = true;
content = { content = {
type = "swap"; type = "swap";
randomEncryption = true; randomEncryption = true;

View file

@ -49,7 +49,6 @@
zpool = { zpool = {
zroot = { zroot = {
type = "zpool"; type = "zpool";
rootFsOptions.mountpoint = "none";
datasets = { datasets = {
"root" = { "root" = {
zfs_type = "filesystem"; zfs_type = "filesystem";
@ -58,7 +57,6 @@
"root/zfs_fs" = { "root/zfs_fs" = {
zfs_type = "filesystem"; zfs_type = "filesystem";
mountpoint = "/zfs_fs"; mountpoint = "/zfs_fs";
options.mountpoint = "/zfs_fs";
options."com.sun:auto-snapshot" = "true"; options."com.sun:auto-snapshot" = "true";
}; };
}; };

View file

@ -19,17 +19,17 @@ in {
}; };
config = { config = {
system.build.formatScript = pkgs.writers.writeDash "disko-create" '' system.build.formatScript = pkgs.writers.writeDash "disko-create" ''
export PATH=${lib.makeBinPath (types.diskoLib.packages cfg.devices pkgs)} export PATH=${lib.makeBinPath (types.diskoLib.packages cfg.devices pkgs)}:$PATH
${types.diskoLib.create cfg.devices} ${types.diskoLib.create cfg.devices}
''; '';
system.build.mountScript = pkgs.writers.writeDash "disko-mount" '' system.build.mountScript = pkgs.writers.writeDash "disko-mount" ''
export PATH=${lib.makeBinPath (types.diskoLib.packages cfg.devices pkgs)} export PATH=${lib.makeBinPath (types.diskoLib.packages cfg.devices pkgs)}:$PATH
${types.diskoLib.mount cfg.devices} ${types.diskoLib.mount cfg.devices}
''; '';
system.build.disko = pkgs.writers.writeBash "disko" '' system.build.disko = pkgs.writers.writeBash "disko" ''
export PATH=${lib.makeBinPath (types.diskoLib.packages cfg.devices pkgs)} export PATH=${lib.makeBinPath (types.diskoLib.packages cfg.devices pkgs)}:$PATH
${types.diskoLib.zapCreateMount cfg.devices} ${types.diskoLib.zapCreateMount cfg.devices}
''; '';

View file

@ -20,7 +20,7 @@ let
(lib.attrNames (builtins.readDir ./.)) (lib.attrNames (builtins.readDir ./.))
); );
allTests = lib.genAttrs (allTestFilenames) (test: import (./. + "/${test}.nix") { inherit makeDiskoTest; }) // allTests = lib.genAttrs (allTestFilenames) (test: import (./. + "/${test}.nix") { inherit makeDiskoTest pkgs; }) //
evalTest "lvm-luks-example" ../example/config.nix // { evalTest "lvm-luks-example" ../example/config.nix // {
standalone = (pkgs.nixos [ ../example/stand-alone/configuration.nix ]).config.system.build.toplevel; standalone = (pkgs.nixos [ ../example/stand-alone/configuration.nix ]).config.system.build.toplevel;
}; };

View file

@ -26,6 +26,7 @@
tsp-create = pkgs.writeScript "create" ((pkgs.callPackage ../. { }).create (import disko-config { disks = builtins.tail disks; inherit lib; })); tsp-create = pkgs.writeScript "create" ((pkgs.callPackage ../. { }).create (import disko-config { disks = builtins.tail disks; inherit lib; }));
tsp-mount = pkgs.writeScript "mount" ((pkgs.callPackage ../. { }).mount (import disko-config { disks = builtins.tail disks; inherit lib; })); tsp-mount = pkgs.writeScript "mount" ((pkgs.callPackage ../. { }).mount (import disko-config { disks = builtins.tail disks; inherit lib; }));
tsp-config = (pkgs.callPackage ../. { }).config (import disko-config { inherit disks; inherit lib; }); tsp-config = (pkgs.callPackage ../. { }).config (import disko-config { inherit disks; inherit lib; });
tsp-disko = pkgs.writeScript "disko" ((pkgs.callPackage ../. { }).zapCreateMount (import disko-config { disks = builtins.tail disks; inherit lib; }));
num-disks = builtins.length (lib.attrNames (import disko-config { inherit lib; }).disk); num-disks = builtins.length (lib.attrNames (import disko-config { inherit lib; }).disk);
installed-system = { modulesPath, ... }: { installed-system = { modulesPath, ... }: {
imports = [ imports = [
@ -60,9 +61,6 @@
efiSupport = efi; efiSupport = efi;
efiInstallAsRemovable = efi; efiInstallAsRemovable = efi;
}; };
environment.systemPackages = [
pkgs.jq
];
}; };
installedTopLevel = (eval-config { installedTopLevel = (eval-config {
modules = [ installed-system ]; modules = [ installed-system ];
@ -93,6 +91,9 @@
(modulesPath + "/profiles/minimal.nix") (modulesPath + "/profiles/minimal.nix")
extraConfig extraConfig
]; ];
environment.systemPackages = [
pkgs.jq
];
# speed-up eval # speed-up eval
documentation.enable = false; documentation.enable = false;
@ -127,20 +128,24 @@
machine.succeed("${tsp-create}") machine.succeed("${tsp-create}")
machine.succeed("${tsp-mount}") machine.succeed("${tsp-mount}")
machine.succeed("${tsp-mount}") # verify that the command is idempotent machine.succeed("${tsp-mount}") # verify that the command is idempotent
machine.succeed("${tsp-disko}") # verify that we can destroy and recreate
''} ''}
${lib.optionalString (testMode == "module") '' ${lib.optionalString (testMode == "module") ''
machine.succeed("${nodes.machine.system.build.formatScript}") machine.succeed("${nodes.machine.system.build.formatScript}")
machine.succeed("${nodes.machine.system.build.mountScript}") machine.succeed("${nodes.machine.system.build.mountScript}")
machine.succeed("${nodes.machine.system.build.mountScript}") # verify that the command is idempotent machine.succeed("${nodes.machine.system.build.mountScript}") # verify that the command is idempotent
machine.succeed("${nodes.machine.system.build.disko}") # verify that we can destroy and recreate again
''} ''}
${lib.optionalString (testMode == "cli") '' ${lib.optionalString (testMode == "cli") ''
# TODO use the disko cli here # TODO use the disko cli here
# machine.succeed("${../.}/disko --no-pkgs --mode create ${disko-config}") # machine.succeed("${../.}/disko --no-pkgs --mode create ${disko-config}")
# machine.succeed("${../.}/disko --no-pkgs --mode mount ${disko-config}") # machine.succeed("${../.}/disko --no-pkgs --mode mount ${disko-config}")
# machine.succeed("${../.}/disko --no-pkgs --mode mount ${disko-config}") # verify that the command is idempotent # machine.succeed("${../.}/disko --no-pkgs --mode mount ${disko-config}") # verify that the command is idempotent
# machine.succeed("${../.}/disko --no-pkgs --mode zap_create_mount ${disko-config}") # verify that we can destroy and recreate again
machine.succeed("${tsp-create}") machine.succeed("${tsp-create}")
machine.succeed("${tsp-mount}") machine.succeed("${tsp-mount}")
machine.succeed("${tsp-mount}") # verify that the command is idempotent machine.succeed("${tsp-mount}") # verify that the command is idempotent
machine.succeed("${tsp-disko}") # verify that we can destroy and recreate
''} ''}
${lib.optionalString testBoot '' ${lib.optionalString testBoot ''

View file

@ -16,4 +16,7 @@ makeDiskoTest {
' '
"""); """);
''; '';
extraConfig = {
environment.systemPackages = [ pkgs.jq ];
};
} }

View file

@ -154,23 +154,11 @@ rec {
*/ */
zapCreateMount = devices: '' zapCreateMount = devices: ''
set -efux set -efux
shopt -s nullglob umount -Rv /mnt || :
# print existing disks
lsblk
# TODO get zap the same way we get create for dev in ${toString (lib.catAttrs "device" (lib.attrValues devices.disk))}; do
# make partitioning idempotent by dismounting already mounted filesystems ${./disk-deactivate}/disk-deactivate "$dev" | bash -x
if findmnt /mnt; then done
umount -Rlv /mnt
fi
# stop all existing raids
if command -v mdadm; then
for r in /dev/md/* /dev/md[0-9]*; do
# might fail if the device was already closed in the loop
mdadm --stop "$r" || true
done
fi
echo 'creating partitions...' echo 'creating partitions...'
${diskoLib.create devices} ${diskoLib.create devices}
@ -912,6 +900,7 @@ rec {
type = types.functionTo types.str; type = types.functionTo types.str;
default = vg: '' default = vg: ''
lvcreate \ lvcreate \
--yes \
${if hasInfix "%" config.size then "-l" else "-L"} ${config.size} \ ${if hasInfix "%" config.size then "-l" else "-L"} ${config.size} \
-n ${config.name} \ -n ${config.name} \
${optionalString (!isNull config.lvm_type) "--type=${config.lvm_type}"} \ ${optionalString (!isNull config.lvm_type) "--type=${config.lvm_type}"} \
@ -1418,7 +1407,7 @@ rec {
internal = true; internal = true;
readOnly = true; readOnly = true;
type = types.functionTo (types.listOf types.package); type = types.functionTo (types.listOf types.package);
default = pkgs: lib.optionals (!isNull config.content) (config.content._pkgs pkgs); default = pkgs: [ pkgs.jq ] ++ lib.optionals (!isNull config.content) (config.content._pkgs pkgs);
}; };
}; };
}); });