--- /dev/null
+#!/bin/bash -l
+# Copyright (C) 2016 Ian Kelling
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+
+cleanup() { :; }
+set -eE -o pipefail
+trap 'cleanup; echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
+script_dir=$(dirname $(readlink -f "$BASH_SOURCE"))
+
+e() { echo "$*"; "$@"; }
+
+
+usage() {
+ cat <<EOF
+# Usage: ${0##*/} [OPTIONS]
+Setup fai or arch pxe (depending on $0 name)
+then start a virtual machine to test the config
+
+Note, sometimes shutting down the existing demohost vm
+fails. Just run again if that happens.
+
+-r Do not reboot.
+-n Create new qcow2(s) for vm
+-h|--help Print help and exit.
+
+Note: Uses GNU getopt options parsing style
+EOF
+ exit $1
+}
+
+
+new_disk=false
+reboot=true
+temp=$(getopt -l help hnr "$@") || usage 1
+eval set -- "$temp"
+while true; do
+ case $1 in
+ -n) new_disk=true; shift ;;
+ -r) reboot=false; shift ;;
+ -h|--help) usage ;;
+ --) shift; break ;;
+ *) echo "$0: Internal error!" ; exit 1 ;;
+ esac
+done
+
+
+# change this to test different disk counts. 1 and > 1 should be the only
+# important things to test.
+disk_count=1
+
+
+if [[ $script_dir == /a/bin/* ]]; then
+ # Copy our script elsewhere so we can develop it
+ # and save it at the same time it's running
+ rm -rf /tmp/faifreeze
+ mkdir -p /a/tmp
+ cp -ar /a/bin/fai /tmp/faifreeze
+ exec /tmp/faifreeze/${BASH_SOURCE##*/} "$@"
+fi
+
+cd $script_dir
+
+is_arch_revm() {
+ [[ ${0##*/} == arch-revm ]]
+}
+
+cleanup() { ./pxe-server; }
+if is_arch_revm; then
+ ./pxe-server demohost arch
+ sleep 2
+ # via osinfo-query os. guessing arch is closest to latest fedora.
+ variant=fedora22
+else
+ ./pxe-server demohost fai
+ sleep 2
+ # 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=ubuntu16.04
+ #variant=debian8
+fi
+
+name=demohost
+
+e s virshrm $name ||:
+
+
+disk_arg=()
+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
+ s rm -f $f
+ e s qemu-img create -o preallocation=metadata -f qcow2 $f 20G
+ fi
+done
+
+if [[ $SSH_CLIENT ]]; then
+ console_arg=--noautoconsole
+fi
+
+# --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 s virt-install --os-variant $variant -n $name --pxe -r 2048 --vcpus 1 \
+ ${disk_arg[*]} -w bridge=br0,mac=52:54:00:9c:ef:ad \
+ --graphics spice,listen=0.0.0.0 $console_arg |& grep -v '^ *$' | uniq &
+
+if [[ $SSH_CLIENT ]]; then
+ fg
+fi
+
+sleep 30
+while ! timeout -s 9 10 ssh root@$name /bin/true; do
+ e sleep 5
++ khfix root@$name ||:
+done
+cleanup() { :; }
+e pxe-server
+if is_arch_revm; then
+ ./arch-init-remote $name
+fi
# Define your local mirros here
# For the first stage, set the CentOS/SLC mirror in /etc/rinse/rinse.conf
-MIRROR_DEBIAN=http://httpredir.debian.org/debian/
+MIRROR_DEBIAN=http://http.us.debian.org/debian
- #MIRROR_DEBIAN=http://localmirror/debian/
MIRROR_UBUNTU=http://mirror.netcologne.de/ubuntu/
+MIRROR_TRISQUEL=http://mirror.fsf.org/trisquel/
MIRROR_CENTOS=http://mirror.netcologne.de/
- #MIRROR_CENTOS=http://localmirror
- #MIRROR_SLC=http://localmirror
EXCLUDE_SQUEEZE=isc-dhcp-client,isc-dhcp-common,info,tasksel,tasksel-data
- EXCLUDE_WHEEZY=isc-dhcp-client,isc-dhcp-common,info,tasksel,tasksel-data
- EXCLUDE_JESSIE=isc-dhcp-client,isc-dhcp-common,info,tasksel,tasksel-data
+ EXCLUDE_WHEEZY=info,tasksel,tasksel-data
+ EXCLUDE_JESSIE=tasksel,tasksel-data
+ EXCLUDE_STRETCH=tasksel,tasksel-data
-
+EXCLUDE_BELENOS=dhcp3-client,dhcp3-common,info
EXCLUDE_TRUSTY=dhcp3-client,dhcp3-common,info
- EXCLUDE_XENIAL=isc-dhcp-client,isc-dhcp-common,udhcpc,dibbler-client,dhcpcd5,info,tasksel,tasksel-data
+ EXCLUDE_XENIAL=tasksel,tasksel-data
INCLUDE_DEBIAN=aptitude
SLC6_32) slc i386 6 ;;
SLC6_64) slc amd64 6 ;;
SLC7_64) slc amd64 7 ;;
- TRUSTY32) trusty i386 ;;
- TRUSTY64) trusty amd64 ;;
- BELENOS64) belenos amd64 ;;
- XENIAL32) xenial i386 ;;
- XENIAL64) xenial amd64 ;;
- SQUEEZE32) squeeze i386 ;;
- SQUEEZE64) squeeze amd64 ;;
- WHEEZY32) wheezy i386 ;;
- WHEEZY64) wheezy amd64 ;;
- JESSIE32) jessie i386 ;;
- JESSIE64) jessie amd64 ;;
- STRETCH64) stretch amd64 ;;
- *) unknown ;;
++ BELANOS*)
++ debgeneric $target $MIRROR_TRISQUEL ;;
+ TRUSTY*|XENIAL*)
+ debgeneric $target $MIRROR_UBUNTU ;;
+ SQUEEZE*|WHEEZY*|JESSIE*|STRETCH*)
+ debgeneric $target $MIRROR_DEBIAN ;;
+ *) echo "Unknown distribution. Aborting."
+ prtdists
+ exit 99 ;;
esac
# cleanup
PACKAGES install DHCPC
isc-dhcp-client
++# ian: note everything after the grub package should be refactored into
++# a new class.
PACKAGES install GRUB_PC
- grub-pc cryptsetup btrfs-tools sudo bridge-utils netcat-openbsd grub-legacy- lilo-
-grub-pc
++grub-pc cryptsetup btrfs-tools sudo bridge-utils netcat-openbsd
+
+ PACKAGES install GRUB_EFI
-grub-efi
++grub-efi cryptsetup btrfs-tools sudo bridge-utils netcat-openbsd
PACKAGES install LVM
lvm2
- PACKAGES aptitude DEBIAN UBUNTU
-PACKAGES install-norec DEBIAN
++PACKAGES install-norec DEBIAN UBUNTU
fai-client
- cron
debconf-utils
file
less
isc-dhcp-client
PACKAGES install GRUB_PC
-grub-pc
+grub-pc cryptsetup btrfs-tools bridge-utils netcat-openbsd
- PACKAGES aptitude-r XORG
+ PACKAGES install XORG
ubuntu-desktop
ubuntu-standard
ubuntu-minimal
#! /bin/bash
+# modified from upstream fai example
error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code
- if ! ifclass STABLE; then
-
+ newnicnames() {
+
+ # determine predictable network names only for stretch and above
+
+ [ $do_init_tasks -eq 0 ] && return
+
+ ver=$($ROOTCMD dpkg-query --showformat='${Version}' --show udev)
+ if dpkg --compare-versions $ver lt 220-7; then
+ return
+ fi
+
+ [ -z $NIC1 ] && return
+
+ fields="ID_NET_NAME_FROM_DATABASE ID_NET_NAME_ONBOARD ID_NET_NAME_SLOT ID_NET_NAME_PATH"
+ for field in $fields; do
+ name=$(udevadm info /sys/class/net/$NIC1 | sed -rn "s/^E: $field=(.+)/\1/p")
+ if [[ $name ]]; then
+ NIC1=$name
+ break
+ fi
+ done
+ if ifclass VM; then
- # older distro still uses eth0
- if ifclass BELENOS64; then
- NIC1=eth0
- else
- # For a vm, we only get ID_NET_NAME_MAC from below,
- # but when it reboots, it uses ID_NET_NAME_SLOT.
- NIC1=ens3
- fi
- else
- # get persistent interface name. Note, these class conditions
- # will need to get modified for new oses. testing vm doesn't use
- # it right now, but other vms do I'm sure.
- for field in ID_NET_NAME_FROM_DATABASE \
- ID_NET_NAME_ONBOARD \
- ID_NET_NAME_SLOT \
- ID_NET_NAME_PATH \
- ID_NET_NAME_MAC; do
- name=$(udevadm info /sys/class/net/$NIC1 | sed -rn "s/^E: $field=(.+)/\1/p")
- if [[ $name ]]; then
- NIC1=$name
- break
- fi
- done
- if [[ ! $name ]]; then
- echo "$0: error: could not find systemd predictable network name"
- exit 1
- fi
++ NIC1=ens3
++ return
+ fi
- fi
+ if [[ ! $name ]]; then
+ echo "$0: error: could not find systemd predictable network name. Using $NIC1."
+ fi
+ }
+
+ newnicnames
+ CIDR=$(ip -o -f inet addr show $NIC1 | awk '{print $4}')
+ if ifclass DHCPC && [ $FAI_ACTION = "install" -o $FAI_ACTION = "dirinstall" ]; then
- if ifclass DHCPC && [ $FAI_ACTION = "install" -o $FAI_ACTION = "dirinstall" ]
- then
- cat > $target/etc/network/interfaces <<-EOF
+ if ifclass VM; then
++
++ # note, this condition would apply to the elif below too,
++ # but I don't specify a static ip in fai, so not bothering
+ cat > $target/etc/network/interfaces <<-EOF
- # generated by FAI
- auto lo $NIC1
- iface lo inet loopback
- iface $NIC1 inet dhcp
+ # generated by FAI
+ auto lo $NIC1
+ iface lo inet loopback
+ iface $NIC1 inet dhcp
EOF
- 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
- gateway $GATEWAYS
+ else
+ cat > $target/etc/network/interfaces <<-EOF
+ # generated by FAI
+ auto lo br0
+ 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 $NIC1
+ bridge_stp off
+ bridge_maxwait 0
+EOF
+ fi
- [ -n "$CIDR" ] && cat > $target/etc/network/interfaces <<-EOF
+ elif [ $FAI_ACTION = "install" -o $FAI_ACTION = "dirinstall" ]; then
++ [ -n "$CIDR" ] && cat > $target/etc/network/interfaces <<-EOF
+ # generated by FAI
+ auto lo $NIC1
+ iface lo inet loopback
+ iface $NIC1 inet static
+ address $CIDR
+ gateway $GATEWAYS
EOF
[ -n "$NETWORK" ] && echo "localnet $NETWORK" > $target/etc/networks
if [ ! -L $target/etc/resolv.conf -a -e /etc/resolv.conf ]; then
#! /bin/bash
- # (c) Thomas Lange, 2001-2015, lange@debian.org
+ # (c) Thomas Lange, 2001-2016, lange@debian.org
# (c) Michael Goetze, 2010-2011, mgoetze@mgoetze.net
+
+# on ubuntu 16.04 which didn't run this script, some things which didn't
+# apply:
+# /etc/dpkg/dpkg.cfg.d/fai didn't exist,
+# machine-id was already setup.
+
+# on that system and a debian stretch system, after reboot,
+# some things done here don't seem to persist:
+# some thin/etc/mtab is symlink somewhere else,
+# and mailname is $HOSTNAME.lan
+
+# the adjtime thing is to support changing the system clock
+# from representing UTC (the default) to localtime (windows default).
+
+# afaik, the only useful thing here for me is setting /etc/hostname
+
error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code
# a list of modules which are loaded at boot time
fi
$ROOTCMD grub-mkdevicemap --no-floppy
-GROOT=$($ROOTCMD grub-probe -tdrive -d $BOOT_DEVICE)
+
# Check if RAID is used for the boot device
if [[ $BOOT_DEVICE =~ '/dev/md' ]]; then
+ GROOT=$($ROOTCMD grub-probe -tdrive -d $BOOT_DEVICE)
raiddev=${BOOT_DEVICE#/dev/}
# install grub on all members of RAID
for device in `LC_ALL=C perl -ne 'if(/^'$raiddev'\s.+raid\d+\s(.+)/){ $_=$1; s/\d+\[\d+\]//g; print }' /proc/mdstat`; do
echo Install grub on /dev/$device
$ROOTCMD grub-install --no-floppy "/dev/$device"
done
+
+ elif [[ $GROOT =~ 'hostdisk' ]]; then
+ cat > $target/boot/grub/device.map <<EOF
+ (hd0) $BOOT_DEVICE
+ EOF
+ $ROOTCMD grub-install --no-floppy --modules=part_msdos $BOOT_DEVICE
+ if [ $? -eq 0 ]; then
+ echo "Grub installed on hostdisk $BOOT_DEVICE"
+ fi
+ rm $target/boot/grub/device.map
+
else
- $ROOTCMD grub-install --no-floppy "$GROOT"
- if [ $? -eq 0 ]; then
- echo "Grub installed on $BOOT_DEVICE = $GROOT"
- fi
+ for dev in $BOOT_DEVICE; do
+ GROOT=$($ROOTCMD grub-probe -tdrive -d $dev)
+ $ROOTCMD grub-install --no-floppy "$GROOT"
+ if [ $? -eq 0 ]; then
+ echo "Grub installed on $dev = $GROOT"
+ fi
+ done
fi
$ROOTCMD update-grub