diff --git a/lib/build.func b/lib/build.func index 37f9e70..880d7ec 100644 --- a/lib/build.func +++ b/lib/build.func @@ -36,6 +36,12 @@ DEFAULT_ROOTFS_STORAGE="${DEFAULT_ROOTFS_STORAGE:-local-lvm}" DEFAULT_TEMPLATE_PATTERN="${DEFAULT_TEMPLATE_PATTERN:-debian-12-standard}" DEFAULT_NAMESERVER="${DEFAULT_NAMESERVER:-}" +# Network profiles: map a VLAN tag → DNS servers (+ subnet), maintained in +# lib/networks.conf so adding a network is a one-line change. Applied even for +# DHCP, so every container gets the right resolvers for its VLAN. +NET_PROFILES_URL="${NET_PROFILES_URL:-https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/lib/networks.conf}" +# Set NET_PROFILES_FILE to a local path to use that instead of the remote file. + # ── error trap ─────────────────────────────────────────────────────────────── _on_error() { local exit_code=$? @@ -63,6 +69,34 @@ show_header() { echo } +# ── network profiles ───────────────────────────────────────────────────────── +# Look up DNS servers for the chosen VLAN tag from lib/networks.conf. +# Sets PROFILE_DNS (space-separated, ready for pct --nameserver) and +# PROFILE_SUBNET. Both stay empty if there's no matching profile. +apply_network_profile() { + PROFILE_DNS=""; PROFILE_SUBNET="" + local key="${VLAN_TAG:-}"; [[ -z "$key" ]] && key="none" + + local data="" + if [[ -n "${NET_PROFILES_FILE:-}" && -r "${NET_PROFILES_FILE:-}" ]]; then + data=$(cat "$NET_PROFILES_FILE") + else + data=$(curl -fsSL "$NET_PROFILES_URL" 2>/dev/null) || data="" + fi + [[ -n "$data" ]] || { msg_warn "Could not load network profiles ($NET_PROFILES_URL)"; return 0; } + + local t s d _rest + while read -r t s d _rest; do + [[ -z "$t" || "$t" == \#* ]] && continue # skip blanks/comments + if [[ "$t" == "$key" ]]; then + PROFILE_SUBNET="$s" + PROFILE_DNS="${d//,/ }" # pct wants space-separated + return 0 + fi + done <<< "$data" + return 0 +} + # ── prompts ────────────────────────────────────────────────────────────────── # Each prompt is skipped if the corresponding variable is already set in env. # VLAN_TAG and NAMESERVER use ${VAR+x} so that explicitly setting them to "" @@ -113,12 +147,24 @@ prompt_lxc_config() { if [[ "$IPCFG" != "dhcp" && -z "$GATEWAY" ]]; then read -rp "Gateway: " GATEWAY fi - # DNS: only meaningful for static IPs (DHCP gets DNS from the lease). - # Default suggestion is the gateway, which doubles as DNS in most homelabs. - if [[ "$IPCFG" != "dhcp" && -z "${NAMESERVER+x}" ]]; then + # DNS is driven by the VLAN tag via the network profile (lib/networks.conf), + # so the right resolvers get set even with DHCP. Precedence: + # 1. explicit NAMESERVER from env (even "" = inherit) → respected as-is + # 2. profile match for this VLAN tag → use its DNS + # 3. static IP, no profile → ask + # 4. DHCP, no profile → inherit from host + apply_network_profile + if [[ -n "${NAMESERVER+x}" ]]; then + : # explicit override from env, leave untouched + elif [[ -n "$PROFILE_DNS" ]]; then + NAMESERVER="$PROFILE_DNS" + msg_info "DNS for VLAN ${VLAN_TAG:-none} (${PROFILE_SUBNET:-?}): $NAMESERVER" + elif [[ "$IPCFG" != "dhcp" ]]; then local default_ns="${DEFAULT_NAMESERVER:-$GATEWAY}" read -rp "DNS server [$default_ns] (empty = inherit from PVE host): " NAMESERVER NAMESERVER="${NAMESERVER:-$default_ns}" + else + msg_warn "No network profile for VLAN ${VLAN_TAG:-none}; DHCP DNS will be inherited." fi } @@ -165,11 +211,11 @@ create_lxc() { --ostype debian --password "$ROOT_PASSWORD" ) - [[ -n "${NAMESERVER:-}" ]] && pct_args+=(--nameserver "$NAMESERVER") + [[ -n "${NAMESERVER:-}" ]] && pct_args+=(--nameserver "${NAMESERVER//,/ }") msg_info "Creating unprivileged LXC $CTID ($CT_HOSTNAME)..." msg_info " net0: $net_opts" - [[ -n "${NAMESERVER:-}" ]] && msg_info " dns: $NAMESERVER" + [[ -n "${NAMESERVER:-}" ]] && msg_info " dns: ${NAMESERVER//,/ }" pct create "${pct_args[@]}" msg_ok "LXC $CTID created" diff --git a/lib/networks.conf b/lib/networks.conf new file mode 100644 index 0000000..ceca92d --- /dev/null +++ b/lib/networks.conf @@ -0,0 +1,19 @@ +# lib/networks.conf — network profiles for proxmox-scripts +# +# Maps a VLAN tag to the DNS servers that network uses, so every LXC gets the +# right resolvers automatically — even when it pulls its IP via DHCP. This is +# looked up by lib/build.func from the VLAN tag entered during installation. +# +# To add a network, add one line. Columns are whitespace-separated: +# +# tag VLAN tag entered at install time. Use "none" for the untagged +# network (i.e. when the VLAN prompt is left empty). +# subnet CIDR of the network. Informational — shown during install. +# dns DNS servers, comma-separated (no spaces). +# +# Precedence note: an explicit NAMESERVER=... passed via env always wins over +# the profile. The profile only fills in DNS when none was given by hand. +# +# tag subnet dns +none 192.168.0.0/24 192.168.0.4,192.168.0.5 +20 10.11.20.0/24 10.11.20.44,10.11.20.55