From 7679a8d356d83c74e0588bf03f8fb4e0a75153a8 Mon Sep 17 00:00:00 2001 From: Dmitriy Kholkin Date: Thu, 23 Feb 2023 00:01:15 +0300 Subject: [PATCH] rewrite autoinstall module --- flake.nix | 22 +- machines/Arch-Builder-VM/autoinstall.nix | 7 +- machines/Flakes-ISO/default.nix | 4 +- machines/Home-Hypervisor/autoinstall.nix | 3 +- machines/NixOS-VM/autoinstall.nix | 13 + machines/NixOS-VM/default.nix | 81 +++++ machines/NixOS-VM/system | 1 + modules/autoinstall/autoinstall.sh | 394 ----------------------- modules/autoinstall/default.nix | 157 ++------- modules/autoinstall/install.nix | 393 ++++++++++++++++++++++ 10 files changed, 546 insertions(+), 529 deletions(-) create mode 100644 machines/NixOS-VM/autoinstall.nix create mode 100644 machines/NixOS-VM/default.nix create mode 100644 machines/NixOS-VM/system delete mode 100755 modules/autoinstall/autoinstall.sh create mode 100755 modules/autoinstall/install.nix diff --git a/flake.nix b/flake.nix index 2f2e489..76fbefd 100644 --- a/flake.nix +++ b/flake.nix @@ -118,7 +118,7 @@ patchesPath = map (x: ./patches + "/${x}"); in flake-utils-plus.lib.mkFlake rec { inherit self inputs; - supportedSystems = [ "x86_64-linux" ]; + supportedSystems = [ "x86_64-linux" "aarch64-linux" ]; sharedPatches = patchesPath [ "mullvad-exclude-containers.patch" "gitea-208605.patch" ]; channelsConfig = { allowUnfree = true; }; @@ -148,6 +148,23 @@ modules = [ (import (./machines/Home-Hypervisor)) { device = "Home-Hypervisor"; mainuser = "ataraxia"; } ]; specialArgs = { inherit inputs; }; }; + Flakes-ISO = { + system = "x86_64-linux"; + modules = [ + (import (./machines/Flakes-ISO)) { device = "Flakes-ISO"; mainuser = "alukard"; } + ./machines/Home-Hypervisor/autoinstall.nix + ./machines/NixOS-VM/autoinstall.nix + ]; + specialArgs = { inherit inputs; }; + }; + Flakes-ISO-Aarch64 = { + system = "aarch64-linux"; + modules = [ + (import (./machines/Flakes-ISO)) { device = "Flakes-ISO-Aarch64"; mainuser = "alukard"; } + ./machines/Arch-Builder-VM/autoinstall.nix + ]; + specialArgs = { inherit inputs; }; + }; }; outputsBuilder = channels: let @@ -198,6 +215,7 @@ modules = [ (import (./machines/Flakes-ISO)) { device = "Flakes-ISO"; mainuser = "alukard"; } ./machines/Home-Hypervisor/autoinstall.nix + ./machines/NixOS-VM/autoinstall.nix ]; specialArgs = { inherit inputs; }; format = "install-iso"; @@ -205,7 +223,7 @@ Flakes-ISO-Aarch64 = nixos-generators.nixosGenerate { system = "aarch64-linux"; modules = [ - (import (./machines/Flakes-ISO)) { device = "Flakes-ISO"; mainuser = "alukard"; } + (import (./machines/Flakes-ISO)) { device = "Flakes-ISO-Aarch64"; mainuser = "alukard"; } ./machines/Arch-Builder-VM/autoinstall.nix ]; specialArgs = { inherit inputs; }; diff --git a/machines/Arch-Builder-VM/autoinstall.nix b/machines/Arch-Builder-VM/autoinstall.nix index 52bbe46..f8e7885 100644 --- a/machines/Arch-Builder-VM/autoinstall.nix +++ b/machines/Arch-Builder-VM/autoinstall.nix @@ -1,13 +1,12 @@ { lib, ... }: { - autoinstall = { - hostname = "Arch-Builder-VM"; + autoinstall.Arch-Builder-VM = { mainuser = "ataraxia"; flakesPath = "/home/nixos/nixos-config"; partitioning.useEntireDisk = true; - partitioning.disk = "/dev/disk/by-id/ata-QEMU_HARDDISK_QM0003"; + partitioning.disk = "/dev/disk/by-path/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-1"; partitioning.nullifyDisk = false; swapPartition.enable = true; - swapPartition.size = "8GiB"; + swapPartition.size = "4GiB"; zfsOpts.ashift = 13; persist.enable = true; }; diff --git a/machines/Flakes-ISO/default.nix b/machines/Flakes-ISO/default.nix index 71e1f54..b5e512c 100644 --- a/machines/Flakes-ISO/default.nix +++ b/machines/Flakes-ISO/default.nix @@ -1,6 +1,6 @@ { modulesPath, lib, inputs, pkgs, config, ... }: { imports = with inputs.self; [ - "${toString modulesPath}/installer/cd-dvd/installation-cd-graphical-plasma5.nix" + "${toString modulesPath}/installer/cd-dvd/installation-cd-base.nix" ../../modules/autoinstall/default.nix ]; @@ -10,7 +10,7 @@ }; config = { - networking.hostName = "Flakes-ISO"; + networking.hostName = config.device; programs.ssh.extraConfig = '' Host nix-builder diff --git a/machines/Home-Hypervisor/autoinstall.nix b/machines/Home-Hypervisor/autoinstall.nix index cb1e9c2..8f68f3a 100644 --- a/machines/Home-Hypervisor/autoinstall.nix +++ b/machines/Home-Hypervisor/autoinstall.nix @@ -1,7 +1,6 @@ { lib, ... }: { - autoinstall = { + autoinstall."Home-Hypervisor" = { debug = false; - hostname = "Home-Hypervisor"; mainuser = "ataraxia"; flakesPath = "/home/nixos/nixos-config"; encryption.enable = true; diff --git a/machines/NixOS-VM/autoinstall.nix b/machines/NixOS-VM/autoinstall.nix new file mode 100644 index 0000000..8f5e87b --- /dev/null +++ b/machines/NixOS-VM/autoinstall.nix @@ -0,0 +1,13 @@ +{ lib, ... }: { + autoinstall.NixOS-VM = { + mainuser = "ataraxia"; + flakesPath = "/home/nixos/nixos-config"; + partitioning.useEntireDisk = true; + partitioning.disk = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-1"; + partitioning.nullifyDisk = true; + swapPartition.enable = true; + swapPartition.size = "4GiB"; + zfsOpts.ashift = 13; + persist.enable = true; + }; +} diff --git a/machines/NixOS-VM/default.nix b/machines/NixOS-VM/default.nix new file mode 100644 index 0000000..5cc31a8 --- /dev/null +++ b/machines/NixOS-VM/default.nix @@ -0,0 +1,81 @@ +{ inputs, config, lib, pkgs, ... }: { + imports = with inputs.self; [ + ./hardware-configuration.nix + # nixosRoles.base + + customModules.devices + ]; + + options = { + device = lib.mkOption { type = lib.types.str; }; + mainuser = lib.mkOption { type = lib.types.str; }; + }; + + config = { + networking.hostName = config.device; + + boot = { + loader.efi.canTouchEfiVariables = false; + loader.efi.efiSysMountPoint = "/boot/efi"; + loader.generationsDir.copyKernels = true; + loader.grub = { + enable = true; + device = "nodev"; + version = 2; + efiSupport = true; + zfsSupport = true; + efiInstallAsRemovable = true; + copyKernels = true; + }; + kernelParams = [ "zswap.enabled=0" "quiet" "scsi_mod.use_blk_mq=1" "modeset" "nofb" ]; + kernelPackages = pkgs.linuxPackages_hardened; + cleanTmpDir = true; + zfs.forceImportAll = false; + }; + + zramSwap = { + enable = true; + algorithm = "zstd"; + memoryPercent = 80; + }; + + environment.systemPackages = [ pkgs.git pkgs.kitty ]; + nix = { + nixPath = lib.mkForce [ "self=/etc/self/compat" "nixpkgs=/etc/nixpkgs" ]; + registry.self.flake = inputs.self; + registry.nixpkgs.flake = inputs.nixpkgs; + extraOptions = '' + experimental-features = nix-command flakes + flake-registry = ${inputs.flake-registry}/flake-registry.json + ''; + }; + environment.etc.nixpkgs.source = inputs.nixpkgs; + environment.etc.self.source = inputs.self; + + services.openssh = { + enable = true; + settings.PasswordAuthentication = false; + settings.PermitRootLogin = lib.mkForce "without-password"; + settings.X11Forwarding = false; + extraConfig = "StreamLocalBindUnlink yes"; + ports = [ 22 ]; + }; + + users.mutableUsers = false; + users.users.ataraxia = { + isNormalUser = true; + extraGroups = [ "systemd-journal" "wheel" ]; + uid = 1000; + hashedPassword = "$y$j9T$ZC44T3XYOPapB26cyPsA4.$8wlYEbwXFszC9nrg0vafqBZFLMPabXdhnzlT3DhUit6"; + shell = pkgs.bash; + }; + users.users.ataraxia.openssh.authorizedKeys.keys = [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC+xd8ClJPvJuAdYC9HlNnjiubEtYfvnKjYr9ROV+UmPVvI3ZITF24OaMI+fxgR0EqGfcUzSGom8528IB53Q3aFMIAaA0vKjW+jrByyB2l/k/+ttpLbH75c9WyOpAcUDTen8BhHKPyXOHoJ1jLu7GFmtPZ+mZo8thFB/VIRrwECHd8DnF0drsSCorkRp1bZC7bAHgztaYHNBUoAVGgJ7nLwW7DotlgbUEDiPJHXOxd/c/ZlXIB/cfUUqF+L5ThbMPhMcwRMspLy+nQdmHhih9k6SkvYqJoNqHT5/XeShb0RkIzvUWT2CYTPop5kAY5mMnatVTOY1FZPhHzk3G8MhOQ3r/elM/ecZxmjL8uozMN9kRGf1IL4DgQZfVqQRILdNSQGb0tfeiyirNZe1RlDw9UvMnZJOw0EkiC9lSSRhBWXXxAmxRrbNFTPQSp+/kiIGDmp2AsGhD11CfTDEU3wcLEUPBUqp1FYSzHncJyEKGy2Dpa5xaUJ0cuyGL4W3WHDXa4sTfY+AIXbQTD88Ujdsbfzyd6lrikG4D/crCurXissrh7q9DuYKWRI24cp5bw9lG33U1EXisnZqFyZNwMAmSj2QEGsHCwSevn0FgyRa2WYXgpZ9hfgY4le+ZSMo2JTosQ6DjGyxMDyQAHJ/ismTTzL67Q2p6U+73toYm62Qqdspw== (none)" + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDP0/DReYSAfkucroMTdELzTORsGhhbEa+W0FDFBnwViHuoqoKvetCOkW657icexc5v/j6Ghy3+Li9twbHnEDzUJVtNtauhGMjOcUYt6pTbeJ09CGSAh+orxzeY4vXp7ANb91xW8yRn/EE4ALxqbLsc/D7TUMl11fmf0UW+kLgU5TcUYVSLMjQqBpD1Lo7lXLrImloDxe5fwoBDT09E59r9tq6+/3aHz8mpKRLsIQIV0Av00BRJ+/OVmZuBd9WS35rfkpUYmpEVInSJy3G4O6kCvY/zc9Bnh67l4kALZZ0+6W23kBGrzaRfaOtCEcscwfIu+6GXiHOL33rrMNNinF0T2942jGc18feL6P/LZCzqz8bGdFNxT43jAGPeDDcrJEWAJZFO3vVTP65dTRTHQG2KlQMzS7tcif6YUlY2JLJIb61ZfLoShH/ini/tqsGT0Be1f3ndOFt48h4XMW1oIF+EXaHYeO2UJ6855m8Wpxs4bP/jX6vMV38IvvnHy4tWD50= alukard@AMD-Workstation" + ]; + users.users.root.openssh.authorizedKeys.keys = + config.users.users.ataraxia.openssh.authorizedKeys.keys; + + system.stateVersion = "22.11"; + }; +} \ No newline at end of file diff --git a/machines/NixOS-VM/system b/machines/NixOS-VM/system new file mode 100644 index 0000000..9bdfd5f --- /dev/null +++ b/machines/NixOS-VM/system @@ -0,0 +1 @@ +x86_64-linux \ No newline at end of file diff --git a/modules/autoinstall/autoinstall.sh b/modules/autoinstall/autoinstall.sh deleted file mode 100755 index 85aa9b1..0000000 --- a/modules/autoinstall/autoinstall.sh +++ /dev/null @@ -1,394 +0,0 @@ -set -eux - -# Make sure everything is defined as an env var -autoReboot="${autoReboot?}" -flakesPath="${flakesPath?}" -hostname="${hostname?}" -mainUser="${mainUser?}" -debug="${debug?}" -entireDisk="${entireDisk?}" -nullifyDisk="${nullifyDisk?}" -disk="${disk?}" -bootPartition="${bootPartition?}" -rootPartition="${rootPartition?}" -swapPartition="${swapPartition?}" -efiSize="${efiSize?}" -bootSize="${bootSize?}" -rootSize="${rootSize?}" -swapSize="${swapSize?}" -useEncryption="${useEncryption?}" -useSwap="${useSwap?}" -argonIterTime="${argonIterTime?}" -cryptrootName="${cryptrootName?}" -cryptbootName="${cryptbootName?}" -passwordFile="${passwordFile?}" -zfsAshift="${zfsAshift?}" -rootPoolReservation="${rootPoolReservation?}" -bootPoolReservation="${bootPoolReservation?}" -usePersistModule="${usePersistModule?}" -persistRoot="${persistRoot?}" -persistHome="${persistHome?}" -oldUefi="${oldUefi?}" - -if [ "$debug" = "true" ]; then -cat >&2 << FIN - autoReboot="${autoReboot}" - flakesPath="${flakesPath}" - hostname="${hostname}" - mainUser="${mainUser}" - debug="${debug}" - entireDisk="${entireDisk}" - nullifyDisk="${nullifyDisk}" - disk="${disk}" - bootPartition="${bootPartition}" - rootPartition="${rootPartition}" - swapPartition="${swapPartition}" - efiSize="${efiSize}" - bootSize="${bootSize}" - rootSize="${rootSize}" - swapSize="${swapSize}" - useEncryption="${useEncryption}" - useSwap="${useSwap}" - argonIterTime="${argonIterTime}" - cryptrootName="${cryptrootName}" - cryptbootName="${cryptbootName}" - passwordFile="${passwordFile}" - zfsAshift="${zfsAshift}" - rootPoolReservation="${rootPoolReservation}" - bootPoolReservation="${bootPoolReservation}" - usePersistModule="${usePersistModule}" - persistRoot="${persistRoot}" - persistHome="${persistHome}" - oldUefi="${oldUefi}" -FIN -fi - -if [ ! -d "${flakesPath}" ]; then - pprint "flakesPath does not exists!" - exit 2 -fi - -if [ "$useEncryption" = "true" && ! -f "${passwordFile}" ]; then - pprint "passwordFile does not exists!" - exit 2 -fi - -pprint () { - local timestamp - timestamp=$(date +%FT%T.%3NZ) - echo -e "${timestamp} $1" 1>&2 -} - -create_new_part_table() { - wack=0 - diskByID="" - if echo $disk | grep '/dev/disk/by-id'; then - diskByID=$disk - else - byid=$(find -L /dev/disk -samefile $disk | grep by-id) - if [ "$byid" = "" ]; then - pprint "fatal: Could not find a /dev/disk/by-id symlink for %s\n" "$disk" - wack=1 - else - diskByID=$byid - fi - fi - - if [ "$debug" = "true" ]; then - cat >&2 << FIN - diskByID=${diskByID} -FIN - fi - - # The for loop has the actual output - if [ "${wack}" -gt 0 ]; then - exit 2 - fi - - if [ "$nullifyDisk" = "true" ]; then - diskname=$(basename $(readlink -f ${diskByID})) - isHDD=$(cat /sys/block/${diskname}/queue/rotational) - if [ "$isHDD" = 1 ]; then - cat /dev/zero > "$diskByID" || true - else - blkdiscard "$diskByID" - fi - fi - - # partitioning - sgdisk --zap-all "$diskByID" - - pprint "Creating boot (EFI) partition" - sgdisk -n1:1MiB:+$efiSize -t1:EF00 "$diskByID" - efiPart="$diskByID-part1" - - pprint "Creating boot (ZFS) partition" - if [ "$useEncryption" = "true" ]; then - sgdisk -n2:0:+$bootSize -t2:8309 "$diskByID" - else - sgdisk -n2:0:+$bootSize -t2:BF00 "$diskByID" - fi - bootPart="$diskByID-part2" - - if [ "$useSwap" = "true" ]; then - pprint "Creating SWAP partition" - sgdisk -n4:0:+$swapSize -t4:8200 "$diskByID" - swapPart="$diskByID-part4" - fi - - if [ "$useEncryption" = "true" ]; then - pprint "Creating LUKS partition" - sgdisk -n3:0:$rootSize -t3:8309 "$diskByID" - else - pprint "Creating ROOT partition" - sgdisk -n3:0:$rootSize -t3:BF00 "$diskByID" - fi - rootPart="$diskByID-part3" - - partprobe "$diskByID" - sleep 1 - - pprint "Format EFI partition $efiPart" - mkfs.vfat -n EFI "$efiPart" -} - - -# Installation begin -if [ "$entireDisk" = "true" ]; then - create_new_part_table -else - use_existing_part_table -fi - -if [ "$useEncryption" = "true" ]; then - password=$(cat $passwordFile) - dd if=/dev/urandom of=/tmp/keyfile0.bin bs=1024 count=4 - - pprint "Creating LUKS container on $bootPart" - echo -n "$password" | cryptsetup --type luks2 --pbkdf argon2id --iter-time $argonIterTime -c aes-xts-plain64 -s 512 -h sha256 luksFormat "$bootPart" - - pprint "Add keyfile to LUKS container on $bootPart" - echo -n "$password" | cryptsetup luksAddKey $bootPart /tmp/keyfile0.bin - - - pprint "Open LUKS container on $bootPart" - cryptsetup luksOpen --allow-discards "$bootPart" "$cryptbootName" -d /tmp/keyfile0.bin - - pprint "Creating LUKS container on $rootPart" - echo -n "$password" | cryptsetup --type luks2 --pbkdf argon2id --iter-time $argonIterTime -c aes-xts-plain64 -s 512 -h sha256 luksFormat "$rootPart" - - pprint "Add keyfile to LUKS container on $rootPart" - echo -n "$password" | cryptsetup luksAddKey $rootPart /tmp/keyfile0.bin - - - pprint "Open LUKS container on $rootPart" - cryptsetup luksOpen --allow-discards "$rootPart" "$cryptrootName" -d /tmp/keyfile0.bin - - bootPool="$(ls /dev/disk/by-id/dm-uuid-*$cryptbootName)" - rootPool="$(ls /dev/disk/by-id/dm-uuid-*$cryptrootName)" -else - bootPool="$bootPart" - rootPool="$rootPart" -fi - -pprint "Create ZFS root pool on $rootPool" -zpool create \ - -f \ - -o ashift=$zfsAshift \ - -o autotrim=on \ - -O acltype=posixacl \ - -O atime=on \ - -O canmount=off \ - -O compression=zstd \ - -O dnodesize=auto \ - -O normalization=formD \ - -O relatime=on \ - -O xattr=sa \ - -O dedup=off \ - -O mountpoint=/ \ - -R /mnt \ - rpool "$rootPool" - -pprint "Create ZFS root datasets" - -if [ "$rootPoolReservation" != "0" ]; then - zfs create -o refreservation=$rootPoolReservation -o canmount=off -o mountpoint=none rpool/reserved -fi -# top level datasets -zfs create -o canmount=off -o mountpoint=none rpool/nixos -zfs create -o canmount=off -o mountpoint=none rpool/user -zfs create -o canmount=off -o mountpoint=none rpool/persistent -# empty root -zfs create -o canmount=noauto -o mountpoint=/ rpool/nixos/root -zfs mount rpool/nixos/root -zfs create -o canmount=on -o mountpoint=/home rpool/user/home -# persistent across boots -if [ "$usePersistModule" = "true" ]; then - zfs create -o canmount=on -o mountpoint=$persistRoot rpool/persistent/impermanence - mkdir -p /mnt$persistRoot$persistHome - chown 1000:100 /mnt$persistRoot$persistHome - chmod 755 /mnt$persistRoot$persistHome -fi -zfs create -o canmount=on -o mountpoint=/srv rpool/persistent/servers -zfs create -o canmount=on -o mountpoint=/etc/secrets rpool/persistent/secrets -zfs create -o canmount=on -o mountpoint=/nix rpool/persistent/nix -zfs create -o canmount=on -o mountpoint=/var/log rpool/persistent/log -zfs create -o canmount=noauto -o atime=off rpool/persistent/lxd -zfs create -o canmount=on -o mountpoint=/var/lib/docker -o atime=off rpool/persistent/docker -zfs create -o canmount=on -o mountpoint=/var/lib/podman -o atime=off rpool/persistent/podman -zfs create -o canmount=on -o mountpoint=/var/lib/nixos-containers -o atime=off rpool/persistent/nixos-containers -zfs create -o canmount=on -o mountpoint=/media/bittorrent -o atime=off -o recordsize=16K -o compression=lz4 rpool/persistent/bittorrent -chown 1000:100 /mnt/media/bittorrent -chmod 775 /mnt/media/bittorrent -zfs create -o canmount=on -o mountpoint=/media/libvirt -o atime=off -o recordsize=16K -o compression=lz4 rpool/persistent/libvirt -chown 1000:67 /mnt/media/libvirt -chmod 775 /mnt/media/libvirt - -# Create empty zfs snapshots -zfs snapshot rpool/nixos@empty -zfs snapshot rpool/nixos/root@empty -zfs snapshot rpool/user@empty -zfs snapshot rpool/user/home@empty -zfs snapshot rpool/persistent@empty -zfs snapshot rpool/persistent/impermanence@empty -zfs snapshot rpool/persistent/servers@empty -zfs snapshot rpool/persistent/secrets@empty -zfs snapshot rpool/persistent/nix@empty -zfs snapshot rpool/persistent/log@empty -zfs snapshot rpool/persistent/lxd@empty -zfs snapshot rpool/persistent/docker@empty -zfs snapshot rpool/persistent/podman@empty -zfs snapshot rpool/persistent/nixos-containers@empty -zfs snapshot rpool/persistent/bittorrent@empty -zfs snapshot rpool/persistent/libvirt@empty - - -pprint "Create ZFS boot pool on $bootPool" -zpool create \ - -f \ - -o compatibility=grub2 \ - -o ashift=$zfsAshift \ - -o autotrim=on \ - -O acltype=posixacl \ - -O atime=on \ - -O canmount=off \ - -O compression=lz4 \ - -O devices=off \ - -O normalization=formD \ - -O relatime=on \ - -O xattr=sa \ - -O dedup=off \ - -O mountpoint=/boot \ - -R /mnt \ - bpool "$bootPool" - -pprint "Create ZFS boot datasets" - -if [ "$bootPoolReservation" != "0" ]; then - zfs create -o refreservation=$bootPoolReservation -o canmount=off -o mountpoint=none bpool/reserved -fi -zfs create -o canmount=off -o mountpoint=none bpool/nixos -zfs create -o canmount=on -o mountpoint=/boot bpool/nixos/boot - -zfs snapshot bpool/nixos@empty -zfs snapshot bpool/nixos/boot@empty - -# Disable cache, stale cache will prevent system from booting -if [ "$usePersistModule" = "true" ]; then - mkdir -p /mnt"$persistRoot"/etc/zfs/ - rm -f /mnt"$persistRoot"/etc/zfs/zpool.cache - touch /mnt"$persistRoot"/etc/zfs/zpool.cache - chmod a-w /mnt"$persistRoot"/etc/zfs/zpool.cache - chattr +i /mnt"$persistRoot"/etc/zfs/zpool.cache -else - mkdir -p /mnt/etc/zfs/ - rm -f /mnt/etc/zfs/zpool.cache - touch /mnt/etc/zfs/zpool.cache - chmod a-w /mnt/etc/zfs/zpool.cache - chattr +i /mnt/etc/zfs/zpool.cache -fi - -mkdir -p /mnt/boot/efi -mount -t vfat "$efiPart" /mnt/boot/efi - -if [ "$useSwap" = "true" ]; then - mkswap -L swap -f "$swapPart" -fi - -pprint "Generate NixOS configuration" -configExists=false -[ -f $flakesPath/machines/$hostname/configuration.nix ] && configExists=true -nixos-generate-config --root /mnt --dir $flakesPath/machines/$hostname -[ "$configExists" = "false" ] && rm -f $flakesPath/machines/$hostname/configuration.nix - -pprint "Append ZFS configuration to hardware-configuration.nix" - -hostID=$(head -c8 /etc/machine-id) - -hardwareConfig=$(mktemp) -if [ "$useEncryption" = "true" ]; then - bootPartUuid=$(blkid --match-tag PARTUUID --output value "$bootPart") - rootPartUuid=$(blkid --match-tag PARTUUID --output value "$rootPart") - - cat < "$hardwareConfig" - networking.hostId = "$hostID"; - boot.zfs.devNodes = "/dev/disk/by-id"; - boot.supportedFilesystems = [ "zfs" ]; - boot.initrd.luks.devices."$cryptbootName".device = "/dev/disk/by-partuuid/$bootPartUuid"; - boot.initrd.luks.devices."$cryptrootName".device = "/dev/disk/by-partuuid/$rootPartUuid"; -CONFIG -else -cat < "$hardwareConfig" - networking.hostId = "$hostID"; - boot.zfs.devNodes = "/dev/disk/by-id"; - boot.supportedFilesystems = [ "zfs" ]; -CONFIG -fi - -sed -i "\$e cat $hardwareConfig" $flakesPath/machines/$hostname/hardware-configuration.nix -sed -i 's|fsType = "zfs";|fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];|g' $flakesPath/machines/$hostname/hardware-configuration.nix -if [ "$useSwap" == "true" ]; then - swapPartUuid=$(blkid --match-tag PARTUUID --output value "$swapPart") - sed -i "s|swapDevices = \[ \];|swapDevices = \[\n {\n device = \"/dev/disk/by-partuuid/$swapPartUuid\";\n randomEncryption.enable = true;\n randomEncryption.allowDiscards = true;\n }\n \];|" $flakesPath/machines/$hostname/hardware-configuration.nix -fi -chown 1000:100 $flakesPath/machines/$hostname/hardware-configuration.nix -git config --global --add safe.directory "$flakesPath" -git -C "$flakesPath" add -A - -pprint "Gen ssh host key for initrd" -ssh-keygen -t ed25519 -N "" -f /mnt/etc/secrets/ssh_host_key -chown root:root /mnt/etc/secrets/ssh_host_key -chmod 600 /mnt/etc/secrets/ssh_host_key - -if [ "$useEncryption" = "true" ]; then - cp /tmp/keyfile0.bin /mnt/etc/secrets/keyfile0.bin - chmod 000 /mnt/etc/secrets/keyfile*.bin -fi - -if [ "$debug" != "true" ]; then - nixos-install --flake "$flakesPath/#$hostname" --root /mnt --no-root-passwd - - configPath="/mnt/persist/home/"$mainUser"/nixos-config" - if [ ! -d "$configPath" ]; then - mkdir -p $configPath - chown 1000:100 $configPath - fi - cp -aT $flakesPath $configPath -fi - -if [ "$oldUefi" = "true" ]; then - mkdir -p /mnt/boot/efi/EFI/Microsoft/Boot - cp /mnt/boot/efi/EFI/BOOT/BOOTX64.EFI /mnt/boot/efi/EFI/Microsoft/Boot/bootmgr.efi - cp /mnt/boot/efi/EFI/BOOT/BOOTX64.EFI /mnt/boot/efi/EFI/Microsoft/Boot/bootmgfw.efi -fi - -umount -Rl /mnt -zpool export -a -if [ "$useEncryption" = "true" ]; then - cryptsetup luksClose $cryptbootName - cryptsetup luksClose $cryptrootName -fi - -if [ "$autoReboot" = "true" ]; then - if ! systemctl reboot --firmware-setup ; then - pprint "Reboot into efi firmware setup failed! Shutdown in 30 seconds" - sleep 30 - systemctl poweroff - fi -fi \ No newline at end of file diff --git a/modules/autoinstall/default.nix b/modules/autoinstall/default.nix index 8fffce4..6c53f3b 100644 --- a/modules/autoinstall/default.nix +++ b/modules/autoinstall/default.nix @@ -1,27 +1,11 @@ -{ config, pkgs, lib, ... }: +{ config, options, lib, pkgs, ... }: + with lib; let cfg = config.autoinstall; - # partitionsAttrs = { - # bootPartition = mkOption { - # type = types.str; - # default = ""; - # description = "Boot partition"; - # }; - # rootPartition = mkOption { - # type = types.str; - # default = ""; - # description = "Root partition"; - # }; - # swapPartition = mkOption { - # type = types.nullOr types.str; - # default = ""; - # description = "Swap partition"; - # }; - # }; -in{ - options = { - autoinstall = { + + autoinstallOptions = { name, ... }: { + options = rec { autoReboot = mkOption { type = types.bool; default = false; @@ -54,11 +38,6 @@ in{ default = false; description = "If we should exit before installing or not to let debugging occur"; }; - hostname = mkOption { - type = types.str; - default = ""; - description = "The hostname the system will be known as"; - }; mainuser = mkOption { type = types.str; default = "alukard"; @@ -153,7 +132,7 @@ in{ }; persistHome = mkOption { type = types.str; - default = "/home/${cfg.mainuser}"; + default = "/home/${cfg.${name}.mainuser}"; description = "Path to home user folder relative to persistRoot"; }; }; @@ -162,107 +141,35 @@ in{ default = false; description = "Copy bootx64.efi to windows efi location (EFI/Microsoft/Boot/bootmgr.efi)"; }; - # rootDevices = mkOption { - # type = types.listOf types.str; - # default = "/dev/sda"; - # description = "the root block device that justdoit will nuke from orbit and force nixos onto"; - # }; - # bootSize = mkOption { - # type = types.str; - # default = "512MiB"; - # description = "/boot size"; - # }; - # swapSize = mkOption { - # type = types.str; - # default = "2GiB"; - # description = "swap size"; - # }; - # osSize = mkOption { - # type = types.str; - # default = "10GiB"; - # description = "size of / partition/whatever basically"; - # }; - # wipe = mkOption { - # type = types.bool; - # default = false; - # description = "run wipefs on devices prior to install"; - # }; - # zero = mkOption { - # type = types.bool; - # default = false; - # description = "zero out devices prior to install (time consuming)"; - # }; - # dedicatedBoot = mkOption { - # type = types.str; - # default = ""; - # description = "If there should be a dedicated /boot device fill this in with the device name."; - # }; - # # Needs a lot more testing somehow, vm's? - # flavor = mkOption { - # type = types.enum [ "single" "zfs" "lvm" ]; - # default = "zfs"; - # description = "Specify the disk layout type, single = no zfs mirroring or lvm mirroring"; - # }; }; }; - config = { - assertions = [{ - assertion = cfg.flakesPath != ""; - message = "flakesPath can't be empty"; - } { - assertion = cfg.hostname != ""; - message = "hostname can't be empty"; - } { - assertion = !(cfg.encryption.enable && cfg.encryption.passwordFile == ""); - message = "If you use encryption, you need to set path to password file"; - }]; - systemd.services."autoinstall-${cfg.hostname}" = { - description = "NixOS Autoinstall"; - # wantedBy = [ "multi-user.target" ]; - # after = [ "network.target" "polkit.service" ]; - path = with pkgs; [ - "/run/current-system/sw/" - "/usr/bin/" - "${systemd}/bin/" - "${git}/bin" - ]; - script = with pkgs; (builtins.readFile ./autoinstall.sh); - environment = config.nix.envVars // rec { - inherit (config.environment.sessionVariables) NIX_PATH; - autoReboot = boolToString cfg.autoReboot; - entireDisk = boolToString cfg.partitioning.useEntireDisk; - nullifyDisk = boolToString cfg.partitioning.nullifyDisk; - disk = cfg.partitioning.disk or "0"; - bootPartition = cfg.partitioning.partitions.bootPartition or "0"; - rootPartition = cfg.partitioning.partitions.rootPartition or "0"; - swapPartition = cfg.partitioning.partitions.swapPartition or "0"; - debug = boolToString cfg.debug; - hostname = cfg.hostname; - flakesPath = cfg.flakesPath; - mainUser = cfg.mainuser; - useSwap = boolToString cfg.swapPartition.enable; - useEncryption = boolToString cfg.encryption.enable; - efiSize = cfg.efiSize; - bootSize = cfg.bootSize; - rootSize = cfg.rootSize; - swapSize = cfg.swapPartition.size or "0"; - argonIterTime = cfg.encryption.argonIterTime; - cryptrootName = cfg.encryption.cryptBoot; - cryptbootName = cfg.encryption.cryptRoot; - passwordFile = cfg.encryption.passwordFile; - zfsAshift = toString cfg.zfsOpts.ashift; - bootPoolReservation = cfg.zfsOpts.bootPoolReservation; - rootPoolReservation = cfg.zfsOpts.rootPoolReservation; - usePersistModule = boolToString cfg.persist.enable; - persistRoot = cfg.persist.persistRoot; - persistHome = cfg.persist.persistHome; - oldUefi = boolToString cfg.oldUefi; - - HOME = "/root"; - # LIBSH = "${./lib.sh}:${../../static/src/lib.sh}"; - }; - serviceConfig = { Type = "oneshot"; }; + mkService = name: opt: { + description = "Autoinstall NixOS on ${name}"; + # wantedBy = [ "multi-user.target" ]; + # after = [ "network.target" "polkit.service" ]; + path = with pkgs; [ + "/run/current-system/sw/" + "/usr/bin/" + "${systemd}/bin/" + "${git}/bin" + ]; + script = import ./install.nix { + inherit lib; inherit opt; hostname = name; }; + environment = config.nix.envVars // rec { + inherit (config.environment.sessionVariables) NIX_PATH; + HOME = "/root"; + }; + serviceConfig = { Type = "oneshot"; }; + }; +in { + options.autoinstall = mkOption { + default = {}; + type = types.attrsOf (types.submodule autoinstallOptions); + }; + + config = lib.mkIf (cfg != {}) { + systemd.services = mapAttrs' (n: v: nameValuePair "autoinstall-${n}" (mkService n v)) cfg; }; } \ No newline at end of file diff --git a/modules/autoinstall/install.nix b/modules/autoinstall/install.nix new file mode 100755 index 0000000..03f0ad3 --- /dev/null +++ b/modules/autoinstall/install.nix @@ -0,0 +1,393 @@ +{ opt, hostname, lib }: +with lib; let + cfg = opt // { + hostname = hostname; + autoReboot = boolToString opt.autoReboot; + entireDisk = boolToString opt.partitioning.useEntireDisk; + nullifyDisk = boolToString opt.partitioning.nullifyDisk; + disk = opt.partitioning.disk or "0"; + bootPartition = opt.partitioning.partitions.bootPartition or "0"; + rootPartition = opt.partitioning.partitions.rootPartition or "0"; + swapPartition = opt.partitioning.partitions.swapPartition or "0"; + debug = boolToString opt.debug; + useSwap = boolToString opt.swapPartition.enable; + useEncryption = boolToString opt.encryption.enable; + swapSize = opt.swapPartition.size or "0"; + zfsAshift = toString opt.zfsOpts.ashift; + usePersistModule = boolToString opt.persist.enable; + oldUefi = boolToString opt.oldUefi; + argonIterTime = opt.encryption.argonIterTime; + passwordFile = opt.encryption.passwordFile; + cryptBoot = opt.encryption.cryptBoot; + cryptRoot = opt.encryption.cryptRoot; + bootPoolReservation = opt.zfsOpts.bootPoolReservation; + rootPoolReservation = opt.zfsOpts.rootPoolReservation; + persistRoot = opt.persist.persistRoot; + persistHome = opt.persist.persistHome; + }; +in '' + set -eux + + if [ "${cfg.debug}" = "true" ]; then + cat >&2 << FIN + autoReboot="${cfg.autoReboot}" + flakesPath="${cfg.flakesPath}" + hostname="${cfg.hostname}" + mainuser="${cfg.mainuser}" + debug="${cfg.debug}" + entireDisk="${cfg.entireDisk}" + nullifyDisk="${cfg.nullifyDisk}" + disk="${cfg.disk}" + bootPartition="${cfg.bootPartition}" + rootPartition="${cfg.rootPartition}" + swapPartition="${cfg.swapPartition}" + efiSize="${cfg.efiSize}" + bootSize="${cfg.bootSize}" + rootSize="${cfg.rootSize}" + swapSize="${cfg.swapSize}" + useEncryption="${cfg.useEncryption}" + useSwap="${cfg.useSwap}" + argonIterTime="${cfg.argonIterTime}" + cryptRoot="${cfg.cryptRoot}" + cryptBoot="${cfg.cryptBoot}" + passwordFile="${cfg.passwordFile}" + zfsAshift="${cfg.zfsAshift}" + rootPoolReservation="${cfg.rootPoolReservation}" + bootPoolReservation="${cfg.bootPoolReservation}" + usePersistModule="${cfg.usePersistModule}" + persistRoot="${cfg.persistRoot}" + persistHome="${cfg.persistHome}" + oldUefi="${cfg.oldUefi}" + FIN + fi + + pprint () { + local timestamp + timestamp=$(date +%FT%T.%3NZ) + echo -e "$timestamp $1" 1>&2 + } + + if [ ! -d "${cfg.flakesPath}" ]; then + pprint "flakesPath does not exists!" + exit 2 + fi + + if [ "${cfg.useEncryption}" = "true" && ! -f "${cfg.passwordFile}" ]; then + pprint "passwordFile does not exists!" + exit 2 + fi + + create_new_part_table() { + wack=0 + diskByID="" + if echo ${cfg.disk} | grep '/dev/disk/by-id'; then + diskByID=${cfg.disk} + else + byid=$(find -L /dev/disk -samefile ${cfg.disk} | grep by-id) + if [ "$byid" = "" ]; then + pprint "fatal: Could not find a /dev/disk/by-id symlink for %s\n" "${cfg.disk}" + wack=1 + else + diskByID=$byid + fi + fi + + if [ "${cfg.debug}" = "true" ]; then + cat >&2 << FIN + diskByID=$diskByID + FIN + fi + + # The for loop has the actual output + if [ "$wack" -gt 0 ]; then + exit 2 + fi + + if [ "${cfg.nullifyDisk}" = "true" ]; then + diskname=$(basename $(readlink -f $diskByID)) + isHDD=$(cat /sys/block/$diskname/queue/rotational) + if [ "$isHDD" = 1 ]; then + cat /dev/zero > "$diskByID" || true + else + blkdiscard "$diskByID" + fi + fi + + # partitioning + sgdisk --zap-all "$diskByID" + + pprint "Creating boot (EFI) partition" + sgdisk -n1:1MiB:+${cfg.efiSize} -t1:EF00 "$diskByID" + efiPart="$diskByID-part1" + + pprint "Creating boot (ZFS) partition" + if [ "${cfg.useEncryption}" = "true" ]; then + sgdisk -n2:0:+${cfg.bootSize} -t2:8309 "$diskByID" + else + sgdisk -n2:0:+${cfg.bootSize} -t2:BF00 "$diskByID" + fi + bootPart="$diskByID-part2" + + if [ "${cfg.useSwap}" = "true" ]; then + pprint "Creating SWAP partition" + sgdisk -n4:0:+${cfg.swapSize} -t4:8200 "$diskByID" + swapPart="$diskByID-part4" + fi + + if [ "${cfg.useEncryption}" = "true" ]; then + pprint "Creating LUKS partition" + sgdisk -n3:0:${cfg.rootSize} -t3:8309 "$diskByID" + else + pprint "Creating ROOT partition" + sgdisk -n3:0:${cfg.rootSize} -t3:BF00 "$diskByID" + fi + rootPart="$diskByID-part3" + + partprobe "$diskByID" + sleep 1 + + pprint "Format EFI partition $efiPart" + mkfs.vfat -n EFI "$efiPart" + } + + + # Installation begin + if [ "${cfg.entireDisk}" = "true" ]; then + create_new_part_table + else + use_existing_part_table + fi + + if [ "${cfg.useEncryption}" = "true" ]; then + password=$(cat ${cfg.passwordFile}) + dd if=/dev/urandom of=/tmp/keyfile0.bin bs=1024 count=4 + + pprint "Creating LUKS container on $bootPart" + echo -n "$password" | cryptsetup --type luks2 --pbkdf argon2id --iter-time ${cfg.argonIterTime} -c aes-xts-plain64 -s 512 -h sha256 luksFormat "$bootPart" - + pprint "Add keyfile to LUKS container on $bootPart" + echo -n "$password" | cryptsetup luksAddKey $bootPart /tmp/keyfile0.bin - + + pprint "Open LUKS container on $bootPart" + cryptsetup luksOpen --allow-discards "$bootPart" "${cfg.cryptBoot}" -d /tmp/keyfile0.bin + + pprint "Creating LUKS container on $rootPart" + echo -n "$password" | cryptsetup --type luks2 --pbkdf argon2id --iter-time ${cfg.argonIterTime} -c aes-xts-plain64 -s 512 -h sha256 luksFormat "$rootPart" - + pprint "Add keyfile to LUKS container on $rootPart" + echo -n "$password" | cryptsetup luksAddKey $rootPart /tmp/keyfile0.bin - + + pprint "Open LUKS container on $rootPart" + cryptsetup luksOpen --allow-discards "$rootPart" "${cfg.cryptRoot}" -d /tmp/keyfile0.bin + + bootPool="$(ls /dev/disk/by-id/dm-uuid-*${cfg.cryptBoot})" + rootPool="$(ls /dev/disk/by-id/dm-uuid-*${cfg.cryptRoot})" + else + bootPool="$bootPart" + rootPool="$rootPart" + fi + + pprint "Create ZFS root pool on $rootPool" + zpool create \ + -f \ + -o ashift=${cfg.zfsAshift} \ + -o autotrim=on \ + -O acltype=posixacl \ + -O atime=on \ + -O canmount=off \ + -O compression=zstd \ + -O dnodesize=auto \ + -O normalization=formD \ + -O relatime=on \ + -O xattr=sa \ + -O dedup=off \ + -O mountpoint=/ \ + -R /mnt \ + rpool "$rootPool" + + pprint "Create ZFS root datasets" + + if [ "${cfg.rootPoolReservation}" != "0" ]; then + zfs create -o refreservation=${cfg.rootPoolReservation} -o canmount=off -o mountpoint=none rpool/reserved + fi + # top level datasets + zfs create -o canmount=off -o mountpoint=none rpool/nixos + zfs create -o canmount=off -o mountpoint=none rpool/user + zfs create -o canmount=off -o mountpoint=none rpool/persistent + # empty root + zfs create -o canmount=noauto -o mountpoint=/ rpool/nixos/root + zfs mount rpool/nixos/root + zfs create -o canmount=on -o mountpoint=/home rpool/user/home + # persistent across boots + if [ "${cfg.usePersistModule}" = "true" ]; then + zfs create -o canmount=on -o mountpoint=${cfg.persistRoot} rpool/persistent/impermanence + mkdir -p /mnt${cfg.persistRoot}${cfg.persistHome} + chown 1000:100 /mnt${cfg.persistRoot}${cfg.persistHome} + chmod 755 /mnt${cfg.persistRoot}${cfg.persistHome} + fi + zfs create -o canmount=on -o mountpoint=/srv rpool/persistent/servers + zfs create -o canmount=on -o mountpoint=/etc/secrets rpool/persistent/secrets + zfs create -o canmount=on -o mountpoint=/nix rpool/persistent/nix + zfs create -o canmount=on -o mountpoint=/var/log rpool/persistent/log + zfs create -o canmount=noauto -o atime=off rpool/persistent/lxd + zfs create -o canmount=on -o mountpoint=/var/lib/docker -o atime=off rpool/persistent/docker + zfs create -o canmount=on -o mountpoint=/var/lib/podman -o atime=off rpool/persistent/podman + zfs create -o canmount=on -o mountpoint=/var/lib/nixos-containers -o atime=off rpool/persistent/nixos-containers + zfs create -o canmount=on -o mountpoint=/media/bittorrent -o atime=off -o recordsize=16K -o compression=lz4 rpool/persistent/bittorrent + chown 1000:100 /mnt/media/bittorrent + chmod 775 /mnt/media/bittorrent + zfs create -o canmount=on -o mountpoint=/media/libvirt -o atime=off -o recordsize=16K -o compression=lz4 rpool/persistent/libvirt + chown 1000:67 /mnt/media/libvirt + chmod 775 /mnt/media/libvirt + + # Create empty zfs snapshots + zfs snapshot rpool/nixos@empty + zfs snapshot rpool/nixos/root@empty + zfs snapshot rpool/user@empty + zfs snapshot rpool/user/home@empty + zfs snapshot rpool/persistent@empty + zfs snapshot rpool/persistent/impermanence@empty + zfs snapshot rpool/persistent/servers@empty + zfs snapshot rpool/persistent/secrets@empty + zfs snapshot rpool/persistent/nix@empty + zfs snapshot rpool/persistent/log@empty + zfs snapshot rpool/persistent/lxd@empty + zfs snapshot rpool/persistent/docker@empty + zfs snapshot rpool/persistent/podman@empty + zfs snapshot rpool/persistent/nixos-containers@empty + zfs snapshot rpool/persistent/bittorrent@empty + zfs snapshot rpool/persistent/libvirt@empty + + + pprint "Create ZFS boot pool on $bootPool" + zpool create \ + -f \ + -o compatibility=grub2 \ + -o ashift=${cfg.zfsAshift} \ + -o autotrim=on \ + -O acltype=posixacl \ + -O atime=on \ + -O canmount=off \ + -O compression=lz4 \ + -O devices=off \ + -O normalization=formD \ + -O relatime=on \ + -O xattr=sa \ + -O dedup=off \ + -O mountpoint=/boot \ + -R /mnt \ + bpool "$bootPool" + + pprint "Create ZFS boot datasets" + + if [ "${cfg.bootPoolReservation}" != "0" ]; then + zfs create -o refreservation=${cfg.bootPoolReservation} -o canmount=off -o mountpoint=none bpool/reserved + fi + zfs create -o canmount=off -o mountpoint=none bpool/nixos + zfs create -o canmount=on -o mountpoint=/boot bpool/nixos/boot + + zfs snapshot bpool/nixos@empty + zfs snapshot bpool/nixos/boot@empty + + # Disable cache, stale cache will prevent system from booting + if [ "${cfg.usePersistModule}" = "true" ]; then + mkdir -p /mnt"${cfg.persistRoot}"/etc/zfs/ + rm -f /mnt"${cfg.persistRoot}"/etc/zfs/zpool.cache + touch /mnt"${cfg.persistRoot}"/etc/zfs/zpool.cache + chmod a-w /mnt"${cfg.persistRoot}"/etc/zfs/zpool.cache + chattr +i /mnt"${cfg.persistRoot}"/etc/zfs/zpool.cache + else + mkdir -p /mnt/etc/zfs/ + rm -f /mnt/etc/zfs/zpool.cache + touch /mnt/etc/zfs/zpool.cache + chmod a-w /mnt/etc/zfs/zpool.cache + chattr +i /mnt/etc/zfs/zpool.cache + fi + + mkdir -p /mnt/boot/efi + mount -t vfat "$efiPart" /mnt/boot/efi + + if [ "${cfg.useSwap}" = "true" ]; then + mkswap -L swap -f "$swapPart" + fi + + pprint "Generate NixOS configuration" + configExists=false + [ -f ${cfg.flakesPath}/machines/${cfg.hostname}/configuration.nix ] && configExists=true + nixos-generate-config --root /mnt --dir ${cfg.flakesPath}/machines/${cfg.hostname} + [ "$configExists" = "false" ] && rm -f ${cfg.flakesPath}/machines/${cfg.hostname}/configuration.nix + + pprint "Append ZFS configuration to hardware-configuration.nix" + + hostID=$(head -c8 /etc/machine-id) + + hardwareConfig=$(mktemp) + if [ "${cfg.useEncryption}" = "true" ]; then + bootPartUuid=$(blkid --match-tag PARTUUID --output value "$bootPart") + rootPartUuid=$(blkid --match-tag PARTUUID --output value "$rootPart") + + cat < "$hardwareConfig" + networking.hostId = "$hostID"; + boot.zfs.devNodes = "/dev/disk/by-partuuid"; + boot.supportedFilesystems = [ "zfs" ]; + boot.initrd.luks.devices."${cfg.cryptBoot}".device = "/dev/disk/by-partuuid/$bootPartUuid"; + boot.initrd.luks.devices."${cfg.cryptRoot}".device = "/dev/disk/by-partuuid/$rootPartUuid"; + CONFIG + else + cat < "$hardwareConfig" + networking.hostId = "$hostID"; + boot.zfs.devNodes = "/dev/disk/by-partuuid"; + boot.supportedFilesystems = [ "zfs" ]; + CONFIG + fi + + sed -i "\$e cat $hardwareConfig" ${cfg.flakesPath}/machines/${cfg.hostname}/hardware-configuration.nix + sed -i 's|fsType = "zfs";|fsType = "zfs"; options = [ "zfsutil" "X-mount.mkdir" ];|g' ${cfg.flakesPath}/machines/${cfg.hostname}/hardware-configuration.nix + if [ "${cfg.useSwap}" == "true" ]; then + swapPartUuid=$(blkid --match-tag PARTUUID --output value "$swapPart") + sed -i "s|swapDevices = \[ \];|swapDevices = \[\n {\n device = \"/dev/disk/by-partuuid/$swapPartUuid\";\n randomEncryption.enable = true;\n randomEncryption.allowDiscards = true;\n }\n \];|" ${cfg.flakesPath}/machines/${cfg.hostname}/hardware-configuration.nix + fi + chown 1000:100 ${cfg.flakesPath}/machines/${cfg.hostname}/hardware-configuration.nix + git config --global --add safe.directory "${cfg.flakesPath}" + git -C "${cfg.flakesPath}" add -A + + pprint "Gen ssh host key for initrd" + ssh-keygen -t ed25519 -N "" -f /mnt/etc/secrets/ssh_host_key + chown root:root /mnt/etc/secrets/ssh_host_key + chmod 600 /mnt/etc/secrets/ssh_host_key + + if [ "${cfg.useEncryption}" = "true" ]; then + cp /tmp/keyfile0.bin /mnt/etc/secrets/keyfile0.bin + chmod 000 /mnt/etc/secrets/keyfile*.bin + fi + + if [ "${cfg.debug}" != "true" ]; then + nixos-install --flake "${cfg.flakesPath}/#${cfg.hostname}" --root /mnt --no-root-passwd + + configPath="/mnt/persist/home/"${cfg.mainuser}"/nixos-config" + if [ ! -d "$configPath" ]; then + mkdir -p $configPath + chown 1000:100 $configPath + fi + cp -aT ${cfg.flakesPath} $configPath + fi + + if [ "${cfg.oldUefi}" = "true" ]; then + mkdir -p /mnt/boot/efi/EFI/Microsoft/Boot + cp /mnt/boot/efi/EFI/BOOT/BOOTX64.EFI /mnt/boot/efi/EFI/Microsoft/Boot/bootmgr.efi + cp /mnt/boot/efi/EFI/BOOT/BOOTX64.EFI /mnt/boot/efi/EFI/Microsoft/Boot/bootmgfw.efi + fi + + umount -Rl /mnt + zpool export -a + if [ "${cfg.useEncryption}" = "true" ]; then + cryptsetup luksClose ${cfg.cryptBoot} + cryptsetup luksClose ${cfg.cryptRoot} + fi + + if [ "${cfg.autoReboot}" = "true" ]; then + if ! systemctl reboot --firmware-setup ; then + pprint "Reboot into efi firmware setup failed! Shutdown in 30 seconds" + sleep 30 + systemctl poweroff + fi + fi +'' \ No newline at end of file