Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UEFI support (rebased) #34

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
/latest-iso-graphical-x86_64-linux
/nixos-in-place-test
.vagrant
*.iso
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ old system and all your old files still exist and are setup to mount on
`/old-root/nixos` and `/` is rebound before spinning up the system; everything
else in `/old-root` is fair game to delete.

NixOS installs GRUB2 on top of your existing boot loader. If you'd like to boot
into `/old-root`, you can; you just need to add the GRUB entry, from
If your system boots using MBR, NixOS installs GRUB2 on top of your existing boot loader.
If you'd like to boot into `/old-root`, you can; you just need to add the GRUB entry, from
`/old-root/boot/grub`, manually in your Nix files.

If your system boots using UEFI, NixOS adds systemd-boot efi image to your
efi system partition, so your bios should let you choose between your old efi
image and systemd-boot.

## Platform-specifics
### Digital Ocean
For use on DO droplets, follow the normal steps for your platform (Debian has
Expand Down
66 changes: 50 additions & 16 deletions install
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,46 @@ check_existence "unsquashfs"
check_existence "mktemp"
check_existence "id"
check_existence "sha256sum"
check_existence "head"
check_existence "tail"
check_existence "fdisk"
check_existence "cat"
log_end "seems sane"

if [ -d /sys/firmware/efi ];
then
log "UEFI systems are not supported yet. See issue #30 on github." >&2
exit 1
fi

## Setup essential variables; allow overriding with input
root_mount=$(mount | grep "/ " | sed 's/ /\n/' | head -n1)
root_type=$(mount | grep -Eo "/ type \w+" | sed 's/ /\n/g' | tail -n1)
if grep '/dev/nvme' <<< $root_mount >/dev/null; then
grub_device=$(echo $root_mount | sed "s|p[0-9]\+$||");
elif grep '/dev/sd' <<< $root_mount >/dev/null; then
grub_device=$(echo $root_mount | sed "s|[0-9]\+||");
elif grep '/dev/vd' <<< $root_mount >/dev/null; then
grub_device=$(echo $root_mount | sed "s|[0-9]\+||");

expect_one_line() {
ERROR_MESSAGE_ZERO=$1
ERROR_MESSAGE_MULTIPLE=$2
(set -eu;
IFS='' read -r x || (echo "$ERROR_MESSAGE_ZERO" >& 2; exit 1)
(! IFS='' read -r) || (echo "$ERROR_MESSAGE_MULTIPLE" >& 2; exit 1)
printf "%s\n" "$x");
}

if [ -d /sys/firmware/efi ]; then
boot_type=uefi
boot_device=$(
set -euo pipefail
fdisk -l -o 'Device,Type' |
grep 'EFI System' |
sed -r 's_([^ ]*) *EFI System$_\1_' |
expect_one_line \
"Fdisk found no EFI System Partitions: please specify with -g option" \
"Found multiple EFI System Partitions: please specify with -g option")
else
log "Unable to determine your grub boot device! Please specify with the -g option."
boot_type=mbr
if grep '/dev/nvme' <<< $root_mount >/dev/null; then
boot_device=$(echo $root_mount | sed "s|p[0-9]\+$||");
elif grep '/dev/sd' <<< $root_mount >/dev/null; then
boot_device=$(echo $root_mount | sed "s|[0-9]\+||");
elif grep '/dev/vd' <<< $root_mount >/dev/null; then
boot_device=$(echo $root_mount | sed "s|[0-9]\+||");
else
log "Unable to determine your grub boot device! Please specify with the -g option."
fi
fi
working_directory=$(mktemp -d)

Expand Down Expand Up @@ -66,7 +87,7 @@ digitalocean=false
while getopts ":g:r:t:Gdw:c:h" opt; do
case $opt in
g)
grub_device=$OPTARG
boot_device=$OPTARG
;;
r)
root_mount=$OPTARG
Expand Down Expand Up @@ -127,9 +148,22 @@ then
fi
fi

boot_description=$(
case $boot_type in
uefi)
echo "uefi boot with esp at $boot_device"
;;
mbr)
echo "mbr at $boot_device"
;;
*)
echo "bad boot type" >&2
exit 1
;;
esac)
## Give one last chance to back out
log "NixOS installer (nixos-in-place)"
log " GRUB => $grub_device"
log " Boot => $boot_description"
log " Root => $root_mount ($root_type)"
log " ISO => $iso"
log " Digital Ocean => $digitalocean"
Expand Down Expand Up @@ -164,7 +198,7 @@ pushd "$working_directory"

