Splux Linux

source-based Linux using SPS

SPS · log · files · refs · tags · releases · people · languages · GitHub · commit

e8ae382


mkiso: give the live image a real DNS resolver

Date
Commite8ae382f0fda9f481b104cb8c1e0783db84341d1
GitHubmirror

Parents

Stat

 Makefile                |  4 ++--
 bin/mkiso               | 29 +++++++++++++++++++++++++-
 lib/mkiso/live-bins     |  2 ++
 lib/mkiso/live-rc       | 54 ++++++++++++++++++++++++++++++++++++++++---------
 lib/mkiso/udhcpc-script | 46 +++++++++++++++++++++++++++++++++++++++++
 tests/test_mkiso.sh     | 18 +++++++++++++++++
 6 files changed, 140 insertions(+), 13 deletions(-)

Diff

diff --git a/Makefile b/Makefile
index bc01a7d..87f5abe 100644
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,7 @@ lint:
 		$(POSIX_SHELL) -n $$library; \
 	done
 	@set -e; for script in lib/mkiso/initrd-init lib/mkiso/live-rc \
-		lib/mkiso/live-plasma lib/mkiso/live-init; do \
+		lib/mkiso/live-plasma lib/mkiso/live-init lib/mkiso/udhcpc-script; do \
 		[ -f $$script ] || continue; \
 		$(POSIX_SHELL) -n $$script; \
 	done
@@ -173,7 +173,7 @@ install:
 	@set -e; for f in lib/mkiso/*; do \
 		[ -f "$$f" ] || continue; \
 		case $$f in \
-			*/live-init|*/initrd-init|*/live-rc|*/live-plasma) \
+			*/live-init|*/initrd-init|*/live-rc|*/live-plasma|*/udhcpc-script) \
 				install -m 0755 $$f "$(DESTDIR)$(LIBDIR)/mkiso/" ;; \
 			*) \
 				install -m 0644 $$f "$(DESTDIR)$(LIBDIR)/mkiso/" ;; \
diff --git a/bin/mkiso b/bin/mkiso
index 4954f7a..d92ee69 100755
--- a/bin/mkiso
+++ b/bin/mkiso
@@ -716,6 +716,32 @@ printf '%s\n' \
 	'input:x:71:root' \
 	'render:x:107:root' \
 	>"$mkiso_live/etc/group"
+printf '%s\n' \
+	'127.0.0.1 localhost splux-live' \
+	'::1 localhost splux-live' \
+	>"$mkiso_live/etc/hosts"
+# Do not copy the host nsswitch.conf: this builder uses mdns modules the
+# live disc does not ship. Without a file, glibc still looks at 127.0.0.1
+# when resolv.conf is missing, so live DNS looks like it "does not exist".
+printf '%s\n' \
+	'passwd: files' \
+	'group: files' \
+	'shadow: files' \
+	'hosts: files dns' \
+	'networks: files' \
+	'protocols: files' \
+	'services: files' \
+	'ethers: files' \
+	'rpc: files' \
+	>"$mkiso_live/etc/nsswitch.conf"
+printf '%s\n' \
+	'nameserver 1.1.1.1' \
+	'nameserver 8.8.8.8' \
+	>"$mkiso_live/etc/resolv.conf"
+if [ -f "$mkiso_libdir/udhcpc-script" ]; then
+	install -m 0755 "$mkiso_libdir/udhcpc-script" \
+		"$mkiso_live/etc/sps/udhcpc-script"
+fi
 # Empty password on the live console only.
 printf '%s\n' 'root::0:0:99999:7:::' >"$mkiso_live/etc/shadow"
 chmod 600 "$mkiso_live/etc/shadow"
@@ -767,7 +793,8 @@ if [ -f "$mkiso_libdir/live-bins" ]; then
 fi
 printf '%s: copying disk tools for setup\n' "$sps_prog" >&2
 for mkiso_cmd in lsblk blkid sfdisk cfdisk fdisk wipefs mkfs.ext4 mke2fs \
