#!/usr/bin/env bash # # bt-netconfig-boot - re-apply saved network settings after reboot. # Runs as root from buttontask-network.service once NetworkManager is up. set -uo pipefail ROOT="${BUTTONTASK_ROOT:-/opt/buttontask}" CFG="$ROOT/config/network.json" SCRIPT="$ROOT/scripts/bt-netconfig" log() { echo "bt-netconfig-boot: $*"; } wait_for_iface() { local iface="$1" i for i in $(seq 1 45); do ip link show "$iface" &>/dev/null && return 0 sleep 1 done return 1 } wait_for_nm() { local i for i in $(seq 1 30); do nmcli general status &>/dev/null && return 0 sleep 1 done return 1 } apply_saved() { [ -f "$CFG" ] || { log "no saved config at $CFG"; return 0; } [ -x "$SCRIPT" ] || { log "bt-netconfig missing: $SCRIPT"; return 1; } python3 - "$CFG" "$SCRIPT" <<'PY' import json, subprocess, sys cfg_path, script = sys.argv[1], sys.argv[2] with open(cfg_path, encoding="utf-8") as f: cfg = json.load(f) iface = (cfg.get("iface") or "").strip() mode = (cfg.get("mode") or "").strip() if not iface or mode not in ("dhcp", "static"): sys.exit(0) args = [script, iface, mode] if mode == "static": args += [ cfg.get("address", ""), str(cfg.get("prefix", 24)), cfg.get("gateway", ""), cfg.get("dns", ""), ] raise SystemExit(subprocess.run(args).returncode) PY } IFACE="eth0" if [ -f "$CFG" ]; then IFACE="$(python3 -c "import json; print(json.load(open('$CFG')).get('iface','eth0'))" 2>/dev/null || echo eth0)" fi wait_for_nm || log "NetworkManager not ready, continuing anyway" wait_for_iface "$IFACE" || log "interface $IFACE not found, continuing anyway" if apply_saved; then log "network ready on $IFACE" else log "saved config apply failed, trying buttontask profiles" while IFS= read -r con; do [ -z "$con" ] && continue iface="${con#buttontask-}" nmcli connection up "$con" ifname "$iface" 2>/dev/null \ || nmcli connection up "$con" 2>/dev/null || true done < <(nmcli -t -f NAME connection show 2>/dev/null | grep '^buttontask-' || true) fi