From 5f680f6bea2faae10ca8e5ccea0d08d18ccc9aa1 Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Sun, 19 Nov 2017 12:37:56 -0500 Subject: [PATCH] various fixes and improvements --- README | 22 ++-- arch-pxe | 16 ++- bash-trace | 49 +-------- fai/config/class/50-host-classes | 3 +- .../distro-install-common/libreboot_grub.cfg | 13 +-- fai/config/files/boot/bash-trace/DEFAULT | 48 +++++++++ fai/config/files/boot/chboot/DEFAULT | 14 ++- .../root/fai-check/VOL_STRETCH_BOOTSTRAP | 2 - fai/config/hooks/extrbase.DEFAULT | 1 - fai/config/hooks/instsoft.DEBIAN | 11 +- fai/config/hooks/partition.DEFAULT | 101 +++++++++++++----- fai/config/package_config/DEBIAN | 10 +- fai/config/package_config/UBUNTU | 2 +- faiserver-setup | 10 +- install-chboot | 1 + myfai-chboot-local | 11 +- pxe-server | 8 +- wrt-setup | 52 +++++---- 18 files changed, 229 insertions(+), 145 deletions(-) mode change 100644 => 120000 bash-trace create mode 100644 fai/config/files/boot/bash-trace/DEFAULT diff --git a/README b/README index f71f643..3e6123b 100644 --- a/README +++ b/README @@ -6,20 +6,18 @@ not added a pxe rom, I use a minimal debian stable subvolume which acts like a pxe rom). I use this for bare metal and vms, and two scripts which can run post boot so I use them on vps distributed image as well. -Features people may find useful: installs encrypted trisquel belenos, , -debian jessie, debian stretch, ubuntu 16.04, and arch (havne't done -recently, probably a bit broken), in a multi-boot setup using multiple -subvolumes of a single btrfs filesystem. Utilizes multiple disks, with -scripts to automatically decrypt on intentional reboots, but not after -shutdown or power loss. +Features people may find useful: installs encrypted trisquel, debian, +ubuntu, and arch (havne't done recently, probably a bit broken), in a +multi-boot setup using multiple subvolumes of a single btrfs filesystem. +Utilizes multiple disks, with scripts to automatically decrypt on +intentional reboots, but not after shutdown or power loss. 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. +fai/config/hooks/partition.DEFAULT. 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. People who use fai may find these things as useful examples: it uses dnsmasq (on a openwrt machine) for dhcp instead of the isc diff --git a/arch-pxe b/arch-pxe index e480b5d..52885b3 100755 --- a/arch-pxe +++ b/arch-pxe @@ -27,7 +27,8 @@ Usage: ${0##*/} Setup arch pxe boot server from the base image Requires manually downloading image. Image path is hardcoded below to -/a/opt/image_name. Run pxe-server HOST|default arch to enable it. +/a/opt/image_name without .iso on the end. adjust the code for a new image. After this, run pxe-server. +HOST|default arch to enable it. -h|--help Print help and exit. EOF @@ -42,11 +43,16 @@ esac x="$(readlink -f "$BASH_SOURCE")" script_dir="${x%/*}" cd /a/opt -iso="archlinux-2017.02.01-dual" -sfs=$iso/arch/x86_64/airootfs.sfs +iso="parabola-systemd-cli-x86_64-netinstall-2017.10.18-00.07-alpha" rm -rf $iso ex $iso.iso -sed -i --follow-symlinks -f - $iso/arch/boot/syslinux/archiso_pxe64.cfg < airootfs.md5; popd # seems if you've done a pxe boot, mounted the nfs, diff --git a/bash-trace b/bash-trace deleted file mode 100644 index 61f8ae5..0000000 --- a/bash-trace +++ /dev/null @@ -1,48 +0,0 @@ -# meant to be sourced. copy/pasted from https://iankelling.org/git/?p=errhandle;a=summary - -bash-trace() { - local -i argc_index=0 arg frame i start=${1:-1} max_indent=8 indent - local source - local extdebug=false - if [[ $(shopt -p extdebug) == *-s* ]]; then - extdebug=true - fi - - for ((frame=0; frame < ${#FUNCNAME[@]}-1; frame++)); do - argc=${BASH_ARGC[frame]} - argc_index+=$argc - ((frame < start)) && continue - if (( ${#BASH_SOURCE[@]} > 1 )); then - source="${BASH_SOURCE[frame+1]}:${BASH_LINENO[frame]}:" - fi - indent=$((frame-start+1)) - indent=$((indent < max_indent ? indent : max_indent)) - printf "%${indent}s↳%sin \`%s" '' "$source" "${FUNCNAME[frame]}" - if $extdebug; then - for ((i=argc_index-1; i >= argc_index-argc; i--)); do - printf " %s" "${BASH_ARGV[i]}" - done - fi - echo \' - done -} - - -errcatch() { - set -E; shopt -s extdebug - _err-trap() { - err=$? - exec >&2 - set +x - echo "${BASH_SOURCE[1]}:${BASH_LINENO[0]}:in \`$BASH_COMMAND' returned $err" - bash-trace 2 - set -e - "${_errcatch_cleanup[@]}" - echo "$0: exiting with code $err" - exit $err - } - trap _err-trap ERR - set -o pipefail -} - -errcatch diff --git a/bash-trace b/bash-trace new file mode 120000 index 0000000..7656675 --- /dev/null +++ b/bash-trace @@ -0,0 +1 @@ +./fai/config/files/boot/bash-trace/DEFAULT \ No newline at end of file diff --git a/fai/config/class/50-host-classes b/fai/config/class/50-host-classes index 8ac4a27..3169fd3 100755 --- a/fai/config/class/50-host-classes +++ b/fai/config/class/50-host-classes @@ -25,7 +25,8 @@ # The base distro: # UBUNTU, DEBIAN # -# The base disto version, which is also the basefile name if it exists: +# The base disto version, which is also the basefile name if it exists. +# Debian stable basefile gets built by faisetup and gets used otherwise,: # STRETCH64, XENIAL64, BELENOS64, FLIDAS64 # # The distro subvol name, we can add as many of these as we want: diff --git a/fai/config/distro-install-common/libreboot_grub.cfg b/fai/config/distro-install-common/libreboot_grub.cfg index 69e1c52..4610044 100644 --- a/fai/config/distro-install-common/libreboot_grub.cfg +++ b/fai/config/distro-install-common/libreboot_grub.cfg @@ -14,17 +14,18 @@ function save_chosen { } # fai_check is so we can act like a pxe boot, but just for fai, and by -# using /debian_bootstrap to do it. We toggle on and off the grub var +# using /stretch_bootstrap to do it. We toggle on and off the grub var # did_fai_check so we can do the check every other boot. Then # /debian_bootstrap checks for that var on boot and if we want to do a -# fai check, it does it, then reboots. But it also sets did_fai_check to -# a 3rd state os_true which means we did the fai check, and we don't -# want to do it again. This is useful for systems without libreboot. +# fai check, it does it, then reboots. But fai-check also sets +# did_fai_check to a 3rd state os_true which means we did the fai check, +# and we don't want to do it again. This is useful for systems without +# libreboot, although it's not used yet. # 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 default=/debianstretch_bootstrap # could use 0 here. set timeout=1 for part in (ahci*4) (ata*4); do @@ -42,7 +43,7 @@ done did_fai_check=false -bs_dir=/debianstable_bootstrap +bs_dir=/debianstretch_bootstrap menuentry $bs_dir --id=$bs_dir { # note, we might be able to use $chosen and avoid setting this here, # and set it inside save_chosen. but I haven't tested it, diff --git a/fai/config/files/boot/bash-trace/DEFAULT b/fai/config/files/boot/bash-trace/DEFAULT new file mode 100644 index 0000000..61f8ae5 --- /dev/null +++ b/fai/config/files/boot/bash-trace/DEFAULT @@ -0,0 +1,48 @@ +# meant to be sourced. copy/pasted from https://iankelling.org/git/?p=errhandle;a=summary + +bash-trace() { + local -i argc_index=0 arg frame i start=${1:-1} max_indent=8 indent + local source + local extdebug=false + if [[ $(shopt -p extdebug) == *-s* ]]; then + extdebug=true + fi + + for ((frame=0; frame < ${#FUNCNAME[@]}-1; frame++)); do + argc=${BASH_ARGC[frame]} + argc_index+=$argc + ((frame < start)) && continue + if (( ${#BASH_SOURCE[@]} > 1 )); then + source="${BASH_SOURCE[frame+1]}:${BASH_LINENO[frame]}:" + fi + indent=$((frame-start+1)) + indent=$((indent < max_indent ? indent : max_indent)) + printf "%${indent}s↳%sin \`%s" '' "$source" "${FUNCNAME[frame]}" + if $extdebug; then + for ((i=argc_index-1; i >= argc_index-argc; i--)); do + printf " %s" "${BASH_ARGV[i]}" + done + fi + echo \' + done +} + + +errcatch() { + set -E; shopt -s extdebug + _err-trap() { + err=$? + exec >&2 + set +x + echo "${BASH_SOURCE[1]}:${BASH_LINENO[0]}:in \`$BASH_COMMAND' returned $err" + bash-trace 2 + set -e + "${_errcatch_cleanup[@]}" + echo "$0: exiting with code $err" + exit $err + } + trap _err-trap ERR + set -o pipefail +} + +errcatch diff --git a/fai/config/files/boot/chboot/DEFAULT b/fai/config/files/boot/chboot/DEFAULT index 8a093d9..ed65c80 100755 --- a/fai/config/files/boot/chboot/DEFAULT +++ b/fai/config/files/boot/chboot/DEFAULT @@ -16,7 +16,13 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -x="$(readlink -f "$BASH_SOURCE")"; source "${x%/*}/bash-trace" +x="$(readlink -f "$BASH_SOURCE")" +f="${x%/*}/bash-trace" +if [[ -e $f ]]; then + source $f +else + source ${x%/*}/../bash-trace/DEFAULT +fi [[ $EUID == 0 ]] || exec sudo "$BASH_SOURCE" "$@" @@ -32,10 +38,10 @@ For example, boot_debianjessie. For a system without libreboot, which is failing completely to boot on one distro, here is how I did a chboot for it: # arch-pxe had been run previously -pxe-server treetowl arch -# reboot treetowl into arch live env +pxe-server some_hostname arch +# reboot some_hostname into arch live env pxe-server # disable pxe server -ssh root@treetowl +ssh root@some_hostname lsblk # identify boot dev. if boot dev is a raid, this could be repeated on all boot devs. mount /dev/sdd3 /mnt mount_point=/mnt/boot_debiantesting # the subvol i want to chboot to diff --git a/fai/config/files/root/fai-check/VOL_STRETCH_BOOTSTRAP b/fai/config/files/root/fai-check/VOL_STRETCH_BOOTSTRAP index b20e8e9..7c405e6 100755 --- a/fai/config/files/root/fai-check/VOL_STRETCH_BOOTSTRAP +++ b/fai/config/files/root/fai-check/VOL_STRETCH_BOOTSTRAP @@ -68,8 +68,6 @@ for dev in $(btrfs fi show / | sed -rn 's#^\s*devid\s.*\s([^0-9 ]+)\S+$#\1#p' \ # connection. So, we wait for 10 seconds. # ref: https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ try-kexec ||: - else - return 0 fi else # we make sure there is only 1 grubenv, diff --git a/fai/config/hooks/extrbase.DEFAULT b/fai/config/hooks/extrbase.DEFAULT index 4efa226..1d1a931 100755 --- a/fai/config/hooks/extrbase.DEFAULT +++ b/fai/config/hooks/extrbase.DEFAULT @@ -5,4 +5,3 @@ if ifclass VM && ! ifclass demohost; then exit 0 fi -#chattr -Rf +C /target diff --git a/fai/config/hooks/instsoft.DEBIAN b/fai/config/hooks/instsoft.DEBIAN index 13c517a..355f46d 100755 --- a/fai/config/hooks/instsoft.DEBIAN +++ b/fai/config/hooks/instsoft.DEBIAN @@ -10,11 +10,12 @@ fi fcopy -Bi /etc/apt/apt.conf.d/force_confdef ainsl -a /etc/ucf.conf "^conf_force_conffold=YES" -# in case the locales are already included inside the base file (Ubuntu) -if [ -f $target/usr/sbin/locale-gen ]; then - $ROOTCMD dpkg-reconfigure -fnoninteractive locales - exit -fi +# ian: on flidas this gives an error: update-locale: Error: invalid locale settings: LANG=en_US.UTF-8 +# # in case the locales are already included inside the base file (Ubuntu) +# if [ -f $target/usr/sbin/locale-gen ]; then +# $ROOTCMD dpkg-reconfigure -fnoninteractive locales +# exit +# fi # if we want to install locales, install them now install_packages -l 2>/dev/null | egrep -q ' locales|locales ' diff --git a/fai/config/hooks/partition.DEFAULT b/fai/config/hooks/partition.DEFAULT index ca7b86d..7a1967b 100755 --- a/fai/config/hooks/partition.DEFAULT +++ b/fai/config/hooks/partition.DEFAULT @@ -18,12 +18,49 @@ set -eE -o pipefail trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR +# for calling outside of FAI, first +# source /a/bin/fai-wrapper +# then to set classes with: fai-setclass OPT1... +# which sets CLASS_OPT1=true... +# +# OPTIONS: +# +# environment variables: +# +# HOSTNAME: if frodo, we exclude 2 devices from the /boot array, which +# the bios does not see. if demohost, we set the luks password to just +# 'x'. +# +# SPECIAL_DISK: For use outside of fai. A base disk name like +# /dev/sdk. If set, we just cryptsetup and partition this one disk then +# exit. This is useful for partitioning a disk in preparation to replace +# a failed or failing disk from a raid10 array. +# +# classes: +# +# REPARTITION: forces repartitioning even if we detect the proper amount +# of partitions already exist. +# +# ROTATIONAL: forces to install onto hdds instead of sdds. normally sdds +# are chosen if they exist. +# +# PARTITION_PROMPT: command line prompt before partitioning +# +# RAID0: forces raid0 filesystem. Normally with 4+ devices, we use +# raid10. + +if [[ $SPECIAL_DISK ]]; then + export CLASS_REPARTITION=true +fi + # # fai's setup-storage won't do btrfs on luks, # # so we do it ourself :) # inspiration taken from files in fai-setup-storage package +# if we are not running in fai, skiptask won't be defined, so carry on. +skiptask partition || ! type skiptask + -skiptask partition || ! type skiptask # for running not in fai #### begin configuration @@ -81,7 +118,7 @@ devbyid() { local f for f in $FAI/distro-install-common/devbyid \ /a/bin/fai/fai/config/distro-install-common/devbyid; do - if [[ -e $f ]]; then $f "$@"; fi + if [[ -e $f ]]; then $f "$@"; break; fi done } @@ -196,7 +233,7 @@ fi if [[ ! $DISTRO ]]; then if ifclass VOL_STRETCH_BOOTSTRAP; then - DISTRO=stretch_bootstrap + DISTRO=debianstretch_bootstrap elif ifclass VOL_STRETCH; then DISTRO=debianstretch elif ifclass VOL_TESTING; then @@ -232,11 +269,11 @@ if [[ ! -e $luks_dir/host-$HOSTNAME ]]; then exit 1 fi -if ifclass tp; then - lukspw=$(cat $luks_dir/traci) -else - lukspw=$(cat $luks_dir/iank) -fi +lukspw=$(cat $luks_dir/iank) +# # ian: disabled while I use the tp host. +# if ifclass tp; then +# lukspw=$(cat $luks_dir/traci) +# fi if ifclass demohost; then lukspw=x fi @@ -255,27 +292,37 @@ for dev in ${devs[@]}; do done shopt -s nullglob if $partition; then - for dev in ${devs[@]}; do - # if we repartition to the same as an old partition, - # we don't want any old fses hanging around. - for (( i=1; i <= lastn; i++ )); do - x=$(add-part $dev $i) - [[ -e $x ]] || continue - count_down=10 - # wipefs has failed, manual run works, google suggests timing issue - while ! wipefs -a $x; do - sleep 2 - count_down=$((count_down - 1)) - (( count_down > 0 )) || exit 1 + + ### begin wipefs + if [[ ! $SPECIAL_DISK ]]; then + for dev in ${devs[@]}; do + # if we repartition to the same as an old partition, + # we don't want any old fses hanging around. + for (( i=1; i <= lastn; i++ )); do + x=$(add-part $dev $i) + [[ -e $x ]] || continue + count_down=10 + # wipefs has failed, manual run works, google suggests timing issue + while ! wipefs -a $x; do + sleep 2 + count_down=$((count_down - 1)) + (( count_down > 0 )) || exit 1 + done done done - done + fi + ### end wipefs + for dev in ${devs[@]}; do + if [[ $SPECIAL_DISK ]]; then + dev=$(devbyid $SPECIAL_DISK) + fi + # parted will round up the disk size. Do -1 so we can have # fully 1MiB unit partitions for easy resizing of the last partition. # Otherwise we would pass in -0 for the end argument for the last partition. # - # parted print error output is expected. example: + # Note: parted print error output is expected. example: # Error: /dev/vda: unrecognised disk label disk_mib=$(( $(parted -m $dev unit MiB print | \ sed -nr "s#^/dev/[^:]+:([0-9]+).*#\1#p") - 1)) @@ -350,6 +397,10 @@ if $partition; then cryptsetup luksOpen `rootdev` `root-cryptname` \ --key-file $luks_dir/host-$HOSTNAME + + if [[ $SPECIAL_DISK ]]; then + exit 0 + fi done ls -la /dev/btrfs-control # this was probably for debugging... sleep 1 @@ -365,7 +416,7 @@ else fi -if [[ $DISTRO != stretch_bootstrap ]]; then +if [[ $DISTRO != debianstretch_bootstrap ]]; then # bootstrap distro doesn't use separate encrypted root. mount -o subvolid=0 $first_root_crypt /mnt # systemd creates subvolumes we want to delete. @@ -403,7 +454,7 @@ btrfs subvolume set-default 0 /mnt # already default, just ensuring it. mkdir -p /mnt/grub2 cp $FAI/distro-install-common/libreboot_grub.cfg /mnt/grub2 -if [[ $DISTRO == stretch_bootstrap ]]; then +if [[ $DISTRO == debianstretch_bootstrap ]]; then # this is just convenience for the libreboot_grub config # so we can glob the other ones easier. boot_vol=$DISTRO @@ -422,7 +473,7 @@ grub-editenv /mnt/grubenv set did_fai_check=true grub-editenv /mnt/grubenv set last_boot=/$boot_vol umount /mnt -if [[ $DISTRO == stretch_bootstrap ]]; then +if [[ $DISTRO == debianstretch_bootstrap ]]; then cat > /tmp/fai/fstab </dev/null || apt-get -y install dnsutils ip=$(host $host | sed -rn 's/^\S+ has address //p;T;q')/32 + if [[ ! $ip || $ip =~ [[:space:]] ]]; then + echo "$0: error: failed to get \$my_ip, got: $my_ip" + exit 1 + fi + fi if modprobe nfsd &>/dev/null; then diff --git a/pxe-server b/pxe-server index 7fced84..b1700be 100755 --- a/pxe-server +++ b/pxe-server @@ -64,7 +64,7 @@ dhcp=true redep=true acks=2 wait=false -temp=$(getopt -l help harSw "$@") || usage 1 +temp=$(getopt -l help adrSwh "$@") || usage 1 eval set -- "$temp" while true; do case $1 in @@ -90,6 +90,12 @@ case $# in ;; esac +if $wait && ! $dhcp; then + echo "$0: error -w conflicts with -d, choose one or other" + exit 1 +fi + + if [[ $host && $host != default ]]; then host_tag="tag:$host," fi diff --git a/wrt-setup b/wrt-setup index 4be2e41..24aa3a0 100755 --- a/wrt-setup +++ b/wrt-setup @@ -91,28 +91,32 @@ mkdir -p /run/archiso/bootmnt # todo: at some later time, i found /mnt/usb not mounted, watch to see if # that is the case after running this or rebooting. # wiki says safe to do in case of fstab changes: -cedit /etc/config/fstab <<'EOF' || { v block umount; v block mount; } -config global automount - option from_fstab 1 - option anon_mount 1 - -config global autoswap - option from_fstab 1 - option anon_swap 1 - -config mount - option target /mnt/usb - option device /dev/sda2 - option fstype ext4 - option options rw,async,noatime,nodiratime - option enabled 1 - option enabled_fsck 0 - -config swap - option device /dev/sda1 - option enabled 1 -EOF +## ian: commented and replaced with just an echo +## since usb port seems to be busted. +echo | cedit /etc/config/fstab +# cedit /etc/config/fstab <<'EOF' || { v block umount; v block mount; } +# config global automount +# option from_fstab 1 +# option anon_mount 1 + +# config global autoswap +# option from_fstab 1 +# option anon_swap 1 + +# config mount +# option target /mnt/usb +# option device /dev/sda2 +# option fstype ext2 +# option options rw,async,noatime,nodiratime +# option enabled 1 +# option enabled_fsck 0 + +# config swap +# option device /dev/sda1 +# option enabled 1 + +# EOF @@ -261,14 +265,15 @@ dnsmasq_restart=false v cedit /etc/hosts <