nix/devices: implement disk-prepare

This commit is contained in:
steveej 2018-11-10 19:24:24 +01:00
parent 1f14b36557
commit afd4bb95f9
5 changed files with 136 additions and 83 deletions

View file

@ -73,29 +73,9 @@ hm-iterate-qtile:
wait $!
kill ${XEPHYR_PID}
# Sorry, this is a manual step for now. Please see nix/os/modules/encryptedDisk.nix for the layout
disk-prepare:
echo NOT IMPLEMENTED
# 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
#
# !!! DANGERIOUS !!! This wipes the disk which is configured for the given device.
disk-prepare dir:
just -v _device diskPrepare {{dir}} --argstr rebuildarg "dummy"
# 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:
@ -105,6 +85,6 @@ disk-mount dir:
disk-umount dir:
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:
just -v _device diskInstall {{dir}} --argstr rebuildarg "dummy"

View file

@ -1,21 +1,22 @@
{ pkgs ? import <nixpkgs> {}
, ownLib ? import ../lib/default.nix { }
, dir
, rebuildarg
, moreargs ? ""
, diskId ? (import ((builtins.getEnv "PWD")+"/${dir}/hw.nix") {}).hardware.encryptedDisk.diskId
, gitRoot ? "$(git rev-parse --show-toplevel)"
}:
let
diskId = (import ((builtins.getEnv "PWD")+"/${dir}/hw.nix") {}).hardware.encryptedDisk.diskId;
GIT_ROOT=''''$(git rev-parse --show-toplevel)'';
mntRootVol="/mnt/${diskId}-root";
in {
in rec {
rebuild = pkgs.writeScript "script" ''
#!/usr/bin/env bash
set -xe
pushd ${GIT_ROOT}/${dir}
pushd ${gitRoot}/${dir}
export NIXOS_CONFIG="$PWD"/configuration.nix
export INSTALL_ROOT="/mnt/$ID-root"
[[ -e "''${NIXOS_CONFIG}" ]]
@ -28,39 +29,106 @@ in {
diskMount = pkgs.writeScript "script" ''
#!/usr/bin/env bash
set -xe
ID=${diskId}
echo Mounting $ID
set -xe
cryptsetup luksOpen /dev/disk/by-id/$ID-part3 $ID-part3
vgchange -ay $ID
mkdir -p /mnt/$ID-root
mount /dev/$ID/root /mnt/$ID-root -o subvol=nixos
mount /dev/$ID/root /mnt/$ID-root/home -o subvol=home
mount /dev/disk/by-id/$ID-part2 /mnt/$ID-root/boot
echo Mounting ${diskId}
cryptsetup luksOpen ${ownLib.disk.bootLuksDevice diskId} ${ownLib.disk.luksName diskId}
vgchange -ay ${ownLib.disk.volumeGroup diskId}
mkdir -p /mnt
mkdir ${mntRootVol}
mount ${ownLib.disk.rootFsDevice diskId} ${mntRootVol}
mount ${ownLib.disk.rootFsDevice diskId} ${mntRootVol}/nixos/home -o subvol=home
mount ${ownLib.disk.bootFsDevice diskId} ${mntRootVol}/nixos/boot
'';
diskUmount = pkgs.writeScript "script" ''
#!/usr/bin/env bash
set -xe
ID=${diskId}
umount -R /mnt/$ID-root
rmdir /mnt/$ID-root
vgchange -an $ID
cryptsetup luksClose $ID-part3
umount -R ${mntRootVol}
rmdir ${mntRootVol}
vgchange -an ${ownLib.disk.volumeGroup diskId}
cryptsetup luksClose ${ownLib.disk.luksName diskId}
sync
'';
diskInstall = pkgs.writeScript "script" ''
#!/usr/bin/env bash
set -xe
ID=${diskId}
pushd ${GIT_ROOT}/${dir}
pushd ${gitRoot}/${dir}
export NIXOS_CONFIG="$PWD"/configuration.nix
export INSTALL_ROOT="/mnt/$ID-root"
[[ -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}
'';
}

View file

@ -25,4 +25,27 @@
];
openssh.authorizedKeys.keys = keys.users.steveej.openssh;
} // 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);
};
}

View file

@ -5,24 +5,7 @@ with lib;
let
cfg = config.hardware.encryptedDisk;
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))];
ownLib = import ../lib/default.nix { };
in {
options.hardware.encryptedDisk = {
enable = mkEnableOption "Enable encrypted filesystem layout";
@ -33,26 +16,26 @@ in {
config = lib.mkIf cfg.enable {
fileSystems."/boot" = {
device = bootFsDevice;
device = (ownLib.disk.bootFsDevice cfg.diskId);
fsType = "vfat";
};
fileSystems."/" = {
device = rootFsDevice;
device = (ownLib.disk.rootFsDevice cfg.diskId);
fsType = "btrfs";
options = [ "subvol=nixos" ];
};
fileSystems."/home" = {
device = rootFsDevice;
device = (ownLib.disk.rootFsDevice cfg.diskId);
fsType = "btrfs";
options = [ "subvol=home" ];
};
swapDevices = [ { device = swapFsDevice; } ];
swapDevices = [ { device = (ownLib.disk.swapFsDevice cfg.diskId); } ];
boot.loader.grub = {
device = bootGrubDevice;
device = (ownLib.disk.bootGrubDevice cfg.diskId);
enableCryptodisk = true;
};
@ -60,11 +43,11 @@ in {
{
name =
let
splitstring = builtins.split "/" bootLuksDevice;
splitstring = builtins.split "/" (ownLib.disk.bootLuksDevice cfg.diskId);
lastelem = (builtins.length splitstring)-1;
in
builtins.elemAt splitstring lastelem;
device = bootLuksDevice;
device = (ownLib.disk.bootLuksDevice cfg.diskId);
preLVM = true;
allowDiscards = true;
}

View file

@ -4,7 +4,6 @@
let
passwords = import ../../../variables/passwords.crypt.nix;
libinfraos = import ../../lib/default.nix { };
inherit (import ../../lib/default.nix { }) mkUser mkRoot;
in {
users.mutableUsers = false;