Skip to content

Commit

Permalink
zfs: create zfs_data pool with LUKS encryption
Browse files Browse the repository at this point in the history
With this patch we create zfs_data pool with LUKS
encryption enabled and modify postBostCommands
accordingly.

Signed-off-by: Vunny Sodhi <[email protected]>
  • Loading branch information
vunnyso committed Dec 20, 2024
1 parent f500bec commit 5b64e44
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 29 deletions.
31 changes: 26 additions & 5 deletions modules/disko/disko-ab-partitions.nix
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
boot = {
initrd.availableKernelModules = [ "zfs" ];
supportedFilesystems = [ "zfs" ];
zfs.extraPools = [ "zfs_data" ];
};
disko = {
# 8GB is the recommeneded minimum for ZFS, so we are using this for VMs to avoid `cp` oom errors.
Expand All @@ -57,7 +58,7 @@
devices = {
disk.disk1 = {
type = "disk";
imageSize = "60G";
imageSize = "70G";
content = {
type = "gpt";
partitions = {
Expand Down Expand Up @@ -91,18 +92,32 @@
#randomEncryption = true;
};
};
zfs_1 = {
size = "100%";
zfs_root = {
size = "30G";
content = {
type = "zfs";
pool = "zfspool";
pool = "zfs_root";
};
};
zfs_data = {
size = "100%";
content = {
name = "zfs_data";
type = "luks";
# TODO: Have a better password mechanism later
settings.keyFile = "${pkgs.writeText "password" "ghaf"}";
content = {
type = "zfs";
pool = "zfs_data";
};
};
};
};
};
};

zpool = {
zfspool = {
zfs_root = {
type = "zpool";
rootFsOptions = {
mountpoint = "none";
Expand All @@ -124,6 +139,12 @@
quota = "30G";
};
};
};
};

zfs_data = {
type = "zpool";
datasets = {
"vm_storage" = {
type = "zfs_fs";
options = {
Expand Down
63 changes: 39 additions & 24 deletions modules/disko/disko-zfs-postboot.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,55 @@
# SPDX-License-Identifier: Apache-2.0
{ pkgs, ... }:
let
postBootCmds = ''
set -xeuo pipefail
zfsPostBoot = pkgs.writeShellApplication {
name = "zfsPostBootScript";
runtimeInputs = with pkgs; [
zfs
gnugrep
gawk
cryptsetup
util-linux
gptfdisk
parted
];
text = ''
set -xeuo pipefail
# Check which physical disk is used by ZFS
ZFS_POOLNAME=$(${pkgs.zfs}/bin/zpool list | ${pkgs.gnugrep}/bin/grep -v NAME | ${pkgs.gawk}/bin/awk '{print $1}')
ZFS_LOCATION=$(${pkgs.zfs}/bin/zpool status -P | ${pkgs.gnugrep}/bin/grep dev | ${pkgs.gawk}/bin/awk '{print $1}')
# Check which physical disk is used by ZFS
ENCRYPTED_POOL=zfs_data
zpool import -f $ENCRYPTED_POOL
ZFS_POOLNAME=$(zpool list | grep -v NAME | grep $ENCRYPTED_POOL | awk '{print $1}')
ZFS_LOCATION=$(zpool status -P | grep dev | grep "$ZFS_POOLNAME" | awk '{print $1}')
# Get the actual device path
P_DEVPATH=$(readlink -f "$ZFS_LOCATION")
# Get the actual device path
P_DEVPATH=$(cryptsetup status "$ZFS_POOLNAME" | grep device | awk '{print $2}')
# Extract the partition number using regex
if [[ "$P_DEVPATH" =~ [0-9]+$ ]]; then
PARTNUM=$(echo "$P_DEVPATH" | ${pkgs.gnugrep}/bin/grep -o '[0-9]*$')
PARENT_DISK=/dev/$(${pkgs.util-linux}/bin/lsblk -no pkname "$P_DEVPATH")
else
echo "No partition number found in device path: $P_DEVPATH"
fi
# Extract the partition number using regex
if [[ "$P_DEVPATH" =~ [0-9]+$ ]]; then
PARTNUM=$(echo "$P_DEVPATH" | grep -o '[0-9]*$')
PARENT_DISK=/dev/$(lsblk -no pkname "$P_DEVPATH" | head -n 1)
else
echo "No partition number found in device path: $P_DEVPATH"
fi
# Fix GPT first
${pkgs.gptfdisk}/bin/sgdisk "$PARENT_DISK" -e
# Fix GPT first
sgdisk "$PARENT_DISK" -e
# Call partprobe to update kernel's partitions
${pkgs.parted}/bin/partprobe
# Call partprobe to update kernel's partitions
partprobe
# Extend the partition to use unallocated space
${pkgs.parted}/bin/parted -s -a opt "$PARENT_DISK" "resizepart $PARTNUM 100%"
# Extend the partition to use unallocated space
parted -s -a opt "$PARENT_DISK" "resizepart $PARTNUM 100%"
# Extend ZFS pool to use newly allocated space
zpool online -e "$ZFS_POOLNAME" "$ZFS_LOCATION"
'';
};

# Extend ZFS pool to use newly allocated space
${pkgs.zfs}/bin/zpool online -e "$ZFS_POOLNAME" "$ZFS_LOCATION"
'';
in
{
# To debug postBootCommands, one may run
# journalctl -u initrd-nixos-activation.service
# inside the running Ghaf host.
boot.postBootCommands = postBootCmds;
boot.postBootCommands = "${zfsPostBoot}/bin/zfsPostBootScript";
}

0 comments on commit 5b64e44

Please sign in to comment.