From 4261ad7e021ec77e7198cf42c3576dad07f12a64 Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Sun, 27 Mar 2016 23:39:07 -0700 Subject: [PATCH] use disk/by-id if possibe, other small fixes --- arch-init | 3 + arch-init-remote | 3 +- chboot | 4 + fai-redep | 15 ++- fai-revm | 28 ++++- fai/config/class/50-host-classes | 4 +- fai/config/hooks/instsoft.DEFAULT | 9 +- fai/config/hooks/partition.DEFAULT | 156 +++++++++++++++++-------- fai/config/scripts/DEBIAN/10-rootpw | 2 +- fai/config/scripts/DEBIAN/30-interface | 31 ++--- fai/config/scripts/GRUB_PC/11-ian | 8 +- faiserver-revm | 2 +- fai-setup => faiserver-setup | 29 +++-- faiserver-uninstall | 9 ++ wrt-setup | 4 +- 15 files changed, 218 insertions(+), 89 deletions(-) rename fai-setup => faiserver-setup (72%) create mode 100755 faiserver-uninstall diff --git a/arch-init b/arch-init index aae184f..c4f573f 100755 --- a/arch-init +++ b/arch-init @@ -33,6 +33,9 @@ case $hostname in exit 1 esac +if [[ -e /root/devbyid ]]; then + mv /root/devbyid /usr/bin +fi rm -f /etc/pacman.d/mirrorlist # https://wiki.archlinux.org/index.php/Mirrors#Sorting_mirrors diff --git a/arch-init-remote b/arch-init-remote index c7f6110..5c2717f 100755 --- a/arch-init-remote +++ b/arch-init-remote @@ -19,7 +19,8 @@ fai_files=( ) sudo scp -r /a/bin/fai/arch-init{,-chroot} \ ${fai_files[@]/#//a/bin/fai/fai/config/} \ - /q/root/luks /p/shadow root@$host: + /a/bin/devbyid \ + /q/root/luks /q/root/shadow root@$host: # creating shadow file string: # on debian, you can use mkpasswd -m sha-512 to generate a pass. # arch doesn't have this program. instead, you can do passwd, diff --git a/chboot b/chboot index 40f5093..9cb23d5 100755 --- a/chboot +++ b/chboot @@ -53,3 +53,7 @@ e grub-bios-setup -d $mount_point/grub/i386-pc -s -m $mount_point/grub/device.ma e umount $mount_point e rmdir $mount_point + +if $reboot; then + reboot now +fi diff --git a/fai-redep b/fai-redep index 0c23459..4ca3ea5 100755 --- a/fai-redep +++ b/fai-redep @@ -19,15 +19,22 @@ scp -r fai/config root@faiserver:/srv/fai # echo "yoursecrectpassword" | mkpasswd -m sha-512 -s # 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. -ssh root@faiserver tee -a /srv/fai/config/class/DEFAULT.var < 0 )); then - devs=( ${ssds[@]} ) + short_devs=( ${ssds[@]} ) else - devs=( ${hds[@]} ) + short_devs=( ${hds[@]} ) +fi + +# check if the partitions exist have the right filesystems +#blkid="$(blkid -s TYPE)" +for dev in ${short_devs[@]}; do + ! $partition || break + y=$(readlink -f $dev) + x=($y[0-9]) + [[ ${#x[@]} == "${lastn}" ]] || partition=true + for (( i=1; i <= lastn; i++ )); do + [[ -e ${dev}$i ]] || partition=true + done + # On one system, blkid is missing some partitions. + # maybe we need a flag, like FUZZY_BLKID or something, so we + # can check that at least some exist. + # for x in "`rootdev`: TYPE=\"crypto_LUKS\"" "`bootdev`: TYPE=\"btrfs\""; do + # echo "$blkid" | grep -Fx "$x" &>/dev/null || partition=true + # done +done + +if $partition && ifclass PARTITION_PROMPT; then + echo "Press any key except ctrl-c to continue and partition these drives:" + echo " ${short_devs[@]}" + read fi +devs=() +shopt -s extglob +for short_dev in ${short_devs[@]}; do + devs+=($(devbyid $short_dev)) +done + + + boot_devs=() for dev in ${devs[@]}; do if ifclass frodo; then @@ -59,7 +124,7 @@ for dev in ${devs[@]}; do # 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, that dir doesn't exist, + # 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, @@ -68,20 +133,20 @@ for dev in ${devs[@]}; do bad_disk=false for id in ata-TOSHIBA_MD04ACA500_8539K4TQFS9A \ ata-TOSHIBA_MD04ACA500_Y5IFK6IJFS9A; do - if [[ $(readlink -f $id) == $dev ]]; then + if [[ $(readlink -f $id) == "$(readlink -f $dev)" ]]; then bad_disk=true break fi done - $bad_disk || boot_devs+=($dev$bootn) + $bad_disk || boot_devs+=(`bootdev`) else - boot_devs+=($dev$bootn) + boot_devs+=(`bootdev`) fi done if [[ ! $DISTRO ]]; then if ifclass STABLE; then - DISTRO=debianjessie + DISTRO=debianstable else DISTRO=debiantesting fi @@ -97,29 +162,13 @@ esac bpart() { # btrfs a partition - dev_n=$1 case ${#@} in [1-3]) mkfs.btrfs -f $@ ;; [4-9]*|[1-3]?*) mkfs.btrfs -f -m raid10 -d raid10 $@ ;; esac } -first_boot_dev=${devs[0]}$bootn - -crypt_devs=() -# somewhat crude detection of whether to partition -for dev in ${devs[@]}; do - crypt_devs+=( /dev/mapper/crypt_dev_${dev#/dev/} ) - x=($dev[0-9]) - [[ ${#x[@]} == ${lastn} ]] || partition=true - for (( i=1; i <= $lastn; i++ )); do - [[ -e ${dev}$i ]] || partition=true - done - for part in $dev$rootn $dev$bootn; do - # type tells us it's not totally blank - blkid | grep "^${part}:.*TYPE=" &>/dev/null || partition=true - done -done +first_boot_dev=$(bootdev ${devs[0]}) # keyfiles generated like: # head -c 2048 /dev/urandom | od | s dd of=/q/root/luks/host-demohost @@ -134,9 +183,9 @@ if ifclass demohost; then fi -crypt=${crypt_devs[0]}$rootn +first_root_crypt=$(root-cryptdev ${devs[0]}) -bios_grub_end=4 +bios_grubn=4 # 1.5 x based on https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Installation_Guide/sect-disk-partitioning-setup-x86.html#sect-custom-partitioning-x86 swap_mib=$(( $(grep ^MemTotal: /proc/meminfo | \ awk '{print $2}') * 3/(${#devs[@]} * 2 ) / 1024 )) @@ -159,8 +208,11 @@ if $partition; then # parted will round up the disk size. Do -1 so we can have # fully 1MiB unit partitions for easy resizing of the last partition. # Otherwise we would pass in -0 for the end argument for the last partition. + # + # parted print error output is expected. example: + # Error: /dev/vda: unrecognised disk label disk_mib=$(( $(parted -m $dev unit MiB print | \ - sed -nr "s#^$dev:([0-9]+).*#\1#p") - 1)) + sed -nr "s#^/dev/[^:]+:([0-9]+).*#\1#p") - 1)) root_end=$(( disk_mib - swap_mib - boot_mib / ${#boot_devs[@]} )) swap_end=$(( root_end + swap_mib)) @@ -176,15 +228,22 @@ if $partition; then $pcmd mkpart primary "" 1MiB 4MiB $pcmd set $bios_grubn bios_grub on $pcmd set $bootn boot on # generally not needed on modern systems - # the mkfs failed randomly on a vm, so I threw a sleep in here. - sleep .1 - - luks_dev=$dev$rootn - yes YES | cryptsetup luksFormat $luks_dev $luks_dir/host-$HOSTNAME \ + # the mkfs failed before on a vm, which prompted me to add + # sleep .1 + # then failed on a physical machine + # with: + # Device /dev/disk/by-id/foo doesn't exist or access denied, + # so here we wait. + secs=0 + while [[ ! -e `rootdev` ]] && (( secs < 10 )); do + sleep 1 + secs=$((secs +1)) + done + yes YES | cryptsetup luksFormat `rootdev` $luks_dir/host-$HOSTNAME \ -c aes-cbc-essiv:sha256 -s 256 || [[ $? == 141 ]] yes "$lukspw" | \ cryptsetup luksAddKey --key-file $luks_dir/host-$HOSTNAME \ - $luks_dev || [[ $? == 141 ]] + `rootdev` || [[ $? == 141 ]] # background: Keyfile and password are treated just # like 2 ways to input a passphrase, so we don't actually need to have # different contents of keyfile and passphrase, but it makes some @@ -195,20 +254,22 @@ if $partition; then # yes 'test' | cryptsetup luksRemoveKey /dev/... \ # /key/file || [[ $? == 141 ]] - cryptsetup luksOpen $luks_dev crypt_dev_${luks_dev##/dev/} \ + cryptsetup luksOpen `rootdev` `root-cryptname` \ --key-file $luks_dir/host-$HOSTNAME done - bpart ${crypt_devs[@]/%/$rootn} + ls -la /dev/btrfs-control + sleep 1 + bpart $(for dev in ${devs[@]}; do root-cryptdev; done) bpart ${boot_devs[@]} else for dev in ${devs[@]}; do - cryptsetup luksOpen $dev$rootn crypt_dev_${dev##/dev/}$rootn \ - --key-file $luks_dir/host-$HOSTNAME || [[ $? == 141 ]] + cryptsetup luksOpen `rootdev` `root-cryptname` \ + --key-file $luks_dir/host-$HOSTNAME done sleep 1 fi -mount -o subvolid=0 $crypt /mnt +mount -o subvolid=0 $first_root_crypt /mnt # systemd creates subvolumes we want to delete. s=($(btrfs subvolume list --sort=-path /mnt | sed -rn "s#^.*path\s*(root_$DISTRO/\S+)\s*\$#\1#p")) @@ -247,23 +308,22 @@ umount /mnt cat > /tmp/fai/fstab <>/tmp/fai/crypttab <> /tmp/fai/fstab </tmp/fai/disk_var.sh <$error?$?:$error))' ERR # save maximum error code # set root password -$ROOTCMD usermod -p $ROOTPW root +$ROOTCMD usermod -p "$ROOTPW" root exit $error diff --git a/fai/config/scripts/DEBIAN/30-interface b/fai/config/scripts/DEBIAN/30-interface index f688fb3..3388dcf 100755 --- a/fai/config/scripts/DEBIAN/30-interface +++ b/fai/config/scripts/DEBIAN/30-interface @@ -7,10 +7,10 @@ if ifclass DHCPC && [ $FAI_ACTION = "install" -o $FAI_ACTION = "dirinstall" ] then if ifclass VM; then cat > $target/etc/network/interfaces <<-EOF - # generated by FAI - auto lo $NIC1 - iface lo inet loopback - iface $NIC1 inet dhcp + # installed by FAI + auto lo $NIC1 + iface lo inet loopback + iface $NIC1 inet dhcp EOF else cat > $target/etc/network/interfaces <<-EOF @@ -19,23 +19,26 @@ EOF iface lo inet loopback iface $NIC1 inet manual # make a bridge by default so we can have bridged vms. + # Some example I read had stp on, but i don't need stp, + # and it causes a vm to fail pxe boot, presumably unless + # you add some delay. + # http://wiki.libvirt.org/page/PXE_boot_%28or_dhcp%29_on_guest_failed iface br0 inet dhcp - bridge_ports eth0 - bridge_stp on - bridge_maxwait 0 - bridge_fd 0 + bridge_ports eth0 + bridge_stp off + bridge_maxwait 0 EOF fi elif [ $FAI_ACTION = "install" -o $FAI_ACTION = "dirinstall" ] then [ -n "$IPADDR" ] && cat > $target/etc/network/interfaces <<-EOF # generated by FAI - auto lo $NIC1 - iface lo inet loopback - iface $NIC1 inet static - address $IPADDR - netmask $NETMASK - broadcast $BROADCAST + auto lo $NIC1 + iface lo inet loopback + iface $NIC1 inet static + address $IPADDR + netmask $NETMASK + broadcast $BROADCAST gateway $GATEWAYS hwaddress ether $(cat /sys/class/net/$NIC1/address) EOF diff --git a/fai/config/scripts/GRUB_PC/11-ian b/fai/config/scripts/GRUB_PC/11-ian index 1bb4fda..d22d8fc 100755 --- a/fai/config/scripts/GRUB_PC/11-ian +++ b/fai/config/scripts/GRUB_PC/11-ian @@ -33,7 +33,11 @@ usermod -aG cdrom,floppy,sudo,audio,dip,video,plugdev,netdev,kvm,systemd-journal EOF -apt-get -y install unison-gtk +$ROOTCMD apt-get -y install unison-gtk if ifclass STABLE; then - apt-get -y install unison-gtk/testing + # don't think this is needed since I figured out how to + # deal with mismatching unison compilers, but I don't + # see any reason to revert it, since it only installs + # a single package which is primarily a single binary + $ROOTCMD apt-get -y install unison-gtk/testing fi diff --git a/faiserver-revm b/faiserver-revm index eeae0b9..c7f82b8 100755 --- a/faiserver-revm +++ b/faiserver-revm @@ -22,4 +22,4 @@ while ! scp fai-setup root@faiserver:; do sleep 5 done -ssh root@faiserver ./fai-setup +ssh root@faiserver ./faiserver-setup diff --git a/fai-setup b/faiserver-setup similarity index 72% rename from fai-setup rename to faiserver-setup index dc0dceb..54b69f6 100755 --- a/fai-setup +++ b/faiserver-setup @@ -7,6 +7,7 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR [[ $EUID == 0 ]] || exec sudo "${BASH_SOURCE}" "$@" +e() { echo "$@"; "$@"; } # for ubuntu: #add-apt-repository -y ppa:fai/ppa @@ -18,8 +19,18 @@ EOF apt-get update # all the dependencies except the dhcp server -apt-get -y install $(apt-cache show fai-quickstart | grep ^Depends: |head -n 1|\ - sed -r 's/^Depends:|,|\|[^,]+|isc-dhcp-server//g') +deps="$(apt-cache show fai-quickstart | grep ^Depends: |head -n 1|\ + sed -r 's/^Depends:|,|\|[^,]+|isc-dhcp-server//g')" +to_install=() +for pkg in $deps; do + dpkg -s $pkg &>/dev/null && continue ||: + to_install+=($pkg) + echo $pkg >> /etc/fai/fai-manually-installed-packages +done +if [[ $to_install ]]; then + apt-get -y install ${to_install[@]} +fi + sed -i 's/^#deb/deb/' /etc/fai/apt/sources.list sed -i 's/#LOGUSER/LOGUSER/' /etc/fai/fai.conf # from man fai-make-nfsroot, @@ -49,14 +60,14 @@ service tftpd-hpa restart # Add debug to -f flag for more verbose output. std_arg="-u nfs://faiserver/srv/fai/config" -fai-chboot -Iv $std_arg default +fai-chboot -Iv $std_arg default # reset so we are idempotent kernel=$(fai-chboot -L '^default$' | awk '{print $3}') type -t host &>/dev/null || apt-get -y install dnsutils my_ip=$(host faiserver $(route -n | sed -rn 's/^(0\.){3}0\s+(\S+).*/\2/p') | \ - sed -rn 's/^faiserver has address //p') + sed -rn 's/^\S+ has address //p') k_args=$(fai-chboot -L '^default$' | \ sed -r "s/^(\S+\s+){3}(.*root=)(.*)/\2$my_ip:\3/") -fai-chboot -k "$k_args" -v -f verbose,sshd,createvt,reboot $std_arg $kernel default +e fai-chboot -k "$k_args" -v -f verbose,sshd,createvt,reboot $std_arg $kernel default # make the faiserver also the apt proxy server apt-get -y install apt-cacher-ng @@ -75,5 +86,9 @@ apt-get -y install apt-cacher-ng # random fai note: as far as I can tell, profiles are just for putting # in a selectable boot menu, which I don't want. -# somewhere I call it faiserver, but debian's default is faiserver.lan -sed -ri 's/faiserver.lan/faiserver/' /srv/fai/nfsroot/root/.ssh/known_hosts +# 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 -ri 's/(^[^,]+,)\S+/\1faiserver/' /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 new file mode 100755 index 0000000..4a9976d --- /dev/null +++ b/faiserver-uninstall @@ -0,0 +1,9 @@ +#!/bin/bash + +set -eE -o pipefail +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR + +[[ $EUID == 0 ]] || exec sudo "${BASH_SOURCE}" "$@" + + +apt-get -y purge $(< /etc/fai/fai-manually-installed-packages) diff --git a/wrt-setup b/wrt-setup index fda94a3..8023523 100755 --- a/wrt-setup +++ b/wrt-setup @@ -200,9 +200,9 @@ cedit /etc/hosts <