better support for systems with no pxe
authorIan Kelling <ian@iankelling.org>
Tue, 11 Oct 2016 05:08:12 +0000 (22:08 -0700)
committerIan Kelling <ian@iankelling.org>
Mon, 6 Feb 2017 06:21:41 +0000 (22:21 -0800)
18 files changed:
README
arch-pxe
debian-pxe-preseed
dsfull
fai-revm
fai/config/distro-install-common/libreboot_grub.cfg [new file with mode: 0644]
fai/config/files/etc/apt/preferences.d/testing/LINODESTABLE [moved from fai/config/files/etc/apt/preferences/LINODESTABLE with 100% similarity]
fai/config/files/etc/apt/preferences.d/testing/STABLE [moved from fai/config/files/etc/apt/preferences/STABLE with 100% similarity]
fai/config/files/etc/systemd/system/fai_check.service/STABLE_BOOTSTRAP [new file with mode: 0644]
fai/config/files/root/fai-check/STABLE_BOOTSTRAP [new file with mode: 0755]
fai/config/hooks/partition.DEFAULT
fai/config/scripts/GRUB_PC/11-ian
faiserver-revm
faiserver-setup
myfai-chboot [new file with mode: 0755]
myfai-chboot-local [new file with mode: 0755]
pxe-server
ubuntu-xenial-live-fai-kexec [new file with mode: 0644]

diff --git a/README b/README
index b53550723c17c7fe98bb6ca670b9dfa6bb97fe5c..b7bfa78746e19e68d69076b90b4abb8f423ef67f 100644 (file)
--- a/README
+++ b/README
@@ -1,28 +1,28 @@
 Multi-boot/distro btrfs provisioning
 
-Some things are specific to my home network. Uses PXE, designed for bare
-metal but also works for pxe booted VM.
-
-Features people may find useful: installs encrypted arch, debian stable,
-& debian testing all on the same btrfs filesystem, smartly utilizing
-multiple disks, with scripts to automatically decrypt on reboots. The
-partititioning and filesystem script is the biggest part and is at
-fai/config/hooks/partition.DEFAULT. Other debian based distros should
-work fine, and I'm planning to add Fedora support. Disks are grouped as
-ssd or hdd and raided in raid 1 or raid 0 per configuration. The base
-partitions are divided into boot, swap, and root, (only boot is
-unencrypted). There are scripts to resize those partitions
-post-provision and while the system is running.
-
-The repo name fai is copied from a project of the same name which this
-project uses for debian installs. It stands for "fully automated
-installer."
+Some things are specific to my home network. Uses pxe or pxe-kexec (for
+systems like libreboot with no pxe rom, we boot into a live cd or distro
+for bootsraping). Works for bare-metal or vms.
+
+Features people may find useful: installs encrypted trisquel belanos,
+arch, debian stable, & debian testing all on the same btrfs filesystem.
+Smartly utilizes multiple disks, with scripts to automatically decrypt
+on reboots. The partititioning and filesystem script is at
+fai/config/hooks/partition.DEFAULT. Other debian based distros at least
+as new as ubuntu 14.04 should work fine, and I'm planning to add Fedora
+support. Disks are grouped as ssd or hdd and raided in raid 1 or raid 0
+per configuration. The base partitions are divided into boot, swap, and
+root, (only boot is unencrypted). There are scripts to resize those
+partitions post-provision and while the system is running.
+
+The repo name fai is copied from the debian project of the same name,
+meaning "fully automated installer."
 
 It also fully automates configuration of an openwrt router after manual
 initial installation.
 
-Provisionining is done, I sync files using unison, then automate further
-setup using a different set of scripts,
+After provisionining is done, I sync files using unison, then automate
+further setup using a different set of scripts,
 https://iankelling.org/git/?p=distro-setup;a=tree.
 
 My network is a wndr3700v2 router with openwrt on it and a few pcs/laptops.
@@ -47,6 +47,8 @@ faiserver-setup # install fai-server on the current machine
 fresize # resize swap or boot partitions in a host
 pxe-server # temporarily enable (usually) fai or arch boot server
 wrt-setup-remote  # setup my router
