better support for systems with no pxe
[automated-distro-installer] / fai / config / hooks / partition.DEFAULT
index f6132268ba1ed63738e8342aa6846d1ec89703e0..9905602cab65a4108057e488a06a507a1ca954b5 100755 (executable)
@@ -20,6 +20,8 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
 
 # # fai's setup-storage won't do btrfs on luks,
 # # so we do it ourself :)
+# inspiration taken from files in fai-setup-storage package
+
 
 skiptask partition || ! type skiptask # for running not in fai
 
@@ -28,7 +30,13 @@ skiptask partition || ! type skiptask # for running not in fai
 rootn=1
 swapn=2
 bootn=3
-bios_grubn=4
+# ext partition so grub can write persistent variables,
+# so it can do a one time boot.
+grub_extn=4
+# bios boot partition,
+# https://wiki.archlinux.org/index.php/GRUB
+bios_grubn=5
+lastn=$bios_grubn
 boot_mib=4000
 
 
@@ -55,7 +63,10 @@ add-part() { # add partition suffix to $dev
 bootdev() { add-part $@ $bootn; }
 rootdev() { add-part $@ $rootn; }
 swapdev() { add-part $@ $swapn; }
-bios_grubdev() { add-part $@ $bios_grubn; }
+grub_extdev() { add-part $@ $grub_extn; }
+# Commented because it's not used, but left because it
+# finishes the pattern and if we ever do need to use it, it's here.
+#bios_grubdev() { add-part $@ $bios_grubn; }
 
 crypt-dev() { echo /dev/mapper/crypt_dev_${1##*/}; }
 crypt-name() { echo crypt_dev_${1##*/}; }
@@ -73,7 +84,6 @@ else
     partition=false # change to true to force a full wipe
 fi
 
-lastn=$bios_grubn
 
 
 hdds=()
@@ -98,7 +108,7 @@ fi
 # check if the partitions exist have the right filesystems
 #blkid="$(blkid -s TYPE)"
 for dev in ${short_devs[@]}; do
-    ! $partition || break
+    if $partition; then break; fi
     y=$(readlink -f $dev)
     x=($y[0-9])
     [[ ${#x[@]}  == "${lastn}" ]] || partition=true
@@ -115,8 +125,8 @@ done
 
 if $partition && ifclass PARTITION_PROMPT; then
     echo "Press any key except ctrl-c to continue and partition these drives:"
-    echo "  ${short_devs[@]}"
-    read
+    echo "  ${short_devs[*]}"
+    read -r
 fi
 
 devs=()
@@ -126,7 +136,7 @@ for short_dev in ${short_devs[@]}; do
 done
 
 
-
+first=false
 boot_devs=()
 for dev in ${devs[@]}; do
     if ifclass frodo; then
@@ -157,6 +167,10 @@ for dev in ${devs[@]}; do
     else
         boot_devs+=(`bootdev`)
     fi
+    if [[ $boot_devs && $first ]]; then
+        first_grub_extdev=`grub_extdev`
+        first=false
+    fi
 done
 
 if [[ ! $DISTRO ]]; then
@@ -175,6 +189,7 @@ if [[ ! $DISTRO ]]; then
         exit 1
     fi
 fi
+first_boot_dev=${boot_devs[0]}
 
 
 case ${#boot_devs[@]} in
@@ -191,7 +206,6 @@ bpart() { # btrfs a partition
     esac
 }
 
-first_boot_dev=${boot_devs[0]}
 
 # keyfiles generated like:
 # head -c 2048 /dev/urandom | od | s dd of=/q/root/luks/host-demohost
@@ -214,7 +228,6 @@ fi
 
 first_root_crypt=$(root-cryptdev ${devs[0]})
 
-bios_grubn=4
 # 1.5 x based on https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Installation_Guide/sect-disk-partitioning-setup-x86.html#sect-custom-partitioning-x86
 swap_mib=$(( $(grep ^MemTotal: /proc/meminfo | \
                    awk '{print $2}') * 3/(${#devs[@]} * 2 ) / 1024 ))
@@ -252,26 +265,45 @@ if $partition; then
         parted -s $dev mklabel gpt
         # MiB because parted complains about alignment otherwise.
         pcmd="parted -a optimal -s -- $dev"
-        $pcmd mkpart primary "ext3" 4MiB ${root_end}MiB
+        $pcmd mkpart primary "ext3" 12MiB ${root_end}MiB
         $pcmd mkpart primary "linux-swap" ${root_end}MiB ${swap_end}MiB
         $pcmd mkpart primary "" ${swap_end}MiB ${disk_mib}MiB
-        # gpt ubuntu cloud image uses ~4. fai uses 1 MiB.
-        # I read something in the parted manual saying cheap flash media
-        # likes to start at 4.
+        # i only need a few k, but googling min size,
+        # I found someone saying that gparted required
+        # required at least 8 because of their hard drive cylinder size.
+        # And 8 is still very tiny.
+        $pcmd mkpart primary "ext2" 4MiB 12MiB
+        # gpt ubuntu cloud image uses ~4 mb for this partition. fai uses 1 MiB.
+        # so, I use 3, whatever.
+        # note: parted manual saying cheap flash media
+        # should to start at 4.
         $pcmd mkpart primary "" 1MiB 4MiB
         $pcmd set $bios_grubn bios_grub on
         $pcmd set $bootn boot on # generally not needed on modern systems
         # the mkfs failed before on a vm, which prompted me to add
         # sleep .1
-        # then failed on a physical machine
+        # then it failed again on a physical machine
         # with:
         # Device /dev/disk/by-id/foo doesn't exist or access denied,
-        # so here we wait.
+        # so I added a wait until it existed.
+        # Then I added the mkfs.ext2, which claimed to succeed,
+        # but then couldn't be found upon reboot. In that case we didn't
+        # wait at all. So I've added a 3 second minimum wait.
+        sleep 3
         secs=0
         while [[ ! -e `rootdev` ]] && (( secs < 10 )); do
             sleep 1
             secs=$((secs +1))
         done
+        # Holds just a single file, rarely written, so
+        # use ext2, like was often used for the /boot partition.
+        # This exists because grub can only persist data to a non-cow fs.
+        # And we use persisting a var in grub to do a one time boot.
+        # We could pass the data on the kernel command line and persist it
+        # to grubenv after booting, but that relies on the boot always succeeding.
+        # This is just a bit more robust, and it could work for booting
+        # into ipxe which can't persist data, if we ever got that working.
+        mkfs.ext2 `grub_extdev`
         yes YES | cryptsetup luksFormat `rootdev` $luks_dir/host-$HOSTNAME \
                              -c aes-cbc-essiv:sha256 -s 256 || [[ $? == 141 ]]
         yes "$lukspw" | \
@@ -296,6 +328,7 @@ if $partition; then
     bpart ${boot_devs[@]}
 else
     for dev in ${devs[@]}; do
+        mkfs.ext2 `grub_extdev`
         cryptsetup luksOpen `rootdev` `root-cryptname` \
                    --key-file $luks_dir/host-$HOSTNAME
     done
@@ -342,38 +375,11 @@ fi
 
 mount -o subvolid=0 $first_boot_dev /mnt
 cd /mnt
-btrfs subvolume set-default 0 /mnt
+btrfs subvolume set-default 0 /mnt # already default, just ensuring it.
 
-# for libreboot systems
+# for libreboot systems.
 mkdir -p /mnt/grub2
-cat >/mnt/grub2/libreboot_grub.cfg <<'EOF'
-#!/bin/sh
-# shebang is for editor file mode detection only
-
-if [ -s $prefix/grubenv ]; then
-    load_env
-fi
-
-set default="0"
-set timeout=1
-
-menuentry debianstable_bootstrap {
-    configfile /$1/boot/grub/grub.cfg
-}
-
-for dir in /boot_*; do
-    if [ x$dir = x$default_subvol ]; then
-        default=default_id
-        menuentry $dir --id=default_id {
-            configfile $1/grub/grub.cfg
-        }
-    else
-        menuentry $dir {
-            configfile $1/grub/grub.cfg
-        }
-    fi
-done
-EOF
+cp $FAI/distro-install-common/libreboot_grub.cfg /mnt/grub2
 
 if [[ $DISTRO == debianstable_bootstrap ]]; then
     # this is just convenience for the libreboot_grub config
@@ -388,6 +394,11 @@ cd /
 umount /mnt
 ## end create subvols ##
 
+dev=${boot_devs[0]}
+mount $first_grub_extdev /mnt
+grub-editenv /mnt/grubenv set did_fai_check=true
+grub-editenv /mnt/grubenv set last_boot=/$boot_vol
+umount /mnt
 
 if [[ $DISTRO == debianstable_bootstrap ]]; then
     cat > /tmp/fai/fstab <<EOF