Skip to content

Instantly share code, notes, and snippets.

@klutchell
Created February 10, 2026 17:31
Show Gist options
  • Select an option

  • Save klutchell/57197ed61ae6b40a3d09fd6ff10e951f to your computer and use it in GitHub Desktop.

Select an option

Save klutchell/57197ed61ae6b40a3d09fd6ff10e951f to your computer and use it in GitHub Desktop.
Test a .nmconnection keyfile with automatic rollback (companion to hetzner-nmconnection.sh)
#!/usr/bin/env bash
# Test an .nmconnection keyfile and always revert. Writes result to /tmp/nm-test-result.
#
# Usage: ./test-nmconnection.sh <path-to.nmconnection>
#
# Designed to work with hetzner-nmconnection.sh:
# ./hetzner-nmconnection.sh 12345 > static.nmconnection
# ./test-nmconnection.sh static.nmconnection
set -euo pipefail
[[ ${1:-} ]] || { echo "usage: $0 <file.nmconnection>" >&2; exit 1; }
CONN_FILE="$1"
[[ -f $CONN_FILE ]] || { echo "error: $CONN_FILE not found" >&2; exit 1; }
CONN_NAME=$(awk -F= '/^id=/ {print $2; exit}' "$CONN_FILE")
[[ -n $CONN_NAME ]] || { echo "error: no id= found in $CONN_FILE" >&2; exit 1; }
ORIGINAL_CONN=$(nmcli -t -f NAME,DEVICE con show --active | head -1 | cut -d: -f1)
[[ -n $ORIGINAL_CONN ]] || { echo "error: no active connection to revert to" >&2; exit 1; }
BASENAME=$(basename "$CONN_FILE")
RESULT_FILE="/tmp/nm-test-result"
echo "testing '$CONN_NAME' from $CONN_FILE (revert to '$ORIGINAL_CONN')"
# -- rollback (always runs, survives SSH disconnect) --
nohup bash -c "
sleep 15
nmcli connection up '$ORIGINAL_CONN' 2>/dev/null
nmcli connection delete '$CONN_NAME' 2>/dev/null
rm -f /etc/NetworkManager/system-connections/$BASENAME
" > /dev/null 2>&1 &
# -- load and activate --
cp "$CONN_FILE" /etc/NetworkManager/system-connections/
chmod 600 /etc/NetworkManager/system-connections/"$BASENAME"
nmcli connection load /etc/NetworkManager/system-connections/"$BASENAME"
nmcli connection up "$CONN_NAME"
# -- test --
sleep 3
{
echo "=== $(date) ==="
echo "connection: $CONN_NAME"
echo "ipv4: $(ping -c 2 -W 5 1.1.1.1 > /dev/null 2>&1 && echo PASS || echo FAIL)"
echo "ipv6: $(ping -c 2 -W 5 2606:4700:4700::1111 > /dev/null 2>&1 && echo PASS || echo FAIL)"
echo "dns: $(ping -c 2 -W 5 cloudflare.com > /dev/null 2>&1 && echo PASS || echo FAIL)"
ip addr show
ip route show
} > "$RESULT_FILE" 2>&1
echo "results written to $RESULT_FILE, reverting in ~15s"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment