mirror of
https://github.com/NiklasGollenstede/nixos-installer.git
synced 2025-08-09 07:31:24 +02:00
make partitioning reproducible, add sgdisk patch,
do partitioning during build instead of install, fix qemu's efi vars, add config.wip.dropbear.hostKeys
This commit is contained in:
@ -46,13 +46,15 @@ function partition-disks { { # 1: diskPaths
|
||||
|
||||
local name ; for name in "@{!config.wip.fs.disks.devices[@]}" ; do
|
||||
if [[ ! ${blockDevs[$name]:-} ]] ; then echo "Path for block device $name not provided" ; exit 1 ; fi
|
||||
eval 'local -A disk='"@{config.wip.fs.disks.devices[$name]}"
|
||||
if [[ ${blockDevs[$name]} != /dev/* ]] ; then
|
||||
local outFile=${blockDevs[$name]} ; ( set -eu
|
||||
eval 'declare -A disk='"@{config.wip.fs.disks.devices[$name]}"
|
||||
install -o root -g root -m 640 -T /dev/null "$outFile" && truncate -s "${disk[size]}" "$outFile"
|
||||
) && blockDevs[$name]=$(losetup --show -f "$outFile") && prepend_trap "losetup -d '${blockDevs[$name]}'" EXIT # NOTE: this must not be inside a sub-shell!
|
||||
local outFile=${blockDevs[$name]} &&
|
||||
install -o root -g root -m 640 -T /dev/null "$outFile" && truncate -s "${disk[size]}" "$outFile" &&
|
||||
blockDevs[$name]=$(losetup --show -f "$outFile") && prepend_trap "losetup -d '${blockDevs[$name]}'" EXIT # NOTE: this must not be inside a sub-shell!
|
||||
else
|
||||
if [[ ! "$(blockdev --getsize64 "${blockDevs[$name]}")" ]] ; then echo "Block device $name does not exist at ${blockDevs[$name]}" ; exit 1 ; fi
|
||||
local size=$( blockdev --getsize64 "${blockDevs[$name]}" || : )
|
||||
if [[ ! $size ]] ; then echo "Block device $name does not exist at ${blockDevs[$name]}" ; exit 1 ; fi
|
||||
if [[ $size != "${disk[size]}" ]] ; then echo "Block device ${blockDevs[$name]}'s size $size does not match the size ${disk[size]} declared for $name" ; exit 1 ; fi
|
||||
blockDevs[$name]=$(realpath "${blockDevs[$name]}")
|
||||
fi
|
||||
done
|
||||
@ -67,10 +69,12 @@ function partition-disks { { # 1: diskPaths
|
||||
for name in "@{!config.wip.fs.disks.devices[@]}" ; do
|
||||
eval 'declare -A disk='"@{config.wip.fs.disks.devices[$name]}"
|
||||
if [[ ${disk[serial]:-} ]] ; then
|
||||
actual=$(udevadm info --query=property --name="$blockDev" | grep -oP 'ID_SERIAL_SHORT=\K.*')
|
||||
if [[ ${disk[serial]} != "$actual" ]] ; then echo "Block device $blockDev does not match the serial declared for ${disk[name]}" ; exit 1 ; fi
|
||||
actual=$( udevadm info --query=property --name="$blockDev" | grep -oP 'ID_SERIAL_SHORT=\K.*' || echo '<none>' )
|
||||
if [[ ${disk[serial]} != "$actual" ]] ; then echo "Block device $blockDev's serial ($actual) does not match the serial (${disk[serial]}) declared for ${disk[name]}" ; exit 1 ; fi
|
||||
fi
|
||||
partition-disk "${disk[name]}" "${blockDevs[${disk[name]}]}"
|
||||
# can (and probably should) restore the backup:
|
||||
( PATH=@{native.gptfdisk}/bin ; set -x ; sgdisk --load-backup=@{config.wip.fs.disks.partitioning}/"${disk[name]}".backup "${blockDevs[${disk[name]}]}" >$beQuiet )
|
||||
#partition-disk "${disk[name]}" "${blockDevs[${disk[name]}]}"
|
||||
done
|
||||
@{native.parted}/bin/partprobe "${blockDevs[@]}"
|
||||
@{native.systemd}/bin/udevadm settle -t 15 || true # sometimes partitions aren't quite made available yet
|
||||
@ -83,16 +87,28 @@ function partition-disks { { # 1: diskPaths
|
||||
function partition-disk {( set -eu # 1: name, 2: blockDev, 3?: devSize
|
||||
name=$1 ; blockDev=$2
|
||||
eval 'declare -A disk='"@{config.wip.fs.disks.devices[$name]}"
|
||||
devSize=${3:-$(@{native.util-linux}/bin/blockdev --getsize64 "$blockDev")}
|
||||
devSize=${3:-$( @{native.util-linux}/bin/blockdev --getsize64 "$blockDev" )}
|
||||
|
||||
declare -a sgdisk=( --zap-all ) # delete existing part tables
|
||||
if [[ ${disk[gptOffset]} != 0 ]] ; then
|
||||
sgdisk+=( --move-main-table=$(( 2 + ${disk[gptOffset]} )) ) # this is incorrectly documented as --adjust-main-table in the man pages (at least versions 1.05 to 1.09 incl)
|
||||
sgdisk+=( --move-secondary-table=$(( devSize/512 - 1 - 32 - ${disk[gptOffset]} )) )
|
||||
fi
|
||||
sgdisk+=( --disk-guid="${disk[guid]}" )
|
||||
|
||||
for partDecl in "@{config.wip.fs.disks.partitionList[@]}" ; do
|
||||
eval 'declare -A part='"$partDecl"
|
||||
if [[ ${part[disk]} != "${disk[name]}" ]] ; then continue ; fi
|
||||
if [[ ${part[size]:-} =~ ^[0-9]+%$ ]] ; then
|
||||
part[size]=$(( $devSize / 1024 * ${part[size]:0:(-1)} / 100 ))K
|
||||
fi
|
||||
sgdisk+=( -a "${part[alignment]:-${disk[alignment]}}" -n "${part[index]:-0}":"${part[position]}":+"${part[size]:-}" -t 0:"${part[type]}" -c 0:"${part[name]}" )
|
||||
sgdisk+=(
|
||||
--set-alignment="${part[alignment]:-${disk[alignment]}}"
|
||||
--new="${part[index]:-0}":"${part[position]}":+"${part[size]:-}"
|
||||
--partition-guid=0:"${part[guid]}"
|
||||
--typecode=0:"${part[type]}"
|
||||
--change-name=0:"${part[name]}"
|
||||
)
|
||||
done
|
||||
|
||||
if [[ ${disk[mbrParts]:-} ]] ; then
|
||||
|
@ -67,8 +67,12 @@ function run-qemu {( set -eu # 1: diskImages
|
||||
qemu+=( -drive format=raw,file="${decl/*=/}" ) #,if=none,index=0,media=disk,id=disk0 -device "virtio-blk-pci,drive=disk0,disable-modern=on,disable-legacy=off" )
|
||||
done
|
||||
|
||||
if [[ @{config.boot.loader.systemd-boot.enable} || ${args[efi]:-} ]] ; then
|
||||
qemu+=( -bios @{pkgs.OVMF.fd}/FV/OVMF.fd ) # UEFI. Otherwise it boots something much like a classic BIOS?
|
||||
if [[ @{config.boot.loader.systemd-boot.enable} || ${args[efi]:-} ]] ; then # UEFI. Otherwise it boots something much like a classic BIOS?
|
||||
#qemu+=( -bios @{pkgs.OVMF.fd}/FV/OVMF.fd ) # This works, but is a legacy fallback that stores the EFI vars in /NvVars on the EFI partition (which is really bad).
|
||||
qemu+=( -drive file=@{pkgs.OVMF.fd}/FV/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on )
|
||||
qemu+=( -drive file=/tmp/qemu-@{config.networking.hostName}-VARS.fd,if=pflash,format=raw,unit=1 )
|
||||
if [[ ! -e /tmp/qemu-@{config.networking.hostName}-VARS.fd ]] ; then cat @{pkgs.OVMF.fd}/FV/OVMF_VARS.fd > /tmp/qemu-@{config.networking.hostName}-VARS.fd ; fi
|
||||
# https://lists.gnu.org/archive/html/qemu-discuss/2018-04/msg00045.html
|
||||
fi
|
||||
if [[ @{config.preface.hardware} == aarch64 ]] ; then
|
||||
qemu+=( -kernel @{config.system.build.kernel}/Image -initrd @{config.system.build.initialRamdisk}/initrd -append "$(echo -n "@{config.boot.kernelParams[@]}")" )
|
||||
@ -79,7 +83,7 @@ function run-qemu {( set -eu # 1: diskImages
|
||||
fi ; done
|
||||
|
||||
if [[ ! ${args[no-nat]:-} ]] ; then
|
||||
qemu+=( -nic user,model=virtio-net-pci ) # NATed, IPs: 10.0.2.15+/32, gateway: 10.0.2.2
|
||||
qemu+=( -nic user,model=virtio-net-pci${args[nat-fw]:+,hostfwd=tcp::${args[nat-fw]//,/,hostfwd=tcp::}} ) # NATed, IPs: 10.0.2.15+/32, gateway: 10.0.2.2
|
||||
fi
|
||||
|
||||
# TODO: network bridging:
|
||||
@ -91,7 +95,11 @@ function run-qemu {( set -eu # 1: diskImages
|
||||
qemu+=( -usb -device usb-host,hostbus="${decl/-*/}",hostport="${decl/*-/}" )
|
||||
done ; fi
|
||||
|
||||
( set -x ; "${qemu[@]}" )
|
||||
if [[ ${args[dry-run]:-} ]] ; then
|
||||
( echo "${qemu[@]}" )
|
||||
else
|
||||
( set -x ; "${qemu[@]}" )
|
||||
fi
|
||||
|
||||
# https://askubuntu.com/questions/54814/how-can-i-ctrl-alt-f-to-get-to-a-tty-in-a-qemu-session
|
||||
|
||||
@ -107,7 +115,6 @@ function add-bootkey-to-keydev {( set -eu # 1: blockDev, 2?: hostHash
|
||||
</dev/urandom tr -dc 0-9a-f | head -c 512 >/dev/disk/by-partlabel/"$bootkeyPartlabel"
|
||||
)}
|
||||
|
||||
|
||||
## Tries to open and mount the systems keystore from its LUKS partition. If successful, adds the traps to close it when the parent shell exits.
|
||||
# See »open-system«'s implementation for some example calls to this function.
|
||||
function mount-keystore-luks { # ...: cryptsetupOptions
|
||||
@ -141,7 +148,7 @@ function open-system { # 1?: diskImages
|
||||
( @{native.systemd}/bin/udevadm settle -t 15 || true ) && # sometimes partitions aren't quite made available yet
|
||||
|
||||
if [[ @{config.wip.fs.keystore.enable} && ! -e /dev/mapper/keystore-@{config.networking.hostName!hashString.sha256:0:8} ]] ; then # Try a bunch of approaches for opening the keystore:
|
||||
mount-keystore-luks --key-file=<(printf %s "@{config.networking.hostName}") ||
|
||||
mount-keystore-luks --key-file=<( printf %s "@{config.networking.hostName}" ) ||
|
||||
mount-keystore-luks --key-file=/dev/disk/by-partlabel/bootkey-@{config.networking.hostName!hashString.sha256:0:8} ||
|
||||
mount-keystore-luks --key-file=<( read -s -p PIN: pin && echo ' touch!' >&2 && ykchalresp -2 "$pin" ) ||
|
||||
# TODO: try static yubikey challenge
|
||||
|
Reference in New Issue
Block a user