From: Ian Kelling Date: Wed, 22 May 2024 00:12:20 +0000 (-0400) Subject: bug fix X-Git-Url: https://iankelling.org/git/?a=commitdiff_plain;ds=sidebyside;h=HEAD;hp=936324619541130f4ab07bd4633f48eb81812613;p=automated-distro-installer bug fix --- diff --git a/README b/README index da28e4e..5e01bb4 100644 --- a/README +++ b/README @@ -104,11 +104,18 @@ fai/config/distro-install-common/end and which shadow file / luks file(s) to copy into the new machine depends on fai-redep arguments. -Also, setup dns in bind and wrt-setup-local. +Also, setup dns in /p/c/host-info and firewall redirects in wrt-setup-local. After install, btrbk to setup data, and then distro-begin && distro end. See notes in distro-begin for other configuration. +# Prerequesites: + + +git clone https://git.savannah.nongnu.org/git/bash-bear-trap.git +sudo install -T bash-bear-trap/bash-bear /usr/local/lib/bash-bear + + # Scripts (meant to be used directly): @@ -125,10 +132,10 @@ fai-redep -t TARGET_HOSTNAME && sudo fai-cd -M -g $PWD/grub.cfg.netinst-noreboot mymk-basefile # Create basefiles for various distros archlike-pxe # Setup pxe boot server from an archlike base image -fai-redep # Deploy fai configuration to host "faiserver" +fai-redep # Deploy fai configuration to host "faiserver.b8.nz" faiserver-uninstall # uninstall fai-server faiserver-setup # install fai-server on the current machine -myfai-chboot # setup fai tftp and nfs. useful for doing pxe-kexec +myfai-chboot # setup fai tftp and nfs. useful for doing pxe-kexec or booting from a fai-cd. pxe-server # disable/enable pxe dhcp, tfp, and nfs. calls myfai-chboot wrt-setup # setup my router in general: dhcp, dns, etc. @@ -191,6 +198,24 @@ ERROR: Kernel modules directory /lib/modules/5.10.0-8-amd not available. Only fo solution: if running from fai-cd, recreate autodiscover cd as noted above in setup. +## Weird package dependency errors + +for example: in fai.log, within instsoft.DEBIAN +``` +The following packages have unmet dependencies: + libc6 : Breaks: locales (< 2.36) but 2.35-0ubuntu3.7+11.0trisquel1 is to be installed +``` + +In this case, it was because the basefile was missing, and so instead +fai decided to use the wrong basefile. + +for example: in fai.log, within instsoft.DEBIAN + +``` +ftar: No matching class found in /var/lib/fai/config/basefiles// +ftar: extracting /var/tmp/base.tar.zst to /target/ +``` + # What good logs look like: logging nfs traffic from server diff --git a/arch-init b/arch-init index 2f14ad6..6a3786f 100755 --- a/arch-init +++ b/arch-init @@ -1,4 +1,4 @@ -#!/bin/bash -x +#!/bin/bash # Copyright (C) 2016 Ian Kelling # This program is free software; you can redistribute it and/or @@ -15,8 +15,13 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -x="$(readlink -f "$BASH_SOURCE")"; source "${x%/*}/bash-trace" -cd ${x%/*} +set -e; . /usr/local/lib/bash-bear; set +e + +this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" +readonly this_file this_dir="${this_file%/*}" +cd "$this_dir" + +set -x export HOSTNAME="$1" mirror=$2 diff --git a/arch-init-remote b/arch-init-remote index d8e4e29..66e19e2 100755 --- a/arch-init-remote +++ b/arch-init-remote @@ -1,6 +1,21 @@ #!/bin/bash -# Copyright (C) 2019 Ian Kelling -# SPDX-License-Identifier: AGPL-3.0-or-later +# This file is part of Ian Kelling's automated-distro-installer +# Copyright (C) 2024 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. + if [[ -s ~/.bashrc ]];then . ~/.bashrc;fi set -x diff --git a/bash-trace b/bash-trace deleted file mode 120000 index 015ae24..0000000 --- a/bash-trace +++ /dev/null @@ -1 +0,0 @@ -fai/config/files/boot/bash-trace/DEFAULT \ No newline at end of file diff --git a/debian-pxe-preseed b/debian-pxe-preseed index aaef9a6..e2d401f 100755 --- a/debian-pxe-preseed +++ b/debian-pxe-preseed @@ -18,11 +18,12 @@ # WARNING: outdated! needs docs and update to debian-stretch -x="$(readlink -f "$BASH_SOURCE")"; source "${x%/*}/bash-trace" - [[ $EUID == 0 ]] || exec sudo "$BASH_SOURCE" "$@" -src=$(readlink -f "${BASH_SOURCE%/*}") +set -e; . /usr/local/lib/bash-bear; set +e + +this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" +readonly this_file this_dir="${this_file%/*}" e() { echo "$*"; "$@"; } @@ -36,11 +37,11 @@ cd $mount_dir e rm -rf debian-wheezy mkdir debian-wheezy cd debian-wheezy -e $src/debian-preseed "$@" # my script +e $this_dir/debian-preseed "$@" # my script cd .. e rm -f tftpboot e ln -s debian-wheezy tftpboot cd / e umount $mount_dir -e $src/pxe-server default plain # my script +e $this_dir/pxe-server default plain # my script diff --git a/fai-redep b/fai-redep index 5e08b2f..250b458 100755 --- a/fai-redep +++ b/fai-redep @@ -1,18 +1,35 @@ #!/bin/bash -# Copyright (C) 2019 Ian Kelling -# SPDX-License-Identifier: AGPL-3.0-or-later -set -eE -o pipefail -trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR +# This file is part of Ian Kelling's automated-distro-installer +# Copyright (C) 2024 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. + [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" -readonly this_file="$(readlink -f -- "${BASH_SOURCE[0]}")"; cd "${this_file%/*}" +set -eE -o pipefail +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR + +this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" +readonly this_file this_dir="${this_file%/*}" +cd "$this_dir" -source bash-trace usage() { - cat <&2 ; usage 1 ;; esac shift done -host=${1:-faiserver} +host=${1:-faiserver.b8.nz} readonly host distro target ##### end command line parsing ######## -m() { printf "$pre %s\n" "$*"; "$@"; } +m() { printf "fai-redep: %s\n" "$*"; "$@"; } # i use faiserver as a dns alias, but ssh key is associated with # a canonical hostname and we will have ssh warning spam unless we @@ -63,8 +80,19 @@ faiserver_host=$(/a/exe/chost $host) # faiserver_host=$host faiserver_addr=$(host $host | sed -rn 's/^\S+ has address //p;T;q' ||:) + +rsrv() { + local -a opts + while [[ $2 ]]; do + opts+=("$1") + shift + done + m rsync "${ropts[@]}" "${opts[@]}" "$rpath$1" +} +rpath=/srv if ! ip a | grep "^ *inet.\? $faiserver_addr" &>/dev/null; then - rpre=(-e "ssh -F $HOME/.ssh/confighome" root@$faiserver_host:) + ropts=(-e "ssh -F $HOME/.ssh/confighome") + rpath="root@$faiserver_host:/srv" faiserver_shell="ssh -F $HOME/.ssh/confighome root@$faiserver_host" fi @@ -75,16 +103,15 @@ rsync -atL /home/iank/.ssh/authorized_keys fai/config/files/root/.ssh/authorized install --owner=iank --group=iank -d fai/config/files/usr/local/bin/hssh install --owner=iank --group=iank -d fai/config/files/usr/local/bin/ssh_filter_btrbk.sh rsync -atL /a/opt/btrbk/ssh_filter_btrbk.sh fai/config/files/usr/local/bin/ssh_filter_btrbk.sh/STANDARD - -m rsync -rlpt --delete --relative --exclude /fai/config/basefiles/ fai/config /a/opt/btrfs-progs-release "${rpre[@]}"/srv +rsrv -rlpt --delete --relative --exclude /fai/config/basefiles/ fai/config / # todo: automatically disable faiserver after a period so # these files are not available. + if [[ $target ]]; then secret_files=(luks/$target luks/host-$target shadow/$target) exists=false - secret_exists=() for f in ${secret_files[@]}; do if [[ -e /q/root/$f ]]; then exists=true @@ -96,22 +123,28 @@ if [[ $target ]]; then for f in ${secrets_to_send[@]}; do echo $f done - } | rsync -lpt --files-from=- /q/root "${rpre[@]}"/srv/fai/config/distro-install-common + } | rsrv -lpt --files-from=- /q/root /fai/config/distro-install-common fi else - rsync -rlpt /q/root/shadow /q/root/luks "${rpre[@]}"/srv/fai/config/distro-install-common + rsrv -rlpt /q/root/shadow /q/root/luks /fai/config/distro-install-common fi +rsrv -rlpt --delete /a/opt/btrfs-progs-release /fai/config/distro-install-common + dirs=(/p/c/machine_specific/${target:-*}/filesystem/etc/ssh) if [[ -e ${dirs[0]} ]]; then - rsync -rlpt --delete --relative ${dirs[@]} "${rpre[@]}"/srv/fai/config/distro-install-common + rsrv -rlpt --delete --relative ${dirs[@]} /fai/config/distro-install-common fi . /a/bin/distro-setup/pkgs -pall+=($(/a/bin/buildscripts/emacs -p; /a/bin/distro-setup/distro-pkgs $distro)) +tmpstr=$(/a/bin/buildscripts/emacs -p && /a/bin/distro-setup/distro-pkgs $distro) +declare -a pall +for p in $tmpstr; do + pall+=($p) +done printf "%s\n%s\n" "PACKAGES install" ${pall[*]} | \ $faiserver_shell dd of=/srv/fai/config/package_config/DESKTOP status=none ||: # broken pipe -rsync -rplt --include '/*.gz' --exclude '/**' --delete-excluded $BASEFILE_DIR/ "${rpre[@]}"/srv/fai/config/basefiles/ +rsrv -rplt --include '/*.zst' --exclude '/**' --delete-excluded $BASEFILE_DIR/ /fai/config/basefiles/ diff --git a/fai-revm b/fai-revm index 050ecda..6bada5e 100755 --- a/fai-revm +++ b/fai-revm @@ -18,12 +18,12 @@ [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" +set -e; . /usr/local/lib/bash-bear; set +e + +this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" +readonly this_file this_dir="${this_file%/*}" +cd "$this_dir" -readonly this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" -script_dir="${this_file%/*}" -# shellcheck source=./bash-trace -source "${script_dir}/bash-trace" -cd $script_dir PATH="$PATH:$PWD" e() { echo "$*"; "$@"; } @@ -88,19 +88,24 @@ disk_count=1 rm -f /tmp/fai-revm-did-pxe -if ! ip l show br0 &>/dev/null; then - cat <<'EOF' -fai-rvm error: no bridge detected. add one to interfaces like this: -iface eth0 inet manual -iface br0 inet dhcp - bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 -EOF - exit 1 +if ip l show br0 &>/dev/null; then + net_arg="-w bridge=br0,mac=52:54:00:9c:ef:ad" +else + # if this computer has ethernet, we could setup a br0 like so: + # cat <<'EOF' + # fai-rvm error: no bridge detected. add one to interfaces like this: + # iface eth0 inet manual + # iface br0 inet dhcp + # bridge_ports eth0 + # bridge_stp off + # bridge_maxwait 0 + # EOF + + # if we only have wifi, cant use eth0 + net_arg="-w network=default,mac=52:54:00:9c:ef:ad" fi -if [[ $script_dir == /a/bin/* ]]; then +if [[ $this_dir == /a/bin/* ]]; then # Copy our script elsewhere so we can develop it # and save it at the same time it's running rm -rf /tmp/faifreeze @@ -140,13 +145,13 @@ else BASEFILE_DIR=/tmp fi isopath=$BASEFILE_DIR/$iso - isosrc=$BASEFILE_DIR/BOOKWORM64.tar.gz + isosrc=$BASEFILE_DIR/BOOKWORM64.tar.zst if [[ ! -e $isopath || $(stat -c %Y $isopath) -lt $(stat -c %Y $isosrc) ]]; then e fai-cd -g $(readlink -f grub.cfg.${iso%%.*}) -f -A $isopath fi boot_arg="--cdrom $isopath" e fai-redep - cat ~/.ssh/demo.pub | /a/exe/cedit -s /srv/fai/nfsroot/root/.ssh/authorized_keys + /a/exe/cedit -s /srv/fai/nfsroot/root/.ssh/authorized_keys <~/.ssh/demo.pub e myfai-chboot default fi # I don't think these variants actually make a diff for us, but I @@ -165,7 +170,7 @@ e virsh destroy $name ||: e virsh undefine $name ||: sleep 1 - +## begin virtual disk creation ## disk_arg=() for ((i=1; i <= disk_count; i++)); do f=/var/lib/libvirt/images/${name}$i @@ -178,6 +183,7 @@ for ((i=1; i <= disk_count; i++)); do e qemu-img create -o preallocation=metadata -f qcow2 $f 50G fi done +## end virtual disk creation ## if [[ $SSH_CLIENT ]]; then console_arg=--noautoconsole @@ -202,7 +208,7 @@ fi e systemctl start libvirtd e virt-install --rng /dev/urandom --os-variant $variant -n $name $boot_arg -r 2048 --vcpus $cpus \ - ${disk_arg[*]} -w bridge=br0,mac=52:54:00:9c:ef:ad $reboot_arg \ + ${disk_arg[*]} $net_arg $reboot_arg \ --graphics spice,listen=0.0.0.0 $console_arg |& grep -v '^ *$' | uniq & diff --git a/fai-wrapper b/fai-wrapper index 5efa7f1..b6a75d3 100644 --- a/fai-wrapper +++ b/fai-wrapper @@ -1,6 +1,20 @@ #!/bin/bash -# Copyright (C) 2019 Ian Kelling -# SPDX-License-Identifier: AGPL-3.0-or-later +# This file is part of Ian Kelling's automated-distro-installer +# Copyright (C) 2024 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. # For using some fai commands outside of fai. # Usually this is sourced from another script. Note this has @@ -11,7 +25,7 @@ export FAI_WRAPPER=true ifclass() { local var=${1/#/CLASS_} - [[ $HOSTNAME == $1 || ${!var} ]] + [[ $HOSTNAME == "$1" || ${!var} ]] } fai-setclass() { for class in "$@"; do diff --git a/fai/config/basefiles/mk-basefile b/fai/config/basefiles/mk-basefile index b81965f..d449c60 100755 --- a/fai/config/basefiles/mk-basefile +++ b/fai/config/basefiles/mk-basefile @@ -1,15 +1,17 @@ #! /bin/bash # mk-basefile, create basefiles for some distributions # -# Thomas Lange, Uni Koeln, 2011-2021 +# Thomas Lange, Uni Koeln, 2011-2024 # based on the Makefile implementation of Michael Goetze # # Usage example: mk-basefile -J STRETCH64 # This will create a STRETCH64.tar.xz basefile. -# Supported distributions (each i386/amd64): +# Supported distributions (i386/amd64): # Debian GNU/Linux -# Ubuntu 14.04/16.04 +# Ubuntu 14.04/16.04/20.04/22.04 +# AlmaLinux 9 +# Rocky Linux 8/9 # CentOS 5/6/7/8 # Scientific Linux Cern 5/6 # @@ -32,6 +34,7 @@ EXCLUDE_BUSTER= EXCLUDE_BULLSEYE= EXCLUDE_BOOKWORM= EXCLUDE_TRIXIE= +EXCLUDE_FORKY= EXCLUDE_SID= EXCLUDE_BELENOS=dhcp3-client,dhcp3-common,info @@ -42,8 +45,9 @@ EXCLUDE_BIONIC=udhcpc,dibbler-client,info EXCLUDE_ETIONA=udhcpc,dibbler-client,info EXCLUDE_FOCAL=udhcpc,dibbler-client,info EXCLUDE_NABIA=udhcpc,dibbler-client,info -EXCLUDE_JAMMY= -EXCLUDE_ARAMO= +EXCLUDE_JAMMY=udhcpc,dibbler-client,info +EXCLUDE_ARAMO=udhcpc,dibbler-client,info +EXCLUDE_NOBLE=udhcpc,dibbler-client,info # here you can add packages, that are needed very early INCLUDE_DEBIAN= @@ -127,7 +131,8 @@ cleanup-deb() { chroot $xtmp apt-get clean rm -f $xtmp/etc/hostname $xtmp/etc/resolv.conf \ $xtmp/var/lib/apt/lists/*_* $xtmp/usr/bin/qemu-*-static \ - $xtmp/etc/udev/rules.d/70-persistent-net.rules + $xtmp/etc/udev/rules.d/70-persistent-net.rules \ + $xtmp/var/lib/dbus/machine-id > $xtmp/etc/machine-id } @@ -154,6 +159,30 @@ tarit() { } +rpmdist() { + + local arch=$1 + local vers=$2 + local dist=$3 + local domain=$(domainname) + + check + setarch $arch + $l32 rinse --directory $xtmp --distribution $dist-$vers --arch $arch --before-post-install $xtmp/post + domainname $domain # workaround for #613377 + cleanup-rinse + tarit +} + + +alma() { + rpmdist $1 $2 alma +} + +rocky() { + rpmdist $1 $2 rocky +} + centos() { local arch=$1 @@ -220,6 +249,9 @@ prtdists() { echo "Available: + ALMA9_64 + ROCKY8_64 + ROCKY9_64 CENTOS5_32 CENTOS5_64 CENTOS6_32 CENTOS6_64 CENTOS7_32 CENTOS7_64 @@ -236,6 +268,7 @@ prtdists() { NABIA64 JAMMY64 ARAMO64 + NOBLE64 SQUEEZE32 SQUEEZE64 WHEEZY32 WHEEZY64 JESSIE32 JESSIE64 @@ -244,6 +277,7 @@ prtdists() { BULLSEYE32 BULLSEYE64 BOOKWORM32 BOOKWORM64 TRIXIE32 TRIXIE64 + FORKY32 FORKY64 SID32 SID64 " } @@ -253,14 +287,14 @@ usage() { cat <&/dev/null && dpkg --print-architecture | tr a-z A-Z # determin if we are a DHCP client or not diff --git a/fai/config/class/20-hwdetect.sh b/fai/config/class/20-hwdetect.sh index 57374c8..b04a948 100755 --- a/fai/config/class/20-hwdetect.sh +++ b/fai/config/class/20-hwdetect.sh @@ -1,6 +1,6 @@ #! /bin/bash -# (c) Thomas Lange, 2002-2013, lange@informatik.uni-koeln.de +# (c) Thomas Lange, 2002-2013, lange@cs.uni-koeln.de # NOTE: Files named *.sh will be evaluated, but their output ignored. @@ -8,12 +8,11 @@ echo 0 > /proc/sys/kernel/printk -#kernelmodules= -# here, you can load modules depending on the kernel version -case $(uname -r) in - 2.6*) kernelmodules="$kernelmodules mptspi dm-mod md-mod aes dm-crypt" ;; - [3456]*) kernelmodules="$kernelmodules mptspi dm-mod md-mod aes dm-crypt" ;; -esac +# example how to load modules depending on the kernel version +#case $(uname -r) in +# 2.6*) kernelmodules="$kernelmodules mptspi dm-mod md-mod aes dm-crypt" ;; +# [3456]*) kernelmodules="$kernelmodules mptspi dm-mod md-mod aes dm-crypt" ;; +#esac for mod in $kernelmodules; do [ X$verbose = X1 ] && echo Loading kernel module $mod diff --git a/fai/config/class/40-parse-profiles.sh b/fai/config/class/40-parse-profiles.sh index 0fed6ee..cb11c17 100755 --- a/fai/config/class/40-parse-profiles.sh +++ b/fai/config/class/40-parse-profiles.sh @@ -2,7 +2,7 @@ # parse *.profile and build a curses menu, so the user can select a profile # -# (c) 2015 by Thomas Lange, lange@informatik.uni-koeln.de +# (c) 2015 by Thomas Lange, lange@cs.uni-koeln.de # Universitaet zu Koeln if [ X$FAI_ACTION = Xinstall -o X$FAI_ACTION = Xdirinstall -o X$FAI_ACTION = X ]; then @@ -14,6 +14,8 @@ fi [ "$flag_menu" ] || return 0 out=$(tty) +# save stdout and redirect stdout to tty +exec 4>&1 > $out tempfile=$(mktemp) tempfile2=$(mktemp) trap "rm -f $tempfile $tempfile2" EXIT INT QUIT @@ -147,8 +149,7 @@ while true; do dialog --clear --item-help --title "FAI - Fully Automatic Installation" --help-button \ --default-item "$default" \ --menu "\nSelect your FAI profile\n\nThe profile will define a list of classes,\nwhich are used by FAI.\n\n\n"\ - 15 70 0 "${par[@]}" 2> $tempfile 1> $out - + 15 70 0 "${par[@]}" 2> $tempfile _retval=$? case $_retval in 0) @@ -158,8 +159,10 @@ while true; do echo "No profile selected." break ;; 2) - dialog --title "Description of all profiles" --textbox $tempfile2 0 0 1> $out;; + dialog --title "Description of all profiles" --textbox $tempfile2 0 0 ;; esac done unset par ardesc arshort arlong arclasses list tempfile tempfile2 _parsed _retval line + +exec 1>&4 # restore stdout diff --git a/fai/config/class/41-warning.sh b/fai/config/class/41-warning.sh index e9f9ec5..f66085d 100755 --- a/fai/config/class/41-warning.sh +++ b/fai/config/class/41-warning.sh @@ -13,11 +13,13 @@ grep -q INSTALL $LOGDIR/FAI_CLASSES || return 0 [ "$flag_menu" ] || return 0 out=$(tty) +# save stdout and redirect stdout to tty +exec 4>&1 > $out red=$(mktemp) echo 'screen_color = (CYAN,RED,ON)' > $red DIALOGRC=$red dialog --colors --clear --aspect 6 --title "FAI - Fully Automatic Installation" --trim \ - --msgbox "\n\n If you continue, \n all your data on the disk \n \n|\Zr\Z1 WILL BE DESTROYED \Z0\Zn|\n\n" 0 0 1>$out + --msgbox "\n\n If you continue, \n all your data on the disk \n \n|\Zr\Z1 WILL BE DESTROYED \Z0\Zn|\n\n" 0 0 # stop on any error, or if ESC was hit if [ $? -ne 0 ]; then @@ -26,3 +28,4 @@ fi rm $red unset red +exec 1>&4 # restore stdout diff --git a/fai/config/class/60-misc b/fai/config/class/60-misc index 1c3b4fd..01eb252 100755 --- a/fai/config/class/60-misc +++ b/fai/config/class/60-misc @@ -1,7 +1,5 @@ #! /bin/bash -ifclass -o CENTOS SLC && exit 0 - ifclass -o GRUB_PC GRUB_EFI && exit 0 if [ -d /sys/firmware/efi ]; then diff --git a/fai/config/class/85-efi-classes b/fai/config/class/85-efi-classes index 711b534..afe6f49 100755 --- a/fai/config/class/85-efi-classes +++ b/fai/config/class/85-efi-classes @@ -6,7 +6,7 @@ if [ ! -d /sys/firmware/efi ] || ifclass GRUB_PC; then exit 0 fi -for c in LVM FAISERVER FAIBASE; do +for c in CLOUD LVM FAISERVER FAIBASE; do if ifclass $c; then echo ${c}_EFI break diff --git a/fai/config/class/DEBIAN.var b/fai/config/class/DEBIAN.var index a00d0f8..18b49b5 100644 --- a/fai/config/class/DEBIAN.var +++ b/fai/config/class/DEBIAN.var @@ -1,5 +1,5 @@ # ian, commented, sources are set with fcopy -# release=bullseye +# release=bookworm # apt_cdn=http://deb.debian.org # security_cdn=http://security.debian.org @@ -25,4 +25,25 @@ MODULESLIST="usbhid psmouse" FAI_RAMDISKS="$target/var/lib/dpkg $target/var/cache" # if you want to use the faiserver as APT proxy -# APTPROXY=http://faiserver:3142 +#APTPROXY=http://faiserver:3142 + + +# The linux-image package has different names for Debian and Ubuntu +if ifclass UBUNTU; then + kernelname=linux-image-generic +elif ifclass I386; then + kernelname=linux-image-686-pae +elif ifclass AMD64; then + kernelname=linux-image-amd64 +fi + +if [ -z "kernelname" ]; then + _arch=$(dpkg --print-architecture 2>/dev/null) + case $_arch in + i386) + kernelname=linux-image-686-pae ;; + *) + kernelname=linux-image-$_arch + esac + unset _arch +fi diff --git a/fai/config/class/DEFAULT.var b/fai/config/class/DEFAULT.var index a999512..d574d7d 100644 --- a/fai/config/class/DEFAULT.var +++ b/fai/config/class/DEFAULT.var @@ -6,7 +6,10 @@ LOGUSER=fai # when downloading from https intead of nfs, this is not set, # it is used as the default for LOGSERVER, and for calling chboot. # My faiserver's hostname is always faiserver, so just hardcoding it. -SERVER=faiserver +# I used bare host in the past, thinking that I could vary this +# between different networks I was on, but it is simpler to just +# user an internet domain that I control. +SERVER=faiserver.b8.nz # busted for debian, no time to troubleshoot atm #APTPROXY=http://faiserver:3142 diff --git a/fai/config/class/FAIBASE.var b/fai/config/class/FAIBASE.var index 34d95ac..2492def 100644 --- a/fai/config/class/FAIBASE.var +++ b/fai/config/class/FAIBASE.var @@ -16,6 +16,10 @@ STOP_ON_ERROR=700 # set parameter for install_packages(8) MAXPACKAGES=800 +# Account on the FAI server for saving log files and calling fai-chboot. +# Remove the hash character in the next line to activate this feature +#LOGUSER=fai + # a user account will be created #username=demo #USERPW='$1$kBnWcO.E$djxB128U7dMkrltJHPf6d1' diff --git a/fai/config/class/ROCKY.var b/fai/config/class/ROCKY.var new file mode 100644 index 0000000..1ec7250 --- /dev/null +++ b/fai/config/class/ROCKY.var @@ -0,0 +1,9 @@ +CONSOLEFONT=lat9v-16 +KEYMAP=us +DEFAULTLOCALE=en_US.UTF-8 +SUPPORTEDLOCALE=en_US.UTF-8:en_US:en + +# if you install much software and have only few RAM, use the RAM disk +# not for var/cache/yum +#FAI_RAMDISKS="$target/var/lib/rpm $target/var/cache/yum" +FAI_RAMDISKS="$target/var/lib/rpm" diff --git a/fai/config/class/UBUNTU.var b/fai/config/class/UBUNTU.var index 6a42495..a453a88 100644 --- a/fai/config/class/UBUNTU.var +++ b/fai/config/class/UBUNTU.var @@ -1,4 +1,4 @@ #iank, i define these by classes. commenting # to make sure these arent used #ubuntumirror=http://archive.ubuntu.com -#ubuntudist=focal +#ubuntudist=jammy diff --git a/fai/config/class/example.profile b/fai/config/class/example.profile index cbcbf82..c55a3ca 100644 --- a/fai/config/class/example.profile +++ b/fai/config/class/example.profile @@ -25,21 +25,21 @@ You should have a fast network connection, because most packages are downloaded from the internet. Classes: INSTALL FAIBASE DEBIAN DEMO XORG GNOME -Name: CentOS 8 -Description: CentOS 8 with Xfce desktop -Short: A normal Xfce desktop, running CentOS 8 -Long: We use the Debian nfsroot for installing the CentOS 8 OS. +Name: Rocky Linux +Description: Rocky Linux 9 with Xfce desktop +Short: A normal Xfce desktop, running Rocky Linux 9 +Long: We use the Debian nfsroot for installing the Rocky Linux 9 OS. You should have a fast network connection, because most packages are downloaded from the internet. -Classes: INSTALL FAIBASE CENTOS CENTOS8_64 XORG +Classes: INSTALL FAIBASE ROCKY ROCKY9_64 XORG Name: Ubuntu -Description: Ubuntu 20.04 LTS desktop installation +Description: Ubuntu 22.04 LTS desktop installation Short: Unity desktop Long: We use the Debian nfsroot for installing the Ubuntu OS. You should have a fast network connection, because most packages are downloaded from the internet. -Classes: INSTALL FAIBASE DEMO DEBIAN UBUNTU FOCAL FOCAL64 XORG +Classes: INSTALL FAIBASE DEMO DEBIAN UBUNTU JAMMY JAMMY64 XORG Name: Inventory Description: Show hardware info diff --git a/fai/config/disk_config/CLOUD_EFI b/fai/config/disk_config/CLOUD_EFI new file mode 100644 index 0000000..0e15072 --- /dev/null +++ b/fai/config/disk_config/CLOUD_EFI @@ -0,0 +1,8 @@ +# config for a disk image for a VM +# +# p= + +disk_config disk1 disklabel:gpt bootable:1 fstabkey:uuid align-at:1M + +p=efi /boot/efi 64M vfat defaults createopts="-F 32" +p=root / 300- ext4 rw,discard,barrier=0,noatime,errors=remount-ro tuneopts="-c 0 -i 0" diff --git a/fai/config/disk_config/FAIBASE b/fai/config/disk_config/FAIBASE index 0c66cbc..bbcffe3 100644 --- a/fai/config/disk_config/FAIBASE +++ b/fai/config/disk_config/FAIBASE @@ -2,6 +2,9 @@ # # +# you may want to add "-O ^metadata_csum_seed" to createopts if the target +# system is older than bullseye. See #866603, #1031415, #1031416 for more info. + disk_config disk1 disklabel:msdos bootable:1 fstabkey:uuid primary / 2G-50G ext4 rw,noatime,errors=remount-ro diff --git a/fai/config/disk_config/FAIBASE_EFI b/fai/config/disk_config/FAIBASE_EFI index 8ff0e4b..cc2ed9c 100644 --- a/fai/config/disk_config/FAIBASE_EFI +++ b/fai/config/disk_config/FAIBASE_EFI @@ -1,10 +1,13 @@ # example of new config file for setup-storage # -# +# p= + +# you may want to add "-O ^metadata_csum_seed" to createopts if the target +# system is older than bullseye. See #866603, #1031415, #1031416 for more info. disk_config disk1 disklabel:gpt bootable:1 fstabkey:uuid -primary /boot/efi 512M vfat rw -primary / 2G-50G ext4 rw,noatime,errors=remount-ro -primary swap 200-10G swap sw -primary /home 100- ext4 rw,noatime,nosuid,nodev createopts="-L home -m 1" tuneopts="-c 0 -i 0" +p=efi /boot/efi 512M vfat rw +p=root / 2G-50G ext4 rw,noatime,errors=remount-ro +p= swap 200-10G swap sw +p=home /home 100- ext4 rw,noatime,nosuid,nodev createopts="-L home -m 1" tuneopts="-c 0 -i 0" diff --git a/fai/config/disk_config/FAISERVER_EFI b/fai/config/disk_config/FAISERVER_EFI index 30adbe3..e11020c 100644 --- a/fai/config/disk_config/FAISERVER_EFI +++ b/fai/config/disk_config/FAISERVER_EFI @@ -1,12 +1,12 @@ # config file for an FAI install server # -# +# p= disk_config disk1 disklabel:gpt fstabkey:uuid -primary /boot/efi 512M vfat rw -primary / 2G-15G ext4 rw,noatime,errors=remount-ro -primary swap 200-1000 swap sw -primary /tmp 100-1000 ext4 rw,noatime,nosuid,nodev createopts="-m 0" tuneopts="-c 0 -i 0" -primary /home 100-40% ext4 rw,noatime,nosuid,nodev createopts="-m 1" tuneopts="-c 0 -i 0" -primary /srv 1G-50% ext4 rw,noatime createopts="-m 1" tuneopts="-c 0 -i 0" +p=efi /boot/efi 512M vfat rw +p=system / 2G-15G ext4 rw,noatime,errors=remount-ro +p=swap swap 200-1000 swap sw +p= /tmp 100-1000 ext4 rw,noatime,nosuid,nodev createopts="-m 0" tuneopts="-c 0 -i 0" +p=home /home 100-40% ext4 rw,noatime,nosuid,nodev createopts="-m 1" tuneopts="-c 0 -i 0" +p=data /srv 1G-50% ext4 rw,noatime createopts="-m 1" tuneopts="-c 0 -i 0" diff --git a/fai/config/disk_config/LVM b/fai/config/disk_config/LVM index 868970a..71e55d3 100644 --- a/fai/config/disk_config/LVM +++ b/fai/config/disk_config/LVM @@ -4,8 +4,8 @@ disk_config disk1 fstabkey:uuid align-at:1M -primary /boot 200 ext2 rw,noatime -primary - 4G- - - +primary /boot 500 ext4 rw,noatime +primary - 4G- - - disk_config lvm diff --git a/fai/config/disk_config/LVM_EFI b/fai/config/disk_config/LVM_EFI index b2609a5..037cb51 100644 --- a/fai/config/disk_config/LVM_EFI +++ b/fai/config/disk_config/LVM_EFI @@ -1,12 +1,12 @@ -# +# p= # entire disk with LVM, separate /home disk_config disk1 disklabel:gpt fstabkey:uuid align-at:1M -primary /boot/efi 512M vfat rw -primary /boot 200 ext2 rw,noatime -primary - 4G- - - +p=efi /boot/efi 512M vfat rw +p=boot /boot 500 ext4 rw,noatime +p=system - 4G- - - disk_config lvm diff --git a/fai/config/disk_config/ROCKY b/fai/config/disk_config/ROCKY new file mode 100644 index 0000000..7b03a39 --- /dev/null +++ b/fai/config/disk_config/ROCKY @@ -0,0 +1,13 @@ +# example of new config file for setup-storage +# +# + +# you may want to add "-O ^metadata_csum_seed" to createopts if the target +# system is older than bullseye. See #866603, #1031415, #1031416 for more info. + +disk_config disk1 disklabel:msdos bootable:1 fstabkey:label + +primary / 4G-50G ext4 rw,noatime,errors=remount-ro createopts="-L ROOT" + +logical swap 200-10G swap sw createopts="-L SWAP" +logical /home 100- ext4 rw,noatime,nosuid,nodev createopts="-L HOME -m 1" tuneopts="-c 0 -i 0" diff --git a/fai/config/distro-install-common/end b/fai/config/distro-install-common/end index f9a0840..2455ece 100755 --- a/fai/config/distro-install-common/end +++ b/fai/config/distro-install-common/end @@ -32,7 +32,9 @@ au() { # add user. i don't use adduser for portability # only setup root pass for bootstrap vol -if ifclass VOL_BULLSEYE_BOOTSTRAP || VOL_BOOKWORM_BOOTSTRAP; then +# for bootstrap vol, we only use root user +if ifclass VOL_BULLSEYE_BOOTSTRAP || ifclass VOL_BOOKWORM_BOOTSTRAP; then + sed 's/^/root:/' $root_pw_f | $ROOTCMD chpasswd -e exit 0 fi @@ -74,6 +76,7 @@ if getent group sudo >/dev/null; then $ROOTCMD usermod -aG sudo iank fi +mkdir -p $target/etc/sudoers.d cat >$target/etc/sudoers.d/ianksudoers <<'EOF' Defaults timestamp_timeout=1440 # used in bashrc diff --git a/fai/config/distro-install-common/ethusb-static b/fai/config/distro-install-common/ethusb-static new file mode 100755 index 0000000..c55b93d --- /dev/null +++ b/fai/config/distro-install-common/ethusb-static @@ -0,0 +1,204 @@ +#!/bin/bash +# I, Ian Kelling, follow the GNU license recommendations at +# https://www.gnu.org/licenses/license-recommendations.en.html. They +# recommend that small programs, < 300 lines, be licensed under the +# Apache License 2.0. This file contains or is part of one or more small +# programs. If a small program grows beyond 300 lines, I plan to switch +# its license to GPL. + +# Copyright 2024 Ian Kelling + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# usage $0 [-c] [off] +# off: Turn off static ip. +# -c config only, don't tell networkmanager to change anything +# -f force interface reup + +if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi +shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4 +set -eE -o pipefail +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR + +[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" + +m() { printf "%s\n" "$*"; "$@"; } + +## begin arg parsing ## + +force=false +conf_only=false +comment='# iank file id: ethusb-dhcp-v1' +off=false +while [[ $1 ]]; do + case $1 in + -c) + conf_only=true + ;; + -f) + force=true + ;; + off) + off=true + comment='# iank file id: ethusb-static-v1' + ;; + *) + echo "$0: error unexpected argument: $1" >&2 + exit 1 + ;; + esac + shift +done + +## end arg parsing ## + + +shopt -s nullglob + +# we already configured the interface once, afterwards, comment and +# uncomment to enable/disable. This makes it so we don't depend on /p +# being mounted. + +conf=/etc/NetworkManager/system-connections/ethusb-static.nmconnection +if ! $force && [[ -s $conf ]] && grep -qFx "$comment" $conf; then + # we already ran successfully in the past to set things this way, so + # do nothing. + exit 0 +fi + + +if [[ $(dig +short @10.2.0.1 -x 10.2.0.2 2>&1 ||:) == kd.b8.nz. ]] \ + && ip n show 10.2.0.1 | grep . &>/dev/null; then + # we are at_home=true + + while read -r ip_suf host mac; do + if [[ $mac != usb ]]; then + continue + fi + if [[ $host == ${HOSTNAME}c ]]; then + + net_info="address1=10.2.0.$ip_suf/16,10.2.0.1 +dns=8.8.8.4;8.8.8.8;" + + break + fi + done

