aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README35
-rwxr-xr-xbootstrap21
-rwxr-xr-xgenmacaddr5
-rwxr-xr-xinit96
-rwxr-xr-xqemu-ifup16
5 files changed, 167 insertions, 6 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..eac7786
--- /dev/null
+++ b/README
@@ -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
diff --git a/bootstrap b/bootstrap
index 5ac3b46..18343be 100755
--- a/bootstrap
+++ b/bootstrap
@@ -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))
diff --git a/init b/init
index 0caf718..b733fde 100755
--- a/init
+++ b/init
@@ -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"