#!/usr/bin/env bash # Local netOrk demo instance for website screenshots. # # up.sh restore fresh demo DB from a pg_dump -Fc file, then anonymize # up.sh start API on :8000 and UI on :5173 (foreground, Ctrl-C stops) # up.sh stop stop the demo database container # # Only the API and the UI run: no Celery worker, no beat, no Redis. Nothing # polls, nothing reboots, nothing reaches a device. Stored credentials are # emptied by anonymize.py and the encryption key is a fresh random one, so # even a leftover value could not be decrypted. set -euo pipefail HERE="$(cd "$(dirname "$0")" && pwd)" DEMO="${NETORK_DEMO_DIR:-$HOME/.cache/netork-demo}" SRC="$DEMO/src" VENV="${NETORK_VENV:-$HOME/dev/NetOrk/.venv}" VERSION="${NETORK_DEMO_VERSION:-v0.28.0}" NETORK_REPO="${NETORK_REPO:-$HOME/dev/NetOrk}" DB=netork-demo-db PORT=55432 ensure_src() { if [ ! -d "$SRC/netork" ]; then mkdir -p "$SRC" git -C "$NETORK_REPO" archive "$VERSION" | tar -x -C "$SRC" fi } ensure_db() { if ! docker ps --format '{{.Names}}' | grep -qx "$DB"; then docker start "$DB" 2>/dev/null || docker run -d --name "$DB" \ -p 127.0.0.1:$PORT:5432 -e POSTGRES_DB=netork -e POSTGRES_USER=netork \ -e POSTGRES_PASSWORD=demo -v netork-demo-pg:/var/lib/postgresql/data postgres:16-alpine until docker exec "$DB" pg_isready -U netork -q; do sleep 1; done fi } case "${1:-}" in restore) dump="${2:?usage: up.sh restore }" ensure_src; ensure_db docker exec "$DB" psql -U netork -d postgres -q \ -c "DROP DATABASE IF EXISTS netork WITH (FORCE)" -c "CREATE DATABASE netork" docker exec -i "$DB" pg_restore -U netork -d netork --no-owner --no-privileges < "$dump" \ || echo "pg_restore reported errors (often only missing roles/extensions); checking ..." got=$(docker exec "$DB" psql -U netork -tA -c "SELECT version_num FROM alembic_version") want=$(cd "$SRC" && PATH="$VENV/bin:$PATH" alembic heads 2>/dev/null | awk '{print $1}') echo "dump schema: $got $VERSION head: $want" # Anonymize first: it empties every secret, so a downgrade that would # have to decrypt something (with a key we do not have) finds nothing. "$VENV/bin/python" "$HERE/anonymize.py" if [ "$got" != "$want" ]; then # The production instance runs a newer build. Walk the copy back to the # release with the newer code's own downgrade migrations. NEWER="${NETORK_NEWER_REF:-origin/main}" echo "migrating the copy from $got back to $want with $NEWER's migrations" rm -rf "$DEMO/src-newer"; mkdir -p "$DEMO/src-newer" git -C "$NETORK_REPO" archive "$NEWER" | tar -x -C "$DEMO/src-newer" # Rows the older schema cannot hold: CrowdSec blocklist alerts whose scope # is a list name, longer than the column they go back into. docker exec "$DB" psql -U netork -q -c \ "DELETE FROM crowdsec_alerts WHERE length(source_scope) > 32" 2>/dev/null || true (cd "$DEMO/src-newer" && PATH="$VENV/bin:$PATH" \ DATABASE_URL="postgresql+asyncpg://netork:demo@127.0.0.1:$PORT/netork" alembic downgrade "$want") "$VENV/bin/python" "$HERE/anonymize.py" --report-only fi ;; start) ensure_src; ensure_db [ -d "$SRC/ui/node_modules" ] || (cd "$SRC/ui" && npm ci --no-audit --no-fund) export DATABASE_URL="postgresql+asyncpg://netork:demo@127.0.0.1:$PORT/netork" export ENVIRONMENT=development export SECRET_KEY="$(openssl rand -hex 32)" export CREDENTIAL_ENCRYPTION_KEY="$("$VENV/bin/python" -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())')" # Nothing listens on port 1: no task can be queued, so no worker could act. export REDIS_URL=redis://127.0.0.1:1/0 CELERY_BROKER_URL=redis://127.0.0.1:1/0 CELERY_RESULT_BACKEND=redis://127.0.0.1:1/1 cd "$SRC" "$VENV/bin/uvicorn" netork.api.main:app --host 127.0.0.1 --port 8000 & api=$! trap 'kill $api 2>/dev/null' EXIT cd ui && npx vite --host 127.0.0.1 --port 5173 --strictPort ;; stop) docker stop "$DB" ;; *) sed -n '2,12p' "$0"; exit 1 ;; esac