From fc4ea9ecbad9fe9ddc1fb8d74ff4c0258221c147 Mon Sep 17 00:00:00 2001 From: Henri Menke Date: Sat, 18 Jul 2020 19:16:41 +1200 Subject: [PATCH] ZFS: Request credentials only for selected pools This change introduces more fine-grained requestEncryptionCredentials. While previously when requestEncryptionCredentials = true, the credentials for all imported pools and all datasets in these imported pools were requested, it is now possible to select exactly the pools and datasets for which credentials should be requested. It is still possible to set requestEncryptionCredentials = true, which continues to act as a wildcard for all pools and datasets, so the change is backwards compatible. --- nixos/modules/tasks/filesystems/zfs.nix | 32 +++++++++++++++++-------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix index c9d9c6c1657d..9ca7c6fb3431 100644 --- a/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixos/modules/tasks/filesystems/zfs.nix @@ -191,13 +191,14 @@ in }; requestEncryptionCredentials = mkOption { - type = types.bool; + type = types.either types.bool (types.listOf types.str); default = true; + example = [ "tank" "data" ]; description = '' - Request encryption keys or passwords for all encrypted datasets on import. - For root pools the encryption key can be supplied via both an - interactive prompt (keylocation=prompt) and from a file - (keylocation=file://). + If true on import encryption keys or passwords for all encrypted datasets + are requested. To only decrypt selected datasets supply a list of dataset + names instead. For root pools the encryption key can be supplied via both + an interactive prompt (keylocation=prompt) and from a file (keylocation=file://). ''; }; @@ -419,9 +420,13 @@ in fi poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool. fi - ${lib.optionalString cfgZfs.requestEncryptionCredentials '' - zfs load-key -a - ''} + ${if isBool cfgZfs.requestEncryptionCredentials + then optionalString cfgZfs.requestEncryptionCredentials '' + zfs load-key -a + '' + else concatMapStrings (fs: '' + zfs load-key ${fs} + '') cfgZfs.requestEncryptionCredentials} '') rootPools)); }; @@ -517,9 +522,16 @@ in done poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool. if poolImported "${pool}"; then - ${optionalString cfgZfs.requestEncryptionCredentials '' + ${optionalString (if isBool cfgZfs.requestEncryptionCredentials + then cfgZfs.requestEncryptionCredentials + else cfgZfs.requestEncryptionCredentials != []) '' ${packages.zfsUser}/sbin/zfs list -rHo name,keylocation ${pool} | while IFS=$'\t' read ds kl; do - (case "$kl" in + (${optionalString (!isBool cfgZfs.requestEncryptionCredentials) '' + if ! echo '${concatStringsSep "\n" cfgZfs.requestEncryptionCredentials}' | grep -qFx "$ds"; then + continue + fi + ''} + case "$kl" in none ) ;; prompt )