Skip to content

Commit ce3b3a1

Browse files
committed
refactor: Bash script for local dev
1 parent 018c2e5 commit ce3b3a1

13 files changed

Lines changed: 205 additions & 109 deletions

deploy/dev.sh

Lines changed: 0 additions & 45 deletions
This file was deleted.

justfile

Lines changed: 75 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,67 @@
11
data_dir := "./data"
22
static_dir := "./static"
33
otel_endpoint := "http://localhost:4317"
4-
registry := "localhost:5001"
54

5+
# ── cluster lifecycle ────────────────────────────────────────────────────────
6+
7+
# Bring up the full edgeflow dev cluster (recreates from scratch)
8+
[group('cluster')]
9+
up: _banner _preflight down build-images cluster-create push-images apply-observability apply-server apply-inference
10+
@bash scripts/dev/next-steps.sh
11+
12+
# Tear down the edgeflow dev cluster
13+
[group('cluster')]
14+
down:
15+
bash scripts/dev/cluster-delete.sh
16+
17+
# Create a fresh k3d cluster and label its nodes
18+
[group('cluster')]
19+
cluster-create:
20+
bash scripts/dev/cluster-create.sh
21+
22+
# ── images ───────────────────────────────────────────────────────────────────
23+
24+
# Pull and tag vendored observability images
625
pull:
7-
#!/usr/bin/env bash
8-
set -euo pipefail
9-
declare -A images=(
10-
["otel/opentelemetry-collector-contrib:0.145.0"]="{{ registry }}/otel-collector-contrib:0.145.0"
11-
["grafana/tempo:2.7.2"]="{{ registry }}/grafana/tempo:2.7.2"
12-
["grafana/loki:3.5.0"]="{{ registry }}/loki:3.5.0"
13-
["grafana/grafana:11.6.1"]="{{ registry }}/grafana:11.6.1"
14-
["prom/prometheus:v3.3.0"]="{{ registry }}/prometheus:v3.3.0"
15-
)
16-
for src in "${!images[@]}"; do
17-
dst="${images[$src]}"
18-
echo "Pulling $src..."
19-
docker pull "$src"
20-
echo "Tagging as $dst..."
21-
docker tag "$src" "$dst"
22-
done
23-
24-
push:
25-
#!/usr/bin/env bash
26-
set -euo pipefail
27-
# Vendor images
28-
for img in \
29-
{{ registry }}/otel-collector-contrib:0.145.0 \
30-
{{ registry }}/prometheus:v3.3.0 \
31-
{{ registry }}/grafana/tempo:2.7.2 \
32-
{{ registry }}/grafana:11.6.1; do
33-
echo "Pushing $img..."
34-
docker push "$img"
35-
done
36-
# App images
37-
for img in edgeflow-server:dev edgeflow-inference:dev-ort; do
38-
echo "Tagging and pushing {{ registry }}/$img..."
39-
docker tag "$img" "{{ registry }}/$img"
40-
docker push "{{ registry }}/$img"
41-
done
42-
43-
# Build everything
26+
bash scripts/dev/pull-vendor-images.sh
27+
28+
# Build the server + inference docker images
29+
build-images:
30+
bash scripts/dev/build-images.sh
31+
32+
# Push vendor + app images to the local registry
33+
push-images:
34+
bash scripts/dev/push-images.sh
35+
36+
# ── partial reapply (for iteration during a dev session) ─────────────────────
37+
38+
# Re-apply the observability manifest and wait
39+
[group('iteration')]
40+
apply-observability:
41+
bash scripts/dev/apply-observability.sh
42+
43+
# Re-apply the server manifest and wait
44+
[group('iteration')]
45+
apply-server:
46+
bash scripts/dev/apply-server.sh
47+
48+
# Re-apply the inference services
49+
[group('iteration')]
50+
apply-inference:
51+
bash scripts/dev/apply-inference.sh
52+
53+
# Rebuild images and roll the running edgeflow-server pod
54+
[group('iteration')]
55+
deploy-server: build-images push-images
56+
kubectl rollout restart deployment/edgeflow-server
57+
kubectl rollout status deployment/edgeflow-server --timeout=120s
58+
59+
# ── host-side build (for hot-reload dev workflows) ───────────────────────────
60+
61+
# Build everything (transforms + UI + native server binary)
4462
build: build-transforms build-ui build-server
4563

46-
# Compile the standard Rust transforms:
47-
# - WASM component → apps/sdk/edgeflow/wasm/standard_pipeline.wasm (server, ~150 KB)
48-
# - Native PyO3 extension → edgeflow/_lib.so (local execution)
64+
# Build the WASM transforms component + the PyO3 extension for the SDK
4965
build-transforms:
5066
cd crates/transforms && \
5167
cargo build --target wasm32-wasip2 --release
@@ -59,36 +75,21 @@ build-ui:
5975
rm -rf {{static_dir}}
6076
cp -r apps/ui/build {{static_dir}}
6177

62-
# Build the server in release mode
78+
# Build the native server binary in release mode
6379
build-server:
6480
cargo build --release -p edgeflow-server
6581

66-
# Apply the observability stack (OTel Collector, Prometheus, Tempo, Grafana)
67-
deploy-observability:
68-
kubectl apply -f deploy/manifests/observability.yaml
69-
kubectl rollout status deployment/otelcol --timeout=120s
70-
kubectl rollout status deployment/prometheus --timeout=120s
71-
kubectl rollout status deployment/tempo --timeout=120s
72-
kubectl rollout status deployment/grafana --timeout=120s
73-
74-
# Build the server image, push to local registry, and rollout restart
75-
deploy-server:
76-
docker build -f deploy/server.Dockerfile -t edgeflow-server:dev .
77-
docker tag edgeflow-server:dev {{ registry }}/edgeflow-server:dev
78-
docker push {{ registry }}/edgeflow-server:dev
79-
kubectl rollout restart deployment/edgeflow-server
80-
kubectl rollout status deployment/edgeflow-server --timeout=120s
82+
# ── dev hot-reload ───────────────────────────────────────────────────────────
8183

