diff options
-rw-r--r-- | README | 35 | ||||
-rwxr-xr-x | bootstrap | 21 | ||||
-rwxr-xr-x | genmacaddr | 5 | ||||
-rwxr-xr-x | init | 96 | ||||
-rwxr-xr-x | qemu-ifup | 16 |
5 files changed, 167 insertions, 6 deletions
@@ -0,0 +1,35 @@ +buildos is a Debian-based in-memory, net-booted operating system specialized +for building software with the build2 toolchain. + +Configuration +------------- + +- Network is configured via DHCP. All Ethernet intrface that have carrier are + tried in (some) order and the first interface that is successfully configure + via DHCP is used. + +- Hostname is configure from the DHCP information. Failed that, a name is + generated based on the MAC address. @@ Maybe also kernel cmdline. + +PXE +--- + +- Copy the kernel image and initrd to TFTP + +# mkdir -p /var/lib/tftpboot/buildos +# cp buildos-image buildos-initrd /var/lib/tftpboot/buildos/ + +- Assuming the host has MAC address de-ad-be-ef-b8-da, create host-specific + configuration (or use 'default' for the last path component to apply to + all the hosts): + +# cat <<EOF >/var/lib/tftpboot/pxelinux.cfg/01-de-ad-be-ef-b8-da +default buildos +prompt 1 +timeout 50 + +label buildos + menu label buildos + kernel /buildos/buildos-image + append initrd=/buildos/buildos-initrd +EOF @@ -29,7 +29,8 @@ id="$(id -un)" btrfs=/btrfs release="unstable" mirror="https://deb.debian.org/debian/" -passwd="123" #@@ TMP root passwd. +passwd="123" #@@ TMP root passwd. +macaddr="DE:AD:BE:EF:B8:DA" # Mac address for testing. root="$btrfs/$id/buildos" @@ -117,7 +118,7 @@ function nspawn () # <systemd-nspawn-args> # (Over)write or append to a file in the installation root, for example: # -# write <<<'unknown' /etc/hostname +# write <<<'localhost' /etc/hostname # function write () # <path> { @@ -140,8 +141,10 @@ if [ "$stage" -eq "1" ]; then # - systemd-container seems to be required by host systemd-nspawn. # pkgs="locales,systemd-container" - pkgs+=",net-tools,iproute2,isc-dhcp-client,wget" - pkgs+=",linux-image-amd64" + pkgs+=",net-tools,iproute2,iptables,isc-dhcp-client,ifupdown,ntp" + pkgs+=",iputils-ping,wget,curl" + pkgs+=",linux-image-amd64,irqbalance,pciutils" + pkgs+=",less" sudo debootstrap \ --foreign \ @@ -153,7 +156,11 @@ if [ "$stage" -eq "1" ]; then # Post-phase 1 fixups. # - write <<<'unknown' /etc/hostname + + # Set the initial hostname to '(none)'. This value is detected and + # overriden by /sbin/dhclient-script if the DHCP server sends host-name. + # + write <<<'(none)' /etc/hostname # Set timezone to UTC (picked up by tzdata package during stage 2). # @@ -339,6 +346,10 @@ fi # Test. # +# To test PXE boot, replace -kernel/-initrd with '-boot n'. +# sudo kvm \ -m 8G \ + -netdev 'tap,id=net0,script=./qemu-ifup' \ + -device "e1000,netdev=net0,mac=$macaddr" \ -kernel buildos-image -initrd buildos-initrd diff --git a/genmacaddr b/genmacaddr new file mode 100755 index 0000000..093e616 --- /dev/null +++ b/genmacaddr @@ -0,0 +1,5 @@ +#!/bin/bash + +# Generate a random mac address for the qemu nic. +# +printf 'DE:AD:BE:EF:%02X:%02X\n' $((RANDOM%256)) $((RANDOM%256)) @@ -57,7 +57,101 @@ udevadm settle || true cmdline="$(cat /proc/cmdline)" info "boot cmdline: $cmdline" -sleep 2 +# Figure out network configuration and generate the corresponding +# /etc/network/interfaces. +# +info "starting network..." + +# We are using udev's predictable interface names. The two character prefixes +# based on the type of interface: +# +# en -- ethernet +# sl -- serial line IP (slip) +# wl -- wlan +# ww -- wwan +# +eth_all="$(cd /sys/class/net && ls -d en?*)" + +if [ -z "$eth_all" ]; then + info "no ethernet interfaces found among:" + ip link show +fi + +eth= +eth_up= +for s in 1 2 4 8; do + + # Try to bring them all up and find the one that has carrier. + # + for i in $eth_all; do + ip link set "$i" up || true + done + + sleep "$s" + + for i in $eth_all; do + if [ "$(cat "/sys/class/net/$i/carrier")" -eq "1" ]; then + info "detected carrier on $i" + eth_up+=" $i" + fi + done + + # Bring them all down. + # + for i in $eth_all; do + ip link set "$i" down || true + done + + # If we didn't find anything, try to wait for carrier longer. + # + if [ -z "$eth_up" ]; then + continue + fi + + # If we end up with several interfaces we simply unleash dhcp on all of + # them and use the first that gets configured. + # + # Note also that it's possible the interface that we want is not yet ready + # in which case we will try to wait for carrier a bit longer. + # + for i in $eth_up; do + if dhclient -v "$i"; then + eth="$i" + break + fi + done + + if [ -n "$eth" ]; then + break + fi +done + +if [ -z "$eth_up" ]; then + error "no ethernet interfaces with carrier among:" + ip link show +fi + +if [ -z "$eth" ]; then + error "no ethernet interfaces with DHCP among:" + ip link show +fi + +mac="$(cat "/sys/class/net/$eth/address")" + +info "configured $eth ($mac)" + +# Set the hostname. +# +hname="$(hostname)" + +if [ "$hname" = "(none)" ]; then + hname="build-$(sed -e 's/://g' <<<"$mac")" + hostname "$hname" +fi + +echo "$hname" >/etc/hostname + +info "hostname $hname" # --machine-id # diff --git a/qemu-ifup b/qemu-ifup new file mode 100755 index 0000000..2541653 --- /dev/null +++ b/qemu-ifup @@ -0,0 +1,16 @@ +#!/bin/bash + +trap "exit 1" ERR + +switch=br0 + +set -x + +#ip tuntap show "$1" + +#ip tuntap add "$1" mode tap user "$(whoami)" # Already created. +ip link set "$1" up +sleep 0.5s +ip link set "$1" master "$switch" + +#ip tuntap show "$1" |