nix/devices: implement disk-prepare
This commit is contained in:
parent
1f14b36557
commit
afd4bb95f9
5 changed files with 136 additions and 83 deletions
28
Justfile
28
Justfile
|
@ -73,29 +73,9 @@ hm-iterate-qtile:
|
||||||
wait $!
|
wait $!
|
||||||
kill ${XEPHYR_PID}
|
kill ${XEPHYR_PID}
|
||||||
|
|
||||||
# Sorry, this is a manual step for now. Please see nix/os/modules/encryptedDisk.nix for the layout
|
# !!! DANGERIOUS !!! This wipes the disk which is configured for the given device.
|
||||||
disk-prepare:
|
disk-prepare dir:
|
||||||
echo NOT IMPLEMENTED
|
just -v _device diskPrepare {{dir}} --argstr rebuildarg "dummy"
|
||||||
# GPT partition table
|
|
||||||
# part1: size: 1MiB type: 4 BIOS BOOT
|
|
||||||
# part2: size: 512MiB label: 2-DISKID (36 char limit?)
|
|
||||||
# part3: size: * label: 3-DISKID (36 char limit?)
|
|
||||||
# cryptsetup format part3
|
|
||||||
# vgcreate DISKID part3
|
|
||||||
# lvcreate DISKID -L 8G -n swap
|
|
||||||
# lvcreate DISKID -l 100%FREE -n root
|
|
||||||
# sudo mkfs.vfat -F32 part2
|
|
||||||
# sudo mkfs.btrfs /dev/DISKID/root
|
|
||||||
# sudo mkswap /dev/DISKID/swap
|
|
||||||
# sudo mount /dev/DISKID/root /mnt
|
|
||||||
# sudo btrfs subvolume create nixos
|
|
||||||
# sudo btrfs subvolume create home
|
|
||||||
# sudo mount /dev/disk/by-partlabel/3-DISKID /mnt/DISKID-root
|
|
||||||
# pushd /dev/disk/by-partlabel/3-DISKID /mnt/DISKID-root
|
|
||||||
# sudo btrfs subvolume create nixos
|
|
||||||
# sudo mkdir nixos/{boot,home}
|
|
||||||
# sudo btrfs subvolume create home
|
|
||||||
#
|
|
||||||
|
|
||||||
# Mount the target disk specified by device configuration directory. The 'dir' argument points to a device configuration, e.g. 'nix/os/devices/steveej-live-mmc-SL32G_0x259093f6'
|
# Mount the target disk specified by device configuration directory. The 'dir' argument points to a device configuration, e.g. 'nix/os/devices/steveej-live-mmc-SL32G_0x259093f6'
|
||||||
disk-mount dir:
|
disk-mount dir:
|
||||||
|
@ -105,6 +85,6 @@ disk-mount dir:
|
||||||
disk-umount dir:
|
disk-umount dir:
|
||||||
just -v _device diskUmount {{dir}} --argstr rebuildarg "dummy"
|
just -v _device diskUmount {{dir}} --argstr rebuildarg "dummy"
|
||||||
|
|
||||||
# Perform an offline installation on the mounted the target disk, specified by device configuration directory
|
# Perform an offline installation on the mounted target disk, specified by device configuration directory
|
||||||
disk-install dir:
|
disk-install dir:
|
||||||
just -v _device diskInstall {{dir}} --argstr rebuildarg "dummy"
|
just -v _device diskInstall {{dir}} --argstr rebuildarg "dummy"
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
{ pkgs ? import <nixpkgs> {}
|
{ pkgs ? import <nixpkgs> {}
|
||||||
|
, ownLib ? import ../lib/default.nix { }
|
||||||
, dir
|
, dir
|
||||||
, rebuildarg
|
, rebuildarg
|
||||||
, moreargs ? ""
|
, moreargs ? ""
|
||||||
|
, diskId ? (import ((builtins.getEnv "PWD")+"/${dir}/hw.nix") {}).hardware.encryptedDisk.diskId
|
||||||
|
, gitRoot ? "$(git rev-parse --show-toplevel)"
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
diskId = (import ((builtins.getEnv "PWD")+"/${dir}/hw.nix") {}).hardware.encryptedDisk.diskId;
|
mntRootVol="/mnt/${diskId}-root";
|
||||||
GIT_ROOT=''''$(git rev-parse --show-toplevel)'';
|
|
||||||
|
|
||||||
in {
|
in rec {
|
||||||
rebuild = pkgs.writeScript "script" ''
|
rebuild = pkgs.writeScript "script" ''
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -xe
|
set -xe
|
||||||
|
|
||||||
pushd ${GIT_ROOT}/${dir}
|
pushd ${gitRoot}/${dir}
|
||||||
export NIXOS_CONFIG="$PWD"/configuration.nix
|
export NIXOS_CONFIG="$PWD"/configuration.nix
|
||||||
export INSTALL_ROOT="/mnt/$ID-root"
|
|
||||||
|
|
||||||
[[ -e "''${NIXOS_CONFIG}" ]]
|
[[ -e "''${NIXOS_CONFIG}" ]]
|
||||||
|
|
||||||
|
@ -28,39 +29,106 @@ in {
|
||||||
diskMount = pkgs.writeScript "script" ''
|
diskMount = pkgs.writeScript "script" ''
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -xe
|
set -xe
|
||||||
ID=${diskId}
|
echo Mounting ${diskId}
|
||||||
echo Mounting $ID
|
cryptsetup luksOpen ${ownLib.disk.bootLuksDevice diskId} ${ownLib.disk.luksName diskId}
|
||||||
set -xe
|
vgchange -ay ${ownLib.disk.volumeGroup diskId}
|
||||||
cryptsetup luksOpen /dev/disk/by-id/$ID-part3 $ID-part3
|
mkdir -p /mnt
|
||||||
vgchange -ay $ID
|
mkdir ${mntRootVol}
|
||||||
mkdir -p /mnt/$ID-root
|
mount ${ownLib.disk.rootFsDevice diskId} ${mntRootVol}
|
||||||
mount /dev/$ID/root /mnt/$ID-root -o subvol=nixos
|
mount ${ownLib.disk.rootFsDevice diskId} ${mntRootVol}/nixos/home -o subvol=home
|
||||||
mount /dev/$ID/root /mnt/$ID-root/home -o subvol=home
|
mount ${ownLib.disk.bootFsDevice diskId} ${mntRootVol}/nixos/boot
|
||||||
mount /dev/disk/by-id/$ID-part2 /mnt/$ID-root/boot
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
diskUmount = pkgs.writeScript "script" ''
|
diskUmount = pkgs.writeScript "script" ''
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -xe
|
set -xe
|
||||||
ID=${diskId}
|
umount -R ${mntRootVol}
|
||||||
umount -R /mnt/$ID-root
|
rmdir ${mntRootVol}
|
||||||
rmdir /mnt/$ID-root
|
vgchange -an ${ownLib.disk.volumeGroup diskId}
|
||||||
vgchange -an $ID
|
cryptsetup luksClose ${ownLib.disk.luksName diskId}
|
||||||
cryptsetup luksClose $ID-part3
|
|
||||||
sync
|
sync
|
||||||
'';
|
'';
|
||||||
|
|
||||||
diskInstall = pkgs.writeScript "script" ''
|
diskInstall = pkgs.writeScript "script" ''
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -xe
|
set -xe
|
||||||
ID=${diskId}
|
pushd ${gitRoot}/${dir}
|
||||||
pushd ${GIT_ROOT}/${dir}
|
|
||||||
export NIXOS_CONFIG="$PWD"/configuration.nix
|
export NIXOS_CONFIG="$PWD"/configuration.nix
|
||||||
export INSTALL_ROOT="/mnt/$ID-root"
|
|
||||||
|
|
||||||
[[ -e "''${NIXOS_CONFIG}" ]]
|
[[ -e "''${NIXOS_CONFIG}" ]]
|
||||||
[[ -e "''${INSTALL_ROOT}" ]]
|
[[ -e "${mntRootVol}/nixos" ]]
|
||||||
|
|
||||||
nixos-install --max-jobs 5 --cores 4 --no-channel-copy --no-root-passwd --root "''${INSTALL_ROOT}"
|
nixos-install --max-jobs 5 --cores 4 --no-channel-copy --no-root-passwd --root ${mntRootVol}/nixos
|
||||||
|
'';
|
||||||
|
|
||||||
|
diskPrepare = pkgs.writeScript "script" ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -xe
|
||||||
|
|
||||||
|
read -p "Continue to format ${ownLib.disk.bootGrubDevice diskId} (YES/n)?" choice
|
||||||
|
case "$choice" in
|
||||||
|
YES ) echo "Continuing in 3 seconds..."; sleep 3;;
|
||||||
|
n|N ) echo "Exiting..."; exit 0;;
|
||||||
|
* ) echo "Exiting..."; exit 1;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Partition
|
||||||
|
sync
|
||||||
|
{
|
||||||
|
fdisk -w always -W always ${ownLib.disk.bootGrubDevice diskId} <<EOF
|
||||||
|
g
|
||||||
|
n
|
||||||
|
1
|
||||||
|
|
||||||
|
+1M
|
||||||
|
n
|
||||||
|
2
|
||||||
|
|
||||||
|
+512M
|
||||||
|
n
|
||||||
|
3
|
||||||
|
|
||||||
|
|
||||||
|
t
|
||||||
|
1
|
||||||
|
4
|
||||||
|
x
|
||||||
|
n
|
||||||
|
2
|
||||||
|
2-${diskId}
|
||||||
|
n
|
||||||
|
3
|
||||||
|
3-${diskId}
|
||||||
|
r
|
||||||
|
w
|
||||||
|
EOF
|
||||||
|
} || {
|
||||||
|
sync
|
||||||
|
partprobe ${ownLib.disk.bootGrubDevice diskId}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Encrypt
|
||||||
|
cryptsetup luksFormat ${ownLib.disk.bootLuksDevice diskId} -
|
||||||
|
cryptsetup luksOpen ${ownLib.disk.bootLuksDevice diskId} ${ownLib.disk.luksName diskId}
|
||||||
|
|
||||||
|
# LVM
|
||||||
|
vgcreate ${ownLib.disk.volumeGroup diskId} ${ownLib.disk.luksPhysicalVolume diskId}
|
||||||
|
lvcreate ${ownLib.disk.volumeGroup diskId} -L 2G -n swap
|
||||||
|
lvcreate ${ownLib.disk.volumeGroup diskId} -l 100%FREE -n root
|
||||||
|
|
||||||
|
# Filesystem
|
||||||
|
mkfs.vfat -F32 ${ownLib.disk.bootFsDevice diskId}
|
||||||
|
mkfs.btrfs ${ownLib.disk.rootFsDevice diskId}
|
||||||
|
mkswap ${ownLib.disk.swapFsDevice diskId}
|
||||||
|
|
||||||
|
# Subvolume and FS hierharchy
|
||||||
|
mkdir -p /mnt
|
||||||
|
mkdir ${mntRootVol}
|
||||||
|
mount ${ownLib.disk.rootFsDevice diskId} ${mntRootVol}
|
||||||
|
btrfs subvolume create ${mntRootVol}/nixos
|
||||||
|
btrfs subvolume create ${mntRootVol}/home
|
||||||
|
mkdir ${mntRootVol}/nixos/{boot,home}
|
||||||
|
|
||||||
|
${diskUmount}
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,4 +25,27 @@
|
||||||
];
|
];
|
||||||
openssh.authorizedKeys.keys = keys.users.steveej.openssh;
|
openssh.authorizedKeys.keys = keys.users.steveej.openssh;
|
||||||
} // args;
|
} // args;
|
||||||
|
|
||||||
|
disk = rec {
|
||||||
|
# TODO: verify the GPT PARTLABEL cap at 36 chars
|
||||||
|
shortenGptPartlabel = partlabel: (builtins.substring 0 36 partlabel);
|
||||||
|
|
||||||
|
# LVM doesn't allow most characters in VG names
|
||||||
|
# TODO: replace this with a whitelist for: [a-zA-Z0-9.-_+]
|
||||||
|
volumeGroup = diskId: builtins.replaceStrings [ ":" ] [ "" ] diskId;
|
||||||
|
|
||||||
|
# This is important at install-time
|
||||||
|
bootGrubDevice = diskId: "/dev/disk/by-id/" + diskId;
|
||||||
|
|
||||||
|
# These are guaranteed by LVM
|
||||||
|
rootFsDevice = diskId: "/dev/" + (volumeGroup diskId) + "/root";
|
||||||
|
swapFsDevice = diskId: "/dev/" + (volumeGroup diskId) + "/swap";
|
||||||
|
|
||||||
|
# Cannot use the disk ID here because might be different at install vs. runtime.
|
||||||
|
# Example: MMC card which is used in the internal reader vs. USB reader
|
||||||
|
bootFsDevice = diskId: "/dev/disk/by-partlabel/" + (shortenGptPartlabel ("2-"+diskId));
|
||||||
|
bootLuksDevice = diskId: "/dev/disk/by-partlabel/" + (shortenGptPartlabel ("3-"+diskId));
|
||||||
|
luksName = diskId: (volumeGroup diskId)+"pv";
|
||||||
|
luksPhysicalVolume = diskId: "/dev/mapper/" + (luksName diskId);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,24 +5,7 @@ with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.hardware.encryptedDisk;
|
cfg = config.hardware.encryptedDisk;
|
||||||
|
ownLib = import ../lib/default.nix { };
|
||||||
|
|
||||||
volumeGroup = cfg.diskId;
|
|
||||||
|
|
||||||
# This is important at install-time
|
|
||||||
bootGrubDevice = lib.concatStrings [ "/dev/disk/by-id/" cfg.diskId ];
|
|
||||||
|
|
||||||
# These are guaranteed by LVM
|
|
||||||
rootFsDevice = lib.concatStrings [ "/dev/" volumeGroup "/root" ];
|
|
||||||
swapFsDevice = lib.concatStrings [ "/dev/" volumeGroup "/swap" ];
|
|
||||||
|
|
||||||
# TODO: verify the GPT PARTLABEL cap at 36 chars
|
|
||||||
shortenPartlabel = name: (builtins.substring 0 36 name);
|
|
||||||
# Cannot use the disk ID here because might be different at install vs. runtime.
|
|
||||||
# Example: MMC card which is used in the internal reader vs. USB reader
|
|
||||||
bootFsDevice = lib.concatStrings [ "/dev/disk/by-partlabel/" (shortenPartlabel ("2-"+cfg.diskId))];
|
|
||||||
bootLuksDevice = lib.concatStrings [ "/dev/disk/by-partlabel/" (shortenPartlabel ("3-"+cfg.diskId))];
|
|
||||||
|
|
||||||
in {
|
in {
|
||||||
options.hardware.encryptedDisk = {
|
options.hardware.encryptedDisk = {
|
||||||
enable = mkEnableOption "Enable encrypted filesystem layout";
|
enable = mkEnableOption "Enable encrypted filesystem layout";
|
||||||
|
@ -33,26 +16,26 @@ in {
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
fileSystems."/boot" = {
|
fileSystems."/boot" = {
|
||||||
device = bootFsDevice;
|
device = (ownLib.disk.bootFsDevice cfg.diskId);
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/" = {
|
fileSystems."/" = {
|
||||||
device = rootFsDevice;
|
device = (ownLib.disk.rootFsDevice cfg.diskId);
|
||||||
fsType = "btrfs";
|
fsType = "btrfs";
|
||||||
options = [ "subvol=nixos" ];
|
options = [ "subvol=nixos" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/home" = {
|
fileSystems."/home" = {
|
||||||
device = rootFsDevice;
|
device = (ownLib.disk.rootFsDevice cfg.diskId);
|
||||||
fsType = "btrfs";
|
fsType = "btrfs";
|
||||||
options = [ "subvol=home" ];
|
options = [ "subvol=home" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices = [ { device = swapFsDevice; } ];
|
swapDevices = [ { device = (ownLib.disk.swapFsDevice cfg.diskId); } ];
|
||||||
|
|
||||||
boot.loader.grub = {
|
boot.loader.grub = {
|
||||||
device = bootGrubDevice;
|
device = (ownLib.disk.bootGrubDevice cfg.diskId);
|
||||||
enableCryptodisk = true;
|
enableCryptodisk = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,11 +43,11 @@ in {
|
||||||
{
|
{
|
||||||
name =
|
name =
|
||||||
let
|
let
|
||||||
splitstring = builtins.split "/" bootLuksDevice;
|
splitstring = builtins.split "/" (ownLib.disk.bootLuksDevice cfg.diskId);
|
||||||
lastelem = (builtins.length splitstring)-1;
|
lastelem = (builtins.length splitstring)-1;
|
||||||
in
|
in
|
||||||
builtins.elemAt splitstring lastelem;
|
builtins.elemAt splitstring lastelem;
|
||||||
device = bootLuksDevice;
|
device = (ownLib.disk.bootLuksDevice cfg.diskId);
|
||||||
preLVM = true;
|
preLVM = true;
|
||||||
allowDiscards = true;
|
allowDiscards = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
let
|
let
|
||||||
passwords = import ../../../variables/passwords.crypt.nix;
|
passwords = import ../../../variables/passwords.crypt.nix;
|
||||||
libinfraos = import ../../lib/default.nix { };
|
|
||||||
inherit (import ../../lib/default.nix { }) mkUser mkRoot;
|
inherit (import ../../lib/default.nix { }) mkUser mkRoot;
|
||||||
in {
|
in {
|
||||||
users.mutableUsers = false;
|
users.mutableUsers = false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue