Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
5.8 KiB
5.8 KiB
Runner S3 Integration Guide
This document specifies how the Runner integrates with S3-compatible storage (e.g., MinIO) to fetch extension bundles by content hash and serve static UI assets.
Links:
- Overview: ee/docs/extension-system/overview.md
- Serving system: ee/docs/extension-system/serving-system.md
Responsibilities
- Fetch and cache extension bundle by content hash:
- Download canonical object from S3 at:
- sha256/<content_hash>/bundle.tar.zst
- sha256/<content_hash>/manifest.json
- Verify integrity (content hash, size if provided), and only accept immutable artifacts.
- Download canonical object from S3 at:
- Serve extension UI assets:
- Public base: ${RUNNER_PUBLIC_BASE}/ext-ui/{extensionId}/{content_hash}/…
- Static assets resolved from the unpacked bundle according to manifest.json (e.g., index.html, JS/CSS assets, media).
- Execution API:
- Expose an HTTP endpoint to execute extension handlers when invoked by Gateway:
- POST /v1/execute
- Ensure runtime fetches entry.wasm (or equivalent) mapped by content_hash and reuses local cache.
- Expose an HTTP endpoint to execute extension handlers when invoked by Gateway:
Configuration Parity with Server
The Runner should use the same S3 settings as the server for consistent access and path semantics.
Required environment variables:
- STORAGE_S3_ENDPOINT: S3/MinIO endpoint (e.g., http://localhost:9000 for MinIO).
- STORAGE_S3_BUCKET: Bucket name used to store/read bundles.
- STORAGE_S3_REGION: Region string; for MinIO use a placeholder like us-east-1 unless configured otherwise.
- STORAGE_S3_ACCESS_KEY: Access key.
- STORAGE_S3_SECRET_KEY: Secret key.
- STORAGE_S3_FORCE_PATH_STYLE: true to force path-style addressing for MinIO.
- STORAGE_S3_BUNDLE_BUCKET: optional override for the bundles bucket (if server publishes to a separate bucket).
- STORAGE_TLS: Optional; set true if using HTTPS and the cert is trusted (otherwise provide appropriate trust settings).
Runner-specific:
- RUNNER_PUBLIC_BASE: Base URL path to serve UI (e.g., /runner).
- RUNNER_CACHE_DIR: Filesystem directory for caching fetched bundles (e.g., /var/cache/alga-runner or ./.cache/runner for local).
- RUNNER_MAX_CACHE_SIZE_BYTES: Optional LRU cap for cache eviction.
- RUNNER_OFFLINE: Optional; if true, disables network fetches and requires bundles to be pre-cached.
Server parity notes:
- The server writes bundles to canonical S3 paths under sha256//. The Runner must only read from canonical locations and never mutate them.
- If the server enforces declaredHash, the Runner should assume sha256//… objects are immutable.
Cache Behavior and Integrity
- On first request for {extensionId, content_hash}:
- Fetch sha256/<content_hash>/manifest.json, validate basic fields (extension, version, entry paths).
- Fetch sha256/<content_hash>/bundle.tar.zst, verify sha256(content) equals content_hash.
- Unpack into RUNNER_CACHE_DIR/<content_hash>/… with a marker indicating successful extraction (e.g., .ready).
- Subsequent requests:
- Serve from cache if .ready is present.
- For HTTP GETs of UI assets, set ETag to the content hash or the asset’s digest.
- Respect If-None-Match and return 304 when ETag matches for immutable assets.
- Eviction:
- If RUNNER_MAX_CACHE_SIZE_BYTES is set, implement LRU eviction of least-recently-used content hashes.
HTTP Flows
-
Execution (from Gateway to Runner):
- POST /v1/execute
- Body includes { extensionId, content_hash, handler, payload, tenant, … }.
- Runner ensures bundle for content_hash is present (fetch+cache if missing), loads entry.wasm, and executes handler.
- POST /v1/execute
-
UI (from Browser to Runner):
- GET ${RUNNER_PUBLIC_BASE}/ext-ui/{extensionId}/{content_hash}/index.html
- GET ${RUNNER_PUBLIC_BASE}/ext-ui/{extensionId}/{content_hash}/assets/
- The Runner maps the path to RUNNER_CACHE_DIR/<content_hash>/ui/… (or equivalent layout from the bundle).
- Set headers:
- Cache-Control: public, max-age=31536000, immutable (safe for immutable paths)
- ETag: "<content_hash>" or strong per-asset digest
- Content-Type: resolved from file extension
Expected S3 Paths
Canonical objects written by the server:
- sha256//bundle.tar.zst
- sha256//manifest.json
The Runner must not depend on non-canonical staging keys; only canonical content-hash keys are considered valid.
Immutability and Conditional Requests
- All content under sha256// is immutable.
- For GET of UI assets, use ETag based on content hash (or a per-file digest within the bundle).
- Honor If-None-Match to enable 304 responses and reduce bandwidth.
- Do not attempt to overwrite or delete S3 objects; cache management is local.
Acceptance Checks (Local Runner with MinIO)
- With MinIO configured via STORAGE_* and path-style:
- Given a content hash H from a finalized upload:
- Runner fetches sha256/H/manifest.json and sha256/H/bundle.tar.zst.
- Runner unpacks and serves UI at:
- ${RUNNER_PUBLIC_BASE}/ext-ui/{extensionId}/H/index.html returns 200
- Subsequent GETs with If-None-Match: "H" return 304
- Execute flow:
- POST /v1/execute with content_hash H executes against entry.wasm and returns a handler result or structured error.
- Given a content hash H from a finalized upload:
Notes
- entry.wasm resolution:
- The manifest’s entry.wasm path is relative to the bundle root; ensure it is present after unpacking.
- Security:
- Validate manifest format and restrict file types and paths during unpack to avoid path traversal.
- Consider running Wasm in a sandbox with appropriate capabilities.
- Timeouts and retries:
- On transient S3 errors, implement exponential backoff for fetches.
- Fail closed if content hash validation fails.
References
- Overview: ee/docs/extension-system/overview.md
- Serving system: ee/docs/extension-system/serving-system.md