## Setup the chroot environment before install
log "Embarking stage1!"
"$here/stage1" "$here" "$root_mount" "$root_type" "$grub_device" "$digitalocean" "$extra_config"
"$here/stage1" "$here" "$root_mount" "$root_type" "$boot_type" "$boot_device" "$digitalocean" "$extra_config"

## Minimize residual space usage
# /var/empty is immutable https://github.com/NixOS/nixpkgs/pull/18365
Expand Down
23 changes: 19 additions & 4 deletions stage1
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ set -eu
here=$1
root_mount=$2
root_type=$3
grub_device=$4
digitalocean=$5
extra_config=$6
boot_type=$4
boot_device=$5
digitalocean=$6
extra_config=$7

## Bring in some helper functions
. "$here/util"
Expand All @@ -29,7 +30,7 @@ log_end "$BASH"

## Don't run systemd on chroot start, run our stage2 script
log "Patching init"
sed -i "s,exec systemd,exec /$BASH -i /nixos-in-place/stage2 $root_mount $root_type $grub_device $digitalocean," "$INIT"
sed -i "s,exec systemd,exec /$BASH -i /nixos-in-place/stage2 $root_mount $root_type $boot_type $boot_device $digitalocean," "$INIT"
sed -i "s,starting systemd,starting /nixos-in-place/stage2," "$INIT"

## Don't try to remount / since we didn't do a proper phase 1
Expand All @@ -44,6 +45,19 @@ mount --bind /nixos nixos
mkdir -p nixos-in-place
mount --bind "$here" nixos-in-place

case "$boot_type" in
mbr)
true
;;
uefi)
(ls -1 /sys/firmware/efi/efivars | grep -q .) || mount -t efivarfs efivarfs /sys/firmware/efi/efivars
mkdir -p nixos/boot
mount "$boot_device" nixos/boot
;;
*)
echo "bad boot type" >&2
exit 1
esac
## Copy extra config, if it exists
if [ ! "$extra_config"x = "x" ];
then
Expand All @@ -56,6 +70,7 @@ chroot . "/$INIT"

## Various platforms use different flags; just try what we can to clean up
log "Cleaning up mounts"
umount -f nixos/boot >/dev/null 2>&1 || true
umount -fR nixos >/dev/null 2>&1 || true
umount -f nixos >/dev/null 2>&1 || true
umount -f nixos-in-place >/dev/null 2>&1 || true
Expand Down
21 changes: 18 additions & 3 deletions stage2
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ set -eu

root_mount=$1
root_type=$2
grub_device=$3
digitalocean=$4
boot_type=$3
boot_device=$4
digitalocean=$5
digitalocean_configs=""

if [ "$digitalocean" = "true" ];
Expand Down Expand Up @@ -47,12 +48,26 @@ nix-env -i pcre
## Generate a base config
nixos-generate-config --root /nixos

grub_device_config=$(
case "$boot_type" in
mbr)
echo "boot.loader.grub.device = \"$boot_device\";\n"
;;
uefi)
true
;;
*)
echo "bad boot type" >&2
exit 1
;;
esac)

cat <<EOF > /nixos/etc/nixos/nixos-in-place.nix
{ config, pkgs, ... }:
{
## Everything below is generated from nixos-in-place; modify with caution!
boot.kernelParams = ["boot.shell_on_fail"];
boot.loader.grub.device = "$grub_device";
$grub_device_config
boot.loader.grub.storePath = "/nixos/nix/store";
boot.initrd.supportedFilesystems = [ "$root_type" ];
boot.initrd.postDeviceCommands = ''
Expand Down
2 changes: 1 addition & 1 deletion util
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ show_help()
log "usage: $0 [OPTION...]"
log
log " -h Show this help message"
log " -g <dev> Set GRUB target device (default: ${grub_device:-undefined})"
log " -g <dev> Set boot device (a device with MBR or EFI System Partition) (default: ${boot_device:-undefined})"
log " -r <dev> Set root filesystem target device (default: ${root_mount:-undefined})"
log " -t <type> Set root filesystem type (default: ${root_type:-undefined})"
log " -G Use the graphical NixOS ISO (default: ${iso:-undefined})"
Expand Down