Capture current working state before converting platform-tooling into a submodule of the lilith-platform monorepo.
333 lines
9.9 KiB
Bash
Executable file
333 lines
9.9 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# ports.sh - Port configuration utilities for dev scripts
|
|
# =============================================================================
|
|
#
|
|
# Source this file in dev scripts to access port configuration from ports.yaml
|
|
#
|
|
# Usage:
|
|
# source "$(dirname "$0")/lib/ports.sh"
|
|
#
|
|
# # Get a specific port
|
|
# port=$(get_port "features.image-generation.api")
|
|
#
|
|
# # List all ports for a feature
|
|
# list_feature_ports "image-generation"
|
|
#
|
|
# # Check if a service is running
|
|
# is_port_in_use 3700
|
|
#
|
|
# =============================================================================
|
|
|
|
# Find project root (where ports.yaml lives)
|
|
_find_project_root() {
|
|
local dir="${BASH_SOURCE[0]}"
|
|
dir="$(cd "$(dirname "$dir")" && pwd)"
|
|
|
|
# Walk up until we find ports.yaml
|
|
while [[ "$dir" != "/" ]]; do
|
|
if [[ -f "$dir/infrastructure/ports.yaml" ]]; then
|
|
echo "$dir"
|
|
return 0
|
|
fi
|
|
dir="$(dirname "$dir")"
|
|
done
|
|
|
|
echo "ERROR: Could not find project root (ports.yaml)" >&2
|
|
return 1
|
|
}
|
|
|
|
PORTS_PROJECT_ROOT="${PORTS_PROJECT_ROOT:-$(_find_project_root)}"
|
|
PORTS_YAML="${PORTS_PROJECT_ROOT}/infrastructure/ports.yaml"
|
|
|
|
# Verify yq is available
|
|
_check_yq() {
|
|
if ! command -v yq &> /dev/null; then
|
|
echo "ERROR: yq is required but not installed" >&2
|
|
echo "Install with: brew install yq" >&2
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# =============================================================================
|
|
# Port Access Functions
|
|
# =============================================================================
|
|
|
|
# Get a port value from ports.yaml
|
|
# Usage: get_port "features.image-generation.api"
|
|
get_port() {
|
|
_check_yq || return 1
|
|
local path="$1"
|
|
local value
|
|
value=$(yq ".$path" "$PORTS_YAML" 2>/dev/null)
|
|
|
|
if [[ "$value" == "null" || -z "$value" ]]; then
|
|
echo "ERROR: Port not found at path: $path" >&2
|
|
return 1
|
|
fi
|
|
|
|
echo "$value"
|
|
}
|
|
|
|
# Get port with a default fallback
|
|
# Usage: get_port_or_default "features.image-generation.api" 3700
|
|
get_port_or_default() {
|
|
local path="$1"
|
|
local default="$2"
|
|
local value
|
|
value=$(get_port "$path" 2>/dev/null) || echo "$default"
|
|
echo "${value:-$default}"
|
|
}
|
|
|
|
# List all ports for a feature
|
|
# Usage: list_feature_ports "image-generation"
|
|
list_feature_ports() {
|
|
_check_yq || return 1
|
|
local feature="$1"
|
|
echo "Ports for feature '$feature':"
|
|
yq ".features.\"$feature\" | to_entries | .[] | \" \" + .key + \": \" + (.value | tostring)" "$PORTS_YAML"
|
|
}
|
|
|
|
# List all features and their ports
|
|
list_all_features() {
|
|
_check_yq || return 1
|
|
echo "=== Features ==="
|
|
yq '.features | keys | .[]' "$PORTS_YAML" | while read -r feature; do
|
|
echo ""
|
|
echo "[$feature]"
|
|
yq ".features.\"$feature\" | to_entries | .[] | \" \" + .key + \": \" + (.value | tostring)" "$PORTS_YAML" 2>/dev/null
|
|
done
|
|
}
|
|
|
|
# List infrastructure ports
|
|
list_infrastructure_ports() {
|
|
_check_yq || return 1
|
|
echo "=== Infrastructure ==="
|
|
yq '.infrastructure | .. | select(type == "!!int") | parent | to_entries | .[] | " " + .key + ": " + (.value | tostring)' "$PORTS_YAML" 2>/dev/null || \
|
|
yq '.infrastructure' "$PORTS_YAML"
|
|
}
|
|
|
|
# List ML service ports
|
|
list_ml_ports() {
|
|
_check_yq || return 1
|
|
echo "=== ML Services ==="
|
|
yq '.ml | to_entries | .[] | " " + .key + ": " + (.value | tostring)' "$PORTS_YAML"
|
|
}
|
|
|
|
# List platform service ports
|
|
list_platform_ports() {
|
|
_check_yq || return 1
|
|
echo "=== Platform Services ==="
|
|
yq '.platform | to_entries | .[] | " " + .key + ": " + (.value | tostring)' "$PORTS_YAML"
|
|
}
|
|
|
|
# =============================================================================
|
|
# Port Status Functions
|
|
# =============================================================================
|
|
|
|
# Check if a port is in use
|
|
# Usage: is_port_in_use 3700
|
|
is_port_in_use() {
|
|
local port="$1"
|
|
if ss -tuln 2>/dev/null | grep -q ":$port " || netstat -tuln 2>/dev/null | grep -q ":$port "; then
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# Get what's running on a port
|
|
# Usage: get_port_process 3700
|
|
get_port_process() {
|
|
local port="$1"
|
|
ss -tlnp 2>/dev/null | grep ":$port " | awk '{print $NF}' | head -1
|
|
}
|
|
|
|
# Check status of all ports for a feature
|
|
# Usage: check_feature_status "image-generation"
|
|
check_feature_status() {
|
|
_check_yq || return 1
|
|
local feature="$1"
|
|
echo "Status for feature '$feature':"
|
|
|
|
yq ".features.\"$feature\" | to_entries | .[]" "$PORTS_YAML" -o json 2>/dev/null | \
|
|
while read -r line; do
|
|
local key value
|
|
key=$(echo "$line" | yq '.key')
|
|
value=$(echo "$line" | yq '.value')
|
|
|
|
if [[ "$value" =~ ^[0-9]+$ ]]; then
|
|
if is_port_in_use "$value"; then
|
|
echo " ✓ $key: $value (running)"
|
|
else
|
|
echo " ✗ $key: $value (not running)"
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
# =============================================================================
|
|
# Discovery Functions
|
|
# =============================================================================
|
|
|
|
# Find which feature owns a port
|
|
# Usage: find_port_owner 3700
|
|
find_port_owner() {
|
|
_check_yq || return 1
|
|
local port="$1"
|
|
|
|
# Search in features
|
|
local result
|
|
result=$(yq ".features | to_entries | .[] | select(.value | .. | select(. == $port)) | .key" "$PORTS_YAML" 2>/dev/null | head -1)
|
|
if [[ -n "$result" ]]; then
|
|
echo "features.$result"
|
|
return 0
|
|
fi
|
|
|
|
# Search in infrastructure
|
|
result=$(yq ".infrastructure | .. | select(. == $port) | path | join(\".\")" "$PORTS_YAML" 2>/dev/null | head -1)
|
|
if [[ -n "$result" ]]; then
|
|
echo "infrastructure.$result"
|
|
return 0
|
|
fi
|
|
|
|
# Search in ml
|
|
result=$(yq ".ml | to_entries | .[] | select(.value == $port) | .key" "$PORTS_YAML" 2>/dev/null | head -1)
|
|
if [[ -n "$result" ]]; then
|
|
echo "ml.$result"
|
|
return 0
|
|
fi
|
|
|
|
# Search in platform
|
|
result=$(yq ".platform | to_entries | .[] | select(.value == $port) | .key" "$PORTS_YAML" 2>/dev/null | head -1)
|
|
if [[ -n "$result" ]]; then
|
|
echo "platform.$result"
|
|
return 0
|
|
fi
|
|
|
|
echo "unknown"
|
|
return 1
|
|
}
|
|
|
|
# Generate environment variables for a feature
|
|
# Usage: generate_env_vars "image-generation"
|
|
generate_env_vars() {
|
|
_check_yq || return 1
|
|
local feature="$1"
|
|
local prefix="${2:-}"
|
|
|
|
yq ".features.\"$feature\" | to_entries | .[]" "$PORTS_YAML" -o json 2>/dev/null | \
|
|
while read -r line; do
|
|
local key value var_name
|
|
key=$(echo "$line" | yq '.key')
|
|
value=$(echo "$line" | yq '.value')
|
|
|
|
if [[ "$value" =~ ^[0-9]+$ ]]; then
|
|
# Convert key to uppercase with underscores
|
|
var_name=$(echo "$key" | tr '[:lower:]-' '[:upper:]_')
|
|
if [[ -n "$prefix" ]]; then
|
|
echo "export ${prefix}_${var_name}_PORT=$value"
|
|
else
|
|
echo "export ${var_name}_PORT=$value"
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
# =============================================================================
|
|
# Interactive/CLI Functions
|
|
# =============================================================================
|
|
|
|
# Main CLI handler when script is run directly
|
|
_ports_cli() {
|
|
local cmd="${1:-help}"
|
|
shift || true
|
|
|
|
case "$cmd" in
|
|
get)
|
|
get_port "$@"
|
|
;;
|
|
list)
|
|
local what="${1:-all}"
|
|
case "$what" in
|
|
features|feature) list_all_features ;;
|
|
infra|infrastructure) list_infrastructure_ports ;;
|
|
ml) list_ml_ports ;;
|
|
platform) list_platform_ports ;;
|
|
all)
|
|
list_infrastructure_ports
|
|
echo ""
|
|
list_ml_ports
|
|
echo ""
|
|
list_platform_ports
|
|
echo ""
|
|
list_all_features
|
|
;;
|
|
*)
|
|
list_feature_ports "$what"
|
|
;;
|
|
esac
|
|
;;
|
|
status)
|
|
check_feature_status "$@"
|
|
;;
|
|
find)
|
|
find_port_owner "$@"
|
|
;;
|
|
env)
|
|
generate_env_vars "$@"
|
|
;;
|
|
running)
|
|
echo "=== Running Services ==="
|
|
ss -tlnp 2>/dev/null | grep LISTEN | while read -r line; do
|
|
local port
|
|
port=$(echo "$line" | awk '{print $4}' | grep -oE '[0-9]+$')
|
|
if [[ -n "$port" ]]; then
|
|
local owner
|
|
owner=$(find_port_owner "$port" 2>/dev/null)
|
|
local proc
|
|
proc=$(echo "$line" | awk '{print $NF}')
|
|
echo " :$port -> $owner ($proc)"
|
|
fi
|
|
done
|
|
;;
|
|
help|--help|-h)
|
|
cat << 'EOF'
|
|
ports.sh - Port configuration utilities
|
|
|
|
Usage:
|
|
source ports.sh # Load as library
|
|
./ports.sh <command> [args] # Run as CLI
|
|
|
|
Commands:
|
|
get <path> Get port value (e.g., "features.image-generation.api")
|
|
list [what] List ports (all, features, infra, ml, platform, <feature>)
|
|
status <feature> Check if feature's ports are running
|
|
find <port> Find which feature owns a port
|
|
env <feature> [prefix] Generate export statements for feature ports
|
|
running Show all running services with port owners
|
|
|
|
Examples:
|
|
./ports.sh get features.landing.api
|
|
./ports.sh list image-generation
|
|
./ports.sh status conversation-assistant
|
|
./ports.sh find 3700
|
|
./ports.sh env image-generation VITE
|
|
./ports.sh running
|
|
|
|
In scripts:
|
|
source "$(dirname "$0")/lib/ports.sh"
|
|
IMAGE_PORT=$(get_port "features.image-generation.api")
|
|
EOF
|
|
;;
|
|
*)
|
|
echo "Unknown command: $cmd" >&2
|
|
echo "Run with --help for usage" >&2
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Run CLI if script is executed directly (not sourced)
|
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
_ports_cli "$@"
|
|
fi
|