git: ab9130c737c7 - main - boot-test.sh: Add a http server per interface
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 26 Sep 2026 06:44:52 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=ab9130c737c718391cf5318a773ae500a955a4f9
commit ab9130c737c718391cf5318a773ae500a955a4f9
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-09-24 14:39:21 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-09-26 06:43:53 +0000
boot-test.sh: Add a http server per interface
Add the built-in python http server, bound to each of the interaces we
create to expand network testing to include http:// in various
scenarios.
Sponsored by: Netflix
---
tools/boot/boot-test.sh | 41 ++++++++++++++++++++++++++++++++++++++++-
tools/boot/boot-test.sh.8 | 32 ++++++++++++++++++++++++--------
2 files changed, 64 insertions(+), 9 deletions(-)
diff --git a/tools/boot/boot-test.sh b/tools/boot/boot-test.sh
index 023d2589824c..fd11f1a39f6b 100755
--- a/tools/boot/boot-test.sh
+++ b/tools/boot/boot-test.sh
@@ -49,6 +49,7 @@ pkg_for() {
*ipxe*) echo sysutils/ipxe ;;
*syslinux*|*memdisk*) echo sysutils/syslinux ;;
*edk2*) echo emulators/qemu ;; # edk2-*.fd ship with qemu
+ python3) echo lang/python3 ;;
*) echo "" ;; # makefs/mkimg etc. = base
esac
}
@@ -1322,6 +1323,21 @@ netboot_network_setup() {
done < "${resolved}"
fi
+ # Each vmnet also gets its own python3 http.server (see netboot_helper),
+ # so http:// fetches (netboot-http-efi) have something to hit at
+ # ${next-server} alongside dnsmasq's tftp-root. Confirm the pid count
+ # still matches the plan and every one of them is still alive.
+ if ${converged}; then
+ if [ -s "${NETBOOT_STATE_DIR}/httpd.pids" ] && \
+ [ "$(wc -l < "${NETBOOT_STATE_DIR}/httpd.pids")" -eq "$(wc -l < "${resolved}")" ]; then
+ while read pid; do
+ ps -p "${pid}" > /dev/null 2>&1 || { converged=false; break; }
+ done < "${NETBOOT_STATE_DIR}/httpd.pids"
+ else
+ converged=false
+ fi
+ fi
+
if ${converged}; then
echo " Existing vmnet(4)/dnsmasq setup already matches -- no sudo needed."
else
@@ -1342,6 +1358,7 @@ netboot_network_setup() {
netboot_helper() {
planfile=$1
[ -r "${planfile}" ] || die "netboot helper: cannot read plan ${planfile}"
+ need_cmd python3
invoker=${SUDO_UID:-$(id -u)}
mkdir -p "${NETBOOT_STATE_DIR}"
@@ -1351,6 +1368,12 @@ netboot_helper() {
kill "$(cat ${NETBOOT_STATE_DIR}/dnsmasq.pid)" 2>/dev/null || true
rm -f "${NETBOOT_STATE_DIR}/dnsmasq.pid"
fi
+ if [ -s "${NETBOOT_STATE_DIR}/httpd.pids" ]; then
+ while read pid; do
+ kill "${pid}" 2>/dev/null || true
+ done < "${NETBOOT_STATE_DIR}/httpd.pids"
+ fi
+ : > "${NETBOOT_STATE_DIR}/httpd.pids"
for vmnet in $(ifconfig -g boot-test 2>/dev/null); do
ifconfig "${vmnet}" destroy
done
@@ -1381,6 +1404,16 @@ EOF
ifconfig "${vmnet}" inet "${gw}/${prefix}" up
chown "${invoker}" "/dev/${vmnet}"
+ # One http.server per subnet, bound only to that subnet's own gw
+ # address (not 0.0.0.0), so concurrently-running tests never collide
+ # on port 80. Serves the exact same tree as dnsmasq's tftp-root above
+ # -- http:// and tftp:// fetches of the same path see identical bytes.
+ # Harmless for tests that never issue an http:// fetch; only
+ # netboot-http-efi actually relies on it today.
+ python3 -m http.server 80 --bind "${gw}" --directory "${tftpdir}" \
+ > "${NETBOOT_STATE_DIR}/httpd-${vmnet}.log" 2>&1 &
+ echo $! >> "${NETBOOT_STATE_DIR}/httpd.pids"
+
# dnsmasq's dhcp-boot only sets DHCP option 67 (bootfile-name), never
# the classic fixed-length BOOTP "file" field -- confirmed by comparing
# against QEMU's own slirp DHCP server, which sets that field directly
@@ -1417,7 +1450,8 @@ EOF
md5 -q "${planfile}" > "${NETBOOT_STATE_DIR}/state.hash"
chown "${invoker}" "${NETBOOT_STATE_DIR}" "${conf}" "${planfile}" \
- "${NETBOOT_STATE_DIR}/dnsmasq.pid" "${NETBOOT_STATE_DIR}/state.hash"
+ "${NETBOOT_STATE_DIR}/dnsmasq.pid" "${NETBOOT_STATE_DIR}/state.hash" \
+ "${NETBOOT_STATE_DIR}"/httpd.pids "${NETBOOT_STATE_DIR}"/httpd-*.log
}
# Manual cleanup: `sudo sh boot-test.sh --netboot-teardown`. Not run
@@ -1427,6 +1461,11 @@ netboot_teardown() {
if [ -s "${NETBOOT_STATE_DIR}/dnsmasq.pid" ]; then
kill "$(cat ${NETBOOT_STATE_DIR}/dnsmasq.pid)" 2>/dev/null || true
fi
+ if [ -s "${NETBOOT_STATE_DIR}/httpd.pids" ]; then
+ while read pid; do
+ kill "${pid}" 2>/dev/null || true
+ done < "${NETBOOT_STATE_DIR}/httpd.pids"
+ fi
for vmnet in $(ifconfig -g boot-test 2>/dev/null); do
ifconfig "${vmnet}" destroy
done
diff --git a/tools/boot/boot-test.sh.8 b/tools/boot/boot-test.sh.8
index dda97cc5d71d..69c1e705d444 100644
--- a/tools/boot/boot-test.sh.8
+++ b/tools/boot/boot-test.sh.8
@@ -1,7 +1,7 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
-.Dd July 5, 2026
+.Dd September 24, 2026
.Dt BOOT-TEST.SH 8
.Os
.Sh NAME
@@ -215,13 +215,28 @@ invokes
once to create the interfaces
.Pq chowning the resulting device nodes back to the invoking user
and start
-.Xr dnsmasq 8 .
+.Xr dnsmasq 8
+plus, on every one of those private
+.Li /30 Ns s ,
+a
+.Xr python3 1
+.Cm http.server
+bound to that subnet's gateway address and serving the same tree as
+.Xr dnsmasq 8 Ns 's
+tftp-root.
+.Ar netboot-http-efi
+forces its root device to an http:// URL and fetches its kernel and
+modules over that server via the loader's own
+.Dq Li http://host/path
+support rather than TFTP; every other netboot test simply ignores it.
Because the interfaces persist until explicitly destroyed,
.Nm
-leaves them and
-.Xr dnsmasq 8
-running afterward; subsequent runs detect the existing setup by comparing a
-hash of the intended configuration and skip
+leaves them,
+.Xr dnsmasq 8 ,
+and the
+.Xr python3 1
+servers running afterward; subsequent runs detect the existing setup by
+comparing a hash of the intended configuration and skip
.Xr sudo 8
entirely, so the prompt is normally seen once per boot rather than once per
run.
@@ -245,10 +260,11 @@ from the base system, and the
.Xr jq 1 ,
.Xr expect 1 ,
.Xr qemu 1 ,
+.Xr dnsmasq 8 ,
and
-.Xr dnsmasq 8
+.Xr python3 1
packages
-.Pq Pa textproc/jq , Pa lang/expect , Pa emulators/qemu , Pa dns/dnsmasq .
+.Pq Pa textproc/jq , Pa lang/expect , Pa emulators/qemu , Pa dns/dnsmasq , Pa lang/python3 .
The network boot tests additionally require the
.Pa sysutils/ipxe
and