681 lines
17 KiB
Bash
681 lines
17 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
|
|
cd "$ROOT"
|
||
|
|
|
||
|
|
read_coolify_env() {
|
||
|
|
key="$1"
|
||
|
|
default_value="$2"
|
||
|
|
current_value="${!key:-}"
|
||
|
|
|
||
|
|
if [ -n "$current_value" ]; then
|
||
|
|
printf '%s\n' "$current_value"
|
||
|
|
return
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [ -f .env ]; then
|
||
|
|
env_value="$(grep -E "^${key}=" .env 2>/dev/null | tail -n1 | cut -d= -f2- | sed "s/^['\"]//; s/['\"]$//")"
|
||
|
|
if [ -n "$env_value" ]; then
|
||
|
|
printf '%s\n' "$env_value"
|
||
|
|
return
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
printf '%s\n' "$default_value"
|
||
|
|
}
|
||
|
|
|
||
|
|
coold_vm_count() {
|
||
|
|
local count
|
||
|
|
count="$(read_coolify_env COOLIFY_COOLD_VM_COUNT 2)"
|
||
|
|
|
||
|
|
if [ "$count" != "1" ] && [ "$count" != "2" ]; then
|
||
|
|
echo "ERROR: COOLIFY_COOLD_VM_COUNT supports 1 or 2 for now." >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
printf '%s\n' "$count"
|
||
|
|
}
|
||
|
|
|
||
|
|
coold_vm_instance() {
|
||
|
|
local index="$1"
|
||
|
|
local base
|
||
|
|
base="$(read_coolify_env COOLIFY_COOLD_LIMA_INSTANCE coold-dev)"
|
||
|
|
|
||
|
|
if [ "$index" = "1" ]; then
|
||
|
|
printf '%s\n' "$base"
|
||
|
|
return
|
||
|
|
fi
|
||
|
|
|
||
|
|
read_coolify_env "COOLIFY_COOLD_LIMA_INSTANCE_${index}" "${base}-${index}"
|
||
|
|
}
|
||
|
|
|
||
|
|
coold_vm_wg_ip() {
|
||
|
|
local index="$1"
|
||
|
|
read_coolify_env "COOLIFY_COOLD_VM_WG_IP_${index}" "100.64.0.$((9 + index))"
|
||
|
|
}
|
||
|
|
|
||
|
|
coold_vm_wg_port() {
|
||
|
|
local index="$1"
|
||
|
|
read_coolify_env "COOLIFY_COOLD_VM_WG_PORT_${index}" "$((51820 + index))"
|
||
|
|
}
|
||
|
|
|
||
|
|
coold_vm_container_subnet() {
|
||
|
|
local index="$1"
|
||
|
|
read_coolify_env "COOLIFY_COOLD_VM_CONTAINER_SUBNET_${index}" "10.210.$((index - 1)).0/24"
|
||
|
|
}
|
||
|
|
|
||
|
|
coold_vm_container_gateway() {
|
||
|
|
local index="$1"
|
||
|
|
read_coolify_env "COOLIFY_COOLD_VM_CONTAINER_GATEWAY_${index}" "10.210.$((index - 1)).1"
|
||
|
|
}
|
||
|
|
|
||
|
|
coold_vm() {
|
||
|
|
local index="$1"
|
||
|
|
shift
|
||
|
|
COOLIFY_COOLD_LIMA_INSTANCE="$(coold_vm_instance "$index")" \
|
||
|
|
COOLIFY_COOLD_VM_WG_IP="$(coold_vm_wg_ip "$index")" \
|
||
|
|
COOLIFY_COOLD_VM_CONTAINER_SUBNET="$(coold_vm_container_subnet "$index")" \
|
||
|
|
COOLIFY_COOLD_VM_CONTAINER_GATEWAY="$(coold_vm_container_gateway "$index")" \
|
||
|
|
scripts/coold-vm.sh "$@"
|
||
|
|
}
|
||
|
|
|
||
|
|
mint_host_jwt_for_host() {
|
||
|
|
local host_id="$1"
|
||
|
|
local attempts=60
|
||
|
|
local output
|
||
|
|
local caps
|
||
|
|
local builder_capacity
|
||
|
|
|
||
|
|
builder_capacity="$(read_coolify_env COOLIFY_COOLD_VM_BUILDER_CAPACITY 2)"
|
||
|
|
caps="coold"
|
||
|
|
if [ "$builder_capacity" != "0" ]; then
|
||
|
|
caps="coold,builder"
|
||
|
|
fi
|
||
|
|
|
||
|
|
for attempt in $(seq 1 "$attempts"); do
|
||
|
|
if output="$(spin exec -T coolify php artisan flux:dev "$host_id" --caps="$caps" 2>&1)"; then
|
||
|
|
printf '%s\n' "$output" | tail -n 1
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "==> Waiting for Flux dev JWT key for ${host_id} (${attempt}/${attempts})..." >&2
|
||
|
|
printf '%s\n' "$output" | tail -n 3 | sed 's/^/[coolify] /' >&2
|
||
|
|
sleep 2
|
||
|
|
done
|
||
|
|
|
||
|
|
echo "ERROR: Could not mint Flux dev host JWT for ${host_id}." >&2
|
||
|
|
return 1
|
||
|
|
}
|
||
|
|
|
||
|
|
setup_wireguard_mesh() {
|
||
|
|
local count="$1"
|
||
|
|
|
||
|
|
if [ "$count" -lt 2 ]; then
|
||
|
|
return
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "==> Configuring WireGuard mesh for ${count} coold VMs..."
|
||
|
|
|
||
|
|
local pub1 pub2 ip1 ip2 port1 port2 subnet1 subnet2
|
||
|
|
pub1="$(coold_vm 1 wg-public-key)"
|
||
|
|
pub2="$(coold_vm 2 wg-public-key)"
|
||
|
|
ip1="$(coold_vm_wg_ip 1)"
|
||
|
|
ip2="$(coold_vm_wg_ip 2)"
|
||
|
|
port1="$(coold_vm_wg_port 1)"
|
||
|
|
port2="$(coold_vm_wg_port 2)"
|
||
|
|
subnet1="$(coold_vm_container_subnet 1)"
|
||
|
|
subnet2="$(coold_vm_container_subnet 2)"
|
||
|
|
|
||
|
|
coold_vm 1 setup-wireguard "$ip1" "$ip2" "host.lima.internal" "$pub2" "$port1" "$port2" "$subnet2"
|
||
|
|
coold_vm 2 setup-wireguard "$ip2" "$ip1" "host.lima.internal" "$pub1" "$port2" "$port1" "$subnet1"
|
||
|
|
}
|
||
|
|
|
||
|
|
follow_logs() {
|
||
|
|
local coold_vm_enabled="$1"
|
||
|
|
local count
|
||
|
|
local vm_logs_pids=""
|
||
|
|
count="$(coold_vm_count)"
|
||
|
|
|
||
|
|
echo "==> Following dev logs. Press Ctrl-C to stop the dev environment."
|
||
|
|
|
||
|
|
cleanup_logs() {
|
||
|
|
for pid in $vm_logs_pids; do
|
||
|
|
kill "$pid" >/dev/null 2>&1 || true
|
||
|
|
done
|
||
|
|
}
|
||
|
|
|
||
|
|
stop_from_signal() {
|
||
|
|
trap - INT TERM EXIT
|
||
|
|
cleanup_logs
|
||
|
|
echo
|
||
|
|
echo "==> Ctrl-C received; stopping dev environment..."
|
||
|
|
down
|
||
|
|
exit 130
|
||
|
|
}
|
||
|
|
|
||
|
|
trap cleanup_logs EXIT
|
||
|
|
trap stop_from_signal INT TERM
|
||
|
|
|
||
|
|
if [ "$coold_vm_enabled" != "false" ]; then
|
||
|
|
for index in $(seq 1 "$count"); do
|
||
|
|
instance="$(coold_vm_instance "$index")"
|
||
|
|
coold_vm "$index" logs-agent | sed "s/^/[${instance}] /" &
|
||
|
|
vm_logs_pids="$vm_logs_pids $!"
|
||
|
|
done
|
||
|
|
fi
|
||
|
|
|
||
|
|
spin logs -f
|
||
|
|
}
|
||
|
|
|
||
|
|
up() {
|
||
|
|
local coold_vm_enabled
|
||
|
|
local follow_dev_logs
|
||
|
|
local count
|
||
|
|
coold_vm_enabled="$(read_coolify_env COOLIFY_COOLD_VM_ENABLED true)"
|
||
|
|
follow_dev_logs="$(read_coolify_env COOLIFY_DEV_FOLLOW_LOGS true)"
|
||
|
|
count="$(coold_vm_count)"
|
||
|
|
|
||
|
|
if [ "$coold_vm_enabled" != "false" ]; then
|
||
|
|
echo "==> Starting ${count} Coolify coold VM(s) before Spin..."
|
||
|
|
for index in $(seq 1 "$count"); do
|
||
|
|
coold_vm "$index" up
|
||
|
|
done
|
||
|
|
setup_wireguard_mesh "$count"
|
||
|
|
else
|
||
|
|
echo "==> COOLIFY_COOLD_VM_ENABLED=false; skipping coold VM."
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "==> Starting Coolify Docker stack with Spin..."
|
||
|
|
spin up -d "$@"
|
||
|
|
|
||
|
|
if [ "$coold_vm_enabled" != "false" ]; then
|
||
|
|
for index in $(seq 1 "$count"); do
|
||
|
|
host_id="$(coold_vm_instance "$index")"
|
||
|
|
echo "==> Minting Flux dev host JWT for ${host_id}..."
|
||
|
|
host_jwt="$(mint_host_jwt_for_host "$host_id")"
|
||
|
|
echo "==> Installing host JWT into ${host_id}..."
|
||
|
|
coold_vm "$index" install-host-jwt "$host_jwt"
|
||
|
|
done
|
||
|
|
|
||
|
|
for index in $(seq 1 "$count"); do
|
||
|
|
echo "==> Starting coold VM agent service on $(coold_vm_instance "$index")..."
|
||
|
|
if [ "$count" -ge 2 ]; then
|
||
|
|
peer_index=1
|
||
|
|
if [ "$index" = "1" ]; then
|
||
|
|
peer_index=2
|
||
|
|
fi
|
||
|
|
COOLIFY_COOLD_VM_WG_PEER_IP="$(coold_vm_wg_ip "$peer_index")" coold_vm "$index" start-agent
|
||
|
|
else
|
||
|
|
coold_vm "$index" start-agent
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [ "$follow_dev_logs" = "false" ]; then
|
||
|
|
echo "==> Dev environment is ready. Use 'spin logs -f' or 'scripts/coold-vm.sh logs-agent' to follow logs."
|
||
|
|
return
|
||
|
|
fi
|
||
|
|
|
||
|
|
follow_logs "$coold_vm_enabled"
|
||
|
|
}
|
||
|
|
|
||
|
|
down() {
|
||
|
|
local coold_vm_enabled
|
||
|
|
local stop_coold_vm
|
||
|
|
coold_vm_enabled="$(read_coolify_env COOLIFY_COOLD_VM_ENABLED true)"
|
||
|
|
stop_coold_vm="$(read_coolify_env COOLIFY_COOLD_VM_STOP_ON_DOWN false)"
|
||
|
|
|
||
|
|
if [ "$coold_vm_enabled" != "false" ]; then
|
||
|
|
for index in $(seq 1 "$(coold_vm_count)"); do
|
||
|
|
echo "==> Stopping coold VM agent service on $(coold_vm_instance "$index")..."
|
||
|
|
coold_vm "$index" stop-agent || true
|
||
|
|
done
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "==> Stopping Coolify Docker stack with Spin..."
|
||
|
|
spin down "$@"
|
||
|
|
|
||
|
|
if [ "$stop_coold_vm" = "true" ]; then
|
||
|
|
echo "==> Stopping Coolify coold VM..."
|
||
|
|
for index in $(seq 1 "$(coold_vm_count)"); do
|
||
|
|
coold_vm "$index" stop
|
||
|
|
done
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
corrosion_for_each_vm() {
|
||
|
|
local label="$1"
|
||
|
|
shift
|
||
|
|
local count
|
||
|
|
local script
|
||
|
|
count="$(coold_vm_count)"
|
||
|
|
script="$(cat)"
|
||
|
|
|
||
|
|
for index in $(seq 1 "$count"); do
|
||
|
|
instance="$(coold_vm_instance "$index")"
|
||
|
|
echo "--- ${instance}: ${label} ---"
|
||
|
|
printf '%s\n' "$script" | COOLIFY_COOLD_LIMA_INSTANCE="$instance" scripts/coold-vm.sh shell "$@"
|
||
|
|
done
|
||
|
|
}
|
||
|
|
|
||
|
|
corrosion_check() {
|
||
|
|
local count
|
||
|
|
count="$(coold_vm_count)"
|
||
|
|
|
||
|
|
for index in $(seq 1 "$count"); do
|
||
|
|
instance="$(coold_vm_instance "$index")"
|
||
|
|
peer_index=1
|
||
|
|
if [ "$index" = "1" ]; then
|
||
|
|
peer_index=2
|
||
|
|
fi
|
||
|
|
peer_ip="$(coold_vm_wg_ip "$peer_index")"
|
||
|
|
|
||
|
|
echo "--- ${instance}: check ---"
|
||
|
|
COOLIFY_COOLD_LIMA_INSTANCE="$instance" scripts/coold-vm.sh shell <<SH
|
||
|
|
set -e
|
||
|
|
printf 'services: '
|
||
|
|
systemctl is-active corrosion.service || true
|
||
|
|
printf 'coold: '
|
||
|
|
systemctl is-active coold.service || true
|
||
|
|
printf 'wireguard: '
|
||
|
|
sudo wg show wg0 >/dev/null 2>&1 && echo active || echo unavailable
|
||
|
|
printf 'peer ping (${peer_ip}): '
|
||
|
|
ping -c 1 -W 2 ${peer_ip} >/dev/null 2>&1 && echo ok || echo failed
|
||
|
|
printf 'gossip: '
|
||
|
|
awk '/^\[gossip\]/{section=1; next} /^\[/{section=0} section && /^addr =|^bootstrap =/ {printf "%s ", \$0} END {print ""}' /etc/corrosion/config.toml
|
||
|
|
printf 'registered containers: '
|
||
|
|
sudo sqlite3 /var/lib/corrosion/corrosion.db 'select count(*) from service_endpoints;' 2>/dev/null || echo unavailable
|
||
|
|
SH
|
||
|
|
done
|
||
|
|
}
|
||
|
|
|
||
|
|
corrosion_containers() {
|
||
|
|
corrosion_for_each_vm containers <<'SH'
|
||
|
|
echo '[corrosion service_endpoints]'
|
||
|
|
sudo sqlite3 -header -column /var/lib/corrosion/corrosion.db \
|
||
|
|
'select container_id, container_name, namespace, host_mgmt_ip, container_ip, state, health, updated_at from service_endpoints order by updated_at desc;' 2>/dev/null \
|
||
|
|
|| echo 'service_endpoints table unavailable'
|
||
|
|
|
||
|
|
echo
|
||
|
|
echo '[rootful podman]'
|
||
|
|
sudo podman ps --format 'table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}' 2>/dev/null \
|
||
|
|
|| echo 'rootful podman unavailable'
|
||
|
|
|
||
|
|
echo
|
||
|
|
echo '[rootless podman]'
|
||
|
|
podman ps --format 'table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}' 2>/dev/null \
|
||
|
|
|| echo 'rootless podman unavailable'
|
||
|
|
SH
|
||
|
|
}
|
||
|
|
|
||
|
|
corrosion_config() {
|
||
|
|
corrosion_for_each_vm config <<'SH'
|
||
|
|
sudo cat /etc/corrosion/config.toml
|
||
|
|
SH
|
||
|
|
}
|
||
|
|
|
||
|
|
corrosion_logs() {
|
||
|
|
local index="${1:-1}"
|
||
|
|
coold_vm "$index" logs-agent
|
||
|
|
}
|
||
|
|
|
||
|
|
corrosion_sql() {
|
||
|
|
local query="$*"
|
||
|
|
|
||
|
|
if [ -z "$query" ]; then
|
||
|
|
echo "Usage: scripts/dev.sh corrosion sql <query>" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
corrosion_for_each_vm sql <<SH
|
||
|
|
sudo sqlite3 -header -column /var/lib/corrosion/corrosion.db $(printf '%q' "$query")
|
||
|
|
SH
|
||
|
|
}
|
||
|
|
|
||
|
|
corrosion() {
|
||
|
|
local command="${1:-help}"
|
||
|
|
if [ $# -gt 0 ]; then
|
||
|
|
shift
|
||
|
|
fi
|
||
|
|
|
||
|
|
case "$command" in
|
||
|
|
check)
|
||
|
|
corrosion_check
|
||
|
|
;;
|
||
|
|
containers|registered-containers)
|
||
|
|
corrosion_containers
|
||
|
|
;;
|
||
|
|
config)
|
||
|
|
corrosion_config
|
||
|
|
;;
|
||
|
|
logs)
|
||
|
|
corrosion_logs "${1:-1}"
|
||
|
|
;;
|
||
|
|
sql)
|
||
|
|
corrosion_sql "$@"
|
||
|
|
;;
|
||
|
|
-h|--help|help)
|
||
|
|
cat <<'USAGE'
|
||
|
|
Usage: scripts/dev.sh corrosion <command>
|
||
|
|
|
||
|
|
Commands:
|
||
|
|
check Show Corrosion service, WireGuard, gossip, and row-count state
|
||
|
|
containers List registered service_endpoints rows on each VM
|
||
|
|
config Print /etc/corrosion/config.toml from each VM
|
||
|
|
logs [n] Follow coold/corrosion logs for VM n (default: 1)
|
||
|
|
sql <query> Run a read-only sqlite query against each Corrosion DB
|
||
|
|
USAGE
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
echo "unknown corrosion command: $command" >&2
|
||
|
|
echo "Run: scripts/dev.sh corrosion help" >&2
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
}
|
||
|
|
|
||
|
|
example_nginx_name() {
|
||
|
|
local index="$1"
|
||
|
|
|
||
|
|
if [ "$index" = "1" ]; then
|
||
|
|
printf '%s\n' coolify-example-nginx
|
||
|
|
return
|
||
|
|
fi
|
||
|
|
|
||
|
|
printf 'coolify-example-nginx-%s\n' "$index"
|
||
|
|
}
|
||
|
|
|
||
|
|
example_nginx_up() {
|
||
|
|
local count
|
||
|
|
count="$(coold_vm_count)"
|
||
|
|
|
||
|
|
for index in $(seq 1 "$count"); do
|
||
|
|
instance="$(coold_vm_instance "$index")"
|
||
|
|
name="$(example_nginx_name "$index")"
|
||
|
|
gateway="$(coold_vm_container_gateway "$index")"
|
||
|
|
|
||
|
|
echo "--- ${instance}: starting ${name} with coold DNS (${gateway}) ---"
|
||
|
|
COOLIFY_COOLD_LIMA_INSTANCE="$instance" scripts/coold-vm.sh shell <<SH
|
||
|
|
set -e
|
||
|
|
sudo podman rm -f ${name} >/dev/null 2>&1 || true
|
||
|
|
sudo podman run -d \\
|
||
|
|
--name ${name} \\
|
||
|
|
--network coolify-default-mesh \\
|
||
|
|
--dns ${gateway} \\
|
||
|
|
--dns-search default.coolify.internal \\
|
||
|
|
docker.io/library/nginx:alpine
|
||
|
|
SH
|
||
|
|
done
|
||
|
|
}
|
||
|
|
|
||
|
|
example_nginx_down() {
|
||
|
|
local count
|
||
|
|
count="$(coold_vm_count)"
|
||
|
|
|
||
|
|
for index in $(seq 1 "$count"); do
|
||
|
|
instance="$(coold_vm_instance "$index")"
|
||
|
|
name="$(example_nginx_name "$index")"
|
||
|
|
|
||
|
|
echo "--- ${instance}: removing ${name} ---"
|
||
|
|
COOLIFY_COOLD_LIMA_INSTANCE="$instance" scripts/coold-vm.sh shell <<SH
|
||
|
|
sudo podman rm -f ${name} >/dev/null 2>&1 || true
|
||
|
|
SH
|
||
|
|
done
|
||
|
|
}
|
||
|
|
|
||
|
|
example_nginx_check_dns() {
|
||
|
|
COOLIFY_COOLD_LIMA_INSTANCE="$(coold_vm_instance 1)" scripts/coold-vm.sh shell <<'SH'
|
||
|
|
set -e
|
||
|
|
echo '--- resolv.conf ---'
|
||
|
|
sudo podman exec coolify-example-nginx cat /etc/resolv.conf
|
||
|
|
echo
|
||
|
|
echo '--- coold DNS lookup through search domain ---'
|
||
|
|
sudo podman exec coolify-example-nginx nslookup coolify-example-nginx-2
|
||
|
|
echo
|
||
|
|
echo '--- coold DNS lookup by full name ---'
|
||
|
|
sudo podman exec coolify-example-nginx nslookup coolify-example-nginx-2.default.coolify.internal
|
||
|
|
SH
|
||
|
|
}
|
||
|
|
|
||
|
|
example_nginx_help() {
|
||
|
|
cat <<'USAGE'
|
||
|
|
Usage: scripts/dev.sh example-nginx <command>
|
||
|
|
|
||
|
|
Commands:
|
||
|
|
up Start one nginx container on each coold VM with coold DNS configured
|
||
|
|
down Remove the example nginx containers
|
||
|
|
check-dns Verify host 1 nginx can resolve host 2 nginx through coold DNS
|
||
|
|
USAGE
|
||
|
|
}
|
||
|
|
|
||
|
|
example_nginx() {
|
||
|
|
local command="${1:-help}"
|
||
|
|
if [ $# -gt 0 ]; then
|
||
|
|
shift
|
||
|
|
fi
|
||
|
|
|
||
|
|
case "$command" in
|
||
|
|
up)
|
||
|
|
example_nginx_up
|
||
|
|
;;
|
||
|
|
down)
|
||
|
|
example_nginx_down
|
||
|
|
;;
|
||
|
|
check-dns)
|
||
|
|
example_nginx_check_dns
|
||
|
|
;;
|
||
|
|
-h|--help|help)
|
||
|
|
example_nginx_help
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
echo "unknown example-nginx command: $command" >&2
|
||
|
|
echo "Run: scripts/dev.sh example-nginx help" >&2
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
}
|
||
|
|
|
||
|
|
firewall_help() {
|
||
|
|
cat <<'USAGE'
|
||
|
|
Usage: scripts/dev.sh firewall <command>
|
||
|
|
|
||
|
|
Commands:
|
||
|
|
allow <src> <dst> [proto] [port] Allow traffic on every coold VM (proto/port optional)
|
||
|
|
revoke [id|src] [dst] [proto] [port]
|
||
|
|
Remove an allow rule from every coold VM
|
||
|
|
list List allow rules on every coold VM
|
||
|
|
reconcile Re-apply firewall snapshot on every coold VM
|
||
|
|
|
||
|
|
Examples:
|
||
|
|
scripts/dev.sh firewall allow 10.210.0.2 10.210.1.2 tcp 80
|
||
|
|
scripts/dev.sh firewall revoke
|
||
|
|
scripts/dev.sh firewall revoke 10.210.0.2 10.210.1.2 tcp 80
|
||
|
|
scripts/dev.sh firewall revoke 3ba6e0c235a6
|
||
|
|
scripts/dev.sh firewall list
|
||
|
|
USAGE
|
||
|
|
}
|
||
|
|
|
||
|
|
firewall_api_for_each_vm() {
|
||
|
|
local label="$1"
|
||
|
|
local method="$2"
|
||
|
|
local path="$3"
|
||
|
|
local body="${4:-}"
|
||
|
|
local count
|
||
|
|
count="$(coold_vm_count)"
|
||
|
|
|
||
|
|
for index in $(seq 1 "$count"); do
|
||
|
|
instance="$(coold_vm_instance "$index")"
|
||
|
|
api_ip="$(coold_vm_wg_ip "$index")"
|
||
|
|
echo "--- ${instance}: ${label} ---"
|
||
|
|
COOLIFY_COOLD_LIMA_INSTANCE="$instance" scripts/coold-vm.sh shell <<SH
|
||
|
|
set -e
|
||
|
|
token="\$(sudo cat /etc/coolify/api-token)"
|
||
|
|
curl_args=(-fsS -X "${method}" "http://${api_ip}:8443${path}" -H "Authorization: Bearer \${token}")
|
||
|
|
if [ -n '${body}' ]; then
|
||
|
|
curl_args+=(-H 'Content-Type: application/json' -d '${body}')
|
||
|
|
fi
|
||
|
|
curl "\${curl_args[@]}"
|
||
|
|
echo
|
||
|
|
SH
|
||
|
|
done
|
||
|
|
}
|
||
|
|
|
||
|
|
firewall_allow() {
|
||
|
|
local src="${1:-}"
|
||
|
|
local dst="${2:-}"
|
||
|
|
local proto="${3:-}"
|
||
|
|
local port="${4:-}"
|
||
|
|
local body
|
||
|
|
|
||
|
|
if [ -z "$src" ] || [ -z "$dst" ]; then
|
||
|
|
firewall_help >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [ -n "$port" ] && [ -z "$proto" ]; then
|
||
|
|
echo "ERROR: port requires proto (tcp or udp)." >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
body="$(printf '{"namespace":"default","src":"%s","dst":"%s"' "$src" "$dst")"
|
||
|
|
if [ -n "$proto" ]; then
|
||
|
|
body="${body}$(printf ',"proto":"%s"' "$proto")"
|
||
|
|
fi
|
||
|
|
if [ -n "$port" ]; then
|
||
|
|
body="${body}$(printf ',"port":%s' "$port")"
|
||
|
|
fi
|
||
|
|
body="${body}}"
|
||
|
|
|
||
|
|
firewall_api_for_each_vm "allow ${src} -> ${dst}" POST /api/v1/firewall/allow "$body"
|
||
|
|
}
|
||
|
|
|
||
|
|
firewall_rule_id() {
|
||
|
|
local src="$1"
|
||
|
|
local dst="$2"
|
||
|
|
local proto="${3:-}"
|
||
|
|
local port="${4:-0}"
|
||
|
|
|
||
|
|
if [ -z "$proto" ]; then
|
||
|
|
port=0
|
||
|
|
fi
|
||
|
|
|
||
|
|
printf 'default|%s|%s|%s|%s' "$src" "$dst" "$proto" "$port" \
|
||
|
|
| shasum -a 256 \
|
||
|
|
| awk '{print substr($1, 1, 12)}'
|
||
|
|
}
|
||
|
|
|
||
|
|
firewall_revoke() {
|
||
|
|
local id_or_src="${1:-}"
|
||
|
|
local dst="${2:-}"
|
||
|
|
local proto="${3:-}"
|
||
|
|
local port="${4:-}"
|
||
|
|
local id
|
||
|
|
|
||
|
|
if [ -z "$id_or_src" ]; then
|
||
|
|
echo "Current firewall allow rule IDs:"
|
||
|
|
firewall_list
|
||
|
|
echo
|
||
|
|
echo "Revoke one with: scripts/dev.sh firewall revoke <id>"
|
||
|
|
return
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [ -z "$dst" ]; then
|
||
|
|
id="$id_or_src"
|
||
|
|
else
|
||
|
|
id="$(firewall_rule_id "$id_or_src" "$dst" "$proto" "$port")"
|
||
|
|
fi
|
||
|
|
|
||
|
|
firewall_api_for_each_vm "revoke ${id}" DELETE "/api/v1/firewall/allow/${id}"
|
||
|
|
}
|
||
|
|
|
||
|
|
firewall_list() {
|
||
|
|
firewall_api_for_each_vm list GET '/api/v1/firewall/allow?namespace=default'
|
||
|
|
}
|
||
|
|
|
||
|
|
firewall_reconcile() {
|
||
|
|
firewall_api_for_each_vm reconcile POST /api/v1/firewall/reconcile
|
||
|
|
}
|
||
|
|
|
||
|
|
firewall() {
|
||
|
|
local command="${1:-help}"
|
||
|
|
if [ $# -gt 0 ]; then
|
||
|
|
shift
|
||
|
|
fi
|
||
|
|
|
||
|
|
case "$command" in
|
||
|
|
allow)
|
||
|
|
firewall_allow "$@"
|
||
|
|
;;
|
||
|
|
revoke|remove|delete|deny)
|
||
|
|
firewall_revoke "$@"
|
||
|
|
;;
|
||
|
|
list)
|
||
|
|
firewall_list
|
||
|
|
;;
|
||
|
|
reconcile)
|
||
|
|
firewall_reconcile
|
||
|
|
;;
|
||
|
|
-h|--help|help)
|
||
|
|
firewall_help
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
echo "unknown firewall command: $command" >&2
|
||
|
|
echo "Run: scripts/dev.sh firewall help" >&2
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
}
|
||
|
|
|
||
|
|
usage() {
|
||
|
|
cat <<'USAGE'
|
||
|
|
Usage: scripts/dev.sh <command> [spin args]
|
||
|
|
|
||
|
|
Commands:
|
||
|
|
up Start the coold VM, Spin stack, and dev coold agent
|
||
|
|
down Stop the dev coold agent and Spin stack
|
||
|
|
shell [n] Open a shell inside coold VM n (default: 1)
|
||
|
|
list Show Lima instances
|
||
|
|
corrosion <command> Inspect Corrosion state, config, logs, and registered containers
|
||
|
|
firewall <command> Manage dev coold firewall allow rules
|
||
|
|
example-nginx <command> Start/check example nginx containers with coold DNS
|
||
|
|
USAGE
|
||
|
|
}
|
||
|
|
|
||
|
|
cmd="${1:-}"
|
||
|
|
if [ $# -gt 0 ]; then
|
||
|
|
shift
|
||
|
|
fi
|
||
|
|
|
||
|
|
case "$cmd" in
|
||
|
|
up)
|
||
|
|
up "$@"
|
||
|
|
;;
|
||
|
|
down)
|
||
|
|
down "$@"
|
||
|
|
;;
|
||
|
|
shell)
|
||
|
|
coold_vm "${1:-1}" shell
|
||
|
|
;;
|
||
|
|
list)
|
||
|
|
limactl list
|
||
|
|
;;
|
||
|
|
corrosion)
|
||
|
|
corrosion "$@"
|
||
|
|
;;
|
||
|
|
firewall)
|
||
|
|
firewall "$@"
|
||
|
|
;;
|
||
|
|
example-nginx)
|
||
|
|
example_nginx "$@"
|
||
|
|
;;
|
||
|
|
-h|--help|help|"")
|
||
|
|
usage
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
echo "unknown command: $cmd" >&2
|
||
|
|
usage >&2
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|