From: Ian Kelling Date: Sun, 10 Jul 2022 21:30:41 +0000 (-0400) Subject: change partitioning to use lvm, refactor for fsf server X-Git-Url: https://iankelling.org/git/?a=commitdiff_plain;h=14f283f82afc48d6cec1bb7498ec34ac2b0da77c;p=automated-distro-installer change partitioning to use lvm, refactor for fsf server --- diff --git a/.gitignore b/.gitignore index d01c086..c49e0c9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /fai/config/class/51-multi-boot /fai/config/files/root/.ssh/authorized_keys +/fai/config/files/root/.ssh/authorized_keys2 /fai/config/files/usr/local diff --git a/README b/README index 4bbcc87..0dc966b 100644 --- a/README +++ b/README @@ -138,6 +138,83 @@ faiserver-disable # Disable the fai nfs server exports fresize # resize swap or boot partitions in a host +# NAT/forward/vpn tftp + +I tried to get this working, but failed. + +tftp server in theory can be forwarded over a vpn, eg on a wireguard tunnel. + +However, I found that when actually pxe booting, it wouldn't work, only +the 1st filename would be requested, eg, in the logs: + +Jun 20 23:51:02 kd in.tftpd[4021350]: RRQ from 10.2.0.12 filename pxelinux.0 + + +To get that far, nating tftp requires some special attention in iptables, like so: + +https://unix.stackexchange.com/questions/579508/iptables-rules-to-forward-tftp-via-nat +iptables -t raw -A PREROUTING -p udp --dport 69 -s 209.51.188.0/24 -j CT --helper tftp +modprobe nf_nat_tftp + +to test tftp from a client machine: + +tftp SERVER_IP -c get pxelinux.0 +rm -fv pxelinux.0 + + +# Common problems + +## kernel mismatch very early error, no remote logs: + +ERROR: the running kernel does not match the kernel modules inside the nfsroot. +ERROR: Kernel modules directory /lib/modules/5.10.0-8-amd not available. Only found /lib/modules/5.10.0-15-amd64 + +solution: if running from fai-cd, recreate autodiscover cd as noted above in setup. + +# What good logs look like: + +logging nfs traffic from server + +s rpcdebug -m nfsd -s all + + +normal nfs mount & umount logs look like: + +journalctl -ef | gr nfs + +Jun 20 22:15:36 kd rpc.mountd[2025725]: authenticated mount request from 10.32.2.1:865 for /srv/fai/nfsroot (/srv/fai/nfsroot) +Jun 20 22:15:36 kd kernel: nfsd: exp_rootfh(/srv/fai/nfsroot [00000000e8c53e54] *:dm-0/5521225) +Jun 20 22:15:36 kd kernel: nfsd: fh_compose(exp 00:1b/5521225 fai/nfsroot, ino=5521225) +Jun 20 22:15:36 kd kernel: nfsd: FSINFO(3) 28: 00070001 00543f49 00000000 d185f7b0 58d1a3c6 00000000 +Jun 20 22:15:36 kd kernel: nfsd: fh_verify(28: 00070001 00543f49 00000000 d185f7b0 58d1a3c6 00000000) +Jun 20 22:15:36 kd kernel: nfsd: PATHCONF(3) 28: 00070001 00543f49 00000000 d185f7b0 58d1a3c6 00000000 +Jun 20 22:15:36 kd kernel: nfsd: fh_verify(28: 00070001 00543f49 00000000 d185f7b0 58d1a3c6 00000000) +Jun 20 22:15:36 kd kernel: nfsd: GETATTR(3) 28: 00070001 00543f49 00000000 d185f7b0 58d1a3c6 00000000 +Jun 20 22:15:36 kd kernel: nfsd: fh_verify(28: 00070001 00543f49 00000000 d185f7b0 58d1a3c6 00000000) +Jun 20 22:15:36 kd kernel: nfsd: FSINFO(3) 28: 00070001 00543f49 00000000 d185f7b0 58d1a3c6 00000000 +Jun 20 22:15:36 kd kernel: nfsd: fh_verify(28: 00070001 00543f49 00000000 d185f7b0 58d1a3c6 00000000) +Jun 20 22:15:36 kd kernel: nfsd: GETATTR(3) 28: 00070001 00543f49 00000000 d185f7b0 58d1a3c6 00000000 +Jun 20 22:15:36 kd kernel: nfsd: fh_verify(28: 00070001 00543f49 00000000 d185f7b0 58d1a3c6 00000000) +Jun 20 22:15:45 kd rpc.mountd[2025725]: authenticated unmount request from 10.32.2.1:986 for /srv/fai/nfsroot (/srv/fai/nfsroot) + +normal tftpd logs from: + +after setting -vv in TFTP_OPTIONS in /etc/default/tftpd-hpa + +journalctl -u tftpd-hpa + +Jun 20 23:51:02 kd in.tftpd[4021350]: RRQ from 10.2.0.12 filename pxelinux.0 +Jun 20 23:51:02 kd in.tftpd[4021351]: RRQ from 10.2.0.12 filename ldlinux.c32 +Jun 20 23:51:02 kd in.tftpd[4021352]: RRQ from 10.2.0.12 filename pxelinux.cfg/a913a477-fca6-234d-a928-6bb011decd05 +Jun 20 23:51:02 kd in.tftpd[4021352]: sending NAK (1, File not found) to 10.2.0.12 +Jun 20 23:51:02 kd in.tftpd[4021353]: RRQ from 10.2.0.12 filename pxelinux.cfg/01-52-54-00-9c-ef-ad +Jun 20 23:51:02 kd in.tftpd[4021353]: sending NAK (1, File not found) to 10.2.0.12 +Jun 20 23:51:02 kd in.tftpd[4021354]: RRQ from 10.2.0.12 filename pxelinux.cfg/0A02000C +Jun 20 23:51:02 kd in.tftpd[4021355]: RRQ from 10.2.0.12 filename vmlinuz-5.10.0-15-amd64 +Jun 20 23:51:03 kd in.tftpd[4021356]: RRQ from 10.2.0.12 filename initrd.img-5.10.0-15-amd64 + + + # Replacing a raid 10 disk pxe-server -S HOST fai @@ -177,7 +254,9 @@ reboot # Expected output in fai logs -On focal, + +## On focal: + fai.log:updatebase.UBUNTU FAILED with exit code 1. the real error is dpkg-reconfigure locales, seems to be related to a workaround for < 20.04, relevant comment: @@ -185,13 +264,17 @@ to a workaround for < 20.04, relevant comment: in config/hooks/instsoft.DEBIAN -For flidas, when installing systemd, this error happens, and it's +## For flidas, + +when installing systemd, this error happens, and it's a superflous upstream bug based on reading the post install script: addgroup: The group `systemd-journal' already exists as a system group. Exiting. Operation failed: No such file or directory -On nabia/newer, python is removed, now its python3, +## On nabia/newer, + +python is removed, now its python3, and its easier to just let the package get removed than do host class package config. fai.log:WARNING: These unknown packages are removed from the installation list: python python-minimal @@ -204,6 +287,10 @@ fai.log:WARNING: These unknown packages are removed from the installation list: Also, cryptsetup-initramfs is new to buster/nabia, it gets removed on earlier versions. +## parted error +fai.log:Error: /dev/vda: unrecognised disk label +This is from parted -m $d unit MiB print. +It happens when there are no partitions yet. # linode notes diff --git a/chost b/chost index 18c0aac..204637b 100755 --- a/chost +++ b/chost @@ -18,4 +18,6 @@ case $h in ;; esac h=${h##* } +# trailing dot in a hostname will mess up rsync +h=${h%.} echo $h diff --git a/fai-redep b/fai-redep index df08b76..924e8b7 100755 --- a/fai-redep +++ b/fai-redep @@ -8,6 +8,8 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR readonly this_file="$(readlink -f -- "${BASH_SOURCE[0]}")"; cd "${this_file%/*}" +source bash-trace + usage() { cat </dev/null; then - rpre="-e 'ssh -F $HOME/.ssh/confighome' root@$faiserver_host:" + rpre=(-e "ssh -F $HOME/.ssh/confighome" root@$faiserver_host:) faiserver_shell="ssh -F $HOME/.ssh/confighome root@$faiserver_host" fi @@ -72,27 +76,35 @@ rsync -atL /a/bin/ds/hssh fai/config/files/usr/local/bin/hssh/STANDARD 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 -rsync -rlpt --delete --relative --exclude /fai/config/basefiles/ fai/config $rpre/srv +m rsync -rlpt --delete --relative --exclude /fai/config/basefiles/ fai/config "${rpre[@]}"/srv # todo: automatically disable faiserver after a period so # these files are not available. if [[ $target ]]; then - if test -e /q/root/shadow/$target; then - shadowfile=shadow/$target # empty otherwise + 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 + secrets_to_send+=("$f") + fi + done + if $exists; then + { + for f in ${secrets_to_send[@]}; do + echo $f + done + } | rsync -lpt --files-from=- /q/root "${rpre[@]}"/srv/fai/config/distro-install-common fi - rsync -lpt --files-from=- /q/root $rpre/srv/fai/config/distro-install-common </dev/null ||: # broken pipe -rsync -rplt --include '/*.gz' --exclude '/**' --delete-excluded $BASEFILE_DIR/ $rpre/srv/fai/config/basefiles/ +rsync -rplt --include '/*.gz' --exclude '/**' --delete-excluded $BASEFILE_DIR/ "${rpre[@]}"/srv/fai/config/basefiles/ diff --git a/fai-revm b/fai-revm index 5aa1e6c..a016a76 100755 --- a/fai-revm +++ b/fai-revm @@ -16,6 +16,8 @@ # 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]}")" script_dir="${this_file%/*}" @@ -36,7 +38,8 @@ then start a virtual machine to test the config Note, sometimes shutting down the existing demohost vm fails. Just run again if that happens. --d Don't do dhcp setup for when we aren't on Ian's home network. +-d When doing pxe, don't do dhcp setup. Good for when we + aren't on Ian's home network. -n Create new qcow2(s) for vm. Good for testing partitioning script, to ensure a blank disk. -p Use pxe instead of autodiscover iso with fai. @@ -69,11 +72,13 @@ while true; do done -# change this to test different disk counts. 1 and > 1 should be the only -# important things to test. +# change this to test different disk counts. +disk_count=3 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: @@ -101,19 +106,23 @@ is_arch_revm() { err-cleanup() { echo "doing cleanup" - e ./pxe-server $dhcp_arg + if [[ -e /tmp/fai-revm-did-pxe ]]; then + e ./pxe-server $dhcp_arg + fi ./faiserver-disable } boot_arg=--pxe if is_arch_revm; then e ./pxe-server $dhcp_arg demohost arch + touch /tmp/fai-revm-did-pxe sleep 2 # via osinfo-query os. guessing arch is closest to latest fedora. variant=fedora22 else if $pxe; then e ./pxe-server $dhcp_arg demohost fai + touch /tmp/fai-revm-did-pxe sleep 2 else killall fai-monitor &>/dev/null ||: @@ -124,23 +133,28 @@ else isopath=$BASEFILE_DIR/$iso isosrc=$BASEFILE_DIR/BULLSEYE64.tar.gz if [[ ! -e $isopath || $(stat -c %Y $isopath) -lt $(stat -c %Y $isosrc) ]]; then - e sudo fai-cd -g $(readlink -f grub.cfg.${iso%%.*}) -f -A $isopath + 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 e myfai-chboot default fi # I don't think these variants actually make a diff for us, but I # use the appropriate one when trying a new distro just in case. - variant=ubuntu14.04 + #variant=ubuntu14.04 #variant=ubuntu16.04 #variant=debian8 + variant=ubuntu20.04 fi name=demohost -e sudo virsh destroy $name ||: -e sudo virsh undefine $name ||: +e virsh destroy $name ||: +sleep 1 +e virsh destroy $name ||: +e virsh undefine $name ||: +sleep 1 disk_arg=() @@ -148,11 +162,11 @@ for ((i=1; i <= disk_count; i++)); do f=/var/lib/libvirt/images/${name}$i disk_arg+=("--disk path=$f") if $new_disk || [[ ! -e $f ]]; then - sudo rm -f $f + rm -f $f # https://btrfs.wiki.kernel.org/index.php/FAQ - sudo touch $f + touch $f chattr +C $f - e sudo qemu-img create -o preallocation=metadata -f qcow2 $f 50G + e qemu-img create -o preallocation=metadata -f qcow2 $f 50G fi done @@ -161,14 +175,14 @@ if [[ $SSH_CLIENT ]]; then fi # docker makes forward default to drop, which blocks the vm pxe on flidas. easiest solution: -e sudo iptables -P FORWARD ACCEPT +e iptables -P FORWARD ACCEPT # --cpu host: this causes mkfs.btrfs to fail with a stack trace which began # something like: # init_module+0x108/0x1000 [raid6_pq] # # uniq is to stop gtk-warning spam -# e sudo virt-install --os-variant $variant -n $name --pxe -r 2048 --vcpus 1 \ +# e virt-install --os-variant $variant -n $name --pxe -r 2048 --vcpus 1 \ # ${disk_arg[*]} -w bridge=br0,mac=52:54:00:9c:ef:ad $reboot_arg \ # --graphics spice,listen=0.0.0.0 $console_arg |& grep -v '^ *$' | uniq & @@ -177,8 +191,8 @@ if (( $(nproc) > 2 )); then cpus=2 fi -e sudo systemctl start libvirtd -e sudo virt-install --rng /dev/urandom --os-variant $variant -n $name $boot_arg -r 2048 --vcpus $cpus \ +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 \ --graphics spice,listen=0.0.0.0 $console_arg |& grep -v '^ *$' | uniq & @@ -188,11 +202,18 @@ if [[ $SSH_CLIENT ]]; then fi sleep 90 -while ! timeout -s 9 10 ssh -oBatchMode=yes root@$name /bin/true; do +while ! timeout -s 9 10 ssh -oBatchMode=yes root@$name true; do e sleep 5 done unset -f err-cleanup -e ./pxe-server $dhcp_arg +if $pxe; then + rm -f /tmp/fai-revm-did-pxe + e ./pxe-server $dhcp_arg +fi + +# this tends to remove it too soon +#echo | /a/exe/cedit -s /srv/fai/nfsroot/root/.ssh/authorized_keys + if is_arch_revm; then ./arch-init-remote $name fi diff --git a/fai/config/class/50-host-classes b/fai/config/class/50-host-classes index 11559c1..80b86b5 100755 --- a/fai/config/class/50-host-classes +++ b/fai/config/class/50-host-classes @@ -28,24 +28,24 @@ echo FAIBASE STANDARD DEBIAN # things installed, to speed up installation. # # STRETCH64, BUSTER64, BULLSEYE64, BOOKWORM64 -# FLIDAS64, FLIDAS64BIG, ETIONA64, NABIA64 +# FLIDAS64, FLIDAS64BIG, ETIONA64, NABIA64, ARAMO64 # XENIAL64, BIONIC64, FOCAL64, # # The distro subvol name, we can add as many of these as we want: # VOL_TESTING, VOL_STRETCH, VOL_BUSTER, VOL_BULLSEYE, VOL_BOOKWORM -# VOL_FLIDAS, VOL_ETIONA, VOL_NABIA +# VOL_FLIDAS, VOL_ETIONA, VOL_NABIA, VOL_ARAMO # VOL_XENIAL, VOL_BIONIC VOL_FOCAL # VOL_BUSTER_BOOTSTRAP. # Using VOL_BUSTER_BOOTSTRAP sets up the install to act like a pxe rom if # grub sets a specific var. # # The apt sources files we want, -# STRETCH_FREE, STRETCH_NONFREE, +# STRETCH_FREE, STRETCH_NONFREE, STRETCH_LINODE # BUSTER_FREE, BUSTER_NONFREE, # BULLSEYE_FREE, BULLSEYE_NONFREE # BOOKWORM_FREE, BOOKWORM_NONFREE # TESTING_FREE, TESTING_NONFREE, -# XENIAL_FREE, BIONIC, FOCAL, FLIDAS, ETIONA, NABIA, STRETCH_LINODE. +# XENIAL_FREE, BIONIC, FOCAL, FLIDAS, ETIONA, NABIA, ARAMO. # # It's all a little redundant in some cases, but it keeps things # simpler. @@ -63,29 +63,19 @@ echo FAIBASE STANDARD DEBIAN # DESKTOP: install a bunch of extra packages. For creating X suffix # basefiles. See README. # -# REPARTITION: we try to reuse partitions/filesystems to install a new -# os into a multi-os system, if we see some basic hueristics, like the -# right amount of them. This overrides that. -# -# REROOTFS: Don't reuse the root filesystem, even if we normally would -# -# NOWIPE: use existing subvolumes if they exist -# -# PARTITION_PROMPT: If we don't see partitions to reuuse, prompt -# to make sure we really want to repartition and use a completely -# fresh install. I use this in case our repartition check has -# a bug in it, or I accidentally set REPARTITION. -# -# ROTATIONAL: in a system with ssd and hdd, install to the hdd -# instead of the default ssd. -# -# RAID0: Use raid 0 even if there are >= 4 disks with boot partitions. -# # LINODE: For running a vm on linode, especially one created with fai-cd. # # IANK / FSF: general setup of my machine vs FSF machines # NABIA_EXTRA: extra repos for NABIA from other distros - +# ARAMO_EXTRA: extra repos for ARAMO from other distros +# +# UBUNTU_UP: for trisquel, we want to inherit ubuntu things, except for +# some ubuntu things which go in this class. UP = upstream. +# +# D16: for kgpe-d16 specific settings. +# +# For filesystem/partitioning related classes, see comments at the top of +# fai/config/hooks/partition.DEFAULT if [[ -e /a/bin/fai/fai-wrapper ]]; then source /a/bin/distro-functions/src/identify-distros @@ -132,7 +122,9 @@ exit 0 #!/bin/bash -echo IANK +# pick one of these: +#echo IANK +#echo FSF if [[ ! -e /a/bin/fai/fai-wrapper || $FAI_ACTION == dirinstall ]]; then case $HOSTNAME in # bullseye based minimal recovery / bootstraping os: diff --git a/fai/config/class/D16.var b/fai/config/class/D16.var new file mode 100644 index 0000000..dc8d96b --- /dev/null +++ b/fai/config/class/D16.var @@ -0,0 +1,3 @@ +# pci=realloc=off = per rubens suggestion to make a d16 more stable +d16_cmdline="console=ttyS0,115200n8 pci=realloc=off console=tty0" +d16_cmdline="pci=realloc=off console=tty0" diff --git a/fai/config/class/LINODE.var b/fai/config/class/LINODE.var index 8f34a2c..3558dfc 100644 --- a/fai/config/class/LINODE.var +++ b/fai/config/class/LINODE.var @@ -5,3 +5,4 @@ linode_gw=172.105.84.1 linode_if=enp0s3 LOGSERVER=b8.nz HOSTNAME=l2 +cmdline_extra=console=ttyS0,19200n8 diff --git a/fai/config/distro-install-common/end b/fai/config/distro-install-common/end index efb501a..602e2ba 100755 --- a/fai/config/distro-install-common/end +++ b/fai/config/distro-install-common/end @@ -18,28 +18,11 @@ if [[ -e $src && -e $dst ]]; then cp -rT $src $dst fi -USER2PW=/q/root/shadow/user2 -# if doesn't exist, we dont set one -ROOTPW=/q/root/shadow/standard -if [[ ! -e $ROOTPW ]]; then - ROOTPW=/q/root/shadow/$HOSTNAME +root_pw_f=/q/root/shadow/standard +if [[ ! -e $root_pw_f ]]; then + root_pw_f=/q/root/shadow/$HOSTNAME fi -chpw() { - # generating a hashed password: - # under debian, you can do - # mkpasswd -m sha-512 -s >/q/root/shadow/standard - # On arch, best seems to be copy your shadow file to a temp location, - # then passwd, get out the new pass, then copy the shadow file back. - - user=$1 - pwfile=$2 - if [[ $pwfile && -e $pwfile ]]; then - printf "$user:" | cat - "$pwfile" | $ROOTCMD chpasswd -e - else - echo "$0: warning: no pw set for $user" >&2 - fi -} au() { # add user. i don't use adduser for portability local user=${@: -1} if ! $ROOTCMD getent passwd $user; then @@ -47,7 +30,12 @@ au() { # add user. i don't use adduser for portability fi } -chpw root "$ROOTPW" +# generating a hashed password: +# under debian, you can do +# mkpasswd -m sha-512 -s >/q/root/shadow/standard +# On arch, best seems to be copy your shadow file to a temp location, +# then passwd, get out the new pass, then copy the shadow file back. +sed 's/^/root:/' $root_pw_f | $ROOTCMD chpasswd -e # only setup root pass for bootstrap vol if ifclass VOL_BULLSEYE_BOOTSTRAP; then @@ -57,11 +45,11 @@ fi # return of 9 = user already exists. so we are idempotent. au iank -chpw iank "$ROOTPW" +sed 's/^/iank:/' $root_pw_f | $ROOTCMD chpasswd -e au user2 if ifclass frodo; then - chpw user2 "$USER2PW" + sed 's/^/user2:/' /q/root/shadow/user2 | $ROOTCMD chpasswd -e fi # comparing iank's groups to user2, I see none she should join on arch $ROOTCMD usermod -a -G user2 iank diff --git a/fai/config/files/boot/bash-trace/DEFAULT b/fai/config/files/boot/bash-trace/DEFAULT index dc1a218..2a4077f 100644 --- a/fai/config/files/boot/bash-trace/DEFAULT +++ b/fai/config/files/boot/bash-trace/DEFAULT @@ -1,10 +1,47 @@ #!/bin/bash -# Copyright (C) 2019 Ian Kelling +# 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. -# Commentary: Print stack trace and exit/return on errors, or use -# functions below for for more details and manual error handling. See -# end of file for credits etc. +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 @@ -17,6 +54,10 @@ # 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 @@ -39,9 +80,11 @@ err-catch() { ) fi declare -i _err_func_last=0 - shopt -s extdebug + if [[ $- != *c* ]]; then + shopt -s extdebug + fi # shellcheck disable=SC2154 - trap '_err-bash-trace-interactive $? "$BASH_COMMAND" ${BASH_ARGC[0]} "${BASH_ARGV[@]}" || return $?' ERR + 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 @@ -86,27 +129,67 @@ err-allow() { # ####################################### err-exit() { - local err=$? + # 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 _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#-} + _err=${1#-} shift - elif (( ! err )); then - err=1 + elif (( ! _err )); then + _err=1 fi if [[ $1 ]]; then - msg="$1" + _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 - printf "%s\n" "$msg" >&2 + ## 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 + printf "%s: exiting with status %s\n" "$0" "$_err" >&2 + exit $_err } ####################################### @@ -176,14 +259,20 @@ _err-bash-trace-interactive() { # We have these passed to us because they are lost inside the # function. ret=$1 - bash_command="$2" - argc=$(( $3 - 1 )) - shift 3 + 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 we are the first. - if (( _err_func_last > last )); then - printf "ERR: \`%s\' returned %s\n" "$bash_command" $ret >&2 + # 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 @@ -207,14 +296,3 @@ _err-bash-trace-interactive() { return 0 fi } - -# Credits etc: -# -# Related: see my bash script template repo at https://iankelling.org/git. -# -# -# Please email me if you have a patches, bugs, feedback, or if you use -# it or republish it since I'm not aware of any users yet -# Ian Kelling . -# -# Tested on bash 4.4.20(1)-release (x86_64-pc-linux-gnu). If you test diff --git a/fai/config/files/etc/apt/preferences.d/aramo-jammy/ARAMO b/fai/config/files/etc/apt/preferences.d/aramo-jammy/ARAMO new file mode 100644 index 0000000..7985fe5 --- /dev/null +++ b/fai/config/files/etc/apt/preferences.d/aramo-jammy/ARAMO @@ -0,0 +1,3 @@ +Package: * +Pin: release n=jammy,o=Ubuntu +Pin-Priority: -100 diff --git a/fai/config/files/etc/apt/sources.list.d/aaa-aramo.list/ARAMO b/fai/config/files/etc/apt/sources.list.d/aaa-aramo.list/ARAMO new file mode 100644 index 0000000..7fdf4ff --- /dev/null +++ b/fai/config/files/etc/apt/sources.list.d/aaa-aramo.list/ARAMO @@ -0,0 +1,11 @@ +deb http://archive.trisquel.org/trisquel/ aramo main +deb-src http://archive.trisquel.org/trisquel/ aramo main + +deb http://archive.trisquel.org/trisquel/ aramo-updates main +deb-src http://archive.trisquel.org/trisquel/ aramo-updates main + +deb http://archive.trisquel.info/trisquel/ aramo-security main +deb-src http://archive.trisquel.info/trisquel/ aramo-security main + +deb http://archive.trisquel.org/trisquel/ aramo-backports main +deb-src http://archive.trisquel.org/trisquel/ aramo-backports main diff --git a/fai/config/files/etc/apt/sources.list.d/focal.list/NABIA b/fai/config/files/etc/apt/sources.list.d/focal.list/NABIA_EXTRA similarity index 100% rename from fai/config/files/etc/apt/sources.list.d/focal.list/NABIA rename to fai/config/files/etc/apt/sources.list.d/focal.list/NABIA_EXTRA diff --git a/fai/config/files/etc/apt/sources.list.d/jammy.list/ARAMO_EXTRA b/fai/config/files/etc/apt/sources.list.d/jammy.list/ARAMO_EXTRA new file mode 120000 index 0000000..4892ca6 --- /dev/null +++ b/fai/config/files/etc/apt/sources.list.d/jammy.list/ARAMO_EXTRA @@ -0,0 +1 @@ +JAMMY \ No newline at end of file diff --git a/fai/config/hooks/instsoft.DEFAULT b/fai/config/hooks/instsoft.DEFAULT index 22c8104..9d8f0b7 100755 --- a/fai/config/hooks/instsoft.DEFAULT +++ b/fai/config/hooks/instsoft.DEFAULT @@ -7,6 +7,10 @@ if ifclass VM && ! ifclass demohost || ifclass VOL_BULLSEYE_BOOTSTRAP || [[ ! $F exit 0 fi +if ifclass FSF; then + exit 0 +fi + keyfile=/var/lib/fai/config/distro-install-common/luks/host-$HOSTNAME f=$target/root/keyscript cat > $f <&2' ERR @@ -80,11 +82,16 @@ fi # ROTATIONAL: forces to install onto hdds instead of sdds. normally sdds # are chosen if they exist. # -# PARTITION_PROMPT: command line prompt before partitioning +# PARTITION_PROMPT: command line prompt before partitioning. This is good +# to set if we don't expect repartitioning to happen. +# +# ROTATIONAL: in a system with ssd and hdd, install to the hdd +# instead of the default ssd. # # RAID0: forces raid0 filesystem. Normally with 4+ devices, we use # raid10. # RAID1: forces raid1 filesystem. +# RAID1c3: forces raid1c3 filesystem (btrfs raid 1, 3 copies). mkroot2tab=false mkroot2=false @@ -94,7 +101,7 @@ if [[ $1 ]]; then if ! type -t ifclass &>/dev/null; then ifclass() { local var=${1/#/CLASS_} - [[ $HOSTNAME == $1 || ${!var} ]] + [[ $HOSTNAME == "$1" || ${!var} ]] } fi @@ -143,8 +150,6 @@ if ! type -p devbyid; then fi fi - - #### begin configuration # this is the ordering of the /dev/sdaX, but @@ -152,27 +157,11 @@ fi # bios_grub # grub_ext # efi -# root -# swap -# boot - -rootn=1 -root2n=2 -swapn=3 -bootn=4 -boot2n=5 -efin=6 -# ext partition so grub can write persistent variables, -# so it can do a one time boot. grub can't write to -# btrfs or any cow fs because it's more -# more complicated to do and they don't want to. -grub_extn=7 -# bios boot partition, -# https://wiki.archlinux.org/index.php/GRUB -bios_grubn=8 -# for an even raid (raid 1), when one disk is bigger, this partition goes on the big disk -even_bign=9 -lastn=$bios_grubn +# lvm +# root +# swap +# boot + @@ -180,45 +169,70 @@ lastn=$bios_grubn ##### begin function defs -add-part() { # add partition suffix to $dev - local d part - if [[ $# == 1 ]]; then - d=$dev - part=$1 +bpart() { # btrfs a partition + case $raid_level in + 0) mkfs.btrfs -f $@ ;; + *) mkfs.btrfs -f -m raid$raid_level -d raid$raid_level $@ ;; + esac +} + + +zilap() { + case $HOSTNAME in + sy|bo) + return 0 + ;; + esac + return 1 +} + +getluks() { + if [[ ! $luks_dir ]]; then + # see README for docs about how to create these + luks_dir=$FAI/distro-install-common/luks + if [[ ! -d $luks_dir ]]; then + luks_dir=/q/root/luks + fi + if [[ ! -d $luks_dir ]]; then + echo "$0: error: no luks_dir found" >&2 + exit 1 + fi + fi + + luks_file=$luks_dir/host-$HOSTNAME + if [[ ! -e $luks_file ]]; then + # shellcheck disable=SC2206 # globbing is intended + hostkeys=($luks_dir/host-*) + # if there is only one key, we might be deploying somewhere + # where dhcp doesnt give us a proper hostname, so use that. + if [[ ${#hostkeys[@]} == 1 && -e ${hostkeys[0]} ]]; then + luks_file=${hostkeys[0]} + else + echo "$0: error: no key for hostname at $luks_file" >&2 + exit 1 + fi + fi + + # # note, corresponding changes in /b/ds/keyscript-{on,off} + if ifclass demohost; then + lukspw=x + elif [[ -e $luks_dir/$HOSTNAME ]]; then + lukspw=$(cat $luks_dir/$HOSTNAME) else - d=$1 - part=$2 + lukspw=$(cat $luks_dir/iank) + fi + + if $mkroot2; then + luks_file=$luks_dir/host-amy + lukspw=$(cat $luks_dir/amy) fi - echo $d-part$part } -rootdev() { add-part $@ $rootn; } -root2dev() { add-part $@ $root2n; } - -# note, the following block could all have $@ like below -# But it is not added since it is not used and shellcheck -# rightly says args never used should not exist. -##swapdev() { add-part $swapn; } - -swapdev() { add-part $swapn; } -bootdev() { add-part $bootn; } -boot2dev() { add-part $boot2n; } -efidev() { add-part $efin; } -grub_extdev() { add-part $grub_extn; } -bios_grubdev() { add-part $bios_grubn; } -even_bigdev() { add-part $even_bign; } - -crypt-dev() { echo /dev/mapper/crypt_dev_${1##*/}; } -crypt-name() { echo crypt_dev_${1##*/}; } -root-cryptdev() { crypt-dev $(rootdev $@); } -root2-cryptdev() { crypt-dev $(root2dev $@); } - -# I omit a possible parameter since it is unused: -##swap-cryptdev() { crypt-dev $(swapdev $@); } -swap-cryptdev() { crypt-dev $(swapdev); } -root-cryptname() { crypt-name $(rootdev); } -root2-cryptname() { crypt-name $(root2dev); } -swap-cryptname() { crypt-name $(swapdev); } + +fsf() { + ifclass FSF +} + dev-mib() { local d=${1:-$dev} @@ -228,6 +242,7 @@ dev-mib() { luks-setup() { local luksdev="$1" + local cryptname="$2" # when we move to newer than trisquel 9, we can remove # --type luks1. We can also check on cryptsetup --help | less /compil # to see about the other settings. Default in debian 9 is luks2. @@ -248,9 +263,121 @@ luks-setup() { # This would remove the keyfile. # yes 'test' | cryptsetup luksRemoveKey /dev/... \ # /key/file || [[ $? == 141 ]] - cryptsetup luksOpen $luksdev $(crypt-name $luksdev) --key-file $luks_file + cryptsetup luksOpen $luksdev $cryptname --key-file $luks_file } +mktab() { + mkdir -p /tmp/fai + dev=${boot_devs[0]} + fstabstd="x-systemd.device-timeout=30s,x-systemd.mount-timeout=30s" + + if [[ $DISTRO == debianbullseye_bootstrap ]]; then + cat > /tmp/fai/fstab </tmp/fai/disk_var.sh < /tmp/fai/fstab <>/tmp/fai/crypttab <> /tmp/fai/fstab <> /tmp/fai/fstab </tmp/fai/disk_var.sh <>/tmp/fai/crypttab <> /tmp/fai/fstab <>/mnt/root/root2-crypttab <>/mnt/root/root2-fstab < 0 )); then read -ra short_devs<<<"${ssds[@]}" else read -ra short_devs<<<"${hdds[@]}" fi +pvn=1 + +# rootn=1 +# root2n=2 +# swapn=3 +# bootn=4 +# boot2n=5 + +efin=2 +# ext partition so grub can write persistent variables, +# so it can do a one time boot. grub can't write to +# btrfs or any cow fs because it's more +# more complicated to do and they don't want to. +grub_extn=3 +# bios boot partition, +# https://wiki.archlinux.org/index.php/GRUB +bios_grubn=4 +# for an even raid (raid 1), when one disk is bigger, this partition goes on the big disk +even_bign=5 +lastn=$even_bign # check if the partitions exist have the right filesystems #blkid="$(blkid -s TYPE)" for dev in ${short_devs[@]}; do @@ -338,57 +495,86 @@ if $partition && ifclass PARTITION_PROMPT; then fi devs=() +vgs=() +root_devs=() +swap_devs=() shopt -s extglob +partsuffix=-part for short_dev in ${short_devs[@]}; do - devs+=("$(devbyid $short_dev)") + dev="$(devbyid $short_dev)" + if [[ $dev != */by-id/* ]]; then + # no by-id link, assume we are in a vm and this is true for all devs. + partsuffix= + fi + # for vms, cant name a vg the same as the short device name, they + # conflict: /dev/$vg is already taken + + dname=${dev##*/} + vg=vg$dname + vgs+=("$vg") + devs+=("$dev") + if fsf; then + root_devs+=(/dev/$vg/root) + swap_devs+=(/dev/$vg/swap) + else + root_devs+=(/dev/mapper/crypt-$vg-root) + swap_devs+=(/dev/mapper/crypt-$vg-swap) + fi done +first_root_dev=${root_devs[0]} if [[ ! ${devs[0]} ]]; then echo "$0: error: failed to detect devs" >&2 exit 1 fi + + +pvsuf=$partsuffix$pvn +efisuf=$partsuffix$efin +grub_extsuf=$partsuffix$grub_extn +bios_grubsuf=$partsuffix$bios_grubn +even_bigsuf=$partsuffix$even_bign + + boot_space=0 first=true boot_devs=() boot2_devs=() for dev in ${devs[@]}; do - if ifclass frodo; then - # I ran into a machine where the bios doesn't know about some disks, - # so 1st stage of grub also doesn't know about them. - # Also, grub does not support mounting degraded btrfs as far as - # I can tell with some googling. - # From within an arch install env, I could detect them by noting - # their partitions were mixed with the next disk in /dev/disk/by-path, - # and I have mixed model disks, and I could see the 8 models which showed - # up in the bios, and thus see which 2 models were missing. - # hdparm -I /dev/sdh will give model info in linux. - # However, in fai on jessie, /dev/disk/by-path dir doesn't exist, - # and I don't see another way, so I'm hardcoding them. - # We still put grub on them and partition them the same, for uniformity - # and in case they get moved to a system that can recognize them, - # we just exclude them from the boot filesystem. - cd /dev/disk/by-id/ - bad_disk=false - for id in ata-TOSHIBA_MD04ACA500_8539K4TQFS9A \ - ata-TOSHIBA_MD04ACA500_Y5IFK6IJFS9A; do - if [[ $(readlink -f $id) == "$(readlink -f $dev)" ]]; then - bad_disk=true - break - fi - done - if ! $bad_disk; then - boot_devs+=("$(bootdev)") - boot2_devs+=("$(boot2dev)") + vg=vg${dev##*/} + # I ran into a machine (frodo) where the bios doesn't know about some disks, + # so 1st stage of grub also doesn't know about them. + # Also, grub does not support mounting degraded btrfs as far as + # I can tell with some googling. + # From within an arch install env, I could detect them by noting + # their partitions were mixed with the next disk in /dev/disk/by-path, + # and I have mixed model disks, and I could see the 8 models which showed + # up in the bios, and thus see which 2 models were missing. + # hdparm -I /dev/sdh will give model info in linux. + # However, in fai on jessie, /dev/disk/by-path dir doesn't exist, + # and I don't see another way, so I'm hardcoding them. + # We still put grub on them and partition them the same, for uniformity + # and in case they get moved to a system that can recognize them, + # we just exclude them from the boot filesystem. + cd /dev/disk/by-id/ + bad_disk=false + for id in ata-TOSHIBA_MD04ACA500_8539K4TQFS9A \ + ata-TOSHIBA_MD04ACA500_Y5IFK6IJFS9A; do + if [[ $(readlink -f $id) == "$(readlink -f $dev)" ]]; then + bad_disk=true + break fi - else - boot_space=$(( boot_space + $(parted -m $dev unit MiB print | \ - sed -nr "s#^/dev/[^:]+:([0-9]+).*#\1#p") - 1)) - boot_devs+=("$(bootdev)") - boot2_devs+=("$(boot2dev)") + done + if $bad_disk; then + continue fi - if $first && (( ${#boot_devs[@]} >= 1 )) ; then - first_efi=$(efidev) - first_grub_extdev=$(grub_extdev) + boot_devs+=(/dev/$vg/boot) + boot2_devs+=(/dev/$vg/boot2) + boot_space=$(( boot_space + $(parted -m $dev unit MiB print | \ + sed -nr "s#^/dev/[^:]+:([0-9]+).*#\1#p") - 1)) + if $first; then + first_efi=$dev$efisuf + first_grub_extdev=$dev$grub_extsuf first=false fi done @@ -397,13 +583,19 @@ first_boot_dev=${boot_devs[0]} even_raid=false if ifclass RAID0 || (( ${#boot_devs[@]} == 1 )); then raid_level=0 -elif ifclass RAID1 || (( ${#boot_devs[@]} <= 3 )); then + raid_duplication=1 +elif ifclass RAID1 || (( ${#boot_devs[@]} == 2 )); then if (( ${#boot_devs[@]} == 2 )); then even_raid=true fi raid_level=1 + raid_duplication=2 +elif ifclass RAID1c3 || (( ${#boot_devs[@]} == 3 )); then + raid_level=1c3 + raid_duplication=3 else raid_level=10 + raid_duplication=2 fi @@ -411,14 +603,17 @@ fi ### Begin calculate boot partition space # due to raid duplication case $raid_level in - 1*) boot_space=$(( boot_space / 2 )) ;; + 1|10) boot_space=$(( boot_space / 2 )) ;; + 1c3) boot_space=$(( boot_space / 3 )) ;; esac -if (( boot_space > 60000 )); then +if fsf; then + boot_mib=4000 +elif (( boot_space > 900000 )); then # this is larger than needed for several /boot subvols, # becuase I keep a minimal debian install on it for # recovery needs and for doing pxe-kexec. boot_mib=10000 - root2_mib=1000000 + root2_mib=500000 boot2_mib=5000 elif (( boot_space > 30000 )); then boot_mib=$(( 5000 + (boot_space - 30000) / 2 )) @@ -433,22 +628,16 @@ else root2_mib=100 boot2_mib=100 fi -case $raid_level in - 1*) - boot_mib=$(( boot_mib * 2 )) - boot2_mib=$(( boot2_mib * 2 )) - root2_mib=$(( root2_mib * 2 )) - ;; -esac -### end calculate boot partition space +boot_part_mib=$(( boot_mib * raid_duplication / ${#boot_devs[@]} )) -bpart() { # btrfs a partition - case $raid_level in - 0) mkfs.btrfs -f $@ ;; - 1) mkfs.btrfs -f -m raid1 -d raid1 $@ ;; - 10) mkfs.btrfs -f -m raid10 -d raid10 $@ ;; - esac -} +if zilap; then + boot2_part_mib=0 + root2_part_mib=0 +else + boot2_part_mib=$(( boot2_mib * raid_duplication / ${#boot_devs[@]} )) + root2_part_mib=$(( root2_mib * raid_duplication / ${#root_devs[@]} )) +fi +### end calculate boot partition space if [[ ! $DISTRO ]]; then @@ -497,164 +686,15 @@ else fi -first_root_crypt=$(root-cryptdev ${devs[0]}) - # 1.5 x based on https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Installation_Guide/sect-disk-partitioning-setup-x86.html#sect-custom-partitioning-x86 swap_mib=$(( $(grep ^MemTotal: /proc/meminfo | \ awk '{print $2}') * 3/(${#devs[@]} * 2 ) / 1024 )) -root_devs=() -for dev in ${devs[@]}; do - root_devs+=("$(rootdev)") -done shopt -s nullglob ##### end variable setup -mktab() { - mkdir -p /tmp/fai - dev=${boot_devs[0]} - fstabstd="x-systemd.device-timeout=30s,x-systemd.mount-timeout=30s" - - if [[ $DISTRO == debianbullseye_bootstrap ]]; then - cat > /tmp/fai/fstab </tmp/fai/disk_var.sh < /tmp/fai/fstab <>/tmp/fai/crypttab <> /tmp/fai/fstab </tmp/fai/disk_var.sh <>/tmp/fai/crypttab <> /tmp/fai/fstab <&2 - exit 1 - fi - fi - - luks_file=$luks_dir/host-$HOSTNAME - if [[ ! -e $luks_file ]]; then - # shellcheck disable=SC2206 # globbing is intended - hostkeys=($luks_dir/host-*) - # if there is only one key, we might be deploying somewhere - # where dhcp doesnt give us a proper hostname, so use that. - if [[ ${#hostkeys[@]} == 1 && -e ${hostkeys[0]} ]]; then - luks_file=${hostkeys[0]} - else - echo "$0: error: no key for hostname at $luks_file" >&2 - exit 1 - fi - fi - - # # note, corresponding changes in /b/ds/keyscript-{on,off} - if ifclass demohost; then - lukspw=x - elif [[ -e $luks_dir/$HOSTNAME ]]; then - lukspw=$(cat $luks_dir/$HOSTNAME) - else - lukspw=$(cat $luks_dir/iank) - fi - - if $mkroot2; then - luks_file=$luks_dir/host-amy - lukspw=$(cat $luks_dir/amy) - fi -} - - -#### root2 non-fai run -doroot2() { - - # We write to these files instead of just /etc/fstab, /etc/crypttab, - # because these are filesystems created after our current root, and so - # this allows us to update other root filesystems too. - rm -f /mnt/root/root2-{fs,crypt}tab - if $partition; then - echo $0: error: found partition=true but have mkroot2 arg - exit 1 - fi - for dev in ${devs[@]}; do - if $mkroot2; then - luks-setup $(root2dev) - fi - cat >>/mnt/root/root2-crypttab <>/mnt/root/root2-fstab < 0 )) || exit 1 - done + count_down=10 + # wipefs has failed, manual run works, google suggests timing issue + while ! wipefs -a $dev; do + sleep 2 + count_down=$((count_down - 1)) + (( count_down > 0 )) || exit 1 done done fi @@ -710,6 +758,7 @@ if $partition; then fi for dev in ${devs[@]}; do + vg=vg${dev##*/} if [[ $SPECIAL_DISK ]]; then dev=$(devbyid $SPECIAL_DISK) fi @@ -724,45 +773,47 @@ if $partition; then disk_mib=$(dev-mib) fi - boot_part_mib=$(( boot_mib / ${#boot_devs[@]} )) - boot2_part_mib=$(( boot2_mib / ${#boot_devs[@]} )) - root2_part_mib=$(( root2_mib / ${#root_devs[@]} )) - root_end=$(( disk_mib - root2_part_mib - swap_mib - boot_part_mib - boot2_part_mib )) - root2_end=$(( root_end + root2_part_mib )) - swap_end=$(( root2_end + swap_mib )) - boot_end=$(( swap_end + boot_part_mib )) parted -s $dev mklabel gpt # MiB because parted complains about alignment otherwise. pcmd="parted -a optimal -s -- $dev" - # root partition, the main big one - $pcmd mkpart primary ext3 524MiB ${root_end}MiB - # without naming, systemd gives us misc errors like: - # dev-disk-by\x2dpartlabel-primary.device: Dev dev-disk-by\x2dpartlabel-primary.device appeared twice - $pcmd name $rootn root - # root2 partition - $pcmd mkpart primary ext3 ${root_end}MiB ${root2_end}MiB - $pcmd name $root2n root2 - # normally a swap is type "linux-swap", but this is encrypted swap. using that - # label will confuse systemd. - # swap partition - $pcmd mkpart primary "" ${root2_end}MiB ${swap_end}MiB - $pcmd name $swapn swap - # boot partition - $pcmd mkpart primary "" ${swap_end}MiB ${boot_end}MiB - $pcmd name $bootn boot - # boot2 partition - $pcmd mkpart primary "" ${boot_end}MiB ${disk_mib}MiB - $pcmd name $boot2n boot2 - # uefi partition. efi sucks, half a gig, rediculous. + # main lvm partition + $pcmd mkpart primary ext3 524MiB ${disk_mib}MiB + $pcmd name $pvn pv + + pvcreate -y $dev$pvsuf + vgcreate -y $vg $dev$pvsuf + + if fsf; then + root_mib=40000 + else + # 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 )) + fi + + # -L unit default mebibyte + lvcreate -y -L $root_mib $vg -n root + lvcreate -y -L $swap_mib $vg -n swap + # unencrypted swap needs mkswap + if fsf; then + mkswap /dev/$vg/swap + fi + lvcreate -y -L $boot_part_mib $vg -n boot + + if zilap; then + # todo: now that we are using lvm, this doesnt need to be done until mkroot2 + lvcreate -y -L $root2_part_mib $vg -n root2 + lvcreate -y -L $boot2_part_mib $vg -n boot2 + fi + + # uefi partition, for normal bios systems, its just in case. $pcmd mkpart primary "fat32" 12MiB 524MiB $pcmd name $efin efi - $pcmd set $efin esp on # note, this is shown here: https://support.system76.com/articles/bootloader/ # but not mentioned https://wiki.archlinux.org/index.php/EFI_system_partition - # probably not needed - $pcmd set $bootn boot on - $pcmd set $boot2n boot on + # might not be needed + $pcmd set $efin esp on + # i only need a few k, but googling min size, # I found someone saying that gparted required # required at least 8 because of their hard drive cylinder size. @@ -793,17 +844,17 @@ if $partition; then # but then couldn't be found upon reboot. In that case we didn't # wait at all. So I've added a 3 second minimum wait. secs=0 - while [[ ! -e $(bios_grubdev) ]] && (( secs < 10 )); do + while [[ ! -e $dev$bios_grubsuf ]] && (( secs < 10 )); do sleep 1 secs=$((secs +1)) done sleep 3 - mkfs.fat -F32 $(efidev) + mkfs.fat -F32 $dev$efisuf - if $even_big_part && [[ $dev == "$even_big_dev" ]]; then - luks-setup $(even_bigdev) - mkfs.btrfs -f $(crypt-dev $(even_bigdev)) + if ! fsf && $even_big_part && [[ $dev == "$even_big_dev" ]]; then + luks-setup $even_big_dev ${even_big_dev##*/} + mkfs.btrfs -f /dev/mapper/${even_big_dev##*/} fi # Holds just a single file, rarely written, so @@ -814,8 +865,13 @@ if $partition; then # to grubenv after booting, but that relies on the boot always succeeding. # This is just a bit more robust, and it could work for booting # into ipxe which can't persist data, if we ever got that working. - mkfs.ext2 $(grub_extdev) - luks-setup $(rootdev) + mkfs.ext2 $dev$grub_extsuf + + # for fsf, no encryption of root because root will not contain any + # sensitive data. + if ! fsf; then + luks-setup /dev/$vg/root crypt-$vg-root + fi if [[ $SPECIAL_DISK ]]; then exit 0 @@ -823,26 +879,29 @@ if $partition; then done ls -la /dev/btrfs-control # this was probably for debugging... sleep 1 - bpart $(for dev in ${devs[@]}; do root-cryptdev; done) + + bpart ${root_devs[@]} bpart ${boot_devs[@]} -else - for dev in ${devs[@]}; do - if [[ -e /dev/mapper/$(root-cryptname) ]]; then - continue - fi - if $rerootfs; then - luks-setup $(rootdev) - sleep 1 - bpart $(for dev in ${devs[@]}; do root-cryptdev; done) - else - cryptsetup luksOpen $(rootdev) $(root-cryptname) \ - --key-file $luks_file - fi - done + +else ## above: if $partition ## + + if ! fsf; then + for vg in ${vgs[@]}; do + if [[ -e /dev/mapper/crypt-$vg-root ]]; then + continue + fi + if $rerootfs; then + luks-setup /dev/$vg/root crypt-$vg-root + else + cryptsetup luksOpen /dev/$vg/root $vg-root \ + --key-file $luks_file + fi + done + fi if $rerootfs; then sleep 1 - bpart $(for dev in ${devs[@]}; do root-cryptdev; done) + bpart ${root_devs[@]} fi sleep 1 fi @@ -850,7 +909,7 @@ fi if $wipe && [[ $DISTRO != debianbullseye_bootstrap ]]; then # bootstrap distro doesn't use separate encrypted root. - mount -o subvolid=0 $first_root_crypt /mnt + mount -o subvolid=0 ${root_devs[0]} /mnt # systemd creates subvolumes we want to delete. mapfile -t s < <(btrfs subvolume list --sort=-path /mnt | sed -rn "s#^.*path\s*(root_$DISTRO/\S+)\s*\$#\1#p") @@ -886,6 +945,7 @@ btrfs subvolume set-default 0 /mnt # already default, just ensuring it. # for libreboot systems. grub2 only reads from subvolid=0 mkdir -p /mnt/grub2 +# todo: this probably needs updating for our lvm transition cp $FAI/distro-install-common/libreboot_grub.cfg /mnt/grub2 if $wipe && [[ -e /mnt/$boot_vol ]]; then diff --git a/fai/config/package_config/ARAMO_EXTRA.gpg b/fai/config/package_config/ARAMO_EXTRA.gpg new file mode 120000 index 0000000..553a478 --- /dev/null +++ b/fai/config/package_config/ARAMO_EXTRA.gpg @@ -0,0 +1 @@ +UBUNTU.gpg \ No newline at end of file diff --git a/fai/config/package_config/NABIA_EXTRA.gpg b/fai/config/package_config/NABIA_EXTRA.gpg new file mode 120000 index 0000000..553a478 --- /dev/null +++ b/fai/config/package_config/NABIA_EXTRA.gpg @@ -0,0 +1 @@ +UBUNTU.gpg \ No newline at end of file diff --git a/fai/config/package_config/STANDARD b/fai/config/package_config/STANDARD index 413254f..4404513 100644 --- a/fai/config/package_config/STANDARD +++ b/fai/config/package_config/STANDARD @@ -34,6 +34,7 @@ xz-utils # ian standard packages # lsof is used in my btrfs util scritps. # netcat is used for proxy. +lvm2 keyutils cryptsetup btrfs-progs @@ -64,8 +65,6 @@ publicsuffix iso-codes # new package buster/nabia+ cryptsetup-initramfs -# https://wiki.debian.org/UsrMerge -usrmerge # for btrbk zstd diff --git a/fai/config/package_config/UBUNTU.asc b/fai/config/package_config/UBUNTU.gpg similarity index 100% rename from fai/config/package_config/UBUNTU.asc rename to fai/config/package_config/UBUNTU.gpg diff --git a/fai/config/scripts/D16/12-d16 b/fai/config/scripts/D16/12-d16 new file mode 100755 index 0000000..df3cd5c --- /dev/null +++ b/fai/config/scripts/D16/12-d16 @@ -0,0 +1,24 @@ +#!/bin/bash -x + +set -eE -o pipefail +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR + +if [[ $EUID != 0 ]]; then + echo "$0: error: expected to be root." + exit 1 +fi + +cat >$FAI_ROOT/etc/grub.d/40_custom <&2' ERR + +if [[ $EUID != 0 ]]; then + echo "$0: error: expected to be root." + exit 1 +fi + +fcopy -riBM /root + + +#### misc configurations +chroot $FAI_ROOT bash <<'EOFOUTER' +if getent group systemd-journal >/dev/null; then + # makes the journal be saved to disk. + mkdir -p /var/log/journal + chmod 755 /var/log/journal +fi +debconf-set-selections </dev/null; then + update-grub2 +else + update-grub +fi + +EOF + + +# I prefer to stick with ifup/down or networkmanager: networkd is not in its +# own package, so cant use in other init systems. b. it works fine. +chroot $FAI_ROOT bash </q/root/shadow/standard - # On arch, best seems to be copy your shadow file to a temp location, - # then passwd, get out the new pass, then copy the shadow file back. - - user=$1 - pwfile=$2 - if [[ $pwfile && -e $pwfile ]]; then - printf "$user:" | cat - "$pwfile" | $ROOTCMD chpasswd -e - else - echo "$0: warning: no pw set for $user" >&2 - fi -} - -chpw root $FAI/distro-install-common/shadow/community0p - - -#### misc configurations -chroot $FAI_ROOT bash <<'EOFOUTER' -if getent group systemd-journal >/dev/null; then - # makes the journal be saved to disk. - mkdir -p /var/log/journal - chmod 755 /var/log/journal -fi -debconf-set-selections <$FAI_ROOT/etc/grub.d/40_custom </dev/null; then - update-grub2 -else - update-grub -fi - -EOF - - - cat > $target/etc/network/interfaces <<-EOF +# todo, need to set static ip here +if ifclass demohost; then + cat > $target/etc/network/interfaces <$target/etc/initramfs-tools/conf.d/mine < $target/etc/network/interfaces <<-EOF -# generated by FAI -auto lo eth0 +else + ip=$(getent ahosts $HOSTNAME |grep ^209.*RAW| sed 's/ .*//') + ip6=$(getent ahosts $HOSTNAME |grep ^2001.*RAW| sed 's/ .*//') + gateway=209.51.188.1 + gateway6=2001:470:142::1 + cat > $target/etc/network/interfaces < /proc/sys/net/ipv6/conf/eth0/accept_dad + address $ip6 + netmask 48 + gateway $gateway6 EOF - fi fi -# I prefer to stick with ifup/down for now. a. networkd is not in its -# own package, so cant use in other init systems. b. it works fine. -chroot $FAI_ROOT bash </dev/null; then - usermod -aG $g iank - fi -done - -if getent group systemd-journal >/dev/null; then - usermod -aG systemd-journal iank -fi -EOFOUTER +##### end network setup ##### +# rm first to remove any symlink rm -f $target/etc/resolv.conf -ln -s ../run/systemd/resolve/stub-resolv.conf $target/etc/resolv.conf -# needed for bitfolk image -if [[ -e /a/bin/fai/fai-wrapper ]]; then - systemctl enable systemd-resolved - systemctl start systemd-resolved -fi - - -# reading through the groups that iank is in but user2 isn't, -for g in plugdev audio video cdrom; do - $ROOTCMD usermod -a -G $g user2 -done +if ifclass demohost; then + cat >$target/etc/resolv.conf <<'EOF' +nameserver 8.8.8.8 +EOF +else + cat >$target/etc/resolv.conf <<'EOF' +domain fsf.org +search fsf.org +nameserver 209.51.188.16 +nameserver 209.51.188.27 +EOF +fi diff --git a/fai/config/scripts/IANK/11-iank b/fai/config/scripts/IANK/11-iank index 47b97ad..1ffb74d 100755 --- a/fai/config/scripts/IANK/11-iank +++ b/fai/config/scripts/IANK/11-iank @@ -26,7 +26,6 @@ fi # -B = no backup files fcopy -riBM /boot # this is also done by FAIBASE/10-misc by default (without B) -fcopy -riBM /root fcopy -riBM /usr/local/bin # this gets done by fai, but just happens too often that @@ -55,9 +54,6 @@ tmpfile1=$(mktemp) chroot $FAI_ROOT /usr/bin/apt-cache policy >$tmpfile1 ||: fcopy -riBM /etc/apt -# get ubuntu key, for running from fai wrapper. -apt-key add $FAI/package_config/UBUNTU.asc - tmpfile2=$(mktemp) chroot $FAI_ROOT /usr/bin/apt-cache policy >$tmpfile2 if ! diff -q $tmpfile1 $tmpfile2; then @@ -84,29 +80,9 @@ fi #### misc configurations -chroot $FAI_ROOT bash <<'EOFOUTER' -if getent group systemd-journal >/dev/null; then - # makes the journal be saved to disk. - mkdir -p /var/log/journal - chmod 755 /var/log/journal -fi -debconf-set-selections <$FAI_ROOT/etc/grub.d/40_custom </dev/null; then - update-grub2 -else - update-grub -fi - -EOF fi ##### end != dirinstall && != NOCRYPT @@ -292,7 +222,6 @@ EOF if [[ $HOSTNAME == li ]]; then - cat > $target/etc/network/interfaces <<-EOF # generated by FAI auto lo eth0 @@ -315,12 +244,6 @@ EOF fi fi -# I prefer to stick with ifup/down for now. a. networkd is not in its -# own package, so cant use in other init systems. b. it works fine. -chroot $FAI_ROOT bash <&2' ERR +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" + usage() { - cat </dev/null; then - sed -ri --follow-symlinks '\%^/srv/fai/%d' /etc/exports - exportfs -ra + + +faiserver_addr=$(host faiserver | sed -rn 's/^\S+ has address //p;T;q' ||:) +if ip a | grep "^ *inet.\? $faiserver_addr" &>/dev/null; then + echo "$0: disabling fai nfs exports or apache site" + ./faiserver-disable-local else - rm -f /etc/apache2/sites-enabled/faiserver.conf - systemctl reload apache2 + echo "$0: sshing to $(chost faiserver) to disable fai nfs exports or apache site" + ssh root@$(chost faiserver) bash &2' ERR + +[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" + +usage() { + cat </dev/null; then + sed -ri --follow-symlinks '\%^/srv/fai/%d' /etc/exports + exportfs -ra +else + rm -f /etc/apache2/sites-enabled/faiserver.conf + systemctl reload apache2 +fi diff --git a/faiserver-setup b/faiserver-setup index 0501bac..4003a24 100755 --- a/faiserver-setup +++ b/faiserver-setup @@ -19,10 +19,9 @@ x="$(readlink -f "$BASH_SOURCE")"; source "${x%/*}/bash-trace" [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" -LC_USEBASHRC=t; . ~/.bashrc usage() { - cat < limittime )); then + if (( cachetime > limittime )); then update=true fi fi @@ -190,9 +194,14 @@ EOF # fi -$sed -f - /etc/fai/nfsroot.conf <>/srv/fai/nfsroot/root/.ssh/known_hosts @@ -309,6 +318,7 @@ done # We could also just dump things in /srv/tftp, but fai # has some defaults, which I don't even use, which expect # the other directory, so it's kind of a tossup, whatever. +# This means fai's example isc-dhcp-server filename directory should remove the fai/ prefix. sed -ri 's,^ *(TFTP_DIRECTORY=).*,\1"/srv/tftp/fai",' /etc/default/tftpd-hpa systemctl restart tftpd-hpa diff --git a/myfai-chboot-local b/myfai-chboot-local index 4fc6f06..8ab5a92 100755 --- a/myfai-chboot-local +++ b/myfai-chboot-local @@ -7,6 +7,7 @@ set -eE -o pipefail trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR kgped16=false +bond=false fai_action=install fai_reboot_arg=,reboot while [[ $1 == -* ]]; do @@ -26,7 +27,11 @@ while [[ $1 == -* ]]; do shift ;; -k) - kgped16=true; + kgped16=true + shift + ;; + -b) + bond=true shift ;; esac @@ -113,6 +118,8 @@ default_k_args=$(fai-chboot -L '^default$' | \ # 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 # and not wait for more conditions where its needed. +#k_args=(FAI_ACTION=$fai_action libata.force=noncq ifname:bootnet0:08:60:6e:10:f0:fe ifname:bootnet1:08:60:6e:10:f0:98 bond=bond0:bootnet0,bootnet1:mode=balance-rr) +#k_args=(FAI_ACTION=$fai_action libata.force=noncq ifname:bootnet0:08:60:6e:10:f0:fe biosdevname=0 bootdev=bootnet0) k_args=(FAI_ACTION=$fai_action libata.force=noncq) if $kgped16; then k_args+=(console=tty0 console=ttyS0,115200) @@ -122,6 +129,14 @@ for arg in $default_k_args; do case $arg in # default root arg is /srv/fai/nfsroot root=*) k_args+=(root=$root_arg) ;; + # note: this works to only dhcp on one interface: ip=eth0:dhcp + ip=*) + if $bond; then + k_args+=("bond=bond0:eth0,eth1:mode=balance-rr ip=bond0:dhcp") + else + k_args+=($arg) + fi + ;; *) k_args+=($arg) ;; esac done diff --git a/mymk-basefile b/mymk-basefile index 7e16503..3aef5b5 100755 --- a/mymk-basefile +++ b/mymk-basefile @@ -20,6 +20,8 @@ Args I've used before: -z BUSTER64 -z STRETCH64 -z XENIAL64 + +-z ARAMO64 -z NABIA64 -z ETIONA64 -z FLIDAS64 diff --git a/pxe-server b/pxe-server index 692ffbb..5915f96 100755 --- a/pxe-server +++ b/pxe-server @@ -18,7 +18,12 @@ [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" -x="$(readlink -f "$BASH_SOURCE")"; source "${x%/*}/bash-trace" +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" usage() { @@ -30,7 +35,10 @@ not general purpose, it has code specific to dhcp servers I run. Without TYPE, disable server and fai server. In that case, HOST is only needed for fsf office network. -HOST A hostname known to the dhcp server, or default for all. +HOST Only do dhcp pxe for HOST. The hostname must be known to the dhcp + server to target its mac. Use "default" for all hosts. + Required in fsf office environment. + TYPE One of arch, parabola, plain, fai. -a Don't setup pxe, just Wait for 2 dhcp acks, then disable the pxe @@ -39,7 +47,7 @@ TYPE One of arch, parabola, plain, fai. after the 2nd. I can't remember exactly why this caused a problem, but I'm hoping the sleep will take care of it. -d Don't alter dhcp config. Only make sense for fai type, and on network - other than home or fsf. + other than home or fsf, or when using fai-cd. -k Pass -k to myfai-chboot. -r Don't redeploy fai config. For example, if there is a different host that is mid-install. @@ -90,10 +98,10 @@ dhcp=true redep=true acks=2 wait=false -fsf=false +fsf_office=false case $HOSTNAME in - x3|kw) fsf=true ;; + x3|kw) fsf_office=true ;; esac chboot_args=() @@ -137,10 +145,14 @@ esac if $wait && ! $dhcp; then - echo "$0: error -w conflicts with -d, choose one or other" + echo "$0: error -w conflicts with -d, choose one or other" >&2 exit 1 fi +if $fsf_office && [[ ! $host ]]; then + echo "$0: at fsf_office, provide HOST arg" >&2 + exit 1 + fi if [[ $host && $host != default ]]; then host_tag="tag:$host," @@ -178,14 +190,14 @@ EOF } ack-wait() { - if $fsf; then + if $fsf_office; then wait_cmd="ssh tarantula.office.fsf.org tail -n0 -f /var/log/syslog" else wait_cmd="ssh cmc logread -f" fi wait_count=$1 if [[ $host ]]; then - if $fsf; then + if $fsf_office; then host_regex=" $(getent hosts kw | awk '{print $1}' | sed 's/\./\\./g')" else host_regex=" $host" @@ -204,7 +216,7 @@ ack-wait() { set-pxe() { $dhcp || return 0 - if $fsf; then + if $fsf_office; then if [[ ! $cmd ]]; then e "removing pxe for $host on tarantula" ssh tarantula.office.fsf.org bash -e </dev/null ||: + m myfai-chboot &>/dev/null ||: fi fi diff --git a/wrt-setup-local b/wrt-setup-local index a1f1ee3..7efa19a 100755 --- a/wrt-setup-local +++ b/wrt-setup-local @@ -750,11 +750,11 @@ config rule config redirect - option name httpkd + option name http option src wan option src_dport 80 option dest lan - option dest_ip $l.2 + option dest_ip $l.7 option proto tcp config rule option src wan @@ -763,11 +763,11 @@ config rule option proto tcp config redirect - option name httpskd + option name https option src wan option src_dport 443 option dest lan - option dest_ip $l.2 + option dest_ip $l.7 option proto tcp config rule option src wan @@ -992,6 +992,8 @@ local-data-ptr: "10.173.8.2 nn.b8.nz" forward-zone: name: "." +# forward-addr: 8.8.8.8 +# forward-addr: 8.8.8.8 # https://developers.cloudflare.com/1.1.1.1/1.1.1.1-for-families/setup-instructions/dns-over-https forward-addr: 1.1.1.3@853#family.cloudflare-dns.com forward-addr: 1.0.0.3@853#family.cloudflare-dns.com @@ -1118,6 +1120,8 @@ dhcp-host=80:fa:5b:1c:6e:cf,set:amy,$l.8,amy # reformatted. The mac is from doing a virt-install, cancelling it, # and copying the generated mac, so it should be randomish. dhcp-host=52:54:00:9c:ef:ad,set:demohost,$l.12,demohost +## for using different dhcp server +#dhcp-host=52:54:00:9c:ef:ad,ignore dhcp-host=62:03:cb:a8:3e:a3,set:trp,$1.13,trp # 14 = wrt3 dhcp-host=00:1f:16:14:01:d8,set:x3,$l.18,x3 @@ -1137,9 +1141,8 @@ dhcp-host=e4:5f:01:07:50:40,set:pi4w,$l.39,pi4w #dhcp-host=,set:pi4,$l.33,pi4 - # faiserver vm -dhcp-host=52:54:00:56:09:f9,set:faiserver,$l.15,faiserver +#dhcp-host=52:54:00:56:09:f9,set:faiserver,$l.15,faiserver # This is the ip it picks by default if dhcp fails, # so might as well use it.