+ubuntu-xenial-live-fai-kexec # do fai install from xenial live cd using kexec
+myfai-chboot # use instead of pxe-server for fai kexec based install
 
 License stuff:
 The license for the project is GPLv2 or later, mostly because fai is
index 78c31066c7099c9c15d70e2428a2ef4f32f0ddfb..5a26fd70a7f97c9a66bc4035907f15a69ed8ce96 100755 (executable)
--- a/arch-pxe
+++ b/arch-pxe
@@ -59,7 +59,7 @@ ssh wrt "cd /mnt/usb && rm -f tftpboot && ln -s $iso tftpboot"
 
 # The default settings in the installer expect to find the NFS at /run/archiso/bootmnt
 
-pxe-server arch
+pxe-server default arch
 
 # background:
 # great documentation at https://wiki.archlinux.org/index.php/PXE
index f97319451cbcc9352c1fdfbad32ba816e6c36ac8..c2a2087cc683c4d441c48230199840a97593d2f1 100755 (executable)
@@ -44,4 +44,4 @@ e ln -s debian-wheezy tftpboot
 
 cd /
 e umount $mount_dir
-e $src/pxe-server -p plain # my script
+e $src/pxe-server default plain # my script
diff --git a/dsfull b/dsfull
index 814300e02c523eabe38d5f0b4997a0538040a748..51ecdda5013c6101e788d5f31383f4b900d4c691 100755 (executable)
--- a/dsfull
+++ b/dsfull
@@ -26,7 +26,7 @@ fi
 set -x
 
 cleanup() { pxe-server :; }
-pxe-server fai $host
+pxe-server $host fai
 
 
 if $reboot; then
@@ -34,7 +34,7 @@ if $reboot; then
     ssh $host "touch /tmp/keyscript-off; sudo reboot" ||: &
 fi
 
-pxe-server -a :
+pxe-server -a
 cleanup() { :; }
 
 error=true
