Files
2026-09-28 18:28:32 +05:30

58 lines
2.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# scripts/run-vm.sh NAME URL: starts a VM with the app's flags, prints the host socket.
# Env: KNOTCHY_DEBUG, KNOTCHY_FIRST_VIEWER_TIMEOUT, KNOTCHY_ENV_FILE, KNOTCHY_SECRETS_DIR.
# Name VMs knotchyctl-<8 hex> so the app's orphan sweep ignores them.
set -euo pipefail
name="${1:?usage: run-vm.sh NAME URL}"
url="${2:?usage: run-vm.sh NAME URL}"
if [[ ! "$name" =~ ^[a-z0-9][a-z0-9-]{0,40}$ ]]; then
echo "run-vm.sh: invalid VM name '$name' (lowercase letters, digits, dashes)" >&2; exit 2
fi
if [[ "$name" =~ ^knotchy-[0-9a-f]{8}$ ]]; then
echo "run-vm.sh: '$name' uses the app's naming; use knotchyctl-<8 hex>" >&2; exit 2
fi
tmp="${TMPDIR:-/tmp}"
run_dir="${tmp%/}/knotchy"
mkdir -p -m 700 "$run_dir"
if [[ ! -d "$run_dir" || -L "$run_dir" || ! -O "$run_dir" ]]; then
echo "run-vm.sh: refusing unsafe socket directory $run_dir" >&2; exit 1
fi
chmod 700 "$run_dir"
sock="$run_dir/$name.sock"
rm -f "$sock"
# The Mac's networks may be public addresses, so the VM blocks them explicitly.
block=$(python3 - <<'PY'
import ipaddress, re, subprocess
out = subprocess.run(["ifconfig"], capture_output=True, text=True).stdout
nets = set()
for ip, mask in re.findall(r"inet (\d+\.\d+\.\d+\.\d+)(?: --> \S+)? netmask 0x([0-9a-f]{8})", out):
if ip.startswith("127."):
continue
net = ipaddress.ip_network(f"{ip}/{bin(int(mask, 16)).count('1')}", strict=False)
if net.prefixlen >= 8:
nets.add(str(net))
print(" ".join(sorted(nets)))
PY
)
if [[ -z "$block" ]]; then
echo "run-vm.sh: warning: found no Mac IPv4 networks to block" >&2
fi
container run -d --rm --name "$name" \
--cpus 4 --memory 2g --shm-size 512m \
--dns 1.1.1.1 \
--cap-add NET_ADMIN \
--masked-path NONE --read-only-path NONE \
--publish-socket "$sock:/tmp/knotchy/knotchy.sock" \
-e "KNOTCHY_URL=$url" \
-e "KNOTCHY_SIZE=1024x640" \
-e "KNOTCHY_BLOCK_CIDRS=$block" \
-e "KNOTCHY_DEBUG=${KNOTCHY_DEBUG:-0}" \
-e "KNOTCHY_FIRST_VIEWER_TIMEOUT=${KNOTCHY_FIRST_VIEWER_TIMEOUT:-60}" \
${KNOTCHY_ENV_FILE:+--env-file "$KNOTCHY_ENV_FILE"} \
${KNOTCHY_SECRETS_DIR:+--cap-add SYS_ADMIN --mount "type=bind,source=$KNOTCHY_SECRETS_DIR,target=/run/knotchy-secrets"} \
local/knotchy-vm:latest >/dev/null
echo "$sock"