/dev/null; then + apt-get install dig + fi + ip=$(dig +short @192.168.0.25 $HOSTNAME.office.fsf.org) + net_info="address1=$ip/24,192.168.0.1 +dns=192.168.0.10;192.168.0.25;" +fi + +wiredx= + +# device that has an eth0, but we aren't using it because it is +# broken. We could just hardcode a mac comparison with `cat +# /sys/class/net/eth0/address` but this is cooler. +if [[ -e /sys/class/net/eth0 ]]; then + bus_info=$(ethtool -i eth0 | awk '$1 == "bus-info:" { print $2 }') + if [[ $bus_info != usb* ]]; then + wiredx=2 + fi +fi + +ethx=$(( wiredx - 1 )) + + + +uuid=$(nmcli con show "Wired connection $wiredx" 2>/dev/null | awk '$1 == "connection.uuid:" {print $2}' ||:) +if [[ ! $uuid ]]; then + # just a uuid that nm generated for me at some point + uuid=0da4c614-6a3c-3ad2-8d4b-c6eebe0814c3 +fi + + +# This template is the result of running, for example +# nmcli con mod "Wired connection 1" \ + # ipv4.addresses "10.2.0.23/24" \ + # ipv4.gateway "10.2.0.1" \ + # ipv4.dns "8.8.8.4,8.8.8.8" + +# which creates a fille named "Wired connection 1.nmconnection", +# below. I see no reason to keep the same file name, or a bunch of +# setting that seem irrelevant, and empty sections don't seem to do +# anything according to the man page. + +# [connection] +# id=Wired connection 2 +# uuid=b0fb7694-dfe6-31a1-81fa-7c17b61515a7 +# type=ethernet +# interface-name=eth1 +# timestamp=1715728264 + +# [ethernet] + +# [ipv4] +# address1=10.2.0.23/16,10.2.0.1 +# dns=8.8.8.4;8.8.8.8; +# method=manual + +# [ipv6] +# addr-gen-mode=stable-privacy +# method=auto + +# [proxy] + +{ + cat </dev/null | awk '$1 == "GENERAL.STATE:" {print $2}' ||:) + + reup=false + if [[ $state == activated ]]; then + reup=true + fi + + m nmcli con reload + + if $reup; then + m nmcli con down $uuid + m nmcli con up $uuid + fi +fi + +if ! grep -F "$comment" $conf; then + printf "%s\n" "$comment" >>$conf +fi diff --git a/fai/config/distro-install-common/install-mainline-kernel-debs b/fai/config/distro-install-common/install-mainline-kernel-debs new file mode 100755 index 0000000..93f7c57 --- /dev/null +++ b/fai/config/distro-install-common/install-mainline-kernel-debs @@ -0,0 +1,87 @@ +#!/bin/bash +# This file is part of Ian Kelling's automated-distro-installer +# Copyright (C) 2024 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. + +set -eE -o pipefail +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR + +[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" + +# default +kernel_ver='6\.6' +case $1 in + stable) + # note: update kernel_ver when we are ready to jump to a new stable kernel. + # Stable kernels are listed here: https://www.kernel.org/category/releases.html + kernel_ver='6\.6' + ;; + unstable) + kernel_ver='[1-9]' + ;; +esac + + +prereqs=() +for p in wget curl; do + if ! type -p $p &>/dev/null; then + prereqs+=($p) + fi +done +if (( ${#prereqs[@]} >= 1 )); then + apt-get -y install ${prereqs[@]} +fi + + +tmpdir=$($ROOTCMD mktemp -d) || exit +# shellcheck disable=SC2154 # defined by fai +outertmp=$target/$tmpdir +trap 'cd; rm -rf "$outertmp"' EXIT +cd $outertmp + +# We get 10 versions cuz maybe the latest directory (or few) get created but not populated. +tmps=$(curl -s https://kernel.ubuntu.com/mainline/ | \ + sed -rn 's,.*alt="\[DIR\]".*href="([^/]+).*,\1,p' | \ + grep -v -- -rc | sed 's/^v//' | grep "^$kernel_ver" | sort -Vr | head -n10) +mapfile -t latest_versions <<<"$tmps" + +for va in "${latest_versions[@]}"; do + sleep .2 # be nice + # note the wiki page about these says to install linux-headers.*generic.*amd64, but + # as of 2024, they have a requirement of a very new glibc, and people report + # that installing it is not needed. + tmpstr=$(curl -s https://kernel.ubuntu.com/mainline/v$va/amd64/CHECKSUMS | awk '$2 ~ /^linux-/ { print $2 }' | sort -u | sed '/linux-headers.*generic.*amd64/d' ) + if [[ $tmpstr ]]; then + mapfile -t pkgs <<<"$tmpstr" + break + fi +done + +if (( ${#pkgs[@]} != 3 )); then + echo "$0: error. expected to find 3 kernel packages, got: ${pkgs[*]}" >&2 + exit 1 +fi + +urls=() +for p in ${pkgs[@]}; do + if ! $ROOTCMD dpkg -s -- "${p%%_*}" 2>&1 | grep -Fx "Status: install ok installed" &>/dev/null; then + urls+=(https://kernel.ubuntu.com/mainline/v$va/amd64/$p) + fi +done +if (( ${#urls[@]} >= 1 )); then + wget -nv "${urls[@]}" + $ROOTCMD dpkg -i ${pkgs[@]/#/$tmpdir/} +fi diff --git a/fai/config/distro-install-common/install-stable-kernel-debs b/fai/config/distro-install-common/install-stable-kernel-debs deleted file mode 100755 index c024796..0000000 --- a/fai/config/distro-install-common/install-stable-kernel-debs +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -x -# This file is part of Ian Kelling's automated-distro-installer -# Copyright (C) 2024 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. - -set -eE -o pipefail -trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR - -[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" - -tmpdir=$(mktemp -d) || exit -trap 'cd; rm -rf "$tmpdir"' EXIT -cd $tmpdir - -# update stable_ver when we are ready to jump to a new stable kernel. -# Stable kernels are listed here: https://www.kernel.org/category/releases.html -stable_ver='6\.6' -va=$(curl -s https://kernel.ubuntu.com/mainline/ | \ - sed -rn 's,.*alt="\[DIR\]".*href="([^/]+).*,\1,p' | \ - grep -v -- -rc | sed 's/^v//' | grep "^$stable_ver" | sort -V | tail -n1) - -# note the wiki page about these says to install linux-headers.*generic.*amd64, but -# as of 2024, they have a requirement of a very new glibc, and people report -# that installing it is not needed. -tmpstr=$(curl -s https://kernel.ubuntu.com/mainline/v$va/amd64/CHECKSUMS | awk '$2 ~ /^linux-/ { print $2 }' | sort -u | grep -iv 'linux-headers.*generic.*amd64' ) -mapfile -t pkgs <<<"$tmpstr" - -if (( ${#pkgs[@]} != 3 )); then - echo "$0: error. expected to find 3 kernel packages, got: ${pkgs[*]}" >&2 - exit 1 -fi - -urls=() -for p in ${pkgs[@]}; do - if ! dpkg -s -- "${p%%_*}" 2>&1 | grep -Fx "Status: install ok installed" &>/dev/null; then - urls+=(https://kernel.ubuntu.com/mainline/v$va/amd64/$p) - fi -done -if (( ${#urls[@]} >= 1 )); then - wget "${urls[@]}" - dpkg -i ./*.deb -fi diff --git a/fai/config/files/boot/bash-trace/DEFAULT b/fai/config/files/boot/bash-trace/DEFAULT deleted file mode 100644 index 2a4077f..0000000 --- a/fai/config/files/boot/bash-trace/DEFAULT +++ /dev/null @@ -1,298 +0,0 @@ -#!/bin/bash -# Bash Error Handler -# Copyright (C) 2020 Ian Kelling -# SPDX-License-Identifier: GPL-3.0-or-later -# -# 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 3 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, see . - - -# This is a single file library, just source this file. When an error -# happens, we print a stack trace then exit. In an interactive shell, we -# return from functions instead of exiting. If err-cleanup is a command, -# it runs before the stack trace. Functions are documented inline below -# for additional use cases. -# -# Note: occasionally the line numbers are off a bit (at least in Bash -# 5.0). This appears to be a bash bug. I plan to report it next time it -# happens to me. -# -# Please email me if you use this or have anything to contribute. I'm -# not aware of any users yet Ian Kelling . -# -# Tested on bash 4.4.20(1)-release (x86_64-pc-linux-gnu) and -# 5.0.17(1)-release (x86_64-pc-linux-gnu). -# -# Related: see my bash script template repo at https://iankelling.org/git. - - -# TODO: investigate to see if we can format output betting in case of -# subshell failure. Right now, we get independent trace from inside and -# outside of the subshell. Note, errexit + inherit_errexit doesn't have -# any smarts around this either. - -if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi - -####################################### -# err-catch: Setup trap on ERR to print stack trace and exit (or return -# if the shell is interactive). This is the most common use case so we -# run it after defining it, you can call err-allow to undo that. -# -# This also sets pipefail because it's a good practice to catch more -# errors. -# -# Note: In interactive shell, stack calling line number is not -# available, so we print function definition lines. -# -# Note: This works like set -e, which has one unintuitive feature: If -# you use a function as part of a conditional, eg: func && come_cmd, a -# failed command within func won't trigger an error. -# -# Globals -# -# err_catch_ignore Array containing glob patterns to test against -# filenames to ignore errors from in interactive -# shell. Initialized to ignore bash-completion -# scripts on debian based systems. -# -# err-cleanup If set, this command will run just before exiting. -# -# _err_func_last Used internally in err-bash-trace-interactive -# -####################################### -err-catch() { - set -E; - if [[ $- == *i* ]]; then - if ! test ${err_catch_ignore+defined}; then - err_catch_ignore=( - '/etc/bash_completion.d/*' - '*/bash-completion/*' - ) - fi - declare -i _err_func_last=0 - if [[ $- != *c* ]]; then - shopt -s extdebug - fi - # shellcheck disable=SC2154 - trap '_err-bash-trace-interactive $? "${PIPESTATUS[*]}" "$BASH_COMMAND" ${BASH_ARGC[0]} "${BASH_ARGV[@]}" || return $?' ERR - else - # Man bash on exdebug: "If set at shell invocation, arrange to - # execute the debugger". We want to avoid that, but I want this file - # to be sourceable from bash startup files. noninteractive ssh and - # sources .bashrc on invocation. login_shell sources things on - # invocation. - # - # extdebug allows us to print function arguments in our stack trace. - if ! shopt login_shell >/dev/null && [[ ! $SSH_CONNECTION ]]; then - shopt -s extdebug - fi - trap err-exit ERR - fi - set -o pipefail -} -# This is the most common use case so run it now. -err-catch - -####################################### -# Undo err-catch/err-catch-interactive -####################################### -err-allow() { - shopt -u extdebug - set +E +o pipefail - trap ERR -} - -####################################### -# err-exit: 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: $? if it is nonzero, otherwise 1. -# MESSAGE Print MESSAGE to stderr. Default: -# ${BASH_SOURCE[1]}:${BASH_LINENO[0]}: `$BASH_COMMAND' returned $? -# -# Globals -# -# err-cleanup If set, this command will run just before exiting. -# -####################################### -err-exit() { - # vars have _ prefix so that we can inspect existing set vars without - # too much overwriting of them. - local _err=$? _pipestatus="${_pipestatus[*]}" - - # This has to come before most things or vars get changed - local _msg="${BASH_SOURCE[1]}:${BASH_LINENO[0]}: \`$BASH_COMMAND' returned $_err" - local _cmdr="$BASH_COMMAND" # command right. we chop of the left, keep the right. - - if [[ $_pipestatus != "$_err" ]]; then - _msg+=", PIPESTATUS: $_pipestatus" - fi - set +x - if [[ $1 == -* ]]; then - _err=${1#-} - shift - elif (( ! _err )); then - _err=1 - fi - if [[ $1 ]]; then - _msg="$1" - fi - - ## Begin printing vars from within BASH_COMMAND ## - local _var _chars _l - local -A _vars - while [[ $_cmdr ]]; do - _chars="${#_cmdr}" - _cmdr="${_cmdr#*$}" - _cmdr="${_cmdr#{}" - if (( _chars == ${#_cmdr} )); then - break - fi - _var="${_cmdr%%[^a-zA-Z0-9_]*}" - if [[ ! $_var || $_var == [0-9]* ]]; then - continue - fi - _vars[${_var}]=t - done - #echo "iank ${_vars[*]}" - #set |& grep ^password - # in my small test, this took 50% longer than piping to grep. - # That seems a small enough penalty to stay in bash here. - if (( ${#_vars[@]} )); then - set |& while read -r _l; do - for _var in "${!_vars[@]}"; do - case $_l in - ${_var}=*) printf "%s\n" "$_l" >&2 ;; - esac - done - done - fi - ## End printing vars from within BASH_COMMAND ## - - printf "%s\n" "$_msg" >&2 - err-bash-trace 2 - set -e # err trap does not work within an error trap - if type -t err-cleanup >/dev/null; then - err-cleanup - fi - printf "%s: exiting with status %s\n" "$0" "$_err" >&2 - exit $_err -} - -####################################### -# Print stack trace -# -# usage: err-bash-trace [FRAME_START] -# -# 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 does for you. -# -# FRAME_START Optional variable to set before calling. The frame to -# start printing on. default=1. If ${#FUNCNAME[@]} <= -# FRAME_START + 1, don't print anything because we are at -# the top level of the script and better off printing a -# general message, for example see what our callers print. -# -####################################### -err-bash-trace() { - local -i argc_index=0 frame i frame_start=${1:-1} - local source_loc - if (( ${#FUNCNAME[@]} <= frame_start + 1 )); then - return 0 - fi - for ((frame=0; frame < ${#FUNCNAME[@]}; frame++)); do - argc=${BASH_ARGC[frame]} - argc_index+=$argc - if ((frame < frame_start)); then continue; fi - if (( ${#BASH_SOURCE[@]} > 1 )); then - source_loc="${BASH_SOURCE[frame]}:${BASH_LINENO[frame-1]}:" - fi - printf " from %sin \`%s" "$source_loc" "${FUNCNAME[frame]}" >&2 - if shopt extdebug >/dev/null; then - for ((i=argc_index-1; i >= argc_index-argc; i--)); do - printf " %s" "${BASH_ARGV[i]}" >&2 - done - fi - echo \' >&2 - done - return 0 -} - -####################################### -# Internal function for err-catch. Prints stack trace from interactive -# shell trap. -# -# Usage: see err-catch-interactive -####################################### -_err-bash-trace-interactive() { - if (( ${#FUNCNAME[@]} <= 1 )); then - return 0 - fi - - for pattern in "${err_catch_ignore[@]}"; do - # shellcheck disable=SC2053 - if [[ ${BASH_SOURCE[1]} == $pattern ]]; then - return 0 - fi - done - - local ret bash_command argc pattern i last - last=$_err_func_last - _err_func_last=${#FUNCNAME[@]} - # We have these passed to us because they are lost inside the - # function. - ret=$1 - pipestatus="$2" - bash_command="$3" - argc=$(( $4 - 1 )) - shift 4 - argv=("$@") - # The trap returns a nonzero, then gets called again. This condition - # tells us if is that has happened by checking if we've gone down a - # stack level. - if (( _err_func_last >= last )); then - printf "ERR: \`%s\' returned %s" "$bash_command" $ret >&2 - if [[ $pipestatus != "$ret" ]]; then - printf ", PIPESTATUS: %s" "$pipestatus" >&2 - fi - echo >&2 - fi - printf " from \`%s" "${FUNCNAME[1]}" >&2 - if shopt extdebug >/dev/null; then - for ((i=argc; i >= 0; i--)); do - printf " %s" "${argv[i]}" >&2 - done - fi - printf "\' defined at %s:%s\n" "${BASH_SOURCE[1]}" "$(declare -F "${FUNCNAME[1]}"|awk "{print \$2}")" >&2 - if [[ -t 1 ]]; then - return $ret - else - # Part of an outgoing pipe, avoid getting get us stuck in a weird - # subshell if we returned nonzero, which would happen in a situation - # like this: - # - # tf() { while read -r line; do :; done < <(asdf); }; - # tf - # - # Note: exit $ret also avoids the stuck subshell problem, and I - # can't notice any difference, but this seems more proper. - return 0 - fi -} diff --git a/fai/config/files/boot/chboot/DEFAULT b/fai/config/files/boot/chboot/DEFAULT index adfbe1c..6b0e964 100755 --- a/fai/config/files/boot/chboot/DEFAULT +++ b/fai/config/files/boot/chboot/DEFAULT @@ -16,21 +16,17 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -[[ $EUID == 0 ]] || exec sudo "$BASH_SOURCE" "$@" +[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" -x="$(readlink -f "$BASH_SOURCE")" -f="${x%/*}/bash-trace" -if [[ -e $f ]]; then - source $f -else - source ${x%/*}/../bash-trace/DEFAULT -fi - +if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi +shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4 +set -eE -o pipefail +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR usage() { - cat </dev/null +echo "Importing local packages to apt cache" curl -fs 'http://127.0.0.1:3142/acng-report.html?doImport=Start+Import&calcSize=cs&asNeeded=an#bottom' >/dev/null +echo "Creating FAI Server setup" # setup the FAI server, including creating the nfsroot, use my own proxy export APTPROXY="http://127.0.0.1:3142" @@ -67,9 +69,12 @@ else echo "==================================================" echo -e "${RED}ERROR${NORMAL}: Setting up the FAI install server ${RED}FAILED${NORMAL}!" echo "Read /var/log/fai/fai-setup.log for more debugging" + echo "Setup script is now moved to /var/tmp/$0" echo "==================================================" echo "" + cp -p $0 /var/tmp sleep 10 + rm -f $0 exit 99 fi @@ -83,7 +88,7 @@ EOF fai-chboot -o default # create a template for booting the installation -fai-chboot -Iv -f verbose,sshd,createvt,menu -u nfs://faiserver/srv/fai/config bullseye.tmpl +fai-chboot -Iv -f verbose,sshd,createvt,menu -u nfs://faiserver/srv/fai/config bookworm.tmpl # Since we do not know the MAC address, our DHCP cannot provide the hostname. # Therefore we do explicitly set the hostname @@ -96,7 +101,7 @@ done fai-monitor > /var/log/fai/fai-monitor.log & # move me away -mv $0 /var/tmp +cp -p $0 /var/tmp # create new rc.local for next reboot echo '#! /bin/bash' > /etc/rc.local diff --git a/fai/config/files/etc/rc.local/LIVEISO b/fai/config/files/etc/rc.local/LIVEISO new file mode 120000 index 0000000..22fbe75 --- /dev/null +++ b/fai/config/files/etc/rc.local/LIVEISO @@ -0,0 +1 @@ +CLOUD \ No newline at end of file diff --git a/fai/config/files/etc/selinux/config/ROCKY b/fai/config/files/etc/selinux/config/ROCKY new file mode 100644 index 0000000..9878acb --- /dev/null +++ b/fai/config/files/etc/selinux/config/ROCKY @@ -0,0 +1,12 @@ +# This file controls the state of SELinux on the system. +# SELINUX= can take one of these three values: +# enforcing - SELinux security policy is enforced. +# permissive - SELinux prints warnings instead of enforcing. +# disabled - No SELinux policy is loaded. +SELINUX=disabled +# SELINUXTYPE= can take one of these two values: +# targeted - Only targeted network daemons are protected. +# strict - Full SELinux protection. +# mls - Multi Level Security protection. +SELINUXTYPE=targeted +# SETLOCALDEFS= Check local definition changes diff --git a/fai/config/hooks/debconf.IMAGE b/fai/config/hooks/debconf.IMAGE index c396636..f91ae3f 100755 --- a/fai/config/hooks/debconf.IMAGE +++ b/fai/config/hooks/debconf.IMAGE @@ -3,7 +3,7 @@ # hook for installing a file system image (tar file) # this works for Ubuntu 14.04 # -# Copyright (C) 2015 Thomas Lange, lange@informatik.uni-koeln.de +# Copyright (C) 2015 Thomas Lange, lange@cs.uni-koeln.de # I use this tar command to create the image of an already running and configured machine @@ -31,8 +31,8 @@ if [ -f $target/etc/debian_version ]; then fi if [ -f $target/etc/centos-release ]; then rm $target/etc/grub2/device.map - $FAI/scripts/CENTOS/40-install-grub - $FAI/scripts/CENTOS/30-mkinitrd + $FAI/scripts/ROCKY/40-install-grub + $FAI/scripts/ROCKY/30-mkinitrd $ROOTCMD fixfiles onboot # this fixes the SELinux security contexts during the first boot fi diff --git a/fai/config/hooks/debconf.ROCKY b/fai/config/hooks/debconf.ROCKY new file mode 100755 index 0000000..f98becd --- /dev/null +++ b/fai/config/hooks/debconf.ROCKY @@ -0,0 +1,3 @@ +#! /bin/bash + +skiptask debconf diff --git a/fai/config/hooks/instsoft.DEBIAN b/fai/config/hooks/instsoft.DEBIAN index 34e6ebb..d6f1ad1 100755 --- a/fai/config/hooks/instsoft.DEBIAN +++ b/fai/config/hooks/instsoft.DEBIAN @@ -23,3 +23,6 @@ if [ $? -eq 0 ]; then $ROOTCMD apt-get -y install locales > /dev/null fi fi + +# use zstd for dracut initrd +ainsl -av /etc/dracut.conf.d/11-debian.conf "compress=zstd" diff --git a/fai/config/hooks/partition.DEFAULT b/fai/config/hooks/partition.DEFAULT index 18f5a23..530a34d 100755 --- a/fai/config/hooks/partition.DEFAULT +++ b/fai/config/hooks/partition.DEFAULT @@ -880,15 +880,19 @@ if $partition; then if fsf; then root_mib=40000 + elif ifclass demohost; then + # just randomish numbers that seem ok for testing. + root_mib=25000 + o_mib=1000 else # This would maximize it, but we are going for a separate filesystem in /o, # so use fixed sizes to allow both to grow # 600 = uefi 512 + grubext 8 + bios grub 3 + some extra cuz this is lvm #root_mib=$(( disk_mib - root2_part_mib - swap_mib - boot_part_mib - boot2_part_mib - 600 )) - o_mib=$(( 120 * 1000 )) + o_mib=$(( 180 * 1000 )) # max minus o, minus a gig just for some extra space max_root_mib=$(( disk_mib - root2_part_mib - swap_mib - boot_part_mib - boot2_part_mib - 600 - o_mib - 1000 )) - root_mib=$(( 1000 * 1000 )) # * 1000 to make it in gb. + root_mib=$(( 1700 * 1000 )) # * 1000 to make it in gb. if (( max_root_mib < root_mib )); then root_mib=$max_root_mib fi diff --git a/fai/config/hooks/repository.ROCKY b/fai/config/hooks/repository.ROCKY new file mode 100755 index 0000000..32e53c3 --- /dev/null +++ b/fai/config/hooks/repository.ROCKY @@ -0,0 +1,27 @@ +#! /bin/bash + +# (c) Michael Goetze, 2010-2011, mgoetze@mgoetze.net + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +if [ $FAI_ACTION = "install" ]; then + ctam + [ -L $target/etc/mtab ] || cp /etc/mtab $target/etc/mtab + + cat > $target/etc/sysconfig/network <<-EOF + NETWORKING=yes + HOSTNAME=$HOSTNAME.$DOMAIN + EOF + echo "127.0.0.1 localhost" > $target/etc/hosts + ifclass DHCPC || ainsl -s /etc/hosts "$IPADDR $HOSTNAME.$DOMAIN $HOSTNAME" + cp /etc/resolv.conf $target/etc +fi + +fcopy -riv /etc/yum.repos.d/ + +# disable the fastestmirror plugin +#fai-sed 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf + +skiptask repository + +exit $error diff --git a/fai/config/hooks/savelog.LAST.sh b/fai/config/hooks/savelog.LAST.sh index 6546814..ba04b98 100755 --- a/fai/config/hooks/savelog.LAST.sh +++ b/fai/config/hooks/savelog.LAST.sh @@ -182,6 +182,8 @@ disabling ASPM data block query control method not found subprocess.py.\+RuntimeWarning: line buffering Resource conflict.\+ found +os-prober will not be executed +/sys/bus/usb/devices/\*:\*/bInterface update-rc.d: warning: start and stop actions are no longer supported" # add pattern on some conditions @@ -219,4 +221,5 @@ if [ -s $errfile ]; then echo "ERRORS found in log files. See $errfile" >&2 else echo "Congratulations! No errors found in log files." +# export flag_reboot=1 # if you want to reboot if no errors are found fi diff --git a/fai/config/hooks/subroutines b/fai/config/hooks/subroutines new file mode 100755 index 0000000..816ead1 --- /dev/null +++ b/fai/config/hooks/subroutines @@ -0,0 +1,31 @@ +#! /bin/bash + +# This file is sourced during task_setup +# you can define your own functions and use them later, for e.g. +# in scripts/... + + +cleanup_base() { + + rm -f $target/etc/mailname \ + $target/etc/machine-id \ + $target/var/lib/dbus/machine-id \ + $target/var/log/install_packages.list + + > $target/etc/machine-id + shred --remove $target/etc/ssh/ssh_host_* +} + + +cleanup_dpkg_apt() { + + rm -f $target/var/log/alternatives.log \ + $target/var/log/apt/* \ + $target/var/log/bootstrap.log \ + $target/var/log/dpkg.log + + rm -rf $target/var/cache/apt/* + rm -rf $target/var/lib/apt/lists/* + rm -f $target/var/lib/dpkg/available* + rm -f -- $target/var/lib/dpkg/*-old +} diff --git a/fai/config/hooks/updatebase.DEBIAN b/fai/config/hooks/updatebase.DEBIAN index e828eef..8b5117f 100755 --- a/fai/config/hooks/updatebase.DEBIAN +++ b/fai/config/hooks/updatebase.DEBIAN @@ -7,8 +7,3 @@ else fi echo force-unsafe-io > $target/etc/dpkg/dpkg.cfg.d/unsafe-io - -# you may want to add i386 arch to amd64 hosts -# if ifclass AMD64; then -# $ROOTCMD dpkg --add-architecture i386 -# fi diff --git a/fai/config/hooks/updatebase.ROCKY b/fai/config/hooks/updatebase.ROCKY new file mode 100755 index 0000000..dd418d8 --- /dev/null +++ b/fai/config/hooks/updatebase.ROCKY @@ -0,0 +1,25 @@ +#! /bin/bash + +if [ ! -f $target/etc/resolv.conf ]; then + cp /etc/resolv.conf $target/etc +fi + +if [ X$verbose = X1 ]; then + echo "Updating base" + $ROOTCMD yum -y update |& tee -a $LOGDIR/software.log +else + $ROOTCMD yum -y update >> $LOGDIR/software.log +fi + +$ROOTCMD systemd-machine-id-setup + +cat > $target/etc/sysconfig/kernel < $target/etc/machine-id - -shred --remove $target/etc/ssh/ssh_host_* + $target/lib/udev/write_net_rules # FIXME: DHCP RFC3442 is used incorrect in Azure if [ -f $target/etc/dhcp/dhclient.conf ]; then - sed -ie 's,rfc3442-classless-static-routes,disabled-\0,' $target/etc/dhcp/dhclient.conf + fai-sed 's,rfc3442-classless-static-routes,disabled-\0,' /etc/dhcp/dhclient.conf fi diff --git a/fai/config/scripts/DEBIAN/11-iank b/fai/config/scripts/DEBIAN/11-iank index 69b9afe..130c7e9 100755 --- a/fai/config/scripts/DEBIAN/11-iank +++ b/fai/config/scripts/DEBIAN/11-iank @@ -24,12 +24,33 @@ if [[ $EUID != 0 ]]; then exit 1 fi +m() { printf "%s\n" "$*"; "$@"; } + + fcopy -riB /root +# in bullseye, installing systemd-resolved says: Converting +# /etc/resolv.conf to a symlink to +# /run/systemd/resolve/stub-resolv.conf... which breaks +# resolution. This happens to be the first script we install a package +# after that. This should do nothing in a fai-wrapper situation. +if [[ ! -s $target/etc/resolv.conf ]]; then + m ls -la $target/etc/resolv.conf ||: + # Keep the symlink in place, systemd-resolved should change the file + # when it runs. + mkdir -p $target/run/systemd/resolve + if [[ ! -s /etc/resolv.conf ]] && ! host google.com; then + echo "ERROR: empty resolv.conf & failed dns resolution. exiting 1" >&2 + exit 1 + fi + cat /etc/resolv.conf >$target/etc/resolv.conf +fi + + #### misc configurations chroot $FAI_ROOT bash <<'EOFOUTER' -set -x +set -xe if getent group systemd-journal >/dev/null; then # makes the journal be saved to disk. mkdir -p /var/log/journal @@ -38,7 +59,12 @@ fi debconf-set-selections < $target/etc/adjtime fi if [ "$UTC" = "yes" ]; then - sed -i -e 's:^LOCAL$:UTC:' $target/etc/adjtime + fai-sed 's:^LOCAL$:UTC:' /etc/adjtime else - sed -i -e 's:^UTC$:LOCAL:' $target/etc/adjtime + fai-sed 's:^UTC$:LOCAL:' /etc/adjtime fi # enable linuxlogo if [ -f $target/etc/inittab ]; then - sed -i -e 's#/sbin/getty 38400#/sbin/getty -f /etc/issue.linuxlogo 38400#' ${target}/etc/inittab + fai-sed 's#/sbin/getty 38400#/sbin/getty -f /etc/issue.linuxlogo 38400#' /etc/inittab elif [ -f $target/lib/systemd/system/getty@.service ]; then - sed -i -e 's#sbin/agetty --noclear#sbin/agetty -f /etc/issue.linuxlogo --noclear#' $target/lib/systemd/system/getty@.service + fai-sed 's#sbin/agetty --noclear#sbin/agetty -f /etc/issue.linuxlogo --noclear#' /lib/systemd/system/getty@.service fi # make sure a machine-id exists @@ -53,9 +53,9 @@ if [ X"$(stat -c '%s' $target/etc/machine-id 2>/dev/null)" = X0 -a -f $target/b $ROOTCMD systemd-machine-id-setup fi -ln -fs /proc/mounts $target/etc/mtab +fai-link /etc/mtab ../proc/self/mounts -rm -f $target/etc/dpkg/dpkg.cfg.d/fai $target/etc/dpkg/dpkg.cfg.d/unsafe-io +rm -f $target/etc/dpkg/dpkg.cfg.d/unsafe-io if [ -d /etc/fai ]; then if ! fcopy -Mv /etc/fai/fai.conf; then diff --git a/fai/config/scripts/FAIBASE/10-misc b/fai/config/scripts/FAIBASE/10-misc index 7a0599d..926b5f0 100755 --- a/fai/config/scripts/FAIBASE/10-misc +++ b/fai/config/scripts/FAIBASE/10-misc @@ -6,7 +6,7 @@ error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code echo $TIMEZONE > $target/etc/timezone if [ -L $target/etc/localtime ]; then - ln -sf /usr/share/zoneinfo/${TIMEZONE} $target/etc/localtime + fai-link /etc/localtime /usr/share/zoneinfo/${TIMEZONE} else cp -f /usr/share/zoneinfo/${TIMEZONE} $target/etc/localtime fi diff --git a/fai/config/scripts/FAIBASE/15-root-ssh-key b/fai/config/scripts/FAIBASE/15-root-ssh-key new file mode 100755 index 0000000..db692ad --- /dev/null +++ b/fai/config/scripts/FAIBASE/15-root-ssh-key @@ -0,0 +1,35 @@ +#! /bin/bash + +# (c) Thomas Lange, 2022, lange@debian.org +# +# Add public ssh key for user root to get login access + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +SSHDIR=$target/root/.ssh +AUKEY=$SSHDIR/authorized_keys + +# reverse order of classes +for c in $classes; do + revclasses="$c $revclasses" +done + +for c in $revclasses; do + if [ -f $FAI/files/root-ssh-key/$c ]; then + if [ -f $AUKEY ]; then + cmp -s $FAI/files/root-ssh-key/$c $AUKEY + if [ $? -eq 0 ]; then + exit + fi + fi + if [ ! -d $SSHDIR ]; then + mkdir -m 700 $SSHDIR + fi + cp -v $FAI/files/root-ssh-key/$c $AUKEY + chown root:root $AUKEY + chmod 700 $AUKEY + break + fi +done + +exit $error diff --git a/fai/config/scripts/FAISERVER/10-conffiles b/fai/config/scripts/FAISERVER/10-conffiles index 92b17fc..e0a60ff 100755 --- a/fai/config/scripts/FAISERVER/10-conffiles +++ b/fai/config/scripts/FAISERVER/10-conffiles @@ -27,8 +27,10 @@ if [ $FAI_ACTION = "install" -o $FAI_ACTION = "dirinstall" ] ; then # add entries for 10 hosts called client 01 .. 10 perl -e 'for (1..10) {printf "192.168.33.%s client%02s\n",101+$_,$_;}' >> $target/etc/hosts - sed -i -e '/# ReuseConnections: 1/d' $target/etc/apt-cacher-ng/acng.conf - ainsl -v /etc/apt-cacher-ng/acng.conf "ReuseConnections: 0" + fai-sed '/# ReuseConnections: 1/d' /etc/apt-cacher-ng/acng.conf + ainsl -v /etc/apt-cacher-ng/acng.conf "ReuseConnections: 1" + ainsl -v /etc/apt-cacher-ng/acng.conf "PipelineDepth: 80" + ainsl -v /etc/apt-cacher-ng/acng.conf "DlMaxRetries: 6" # copy base file for faster building of nfsroot if [ -f /var/tmp/base.tar.xz ]; then @@ -38,7 +40,7 @@ if [ $FAI_ACTION = "install" -o $FAI_ACTION = "dirinstall" ] ; then if [ -d /media/mirror/pool ]; then mkdir $target/var/cache/apt-cacher-ng/_import cp -p /media/mirror/pool/*/*/*/*.deb $target/var/cache/apt-cacher-ng/_import - $ROOTCMD chown -R apt-cacher-ng.apt-cacher-ng /var/cache/apt-cacher-ng/_import + $ROOTCMD chown -R apt-cacher-ng:apt-cacher-ng /var/cache/apt-cacher-ng/_import fi # copy basefiles from CD to config space diff --git a/fai/config/scripts/GRUB_EFI/10-setup b/fai/config/scripts/GRUB_EFI/10-setup index 7dd92d4..24054e1 100755 --- a/fai/config/scripts/GRUB_EFI/10-setup +++ b/fai/config/scripts/GRUB_EFI/10-setup @@ -11,6 +11,11 @@ error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code # installation into the removable media paths as well as the standard # debian path. +# do only execute for Debian and similar distros +if ! ifclass DEBIAN ; then + exit 0 +fi + set -a # do not set up grub during dirinstall @@ -41,28 +46,35 @@ if [ "${_bdev%%-*}" = "/dev/dm" ]; then BOOT_DEVICE=$( lvs --noheadings -o devices $BOOT_DEVICE | sed -e 's/^*\([^(]*\)(.*$/\1/' ) fi +opts="--no-floppy --target=x86_64-efi --modules=part_gpt" + # Check if RAID is used for the boot device if [[ $BOOT_DEVICE =~ '/dev/md' ]]; then raiddev=${BOOT_DEVICE#/dev/} # install grub on all members of RAID for device in $(LC_ALL=C perl -ne 'if(/^'$raiddev'\s.+raid\d+\s(.+)/){ $_=$1; s/\d+\[\d+\]//g; print }' /proc/mdstat); do echo Install grub on /dev/$device - $ROOTCMD grub-install --no-floppy --force-extra-removable "/dev/$device" + $ROOTCMD grub-install $opts --force-extra-removable "/dev/$device" done elif [[ $BOOT_DEVICE =~ '/dev/loop' ]]; then # do not update vmram when using a loop device - $ROOTCMD grub-install --no-floppy --force-extra-removable --modules=part_gpt --no-nvram $BOOT_DEVICE + $ROOTCMD grub-install $opts --force-extra-removable --no-nvram $BOOT_DEVICE if [ $? -eq 0 ]; then echo "Grub installed on hostdisk $BOOT_DEVICE" fi else - $ROOTCMD grub-install --no-floppy --modules=part_gpt "$GROOT" + $ROOTCMD grub-install $opts "$GROOT" if [ $? -eq 0 ]; then echo "Grub installed on $BOOT_DEVICE = $GROOT" fi fi $ROOTCMD update-grub +if [[ $BOOT_DEVICE =~ '/dev/loop' ]]; then + : +else + efibootmgr -v +fi exit $error diff --git a/fai/config/scripts/GRUB_PC/10-setup b/fai/config/scripts/GRUB_PC/10-setup index 11535f1..7ea23fd 100755 --- a/fai/config/scripts/GRUB_PC/10-setup +++ b/fai/config/scripts/GRUB_PC/10-setup @@ -4,6 +4,11 @@ error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code set -x +# do only execute for Debian and similar distros +if ! ifclass DEBIAN ; then + exit 0 +fi + set -a # do not set up grub during dirinstall @@ -20,6 +25,11 @@ fi # disable os-prober because of #802717 ainsl /etc/default/grub 'GRUB_DISABLE_OS_PROBER=true' +# efivars may still be mounted from the host system during fai-diskimage +if [ -d $target/sys/firmware/efi/efivars ]; then + umount $target/sys/firmware/efi/efivars +fi + # skip the rest, if not an initial installation if [ $FAI_ACTION != "install" ]; then $ROOTCMD update-grub @@ -74,10 +84,11 @@ if [[ $BOOT_DEVICE =~ '/dev/md' ]]; then else for dev in $BOOT_DEVICE; do mbrdev=$(get_stable_devname $dev) - if [ -z "$mbrdevices" ]; then + if [ -z "$mbrdev" ]; then # if we cannot find a persistent name (for e.g. in a VM) use old name - mbrdevices+="$dev, " + mbrdev="$dev" fi + mbrdevices+="$mbrdev, " echo "Installing grub on $dev = $mbrdev" $ROOTCMD grub-install --no-floppy "$mbrdev" done diff --git a/fai/config/scripts/IANK/11-iank b/fai/config/scripts/IANK/11-iank index 63c85f9..99316b8 100755 --- a/fai/config/scripts/IANK/11-iank +++ b/fai/config/scripts/IANK/11-iank @@ -24,25 +24,13 @@ if [[ $EUID != 0 ]]; then exit 1 fi +# ignore this line. hack to make shellcheck ignore $target +if [[ ! $target ]]; then target=; fi + if ! type -t fcopy &>/dev/null; then sudo apt-get -y install fai-client fi -if [[ -e /a/bin/fai/fai-wrapper ]]; then - chroot() { - shift - "$@" - } -fi - -if [[ $FAI_ROOT == / ]]; then - source /a/bin/bash_unpublished/source-state - bprogs_dir=/a/opt/btrfs-progs-release -else - bprogs_dir=/srv/btrfs-progs-release - chroot="chroot $FAI_ROOT" -fi - # -r = recursive # -i = ignore non-matching class warnings, always exit 0 # -B = no backup files @@ -66,6 +54,8 @@ if [[ ! -e $dst && -e $src ]]; then mount -o bind $src $dst fi + + $FAI/distro-install-common/end @@ -75,13 +65,13 @@ $FAI/distro-install-common/end # I run this as a single post-fai script to update things that have changed. tmpfile1=$(mktemp) # this can fail if we need an apt update -$chroot /usr/bin/apt-cache policy >$tmpfile1 ||: +$ROOTCMD /usr/bin/apt-cache policy >$tmpfile1 ||: fcopy -riB /etc/apt tmpfile2=$(mktemp) -$chroot /usr/bin/apt-cache policy >$tmpfile2 +$ROOTCMD /usr/bin/apt-cache policy >$tmpfile2 if ! diff -q $tmpfile1 $tmpfile2; then - $chroot /usr/bin/apt update + $ROOTCMD /usr/bin/apt update fi # outside of fai, this seems to regularly lead to # E: Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable) @@ -105,7 +95,6 @@ fi #### misc configurations - if [[ $FAI_ACTION != dirinstall ]] && ! ifclass NOCRYPT; then if ifclass LINODE; then speed=19200 @@ -131,7 +120,7 @@ TimeoutStartSec=20 WantedBy=dev-disk-by\x2did-ata\x2dSamsung_SSD_870_QVO_8TB_S5VUNG0N900656V.device EOF - $chroot bash <<'EOFOUTER' + $ROOTCMD bash <<'EOFOUTER' systemctl enable myncq.service /usr/bin/myncq no-upgrub EOFOUTER @@ -180,8 +169,8 @@ EOF fi # use networkmanager if this host has wireless. -if [[ $HOSTNAME == bo ]] || type -p iw &>/dev/null && [[ $(iw dev) ]]; then - $chroot bash <&1 ||:) == kd.b8.nz. ]] \ + && ip n show 10.2.0.1 | grep . &>/dev/null; then + # we are at_home + $FAI/distro-install-common/ethusb-static $ethusb_arg + else + $FAI/distro-install-common/ethusb-static off $ethusb_arg + fi + + else cat > $target/etc/network/interfaces <<-EOF # generated by FAI @@ -224,44 +228,9 @@ EOF fi -case $HOSTNAME in - sy) - $FAI/distro-install-common/install-stable-kernel-debs - ;; - *) - $chroot apt-get -y install linux-libre - ;; -esac - -pre=https://mirrors.edge.kernel.org/pub/linux/kernel/people/kdave/btrfs-progs -tarball=$(curl -s $pre/sha256sums.asc \ - | awk '$2 ~ /^btrfs-progs-v/ { print $2 }' | grep -v -- -rc | grep "^btrfs-progs-v.*gz\$" | sort -V | tail -n1) -url="$pre/$tarball" -dir=${tarball%.tar.gz} -ver=${dir#btrfs-progs-} -cur_ver=$(btrfs --version 2>/dev/null | awk '{print $2}') ||: -if [[ $ver != "$cur_ver" ]]; then - if [[ $HOST2 == "$HOSTNAME" && $ver != "$($bprogs_dir/btrfs --version 2>/dev/null | awk '{print $2}')" ]]; then - rm -rf $bprogs_dir - cd /tmp - wget $url - sudo -u iank tar xzf $tarball - mv ${tarball%.tar.gz} $bprogs_dir - cd $bprogs_dir - apt-get -y build-dep btrfs-progs - sudo -u iank ./configure --disable-documentation - sudo -u iank make - make install - else - $chroot bash -xe <$target/etc/initramfs-tools/conf.d/mine <&1 | grep -Fx "Status: install ok installed" &>/dev/null; then + apt-get -y install wget + wget -O /target/tmp/x.deb https://linux-libre.fsfla.org/pub/linux-libre/freesh/pool/main/f/freesh-archive-keyring/freesh-archive-keyring_1.1_all.deb + $ROOTCMD dpkg -i /tmp/x.deb + $ROOTCMD apt-get update + $ROOTCMD apt-get -y install linux-libre + fi + ;; +esac + +pre=https://mirrors.edge.kernel.org/pub/linux/kernel/people/kdave/btrfs-progs +tarball=$(curl -s $pre/sha256sums.asc \ + | awk '$2 ~ /^btrfs-progs-v/ { print $2 }' | grep -v -- -rc | grep "^btrfs-progs-v.*gz\$" | sort -V | tail -n1) +url="$pre/$tarball" +dir=${tarball%.tar.gz} +ver=${dir#btrfs-progs-} +cur_ver=$($ROOTCMD btrfs --version 2>/dev/null | awk '{print $2}') ||: + +if [[ $FAI_ROOT == / ]]; then + bp_dir=/a/opt/btrfs-progs-release +else + bp_dir=$FAI/distro-install-common/btrfs-progs-release +fi +if [[ $ver != "$cur_ver" ]]; then + if [[ $ver != "$($bp_dir/btrfs --version 2>/dev/null | awk '{print $2}')" ]]; then + cd $target/tmp + wget $url + tar xzf $tarball + $ROOTCMD apt-get -y build-dep btrfs-progs + # no docs cuz I didn't want to bother fixing error of missing docs dependencies + $ROOTCMD bash -xe <&1 | grep -Fx "Status: install ok installed" &>/dev/null; then + $ROOTCMD apt-get -y install build-essential + fi + + if [[ $FAI_ROOT == / ]]; then + cd /a/opt/btrfs-progs-release + make install + else + mkdir -p $target/tmp/bprogs + mount -o bind $bp_dir $target/tmp/bprogs + $ROOTCMD bash -xe <$error?$?:$error))' ERR # save maximum error code +# remove crypt password from format.log +if [ -f $LOGDIR/format.log ]; then + perl -i -pane "s/Executing: yes '.+?' \| cryptsetup/Executing: yes 'XXXXXXXXXXXXX' | cryptsetup/" $LOGDIR/format.log +fi + if [ "$FAI_ACTION" = "dirinstall" -o $do_init_tasks -eq 0 ] ; then : else @@ -15,15 +20,19 @@ else fi fi - # i use dm for crypt, not lvm, so this gives false positive. todo, send patch to remove this - # upstream. - # usedm=$(dmsetup ls 2>/dev/null | egrep -v '^live-rw|^live-base|^No devices found' | wc -l) - # if [ $usedm -ne 0 ]; then - # if [ ! -d $target/etc/lvm ]; then - # echo ERROR: Found lvm devices, but the lvm2 package was not installed - # error=1 - # fi - # fi + if [ -f $target/etc/crypttab ] && [ ! -f $target/sbin/cryptsetup ]; then + echo ERROR: Encrypted devices used, but the crypsetup package was not installed. + echo ERROR: You want to add cryptsetup-initramfs or dracut to some package_config file. + fi + + # note, if we used dm for crypt, not lvm, so would givee false positive. todo, send patch to fix + usedm=$(dmsetup ls 2>/dev/null | egrep -v '^live-rw|^live-base|^No devices found' | wc -l) + if [ $usedm -ne 0 ]; then + if [ ! -d $target/etc/lvm ]; then + echo ERROR: Found lvm devices, but the lvm2 package was not installed + error=1 + fi + fi fi # remove backup files from cfengine, but only if cfengine is installed @@ -74,7 +83,7 @@ setrel() { return fi - dists="jessie stretch buster bullseye bookworm trixie jammy focal bionic xenial trusty aramo nabia etiona" + dists="jessie stretch buster bullseye bookworm trixie forky noble jammy focal bionic xenial trusty aramo nabia etiona" for d in $dists; do if grep -iq $d $target/etc/os-release; then release=$d @@ -85,18 +94,31 @@ setrel() { # if installation was done from CD, replace useless sources.list setrel -if [ -f $target/etc/apt/sources.list -a -n "$release" ]; then - grep -q 'file generated by fai-cd' $target/etc/apt/sources.list && cat < $target/etc/apt/sources.list -deb $apt_cdn/debian $release main contrib non-free -deb $security_cdn/debian-security ${secsuite} main contrib non-free +if [ -f $target/etc/apt/sources.list ] && [ -n "$release" ]; then + if grep -q 'file generated by fai-cd' $target/etc/apt/sources.list; then + echo "Create new sources.list for $release" + cat < $target/etc/apt/sources.list +deb $apt_cdn/debian $release main contrib non-free non-free-firmware +deb $security_cdn/debian-security ${secsuite} main contrib non-free non-free-firmware #deb [trusted=yes] http://fai-project.org/download $release koeln EOF + fi # if the package fai-server was installed, enable the project's repository if dpkg-query --admindir=$target/var/lib/dpkg -W fai-server >/dev/null 2>&1; then - sed -i -e '/fai-project.org/s/^#//' $target/etc/apt/sources.list + fai-sed '/fai-project.org/s/^#//' /etc/apt/sources.list fi fi +# install default sources.list for Debian based distributions +if [ -d $target/etc/apt ] && [ ! -f $target/etc/apt/sources.list ]; then + fcopy -Svc DEBIAN_DEFAULT /etc/apt/sources.list +fi + +# older releases do not have the non-free-firmware section +if [ -n "$release" ] && [[ "buster bullseye" =~ "$release" ]]; then + sed -i -e 's/non-free-firmware//g' $target/etc/apt/sources.list +fi + # for ARM architecture, we may need the kernel and initrd to boot or flash the device if ifclass ARM64; then cp -pv $target/boot/vmlinuz* $target/boot/initrd* $FAI_RUNDIR diff --git a/fai/config/scripts/LIVEISO/20-initrd b/fai/config/scripts/LIVEISO/20-initrd new file mode 100755 index 0000000..4dcbc66 --- /dev/null +++ b/fai/config/scripts/LIVEISO/20-initrd @@ -0,0 +1,15 @@ +#! /bin/bash + +# create an initrd for booting from ISO + +# get highest kernel version +ver=$(ls -r1 $target/boot/initrd.img-*|tail -1| sed 's/.\+initrd.img-//') +if [ -z "$ver" ]; then + echo "ERROR: no initrd found in $0" + exit 9 +fi + +rm $target/boot/initrd.img-$ver +$ROOTCMD dracut -N --zstd --filesystems ext4 -a "dmsquash-live " -o"btrfs crypt dash lvm resume usrmount modsign mdraid shutdown virtfs" /boot/initrd.img-$ver $ver + +echo ISO initrd was created diff --git a/fai/config/scripts/LIVEISO/90-cleanup b/fai/config/scripts/LIVEISO/90-cleanup new file mode 100755 index 0000000..08828d2 --- /dev/null +++ b/fai/config/scripts/LIVEISO/90-cleanup @@ -0,0 +1,7 @@ +#! /bin/bash + +# this is defined in hooks/subroutines +cleanup_dpkg_apt +cleanup_base + +echo cleanup for live ISO done diff --git a/fai/config/scripts/ROCKY/10-security b/fai/config/scripts/ROCKY/10-security new file mode 100755 index 0000000..566c3f4 --- /dev/null +++ b/fai/config/scripts/ROCKY/10-security @@ -0,0 +1,14 @@ +#! /bin/bash + +# (c) Michael Goetze, 2010-11, mgoetze@mgoetze.net +# Thomas Lange, 2015-2020 + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +$ROOTCMD usermod -p $ROOTPW root + +fcopy -v /etc/selinux/config +$ROOTCMD fixfiles onboot # this fixes the SELinux security contexts during the first boot +chmod a+rx $target + +exit $error diff --git a/fai/config/scripts/ROCKY/30-mkinitrd b/fai/config/scripts/ROCKY/30-mkinitrd new file mode 100755 index 0000000..4d86bec --- /dev/null +++ b/fai/config/scripts/ROCKY/30-mkinitrd @@ -0,0 +1,25 @@ +#! /bin/bash + +# (c) Michael Goetze, 2010-2011, mgoetze@mgoetze.net +# (c) Thomas Lange, 2011, Uni Koeln + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +ainsl -v /etc/fstab "proc /proc proc defaults 0 0" +ainsl -v /etc/fstab "sysfs /sys sysfs auto 0 0" + +version=$($ROOTCMD rpm -qv kernel | cut -d- -f2-) + + +if [ -f $target/etc/lvm/lvm.conf ]; then + fai-sed 's/use_lvmetad = 1/use_lvmetad = 0/' /etc/lvm/lvm.conf + ainsl -av /etc/dracut.conf.d/fai.conf 'add_dracutmodules+=" lvm "' +fi + + +# add filesystem driver into initrd +ainsl -av /etc/dracut.conf.d/fai.conf 'filesystems+=" ext4 "' +$ROOTCMD dracut -v --kver $version --force + + +exit $error diff --git a/fai/config/scripts/ROCKY/40-install-grub b/fai/config/scripts/ROCKY/40-install-grub new file mode 100755 index 0000000..5590ded --- /dev/null +++ b/fai/config/scripts/ROCKY/40-install-grub @@ -0,0 +1,87 @@ +#! /bin/bash + +# (c) Michael Goetze, 2011, mgoetze@mgoetze.net +# (c) Thomas Lange 2014 + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +if [ -r $LOGDIR/disk_var.sh ] ; then + . $LOGDIR/disk_var.sh +else + echo "disk_var.sh not found!" + exit 1 +fi + + +# CentOS 7 does not have a device.map file, so generate one +if [ -d $target/boot/grub2 -a ! -f $target/boot/grub2/device.map ]; then + echo "# Generated by FAI" >> $target/boot/grub2/device.map + centosdisks=$(awk '/[sv]d.$/ {print $4}' /proc/partitions | sort) + dcount=0 + for d in $centosdisks; do + echo "(hd$dcount) /dev/$d" >> $target/boot/grub2/device.map + dcount=$((dcount + 1)) + done +fi + +bootdev=$(device2grub $BOOT_DEVICE) +bootpart=$(device2grub $BOOT_PARTITION) +version=$($ROOTCMD rpm -qv kernel | cut -d- -f2-) + +if grep '[[:space:]]/boot[[:space:]]' $LOGDIR/fstab; then + bootdir='' +else + bootdir='/boot' +fi + +mount -o bind /dev $target/dev + +if [ -f $target/usr/sbin/grub2-install ]; then + + # CentOS 7 + $ROOTCMD grub2-install --no-floppy "$BOOT_DEVICE" + $ROOTCMD grub2-mkconfig --output=/boot/grub2/grub.cfg +else + +$ROOTCMD grub-install --just-copy + +$ROOTCMD grub --device-map=/dev/null --no-floppy --batch <<-EOF + device $bootdev $BOOT_DEVICE + root $bootpart + setup $bootdev + quit + EOF + +ln -s ./menu.lst $target/boot/grub/grub.conf + +if [ -f $target/boot/grub/splash.xpm.gz ]; then + pretty="splashimage=$bootpart$bootdir/grub/splash.xpm.gz" +else + pretty="color cyan/blue white/blue" +fi + +title=$(head -1 $target/etc/redhat-release) + +cat > $target/boot/grub/grub.conf <<-EOF + timeout 5 + default 0 + $pretty + hiddenmenu + + title $title + root $bootpart + kernel $bootdir/vmlinuz-$version root=$ROOT_PARTITION ro + initrd $bootdir/initramfs-$version.img + EOF + +fi + +umount $target/dev + +echo "" +echo "Grub installed on $BOOT_DEVICE = $bootdev" +echo "Grub boot partition is $BOOT_PARTITION = $bootpart" +echo "Root partition is $ROOT_PARTITION" +echo "Boot kernel: $version" + +exit $error diff --git a/fai/config/scripts/ROCKY/50-sysconfig b/fai/config/scripts/ROCKY/50-sysconfig new file mode 100755 index 0000000..e9054b6 --- /dev/null +++ b/fai/config/scripts/ROCKY/50-sysconfig @@ -0,0 +1,35 @@ +#! /bin/bash + +# (c) Michael Goetze, 2011, mgoetze@mgoetze.net + +error=0 ; trap "error=$((error|1))" ERR + +cat > $target/etc/sysconfig/clock <<-EOF + UTC=$UTC + ZONE=$TIMEZONE + EOF +cat > $target/etc/sysconfig/i18n <<-EOF + LANG="$DEFAULTLOCALE" + SUPPORTED="$SUPPORTEDLOCALE" + SYSFONT="$CONSOLEFONT" + EOF +cat > $target/etc/sysconfig/keyboard <<-EOF + KEYBOARDTYPE="pc" + KEYTABLE="$KEYMAP" + EOF + +# can not be used, because we still not use systemd in FAI +# $ROOTCMD localectl set-locale LANG=$DEFAULTLOCALE + +cat > $target/etc/locale.conf <<-EOF + LANG="$DEFAULTLOCALE" + EOF +if [ -f $target/usr/lib/locale/locale-archive.tmpl \ + -a ! -s $target/usr/lib/locale/locale-archive ]; then + mv $target/usr/lib/locale/locale-archive.tmpl $target/usr/lib/locale/locale-archive +fi + +fcopy -iv /etc/sysconfig/i18n /etc/sysconfig/keyboard + +exit $error + diff --git a/fai/config/scripts/ROCKY/60-network-scripts b/fai/config/scripts/ROCKY/60-network-scripts new file mode 100755 index 0000000..9777418 --- /dev/null +++ b/fai/config/scripts/ROCKY/60-network-scripts @@ -0,0 +1,81 @@ +#! /bin/bash + +error=0 ; trap "error=$((error|1))" ERR + +ifcfg_config() { + + cat > $target/etc/sysconfig/network-scripts/ifcfg-$NIC1 <<-EOF + # generated by FAI + TYPE=Ethernet + PROXY_METHOD=none + BOOTPROTO=dhcp + DEFROUTE=yes + BROWSER_ONLY=no + IP4_FAILURE_FATAL=no + IPV6INIT=no + IPV6_AUTOCONF=no + NAME=$NIC1 + DEVICE=$NIC1 + ONBOOT=yes + EOF +} + +nm_config() { + + uuid=$(uuidgen) + + cat > $target/etc/NetworkManager/system-connections/${NIC1}.nmconnection << EOF + +# generated by FAI +[connection] +id=$NIC1 +uuid=$uuid +type=ethernet +autoconnect-priority=-999 +interface-name=$NIC1 + +[ethernet] + +[ipv4] +method=auto + +[ipv6] +addr-gen-mode=eui64 +method=auto + +[proxy] +EOF + + chmod 600 $target/etc/NetworkManager/system-connections/${NIC1}.nmconnection +} + + + +# determine predictable network names +fields="ID_NET_NAME_FROM_DATABASE ID_NET_NAME_ONBOARD ID_NET_NAME_SLOT ID_NET_NAME_PATH" +for field in $fields; do + name=$(udevadm info /sys/class/net/$NIC1 | sed -rn "s/^E: $field=(.+)/\1/p") + if [[ $name ]]; then + NIC1=$name + break + fi +done +if [[ ! $name ]]; then + echo "$0: error: could not find systemd predictable network name. Using $NIC1." +fi + +if [ $FAI_ACTION != "softupdate" ] && ifclass DHCPC; then + . $target/etc/os-release + major=$(echo ${VERSION_ID} | awk -F '.' '{ print $1 }') + + if [ $major -lt 9 ]; then + ifcfg_config + else + nm_config + fi +fi + +fcopy -iv /etc/sysconfig/network /etc/resolv.conf /etc/networks +fcopy -ivr /etc/sysconfig/network-scripts + +exit $error diff --git a/fai/config/scripts/ROCKY/80-misc b/fai/config/scripts/ROCKY/80-misc new file mode 100755 index 0000000..09c8d49 --- /dev/null +++ b/fai/config/scripts/ROCKY/80-misc @@ -0,0 +1,21 @@ +#! /bin/bash + +error=0 ; trap "error=$((error|1))" ERR + +# add a $username user account +if [ -n "$username" ]; then + if ! $ROOTCMD getent passwd $username ; then + $ROOTCMD adduser -c "$username user" $username + $ROOTCMD usermod -p "$USERPW" $username + fi +fi + +# enable graphical login screen, make run level 5 as default +if [ -f $target/usr/sbin/gdm ]; then + fai-sed 's/id:3:initdefault:/id:5:initdefault:/' /etc/inittab + # do not run this tool + echo "RUN_FIRSTBOOT=NO" > $target/etc/sysconfig/firstboot +fi + +exit $error + diff --git a/fai/config/scripts/ROCKY/90-cleanup b/fai/config/scripts/ROCKY/90-cleanup new file mode 100755 index 0000000..2eadacd --- /dev/null +++ b/fai/config/scripts/ROCKY/90-cleanup @@ -0,0 +1,3 @@ +#! /bin/bash + +$ROOTCMD yum clean all diff --git a/fai/config/tests/Faitest.pm b/fai/config/tests/Faitest.pm index 022b407..b806599 100644 --- a/fai/config/tests/Faitest.pm +++ b/fai/config/tests/Faitest.pm @@ -2,7 +2,7 @@ # Subroutines for automatic tests # -# Copyright (C) 2009 Thomas Lange, lange@informatik.uni-koeln.de +# Copyright (C) 2009 Thomas Lange, lange@cs.uni-koeln.de # Based on the first version by Sebastian Hetze, 08/2008 package FAITEST; diff --git a/faiserver-disable b/faiserver-disable index 65e2aa8..74aaef8 100755 --- a/faiserver-disable +++ b/faiserver-disable @@ -1,16 +1,17 @@ #!/bin/bash -readonly this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" -script_dir="${this_file%/*}" -# shellcheck source=./bash-trace -source "${script_dir}/bash-trace" -cd $script_dir -source "${script_dir}/bash-trace" +if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi +shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4 +set -eE -o pipefail +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR +this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" +readonly this_file this_dir="${this_file%/*}" +cd "$this_dir" usage() { - cat </dev/null; then echo "$0: disabling fai nfs exports or apache site" ./faiserver-disable-local else - echo "$0: sshing to $(chost faiserver) to disable fai nfs exports or apache site" - ssh root@$(chost faiserver) bash >/srv/fai/nfsroot/root/.ssh/known_hosts done @@ -369,6 +362,6 @@ echo "c0:2345:respawn:/sbin/agetty 115200 ttyS0 linux" >>/srv/fai/nfsroot/etc/in # the logsave prompted because the hostname faiserver was uknown. # Here it was faiserver.lan when running from a faiserver vm. # When running from a normal host with faiserver alias, it was the normal hosts name. -$sed 's/(^[^,]+,)\S+/\1faiserver/' /srv/fai/nfsroot/root/.ssh/known_hosts +$sed 's/(^[^,]+,)\S+/\1faiserver.b8.nz/' /srv/fai/nfsroot/root/.ssh/known_hosts # ditch the logo banner up top which screws with less. touch /srv/fai/nfsroot/.nocolorlogo diff --git a/faiserver-uninstall b/faiserver-uninstall index 71a4ea0..8392b35 100755 --- a/faiserver-uninstall +++ b/faiserver-uninstall @@ -15,20 +15,25 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" + +if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi +shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4 set -eE -o pipefail -trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR -[[ $EUID == 0 ]] || exec sudo "${BASH_SOURCE}" "$@" usage() { - cat </dev/null || continue if [[ -e $dir/boot ]]; then dir=$dir/boot fi - e install -m 755 -o root -g root bash-trace $dir e install -m 755 -o root -g root chboot $dir done e umount $mount_point diff --git a/lk b/lk index b757fcc..3364717 100755 --- a/lk +++ b/lk @@ -74,4 +74,4 @@ fi # I don't know whats going on, but just running the same # command again once it finishes works, and this is only # rarely used and done manually anyways, so whatever. -pxe-kexec -n --ignore-whitelist -l fai-generated faiserver +pxe-kexec -n --ignore-whitelist -l fai-generated faiserver.b8.nz diff --git a/mk-basefile-big b/mk-basefile-big index 873b7ff..1a6b6a9 100755 --- a/mk-basefile-big +++ b/mk-basefile-big @@ -16,11 +16,13 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -[[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@" +[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" +set -e; . /usr/local/lib/bash-bear; set +e -x="$(readlink -f "$BASH_SOURCE")"; source "${x%/*}/bash-trace" -x="$(readlink -f -- "$BASH_SOURCE")"; PATH="${x%/*}:$PATH" # directory of this file +this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" +readonly this_file this_dir="${this_file%/*}" +PATH="$this_dir:$PATH" # directory of this file usage() { cat < /srv/fai/config/class/51-multi-boot rm -rf $t; mkdir -p $t +# shellcheck disable=SC1007 # intentional LANG= fai -N -u hostname_does_not_matter dirinstall $t # Turn a dirinstall into a basefile. taken from mk-basefile @@ -100,7 +103,7 @@ rm -f $t/etc/hostname $t/etc/resolv.conf \ $t/var/lib/apt/lists/*_* $t/usr/bin/qemu-*-static \ $t/etc/udev/rules.d/70-persistent-net.rules echo | dd of=$t/etc/machine-id -tar --one-file-system -C $t -cf - . | gzip > /a/bin/fai-basefiles/basefiles/${distver^^}64BIG.tar.gz +tar --one-file-system -C $t -cf - . | zstd -9 > /a/bin/fai-basefiles/basefiles/${distver^^}64BIG.tar.zst cleanup diff --git a/myfai-chboot b/myfai-chboot index 743859a..aa3c088 100755 --- a/myfai-chboot +++ b/myfai-chboot @@ -19,42 +19,52 @@ set -eE -o pipefail trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR -x=$(readlink -f "$BASH_SOURCE"); cd ${x%/*} +this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" +readonly this_file this_dir="${this_file%/*}" +cd "$this_dir" usage() { - cat </dev/null; then ./myfai-chboot-local "$@" else diff --git a/myfai-chboot-local b/myfai-chboot-local index 4cef9a5..ca4d32e 100755 --- a/myfai-chboot-local +++ b/myfai-chboot-local @@ -16,54 +16,72 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# note, this script gets piped to bash, so cant cd to current dir -[[ $EUID == 0 ]] || exec sudo "${BASH_SOURCE}" "$@" +[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" + +set -x set -eE -o pipefail trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR +pre="${0##*/}:" +m() { printf "$pre %s\n" "$*"; "$@"; } +e() { printf "$pre %s\n" "$*"; } +err() { echo "[$(date +'%Y-%m-%d %H:%M:%S%z')]: $pre: $*" >&2; } + +usage() { + cat <&2; exit 1; } + +temp=$(getopt -l help,no-r hSi "$@") || usage 1 +eval set -- "$temp" +while true; do case $1 in - -h|--help) - echo "see help from myfai-chboot" - exit 0 - ;; -S) fai_action=sysinfo fai_reboot_arg= - shift ;; -i) #inventory fai_action=inventory fai_reboot_arg= - shift ;; -k) kgped16=true - shift ;; -b) bond=true - shift ;; --no-r) fai_reboot_arg= - shift ;; + -h|--help) usage ;; + --) shift; break ;; + *) echo "$0: unexpected args: $*" >&2 ; usage 1 ;; esac + shift done - -pre="${0##*/}:" -m() { printf "$pre %s\n" "$*"; "$@"; } -e() { printf "$pre %s\n" "$*"; } -err() { echo "[$(date +'%Y-%m-%d %H:%M:%S%z')]: $pre: $*" >&2; } - -host=$1 +read -r host <<<"$@" +readonly host rm -f /srv/tftp/fai/pxelinux.cfg/* @@ -112,7 +130,7 @@ else fi if modprobe nfsd &>/dev/null; then - std_arg="-u nfs://faiserver/srv/fai/config" + std_arg="-u nfs://faiserver.b8.nz/srv/fai/config" # nfsv4 wont do rw with overlayfs yet # https://lists.uni-koeln.de/pipermail/linux-fai/2017-March/011641.html root_arg="$my_ip:/srv/fai/nfsroot:vers=3" @@ -132,9 +150,9 @@ EOF fi systemctl start nfs-server # assumes recent os else - std_arg="-u http://faiserver:8080/config.tar.gz" - root_arg="live:http://faiserver:8080/squash.img" - /a/exe/web-conf -i -p 8080 - apache2 faiserver < Deny from all Allow from $ip @@ -151,7 +169,7 @@ kernel=$(fai-chboot -L '^default$' | awk '{print $3}') default_k_args=$(fai-chboot -L '^default$' | \ sed -r "s/^(\S+\s+){3}(.*)/\2/") # example of default_k_args -# initrd=initrd.img-3.16.0-4-amd64 ip=dhcp root=192.168.1.3:/srv/fai/nfsroot FAI_CONFIG_SRC=nfs://faiserver/srv/fai/config FAI_ACTION=install +# initrd=initrd.img-3.16.0-4-amd64 ip=dhcp root=192.168.1.3:/srv/fai/nfsroot FAI_CONFIG_SRC=nfs://faiserver.b8.nz/srv/fai/config FAI_ACTION=install # https://wiki.archlinux.org/index.php/Solid_state_drive#Resolving_NCQ_errors # currently on needed on d16 samsung 870 qvo, but better to have this diff --git a/mymk-basefile b/mymk-basefile index 9dc7b14..1f32665 100755 --- a/mymk-basefile +++ b/mymk-basefile @@ -16,12 +16,15 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -x="$(readlink -f "$BASH_SOURCE")"; source "${x%/*}/bash-trace" -script_dir="${x%/*}" +set -e; . /usr/local/lib/bash-bear; set +e + +this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" +readonly this_file this_dir="${this_file%/*}" +cd "$this_dir" usage() { - cat <&2' ERR [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" -x="$(readlink -f "$BASH_SOURCE")"; cd ${x%/*} +this_file="$(readlink -f -- "${BASH_SOURCE[0]}")" +readonly this_file this_dir="${this_file%/*}" +cd "$this_dir" usage() { - cat <&2;exit 1;}; . $f +set -e; . /usr/local/lib/bash-bear; set +e + usage() { cat < $(date +%s) )); then + if ! (( $(date -r ${f[0]} +%s) + 60*60*24 > $(date +%s) )); then if ! opkg update; then echo "$0: warning: opkg update failed" >&2 fi @@ -157,7 +159,7 @@ pi() { pmirror fi done - if [[ $to_install ]]; then + if (( ${#to_install[@]} >= 1 )); then opkg install ${to_install[@]} fi } @@ -238,7 +240,7 @@ fi if $secrets; then key=${rkey[$h]} fi -: ${key:=pictionary49} +: "${key:=pictionary49}" mask=255.255.0.0 cidr=16 @@ -536,8 +538,7 @@ EOF # option config /etc/openvpn/client.conf # EOF -wgip4=10.3.0.1/24 -wgip6=fdfd::1/64 + wgport=26000 network_restart=false @@ -577,10 +578,10 @@ if $network_restart; then v /etc/init.d/network reload fi -firewall-cedit() { - if $client; then - cedit wific /etc/config/firewall <