index fcb9c073a58e0c74ba2702f490f0d82f4a53670e..97b6338ff1f97e9d64871c39ed9f628c98d6c132 100755 (executable)
--- a/fai-revm
+++ b/fai-revm
@@ -79,14 +79,14 @@ is_arch_revm() {
     [[ ${0##*/} == arch-revm ]]
 }
 
-cleanup() { ./pxe-server :; }
+cleanup() { ./pxe-server; }
 if is_arch_revm; then
-    ./pxe-server arch
+    ./pxe-server demohost arch
     sleep 2
     # via osinfo-query os. guessing arch is closest to latest fedora.
     variant=fedora22
 else
-    ./pxe-server fai
+    ./pxe-server demohost fai
     sleep 2
     # I don't think these variants actually make a diff for us, but I
     # use the appropriate one when trying a new distro just in case.
@@ -132,7 +132,7 @@ while ! timeout -s 9 10 ssh root@$name /bin/true; do
     e sleep 5
 done
 cleanup() { :; }
-e pxe-server :
+e pxe-server
 if is_arch_revm; then
     ./arch-init-remote $name
 fi
diff --git a/fai/config/distro-install-common/libreboot_grub.cfg b/fai/config/distro-install-common/libreboot_grub.cfg
new file mode 100644 (file)
index 0000000..b48ea52
--- /dev/null
@@ -0,0 +1,58 @@
+#!/bin/sh
+# shebang is for editor file mode detection only
+
+function save_vars {
+    if [ -s $envfile ]; then
+        for var in $@; do
+            save_env --file $envfile $var
+        done
+    fi
+}
+
+function save_chosen {
+    last_boot=$CHOSEN
+    save_vars did_fai_check last_boot
+}
+
+# we don't set this to fai check so we can't get into
+# an infinite reboot cycle. We depend on the os to
+# create the initial grubenv file.
+set default=/debianstable_bootstrap # could use 0 here.
+set timeout=1
+
+for part in (ahci*4) (ata*4); do
+    envfile=$part/grubenv
+    if [ -s $envfile ]; then
+        load_env --file $envfile
+        if [ x$did_fai_check != xtrue -a x$last_boot != x$default ]; then
+            set default=fai-check
+        elif [ ! -z $last_boot ]; then
+            set default=$last_boot
+        fi
+        break
+    fi
+done
+
+did_fai_check=false
+
+bs_dir=/debianstable_bootstrap
+menuentry $bs_dir --id=$bs_dir {
+    save_chosen
+    configfile $bs_dir/boot/grub/grub.cfg
+}
+
+for dir in  /boot_*; do
+    if [ $dir == '/boot_*' ]; then
+        break
+    fi
+    menuentry $dir --id=$dir {
+        save_chosen
+        configfile $1/grub/grub.cfg
+    }
+done
+
+menuentry fai-check --id=fai-check {
+    did_fai_check=true
+    save_vars did_fai_check
+    configfile $bs_dir/boot/grub/grub.cfg
+}
diff --git a/fai/config/files/etc/systemd/system/fai_check.service/STABLE_BOOTSTRAP b/fai/config/files/etc/systemd/system/fai_check.service/STABLE_BOOTSTRAP
new file mode 100644 (file)
index 0000000..2328452
--- /dev/null
@@ -0,0 +1,9 @@
+[Unit]
+Description=check whether to kexec to fai, reboot, or do nothing
+
+[Service]
+Type=oneshot
+ExecStart=/root/fai-check
+
+[Install]
+WantedBy=multi-user.target
diff --git a/fai/config/files/root/fai-check/STABLE_BOOTSTRAP b/fai/config/files/root/fai-check/STABLE_BOOTSTRAP
new file mode 100755 (executable)
index 0000000..29bb1fb
--- /dev/null
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
+
+fai_check=false
+check-fai() {
+    # we could just as well check if last_boot != /debianstable_boostrap
+    # the intent with this one is just a little clearer.
+    if [[ $did_fai_check == true ]]; then
+        fai_check=true
+        pxe-kexec -n --ignore-whitelist -l fai-generated faiserver ||:
+    else
+        return 0
+    fi
+}
+
+first=true
+for dev in $(btrfs fi show / | sed -rn 's#^\s*devid\s.*\s([^0-9 ]+)\S+$#\1#p' \
+                 |sort); do
+    dev+=4
+    mount $dev /mnt
+    if $first; then
+        if [[ -e /mnt/grubenv ]]; then
+            source <(grub-editenv /mnt/grubenv list)
+        fi
+        first=false
+        check-fai
+    else
+        # we make sure there is only 1 grubenv,
+        # so grub can just find the first one, in whatever order
+        # if looks at them, which may not be the same as us.
+        # If the disk dies, we just lose the default boot option,
+        # we will have to do manual steps to replace it anyways.
+        rm -f /mnt/gruvenv
+    fi
+    umount /mnt
+done
+
+if $fai_check && [[ $last_boot != /debianstable_boostrap ]]; then
+    # no need to reboot if we actually want to boot into this os.
+    reboot
+fi
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
index 3be239f424b1de99488e31aefaf555ef1a885adf..199e4f860745ac55c1eb4ac23fc3509d08cfcb58 100755 (executable)
@@ -8,9 +8,10 @@ if [[ $EUID != 0 ]]; then
   exit 1
 fi
 
-# note:
-# fcopy -i = ignore nonmatching class error, always return 0.
-fcopy -riM /root/.ssh
+
+if ! type -t fcopy &>/dev/null; then
+  sudo apt-get -y install fai-client
+fi
 
 chroot $FAI_ROOT bash <<'EOFOUTER'
 debconf-set-selections <<EOF
@@ -19,14 +20,17 @@ EOF
 apt-get install -y pxe-kexec
 EOFOUTER
 
+# note: # fcopy -i = ignore nonmatching class error, always return 0.
+# this is also done by FABASE/10-misc by default.
+fcopy -ir /root
 if ifclass STABLE_BOOTSTRAP; then
+  fcopy -ri /etc/systemd/system
+  chroot $FAI_ROOT bash <<'EOFOUTER'
+systemctl enable fai_check.service
+EOFOUTER
   exit 0
 fi
 
-if ! type -t fcopy &>/dev/null; then
-  sudo apt-get -y install fai-client
-fi
-
 dir=/q/root/shadow
 fai_shadow=$FAI/distro-install-common/shadow
 if [[ ! -e $dir && -e $fai_shadow ]]; then
@@ -35,19 +39,15 @@ if [[ ! -e $dir && -e $fai_shadow ]]; then
 fi
 $FAI/distro-install-common/end
 
-if ifclass STABLE || ifclass LINODESTABLE; then
-  fcopy -M /etc/apt/preferences
-fi
 
-if ifclass DEBIAN; then
-  fcopy -M /etc/apt/preferences.d/unstable
-fi
-fcopy -riM /etc/apt/sources.list.d
+# these get copied in an earlier stage by fai, but leaving it here since
+# I run this as a single post-fai script to update things that have changed.
+fcopy -ri /etc/apt/preferences.d
+fcopy -ri /etc/apt/sources.list.d
 $ROOTCMD apt-get update
 
 
 
-
 rm -f $FAI_ROOT/etc/apt/sources.list
 
 chroot $FAI_ROOT bash <<'EOF'
@@ -91,4 +91,3 @@ EOF
 for g in plugdev audio video cdrom; do
     $ROOTCMD usermod -a -G $g traci
 done
-
index 1065f3b84b45fd3648114aa6c74ce2819f153c82..78427231df54960f855e2c15b5738c20488742a8 100755 (executable)
@@ -34,6 +34,6 @@ done
 
 # note: with a vm, pxe boot is turned off in the bios after it's first reboot.
 cleanup() { :; }
-./pxe-server :
+./pxe-server
 
 ssh $opts root@faiserver ./faiserver-setup
index 18933bbf586aea2d060a4b8ac1fbefa92c661010..e43d0192f79eed094432471a95f52da8bb5c5dd5 100755 (executable)
@@ -108,17 +108,6 @@ e fai-setup -vf
 
 # Add debug to -f flag for more verbose output.
 
-std_arg="-u nfs://faiserver/srv/fai/config"
-e fai-chboot -Iv $std_arg default # reset so we are idempotent
-kernel=$(fai-chboot -L '^default$' | awk '{print $3}')
-type -t host &>/dev/null || apt-get -y install dnsutils
-# resolve host using gateway address
-my_ip=$(host faiserver $(route -n | sed -rn 's/^(0\.){3}0\s+(\S+).*/\2/p') | \
-            sed -rn 's/^\S+ has address //p')
-k_args=$(fai-chboot -L '^default$' | \
-             sed -r "s/^(\S+\s+){3}(.*root=)(.*)/\2$my_ip:\3/")
-e fai-chboot -k "$k_args" -v -f verbose,sshd,createvt,reboot $std_arg $kernel default
-
 # make the faiserver also the apt proxy server
 apt-get -y install apt-cacher-ng
 
diff --git a/myfai-chboot b/myfai-chboot
new file mode 100755 (executable)
index 0000000..e216aa0
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
+
+
+usage() {
+    cat <<'EOF'
+usage $0 [hostname|ip|default]...
+
+Sets up tftp pxe config. No argument disables for all hosts.
+EOF
+    exit $1
+}
+
+cd "${BASH_SOURCE%/*}" # directory of the script
+
+ssh root@faiserver bash -s "$@" <myfai-chboot-local
diff --git a/myfai-chboot-local b/myfai-chboot-local
new file mode 100755 (executable)
index 0000000..74600d5
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
+
+[[ $EUID == 0 ]] || exec sudo "${BASH_SOURCE}" "$@"
+
+e() { echo "$@"; "$@"; }
+
+
+rm -f /srv/tftp/fai/pxelinux.cfg/*
+if [[ ! $1 ]]; then
+    exit 0
+fi
+
+std_arg="-u nfs://faiserver/srv/fai/config"
+e fai-chboot -Iv $std_arg default # set it to default to get a val out of it next
+kernel=$(fai-chboot -L '^default$' | awk '{print $3}')
+# man page doesn't explain this, but this deletes & thus disables
+# all chboot systems.
+rm -f /srv/tftp/fai/pxelinux.cfg/*
+type -t host &>/dev/null || apt-get -y install dnsutils
+gateway_ip=$(route -n | sed -rn 's/^(0\.){3}0\s+(\S+).*/\2/p')
+my_ip=$(host faiserver $gateway_ip | sed -rn 's/^\S+ has address //p')
+k_args=$(fai-chboot -L '^default$' | \
+             sed -r "s/^(\S+\s+){3}(.*root=)(.*)/\2$my_ip:\3/")
+e fai-chboot -k "$k_args" -v -f verbose,sshd,createvt,reboot $std_arg $kernel "$@"
+
+
+# todo, remove the nopxe script. adjust fai-check to reboot if it fails on the kexec.
index d8cbeb819b03bc134245ba0ec484f03577cf3114..6adbf19214286141b7622392f3ceff35226a1f5d 100755 (executable)
@@ -28,11 +28,11 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
 
 usage() {
     cat <<EOF
-Usage: ${0##*/} [OPTIONS] TYPE [HOST]
+Usage: ${0##*/} [OPTIONS] [HOST TYPE]
 One line description
 
-TYPE is one of arch, plain, fai, or : for no pxe server.
-HOST makes the pxe server only for that specific host
+TYPE is one of arch, plain, fai.
+HOST is a hostname known to the dhcp server, or default for all, or none to disable
 
 -r         Don't redeploy fai config.
 -a         Wait for 2 dhcp acks, then disable the pxe server after a delay.
@@ -68,12 +68,16 @@ while true; do
     esac
 done
 
-read type host <<<"$@"
+read host type <<<"$@"
 
-if [[ ! $type ]]; then
-    echo "$0: error: exptected 1 argument of type"
-    usage 1
-fi
+case $# in
+    0|2);;
+    *)
+        echo "$0: error: expected 0 or 2 arguments"
+        echo
+        usage 1
+        ;;
+esac
 
 if [[ $host ]]; then
     host_tag="tag:$host,"
@@ -127,19 +131,22 @@ ack-wait() {
 }
 
 set-pxe() {
-    ${1:-$type} | ssh wrt "cedit pxe-server /etc/dnsmasq.conf || /etc/init.d/dnsmasq restart
-if [[ $type == arch ]]; then arch-pxe-mount; fi"
+    ${type:-:}|ssh wrt "cedit pxe /etc/dnsmasq.conf || /etc/init.d/dnsmasq restart
+$([[ $type == arch ]] && echo arch-pxe-mount)"
 }
 
 
 if $set; then
     set-pxe
-
     if [[ $type == fai ]]; then
+        myfai-chboot $host
         if $redep; then
             fai-redep
         fi
         faiserver-enable
+    else
+        myfai-chboot
+        faiserver-disable
     fi
 fi
 
@@ -150,7 +157,7 @@ if $wait; then
     # bleh.
     echo "waiting for $acks dhcp acks then disabling pxe"
     ack-wait $acks
-    set-pxe :
+    set-pxe
 
     # previously tried waiting for one more ack then disabling faiserver,
     # since it can contain sensitive info, so turn it off when not in use,
diff --git a/ubuntu-xenial-live-fai-kexec b/ubuntu-xenial-live-fai-kexec
new file mode 100644 (file)
index 0000000..c44e9b2
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/bash
+# You can copy this to a http server, then curl url|sudo bash
+
+set -ex
+sed -ri '/^\s*deb\s+http/s/$/ universe/' /etc/apt/sources.list
+apt-get update
+apt-get install -y debconf
+debconf-set-selections <<EOF
+kexec-tools kexec-tools/load_kexec boolean false
+EOF
+apt-get install -y pxe-kexec
+sleep 5
+pxe-kexec -n --ignore-whitelist -l fai-generated faiserver