Code import - branch 1.3.0
This commit is contained in:
133
init_port_forward.sh
Executable file
133
init_port_forward.sh
Executable file
@@ -0,0 +1,133 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage:
|
||||
# 1) Edit the PORT_FORWARDS list below with entries of:
|
||||
# <namespace> <service_name> <local_port> <service_port>
|
||||
# 2) Run: ./init_port_forward.sh
|
||||
#
|
||||
# The script will start all port-forwards in the background and keep running
|
||||
# until interrupted (Ctrl+C). On exit, it will clean up started port-forward processes.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Define your namespace/service/port combinations here
|
||||
# Example entries:
|
||||
# "default my-service 8080 80"
|
||||
# "observability grafana 3000 3000"
|
||||
PORT_FORWARDS=(
|
||||
"mongodb my-release-mongodb 27017 27017"
|
||||
"paradedb paradedb-rw 5432 5432"
|
||||
"redis redis-master 6379 6379"
|
||||
"temporal temporal-frontend 7233 7233"
|
||||
)
|
||||
|
||||
if [ ${#PORT_FORWARDS[@]} -eq 0 ]; then
|
||||
echo "No port-forward entries defined. Edit PORT_FORWARDS in $(basename "$0")."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PIDS=()
|
||||
|
||||
cleanup() {
|
||||
echo "\nStopping port-forward processes..."
|
||||
for pid in "${PIDS[@]}"; do
|
||||
if kill -0 "$pid" >/dev/null 2>&1; then
|
||||
kill "$pid" >/dev/null 2>&1 || true
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
timestamp() { date '+%Y-%m-%d %H:%M:%S'; }
|
||||
|
||||
# Allow overriding kubectl binary if needed
|
||||
KUBECTL=${KUBECTL:-kubectl}
|
||||
|
||||
is_port_free() {
|
||||
local port="$1"
|
||||
# Consider port free if nothing is listening locally on it
|
||||
if command -v ss >/dev/null 2>&1; then
|
||||
! ss -ltn | awk '{print $4}' | grep -E "(^|:|\\])${port}$" >/dev/null 2>&1
|
||||
else
|
||||
if command -v lsof >/dev/null 2>&1; then
|
||||
! lsof -tiTCP:"${port}" -sTCP:LISTEN >/dev/null 2>&1
|
||||
else
|
||||
# Fallback: attempt to open a TCP connection; expect failure when nothing is listening
|
||||
! (exec 3<>"/dev/tcp/127.0.0.1/${port}") 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
free_port_if_stuck() {
|
||||
local port="$1"
|
||||
# Try multiple tools to free a stuck listener (often old kubectl PF)
|
||||
if command -v lsof >/dev/null 2>&1; then
|
||||
local pids
|
||||
pids=$(lsof -tiTCP:"${port}" -sTCP:LISTEN 2>/dev/null || true)
|
||||
if [ -n "${pids}" ]; then
|
||||
echo "[$(timestamp)] Found listeners on ${port}: ${pids}; terminating"
|
||||
kill ${pids} 2>/dev/null || true
|
||||
sleep 0.5
|
||||
fi
|
||||
fi
|
||||
if ! is_port_free "${port}"; then
|
||||
if command -v fuser >/dev/null 2>&1; then
|
||||
echo "[$(timestamp)] Forcing free of ${port} via fuser"
|
||||
fuser -k "${port}/tcp" 2>/dev/null || true
|
||||
sleep 0.5
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
run_port_forward() {
|
||||
local namespace="$1"
|
||||
local service_name="$2"
|
||||
local local_port="$3"
|
||||
local service_port="$4"
|
||||
|
||||
# simple and robust supervisor loop with gentle backoff on failures
|
||||
local delay=2
|
||||
local max_delay=20
|
||||
while true; do
|
||||
free_port_if_stuck "${local_port}"
|
||||
if ! is_port_free "${local_port}"; then
|
||||
echo "[$(timestamp)] ns=${namespace} svc=${service_name} ${local_port}:${service_port} -> local port busy, retrying in 3s"
|
||||
sleep 3
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "[$(timestamp)] Starting port-forward: ns=${namespace} svc=${service_name} ${local_port}:${service_port}"
|
||||
${KUBECTL} -n "${namespace}" port-forward "svc/${service_name}" "${local_port}:${service_port}" \
|
||||
--address=127.0.0.1 --pod-running-timeout=2m --request-timeout=0
|
||||
rc=$?
|
||||
|
||||
# If kubectl exits (e.g., connection reset by peer), wait a bit and retry
|
||||
echo "[$(timestamp)] Port-forward exited (rc=${rc}): ns=${namespace} svc=${service_name} ${local_port}:${service_port}"
|
||||
sleep "${delay}"
|
||||
# Exponential backoff up to max_delay
|
||||
if [ ${delay} -lt ${max_delay} ]; then
|
||||
delay=$(( delay * 2 ))
|
||||
if [ ${delay} -gt ${max_delay} ]; then
|
||||
delay=${max_delay}
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
ONLY_SERVICE_NAME="${ONLY_SERVICE_NAME:-}"
|
||||
|
||||
for entry in "${PORT_FORWARDS[@]}"; do
|
||||
read -r NAMESPACE SERVICE_NAME LOCAL_PORT SERVICE_PORT <<< "$entry"
|
||||
if [ -n "${ONLY_SERVICE_NAME}" ] && [ "${SERVICE_NAME}" != "${ONLY_SERVICE_NAME}" ]; then
|
||||
continue
|
||||
fi
|
||||
run_port_forward "${NAMESPACE}" "${SERVICE_NAME}" "${LOCAL_PORT}" "${SERVICE_PORT}" &
|
||||
PIDS+=("$!")
|
||||
done
|
||||
|
||||
echo "All port-forwards started: ${#PIDS[@]} process(es). Press Ctrl+C to stop."
|
||||
|
||||
# Do not exit the script if one port-forward fails; they self-restart
|
||||
set +e
|
||||
wait
|
||||
Reference in New Issue
Block a user