-	mkfs.vfat mkswap partprobe udevadm udevd grub-install grub-mkconfig
+	mkfs.vfat mkswap partprobe udevadm udevd grub-install grub-mkconfig \
+	dhcpcd
 do
 	mkiso_copy_host_cmd "$mkiso_cmd" || :
 done
diff --git a/lib/mkiso/live-bins b/lib/mkiso/live-bins
index 598b953..92b2375 100644
--- a/lib/mkiso/live-bins
+++ b/lib/mkiso/live-bins
@@ -30,3 +30,5 @@
 /usr/sbin/mkswap
 /sbin/partprobe
 /usr/sbin/partprobe
+/sbin/dhcpcd
+/usr/sbin/dhcpcd
diff --git a/lib/mkiso/live-rc b/lib/mkiso/live-rc
index d33e1c5..10883dc 100644
--- a/lib/mkiso/live-rc
+++ b/lib/mkiso/live-rc
@@ -71,16 +71,7 @@ do
 	modprobe "$mod" 2>/dev/null || :
 done
 
-if command -v ip >/dev/null 2>&1; then
-	ip link set lo up 2>/dev/null || :
-fi
-if command -v dhcpcd >/dev/null 2>&1; then
-	dhcpcd -b 2>/dev/null || :
-elif command -v dhclient >/dev/null 2>&1; then
-	dhclient -nw 2>/dev/null || :
-fi
-
-# udev if present (eudev or systemd-udevd).
+# udev first so virtio_net and friends have device nodes before DHCP.
 if command -v udevd >/dev/null 2>&1; then
 	udevd --daemon 2>/dev/null || :
 	udevadm trigger --action=add 2>/dev/null || :
@@ -91,6 +82,49 @@ elif [ -x /lib/systemd/systemd-udevd ]; then
 	udevadm settle --timeout=5 2>/dev/null || :
 fi
 
+if command -v ip >/dev/null 2>&1; then
+	ip link set lo up 2>/dev/null || :
+	for sps_netif in /sys/class/net/*; do
+		sps_if=${sps_netif##*/}
+		[ "$sps_if" = lo ] && continue
+		ip link set "$sps_if" up 2>/dev/null || :
+	done
+fi
+# A host resolv.conf symlink to systemd-resolved would leave libc talking
+# to 127.0.0.53 with no daemon. Keep a real file; DHCP may overwrite it.
+if [ -L /etc/resolv.conf ]; then
+	rm -f /etc/resolv.conf
+fi
+if [ ! -s /etc/resolv.conf ] || ! grep -q '^nameserver ' /etc/resolv.conf
+then
+	printf '%s\n' 'nameserver 1.1.1.1' 'nameserver 8.8.8.8' \
+		>/etc/resolv.conf
+fi
+if [ ! -s /etc/nsswitch.conf ]; then
+	printf '%s\n' 'passwd: files' 'group: files' 'shadow: files' \
+		'hosts: files dns' 'networks: files' 'protocols: files' \
+		'services: files' >/etc/nsswitch.conf
+fi
+mkdir -p /var/lib/dhcpcd /var/db /run/dhcpcd
+if command -v dhcpcd >/dev/null 2>&1; then
+	dhcpcd -b 2>/dev/null || :
+elif command -v udhcpc >/dev/null 2>&1; then
+	sps_udhcp_script=/etc/sps/udhcpc-script
+	for sps_netif in /sys/class/net/*; do
+		sps_if=${sps_netif##*/}
+		[ "$sps_if" = lo ] && continue
+		if [ -x "$sps_udhcp_script" ]; then
+			udhcpc -i "$sps_if" -s "$sps_udhcp_script" -b \
+				-p /run/udhcpc."$sps_if".pid 2>/dev/null || :
+		else
+			udhcpc -i "$sps_if" -b \
+				-p /run/udhcpc."$sps_if".pid 2>/dev/null || :
+		fi
+	done
+elif command -v dhclient >/dev/null 2>&1; then
+	dhclient -nw 2>/dev/null || :
+fi
+
 # System bus before Plasma. Always rewrite system-local.conf: a copied
 # host file would otherwise keep <user>messagebus</user>.
 mkdir -p /run/dbus /var/lib/dbus /etc/dbus-1
