deploy: find cellular profile by id, no-auto-default NM conf, warn on NM enable failure
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
# NetworkManager must never auto-create "Wired connection" DHCP profiles on ports
|
||||||
|
# that netplan / ./deploy.sh --apply-network has not handed to it yet; otherwise it
|
||||||
|
# races systemd-networkd's DHCP on the Starlink port.
|
||||||
|
[main]
|
||||||
|
no-auto-default=*
|
||||||
@@ -13,9 +13,12 @@
|
|||||||
# ./deploy.sh --wan-plan [conf] # what the NetworkManager WAN provisioning would do (read-only, no root)
|
# ./deploy.sh --wan-plan [conf] # what the NetworkManager WAN provisioning would do (read-only, no root)
|
||||||
# ./deploy.sh render <file> # preview a templated file on stdout
|
# ./deploy.sh render <file> # preview a templated file on stdout
|
||||||
# ./deploy.sh --redact # filter stdin, masking secret values (used by --diff; for tests)
|
# ./deploy.sh --redact # filter stdin, masking secret values (used by --diff; for tests)
|
||||||
# Idempotent. Netplan (wlan0 + Starlink NIC = NM-managed WANs; eth0 is a LAN
|
# VANLINK_NM_DIR=<dir> # test override: where existing NM *.nmconnection files are looked up (default /etc/NetworkManager/system-connections)
|
||||||
# port on br0) is NOT deployed here — reference copy in ap/50-van-wan.yaml,
|
# Idempotent. Netplan (the NM-managed WANs; eth0 is a LAN port on br0) is never
|
||||||
# applied once manually (apply flaps uplinks). We do check it for drift below.
|
# changed by a routine deploy (applying it flaps the uplinks). ENABLE_NM_WAN=0:
|
||||||
|
# applied manually from the reference copy in ap/50-van-wan.yaml, and checked for
|
||||||
|
# drift below. ENABLE_NM_WAN=1: a missing/differing WAN netplan is only warned
|
||||||
|
# about; it is applied by `./deploy.sh --apply-network` alone.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd "$(dirname "$(readlink -f "$0")")"
|
cd "$(dirname "$(readlink -f "$0")")"
|
||||||
|
|
||||||
@@ -98,6 +101,19 @@ nm_wan_state_netplan() { # missing | differs | matches (the installed WAN netpl
|
|||||||
else echo differs; fi
|
else echo differs; fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cellular_profile_exists() { # true if an NM profile with id=$CELLULAR_CONN_NAME exists (any file name, or known to nmcli)
|
||||||
|
local d=${VANLINK_NM_DIR:-/etc/NetworkManager/system-connections} f names
|
||||||
|
for f in "$d"/*.nmconnection; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
if grep -Fx "id=${CELLULAR_CONN_NAME}" "$f" >/dev/null 2>&1; then return 0; fi
|
||||||
|
done
|
||||||
|
if command -v nmcli >/dev/null 2>&1; then
|
||||||
|
names=$(nmcli -g NAME connection show 2>/dev/null) || names=
|
||||||
|
if printf '%s\n' "$names" | grep -Fx "${CELLULAR_CONN_NAME}" >/dev/null 2>&1; then return 0; fi
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
check_rendered() { # check_rendered <src> <rendered-file> — fail on a leftover @TOKEN@
|
check_rendered() { # check_rendered <src> <rendered-file> — fail on a leftover @TOKEN@
|
||||||
local left
|
local left
|
||||||
left=$(grep -oE "$TOKEN_RE" "$2" | sort -u | tr '\n' ' ') || true
|
left=$(grep -oE "$TOKEN_RE" "$2" | sort -u | tr '\n' ' ') || true
|
||||||
@@ -315,7 +331,7 @@ case "${1:-}" in
|
|||||||
if [ -f /etc/netplan/10-dhcp-all-interfaces.yaml ]; then echo " armbian: /etc/netplan/10-dhcp-all-interfaces.yaml present -> would move aside"; else echo " armbian: /etc/netplan/10-dhcp-all-interfaces.yaml absent"; fi
|
if [ -f /etc/netplan/10-dhcp-all-interfaces.yaml ]; then echo " armbian: /etc/netplan/10-dhcp-all-interfaces.yaml present -> would move aside"; else echo " armbian: /etc/netplan/10-dhcp-all-interfaces.yaml absent"; fi
|
||||||
if [ -z "${CELLULAR_APN:-}" ]; then
|
if [ -z "${CELLULAR_APN:-}" ]; then
|
||||||
echo " cellular profile: skipped (no CELLULAR_APN)"
|
echo " cellular profile: skipped (no CELLULAR_APN)"
|
||||||
elif [ -e "/etc/NetworkManager/system-connections/${CELLULAR_CONN_NAME}.nmconnection" ]; then
|
elif cellular_profile_exists; then
|
||||||
echo " cellular profile: ${CELLULAR_CONN_NAME} apn=${CELLULAR_APN} exists"
|
echo " cellular profile: ${CELLULAR_CONN_NAME} apn=${CELLULAR_APN} exists"
|
||||||
else
|
else
|
||||||
echo " cellular profile: ${CELLULAR_CONN_NAME} apn=${CELLULAR_APN} would create"
|
echo " cellular profile: ${CELLULAR_CONN_NAME} apn=${CELLULAR_APN} would create"
|
||||||
@@ -643,6 +659,8 @@ install -D -m0644 power/10-vanlink-watchdog.conf /etc/systemd/system.conf.d/10-v
|
|||||||
|
|
||||||
if [ "$ENABLE_NM_WAN" = 1 ]; then
|
if [ "$ENABLE_NM_WAN" = 1 ]; then
|
||||||
echo "== networkmanager WANs =="
|
echo "== networkmanager WANs =="
|
||||||
|
# In place before the package starts NM: no auto-created "Wired connection" profiles.
|
||||||
|
install -D -m0644 ap/nm-no-auto-default.conf /etc/NetworkManager/conf.d/00-van-no-auto-default.conf
|
||||||
if ! dpkg -s network-manager >/dev/null 2>&1; then
|
if ! dpkg -s network-manager >/dev/null 2>&1; then
|
||||||
# Installed only now: the package starts NM, which manages Wi-Fi/gsm devices by
|
# Installed only now: the package starts NM, which manages Wi-Fi/gsm devices by
|
||||||
# default, so van-ap-unmanaged.conf (AP radios, LAN ports) must already be in place.
|
# default, so van-ap-unmanaged.conf (AP radios, LAN ports) must already be in place.
|
||||||
@@ -650,7 +668,8 @@ if [ "$ENABLE_NM_WAN" = 1 ]; then
|
|||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y network-manager \
|
DEBIAN_FRONTEND=noninteractive apt-get install -y network-manager \
|
||||||
|| { echo "deploy: apt-get install network-manager failed" >&2; exit 1; }
|
|| { echo "deploy: apt-get install network-manager failed" >&2; exit 1; }
|
||||||
fi
|
fi
|
||||||
systemctl enable --now NetworkManager ModemManager >/dev/null 2>&1 || true
|
systemctl enable --now NetworkManager ModemManager >/dev/null 2>&1 \
|
||||||
|
|| warn "failed to enable/start NetworkManager/ModemManager (check: systemctl status NetworkManager ModemManager)"
|
||||||
nmcli general reload conf 2>/dev/null || true
|
nmcli general reload conf 2>/dev/null || true
|
||||||
for nm_if in "$WIFI_5G_IFACE" "$WIFI_2G_IFACE" "$LAN_IFACE" ${ONBOARD_LAN_IFACE:-}; do
|
for nm_if in "$WIFI_5G_IFACE" "$WIFI_2G_IFACE" "$LAN_IFACE" ${ONBOARD_LAN_IFACE:-}; do
|
||||||
[ -e "/sys/class/net/$nm_if" ] || continue
|
[ -e "/sys/class/net/$nm_if" ] || continue
|
||||||
@@ -660,7 +679,7 @@ if [ "$ENABLE_NM_WAN" = 1 ]; then
|
|||||||
done
|
done
|
||||||
if [ -n "${CELLULAR_APN:-}" ]; then
|
if [ -n "${CELLULAR_APN:-}" ]; then
|
||||||
nm_keyfile="/etc/NetworkManager/system-connections/${CELLULAR_CONN_NAME}.nmconnection"
|
nm_keyfile="/etc/NetworkManager/system-connections/${CELLULAR_CONN_NAME}.nmconnection"
|
||||||
if [ -e "$nm_keyfile" ]; then
|
if cellular_profile_exists; then
|
||||||
echo " cellular connection ${CELLULAR_CONN_NAME} exists — left unchanged"
|
echo " cellular connection ${CELLULAR_CONN_NAME} exists — left unchanged"
|
||||||
elif [ -z "${CELLULAR_UUID:-}" ]; then
|
elif [ -z "${CELLULAR_UUID:-}" ]; then
|
||||||
warn "CELLULAR_UUID is empty — not creating the cellular keyfile $nm_keyfile"
|
warn "CELLULAR_UUID is empty — not creating the cellular keyfile $nm_keyfile"
|
||||||
@@ -670,8 +689,9 @@ if [ "$ENABLE_NM_WAN" = 1 ]; then
|
|||||||
echo " created cellular connection ${CELLULAR_CONN_NAME} (apn ${CELLULAR_APN}) — no modem needed"
|
echo " created cellular connection ${CELLULAR_CONN_NAME} (apn ${CELLULAR_APN}) — no modem needed"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [ "$(nm_wan_state_netplan)" != matches ]; then
|
nm_np_state=$(nm_wan_state_netplan)
|
||||||
warn "WAN netplan is not provisioned/up to date: run ./deploy.sh --apply-network (backs up /etc/netplan and rolls back automatically if the uplink does not come back)"
|
if [ "$nm_np_state" != matches ]; then
|
||||||
|
warn "WAN netplan is $nm_np_state (not provisioned/up to date): run ./deploy.sh --apply-network (backs up /etc/netplan and rolls back automatically if the uplink does not come back)"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -242,4 +242,19 @@ u2=$(VANLINK_CONF=hosts/wan.conf ./deploy.sh render ap/cellular.nmconnection | g
|
|||||||
[ -n "$u1" ] && [ "$u1" != "uuid=" ] && [ "$u1" = "$u2" ] && ok "cellular uuid non-empty and stable across hosts" || bad "cellular uuid: '$u1' vs '$u2'"
|
[ -n "$u1" ] && [ "$u1" != "uuid=" ] && [ "$u1" = "$u2" ] && ok "cellular uuid non-empty and stable across hosts" || bad "cellular uuid: '$u1' vs '$u2'"
|
||||||
[ "$(grep -v '^[[:space:]]*#' deploy.sh | grep -c uuidgen)" = 0 ] && ok "deploy.sh does not call uuidgen" || bad "deploy.sh calls uuidgen"
|
[ "$(grep -v '^[[:space:]]*#' deploy.sh | grep -c uuidgen)" = 0 ] && ok "deploy.sh does not call uuidgen" || bad "deploy.sh calls uuidgen"
|
||||||
|
|
||||||
|
# 17b. an existing cellular profile is found by id, whatever its file name
|
||||||
|
nmd=$(mktemp -d); nme=$(mktemp -d)
|
||||||
|
printf '[connection]\nid=Koodo\ntype=gsm\n' > "$nmd/weird-file-name.nmconnection"
|
||||||
|
p=$(VANLINK_NM_DIR=$nmd VANLINK_CONF=hosts/van.conf ./deploy.sh --wan-plan 2>&1)
|
||||||
|
echo "$p" | grep -q 'cellular profile: Koodo apn=sp.koodo.com exists' && ok "wan-plan: profile found under another file name" || bad "wan-plan: profile under other file name not found"
|
||||||
|
if command -v nmcli >/dev/null 2>&1 && nmcli -g NAME connection show 2>/dev/null | grep -Fxq Koodo; then
|
||||||
|
ok "wan-plan would-create assertion skipped (this machine's NM lists Koodo)"
|
||||||
|
else
|
||||||
|
p=$(VANLINK_NM_DIR=$nme VANLINK_CONF=hosts/van.conf ./deploy.sh --wan-plan 2>&1)
|
||||||
|
echo "$p" | grep -q 'cellular profile: Koodo apn=sp.koodo.com would create' && ok "wan-plan: empty NM dir -> would create" || bad "wan-plan: empty NM dir should say would create"
|
||||||
|
fi
|
||||||
|
rm -rf "$nmd" "$nme"
|
||||||
|
# 17c. NM must not auto-create "Wired connection" profiles
|
||||||
|
[ "$(grep -v '^[[:space:]]*#' ap/nm-no-auto-default.conf 2>/dev/null | grep -v '^[[:space:]]*$')" = "$(printf '[main]\nno-auto-default=*')" ] && ok "nm-no-auto-default.conf is [main] + no-auto-default=*" || bad "ap/nm-no-auto-default.conf missing or wrong"
|
||||||
|
|
||||||
exit "$fail"
|
exit "$fail"
|
||||||
|
|||||||
Reference in New Issue
Block a user