fix: handle OpenVZ network detection (Issue #25)

OpenVZ containers use a different route format:
- Standard: "default via 192.168.1.1 dev eth0"
- OpenVZ:   "default dev venet0 scope link"

The old code used awk '{print $5}' which returned "link" instead
of "venet0" on OpenVZ, causing the script to fail silently when
trying to get IP info from a non-existent "link" interface.

Changes:
- Parse route format to detect "via" vs "dev" patterns
- Use appropriate awk field based on route type
- Validate detected interface exists before using it
- Handle OpenVZ having no gateway (no "via" in route)
- Wrap IP detection pipeline in subshell with || true
This commit is contained in:
SamNet-dev
2026-02-05 09:52:24 -06:00
parent 1ece31c329
commit fcc18542f3

View File

@@ -476,26 +476,46 @@ download_paqet() {
detect_network() {
log_info "Auto-detecting network configuration..."
# Default interface
DETECTED_IFACE=$(ip route show default 2>/dev/null | awk '{print $5; exit}')
# Default interface - handle both standard "via X dev Y" and OpenVZ "dev Y scope link" formats
# Standard: "default via 192.168.1.1 dev eth0" -> $5 = eth0
# OpenVZ: "default dev venet0 scope link" -> $3 = venet0
local _route_line
_route_line=$(ip route show default 2>/dev/null | head -1)
if [[ "$_route_line" == *" via "* ]]; then
# Standard format with gateway
DETECTED_IFACE=$(echo "$_route_line" | awk '{print $5}')
elif [[ "$_route_line" == *" dev "* ]]; then
# OpenVZ/direct format without gateway
DETECTED_IFACE=$(echo "$_route_line" | awk '{print $3}')
fi
# Validate detected interface exists
if [ -n "$DETECTED_IFACE" ] && ! ip link show "$DETECTED_IFACE" &>/dev/null; then
DETECTED_IFACE=""
fi
if [ -z "$DETECTED_IFACE" ]; then
# Skip loopback, docker, veth, bridge, and other virtual interfaces
# Note: grep -v returns exit 1 if no matches, so we add || true for pipefail
DETECTED_IFACE=$(ip -o link show 2>/dev/null | awk -F': ' '{gsub(/ /,"",$2); print $2}' | { grep -vE '^(lo|docker[0-9]|br-|veth|virbr|tun|tap|wg)' || true; } | head -1)
fi
# Local IP
# Local IP - wrap entire pipeline to prevent pipefail exit
if [ -n "$DETECTED_IFACE" ]; then
# Note: grep returns exit 1 if no matches, so we add || true for pipefail
DETECTED_IP=$(ip -4 addr show "$DETECTED_IFACE" 2>/dev/null | awk '/inet /{print $2}' | cut -d/ -f1 | { grep -o '[0-9.]*' || true; } | head -1)
# Note: wrap in subshell with || true to handle cases where interface is invalid or has no IP
DETECTED_IP=$( (ip -4 addr show "$DETECTED_IFACE" 2>/dev/null | awk '/inet /{print $2}' | cut -d/ -f1 | { grep -o '[0-9.]*' || true; } | head -1) || true )
fi
if [ -z "$DETECTED_IP" ]; then
DETECTED_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
[ -z "$DETECTED_IP" ] && DETECTED_IP=$(ip -4 addr show scope global 2>/dev/null | awk '/inet /{gsub(/\/.*/, "", $2); print $2; exit}')
fi
# Gateway IP
DETECTED_GATEWAY=$(ip route show default 2>/dev/null | awk '{print $3; exit}')
# Gateway IP - only present in standard "via X" format, not in OpenVZ
if [[ "$_route_line" == *" via "* ]]; then
DETECTED_GATEWAY=$(echo "$_route_line" | awk '{print $3}')
else
DETECTED_GATEWAY=""
fi
# Gateway MAC
DETECTED_GW_MAC=""
@@ -1982,25 +2002,45 @@ _check_length() { [ ${#1} -le "${2:-256}" ]; }
detect_network() {
log_info "Auto-detecting network configuration..."
# Default interface
DETECTED_IFACE=$(ip route show default 2>/dev/null | awk '{print $5; exit}')
# Default interface - handle both standard "via X dev Y" and OpenVZ "dev Y scope link" formats
# Standard: "default via 192.168.1.1 dev eth0" -> $5 = eth0
# OpenVZ: "default dev venet0 scope link" -> $3 = venet0
local _route_line
_route_line=$(ip route show default 2>/dev/null | head -1)
if [[ "$_route_line" == *" via "* ]]; then
# Standard format with gateway
DETECTED_IFACE=$(echo "$_route_line" | awk '{print $5}')
elif [[ "$_route_line" == *" dev "* ]]; then
# OpenVZ/direct format without gateway
DETECTED_IFACE=$(echo "$_route_line" | awk '{print $3}')
fi
# Validate detected interface exists
if [ -n "$DETECTED_IFACE" ] && ! ip link show "$DETECTED_IFACE" &>/dev/null; then
DETECTED_IFACE=""
fi
if [ -z "$DETECTED_IFACE" ]; then
# Note: grep -v returns exit 1 if no matches, so we add || true for pipefail
DETECTED_IFACE=$(ip -o link show 2>/dev/null | awk -F': ' '{gsub(/ /,"",$2); print $2}' | { grep -vE '^(lo|docker[0-9]|br-|veth|virbr|tun|tap|wg)' || true; } | head -1)
fi
# Local IP
# Local IP - wrap entire pipeline to prevent pipefail exit
if [ -n "$DETECTED_IFACE" ]; then
# Note: grep returns exit 1 if no matches, so we add || true for pipefail
DETECTED_IP=$(ip -4 addr show "$DETECTED_IFACE" 2>/dev/null | awk '/inet /{print $2}' | cut -d/ -f1 | { grep -o '[0-9.]*' || true; } | head -1)
# Note: wrap in subshell with || true to handle cases where interface is invalid or has no IP
DETECTED_IP=$( (ip -4 addr show "$DETECTED_IFACE" 2>/dev/null | awk '/inet /{print $2}' | cut -d/ -f1 | { grep -o '[0-9.]*' || true; } | head -1) || true )
fi
if [ -z "$DETECTED_IP" ]; then
DETECTED_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
[ -z "$DETECTED_IP" ] && DETECTED_IP=$(ip -4 addr show scope global 2>/dev/null | awk '/inet /{gsub(/\/.*/, "", $2); print $2; exit}')
fi
# Gateway IP
DETECTED_GATEWAY=$(ip route show default 2>/dev/null | awk '{print $3; exit}')
# Gateway IP - handle OpenVZ format (may not have gateway)
if [[ "$_route_line" == *" via "* ]]; then
DETECTED_GATEWAY=$(echo "$_route_line" | awk '{print $3}')
else
DETECTED_GATEWAY=""
fi
# Gateway MAC
DETECTED_GW_MAC=""