rewrite autoinstall module
This commit is contained in:
parent
197d4f8402
commit
7679a8d356
22
flake.nix
22
flake.nix
@ -118,7 +118,7 @@
|
|||||||
patchesPath = map (x: ./patches + "/${x}");
|
patchesPath = map (x: ./patches + "/${x}");
|
||||||
in flake-utils-plus.lib.mkFlake rec {
|
in flake-utils-plus.lib.mkFlake rec {
|
||||||
inherit self inputs;
|
inherit self inputs;
|
||||||
supportedSystems = [ "x86_64-linux" ];
|
supportedSystems = [ "x86_64-linux" "aarch64-linux" ];
|
||||||
|
|
||||||
sharedPatches = patchesPath [ "mullvad-exclude-containers.patch" "gitea-208605.patch" ];
|
sharedPatches = patchesPath [ "mullvad-exclude-containers.patch" "gitea-208605.patch" ];
|
||||||
channelsConfig = { allowUnfree = true; };
|
channelsConfig = { allowUnfree = true; };
|
||||||
@ -148,6 +148,23 @@
|
|||||||
modules = [ (import (./machines/Home-Hypervisor)) { device = "Home-Hypervisor"; mainuser = "ataraxia"; } ];
|
modules = [ (import (./machines/Home-Hypervisor)) { device = "Home-Hypervisor"; mainuser = "ataraxia"; } ];
|
||||||
specialArgs = { inherit inputs; };
|
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
|
outputsBuilder = channels: let
|
||||||
@ -198,6 +215,7 @@
|
|||||||
modules = [
|
modules = [
|
||||||
(import (./machines/Flakes-ISO)) { device = "Flakes-ISO"; mainuser = "alukard"; }
|
(import (./machines/Flakes-ISO)) { device = "Flakes-ISO"; mainuser = "alukard"; }
|
||||||
./machines/Home-Hypervisor/autoinstall.nix
|
./machines/Home-Hypervisor/autoinstall.nix
|
||||||
|
./machines/NixOS-VM/autoinstall.nix
|
||||||
];
|
];
|
||||||
specialArgs = { inherit inputs; };
|
specialArgs = { inherit inputs; };
|
||||||
format = "install-iso";
|
format = "install-iso";
|
||||||
@ -205,7 +223,7 @@
|
|||||||
Flakes-ISO-Aarch64 = nixos-generators.nixosGenerate {
|
Flakes-ISO-Aarch64 = nixos-generators.nixosGenerate {
|
||||||
system = "aarch64-linux";
|
system = "aarch64-linux";
|
||||||
modules = [
|
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
|
./machines/Arch-Builder-VM/autoinstall.nix
|
||||||
];
|
];
|
||||||
specialArgs = { inherit inputs; };
|
specialArgs = { inherit inputs; };
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
{ lib, ... }: {
|
{ lib, ... }: {
|
||||||
autoinstall = {
|
autoinstall.Arch-Builder-VM = {
|
||||||
hostname = "Arch-Builder-VM";
|
|
||||||
mainuser = "ataraxia";
|
mainuser = "ataraxia";
|
||||||
flakesPath = "/home/nixos/nixos-config";
|
flakesPath = "/home/nixos/nixos-config";
|
||||||
partitioning.useEntireDisk = true;
|
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;
|
partitioning.nullifyDisk = false;
|
||||||
swapPartition.enable = true;
|
swapPartition.enable = true;
|
||||||
swapPartition.size = "8GiB";
|
swapPartition.size = "4GiB";
|
||||||
zfsOpts.ashift = 13;
|
zfsOpts.ashift = 13;
|
||||||
persist.enable = true;
|
persist.enable = true;
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ modulesPath, lib, inputs, pkgs, config, ... }: {
|
{ modulesPath, lib, inputs, pkgs, config, ... }: {
|
||||||
imports = with inputs.self; [
|
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
|
../../modules/autoinstall/default.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -10,7 +10,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
networking.hostName = "Flakes-ISO";
|
networking.hostName = config.device;
|
||||||
|
|
||||||
programs.ssh.extraConfig = ''
|
programs.ssh.extraConfig = ''
|
||||||
Host nix-builder
|
Host nix-builder
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{ lib, ... }: {
|
{ lib, ... }: {
|
||||||
autoinstall = {
|
autoinstall."Home-Hypervisor" = {
|
||||||
debug = false;
|
debug = false;
|
||||||
hostname = "Home-Hypervisor";
|
|
||||||
mainuser = "ataraxia";
|
mainuser = "ataraxia";
|
||||||
flakesPath = "/home/nixos/nixos-config";
|
flakesPath = "/home/nixos/nixos-config";
|
||||||
encryption.enable = true;
|
encryption.enable = true;
|
||||||
|
13
machines/NixOS-VM/autoinstall.nix
Normal file
13
machines/NixOS-VM/autoinstall.nix
Normal file
@ -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;
|
||||||
|
};
|
||||||
|
}
|
81
machines/NixOS-VM/default.nix
Normal file
81
machines/NixOS-VM/default.nix
Normal file
@ -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";
|
||||||
|
};
|
||||||
|
}
|
1
machines/NixOS-VM/system
Normal file
1
machines/NixOS-VM/system
Normal file
@ -0,0 +1 @@
|
|||||||
|
x86_64-linux
|
@ -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 <<CONFIG > "$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 <<CONFIG > "$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
|
|
@ -1,27 +1,11 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, options, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.autoinstall;
|
cfg = config.autoinstall;
|
||||||
# partitionsAttrs = {
|
|
||||||
# bootPartition = mkOption {
|
autoinstallOptions = { name, ... }: {
|
||||||
# type = types.str;
|
options = rec {
|
||||||
# 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 = {
|
|
||||||
autoReboot = mkOption {
|
autoReboot = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
@ -54,11 +38,6 @@ in{
|
|||||||
default = false;
|
default = false;
|
||||||
description = "If we should exit before installing or not to let debugging occur";
|
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 {
|
mainuser = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "alukard";
|
default = "alukard";
|
||||||
@ -153,7 +132,7 @@ in{
|
|||||||
};
|
};
|
||||||
persistHome = mkOption {
|
persistHome = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "/home/${cfg.mainuser}";
|
default = "/home/${cfg.${name}.mainuser}";
|
||||||
description = "Path to home user folder relative to persistRoot";
|
description = "Path to home user folder relative to persistRoot";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -162,107 +141,35 @@ in{
|
|||||||
default = false;
|
default = false;
|
||||||
description = "Copy bootx64.efi to windows efi location (EFI/Microsoft/Boot/bootmgr.efi)";
|
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}" = {
|
mkService = name: opt: {
|
||||||
description = "NixOS Autoinstall";
|
description = "Autoinstall NixOS on ${name}";
|
||||||
# wantedBy = [ "multi-user.target" ];
|
# wantedBy = [ "multi-user.target" ];
|
||||||
# after = [ "network.target" "polkit.service" ];
|
# after = [ "network.target" "polkit.service" ];
|
||||||
path = with pkgs; [
|
path = with pkgs; [
|
||||||
"/run/current-system/sw/"
|
"/run/current-system/sw/"
|
||||||
"/usr/bin/"
|
"/usr/bin/"
|
||||||
"${systemd}/bin/"
|
"${systemd}/bin/"
|
||||||
"${git}/bin"
|
"${git}/bin"
|
||||||
];
|
];
|
||||||
script = with pkgs; (builtins.readFile ./autoinstall.sh);
|
script = import ./install.nix {
|
||||||
environment = config.nix.envVars // rec {
|
inherit lib; inherit opt; hostname = name;
|
||||||
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"; };
|
|
||||||
};
|
};
|
||||||
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
393
modules/autoinstall/install.nix
Executable file
393
modules/autoinstall/install.nix
Executable file
@ -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 <<CONFIG > "$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 <<CONFIG > "$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
|
||||||
|
''
|
Loading…
x
Reference in New Issue
Block a user