--- /dev/null
+#!/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
--- /dev/null
+#!/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 <<EOF
+/^ *HOOKS.*\b$x\b/!s/^( *HOOKS=.*)filesystems/\1$x filesystems/
+EOF
+done
+
+
+
+# for desktop without full fs encryption, use this:
+#cat > /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 <<EOF
+s#^\s*FILES=.*#FILES="/crypto_keyfile.bin${dup_keys[*]}"#
+EOF
+ echo "$0: FILES:"
+ grep FILES /etc/mkinitcpio.conf
+ k_args="${k_args[*]}"
+ echo "$0: grub cmdline additions: $k_args"
+ sed -ri -f - /etc/default/grub <<EOF
+\%$k_args%!s%^ *GRUB_CMDLINE_LINUX_DEFAULT *= *"%\0$k_args %
+EOF
+fi
+
+mkinitcpio -p linux
+
+
+# remove the default quiet arg.
+# this doesn't seem to affect anything, so leave it alone.
+#sed -ri 's/^( *GRUB_CMDLINE_LINUX_DEFAULT *= *.*) ?\bquiet\b(.*)/\1\2/' /etc/default/grub
+
+# https://wiki.archlinux.org/index.php/GRUB#Install_to_disk
+grub-install --recheck $grubdisk
+grub-mkconfig -o /boot/grub/grub.cfg
+pacman -S --noconfirm openssh unison
+
+echo "root:$ROOTPW" | chpasswd -e
+
+pacman -S --noconfirm sudo
+
+useradd -m -p "$ROOTPW" ian
+
+/root/distro-install-common/end
+systemctl enable sshd
+
+rm -rf /home/ian/.ssh
+cp -r /root/.ssh /home/ian
+chown ian:ian /home/ian/.ssh
+# the groups recommended by
+# https://wiki.archlinux.org/index.php/Users_and_groups#Group_list
+usermod -aG games,rfkill,users,uucp,wheel ian
+
+# setup a bridge, so we can have 1st class vms.
+cat > /etc/systemd/network/wired.network <<EOF
+[Match]
+Name=en*
+
+[Network]
+Bridge=br0
+EOF
+
+cat > /etc/systemd/network/br0.network <<EOF
+[Match]
+Name=br0
+
+[Network]
+DHCP=ipv4
+EOF
+
+pacman -S --noconfirm net-tools # for route
+mac=$(cat /sys/class/net/$(route -n | sed -rn 's/^0\.0\.0\.0.*[[:space:]]([^[:space:]]+)[[:space:]]*$/\1/p')/address)
+cat > /etc/systemd/network/br0.netdev <<EOF
+[NetDev]
+Name=br0
+Kind=bridge
+# use the same mac as the physical port,
+# which is mapped to a static ip in our dhcp server.
+MACAddress=$mac
+EOF
+
+for x in networkd resolved; do systemctl enable systemd-$x; done
--- /dev/null
+#!/bin/bash -lx
+
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
+
+host=$1
+
+[[ $host == frodo ]] && scp /a/c/machine_specific/frodo/subdir_files/.ssh/* frodo:.ssh/
+if [[ -e /var/cache/pacman/pkg ]]; then
+ darkhttpd /var/cache/pacman/pkg &
+ url=http://$HOSTNAME:8080
+fi
+faid=/a/bin/fai
+fai_files=(
+ distro-install-common
+ hooks/partition.DEFAULT
+ class/50-host-classes
+)
+sudo scp -r /a/bin/fai/arch-init{,-chroot} \
+ ${fai_files[@]/#//a/bin/fai/fai/config/} \
+ /q/root/luks /p/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,
+# and extract it from the shadow file.
+ssh root@$host bash -x ./arch-init "'$(cat /p/shadow/standard)'" $host $url
+ssh root@$host reboot now || [[ $? == 255 ]]
+# we need to wait for reboot and input encryption password,
+# so no doing this now.
+# ssh $host /a/bin/distro-begin
+
+killall darkhttpd
+# todo: this doesn't work. figure out why.
+#kill $!
--- /dev/null
+#!/bin/bash -lx
+
+# manually download image to /a/opt, and set it's name below.
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
+
+cd /a/opt
+#iso="archlinux-2015.11.01-dual"
+iso="archlinux-2016.01.01-dual"
+sfs=$iso/arch/x86_64/airootfs.sfs
+rm -rf $iso
+ex $iso.iso
+sed -i -f - $iso/arch/boot/syslinux/archiso_pxe64.cfg <<EOF
+1itotaltimeout 1
+/^LABEL arch64_nfs/a menu default
+s/^APPEND .*/\0 script=myarchinit.sh/
+EOF
+# based on https://blog.chendry.org/2015/02/06/automating-arch-linux-installation.html
+# and https://wiki.archlinux.org/index.php/Remastering_the_Install_ISO
+
+s rm -rf squashfs-root # remove any existing folder
+s unsquashfs $sfs
+s mkdir -p squashfs-root/root/.ssh
+s chmod 755 squashfs-root/root/.ssh
+s cp ~/.ssh/id_rsa.pub squashfs-root/root/.ssh/authorized_keys
+s dd of=squashfs-root/root/myarchinit.sh <<EOF
+#!/bin/bash
+echo $(date) > /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
--- /dev/null
+fai-revm
\ No newline at end of file
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
# 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
exit 0
fi
-chattr -Rf +C /target
+#chattr -Rf +C /target
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
#### 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}})
# 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
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
fi
-for dev in ${devs[@]}; do
- cat >>/tmp/fai/crypttab <<EOF
-crypt_dev_${dev##/dev/}3 ${dev}3 none keyscript=/root/keyscript,discard,luks
-EOF
-done
-
-for dev in ${devs[@]}; do
- cat >>/tmp/fai/crypttab <<EOF
-swap ${dev}2 /dev/urandom swap,cipher=aes-xts-plain64,size=256,hash=ripemd160
-EOF
-done
-# this is duplicated in arch-init
cat > /tmp/fai/fstab <<EOF
$crypt / btrfs noatime,subvol=/root 0 0
-$crypt /a btrfs noatime,subvol=/a 0 0
+$crypt /q btrfs noatime,subvol=/q 0 0
$crypt /home btrfs noatime,subvol=/home 0 0
${devs[0]}1 /boot ext4 noatime 0 2
EOF
+swaps=()
+for dev in ${devs[@]}; do
+ s=crypt_swap_${dev##/dev/}2
+ swaps+=(/dev/mapper/$s)
+ cat >>/tmp/fai/crypttab <<EOF
+crypt_dev_${dev##/dev/}3 ${dev}3 none keyscript=/root/keyscript,discard,luks
+$s ${dev}2 /dev/urandom swap,cipher=aes-xts-plain64,size=256,hash=ripemd160
+EOF
+ cat >> /tmp/fai/fstab <<EOF
+/dev/mapper/$s none swap sw 0 0
+EOF
+done
+
+
+# swaplist seems to do nothing.
cat >/tmp/fai/disk_var.sh <<EOF
ROOT_PARTITION=\${ROOT_PARTITION:-$crypt}
BOOT_PARTITION=\${BOOT_PARTITION:-${devs[0]}1}
BOOT_DEVICE=\${BOOT_DEVICE:-"${devs[0]}"}
-SWAPLIST=\${SWAPLIST:-"${devs[@]/%/2}"}
+SWAPLIST=\${SWAPLIST:-"${swaps[@]}"}
EOF
$ROOTCMD usermod -p "$ROOTPW" ian
+fcopy -rM -i /home/ian/.ssh
/var/lib/fai/config/distro-install-common/end
-fcopy -rM -i /home/ian/.ssh
+
$ROOTCMD chown -R 1000:1000 /home/ian/.ssh
$ROOTCMD chmod -R u=Xrw,og= /home/ian/.ssh
$ROOTCMD cp -ar /home/ian/.ssh /root
$ROOTCMD chown -R root:root /root/.ssh
-$ROOTCMD ln -s /a/p /
-dir=/a/p/c/machine_specific/$HOSTNAME/.unison
-$ROOTCMD mkdir -p $dir
-$ROOTCMD rm -rf /root/.unison
-$ROOTCMD ln -s $dir /root
-
-$ROOTCMD usermod -aG cdrom,floppy,sudo,audio,dip,video,plugdev,netdev ian
+# default jessie groups + kvm
+$ROOTCMD usermod -aG cdrom,floppy,sudo,audio,dip,video,plugdev,netdev,kvm ian