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:
68
paqctl.sh
68
paqctl.sh
@@ -476,26 +476,46 @@ download_paqet() {
|
|||||||
detect_network() {
|
detect_network() {
|
||||||
log_info "Auto-detecting network configuration..."
|
log_info "Auto-detecting network configuration..."
|
||||||
|
|
||||||
# Default interface
|
# Default interface - handle both standard "via X dev Y" and OpenVZ "dev Y scope link" formats
|
||||||
DETECTED_IFACE=$(ip route show default 2>/dev/null | awk '{print $5; exit}')
|
# 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
|
if [ -z "$DETECTED_IFACE" ]; then
|
||||||
# Skip loopback, docker, veth, bridge, and other virtual interfaces
|
# Skip loopback, docker, veth, bridge, and other virtual interfaces
|
||||||
# Note: grep -v returns exit 1 if no matches, so we add || true for pipefail
|
# 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)
|
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
|
fi
|
||||||
|
|
||||||
# Local IP
|
# Local IP - wrap entire pipeline to prevent pipefail exit
|
||||||
if [ -n "$DETECTED_IFACE" ]; then
|
if [ -n "$DETECTED_IFACE" ]; then
|
||||||
# Note: grep returns exit 1 if no matches, so we add || true for pipefail
|
# 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)
|
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
|
fi
|
||||||
if [ -z "$DETECTED_IP" ]; then
|
if [ -z "$DETECTED_IP" ]; then
|
||||||
DETECTED_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
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}')
|
[ -z "$DETECTED_IP" ] && DETECTED_IP=$(ip -4 addr show scope global 2>/dev/null | awk '/inet /{gsub(/\/.*/, "", $2); print $2; exit}')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Gateway IP
|
# Gateway IP - only present in standard "via X" format, not in OpenVZ
|
||||||
DETECTED_GATEWAY=$(ip route show default 2>/dev/null | awk '{print $3; exit}')
|
if [[ "$_route_line" == *" via "* ]]; then
|
||||||
|
DETECTED_GATEWAY=$(echo "$_route_line" | awk '{print $3}')
|
||||||
|
else
|
||||||
|
DETECTED_GATEWAY=""
|
||||||
|
fi
|
||||||
|
|
||||||
# Gateway MAC
|
# Gateway MAC
|
||||||
DETECTED_GW_MAC=""
|
DETECTED_GW_MAC=""
|
||||||
@@ -1982,25 +2002,45 @@ _check_length() { [ ${#1} -le "${2:-256}" ]; }
|
|||||||
detect_network() {
|
detect_network() {
|
||||||
log_info "Auto-detecting network configuration..."
|
log_info "Auto-detecting network configuration..."
|
||||||
|
|
||||||
# Default interface
|
# Default interface - handle both standard "via X dev Y" and OpenVZ "dev Y scope link" formats
|
||||||
DETECTED_IFACE=$(ip route show default 2>/dev/null | awk '{print $5; exit}')
|
# 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
|
if [ -z "$DETECTED_IFACE" ]; then
|
||||||
# Note: grep -v returns exit 1 if no matches, so we add || true for pipefail
|
# 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)
|
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
|
fi
|
||||||
|
|
||||||
# Local IP
|
# Local IP - wrap entire pipeline to prevent pipefail exit
|
||||||
if [ -n "$DETECTED_IFACE" ]; then
|
if [ -n "$DETECTED_IFACE" ]; then
|
||||||
# Note: grep returns exit 1 if no matches, so we add || true for pipefail
|
# 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)
|
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
|
fi
|
||||||
if [ -z "$DETECTED_IP" ]; then
|
if [ -z "$DETECTED_IP" ]; then
|
||||||
DETECTED_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
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}')
|
[ -z "$DETECTED_IP" ] && DETECTED_IP=$(ip -4 addr show scope global 2>/dev/null | awk '/inet /{gsub(/\/.*/, "", $2); print $2; exit}')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Gateway IP
|
# Gateway IP - handle OpenVZ format (may not have gateway)
|
||||||
DETECTED_GATEWAY=$(ip route show default 2>/dev/null | awk '{print $3; exit}')
|
if [[ "$_route_line" == *" via "* ]]; then
|
||||||
|
DETECTED_GATEWAY=$(echo "$_route_line" | awk '{print $3}')
|
||||||
|
else
|
||||||
|
DETECTED_GATEWAY=""
|
||||||
|
fi
|
||||||
|
|
||||||
# Gateway MAC
|
# Gateway MAC
|
||||||
DETECTED_GW_MAC=""
|
DETECTED_GW_MAC=""
|
||||||
|
|||||||
Reference in New Issue
Block a user