feat(velxio): modular standalone orchestration & dynamic tailscale config
- Tambah podman-compose.velxio.yml untuk deployment Velxio standalone - Tambah command elemes.sh (velxio-run, velxio-runbuild, velxio-stop, velxio-status) - Template lms-tail.json.template dengan auto-generation via elemes.sh berdasarkan VELXIO_MODE - Dukungan VELXIO_COMPILER_URL dinamis pada compose utama
This commit is contained in:
parent
186161ac96
commit
77028e58ff
12
.env.example
12
.env.example
|
|
@ -21,6 +21,18 @@ COMPILER_WORKER_URL=http://compiler-worker:8080/execute
|
|||
ELEMES_HOST=sinau-c-hostname-kamu
|
||||
TS_AUTHKEY=tskey-auth-xxxx
|
||||
|
||||
# ── Velxio Modular Deployment (opsional) ───────
|
||||
# Mode operasi Velxio: 'local' (bundled dalam compose) atau 'remote' (terpisah)
|
||||
VELXIO_MODE=local
|
||||
# URL compiler Velxio (hanya perlu di-set saat VELXIO_MODE=remote)
|
||||
# Default local: http://127.0.0.1:80/api/compile/
|
||||
# Contoh remote via MagicDNS: http://velxio-dev:80/api/compile/
|
||||
#VELXIO_COMPILER_URL=
|
||||
# Hostname Tailscale untuk standalone Velxio node (dipakai di mesin Velxio & Elemes)
|
||||
VELXIO_HOST=velxio-dev
|
||||
# Auth key Tailscale terpisah untuk standalone Velxio node (di mesin Velxio)
|
||||
VELXIO_TS_AUTHKEY=
|
||||
|
||||
# ── Flask (opsional: untuk dev mode lokal) ─────
|
||||
FLASK_DEBUG=false
|
||||
|
||||
|
|
|
|||
|
|
@ -13,3 +13,4 @@ velxio-deployer-firmware/build
|
|||
velxio-deployer-firmware/managed_components/
|
||||
lms-c-precompiled.tar
|
||||
.browser-test/
|
||||
config/lms-tail.json
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
"Proxy": "http://127.0.0.1:5000/velxio-compile"
|
||||
},
|
||||
"/velxio/": {
|
||||
"Proxy": "http://127.0.0.1:80/"
|
||||
"Proxy": "__VELXIO_PROXY_TARGET__"
|
||||
},
|
||||
"/flowchart/": {
|
||||
"Proxy": "http://127.0.0.1:8081/"
|
||||
173
elemes.sh
173
elemes.sh
|
|
@ -62,6 +62,70 @@ compose_restart() {
|
|||
run_compose_out restart "$@"
|
||||
}
|
||||
|
||||
# Helper untuk membaca nilai konfigurasi dari .env tanpa source
|
||||
env_val() {
|
||||
grep -m1 "^${1}=" "$PARENT_DIR/.env" 2>/dev/null | cut -d= -f2-
|
||||
}
|
||||
|
||||
# ── Velxio standalone compose helpers ────────────────────────
|
||||
VELXIO_PROJECT="${PROJECT_NAME}-velxio"
|
||||
|
||||
run_velxio_compose() {
|
||||
cd "$SCRIPT_DIR" || exit
|
||||
if [ "$VERBOSE" -eq 1 ]; then
|
||||
podman-compose -p "$VELXIO_PROJECT" -f podman-compose.velxio.yml \
|
||||
--env-file "$PARENT_DIR/.env" "$@"
|
||||
else
|
||||
podman-compose -p "$VELXIO_PROJECT" -f podman-compose.velxio.yml \
|
||||
--env-file "$PARENT_DIR/.env" "$@" \
|
||||
2> >(grep -v -E "$NOISE_RE" >&2)
|
||||
fi
|
||||
}
|
||||
|
||||
run_velxio_compose_quiet() {
|
||||
if [ "$VERBOSE" -eq 1 ]; then
|
||||
run_velxio_compose "$@"
|
||||
else
|
||||
run_velxio_compose "$@" >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
# Daftar services elemes berdasarkan VELXIO_MODE.
|
||||
# Return kosong = start all (local mode).
|
||||
# Return daftar service = start hanya yang terdaftar (remote mode).
|
||||
elemes_services() {
|
||||
local mode
|
||||
mode="$(env_val VELXIO_MODE)"
|
||||
mode="${mode:-local}"
|
||||
if [ "$mode" = "remote" ]; then
|
||||
echo "elemes-ts postgres elemes compiler-worker elemes-frontend flowchart"
|
||||
fi
|
||||
}
|
||||
|
||||
# Generate lms-tail.json dari template berdasarkan VELXIO_MODE.
|
||||
# Dipanggil sebelum container start agar Tailscale Serve config up-to-date.
|
||||
generate_ts_config() {
|
||||
local template="$SCRIPT_DIR/config/lms-tail.json.template"
|
||||
local output="$SCRIPT_DIR/config/lms-tail.json"
|
||||
|
||||
if [ ! -f "$template" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local mode
|
||||
mode="$(env_val VELXIO_MODE)"
|
||||
mode="${mode:-local}"
|
||||
|
||||
if [ "$mode" = "remote" ]; then
|
||||
local velxio_host
|
||||
velxio_host="$(env_val VELXIO_HOST)"
|
||||
velxio_host="${velxio_host:-velxio-dev}"
|
||||
sed "s|__VELXIO_PROXY_TARGET__|http://${velxio_host}:80/|g" "$template" > "$output"
|
||||
else
|
||||
sed 's|__VELXIO_PROXY_TARGET__|http://127.0.0.1:80/|g' "$template" > "$output"
|
||||
fi
|
||||
}
|
||||
|
||||
# First-run/health DB: tunggu PostgreSQL, migrasi schema (idempotent), lalu
|
||||
# bootstrap akun guru otomatis bila TEACHER_TOKEN di .env tidak kosong.
|
||||
db_init() {
|
||||
|
|
@ -153,6 +217,16 @@ init)
|
|||
echo "🔐 [Buat] Folder state/ (untuk Tailscale credentials & state)"
|
||||
fi
|
||||
|
||||
# state/velxio/ (untuk Tailscale credentials & state Velxio standalone)
|
||||
if [ -d "$PARENT_DIR/state/velxio" ]; then
|
||||
echo "✅ [Skip] Folder state/velxio/ sudah ada"
|
||||
else
|
||||
mkdir -p "$PARENT_DIR/state/velxio"
|
||||
echo "🔐 [Buat] Folder state/velxio/ (untuk Tailscale Velxio standalone)"
|
||||
fi
|
||||
|
||||
generate_ts_config
|
||||
|
||||
echo ""
|
||||
echo "🎯 Selesai! Langkah selanjutnya yang direkomendasikan:"
|
||||
echo " 👉 1. Edit file ../.env sesuai dengan kebutuhan environment-mu"
|
||||
|
|
@ -181,7 +255,14 @@ runbuild)
|
|||
;;&
|
||||
runbuild | runclearbuild)
|
||||
echo "🚀 Menjalankan container di background..."
|
||||
run_compose up --force-recreate -d
|
||||
generate_ts_config
|
||||
SERVICES=$(elemes_services)
|
||||
if [ -n "$SERVICES" ]; then
|
||||
echo " ℹ️ VELXIO_MODE=remote → Velxio tidak dijalankan secara lokal"
|
||||
run_compose up --force-recreate -d $SERVICES
|
||||
else
|
||||
run_compose up --force-recreate -d
|
||||
fi
|
||||
echo "✅ Elemes berhasil dijalankan!"
|
||||
db_init
|
||||
;;&
|
||||
|
|
@ -206,7 +287,14 @@ runbuild | runclearbuild)
|
|||
;;
|
||||
run)
|
||||
echo "🚀 Menjalankan container..."
|
||||
run_compose up -d
|
||||
generate_ts_config
|
||||
SERVICES=$(elemes_services)
|
||||
if [ -n "$SERVICES" ]; then
|
||||
echo " ℹ️ VELXIO_MODE=remote → Velxio tidak dijalankan secara lokal"
|
||||
run_compose up -d $SERVICES
|
||||
else
|
||||
run_compose up -d
|
||||
fi
|
||||
echo "✅ Elemes berhasil dijalankan!"
|
||||
db_init
|
||||
;;
|
||||
|
|
@ -470,6 +558,81 @@ docs-validate)
|
|||
compose_exec -w /app -e PYTHONPATH=services \
|
||||
elemes python scripts/validate_docs.py
|
||||
;;
|
||||
velxio-stop | velxio-run | velxio-runbuild)
|
||||
echo "🛑 Menghentikan Velxio standalone..."
|
||||
run_velxio_compose_quiet down
|
||||
;;&
|
||||
velxio-stop)
|
||||
echo "✅ Velxio standalone dihentikan."
|
||||
;;
|
||||
velxio-runbuild)
|
||||
echo "🏗️ Membangun Velxio standalone image..."
|
||||
run_velxio_compose build
|
||||
;;&
|
||||
velxio-run)
|
||||
if ! podman image exists lms-velxio-standalone:latest 2>/dev/null; then
|
||||
echo "⚠️ Image 'lms-velxio-standalone:latest' belum dibangun."
|
||||
echo " Jalankan: ./elemes.sh velxio-runbuild"
|
||||
exit 1
|
||||
fi
|
||||
;;&
|
||||
velxio-runbuild | velxio-run)
|
||||
echo "🚀 Menjalankan Velxio standalone di background..."
|
||||
run_velxio_compose up -d
|
||||
echo "✅ Velxio standalone berhasil dijalankan!"
|
||||
echo ""
|
||||
VH="$(env_val VELXIO_HOST)"
|
||||
VH="${VH:-velxio-dev}"
|
||||
echo "📡 Velxio standalone info:"
|
||||
echo " Tailscale hostname : $VH"
|
||||
echo " Port internal : 80 (Nginx → FastAPI :8001)"
|
||||
echo ""
|
||||
echo "💡 Untuk menghubungkan Elemes ke Velxio ini, set di .env mesin Elemes:"
|
||||
echo " VELXIO_MODE=remote"
|
||||
echo " VELXIO_HOST=$VH"
|
||||
echo " VELXIO_COMPILER_URL=http://$VH:80/api/compile/"
|
||||
;;
|
||||
velxio-status)
|
||||
echo "📊 === Status Velxio ==="
|
||||
MODE="$(env_val VELXIO_MODE)"
|
||||
MODE="${MODE:-local}"
|
||||
echo " Mode: $MODE"
|
||||
|
||||
if [ "$MODE" = "local" ]; then
|
||||
echo " Velxio berjalan dalam compose utama (bundled)"
|
||||
if podman ps --filter "label=io.podman.compose.project=$PROJECT_NAME" \
|
||||
--filter "label=com.docker.compose.service=velxio" \
|
||||
--format '{{.Names}} — {{.Status}}' 2>/dev/null | grep -q .; then
|
||||
echo " ✅ Container:"
|
||||
podman ps --filter "label=io.podman.compose.project=$PROJECT_NAME" \
|
||||
--filter "label=com.docker.compose.service=velxio" \
|
||||
--format ' {{.Names}} — {{.Status}}'
|
||||
else
|
||||
echo " ⚠️ Container: not running"
|
||||
fi
|
||||
else
|
||||
echo " Velxio berjalan terpisah (remote)"
|
||||
VURL="$(env_val VELXIO_COMPILER_URL)"
|
||||
echo " VELXIO_COMPILER_URL: ${VURL:-<belum diset>}"
|
||||
if podman ps --filter "label=io.podman.compose.project=$VELXIO_PROJECT" \
|
||||
--format '{{.Names}}' 2>/dev/null | grep -q .; then
|
||||
echo " ✅ Standalone container (lokal):"
|
||||
podman ps --filter "label=io.podman.compose.project=$VELXIO_PROJECT" \
|
||||
--format ' {{.Names}} — {{.Status}}'
|
||||
else
|
||||
echo " ℹ️ Tidak ada standalone container lokal (Velxio berjalan di mesin remote)"
|
||||
fi
|
||||
if [ -n "$VURL" ]; then
|
||||
HEALTH_URL=$(echo "$VURL" | sed 's|/api/compile.*|/health|')
|
||||
echo -n " 🔍 Health check ($HEALTH_URL)... "
|
||||
if curl -sf --max-time 5 "$HEALTH_URL" >/dev/null 2>&1; then
|
||||
echo "✅ reachable"
|
||||
else
|
||||
echo "❌ unreachable"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "💡 Cara Penggunaan elemes.sh:"
|
||||
echo " ./elemes.sh init # Inisialisasi konfigurasi, folder, & template .env"
|
||||
|
|
@ -493,6 +656,12 @@ docs-validate)
|
|||
echo " ./elemes.sh test-worker # Compiler worker test suite"
|
||||
echo " ./elemes.sh docs-validate # Validasi frontmatter & broken link di docs/*.md"
|
||||
echo " ./elemes.sh loadtest # Menjalankan utilitas simulasi Load Test (Locust)"
|
||||
echo ""
|
||||
echo "📡 Velxio Modular:"
|
||||
echo " ./elemes.sh velxio-run # Jalankan Velxio standalone (reuse image)"
|
||||
echo " ./elemes.sh velxio-runbuild # Build lalu jalankan Velxio standalone"
|
||||
echo " ./elemes.sh velxio-stop # Hentikan Velxio standalone"
|
||||
echo " ./elemes.sh velxio-status # Cek status & health Velxio (local/remote)"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
velxio-ts:
|
||||
image: docker.io/tailscale/tailscale:latest
|
||||
hostname: ${VELXIO_HOST:-velxio-dev}
|
||||
environment:
|
||||
- TS_AUTHKEY=${VELXIO_TS_AUTHKEY}
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
- TS_USERSPACE=true
|
||||
volumes:
|
||||
- ../state/velxio:/var/lib/tailscale
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
cap_add:
|
||||
- net_admin
|
||||
- sys_module
|
||||
restart: unless-stopped
|
||||
|
||||
velxio:
|
||||
image: lms-velxio-standalone:latest
|
||||
build:
|
||||
context: ./velxio
|
||||
dockerfile: Dockerfile.standalone
|
||||
network_mode: service:velxio-ts
|
||||
environment:
|
||||
- SECRET_KEY=${VELXIO_SECRET_KEY:-embed-only-no-auth-needed}
|
||||
- DATABASE_URL=sqlite+aiosqlite:////app/data/velxio.db
|
||||
- DATA_DIR=/app/data
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- velxio-ts
|
||||
volumes:
|
||||
- velxio-standalone-data:/app/data
|
||||
- velxio-standalone-arduino-libs:/root/.arduino15
|
||||
- velxio-standalone-ccache:/var/cache/ccache
|
||||
- velxio-standalone-build:/var/lib/velxio-build
|
||||
|
||||
volumes:
|
||||
velxio-standalone-data:
|
||||
velxio-standalone-arduino-libs:
|
||||
velxio-standalone-ccache:
|
||||
velxio-standalone-build:
|
||||
|
|
@ -51,7 +51,7 @@ services:
|
|||
environment:
|
||||
- COMPILER_WORKER_URL=http://127.0.0.1:8080/execute
|
||||
- COMPILER_WORKER_BASE_URL=http://127.0.0.1:8080
|
||||
- VELXIO_COMPILER_URL=http://127.0.0.1:80/api/compile/
|
||||
- VELXIO_COMPILER_URL=${VELXIO_COMPILER_URL:-http://127.0.0.1:80/api/compile/}
|
||||
- DATABASE_URL=${DATABASE_URL}
|
||||
- TOKEN_PEPPER=${TOKEN_PEPPER}
|
||||
- STORAGE_BACKEND=${STORAGE_BACKEND:-postgresql}
|
||||
|
|
|
|||
Loading…
Reference in New Issue