From 78a1427fc167ccee73d448054a9c40c19d737ed3 Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Sun, 10 Nov 2019 14:13:43 -0500 Subject: [PATCH] new stack trace, linode fixes, minor improvements --- README | 10 +- arch-init-remote | 20 +- archlike-pxe | 24 +- debian-pxe-preseed | 3 +- dsfull | 8 +- fai-redep | 4 +- fai-revm | 20 +- fai-wrapper | 2 +- fai/config/class/50-host-classes | 2 +- fai/config/class/LINODE.var | 4 +- fai/config/distro-install-common/end | 3 + fai/config/files/boot/bash-trace/DEFAULT | 237 +++++++++++++++--- fai/config/hooks/partition.DEFAULT | 42 +++- fai/config/scripts/DEBIAN/30-interface | 16 +- fai/config/scripts/GRUB_PC/11-iank | 23 +- faiserver-revm | 11 +- fresize | 2 +- ...etinst-linode => grub.cfg.netinst-noreboot | 0 mk-basefile-big | 3 +- myfai-chboot-local | 16 +- pxe-server | 26 +- wrt-setup-local | 71 +++++- 22 files changed, 392 insertions(+), 155 deletions(-) rename grub.cfg.netinst-linode => grub.cfg.netinst-noreboot (100%) diff --git a/README b/README index 312d330..eae4b2d 100644 --- a/README +++ b/README @@ -96,11 +96,11 @@ on fai-redep arguments. # create tiny autodiscover cd fai-redep && sudo fai-cd -g $PWD/grub.cfg.autodiscover -f -A $BASEFILE_DIR/autodiscover.iso -# create normal fai cd (replace TARGET_HOST) -fai-redep -t TARGET_HOST && sudo fai-cd -M -g $PWD/grub.cfg.netinst -f $BASEFILE_DIR/netinst.iso -note, may need to set hostname, depending on config, -and some other things for environment not on your lan -for example see fai/config/class/LINODE.var. See linode notes below. +# create normal fai cd (replace TARGET_HOSTNAME) +fai-redep -t TARGET_HOSTNAME && sudo fai-cd -M -g $PWD/grub.cfg.netinst-noreboot -f $BASEFILE_DIR/netinst.iso +# note, may need to set hostname, depending on config, +# and some other things for environment not on your lan +# for example see fai/config/class/LINODE.var. See linode notes below. mymk-basefile # Create basefiles for various distros archlike-pxe # Setup pxe boot server from an archlike base image diff --git a/arch-init-remote b/arch-init-remote index 0952543..d8e4e29 100755 --- a/arch-init-remote +++ b/arch-init-remote @@ -1,19 +1,7 @@ -#!/bin/bash -l -# Copyright (C) 2016 Ian Kelling - -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +#!/bin/bash +# Copyright (C) 2019 Ian Kelling +# SPDX-License-Identifier: AGPL-3.0-or-later +if [[ -s ~/.bashrc ]];then . ~/.bashrc;fi set -x diff --git a/archlike-pxe b/archlike-pxe index ba39c45..085679a 100755 --- a/archlike-pxe +++ b/archlike-pxe @@ -1,4 +1,4 @@ -#!/bin/bash -l +#!/bin/bash # Copyright (C) 2016 Ian Kelling # This program is free software; you can redistribute it and/or @@ -17,9 +17,7 @@ # Setup arch pxe boot server from the base image. # - -set -eE -o pipefail -trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR +if [[ -s ~/.bashrc ]];then . ~/.bashrc;fi usage() { cat < airootfs.md5; popd @@ -90,4 +88,4 @@ ssh wrt "cd /mnt/usb && rm -f tftpboot && ln -s $idir tftpboot" # complicated, so fuck it, we use nfs cuz it's easy rm -rf $idir -s rm -rf squashfs-root +sudo rm -rf squashfs-root diff --git a/debian-pxe-preseed b/debian-pxe-preseed index a3ed886..bac251a 100755 --- a/debian-pxe-preseed +++ b/debian-pxe-preseed @@ -28,8 +28,7 @@ e() { echo "$*"; "$@"; } mount_dir=$(mktemp -d) -cleanup() { cd; umount -f $mount_dir; } -_errcatch_cleanup=cleanup +errcatch-cleanup() { cd; umount -f $mount_dir; } e mount -o users wrt:/mnt/usb $mount_dir diff --git a/dsfull b/dsfull index f1371d1..cdb840b 100755 --- a/dsfull +++ b/dsfull @@ -1,4 +1,4 @@ -#!/bin/bash -l +#!/bin/bash # Copyright (C) 2016 Ian Kelling # Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -x="$(readlink -f "$BASH_SOURCE")"; source "${x%/*}/bash-trace" +if [[ -s ~/.bashrc ]];then . ~/.bashrc;fi reboot=true if [[ $1 == -r ]]; then @@ -70,7 +70,7 @@ if $kexec; then myfai-chboot $host live-kexec $host ||: else - cleanup() { pxe-server; }; _errcatch_cleanup=cleanup + errcatch-cleanup() { pxe-server; } pxe-server $host fai if $reboot; then @@ -79,7 +79,7 @@ else fi pxe-server -a - unset _errcatch_cleanup + unset errcatch-cleanup fi error=true diff --git a/fai-redep b/fai-redep index ac73c7b..0541497 100755 --- a/fai-redep +++ b/fai-redep @@ -59,7 +59,7 @@ sudo rsync -a /root/.ssh/home.pub \ # these files are not available. if [[ $target ]]; then - if [[ -e /q/root/shadow/$target ]]; then + if sudo test -e /q/root/shadow/$target; then shadowfile=shadow/$target # empty otherwise fi sudo rsync -lpt --files-from=- /q/root root@$faiserver_host:/srv/fai/config/distro-install-common </dev/null ||: # broken pipe -rsync -rplt --delete $BASEFILE_DIR/*.gz root@$faiserver_host:/srv/fai/config/basefiles/ +rsync -rplt --include '/*.gz' --exclude '/**' --delete-excluded $BASEFILE_DIR/ root@$faiserver_host:/srv/fai/config/basefiles/ ssh root@$faiserver_host bash <<'EOF' set -eE -o pipefail # make it the root because pxe-kexec only looks there. diff --git a/fai-revm b/fai-revm index 7645888..a44b218 100755 --- a/fai-revm +++ b/fai-revm @@ -1,4 +1,4 @@ -#!/bin/bash -l +#!/bin/bash # Copyright (C) 2016 Ian Kelling # This program is free software; you can redistribute it and/or @@ -22,6 +22,7 @@ script_dir="${this_file%/*}" # shellcheck source=./bash-trace source "${script_dir}/bash-trace" cd $script_dir +PATH="$PATH:$PWD" e() { echo "$*"; "$@"; } @@ -86,12 +87,11 @@ is_arch_revm() { [[ ${0##*/} == arch-revm ]] } -cleanup() { +errcatch-cleanup() { echo "doing cleanup" e ./pxe-server $dhcp_arg ./faiserver-disable } -_errcatch_cleanup=cleanup boot_arg=--pxe if is_arch_revm; then @@ -112,7 +112,7 @@ else isopath=$BASEFILE_DIR/$iso isosrc=$BASEFILE_DIR/STRETCH64.tar.gz if [[ ! -e $isopath || $(stat -c %Y $isopath) -lt $(stat -c %Y $isosrc) ]]; then - e s fai-cd -g $(readlink -f grub.cfg.${iso%%.*}) -f -A $isopath + e sudo fai-cd -g $(readlink -f grub.cfg.${iso%%.*}) -f -A $isopath fi boot_arg="--cdrom $isopath" e fai-redep @@ -127,7 +127,7 @@ fi name=demohost -e s virshrm $name ||: +e sudo virshrm $name ||: disk_arg=() @@ -135,8 +135,8 @@ for ((i=1; i <= disk_count; i++)); do f=/var/lib/libvirt/images/${name}$i disk_arg+=("--disk path=$f") if $new_disk || [[ ! -e $f ]]; then - s rm -f $f - e s qemu-img create -o preallocation=metadata -f qcow2 $f 50G + sudo rm -f $f + e sudo qemu-img create -o preallocation=metadata -f qcow2 $f 50G fi done @@ -152,12 +152,12 @@ s iptables -P FORWARD ACCEPT # init_module+0x108/0x1000 [raid6_pq] # # uniq is to stop gtk-warning spam -# e s virt-install --os-variant $variant -n $name --pxe -r 2048 --vcpus 1 \ +# e sudo virt-install --os-variant $variant -n $name --pxe -r 2048 --vcpus 1 \ # ${disk_arg[*]} -w bridge=br0,mac=52:54:00:9c:ef:ad $reboot_arg \ # --graphics spice,listen=0.0.0.0 $console_arg |& grep -v '^ *$' | uniq & -e s virt-install --rng /dev/urandom --os-variant $variant -n $name $boot_arg -r 2048 --vcpus 1 \ +e sudo virt-install --rng /dev/urandom --os-variant $variant -n $name $boot_arg -r 2048 --vcpus 1 \ ${disk_arg[*]} -w bridge=br0,mac=52:54:00:9c:ef:ad $reboot_arg \ --graphics spice,listen=0.0.0.0 $console_arg |& grep -v '^ *$' | uniq & @@ -170,7 +170,7 @@ sleep 30 while ! timeout -s 9 10 ssh -oBatchMode=yes root@$name /bin/true; do e sleep 5 done -unset _errcatch_cleanup +unset errcatch-cleanup e ./pxe-server $dhcp_arg if is_arch_revm; then ./arch-init-remote $name diff --git a/fai-wrapper b/fai-wrapper index 4203f80..93e1c6d 100644 --- a/fai-wrapper +++ b/fai-wrapper @@ -28,7 +28,7 @@ eval-fai-classfile() { echo "$0: probably an error: eval-fai-classfile no such file: $file" return 0 fi - fai-setclass $(bash -l $file) + fai-setclass $(bash $file) } export -f ifclass classes=DEFAULT # used by fcopy diff --git a/fai/config/class/50-host-classes b/fai/config/class/50-host-classes index c7091f0..ef0c781 100755 --- a/fai/config/class/50-host-classes +++ b/fai/config/class/50-host-classes @@ -1,4 +1,4 @@ -#!/bin/bash -l +#!/bin/bash # assign classes to hosts based on their hostname diff --git a/fai/config/class/LINODE.var b/fai/config/class/LINODE.var index e8bfb1f..8f34a2c 100644 --- a/fai/config/class/LINODE.var +++ b/fai/config/class/LINODE.var @@ -1,6 +1,6 @@ APTPROXY= -linode_ip=1.2.3.4 -linode_gw=1.2.3.1 +linode_ip=172.105.84.95 +linode_gw=172.105.84.1 # this is the same at least in 2 regions linode_if=enp0s3 LOGSERVER=b8.nz diff --git a/fai/config/distro-install-common/end b/fai/config/distro-install-common/end index 3d061b3..1fd8ca6 100755 --- a/fai/config/distro-install-common/end +++ b/fai/config/distro-install-common/end @@ -24,6 +24,9 @@ if ifclass ziva; then else # if doesn't exist, we dont set one ROOTPW=/q/root/shadow/standard + if [[ ! -e $ROOTPW ]]; then + ROOTPW=/q/root/shadow/$HOSTNAME + fi fi chpw() { diff --git a/fai/config/files/boot/bash-trace/DEFAULT b/fai/config/files/boot/bash-trace/DEFAULT index 61f8ae5..246042d 100644 --- a/fai/config/files/boot/bash-trace/DEFAULT +++ b/fai/config/files/boot/bash-trace/DEFAULT @@ -1,48 +1,203 @@ +#!/bin/bash +# Copyright (C) 2019 Ian Kelling +# SPDX-License-Identifier: AGPL-3.0-or-later + # 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 +# Commentary: Bash stack trace and error handling functions. This file +# is meant to be sourced. It loads some functions which you may want to +# call manually (see the comments at the start of each one), and then +# runs err-catch. See the README file for a slightly longer explanation. + + +####################################### +# Print stack trace +# +# usage: err-bash-trace [MESSAGE] +# +# This function is called by the other functions which print stack +# traces. +# +# It does not show function args unless you first run: +# shopt -s extdebug +# which err-catch & err-print do for you. +# +# MESSAGE Message to print just before the stack trace. +# +# _frame_start Optional variable to set before calling. The frame to +# start printing on. default=1. Useful when printing from +# an ERR trap function to avoid printing that function. +####################################### +err-bash-trace() { + local -i argc_index=0 frame i start=${_frame_start:-1} + local source + if [[ $1 ]]; then + printf "%s\n" "$1" + fi + for ((frame=0; frame < ${#FUNCNAME[@]}; frame++)); do + argc=${BASH_ARGC[frame]} + argc_index+=$argc + ((frame < start)) && continue + if (( ${#BASH_SOURCE[@]} > 1 )); then + source="${BASH_SOURCE[frame]}:${BASH_LINENO[frame-1]}:" + fi + printf " from %sin \`%s" "$source" "${FUNCNAME[frame]}" + if shopt extdebug >/dev/null; then + for ((i=argc_index-1; i >= argc_index-argc; i--)); do + printf " %s" "${BASH_ARGV[i]}" + done + fi + echo \' + done + return 0 +} + +####################################### +# On error print stack trace and exit +# +# Globals: +# errcatch-cleanup If set, this command will run just before exiting. +####################################### +err-catch() { + set -E; shopt -s extdebug + _err-trap() { + err=$? + exec >&2 + set +x + local msg="${BASH_SOURCE[1]}:${BASH_LINENO[0]}: \`$BASH_COMMAND' returned $err" + if (( ${#FUNCNAME[@]} > 2 )); then + local _frame_start=2 + err-bash-trace "$msg" + else + echo "$msg" + fi + set -e # err trap does not work within an error trap + if type -t errcatch-cleanup >/dev/null; then + errcatch-cleanup + fi + echo "$0: exiting with status $err" + exit $err + } + trap _err-trap ERR + set -o pipefail +} + + +####################################### +# For interactive shells: on error, print stack trace and return +# +# Globals: +# err_catch_ignore Array containing glob patterns to test against filenames to ignore +# errors from. Initialized to ignore bash-completion scripts on debian +# based systems. +# _err_func_last Used internally. +# _err_catch_err Used internally. +# _err_catch_i Used internally. +# _err_catch_ignore Used internally. +# +# misc: All shellcheck disables for this function are false positives. +####################################### +# shellcheck disable=SC2120 +err-catch-interactive() { + err_catch_ignore=( + '/etc/bash_completion.d/*' + ) + # shellcheck disable=SC2034 + declare -i _err_func_last=0 + set -E; shopt -s extdebug + # shellcheck disable=SC2154 + trap '_err_catch_err=$? _trap_bc="$BASH_COMMAND" + _err_catch_ignore=false + for _err_catch_i in "${err_catch_ignore[@]}"; do + if [[ ${BASH_SOURCE[0]} == $_err_catch_i ]]; then + _err_catch_ignore=true + break + fi + done + if ! $_err_catch_ignore; then + if (( ${#FUNCNAME[@]} > _err_func_last )); then + echo ERR: \`$_trap_bc'"\'"' returned $_err_catch_err + fi + _err_func_last=${#FUNCNAME[@]} + if (( _err_func_last )); then + printf " from %s:%s:in \`%s" "${BASH_SOURCE[0]}" "$(declare -F "${FUNCNAME[0]}"|awk "{print \$2}")" "${FUNCNAME[0]}" + if shopt extdebug >/dev/null; then + for ((_err_catch_i=${BASH_ARGC[0]}-1; _err_catch_i >= 0; _err_catch_i--)); do + printf " %s" "${BASH_ARGV[_err_catch_i]}" + done + fi + echo '"\'"' + return $_err_catch_err + fi + fi' ERR + set -o pipefail } -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 +####################################### +# Undoes err-catch/err-catch-interactive +####################################### +err-allow() { + shopt -u extdebug + set +E +o pipefail + trap ERR +} + +####################################### +# On error, print stack trace +####################################### +err-print() { + # help: on errors: print stack trace + # + # This function depends on err-bash-trace. + + set -E; shopt -s extdebug + _err-trap() { + err=$? + exec >&2 + set +x + echo "${BASH_SOURCE[1]}:${BASH_LINENO[0]}: \`$BASH_COMMAND' returned $err" + err-bash-trace 2 + } + trap _err-trap ERR + set -o pipefail +} + + +####################################### +# Print stack trace and exit +# +# Use this instead of the exit command to be more informative. +# +# usage: err-exit [EXIT_CODE] [MESSAGE] +# +# EXIT_CODE Default is 1. +# MESSAGE Print MESSAGE to stderr. If only one of EXIT_CODE +# and MESSAGE is given, we consider it to be an +# exit code if it is a number. +####################################### +err-exit() { + exec >&2 + code=1 + if [[ "$*" ]]; then + if [[ ${1/[^0-9]/} == "$1" ]]; then + code=$1 + if [[ $2 ]]; then + printf '%s\n' "$2" >&2 + fi + else + printf '%s\n' "$0: $1" >&2 + fi + fi + echo "${BASH_SOURCE[1]}:${BASH_LINENO[0]}" + err-bash-trace 2 + echo "$0: exiting with code $code" + exit $err } -errcatch +# We want this more often than not, so run it now. +if [[ $- == *i* ]]; then + err-catch-interactive +else + err-catch +fi diff --git a/fai/config/hooks/partition.DEFAULT b/fai/config/hooks/partition.DEFAULT index ab436bd..ccaca6e 100755 --- a/fai/config/hooks/partition.DEFAULT +++ b/fai/config/hooks/partition.DEFAULT @@ -93,10 +93,7 @@ grub_extn=4 # https://wiki.archlinux.org/index.php/GRUB bios_grubn=5 lastn=$bios_grubn -# this is larger than needed for several /boot subvols, -# becuase I keep a minimal debian install on it, for -# recovery needs, and for doing pxe-kexec. -boot_mib=10000 + ##### end configuration @@ -212,7 +209,7 @@ if [[ ! ${devs[0]} ]]; then exit 1 fi - +boot_space=0 first=false boot_devs=() for dev in ${devs[@]}; do @@ -242,6 +239,8 @@ for dev in ${devs[@]}; do done $bad_disk || boot_devs+=($(bootdev)) else + boot_space=$(( boot_space + $(parted -m $dev unit MiB print | \ + sed -nr "s#^/dev/[^:]+:([0-9]+).*#\1#p") - 1)) boot_devs+=($(bootdev)) fi if [[ $boot_devs && $first ]]; then @@ -256,11 +255,32 @@ elif ifclass RAID1 || (( ${#boot_devs[@]} <= 3 )); then raid_level=1 else raid_level=10 - # need double the space if we are raid 10, and then - # might as well give some extra. - boot_mib=$((boot_mib * 3)) fi +### Begin calculate boot partition space +# due to raid duplication +case $raid_level in + 1*) boot_space=$(( boot_space / 2 )) ;; +esac +if (( boot_space > 60000 )); then + # this is larger than needed for several /boot subvols, + # becuase I keep a minimal debian install on it for + # recovery needs and for doing pxe-kexec. + boot_mib=10000 +elif (( boot_space > 30000 )); then + boot_mib=$(( 5000 + (boot_space - 30000) / 2 )) +else + # Small vms don't have room for /boot recovery. With 3 kernels + # installed, i'm using 132M on t8, so this seems like plenty of + # room. note: rhel 8 recomments 1g for /boot. + boot_mib=500 + # +fi +case $raid_level in + 1*) boot_mib=$(( boot_mib * 2 )) ;; +esac +### end calculate boot partition space + if [[ ! $DISTRO ]]; then @@ -541,8 +561,8 @@ else # note, fai creates the mountpoints listed here cat > /tmp/fai/fstab <> /tmp/fai/fstab < $target/etc/network/interfaces < $target/etc/network/interfaces </etc/initramfs-tools/conf.d/mine <$target/etc/initramfs-tools/conf.d/mine < 60*60*2 )); then - $ROOTCMD apt-get update + i=0 + while fuser $FAI_ROOT/var/lib/dpkg/lock &>/dev/null; do + sleep 1 + i=$(( i+1 )) + if (( i > 300 )); then + echo "error: timed out waiting for /var/lib/dpkg/lock" >&2 + exit 1 + fi + $ROOTCMD apt-get update + done fi @@ -108,13 +117,17 @@ EOF if [[ $FAI_ACTION != dirinstall ]]; then + # luks options, see man systemd-cryptsetup-generator + # all i know is that with luks.crypttab=no, swap still timed out on boot. + # and with rd.luks.crypttab=no, it works. + cmdline="rd.luks.crypttab=no console=ttyS0" if ifclass LINODE; then speed=19200 - # luks.crypttab=no see man systemd-cryptsetup-generator - cmdline="luks.crypttab=no console=ttyS0,${speed}n8" + cmdline+=",${speed}n8" + cmdline="rd.luks.crypttab=no console=ttyS0,${speed}n8" else speed=115200 - cmdline="luks.crypttab=no console=ttyS0,${speed} console=tty0" + cmdline+=",${speed}n8 console=tty0" fi cat >$FAI_ROOT/etc/grub.d/40_custom <&2; } host=$1 @@ -68,6 +65,7 @@ else exit 1 fi ip=$ip/32 + echo "$0: found ip of $host: $ip" fi if modprobe nfsd &>/dev/null; then @@ -105,7 +103,7 @@ fi # man page doesn't explain this, but this deletes & thus disables # all chboot systems. -e fai-chboot -iv $std_arg default # set it to default to get a val out of it next +m 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}') default_k_args=$(fai-chboot -L '^default$' | \ sed -r "s/^(\S+\s+){3}(.*)/\2/") @@ -125,7 +123,7 @@ for arg in $default_k_args; do esac done rm -f /srv/tftp/fai/pxelinux.cfg/* -e fai-chboot -k "${k_args[*]}" -v -f verbose,sshd,createvt$fai_reboot_arg $std_arg $kernel "$host" +m fai-chboot -k "${k_args[*]}" -v -f verbose,sshd,createvt$fai_reboot_arg $std_arg $kernel "$host" # this is needed for autodiscover iso. i'm not sure, it might override # the fai-chboot method of setting this, i'm not sure. diff --git a/pxe-server b/pxe-server index 6137386..07262fc 100755 --- a/pxe-server +++ b/pxe-server @@ -61,6 +61,11 @@ EOF exit $1 } +pre="${0##*/}:" +m() { printf "$pre %s\n" "$*"; "$@"; } +e() { printf "$pre %s\n" "$*"; } +err() { echo "[$(date +'%Y-%m-%d %H:%M:%S%z')]: $pre: $*" >&2; } + ##### begin command line parsing ######## dhcp=true @@ -70,7 +75,7 @@ wait=false fsf=false case $HOSTNAME in - x2|x3|kw) fsf=true ;; + x2|kw) fsf=true ;; esac chboot_args=() @@ -125,11 +130,6 @@ fi ##### end command line parsing ######## -e() { - echo "$@" - "$@" -} - archlike() { cat <