mirror of
https://github.com/ilyakooo0/nixpkgs.git
synced 2024-11-11 04:02:55 +03:00
Merge pull request #203171 from ElvishJerricco/zfs-fix-requested-credentials
nixos/zfs: Ensure pool has datasets to decrypt
This commit is contained in:
commit
3d7270abd5
@ -97,10 +97,15 @@ let
|
||||
in
|
||||
map (x: "${mountPoint x}.mount") (getPoolFilesystems pool);
|
||||
|
||||
getKeyLocations = pool:
|
||||
if isBool cfgZfs.requestEncryptionCredentials
|
||||
then "${cfgZfs.package}/sbin/zfs list -rHo name,keylocation,keystatus ${pool}"
|
||||
else "${cfgZfs.package}/sbin/zfs list -Ho name,keylocation,keystatus ${toString (filter (x: datasetToPool x == pool) cfgZfs.requestEncryptionCredentials)}";
|
||||
getKeyLocations = pool: if isBool cfgZfs.requestEncryptionCredentials then {
|
||||
hasKeys = cfgZfs.requestEncryptionCredentials;
|
||||
command = "${cfgZfs.package}/sbin/zfs list -rHo name,keylocation,keystatus ${pool}";
|
||||
} else let
|
||||
keys = filter (x: datasetToPool x == pool) cfgZfs.requestEncryptionCredentials;
|
||||
in {
|
||||
hasKeys = keys != [];
|
||||
command = "${cfgZfs.package}/sbin/zfs list -Ho name,keylocation,keystatus ${toString keys}";
|
||||
};
|
||||
|
||||
createImportService = { pool, systemd, force, prefix ? "" }:
|
||||
nameValuePair "zfs-import-${pool}" {
|
||||
@ -124,7 +129,9 @@ let
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
environment.ZFS_FORCE = optionalString force "-f";
|
||||
script = (importLib {
|
||||
script = let
|
||||
keyLocations = getKeyLocations pool;
|
||||
in (importLib {
|
||||
# See comments at importLib definition.
|
||||
zpoolCmd = "${cfgZfs.package}/sbin/zpool";
|
||||
awkCmd = "${pkgs.gawk}/bin/awk";
|
||||
@ -139,10 +146,8 @@ let
|
||||
done
|
||||
poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool.
|
||||
if poolImported "${pool}"; then
|
||||
${optionalString (if isBool cfgZfs.requestEncryptionCredentials
|
||||
then cfgZfs.requestEncryptionCredentials
|
||||
else cfgZfs.requestEncryptionCredentials != []) ''
|
||||
${getKeyLocations pool} | while IFS=$'\t' read ds kl ks; do
|
||||
${optionalString keyLocations.hasKeys ''
|
||||
${keyLocations.command} | while IFS=$'\t' read ds kl ks; do
|
||||
{
|
||||
if [[ "$ks" != unavailable ]]; then
|
||||
continue
|
||||
@ -565,7 +570,7 @@ in
|
||||
''
|
||||
else concatMapStrings (fs: ''
|
||||
zfs load-key -- ${escapeShellArg fs}
|
||||
'') cfgZfs.requestEncryptionCredentials}
|
||||
'') (filter (x: datasetToPool x == pool) cfgZfs.requestEncryptionCredentials)}
|
||||
'') rootPools));
|
||||
|
||||
# Systemd in stage 1
|
||||
|
@ -17,103 +17,151 @@ let
|
||||
makeTest {
|
||||
name = "zfs-" + name;
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ adisbladis ];
|
||||
maintainers = [ adisbladis elvishjerricco ];
|
||||
};
|
||||
|
||||
nodes.machine = { pkgs, lib, ... }:
|
||||
let
|
||||
usersharePath = "/var/lib/samba/usershares";
|
||||
in {
|
||||
virtualisation.emptyDiskImages = [ 4096 ];
|
||||
virtualisation = {
|
||||
emptyDiskImages = [ 4096 4096 ];
|
||||
useBootLoader = true;
|
||||
useEFIBoot = true;
|
||||
};
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.timeout = 0;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
networking.hostId = "deadbeef";
|
||||
boot.kernelPackages = kernelPackage;
|
||||
boot.supportedFilesystems = [ "zfs" ];
|
||||
boot.zfs.enableUnstable = enableUnstable;
|
||||
|
||||
services.samba = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
registry shares = yes
|
||||
usershare path = ${usersharePath}
|
||||
usershare allow guests = yes
|
||||
usershare max shares = 100
|
||||
usershare owner only = no
|
||||
'';
|
||||
};
|
||||
systemd.services.samba-smbd.serviceConfig.ExecStartPre =
|
||||
"${pkgs.coreutils}/bin/mkdir -m +t -p ${usersharePath}";
|
||||
|
||||
environment.systemPackages = [ pkgs.parted ];
|
||||
|
||||
# Setup regular fileSystems machinery to ensure forceImportAll can be
|
||||
# tested via the regular service units.
|
||||
virtualisation.fileSystems = {
|
||||
"/forcepool" = {
|
||||
device = "forcepool";
|
||||
# /dev/disk/by-id doesn't get populated in the NixOS test framework
|
||||
boot.zfs.devNodes = "/dev/disk/by-uuid";
|
||||
|
||||
specialisation.samba.configuration = {
|
||||
services.samba = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
registry shares = yes
|
||||
usershare path = ${usersharePath}
|
||||
usershare allow guests = yes
|
||||
usershare max shares = 100
|
||||
usershare owner only = no
|
||||
'';
|
||||
};
|
||||
systemd.services.samba-smbd.serviceConfig.ExecStartPre =
|
||||
"${pkgs.coreutils}/bin/mkdir -m +t -p ${usersharePath}";
|
||||
virtualisation.fileSystems = {
|
||||
"/tmp/mnt" = {
|
||||
device = "rpool/root";
|
||||
fsType = "zfs";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
specialisation.encryption.configuration = {
|
||||
boot.zfs.requestEncryptionCredentials = [ "automatic" ];
|
||||
virtualisation.fileSystems."/automatic" = {
|
||||
device = "automatic";
|
||||
fsType = "zfs";
|
||||
};
|
||||
virtualisation.fileSystems."/manual" = {
|
||||
device = "manual";
|
||||
fsType = "zfs";
|
||||
};
|
||||
virtualisation.fileSystems."/manual/encrypted" = {
|
||||
device = "manual/encrypted";
|
||||
fsType = "zfs";
|
||||
options = [ "noauto" ];
|
||||
};
|
||||
};
|
||||
|
||||
# forcepool doesn't exist at first boot, and we need to manually test
|
||||
# the import after tweaking the hostId.
|
||||
systemd.services.zfs-import-forcepool.wantedBy = lib.mkVMOverride [];
|
||||
systemd.targets.zfs.wantedBy = lib.mkVMOverride [];
|
||||
boot.zfs.forceImportAll = true;
|
||||
# /dev/disk/by-id doesn't get populated in the NixOS test framework
|
||||
boot.zfs.devNodes = "/dev/disk/by-uuid";
|
||||
specialisation.forcepool.configuration = {
|
||||
systemd.services.zfs-import-forcepool.wantedBy = lib.mkVMOverride [ "forcepool.mount" ];
|
||||
systemd.targets.zfs.wantedBy = lib.mkVMOverride [];
|
||||
boot.zfs.forceImportAll = true;
|
||||
virtualisation.fileSystems."/forcepool" = {
|
||||
device = "forcepool";
|
||||
fsType = "zfs";
|
||||
options = [ "noauto" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.succeed(
|
||||
"modprobe zfs",
|
||||
"zpool status",
|
||||
"ls /dev",
|
||||
"mkdir /tmp/mnt",
|
||||
"udevadm settle",
|
||||
"parted --script /dev/vdb mklabel msdos",
|
||||
"parted --script /dev/vdb -- mkpart primary 1024M -1s",
|
||||
"udevadm settle",
|
||||
"zpool create rpool /dev/vdb1",
|
||||
"zfs create -o mountpoint=legacy rpool/root",
|
||||
# shared datasets cannot have legacy mountpoint
|
||||
"zfs create rpool/shared_smb",
|
||||
"mount -t zfs rpool/root /tmp/mnt",
|
||||
"udevadm settle",
|
||||
# wait for samba services
|
||||
"systemctl is-system-running --wait",
|
||||
"zfs set sharesmb=on rpool/shared_smb",
|
||||
"zfs share rpool/shared_smb",
|
||||
"smbclient -gNL localhost | grep rpool_shared_smb",
|
||||
"umount /tmp/mnt",
|
||||
"zpool destroy rpool",
|
||||
"udevadm settle",
|
||||
"parted --script /dev/vdc mklabel msdos",
|
||||
"parted --script /dev/vdc -- mkpart primary 1024M -1s",
|
||||
"parted --script /dev/vdd mklabel msdos",
|
||||
"parted --script /dev/vdd -- mkpart primary 1024M -1s",
|
||||
)
|
||||
|
||||
machine.succeed(
|
||||
'echo password | zpool create -o altroot="/tmp/mnt" '
|
||||
+ "-O encryption=aes-256-gcm -O keyformat=passphrase rpool /dev/vdb1",
|
||||
"zfs create -o mountpoint=legacy rpool/root",
|
||||
"mount -t zfs rpool/root /tmp/mnt",
|
||||
"udevadm settle",
|
||||
"umount /tmp/mnt",
|
||||
"zpool destroy rpool",
|
||||
"udevadm settle",
|
||||
)
|
||||
with subtest("sharesmb works"):
|
||||
machine.succeed(
|
||||
"zpool create rpool /dev/vdc1",
|
||||
"zfs create -o mountpoint=legacy rpool/root",
|
||||
# shared datasets cannot have legacy mountpoint
|
||||
"zfs create rpool/shared_smb",
|
||||
"bootctl set-default nixos-generation-1-specialisation-samba.conf",
|
||||
"sync",
|
||||
)
|
||||
machine.crash()
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.succeed(
|
||||
"zfs set sharesmb=on rpool/shared_smb",
|
||||
"zfs share rpool/shared_smb",
|
||||
"smbclient -gNL localhost | grep rpool_shared_smb",
|
||||
"umount /tmp/mnt",
|
||||
"zpool destroy rpool",
|
||||
)
|
||||
|
||||
with subtest("encryption works"):
|
||||
machine.succeed(
|
||||
'echo password | zpool create -O mountpoint=legacy '
|
||||
+ "-O encryption=aes-256-gcm -O keyformat=passphrase automatic /dev/vdc1",
|
||||
"zpool create -O mountpoint=legacy manual /dev/vdd1",
|
||||
"echo otherpass | zfs create "
|
||||
+ "-o encryption=aes-256-gcm -o keyformat=passphrase manual/encrypted",
|
||||
"bootctl set-default nixos-generation-1-specialisation-encryption.conf",
|
||||
"sync",
|
||||
"zpool export automatic",
|
||||
"zpool export manual",
|
||||
)
|
||||
machine.crash()
|
||||
machine.start()
|
||||
machine.wait_for_console_text("Starting password query on")
|
||||
machine.send_console("password\n")
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.succeed(
|
||||
"zfs get keystatus manual/encrypted | grep unavailable",
|
||||
"echo otherpass | zfs load-key manual/encrypted",
|
||||
"systemctl start manual-encrypted.mount",
|
||||
"umount /automatic /manual/encrypted /manual",
|
||||
"zpool destroy automatic",
|
||||
"zpool destroy manual",
|
||||
)
|
||||
|
||||
with subtest("boot.zfs.forceImportAll works"):
|
||||
machine.succeed(
|
||||
"rm /etc/hostid",
|
||||
"zgenhostid deadcafe",
|
||||
"zpool create forcepool /dev/vdb1 -O mountpoint=legacy",
|
||||
"zpool create forcepool /dev/vdc1 -O mountpoint=legacy",
|
||||
"bootctl set-default nixos-generation-1-specialisation-forcepool.conf",
|
||||
"rm /etc/hostid",
|
||||
"sync",
|
||||
)
|
||||
machine.shutdown()
|
||||
machine.start()
|
||||
machine.succeed("udevadm settle")
|
||||
machine.crash()
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.fail("zpool import forcepool")
|
||||
machine.succeed(
|
||||
"systemctl start zfs-import-forcepool.service",
|
||||
"mount -t zfs forcepool /tmp/mnt",
|
||||
"systemctl start forcepool.mount",
|
||||
"mount | grep forcepool",
|
||||
)
|
||||
'' + extraTest;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user