From 06a4e8abb24615446abb05b0215ccdee8e0f9009 Mon Sep 17 00:00:00 2001 From: Vid Smole Date: Tue, 14 Jul 2026 11:37:06 +0200 Subject: [PATCH 1/9] Create a menu based network config --- subscripts/4Network/2Configure_networking.sh | 663 ++++++++++++++----- 1 file changed, 498 insertions(+), 165 deletions(-) diff --git a/subscripts/4Network/2Configure_networking.sh b/subscripts/4Network/2Configure_networking.sh index 0d424f2..a9bbc4b 100755 --- a/subscripts/4Network/2Configure_networking.sh +++ b/subscripts/4Network/2Configure_networking.sh @@ -1,61 +1,50 @@ #!/bin/bash -yesno_def_no() { - whiptail --title "Network Config" --yesno "$1" --yes-button "No" --no-button "Yes" 0 0 - ret_val=$? +set -u - if [ $ret_val -eq 255 ]; then - exit 1 - elif [ $ret_val -eq 1 ]; then - # echo "User hit Yes" - return 1 - elif [ $ret_val -eq 0 ]; then - # echo "User hit No" - return 0 - else - echo "Error state" - fi -} +TITLE="Network Config" +FILENAME="/tmp/01-netcfg.yaml" yesno_def_yes() { - whiptail --title "Network Config" --yesno "$1" 0 0 + whiptail --title "$TITLE" --yesno "$1" 0 0 ret_val=$? - if [ $ret_val -eq 255 ]; then + if [ "$ret_val" -eq 255 ]; then exit 1 - elif [ $ret_val -eq 0 ]; then - # echo "User hit Yes" - return 1 - elif [ $ret_val -eq 1 ]; then - # echo "User hit No" - return 0 + elif [ "$ret_val" -eq 0 ]; then + return 1 # user selected Yes + elif [ "$ret_val" -eq 1 ]; then + return 0 # user selected No else echo "Error state" + exit 1 fi } input_box() { - tmp=$(whiptail --inputbox "$1" 0 0 "$2" 3>&1 1>&2 2>&3) + local prompt="$1" + local default_value="${2:-}" + + local tmp + tmp=$(whiptail --title "$TITLE" --inputbox "$prompt" 0 0 "$default_value" 3>&1 1>&2 2>&3) + ret_val=$? - if [ $ret_val -eq 255 ]; then - # User hit Escape + if [ "$ret_val" -eq 255 ]; then exit 1 - elif [ $ret_val -eq 1 ]; then - # User hit Cancel + elif [ "$ret_val" -eq 1 ]; then exit 1 - elif [ $ret_val -eq 0 ]; then - # valid input - printf '%s\n' "$tmp" # this outputs the user input so callers can capture it (e.g. foo=$(input_box ...) + elif [ "$ret_val" -eq 0 ]; then + printf '%s\n' "$tmp" return 0 else echo "Error state" - exit 0 + exit 1 fi } error_msg() { - whiptail --title "Network config" --msgbox "$1" 0 0 + whiptail --title "$TITLE" --msgbox "$1" 0 0 } enable_systemd_networkd() { @@ -64,183 +53,527 @@ enable_systemd_networkd() { } disable_network_manager() { - sudo systemctl disable --now NetworkManager NetworkManager-wait-online NetworkManager-dispatcher - sudo systemctl mask NetworkManager NetworkManager-wait-online NetworkManager-dispatcher + sudo systemctl disable --now NetworkManager NetworkManager-wait-online NetworkManager-dispatcher 2>/dev/null || true + sudo systemctl mask NetworkManager NetworkManager-wait-online NetworkManager-dispatcher 2>/dev/null || true +} + +is_wifi_interface() { + local int="$1" + [[ "$int" =~ ^wlan[0-9]+$ ]] } -# If netplan is not installed, install it -if ! command -v netplan &>/dev/null; then - echo "Netplan not found, installing..." - sudo apt update && sudo apt install -y netplan.io -fi +is_ethernet_interface() { + local int="$1" + [[ "$int" =~ ^eth[0-9]+$ ]] +} -if [[ "$NON_INTERACTIVE_MODE" -ne 1 ]]; then - yesno_def_yes "This script will configure networking on the device. Systemd-networkd will be used as the backend for netplan and NetworkManager will be disabled. If you're connected via SSH you may lose connection when applying. Do you want to continue?" - ret_val=$? - if [ $ret_val -eq 1 ]; then - echo "Continuing with network config..." - elif [ $ret_val -eq 0 ]; then - echo "Aborting network config..." - exit 0 +get_default_ip_for_interface() { + local int="$1" + + if is_wifi_interface "$int"; then + if [[ "${USE_DEFAULTS_FOR:-}" == "F4F" ]]; then + echo "192.168.12.101" + else + echo "192.168.69.101" + fi + else + echo "10.10.20.101" fi -fi +} -if [[ "$NON_INTERACTIVE_MODE" -ne 1 ]]; then - yesno_def_yes "Delete all previous netplan configs? (Recommended)" - ret_val=$? - if [ $ret_val -eq 1 ]; then - sudo rm -f /etc/netplan/*.yaml +get_default_gateway_for_interface() { + local int="$1" + + if is_wifi_interface "$int"; then + if [[ "${USE_DEFAULTS_FOR:-}" == "F4F" ]]; then + echo "192.168.12.1" + else + echo "192.168.69.1" + fi + else + echo "10.10.20.1" fi -else - # Non-interactive mode handling - if [ "${NETWORKING_DELETE_PREVIOUS_NETPLAN_CONFIGS:-}" = "true" ]; then - echo "removing previous netplan configs" - sudo rm -f /etc/netplan/*.yaml +} + +get_default_ssid() { + if [[ "${USE_DEFAULTS_FOR:-}" == "F4F" ]]; then + echo "f4f_robot" else - echo "keeping previous netplan configs" + echo "mrs_ctu" fi -fi +} + +get_default_wifi_password() { + echo "mikrokopter" +} + +init_interface_defaults() { + local int="$1" -FILENAME=/tmp/01-netcfg.yaml -rm -f -- "$FILENAME" -touch -- "$FILENAME" + CFG_ENABLED["$int"]="yes" + CFG_DHCP4["$int"]="yes" + CFG_ADDRESS["$int"]="$(get_default_ip_for_interface "$int")" + CFG_PREFIX["$int"]="24" + CFG_GATEWAY["$int"]="$(get_default_gateway_for_interface "$int")" + CFG_DNS["$int"]="8.8.8.8" + + if is_wifi_interface "$int"; then + CFG_TYPE["$int"]="wifi" + CFG_SSID["$int"]="$(get_default_ssid)" + CFG_PASSWORD["$int"]="$(get_default_wifi_password)" + else + CFG_TYPE["$int"]="ethernet" + CFG_SSID["$int"]="" + CFG_PASSWORD["$int"]="" + fi +} -if [[ "$NON_INTERACTIVE_MODE" -ne 1 ]]; then - echo "network:" >>"$FILENAME" - echo " version: 2" >>"$FILENAME" - echo " renderer: networkd" >>"$FILENAME" +interface_summary() { + local int="$1" + local enabled="${CFG_ENABLED[$int]}" + local dhcp="${CFG_DHCP4[$int]}" - eths=$(ls /sys/class/net | grep -E '^eth') - wlans=$(ls /sys/class/net | grep -E '^wlan') + if [ "$enabled" != "yes" ]; then + echo "disabled" + return + fi - if [ -z "${eths}" ]; then - error_msg "No Ethernet interfaces found! (looking for eth0, eth1 ...).\nYour Ethernet interfaces may have different names, run the Network Interface Names Fix first and then restart.\n\n\n Continuing with Wi-Fi config. " + if [ "$dhcp" = "yes" ]; then + echo "DHCP" else - echo " ethernets:" >>/tmp/01-netcfg.yaml + echo "static ${CFG_ADDRESS[$int]}/${CFG_PREFIX[$int]}" + fi +} + +edit_interface_menu() { + local int="$1" - for int in ${eths}; do - echo " $int:" >>/tmp/01-netcfg.yaml + while true; do + local type="${CFG_TYPE[$int]}" + local menu_text - yesno_def_no "Do you want to use DHCP on $int?" - ret_val=$? + menu_text="Interface: $int - if [ $ret_val -eq 1 ]; then - echo " dhcp4: yes" >>/tmp/01-netcfg.yaml - echo " dhcp6: no" >>/tmp/01-netcfg.yaml - elif [ $ret_val -eq 0 ]; then - echo " dhcp4: no" >>/tmp/01-netcfg.yaml - echo " dhcp6: no" >>/tmp/01-netcfg.yaml +Current summary: +$(interface_summary "$int") - address=$(input_box "Enter your static IP address for $int:" "10.10.20.101") - echo " addresses: [$address/24]" >>/tmp/01-netcfg.yaml +Choose option to edit:" - gateway=$(input_box "Enter your default gateway address for $int:" "10.10.20.1") - echo " routes:" >>/tmp/01-netcfg.yaml - echo " - to: default" >>/tmp/01-netcfg.yaml - echo " via: $gateway" >>/tmp/01-netcfg.yaml - echo " metric: 200" >>/tmp/01-netcfg.yaml + local menu_items=( + "Enabled" "${CFG_ENABLED[$int]}" + ) - dns=$(input_box "Enter your DNS server address for $int:" "8.8.8.8") - echo " nameservers:" >>/tmp/01-netcfg.yaml - echo " addresses: [$dns]" >>/tmp/01-netcfg.yaml + if [ "${CFG_ENABLED[$int]}" = "yes" ]; then + menu_items+=( + "DHCP IPv4" "${CFG_DHCP4[$int]}" + ) + + if [ "${CFG_DHCP4[$int]}" = "no" ]; then + menu_items+=( + "Static address" "${CFG_ADDRESS[$int]}" + "CIDR prefix" "${CFG_PREFIX[$int]}" + "Default gateway" "${CFG_GATEWAY[$int]}" + "DNS server" "${CFG_DNS[$int]}" + ) fi - done - fi - if [ -z "${wlans}" ]; then - error_msg "No Wlan interfaces found! (looking for wlan0, wlan1 ...).\nYour Wlan interfaces may have different names, run the Network Interface Names Fix first and then restart.\n\n\n" - else - echo " wifis:" >>/tmp/01-netcfg.yaml - - for int in ${wlans}; do - echo " $int:" >>/tmp/01-netcfg.yaml - - yesno_def_no "Do you want to use DHCP on $int?" - dhcp=$? - - if [ $dhcp -eq 1 ]; then - echo " dhcp4: yes" >>/tmp/01-netcfg.yaml - echo " dhcp6: no" >>/tmp/01-netcfg.yaml - elif [ $dhcp -eq 0 ]; then - echo " dhcp4: no" >>/tmp/01-netcfg.yaml - echo " dhcp6: no" >>/tmp/01-netcfg.yaml - - address="" - if [[ $USE_DEFAULTS_FOR == "F4F" ]]; then - address=$(input_box "Enter your static IP address for $int:" "192.168.12.101") - else - address=$(input_box "Enter your static IP address for $int:" "192.168.69.101") - fi - echo " addresses: [$address/24]" >>/tmp/01-netcfg.yaml - - gateway="" - if [[ $USE_DEFAULTS_FOR == "F4F" ]]; then - gateway=$(input_box "Enter your default gateway address:" "192.168.12.1") - else - gateway=$(input_box "Enter your default gateway address:" "192.168.69.1") - fi - echo " routes:" >>/tmp/01-netcfg.yaml - echo " - to: default" >>/tmp/01-netcfg.yaml - echo " via: $gateway" >>/tmp/01-netcfg.yaml - echo " metric: 100" >>/tmp/01-netcfg.yaml + if [ "$type" = "wifi" ]; then + menu_items+=( + "Wi-Fi SSID" "${CFG_SSID[$int]}" + "Wi-Fi password" "${CFG_PASSWORD[$int]}" + ) fi + fi + + local choice + choice=$(whiptail --title "$TITLE - $int" --ok-button "Edit" --cancel-button "Back" --menu "$menu_text" \ + 22 60 10 "${menu_items[@]}" 3>&1 1>&2 2>&3) + ret_val=$? + + case "$ret_val" in + 0) + ;; + 1) + # User pressed Back + return + ;; + + 255) + # Escape + return + ;; + + *) + echo "Error state" + exit 1 + ;; + esac + + case "$choice" in + "Enabled") + yesno_def_yes "Enable interface $int?" + if [ "$?" -eq 1 ]; then + CFG_ENABLED["$int"]="yes" + else + CFG_ENABLED["$int"]="no" + fi + ;; - ap_name="" - if [[ $USE_DEFAULTS_FOR == "F4F" ]]; then - ap_name=$(input_box "Enter your WiFi name (SSID):" "f4f_robot") + "DHCP IPv4") + yesno_def_yes "Use DHCP IPv4 on $int?" + if [ "$?" -eq 1 ]; then + CFG_DHCP4["$int"]="yes" else - ap_name=$(input_box "Enter your WiFi name (SSID):" "mrs_ctu") + CFG_DHCP4["$int"]="no" fi + ;; + + "Static address") + CFG_ADDRESS["$int"]=$(input_box "Enter static IP address for $int:" "${CFG_ADDRESS[$int]}") + CFG_DHCP4["$int"]="no" + ;; + + "CIDR prefix") + CFG_PREFIX["$int"]=$(input_box "Enter CIDR prefix for $int, for example 24:" "${CFG_PREFIX[$int]}") + CFG_DHCP4["$int"]="no" + ;; + + "Default gateway") + CFG_GATEWAY["$int"]=$(input_box "Enter default gateway for $int:" "${CFG_GATEWAY[$int]}") + CFG_DHCP4["$int"]="no" + ;; + + "DNS server") + CFG_DNS["$int"]=$(input_box "Enter DNS server address for $int:" "${CFG_DNS[$int]}") + ;; + + "Wi-Fi SSID") + CFG_SSID["$int"]=$(input_box "Enter Wi-Fi SSID for $int:" "${CFG_SSID[$int]}") + ;; + + "Wi-Fi password") + CFG_PASSWORD["$int"]=$(input_box "Enter Wi-Fi password for $int:" "${CFG_PASSWORD[$int]}") + ;; + esac + done +} + +main_interface_menu() { + while true; do + local menu_items=() - echo " access-points:" >>/tmp/01-netcfg.yaml - echo " \"$ap_name\":" >>/tmp/01-netcfg.yaml + for int in "${INTERFACES[@]}"; do + menu_items+=("$int" "$(interface_summary "$int")") + done - password=$(input_box "Enter your WiFi password:" "mikrokopter") - echo " password: \"$password\"" >>/tmp/01-netcfg.yaml + # Blank separator line + menu_items+=(" " " ") + + menu_items+=("Save/Apply" "Generate netplan and continue") + + local choice + choice=$(whiptail --title "$TITLE" \ + --ok-button "Select" \ + --cancel-button "Cancel" \ + --menu "Select an interface to configure:" \ + 24 60 14 \ + "${menu_items[@]}" \ + 3>&1 1>&2 2>&3) + + ret_val=$? + + case "$ret_val" in + 0) + case "$choice" in + "Save/Apply") + generate_netplan + return + ;; + + " ") # Blank separator line, ignore + continue + ;; + + *) + edit_interface_menu "$choice" + ;; + esac + ;; + *) + echo "Error state" + exit 1 + ;; + esac + done +} - if [ $dhcp -eq 0 ]; then - dns=$(input_box "Enter your DNS server address:" "8.8.8.8") - echo " nameservers:" >>/tmp/01-netcfg.yaml - echo " addresses: [$dns]" >>/tmp/01-netcfg.yaml +generate_netplan() { + rm -f -- "$FILENAME" + + { + echo "network:" + echo " version: 2" + echo " renderer: networkd" + } >>"$FILENAME" + + local has_ethernet="no" + local has_wifi="no" + + for int in "${INTERFACES[@]}"; do + [ "${CFG_ENABLED[$int]}" = "yes" ] || continue + + if [ "${CFG_TYPE[$int]}" = "ethernet" ]; then + has_ethernet="yes" + elif [ "${CFG_TYPE[$int]}" = "wifi" ]; then + has_wifi="yes" + fi + done + + if [ "$has_ethernet" = "yes" ]; then + echo " ethernets:" >>"$FILENAME" + + for int in "${INTERFACES[@]}"; do + [ "${CFG_ENABLED[$int]}" = "yes" ] || continue + [ "${CFG_TYPE[$int]}" = "ethernet" ] || continue + + { + echo " $int:" + echo " dhcp4: ${CFG_DHCP4[$int]}" + echo " dhcp6: no" + } >>"$FILENAME" + + if [ "${CFG_DHCP4[$int]}" = "no" ]; then + { + echo " addresses:" + echo " - ${CFG_ADDRESS[$int]}/${CFG_PREFIX[$int]}" + echo " routes:" + echo " - to: default" + echo " via: ${CFG_GATEWAY[$int]}" + echo " nameservers:" + echo " addresses:" + echo " - ${CFG_DNS[$int]}" + } >>"$FILENAME" fi + done + fi + if [ "$has_wifi" = "yes" ]; then + echo " wifis:" >>"$FILENAME" + + for int in "${INTERFACES[@]}"; do + [ "${CFG_ENABLED[$int]}" = "yes" ] || continue + [ "${CFG_TYPE[$int]}" = "wifi" ] || continue + + { + echo " $int:" + echo " dhcp4: ${CFG_DHCP4[$int]}" + echo " dhcp6: no" + } >>"$FILENAME" + + if [ "${CFG_DHCP4[$int]}" = "no" ]; then + { + echo " addresses:" + echo " - ${CFG_ADDRESS[$int]}/${CFG_PREFIX[$int]}" + echo " routes:" + echo " - to: default" + echo " via: ${CFG_GATEWAY[$int]}" + echo " nameservers:" + echo " addresses:" + echo " - ${CFG_DNS[$int]}" + } >>"$FILENAME" + fi + + { + echo " access-points:" + echo " \"${CFG_SSID[$int]}\":" + echo " password: \"${CFG_PASSWORD[$int]}\"" + } >>"$FILENAME" done fi +} - netplan=$(cat /tmp/01-netcfg.yaml) - yesno_def_yes "The following netplan was generated: \n\n $netplan \n\n Copy to /etc/netplan and Apply?" - ret_val=$? +validate_basic_config() { + local errors="" + + for int in "${INTERFACES[@]}"; do + [ "${CFG_ENABLED[$int]}" = "yes" ] || continue + + if [ "${CFG_DHCP4[$int]}" = "no" ]; then + if [ -z "${CFG_ADDRESS[$int]}" ]; then + errors="${errors}\n$int: missing static IP address" + fi - if [ $ret_val -eq 0 ]; then + if [ -z "${CFG_PREFIX[$int]}" ]; then + errors="${errors}\n$int: missing CIDR prefix" + fi + + if [ -z "${CFG_GATEWAY[$int]}" ]; then + errors="${errors}\n$int: missing gateway" + fi + + if [ -z "${CFG_DNS[$int]}" ]; then + errors="${errors}\n$int: missing DNS server" + fi + fi + + if [ "${CFG_TYPE[$int]}" = "wifi" ]; then + if [ -z "${CFG_SSID[$int]}" ]; then + errors="${errors}\n$int: missing Wi-Fi SSID" + fi + + if [ -z "${CFG_PASSWORD[$int]}" ]; then + errors="${errors}\n$int: missing Wi-Fi password" + fi + fi + done + + if [ -n "$errors" ]; then + error_msg "Configuration errors:$errors" + return 1 + fi + + return 0 +} + +install_netplan_if_missing() { + if ! command -v netplan >/dev/null 2>&1; then + echo "Netplan not found, installing..." + sudo apt update && sudo apt install -y netplan.io + fi +} + +detect_interfaces() { + INTERFACES=() + + while IFS= read -r int; do + if is_ethernet_interface "$int" || is_wifi_interface "$int"; then + INTERFACES+=("$int") + fi + done < <(ls /sys/class/net) + + if [ "${#INTERFACES[@]}" -eq 0 ]; then + error_msg "No ethX or wlanX network interfaces found. + +Your interfaces may have different names, for example: +enp3s0, ens33, wlp2s0 + +Run the Network Interface Names Fix first and then restart this script." + exit 1 + fi +} + +copy_and_apply_netplan() { + echo "Enabling systemd-networkd ..." + enable_systemd_networkd + + echo "Disabling NetworkManager ..." + disable_network_manager + + echo "Copying netplan ..." + sudo cp "$FILENAME" /etc/netplan/01-netcfg.yaml + sudo chmod 600 /etc/netplan/01-netcfg.yaml + + echo "Generating netplan ..." + sudo netplan generate + + echo "Applying netplan ..." + sudo netplan apply + + echo "Done" +} + +interactive_mode() { + yesno_def_yes "This script will configure networking on the device. + +systemd-networkd will be used as the backend for netplan and NetworkManager will be disabled. + +If you are connected via SSH, you may lose connection when applying. + +Do you want to continue?" + + if [ "$?" -eq 0 ]; then + echo "Aborting network config..." exit 0 fi -else + yesno_def_yes "Delete all previous netplan configs? Recommended." + + if [ "$?" -eq 1 ]; then + sudo rm -f /etc/netplan/*.yaml + fi + + detect_interfaces + + declare -gA CFG_TYPE + declare -gA CFG_ENABLED + declare -gA CFG_DHCP4 + declare -gA CFG_ADDRESS + declare -gA CFG_PREFIX + declare -gA CFG_GATEWAY + declare -gA CFG_DNS + declare -gA CFG_SSID + declare -gA CFG_PASSWORD + + for int in "${INTERFACES[@]}"; do + init_interface_defaults "$int" + done + + while true; do + main_interface_menu + + if ! validate_basic_config; then + continue + fi + + local netplan_preview + netplan_preview=$(cat "$FILENAME") + + yesno_def_yes "The following netplan was generated: + + $netplan_preview + + Copy to /etc/netplan and apply?" + + if [ "$?" -eq 1 ]; then + # User selected Yes + break + else + # User selected No, go back to interface selection menu + continue + fi + done +} + +non_interactive_mode() { + if [ "${NETWORKING_DELETE_PREVIOUS_NETPLAN_CONFIGS:-}" = "true" ]; then + echo "Removing previous netplan configs" + sudo rm -f /etc/netplan/*.yaml + else + echo "Keeping previous netplan configs" + fi - # Read directly from the exported environment variable network_config="${NETWORKING_NETPLAN_CONFIG:-}" if [ -z "$network_config" ]; then - echo "No network config found in profile! Please set the NETWORKING_NETPLAN_CONFIG variable in your profile to a valid netplan config yaml string. Aborting." + echo "No network config found in profile." + echo "Please set NETWORKING_NETPLAN_CONFIG to a valid netplan YAML string." exit 1 - else - echo "$network_config" >"$FILENAME" fi -fi -echo "Enabling systemd-networkd ..." -enable_systemd_networkd + echo "$network_config" >"$FILENAME" +} -echo "Disabling NetworkManager ..." -disable_network_manager +main() { + install_netplan_if_missing -echo "Copying netplan ..." -sudo cp /tmp/01-netcfg.yaml /etc/netplan -sudo chmod 600 /etc/netplan/01-netcfg.yaml + if [[ "${NON_INTERACTIVE_MODE:-0}" -ne 1 ]]; then + interactive_mode + else + non_interactive_mode + fi -echo "Applying netplan ..." -sudo netplan generate -sudo netplan apply + copy_and_apply_netplan + exit 0 +} -echo "Done" -exit 0 +main "$@" From add43cb60ccdf718aba12eb8602b88a9409d3b24 Mon Sep 17 00:00:00 2001 From: Vid Smole Date: Mon, 20 Jul 2026 15:53:47 +0200 Subject: [PATCH 2/9] Update button text --- subscripts/4Network/2Configure_networking.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subscripts/4Network/2Configure_networking.sh b/subscripts/4Network/2Configure_networking.sh index a9bbc4b..a3e0a1f 100755 --- a/subscripts/4Network/2Configure_networking.sh +++ b/subscripts/4Network/2Configure_networking.sh @@ -269,7 +269,7 @@ main_interface_menu() { # Blank separator line menu_items+=(" " " ") - menu_items+=("Save/Apply" "Generate netplan and continue") + menu_items+=("Save" "Generate netplan and continue") local choice choice=$(whiptail --title "$TITLE" \ @@ -285,7 +285,7 @@ main_interface_menu() { case "$ret_val" in 0) case "$choice" in - "Save/Apply") + "Save") generate_netplan return ;; From 20bea795e09b59192958fab7f58532b8ef3a23e8 Mon Sep 17 00:00:00 2001 From: Vid Smole Date: Mon, 20 Jul 2026 16:13:07 +0200 Subject: [PATCH 3/9] Add toggle for default gateway for each interface --- subscripts/4Network/2Configure_networking.sh | 82 ++++++++++++++++---- 1 file changed, 67 insertions(+), 15 deletions(-) diff --git a/subscripts/4Network/2Configure_networking.sh b/subscripts/4Network/2Configure_networking.sh index a3e0a1f..5cf9c63 100755 --- a/subscripts/4Network/2Configure_networking.sh +++ b/subscripts/4Network/2Configure_networking.sh @@ -95,6 +95,16 @@ get_default_gateway_for_interface() { fi } +get_default_gateway_to_internet_for_interface() { + local int="$1" + + if is_wifi_interface "$int"; then + echo "yes" + else + echo "no" + fi +} + get_default_ssid() { if [[ "${USE_DEFAULTS_FOR:-}" == "F4F" ]]; then echo "f4f_robot" @@ -115,6 +125,7 @@ init_interface_defaults() { CFG_ADDRESS["$int"]="$(get_default_ip_for_interface "$int")" CFG_PREFIX["$int"]="24" CFG_GATEWAY["$int"]="$(get_default_gateway_for_interface "$int")" + CFG_GATEWAY_TO_INTERNET["$int"]="$(get_default_gateway_to_internet_for_interface "$int")" CFG_DNS["$int"]="8.8.8.8" if is_wifi_interface "$int"; then @@ -141,7 +152,11 @@ interface_summary() { if [ "$dhcp" = "yes" ]; then echo "DHCP" else - echo "static ${CFG_ADDRESS[$int]}/${CFG_PREFIX[$int]}" + if [ "${CFG_GATEWAY_TO_INTERNET[$int]}" = "yes" ]; then + echo "static ${CFG_ADDRESS[$int]}/${CFG_PREFIX[$int]}, internet gateway" + else + echo "static ${CFG_ADDRESS[$int]}/${CFG_PREFIX[$int]}, no internet gateway" + fi fi } @@ -172,7 +187,16 @@ Choose option to edit:" menu_items+=( "Static address" "${CFG_ADDRESS[$int]}" "CIDR prefix" "${CFG_PREFIX[$int]}" - "Default gateway" "${CFG_GATEWAY[$int]}" + "Gateway to internet" "${CFG_GATEWAY_TO_INTERNET[$int]}" + ) + + if [ "${CFG_GATEWAY_TO_INTERNET[$int]}" = "yes" ]; then + menu_items+=( + "Default gateway" "${CFG_GATEWAY[$int]}" + ) + fi + + menu_items+=( "DNS server" "${CFG_DNS[$int]}" ) fi @@ -187,7 +211,7 @@ Choose option to edit:" local choice choice=$(whiptail --title "$TITLE - $int" --ok-button "Edit" --cancel-button "Back" --menu "$menu_text" \ - 22 60 10 "${menu_items[@]}" 3>&1 1>&2 2>&3) + 22 70 12 "${menu_items[@]}" 3>&1 1>&2 2>&3) ret_val=$? case "$ret_val" in @@ -238,6 +262,16 @@ Choose option to edit:" CFG_DHCP4["$int"]="no" ;; + "Gateway to internet") + yesno_def_yes "Should $int use a default gateway to the internet?" + if [ "$?" -eq 1 ]; then + CFG_GATEWAY_TO_INTERNET["$int"]="yes" + else + CFG_GATEWAY_TO_INTERNET["$int"]="no" + fi + CFG_DHCP4["$int"]="no" + ;; + "Default gateway") CFG_GATEWAY["$int"]=$(input_box "Enter default gateway for $int:" "${CFG_GATEWAY[$int]}") CFG_DHCP4["$int"]="no" @@ -276,7 +310,7 @@ main_interface_menu() { --ok-button "Select" \ --cancel-button "Cancel" \ --menu "Select an interface to configure:" \ - 24 60 14 \ + 24 70 14 \ "${menu_items[@]}" \ 3>&1 1>&2 2>&3) @@ -290,7 +324,8 @@ main_interface_menu() { return ;; - " ") # Blank separator line, ignore + " ") + # Blank separator line, ignore continue ;; @@ -346,9 +381,17 @@ generate_netplan() { { echo " addresses:" echo " - ${CFG_ADDRESS[$int]}/${CFG_PREFIX[$int]}" - echo " routes:" - echo " - to: default" - echo " via: ${CFG_GATEWAY[$int]}" + } >>"$FILENAME" + + if [ "${CFG_GATEWAY_TO_INTERNET[$int]}" = "yes" ]; then + { + echo " routes:" + echo " - to: default" + echo " via: ${CFG_GATEWAY[$int]}" + } >>"$FILENAME" + fi + + { echo " nameservers:" echo " addresses:" echo " - ${CFG_DNS[$int]}" @@ -374,9 +417,17 @@ generate_netplan() { { echo " addresses:" echo " - ${CFG_ADDRESS[$int]}/${CFG_PREFIX[$int]}" - echo " routes:" - echo " - to: default" - echo " via: ${CFG_GATEWAY[$int]}" + } >>"$FILENAME" + + if [ "${CFG_GATEWAY_TO_INTERNET[$int]}" = "yes" ]; then + { + echo " routes:" + echo " - to: default" + echo " via: ${CFG_GATEWAY[$int]}" + } >>"$FILENAME" + fi + + { echo " nameservers:" echo " addresses:" echo " - ${CFG_DNS[$int]}" @@ -407,7 +458,7 @@ validate_basic_config() { errors="${errors}\n$int: missing CIDR prefix" fi - if [ -z "${CFG_GATEWAY[$int]}" ]; then + if [ "${CFG_GATEWAY_TO_INTERNET[$int]}" = "yes" ] && [ -z "${CFG_GATEWAY[$int]}" ]; then errors="${errors}\n$int: missing gateway" fi @@ -510,6 +561,7 @@ Do you want to continue?" declare -gA CFG_ADDRESS declare -gA CFG_PREFIX declare -gA CFG_GATEWAY + declare -gA CFG_GATEWAY_TO_INTERNET declare -gA CFG_DNS declare -gA CFG_SSID declare -gA CFG_PASSWORD @@ -530,9 +582,9 @@ Do you want to continue?" yesno_def_yes "The following netplan was generated: - $netplan_preview +$netplan_preview - Copy to /etc/netplan and apply?" +Copy to /etc/netplan and apply?" if [ "$?" -eq 1 ]; then # User selected Yes @@ -576,4 +628,4 @@ main() { exit 0 } -main "$@" +main "$@" \ No newline at end of file From b4c23841be70be113e3beb5119a5647e530da4c8 Mon Sep 17 00:00:00 2001 From: Vid Smole Date: Tue, 21 Jul 2026 15:16:42 +0200 Subject: [PATCH 4/9] Remove prompt about changing to networkd --- subscripts/4Network/2Configure_networking.sh | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/subscripts/4Network/2Configure_networking.sh b/subscripts/4Network/2Configure_networking.sh index 5cf9c63..a7fd098 100755 --- a/subscripts/4Network/2Configure_networking.sh +++ b/subscripts/4Network/2Configure_networking.sh @@ -534,19 +534,6 @@ copy_and_apply_netplan() { } interactive_mode() { - yesno_def_yes "This script will configure networking on the device. - -systemd-networkd will be used as the backend for netplan and NetworkManager will be disabled. - -If you are connected via SSH, you may lose connection when applying. - -Do you want to continue?" - - if [ "$?" -eq 0 ]; then - echo "Aborting network config..." - exit 0 - fi - yesno_def_yes "Delete all previous netplan configs? Recommended." if [ "$?" -eq 1 ]; then From f5d08a2d6eef244180fd12340531f7c53cc66a43 Mon Sep 17 00:00:00 2001 From: Vid Smole Date: Tue, 21 Jul 2026 15:38:56 +0200 Subject: [PATCH 5/9] Add option for deleting old configs --- subscripts/4Network/2Configure_networking.sh | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/subscripts/4Network/2Configure_networking.sh b/subscripts/4Network/2Configure_networking.sh index a7fd098..2ac7265 100755 --- a/subscripts/4Network/2Configure_networking.sh +++ b/subscripts/4Network/2Configure_networking.sh @@ -117,6 +117,10 @@ get_default_wifi_password() { echo "mikrokopter" } +delete_old_netplan_configs() { + sudo rm -f /etc/netplan/*.yaml +} + init_interface_defaults() { local int="$1" @@ -303,7 +307,8 @@ main_interface_menu() { # Blank separator line menu_items+=(" " " ") - menu_items+=("Save" "Generate netplan and continue") + menu_items+=("Cleanup" "Delete old netplan configs") + menu_items+=("Save" "Generate netplan config and continue") local choice choice=$(whiptail --title "$TITLE" \ @@ -323,6 +328,10 @@ main_interface_menu() { generate_netplan return ;; + "Cleanup") + delete_old_netplan_configs + return + ;; " ") # Blank separator line, ignore @@ -534,12 +543,6 @@ copy_and_apply_netplan() { } interactive_mode() { - yesno_def_yes "Delete all previous netplan configs? Recommended." - - if [ "$?" -eq 1 ]; then - sudo rm -f /etc/netplan/*.yaml - fi - detect_interfaces declare -gA CFG_TYPE From ae4ca14e1cea36829b05db53bf1643de35c0d0e3 Mon Sep 17 00:00:00 2001 From: Vid Smole Date: Tue, 21 Jul 2026 15:39:07 +0200 Subject: [PATCH 6/9] Improve msg --- subscripts/4Network/2Configure_networking.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subscripts/4Network/2Configure_networking.sh b/subscripts/4Network/2Configure_networking.sh index 2ac7265..57005fe 100755 --- a/subscripts/4Network/2Configure_networking.sh +++ b/subscripts/4Network/2Configure_networking.sh @@ -574,7 +574,7 @@ interactive_mode() { $netplan_preview -Copy to /etc/netplan and apply?" +Save to /etc/netplan/01-netcfg.yaml and apply?" if [ "$?" -eq 1 ]; then # User selected Yes From f109859c9d5c2fdda166f2035c339b6c8ff36997 Mon Sep 17 00:00:00 2001 From: Vid Smole Date: Tue, 21 Jul 2026 15:56:33 +0200 Subject: [PATCH 7/9] Rename function --- subscripts/4Network/2Configure_networking.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subscripts/4Network/2Configure_networking.sh b/subscripts/4Network/2Configure_networking.sh index 57005fe..3e4369f 100755 --- a/subscripts/4Network/2Configure_networking.sh +++ b/subscripts/4Network/2Configure_networking.sh @@ -43,7 +43,7 @@ input_box() { fi } -error_msg() { +msgbox() { whiptail --title "$TITLE" --msgbox "$1" 0 0 } @@ -488,7 +488,7 @@ validate_basic_config() { done if [ -n "$errors" ]; then - error_msg "Configuration errors:$errors" + msgbox "Configuration errors:$errors" return 1 fi @@ -512,7 +512,7 @@ detect_interfaces() { done < <(ls /sys/class/net) if [ "${#INTERFACES[@]}" -eq 0 ]; then - error_msg "No ethX or wlanX network interfaces found. + msgbox "No ethX or wlanX network interfaces found. Your interfaces may have different names, for example: enp3s0, ens33, wlp2s0 From 6b7f8208b50de805b8dce5c61ee58b604e3b745c Mon Sep 17 00:00:00 2001 From: Vid Smole Date: Tue, 21 Jul 2026 15:56:44 +0200 Subject: [PATCH 8/9] Print message after removing --- subscripts/4Network/2Configure_networking.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subscripts/4Network/2Configure_networking.sh b/subscripts/4Network/2Configure_networking.sh index 3e4369f..3cfdc2f 100755 --- a/subscripts/4Network/2Configure_networking.sh +++ b/subscripts/4Network/2Configure_networking.sh @@ -119,6 +119,7 @@ get_default_wifi_password() { delete_old_netplan_configs() { sudo rm -f /etc/netplan/*.yaml + msgbox "Deleted all yaml files in /etc/netplan/" } init_interface_defaults() { @@ -330,7 +331,6 @@ main_interface_menu() { ;; "Cleanup") delete_old_netplan_configs - return ;; " ") From ac72b8a4fddec582e92d3cabd3c52dafa223d89c Mon Sep 17 00:00:00 2001 From: Vid Smole Date: Wed, 22 Jul 2026 09:04:43 +0200 Subject: [PATCH 9/9] Add metric --- subscripts/4Network/2Configure_networking.sh | 39 ++++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/subscripts/4Network/2Configure_networking.sh b/subscripts/4Network/2Configure_networking.sh index 3cfdc2f..bb4ff4b 100755 --- a/subscripts/4Network/2Configure_networking.sh +++ b/subscripts/4Network/2Configure_networking.sh @@ -95,6 +95,16 @@ get_default_gateway_for_interface() { fi } +get_metric_for_interface() { + local int="$1" + + if is_wifi_interface "$int"; then + echo "100" + else + echo "200" + fi +} + get_default_gateway_to_internet_for_interface() { local int="$1" @@ -129,8 +139,9 @@ init_interface_defaults() { CFG_DHCP4["$int"]="yes" CFG_ADDRESS["$int"]="$(get_default_ip_for_interface "$int")" CFG_PREFIX["$int"]="24" - CFG_GATEWAY["$int"]="$(get_default_gateway_for_interface "$int")" CFG_GATEWAY_TO_INTERNET["$int"]="$(get_default_gateway_to_internet_for_interface "$int")" + CFG_GATEWAY["$int"]="$(get_default_gateway_for_interface "$int")" + CFG_METRIC["$int"]="$(get_metric_for_interface "$int")" CFG_DNS["$int"]="8.8.8.8" if is_wifi_interface "$int"; then @@ -158,9 +169,9 @@ interface_summary() { echo "DHCP" else if [ "${CFG_GATEWAY_TO_INTERNET[$int]}" = "yes" ]; then - echo "static ${CFG_ADDRESS[$int]}/${CFG_PREFIX[$int]}, internet gateway" + echo "static ${CFG_ADDRESS[$int]}/${CFG_PREFIX[$int]} metric ${CFG_METRIC[$int]}" else - echo "static ${CFG_ADDRESS[$int]}/${CFG_PREFIX[$int]}, no internet gateway" + echo "static ${CFG_ADDRESS[$int]}/${CFG_PREFIX[$int]}" fi fi } @@ -196,9 +207,8 @@ Choose option to edit:" ) if [ "${CFG_GATEWAY_TO_INTERNET[$int]}" = "yes" ]; then - menu_items+=( - "Default gateway" "${CFG_GATEWAY[$int]}" - ) + menu_items+=("Default gateway" "${CFG_GATEWAY[$int]}") + menu_items+=("Metric" "${CFG_METRIC[$int]}") fi menu_items+=( @@ -259,12 +269,10 @@ Choose option to edit:" "Static address") CFG_ADDRESS["$int"]=$(input_box "Enter static IP address for $int:" "${CFG_ADDRESS[$int]}") - CFG_DHCP4["$int"]="no" ;; "CIDR prefix") CFG_PREFIX["$int"]=$(input_box "Enter CIDR prefix for $int, for example 24:" "${CFG_PREFIX[$int]}") - CFG_DHCP4["$int"]="no" ;; "Gateway to internet") @@ -274,12 +282,14 @@ Choose option to edit:" else CFG_GATEWAY_TO_INTERNET["$int"]="no" fi - CFG_DHCP4["$int"]="no" ;; "Default gateway") CFG_GATEWAY["$int"]=$(input_box "Enter default gateway for $int:" "${CFG_GATEWAY[$int]}") - CFG_DHCP4["$int"]="no" + ;; + + "Metric") + CFG_METRIC["$int"]=$(input_box "Enter metric for $int. Only the active gateway with the lowest metric will be used for internet access:" "${CFG_METRIC[$int]}") ;; "DNS server") @@ -397,6 +407,7 @@ generate_netplan() { echo " routes:" echo " - to: default" echo " via: ${CFG_GATEWAY[$int]}" + echo " metric: ${CFG_METRIC[$int]}" } >>"$FILENAME" fi @@ -433,6 +444,7 @@ generate_netplan() { echo " routes:" echo " - to: default" echo " via: ${CFG_GATEWAY[$int]}" + echo " metric: ${CFG_METRIC[$int]}" } >>"$FILENAME" fi @@ -471,6 +483,10 @@ validate_basic_config() { errors="${errors}\n$int: missing gateway" fi + if [ "${CFG_GATEWAY_TO_INTERNET[$int]}" = "yes" ] && [ -z "${CFG_METRIC[$int]}" ]; then + errors="${errors}\n$int: missing metric" + fi + if [ -z "${CFG_DNS[$int]}" ]; then errors="${errors}\n$int: missing DNS server" fi @@ -550,8 +566,9 @@ interactive_mode() { declare -gA CFG_DHCP4 declare -gA CFG_ADDRESS declare -gA CFG_PREFIX - declare -gA CFG_GATEWAY declare -gA CFG_GATEWAY_TO_INTERNET + declare -gA CFG_GATEWAY + declare -gA CFG_METRIC declare -gA CFG_DNS declare -gA CFG_SSID declare -gA CFG_PASSWORD