diff --git a/lib/mkiso/udhcpc-script b/lib/mkiso/udhcpc-script
new file mode 100644
index 0000000..f10ac5f
--- /dev/null
+++ b/lib/mkiso/udhcpc-script
@@ -0,0 +1,46 @@
+#!/bin/busybox sh
+# Busybox udhcpc hook for the live image. dhcpcd is preferred; this is
+# the slim-disc fallback so a lease still writes nameservers.
+
+resolv=/etc/resolv.conf
+
+case $1 in
+	deconfig)
+		if command -v ip >/dev/null 2>&1; then
+			ip addr flush dev "$interface" 2>/dev/null || :
+			ip link set "$interface" up 2>/dev/null || :
+		fi
+		;;
+	bound|renew)
+		if command -v ip >/dev/null 2>&1; then
+			ip link set "$interface" up 2>/dev/null || :
+			ip addr flush dev "$interface" 2>/dev/null || :
+			if [ -n "$ip" ]; then
+				if [ -n "$mask" ]; then
+					ip addr add "$ip/$mask" \
+						${broadcast:+broadcast $broadcast} \
+						dev "$interface" 2>/dev/null || :
+				else
+					ip addr add "$ip" \
+						${broadcast:+broadcast $broadcast} \
+						dev "$interface" 2>/dev/null || :
+				fi
+			fi
+			if [ -n "$router" ]; then
+				for gw in $router; do
+					ip route replace default via "$gw" \
+						dev "$interface" 2>/dev/null || :
+					break
+				done
+			fi
+		fi
+		if [ -n "$dns" ]; then
+			: >"$resolv"
+			[ -n "$domain" ] && printf 'search %s\n' "$domain" >>"$resolv"
+			for ns in $dns; do
+				printf 'nameserver %s\n' "$ns" >>"$resolv"
+			done
+		fi
+		;;
+esac
+exit 0
diff --git a/tests/test_mkiso.sh b/tests/test_mkiso.sh
index d15220d..0a44c80 100755
--- a/tests/test_mkiso.sh
+++ b/tests/test_mkiso.sh
@@ -118,6 +118,24 @@ grep -q libgallium "$mkiso" ||
 	fail 'plasma ISO must copy Mesa libgallium'
 grep -q 'video:x:18:root' "$layout/etc/group" ||
 	fail 'live group must include video for seatd/DRM'
+grep -q 'hosts: files dns' "$layout/etc/nsswitch.conf" ||
+	fail 'live nsswitch must use files+dns (not host mdns)'
+grep -q 'nameserver 1.1.1.1' "$layout/etc/resolv.conf" ||
+	fail 'live resolv.conf must ship a fallback nameserver'
+grep -q localhost "$layout/etc/hosts" || fail 'live /etc/hosts missing localhost'
+grep -q dhcpcd "$project_dir/lib/mkiso/live-bins" ||
+	fail 'live-bins must include dhcpcd so slim images get a DHCP client'
+[ -x "$layout/etc/sps/udhcpc-script" ] ||
+	fail 'live udhcpc-script missing'
+grep -q 'udevd --daemon' "$layout/etc/sps/live-rc" ||
+	fail 'live-rc must start udev'
+# DHCP must not run before udev; virtio_net has no name yet.
+live_rc=$layout/etc/sps/live-rc
+udev_line=$(grep -n 'udevd --daemon' "$live_rc" | head -1 | cut -d: -f1)
+dhcp_line=$(grep -n 'dhcpcd -b' "$live_rc" | head -1 | cut -d: -f1)
+[ -n "$udev_line" ] && [ -n "$dhcp_line" ] &&
+	[ "$udev_line" -lt "$dhcp_line" ] ||
+	fail 'live-rc must start udev before dhcpcd'
 grep -q kwin_wayland_wrapper "$project_dir/lib/mkiso/plasma-bins" ||
 	fail 'plasma-bins must include kwin_wayland_wrapper'
 grep -q xdg-permission-store "$project_dir/lib/mkiso/plasma-bins" ||