Skip to content

Commit

Permalink
Merge pull request #921 from nix-community/zfs-fix
Browse files Browse the repository at this point in the history
zfs: run load-key on mount/unmount
  • Loading branch information
Mic92 authored Dec 20, 2024
2 parents 600d2e1 + d8f3cfc commit 2ee76c8
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 26 deletions.
2 changes: 1 addition & 1 deletion cli.nix
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ let
diskoScript =
if hasDiskoConfigFlake then
diskoEval
else if (lib.traceValSeq hasDiskoModuleFlake) then
else if hasDiskoModuleFlake then
(builtins.getFlake flake).nixosConfigurations.${flakeAttr}.config.system.build.${diskoAttr} or (
pkgs.writeShellScriptBin "disko-compat-error" ''
echo 'Error: Attribute `nixosConfigurations.${flakeAttr}.config.system.build.${diskoAttr}` >&2
Expand Down
16 changes: 15 additions & 1 deletion example/zfs.nix
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
options.mountpoint = "legacy";
mountpoint = "/zfs_legacy_fs";
};
zfs_testvolume = {
zfs_volume = {
type = "zfs_volume";
size = "10M";
content = {
Expand All @@ -81,6 +81,20 @@
mountpoint = "/ext4onzfs";
};
};
zfs_encryptedvolume = {
type = "zfs_volume";
size = "10M";
options = {
encryption = "aes-256-gcm";
keyformat = "passphrase";
keylocation = "file:///tmp/secret.key";
};
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/ext4onzfsencrypted";
};
};
encrypted = {
type = "zfs_fs";
options = {
Expand Down
12 changes: 10 additions & 2 deletions lib/types/zfs_fs.nix
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,13 @@
_mount = diskoLib.mkMountOption {
inherit config options;
default =
lib.optionalAttrs (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off") {
(lib.optionalAttrs (config.options.keylocation or "none" != "none") {
dev = ''
if [ "$(zfs get keystatus ${config._name} -H -o value)" == "unavailable" ]; then
zfs load-key ${config._name}
fi
'';
}) // lib.optionalAttrs (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off") {
fs.${config.mountpoint} = ''
if ! findmnt ${config._name} "${rootMountPoint}${config.mountpoint}" >/dev/null 2>&1; then
mount ${config._name} "${rootMountPoint}${config.mountpoint}" \
Expand All @@ -117,7 +123,9 @@
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default =
lib.optionalAttrs (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off") {
(lib.optionalAttrs (config.options.keylocation or "none" != "none") {
dev = "zfs unload-key ${config.name}";
}) // lib.optionalAttrs (config.options.mountpoint or "" != "none" && config.options.canmount or "" != "off") {
fs.${config.mountpoint} = ''
if findmnt ${config._name} "${rootMountPoint}${config.mountpoint}" >/dev/null 2>&1; then
umount "${rootMountPoint}${config.mountpoint}"
Expand Down
25 changes: 21 additions & 4 deletions lib/types/zfs_volume.nix
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,30 @@
};
_mount = diskoLib.mkMountOption {
inherit config options;
default =
lib.optionalAttrs (config.content != null) config.content._mount;
default = {
dev = ''
${lib.optionalString (config.options.keylocation or "none" != "none") ''
if [ "$(zfs get keystatus ${config.name} -H -o value)" == "unavailable" ]; then
zfs load-key ${config.name}
fi
''}
${config.content._mount.dev or ""}
'';
fs = config.content._mount.fs or { };
};
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default =
lib.optionalAttrs (config.content != null) config.content._unmount;
default = {
dev = ''
${lib.optionalString (config.options.keylocation or "none" != "none") "zfs unload-key ${config.name}"}
${config.content._unmount.dev or ""}
'';

fs = config.content._unmount.fs;
};
};
_config = lib.mkOption {
internal = true;
Expand Down
29 changes: 13 additions & 16 deletions lib/types/zpool.nix
Original file line number Diff line number Diff line change
Expand Up @@ -299,33 +299,30 @@ in
inherit config options;
default =
let
datasetMounts = diskoLib.deepMergeMap (dataset: dataset._mount) (lib.attrValues config.datasets);
datasetFilesystemsMounts = diskoLib.deepMergeMap (dataset: dataset._mount.fs or {}) (lib.attrValues config.datasets);
in
{
dev = ''
zpool list "${config.name}" >/dev/null 2>/dev/null ||
zpool import -l -R ${rootMountPoint} "${config.name}"
${lib.concatMapStrings (x: x.dev or "") (lib.attrValues datasetMounts)}
${lib.concatMapStrings (x: x._mount.dev or "") (lib.attrValues config.datasets)}
'';
fs = datasetMounts.fs or { };
fs = datasetFilesystemsMounts;
};
};
_unmount = diskoLib.mkUnmountOption {
inherit config options;
default =
let
datasetUnmounts = diskoLib.deepMergeMap (dataset: dataset._unmount) (lib.attrValues config.datasets);
in
{
dev = ''
${lib.concatMapStrings (x: x.dev or "") (lib.attrValues datasetUnmounts)}
default = {
dev = ''
${lib.concatMapStrings (dataset: dataset._unmount.dev or "") (lib.attrValues config.datasets)}
if zpool list "${config.name}" >/dev/null 2>/dev/null; then
zpool export "${config.name}"
fi
'';
fs = datasetUnmounts.fs or { };
};
if zpool list "${config.name}" >/dev/null 2>/dev/null; then
zpool export "${config.name}"
fi
'';
fs = diskoLib.deepMergeMap (dataset: dataset._unmount.fs or {}) (lib.attrValues config.datasets);
};
};
_config = lib.mkOption {
internal = true;
Expand Down
7 changes: 5 additions & 2 deletions tests/zfs.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ diskoLib.testLib.makeDiskoTest {
fileSystems."/zfs_legacy_fs".options = [ "nofail" ]; # TODO find out why we need this!
};
extraTestScript = ''
machine.succeed("test -b /dev/zvol/zroot/zfs_testvolume");
machine.succeed("test -b /dev/zvol/zroot/zfs_volume");
machine.succeed("test -b /dev/zvol/zroot/zfs_encryptedvolume");
def assert_property(ds, property, expected_value):
out = machine.succeed(f"zfs get -H {property} {ds} -o value").rstrip()
Expand All @@ -23,14 +24,16 @@ diskoLib.testLib.makeDiskoTest {
assert_property("zroot/zfs_fs", "compression", "zstd")
assert_property("zroot", "com.sun:auto-snapshot", "false")
assert_property("zroot/zfs_fs", "com.sun:auto-snapshot", "true")
assert_property("zroot/zfs_testvolume", "volsize", "10M")
assert_property("zroot/zfs_volume", "volsize", "10M")
assert_property("zroot/zfs_encryptedvolume", "volsize", "10M")
assert_property("zroot/zfs_unmounted_fs", "mountpoint", "none")
machine.succeed("zfs get name zroot@blank")
machine.succeed("mountpoint /zfs_fs");
machine.succeed("mountpoint /zfs_legacy_fs");
machine.succeed("mountpoint /ext4onzfs");
machine.succeed("mountpoint /ext4onzfsencrypted");
machine.succeed("mountpoint /zfs_crypted");
machine.succeed("zfs get keystatus zroot/encrypted");
machine.succeed("zfs get keystatus zroot/encrypted/test");
Expand Down

0 comments on commit 2ee76c8

Please sign in to comment.