dotfiles/hosts/i001/hardware-mounts.nix
RingOfStorms (Joshua Bell) e95c4211f2 more unlock tries
2025-12-14 14:35:17 -06:00

209 lines
5.8 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ lib, pkgs, ... }:
let
BOOT = "/dev/disk/by-uuid/ABDB-2A38";
PRIMARY_UUID = "08610781-26d3-456f-9026-35dd4a40846f";
PRIMARY = "/dev/disk/by-uuid/${PRIMARY_UUID}";
USB_KEY = "/dev/disk/by-uuid/9985-EBD1";
escape = lib.mkDefault lib.escapeSystemdPath;
in
{
# BOOT
fileSystems."/boot" = {
device = BOOT;
fsType = "vfat";
options = [
"fmask=0022"
"dmask=0022"
];
};
# PRIMARY
fileSystems."/" = {
device = PRIMARY;
fsType = "bcachefs";
options = [
"X-mount.subdir=@root"
];
};
fileSystems."/.old_roots" = {
device = PRIMARY;
fsType = "bcachefs";
options = [
"nofail" # this may not exist yet just skip it
"X-mount.mkdir"
"X-mount.subdir=@old_roots"
];
};
fileSystems."/nix" = {
device = PRIMARY;
fsType = "bcachefs";
options = [
"X-mount.mkdir"
"X-mount.subdir=@nix"
"relatime"
];
};
fileSystems."/.snapshots" = {
device = PRIMARY;
fsType = "bcachefs";
options = [
"X-mount.mkdir"
"X-mount.subdir=@root"
"relatime"
];
};
fileSystems."/.swap" = {
device = PRIMARY;
fsType = "bcachefs";
options = [
"X-mount.mkdir"
"X-mount.subdir=@swap"
"noatime"
];
};
# (optional) for preservation/impermanence
fileSystems."/persist" = {
device = PRIMARY;
fsType = "bcachefs";
options = [
"X-mount.mkdir"
"X-mount.subdir=@persist"
];
};
# SWAP
swapDevices = [
# {
# device = "/.swap/swapfile";
# size = 8 * 1024; # Creates an 8GB swap file
# }
];
# PRIMARY unencrypt
boot.initrd.systemd.enable = true;
boot.supportedFilesystems = [
"bcachefs"
"vfat"
];
# 1. Disable the automatically generated unlock services
boot.initrd.systemd.services = {
# the module creates services named unlock-bcachefs-<escaped-mountpoint>
"unlock-bcachefs-${escape "/"}".enable = false;
"unlock-bcachefs-${escape "/.old_roots"}".enable = false;
"unlock-bcachefs-${escape "/nix"}".enable = false;
"unlock-bcachefs-${escape "/.snapshots"}".enable = false;
"unlock-bcachefs-${escape "/.swap"}".enable = false;
"unlock-bcachefs-${escape "/persist"}".enable = false;
# 2. Your single custom unlock unit
unlock-bcachefs-custom = {
description = "Custom single bcachefs unlock for all subvolumes";
wantedBy = [ "initrd.target" ];
before = [ "sysroot.mount" ];
# Wait for udev so the /dev/disk/by-uuid path and the USB key appear
requires = [ "systemd-udev-settle.service" ];
after = [ "systemd-udev-settle.service" ];
serviceConfig = {
Type = "oneshot";
# NOTE: put the real password here, or better: read it from USB_KEY
# ExecStart = ''
# /bin/sh -c 'echo "password" | ${pkgs.bcachefs-tools}/bin/bcachefs unlock ${PRIMARY}'
# '';
# ExecStart = ''
# /bin/sh -c 'mount -o ro ${USB_KEY} /key && \
# cat /key/bcachefs.key | ${pkgs.bcachefs-tools}/bin/bcachefs unlock ${PRIMARY}'
# '';
# We inline a script that roughly mimics tryUnlock + openCommand behavior,
# but uses a key file from the USB stick instead of systemd-ask-password.
ExecStart = ''
/bin/sh -eu
DEVICE="${PRIMARY_UUID}"
UUID="${PRIMARY_UUID}"
echo "waiting for device to appear ''${DEVICE}"
success=false
target=""
# approximate tryUnlock loop from the module
for try in $(seq 10); do
if [ -e "''${DEVICE}" ]; then
target="$(readlink -f "''${DEVICE}")"
success=true
break
else
# try to resolve by uuid via blkid
if target="$(blkid --uuid "''${UUID}" 2>/dev/null)"; then
success=true
break
fi
fi
echo -n "."
sleep 1
done
echo
if [ "''${success}" != true ]; then
echo "Cannot find device ''${DEVICE} (UUID=''${UUID})" >&2
exit 1
fi
DEVICE="''${target}"
# pre-check: is it encrypted / already unlocked?
if ! ${pkgs.bcachefs-tools}/bin/bcachefs unlock -c "''${DEVICE}" > /dev/null 2>&1; then
echo "Device ''${DEVICE} is not encrypted or cannot be probed with -c" >&2
exit 1
fi
# mount USB, read key, unlock adjust paths as you like
# mkdir -p /key
# mount -o ro "${USB_KEY}" /key
#
# if [ ! -f /key/bcachefs.key ]; then
# echo "Missing /key/bcachefs.key on USB; cannot unlock" >&2
# umount /key || true
# exit 1
# fi
# cat /key/bcachefs.key | ${pkgs.bcachefs-tools}/bin/bcachefs unlock "''${DEVICE}"
echo "test" | ${pkgs.bcachefs-tools}/bin/bcachefs unlock "''${DEVICE}"
# umount /key || true
echo "bcachefs unlock successful for ''${DEVICE}"
'';
};
};
};
# TODO this works for resetting root!
# boot.initrd.postResumeCommands = lib.mkAfter ''
# echo "test" | bcachefs unlock ${PRIMARY}
#
# mkdir /primary_tmp
# mount ${PRIMARY} primary_tmp/
# if [[ -e /primary_tmp/@root ]]; then
# mkdir -p /primary_tmp/@old_roots
# bcachefs set-file-option /primary_tmp/@old_roots --compression=zstd
#
# timestamp=$(date --date="@$(stat -c %Y /primary_tmp/@root)" "+%Y-%m-%-d_%H:%M:%S")
# bcachefs subvolume snapshot /primary_tmp/@root "/primary_tmp/@old_roots/$timestamp"
# bcachefs subvolume delete /primary_tmp/@root
# fi
#
# for i in $(find /primary_tmp/old_roots/ -maxdepth 1 -mtime +30); do
# bcachefs subvolume delete "$i"
# done
#
# bcachefs subvolume create /primary_tmp/@root
# umount /primary_tmp
# '';
}