82-
# Run the server in dev mode (with OTEL if the observability stack is up)
84+
# Run the server natively (with OTEL if the observability stack is up)
8385
dev-server:
8486
EDGEFLOW_DATA_DIR={{data_dir}} EDGEFLOW_STATIC_DIR={{static_dir}} \
8587
OTEL_EXPORTER_OTLP_ENDPOINT={{otel_endpoint}} \
8688
PROMETHEUS_URL=http://localhost:9090 \
8789
RUST_LOG=edgeflow_server=debug,tower_http=debug \
8890
cargo run -p edgeflow-server
8991

90-
# Run an inference pod locally against the dev server (requires EDGEFLOW_TARGET)
91-
# Example: just dev-inference iris-inference
92+
# Run an inference pod natively against the dev server. Example: just dev-inference iris-inference
9293
dev-inference target:
9394
EDGEFLOW_SERVER=http://localhost:5000 \
9495
EDGEFLOW_TARGET={{target}} \
@@ -101,15 +102,15 @@ dev-inference target:
101102
dev-ui:
102103
cd apps/ui && npm run dev
103104

104-
# Run a load test against a target
105-
# Example: just bench iris-inference
106-
# Example: just bench adult-inference 50 120s
105+
# ── tests / docs / housekeeping ──────────────────────────────────────────────
106+
107+
# Run a load test against a target. Example: just bench iris-inference 50 120s
107108
bench target users="10" duration="60s":
108109
cd scripts/test-load && ./bench.sh {{target}} {{users}} {{duration}}
109110

110111
# Run Rust unit tests
111112
test:
112-
cargo test
113+
cargo test --workspace
113114

114115
# Run MLflow compatibility tests against a running server
115116
test-compat uri="http://localhost:5000":
@@ -126,3 +127,13 @@ docs:
126127
clean:
127128
cargo clean
128129
rm -rf {{static_dir}} apps/ui/build apps/ui/node_modules
130+
131+
# ── private helpers ──────────────────────────────────────────────────────────
132+
133+
[private]
134+
_banner:
135+
@bash scripts/dev/banner.sh
136+
137+
[private]
138+
_preflight:
139+
@bash scripts/dev/preflight.sh

scripts/dev/apply-inference.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env bash
2+
# Apply the inference Services. Pods are created on demand by the server when
3+
# a deployment is requested, so there is nothing to wait for here.
4+
set -euo pipefail
5+
6+
kubectl apply -f deploy/manifests/inference.yaml

scripts/dev/apply-observability.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
# Apply the observability manifest and wait for all components to be ready.
3+
set -euo pipefail
4+
5+
kubectl apply -f deploy/manifests/observability.yaml
6+
kubectl rollout status deployment/otelcol --timeout=120s
7+
kubectl rollout status deployment/prometheus --timeout=120s
8+
kubectl rollout status deployment/tempo --timeout=120s
9+
kubectl rollout status deployment/grafana --timeout=120s

scripts/dev/apply-server.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env bash
2+
# Apply the edgeflow-server manifest and wait for it to be ready.
3+
set -euo pipefail
4+
5+
kubectl apply -f deploy/manifests/server.yaml
6+
kubectl rollout status deployment/edgeflow-server --timeout=120s

scripts/dev/banner.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
cat <<'EOF'
3+
4+
▄▄▄▄ ▄▄▄ ▄▄▄ ▄▄▄▄ ▄▄▄▄ ▄ ▄▄▄ ▄ ▄
5+
█▄▄ █ █ █ ▄▄ █▄▄ █▄▄ █ █ █ █ █ █
6+
█▄▄▄ █▄▄▀ ▀▄▄█ █▄▄▄ █ █▄▄▄ ▀▄▄▀ ▀▄▀▄▀
7+
train in python, serve in rust
8+
9+
EOF

scripts/dev/build-images.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env bash
2+
# Build the server and inference docker images via docker buildx bake.
3+
set -euo pipefail
4+
docker buildx bake -f deploy/docker-bake.hcl server inference-ort

scripts/dev/cluster-create.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env bash
2+
# Create the edgeflow k3d cluster and label its nodes.
3+
set -euo pipefail
4+
5+
k3d cluster create --config deploy/k3d-cluster.yaml
6+
7+
kubectl label node k3d-edgeflow-server-0 \
8+
edgeflow-role=server --overwrite
9+
kubectl label node k3d-edgeflow-agent-0 k3d-edgeflow-agent-1 k3d-edgeflow-agent-2 \
10+
edgeflow-role=agent --overwrite

scripts/dev/cluster-delete.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
# Delete the edgeflow k3d cluster. Idempotent.
3+
set -euo pipefail
4+
5+
if k3d cluster list | grep -q "^edgeflow"; then
6+
k3d cluster delete edgeflow
7+
else
8+
echo "no edgeflow cluster to delete"
9+
fi

scripts/dev/next-steps.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env bash
2+
cat <<'EOF'
3+
4+
cluster ready.
5+
6+
server http://localhost:5000
7+
grafana http://localhost:3000
8+
prometheus http://localhost:9090
9+
10+
deploy a model:
11+
cd examples/01-quickstart-iris && uv run python train.py
12+
13+
tear down:
14+
just down
15+
16+
EOF

0 commit comments

Comments
 (0)