git: c994f226bbd3 - main - bsdinstall: Add new Auto option to netconfig interface selection dialog

From: Jessica Clarke <jrtc27_at_FreeBSD.org>
Date: Fri, 09 Feb 2024 18:25:33 UTC
The branch main has been updated by jrtc27:

URL: https://cgit.FreeBSD.org/src/commit/?id=c994f226bbd3c0762e3c642515fef5f9d5589493

commit c994f226bbd3c0762e3c642515fef5f9d5589493
Author:     Jessica Clarke <jrtc27@FreeBSD.org>
AuthorDate: 2024-02-09 18:13:47 +0000
Commit:     Jessica Clarke <jrtc27@FreeBSD.org>
CommitDate: 2024-02-09 18:13:47 +0000

    bsdinstall: Add new Auto option to netconfig interface selection dialog
    
    This changes the OK / Cancel buttons into Auto / Manual / Cancel, with
    Auto being the default. Manual behaves like OK used to, i.e. presents a
    series of dialogs asking exactly how to configure the interface, and
    Cancel is unchanged, exiting with exit code 1. Auto will attempt to
    configure IPv4+DHCP and IPv6+SLAAC with no interaction, failing only if
    neither can be configured, thereby supporting all of IPv4-only,
    IPv6-only and dual-stack environments. If at least one DNS server is
    provided, it will also skip asking for DNS settings, otherwise it will
    act like Manual mode for the purposes of DNS settings and prompt. For a
    standard dual-stack environment this cuts down the number of netconfig
    dialogs from 6 (interface, IPv4, DHCP, IPv6, SLAAC, DNS) to just the
    first one.
    
    Reviewed by:    brooks
    Differential Revision:  https://reviews.freebsd.org/D43731
---
 usr.sbin/bsdinstall/scripts/netconfig      | 77 +++++++++++++++++++++++-------
 usr.sbin/bsdinstall/scripts/netconfig_ipv4 | 26 +++++++++-
 usr.sbin/bsdinstall/scripts/netconfig_ipv6 | 30 ++++++++++--
 3 files changed, 109 insertions(+), 24 deletions(-)

diff --git a/usr.sbin/bsdinstall/scripts/netconfig b/usr.sbin/bsdinstall/scripts/netconfig
index 77b71867eb4a..130db2937234 100755
--- a/usr.sbin/bsdinstall/scripts/netconfig
+++ b/usr.sbin/bsdinstall/scripts/netconfig
@@ -73,8 +73,21 @@ if [ -z "$INTERFACES" ]; then
 fi
 
 exec 5>&1
-INTERFACE=`echo $BSDDIALOG_ITEMS | xargs -o bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' --menu 'Please select a network interface to configure:' 0 0 0 2>&1 1>&5`
-if [ $? -eq $BSDDIALOG_CANCEL ]; then exit 1; fi
+INTERFACE=$(echo $BSDDIALOG_ITEMS | xargs -o bsddialog \
+    --backtitle "$OSNAME Installer" --title 'Network Configuration' \
+    --ok-label 'Auto' --extra-button --extra-label 'Manual' \
+    --menu 'Please select a network interface to configure:' 0 0 0 2>&1 1>&5)
+# xargs collapses exit codes to 0/1 (ignoring signals and 255), so exploit
+# bsddialog output being empty when cancelling to distinguish Manual (Extra)
+# from Cancel.
+if [ $? -eq $BSDDIALOG_OK ]; then
+	AUTO=auto
+else
+	if [ -z "$INTERFACE" ]; then
+		exit 1
+	fi
+	AUTO=
+fi
 exec 5>&-
 
 : > $BSDINSTALL_TMPETC/._rc.conf.net
@@ -103,30 +116,46 @@ case $? in
 0)	IPV4_AVAIL=1 ;;
 esac
 
-if [ ${IPV4_AVAIL} -eq 1 ]; then
+AUTO_FAIL=
+if [ ${IPV4_AVAIL} -eq 1 -a -z "$AUTO" ]; then
 	bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' \
 	    --yesno 'Would you like to configure IPv4 for this interface?' 0 0
-	if [ $? -eq $BSDDIALOG_OK ]; then
-		bsdinstall netconfig_ipv4 ${INTERFACE} "${IFCONFIG_PREFIX}" || \
-		exec $0
-	else
+	if [ $? -ne $BSDDIALOG_OK ]; then
 		IPV4_AVAIL=0
 	fi
 fi
