Merge pull request 'Set container DNS from the VLAN tag via a network profile (incl. DHCP)' (#2) from network-profiles into main

Reviewed-on: #2
This commit was merged in pull request #2.
This commit is contained in:
2026-06-07 21:25:27 +02:00
2 changed files with 70 additions and 5 deletions
+51 -5
View File
@@ -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"
+19
View File
@@ -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