From a4bf1d090bfbb5603bd6f2aa9f67a2e8a702d476 Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Sat, 30 Jan 2016 12:04:30 -0800 Subject: [PATCH] add arch support, fixup various things --- arch-init | 144 +++++++++++++++++++++++++ arch-init-chroot | 151 +++++++++++++++++++++++++++ arch-init-remote | 35 +++++++ arch-pxe | 57 ++++++++++ arch-revm | 1 + fai-revm | 21 ++-- fai/config/distro-install-common/end | 12 +++ fai/config/hooks/extrbase.DEFAULT | 2 +- fai/config/hooks/instsoft.DEFAULT | 8 -- fai/config/hooks/partition.DEFAULT | 59 ++++++----- fai/config/scripts/GRUB_PC/11-ian | 12 +-- 11 files changed, 452 insertions(+), 50 deletions(-) create mode 100755 arch-init create mode 100755 arch-init-chroot create mode 100755 arch-init-remote create mode 100755 arch-pxe create mode 120000 arch-revm diff --git a/arch-init b/arch-init new file mode 100755 index 0000000..30ec9f1 --- /dev/null +++ b/arch-init @@ -0,0 +1,144 @@ +#!/bin/bash -x + +# see t.org for how to call + +set -eE -o pipefail +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR + +cd "${BASH_SOURCE%/*}" + +export ROOTPW="$1" +export hostname="$2" +mirror=$3 + +(( $# >= 2 )) || { echo "error: need 2 arguments"; exit 1; } + +case $hostname in + x2) + export grubdisk=/dev/sda + ;; + demohost) + export grubdisk=/dev/vda + ;; + treetowl) + bootid=64d495ee-c9fe-4174-b20a-6c5e47abcfa1 + export grubdisk=$(blkid|sed -nr "/$bootid/s/^([^0-9]+).*/\1/p") + ;; + frodo) + rootid=e9ce7b46-9a21-4e79-b7f7-0b18acb57587 + export grubdisk=$(blkid|sed -nr "/$rootid/s/(^[^0-9]*).*/\1/p") + ;; + *) + echo "unrecognized hostname: $hostname" + exit 1 +esac + + +rm -f /etc/pacman.d/mirrorlist +# https://wiki.archlinux.org/index.php/Mirrors#Sorting_mirrors + +if [[ $mirror ]]; then + echo "Server = $mirror" >> /etc/pacman.d/mirrorlist +fi +curl -s 'https://www.archlinux.org/mirrorlist/?country=US&protocol=https&ip_version=4&ip_version=6&use_mirror_status=on' | + sed -r 's/^[ #]*(Server *=)/\1/' >> /etc/pacman.d/mirrorlist + +ifclass() { + local var=${1/#/CLASS_} + [[ $hostname == $1 || ${!var} ]] +} +export -f ifclass +for x in $(bash 50-host-classes); do + export CLASS_$x=true +done + +export LUKS_DIR=/root/luks +export HOSTNAME=$hostname +chmod +x partition.DEFAULT +./partition.DEFAULT +# arch doesn't need crypttab entries for initramfs crypt partititions +sed -ri '/^crypt_dev/d' /tmp/fai/crypttab +mount -o subvol=/root /dev/mapper/crypt_dev_?da3 /mnt +mkdir -p /mnt/{q,home} +mount -o subvol=/q /dev/mapper/crypt_dev_?da3 /mnt/q +mount -o subvol=/home /dev/mapper/crypt_dev_?da3 /mnt/home +mkdir -p /mnt/etc +cp /tmp/fai/{fstab,crypttab} /mnt/etc +mkdir -p /mnt/boot +mount /dev/?da1 /mnt/boot + +# https://wiki.archlinux.org/index.php/Dm-crypt/Device_encryption#Keyfiles +cp /root/luks/host-$hostname /mnt/crypto_keyfile.bin + + +shopt -s extglob +case $hostname in + # these hosts are broken, not updated to new fai hyrbrid scripts. + frodo) + + # for this system, no separate /boot, to keep partitions simple, + # since we want simpler backup recovery. + mount -U $rootid /mnt + ;;& + treetowl) + mount /dev/mapper/vg_treetowl00-lv02 /mnt + mount -U $bootid /mnt/boot + ;;& + frodo|treetowl) + rm -rf /mnt/!(a|i|q|f|boot) /mnt/boot/* + ;; +esac + + + +if [[ $mirror ]]; then + echo "$0: 404 errors about core.db etc are normal, +they will succeed using the secodary mirror" +fi +pacstrap /mnt base +case $hostname in + frodo) + # the root .ssh needs to be like this, + # because it\'s used to get the key to mount an encrypted filesystem + # on top of itself. + d=/mnt/q/root/.ssh + rm -rf $d # for idempotency + mkdir -p $d + scp -oStrictHostKeyChecking=no ian@treetowl:/a/c/machine_specific/frodo/subdir_files/.ssh/* $d + cp .ssh/* $d + ln -s /q/root/.ssh /mnt/root + # background: errors=remount-ro is a debian installer thing. seems like + # not a bad idea. man mount says: The default is set in the filesystem + # superblock, and can be changed using tune2fs(8) + + cat > /mnt/etc/fstab <<'EOF' +UUID=e9ce7b46-9a21-4e79-b7f7-0b18acb57587 / ext4 noatime,errors=remount-ro 0 1 +UUID=dd67766f-93c5-4ce3-9877-a1d9841dd4a4 none swap sw 0 0 +/dev/sr0 /media/cdrom0 udf,iso9660 user,noauto 0 0 +/dev/mapper/crypta7 /mnt/btrfs_root btrfs subvolid=0,noatime,noauto 0 2 +/dev/mapper/crypta7 /a btrfs subvol=a,noatime,noauto 0 2 +EOF + ;; + *) + genfstab -p /mnt > /mnt/etc/fstab + cp -r .ssh /mnt/root + cp -r /root/distro-install-common /mnt/root + ;;& + treetowl) + echo "UUID=a9e83bb7-d23d-4de6-ba9f-d88b887f7206 /a ext4 noatime 0 2" >> /mnt/etc/fstab + ;; +esac + +cp /root/arch-init-chroot /mnt/root +# for manual commands, arch-chroot /mnt bash +arch-chroot /mnt /root/arch-init-chroot + +# this gets mounted in chroot so we have to do it outside +rm -f /mnt/etc/resolv.conf +ln -s /run/systemd/resolve/resolv.conf /mnt/etc/resolv.conf + +# not necsesary, but makes reboot go fast. +umount -R /mnt + +# causes 255 exit code, so doing this from the caller script. +# reboot now diff --git a/arch-init-chroot b/arch-init-chroot new file mode 100755 index 0000000..53a2b94 --- /dev/null +++ b/arch-init-chroot @@ -0,0 +1,151 @@ +#!/bin/bash -x +set -eE -o pipefail +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR + +for x in /etc/*.pacorig; do + mv $x ${x%.pacorig} +done + +echo $hostname > /etc/hostname +ln -s /usr/share/zoneinfo/America/Los_Angeles /etc/localtime +l=en_US.UTF-8 +echo "$l UTF-8" > /etc/locale.gen +locale-gen +echo "LANG=$l" > /etc/locale.conf +# if coming from windows, and you had to set the time, do this +# hwclock --systohc --utc + +# A password is required to access the volume: +# Command requires device and ampped name as arguments + +# If we were using btrfs raid, we supposedly would need this. +# # add btrfs as module instead of hook due to +# # https://wiki.archlinux.org/index.php/Btrfs, +# # https://bugs.archlinux.org/task/42884 +# # disabled, as with just the module, startup spammed something about +# # command takes a device name and something else. +# sed -ri '/^ *MODULES *=.*btrfs/!s/^( *MODULES *=.*)"/\1 btrfs"/' /etc/mkinitcpio.conf +# # remove extra space +# sed -ri 's/^( *MODULES *=[^"]*)" */\1"/' /etc/mkinitcpio.conf + +# https://wiki.archlinux.org/index.php/Dm-crypt/Encrypting_an_entire_system#Configuring_mkinitcpio_2 +# used to have lvm2 after encrypt for lvm. +for x in encrypt encrypt1 btrfs; do sed -ri -f - /etc/mkinitcpio.conf < /etc/crypttab <<'EOF' +#tmp /dev/lvm/tmp /dev/urandom tmp,cipher=aes-xts-plain64,size=256 + +# otgherwise ERROR: file not found: `fsck.btrfs' +pacman -S --noconfirm btrfs-progs + +pacman -S --noconfirm grub gptfdisk + +if [[ $hostname == x2 || $hostname == demohost ]]; then + echo "$0: fstab:" + cat /etc/fstab + # https://wiki.archlinux.org/index.php/Dm-crypt/System_configuration#Boot_loader + # if cryptdevice was lvm, it woulde be in this format, + # where x2-vg is from lvdisplay, VG Name field. + # cryptdevice=/dev/disk/by-uuid/585dff23-136f-446f-815f-01053b70c957:x2-vg + # but, if you are using your own fstab, it seems you just give it a name, + # which will be the crypt device name under /dev/mapper/ + # https://wiki.archlinux.org/index.php/GRUB#Additional_arguments + crypt_dev=(/dev/?da3) + crypt_name=crypt_dev_${crypt_dev##/dev/} + k_args=( + cryptdevice=$crypt_dev:$crypt_name:allow-discards + root=/dev/mapper/$crypt_name + resume=${crypt_dev%3}2 + ) + crypt_mapper_devs=(/dev/mapper/crypt_dev_?d[a-z]3) + keyfile_vars=() + for ((i=1; i < ${#crypt_mapper_devs[@]}; i++)); do + ((i!=1)) || dup_keys=(" ") + cp /crypto_keyfile.bin /crypto_keyfile$i.bin + dup_keys+=(/crypto_keyfile$i.bin) + base=/usr/lib/initcpio + cp $base/hooks/encrypt{,$i} + cp $base/install/encrypt{,$i} + sed -i "s/cryptdevice/cryptdevice$i/" $base/hooks/encrypt$i + sed -i "s/cryptkey/cryptkey$i/" $base/hooks/encrypt$i + crypt_name=${crypt_mapper_devs[i]#/dev/mapper/} + crypt_dev=/dev/${crypt_name#crypt_dev_} + k_args+=(cryptdevice$i=$crypt_dev:$crypt_name:allow-discards + cryptkey$i=rootfs:/crypto_keyfile$i.bin) + done + # this is the default file, otherwise you use cryptkey=device:fstype:path + sed -ri -f - /etc/mkinitcpio.conf < /etc/systemd/network/wired.network < /etc/systemd/network/br0.network < /etc/systemd/network/br0.netdev < /tmp/myarchinit.log +dhcpcd eth0 +systemctl start sshd +EOF +s rm $sfs +s mksquashfs squashfs-root $sfs -comp xz +# file transfer to wrt is slow, so remove some useless files +rm $iso/arch/i686/airootfs.sfs $iso/arch/boot/i686/archiso.img +c $(dirname $sfs); md5sum ${sfs##*/} > airootfs.md5; b + +# seems if you've done a pxe boot, mounted the nfs, +# then shutdown, it's still busy. +ssh wrt "/etc/init.d/nfsd stop; \ +{ ! mount | grep /run/archiso/bootmnt || umount /run/archiso/bootmnt; } && \ +rm -rf /mnt/usb/$iso" +scp -r $iso wrt:/mnt/usb +ssh wrt "cd /mnt/usb && rm -f tftpboot && ln -s $iso tftpboot" + +# The default settings in the installer expect to find the NFS at /run/archiso/bootmnt + +pxe-server arch + +# background: +# great documentation at https://wiki.archlinux.org/index.php/PXE +# background: arch can do netboot like ubuntu etc, but the docs look a little complicated, so fuck it, +# we use nfs cuz it's easy + +rm -rf $iso +s rm -rf squashfs-root diff --git a/arch-revm b/arch-revm new file mode 120000 index 0000000..de8dd4b --- /dev/null +++ b/arch-revm @@ -0,0 +1 @@ +fai-revm \ No newline at end of file diff --git a/fai-revm b/fai-revm index af8bc36..97bb1a8 100755 --- a/fai-revm +++ b/fai-revm @@ -11,16 +11,23 @@ new_disk=false cd "${BASH_SOURCE%/*}" -./fai-redep +[[ $0 == *arch-revm ]] || ./fai-redep -s virshrm demohost ||: +name=demohost -for f in /var/lib/libvirt/images/demohost{,b}; do +s virshrm $name ||: + +for f in /var/lib/libvirt/images/${name}{,b}; do if $new_disk || [[ ! -e $f ]]; then s qemu-img create -o preallocation=metadata -f qcow2 $f 30G fi done -# osinfo-query os | gr jessie -s virt-install --os-variant debian8 --cpu host -n demohost --pxe -r 2048 --vcpus 1 \ - --disk path=/var/lib/libvirt/images/demohost \ - --disk path=/var/lib/libvirt/images/demohostb -w bridge=br0,mac=52:54:00:9c:ef:ad + +disk_arg=("--disk path=/var/lib/libvirt/images/$name"{,b}) +s virt-install --os-variant debian8 --cpu host -n $name --pxe -r 2048 --vcpus 1 \ + ${disk_arg[*]} -w bridge=br0,mac=52:54:00:9c:ef:ad & + +if [[ $0 == *arch-revm ]]; then + sleep 80 + ./arch-init-remote $name +fi diff --git a/fai/config/distro-install-common/end b/fai/config/distro-install-common/end index 666b781..61b99ac 100755 --- a/fai/config/distro-install-common/end +++ b/fai/config/distro-install-common/end @@ -14,3 +14,15 @@ echo "fs.inotify.max_user_watches = 1000000" >> $target/etc/sysctl.d/99-sysctl.c # sysctl --system echo 'ian ALL=(ALL) NOPASSWD: ALL' >> $target/etc/sudoers + + +dir=/q/p/c/machine_specific/$HOSTNAME/.unison +$ROOTCMD mkdir -p $dir +$ROOTCMD rm -rf /root/.unison +$ROOTCMD ln -s $dir /root +$ROOTCMD ln -s /q/p / +$ROOTCMD ln -s /q/a / + +# kvm is normally created by some package, +# but unison doesn't like unknown groups, so make it now so initial sync works. +$ROOTCMD groupadd kvm diff --git a/fai/config/hooks/extrbase.DEFAULT b/fai/config/hooks/extrbase.DEFAULT index fe3eda5..4efa226 100755 --- a/fai/config/hooks/extrbase.DEFAULT +++ b/fai/config/hooks/extrbase.DEFAULT @@ -5,4 +5,4 @@ if ifclass VM && ! ifclass demohost; then exit 0 fi -chattr -Rf +C /target +#chattr -Rf +C /target diff --git a/fai/config/hooks/instsoft.DEFAULT b/fai/config/hooks/instsoft.DEFAULT index ab6e213..bdb856b 100755 --- a/fai/config/hooks/instsoft.DEFAULT +++ b/fai/config/hooks/instsoft.DEFAULT @@ -16,14 +16,6 @@ EOFOUTER chmod +x $f -crypt_dev=(/dev/mapper/crypt_dev_?da3) -crypt_dev=${crypt_dev[0]} -crypt_name=${crypt_dev##/dev/mapper/} -dev=(/dev/?da3) -dev=${dev[0]} - -dd if=$keyfile of=$crypt_dev - f=$target/root/keyscript-manual cat >$f <<'EOF' #!/bin/sh diff --git a/fai/config/hooks/partition.DEFAULT b/fai/config/hooks/partition.DEFAULT index e2a32ca..64e09a2 100755 --- a/fai/config/hooks/partition.DEFAULT +++ b/fai/config/hooks/partition.DEFAULT @@ -8,22 +8,25 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR #### begin configuration -if ifclass VM; then - d=vd -else - d=sd -fi - -if ifclass TWO_DISK; then +if ifclass TWO_DISK || ifclass demohost; then letters=(a b) elif ifclass ONE_DISK; then letters=(a) else - exit + exit 1 fi ##### end configuration -skiptask partition + +if ifclass VM; then + d=vd +else + d=sd +fi + + + +skiptask partition ||: # for running out of fai devs=(${letters[@]/#//dev/${d}}) crypt_devs=(${letters[@]/#//dev/mapper/crypt_dev_${d}}) @@ -47,7 +50,7 @@ partition=true # override temporarily # keyfiles generated like: # head -c 2048 /dev/urandom | od | s dd of=/q/root/luks/host-demohost -luks_dir=/var/lib/fai/config/distro-install-common/luks +luks_dir=${LUKS_DIR:-/var/lib/fai/config/distro-install-common/luks} if ifclass tp; then lukspw=$(cat $luks_dir/traci) else @@ -68,18 +71,19 @@ swap_end=$(( $(grep ^MemTotal: /proc/meminfo| awk '{print $2}') * 3/(${#devs[@]} create_subvols() { cd /mnt - for x in a home root; do + for x in q home root; do btrfs subvolume list . | grep "$x$" >/dev/null || btrfs subvolume create $x done btrfs subvolume set-default \ $(btrfs subvolume list . | grep 'root$' | awk '{print $2}') . + chattr -Rf +C root cd / umount /mnt } +mkdir -p /tmp/fai shopt -s nullglob if $partition; then - mkdir -p /tmp/fai for dev in ${devs[@]}; do for x in $dev[0-9]; do wipefs -a $x; done parted -s $dev mklabel gpt @@ -144,30 +148,33 @@ else fi -for dev in ${devs[@]}; do - cat >>/tmp/fai/crypttab <>/tmp/fai/crypttab < /tmp/fai/fstab <>/tmp/fai/crypttab <> /tmp/fai/fstab </tmp/fai/disk_var.sh <