+if [ ${IPV4_AVAIL} -eq 1 ]; then
+	bsdinstall netconfig_ipv4 ${INTERFACE} "${IFCONFIG_PREFIX}" $AUTO
+	if [ $? -ne $BSDDIALOG_OK ]; then
+		if [ -z "$AUTO" ]; then
+			exec $0
+		fi
+		IPV4_AVAIL=0
+		AUTO_FAIL="$AUTO_FAIL${AUTO_FAIL:+, }IPv4"
+	fi
+fi
 # In case wlanconfig left an option and we do not support IPv4 we need to write
 # it out on its own.  We cannot write it out with IPv6 as that suffix.
 if [ ${IPV4_AVAIL} -eq 0 -a -n ${IFCONFIG_PREFIX} ]; then
 	sysrc -f $BSDINSTALL_TMPETC/._rc.conf.net ifconfig_$INTERFACE="${IFCONFIG_PREFIX}"
 fi
-if [ ${IPV6_AVAIL} -eq 1 ]; then
+if [ ${IPV6_AVAIL} -eq 1 -a -z "$AUTO" ]; then
 	bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' \
 	    --yesno 'Would you like to configure IPv6 for this interface?' 0 0
-	if [ $? -eq $BSDDIALOG_OK ]; then
-		bsdinstall netconfig_ipv6 ${INTERFACE} || exec $0
-	else
+	if [ $? -ne $BSDDIALOG_OK ]; then
 		IPV6_AVAIL=0
 	fi
 fi
+if [ ${IPV6_AVAIL} -eq 1 ]; then
+	bsdinstall netconfig_ipv6 ${INTERFACE} $AUTO
+	if [ $? -ne $BSDDIALOG_OK ]; then
+		if [ -z "$AUTO" ]; then
+			exec $0
+		fi
+		IPV6_AVAIL=0
+		AUTO_FAIL="$AUTO_FAIL${AUTO_FAIL:+, }IPv6"
+	fi
+fi
 
 SEARCH=""
 IP4_1=""
@@ -180,16 +209,28 @@ elif [ ${IPV4_AVAIL} -eq 1 ]; then
 	    'IPv4 DNS #1' 2 1 \"${IP4_1}\" 2 16 16 16 0
 	    'IPv4 DNS #2' 3 1 \"${IP4_2}\" 3 16 16 16 0"
 else
+	if [ -n "$AUTO_FAIL" ]; then
+		bsddialog --backtitle "$OSNAME Installer" \
+		    --msgbox "Failed to automatically configure interface (tried $AUTO_FAIL)." 0 0
+		exec $0
+	fi
 	exit 0
 fi
 
-exec 5>&1
-RESOLV=$(echo "${RESOLV}" | xargs -o bsddialog --backtitle "$OSNAME Installer" \
-	--title 'Network Configuration' \
-	--mixedform 'Resolver Configuration' 0 0 0 \
-2>&1 1>&5)
-if [ $? -eq $BSDDIALOG_CANCEL ]; then exec $0; fi
-exec 5>&-
+# Auto only guaranteed to have IPv4 and/or IPv6 address; may not have
+# nameserver available
+if [ -n "$AUTO" ] && [ -n "${IP4_1}" -o -n "${IP6_1}" ]; then
+	# Convert from bsddialog arguments to default output
+	RESOLV=$(echo "${RESOLV}" | xargs -n9 sh -c 'echo "$4"' '')
+else
+	exec 5>&1
+	RESOLV=$(echo "${RESOLV}" | xargs -o bsddialog --backtitle "$OSNAME Installer" \
+		--title 'Network Configuration' \
+		--mixedform 'Resolver Configuration' 0 0 0 \
+	2>&1 1>&5)
+	if [ $? -eq $BSDDIALOG_CANCEL ]; then exec $0; fi
+	exec 5>&-
+fi
 
 echo ${RESOLV} | tr ' ' '\n' | \
 awk '
diff --git a/usr.sbin/bsdinstall/scripts/netconfig_ipv4 b/usr.sbin/bsdinstall/scripts/netconfig_ipv4
index 8f747a9d0162..7e3669f697d9 100755
--- a/usr.sbin/bsdinstall/scripts/netconfig_ipv4
+++ b/usr.sbin/bsdinstall/scripts/netconfig_ipv4
@@ -40,6 +40,7 @@ f_include $BSDCFG_SHARE/dialog.subr
 
 INTERFACE=$1
 IFCONFIG_PREFIX="$2"
+AUTO="${3:-}"
 test -z "$IFCONFIG_PREFIX" || IFCONFIG_PREFIX="$2 "
 case "${INTERFACE}" in
 "")	bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' \
@@ -47,9 +48,27 @@ case "${INTERFACE}" in
 	exit 1
 	;;
 esac
+case "$AUTO" in
+""|auto)
+	;;
+*)
+	bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' \
+	    --msgbox "Bad auto option '$AUTO'." 0 0
+	exit 1
+	;;
+esac
 
-bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' --yesno 'Would you like to use DHCP to configure this interface?' 0 0
-if [ $? -eq $BSDDIALOG_OK ]; then
+if [ -n "$AUTO" ]; then
+	DHCP=1
+else
+	bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' --yesno 'Would you like to use DHCP to configure this interface?' 0 0
+	if [ $? -eq $BSDDIALOG_OK ]; then
+		DHCP=1
+	else
+		DHCP=0
+	fi
+fi
+if [ $DHCP -eq 1 ]; then
 	if [ ! -z $BSDINSTALL_CONFIGCURRENT ]; then
 		# XXX: get interface down otherwise after installation restart
 		# dhclient does not build a new resolv.conf (see PR262262).
@@ -59,6 +78,9 @@ if [ $? -eq $BSDDIALOG_OK ]; then
 		err=$( pkill -F /var/run/dhclient/dhclient.${INTERFACE}.pid; dhclient $INTERFACE 2>&1 )
 		if [ $? -ne 0 ]; then
 			f_dprintf "%s" "$err"
+			if [ -n "$AUTO" ]; then
+				exit 1
+			fi
 			bsddialog --backtitle "$OSNAME Installer" --msgbox "DHCP lease acquisition failed." 0 0
 			exec $0 ${INTERFACE} "${IFCONFIG_PREFIX}"
 		fi
diff --git a/usr.sbin/bsdinstall/scripts/netconfig_ipv6 b/usr.sbin/bsdinstall/scripts/netconfig_ipv6
index b851069eee14..d60a3014ccc4 100755
--- a/usr.sbin/bsdinstall/scripts/netconfig_ipv6
+++ b/usr.sbin/bsdinstall/scripts/netconfig_ipv6
@@ -48,19 +48,38 @@ f_include $BSDCFG_SHARE/dialog.subr
 #
 
 INTERFACE=$1
+AUTO="${2:-}"
 case "${INTERFACE}" in
 "")	bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' \
 	    --msgbox 'No interface specified for IPv6 configuration.' 0 0
 	exit 1
 	;;
 esac
+case "$AUTO" in
+""|auto)
+	;;
+*)
+	bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' \
+	    --msgbox "Bad auto option '$AUTO'." 0 0
+	exit 1
+	;;
+esac
 
 AGAIN=""
 while : ; do
-	MSG="Would you like to try stateless address autoconfiguration (SLAAC)${AGAIN}?"
-	bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' \
-	    --yesno "${MSG}" 0 0
-	if [ $? -eq $BSDDIALOG_OK ]; then
+	if [ -n "$AUTO" ]; then
+		SLAAC=1
+	else
+		MSG="Would you like to try stateless address autoconfiguration (SLAAC)${AGAIN}?"
+		bsddialog --backtitle "$OSNAME Installer" --title 'Network Configuration' \
+		    --yesno "${MSG}" 0 0
+		if [ $? -eq $BSDDIALOG_OK ]; then
+			SLAAC=1
+		else
+			SLAAC=0
+		fi
+	fi
+	if [ $SLAAC -eq 1 ]; then
 		if [ ! -z $BSDINSTALL_CONFIGCURRENT ]; then
 			bsddialog --backtitle "$OSNAME Installer" \
 			    --infobox "Sending Router Solicitation ..." 0 0
@@ -68,6 +87,9 @@ while : ; do
 			err=$( rtsol -F $INTERFACE 2>&1 )
 			if [ $? -ne 0 ]; then
 				f_dprintf "%s" "$err"
+				if [ -n "$AUTO" ]; then
+					exit 1
+				fi
 				bsddialog --backtitle "$OSNAME Installer" --msgbox "SLAAC failed." 0 0
 				AGAIN=" again"
 				continue