feat(airgap): multi-source import (server path, URL, file upload) with overlay UX
Import now supports three sources: server-side path (USB/NFS volumes), backend URL download, and browser file upload. Export/import workflows refactored from routed pages to overlay dialogs. Docs updated with volume mount instructions and source comparison table. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -50,6 +50,24 @@ Rollback resistance is enforced via:
|
||||
- A monotonicity checker (`IVersionMonotonicityChecker`) that compares incoming bundle versions to the active version.
|
||||
- Optional force-activate path requiring a human reason, stored alongside the activation record.
|
||||
|
||||
## Import sources
|
||||
|
||||
The importer accepts bundles from three sources:
|
||||
|
||||
| Source | Transport | Use case |
|
||||
|---|---|---|
|
||||
| **Server path** | Container reads from the import staging volume at `/var/lib/concelier/import/`. Host-side location controlled by `STELLAOPS_AIRGAP_IMPORT_DIR` (default `./airgap-import`). | USB drives, NFS mounts, large bundles (GB+). Zero browser transfer. |
|
||||
| **URL** | Backend fetches the bundle from an internal URL directly. | Internal mirrors, S3, artifact registries. |
|
||||
| **File upload** | Browser uploads via multipart/form-data. | Small bundles only; limited by browser memory. |
|
||||
|
||||
For Docker Compose deployments, the import volume is mounted read-only:
|
||||
```yaml
|
||||
# In docker-compose.stella-ops.yml (concelier service):
|
||||
- ${STELLAOPS_AIRGAP_IMPORT_DIR:-./airgap-import}:/var/lib/concelier/import:ro
|
||||
```
|
||||
|
||||
For Kubernetes deployments, mount an emptyDir, hostPath, or PVC at `/var/lib/concelier/import` and pre-stage bundles via init containers or sidecar pods.
|
||||
|
||||
## Storage model
|
||||
|
||||
The importer writes deterministic metadata that other components can query:
|
||||
|
||||
@@ -13,9 +13,38 @@ Scope: deploy sealed-mode Concelier evidence bundles using deterministic NDJSON
|
||||
- Concelier WebService running with `concelier:features:airgap` enabled.
|
||||
- No external egress; only local file system allowed for bundle path.
|
||||
- PostgreSQL indexes applied (`advisory_observations`, `advisory_linksets` tables).
|
||||
- **Import volume mounted**: The Concelier container must have the import staging directory mounted. In Docker Compose this is configured via `STELLAOPS_AIRGAP_IMPORT_DIR` (defaults to `./airgap-import` on the host, mounted read-only at `/var/lib/concelier/import` inside the container).
|
||||
|
||||
## Import Volume Setup (Docker Compose)
|
||||
|
||||
The Concelier service mounts an import staging volume for air-gapped bundle ingestion.
|
||||
Bundles placed on the host at `$STELLAOPS_AIRGAP_IMPORT_DIR` are visible inside the container at `/var/lib/concelier/import/`.
|
||||
|
||||
```bash
|
||||
# Default: ./airgap-import relative to the compose directory
|
||||
mkdir -p devops/compose/airgap-import
|
||||
|
||||
# Override: point to USB, NFS mount, or any host directory
|
||||
export STELLAOPS_AIRGAP_IMPORT_DIR=/media/usb/stellaops-bundles
|
||||
docker compose -f docker-compose.stella-ops.yml up -d concelier
|
||||
```
|
||||
|
||||
The volume is mounted **read-only** — the Concelier service reads and validates bundles but never modifies the staging directory. The environment variable `CONCELIER_IMPORT__STAGINGROOT` tells the service where to find staged bundles inside the container.
|
||||
|
||||
### UI Console Import
|
||||
|
||||
The Feeds & Airgap console (Ops → Operations → Feeds & Airgap → Airgap Bundles → Import) supports three import sources:
|
||||
|
||||
| Source | Description | Volume needed? |
|
||||
|---|---|---|
|
||||
| **Server Path** | Path inside the container (e.g. `/var/lib/concelier/import/bundle.tar.gz`). Zero browser transfer. | Yes |
|
||||
| **URL** | Internal URL the backend downloads directly. | No |
|
||||
| **File Upload** | Browser drag-and-drop for small bundles. | No |
|
||||
|
||||
For large bundles (GB+), use **Server Path** or **URL** — never browser upload.
|
||||
|
||||
## Steps
|
||||
1) Transfer bundle directory to offline controller host.
|
||||
1) Stage the bundle onto the import volume (or transfer to the offline controller host).
|
||||
2) Verify hashes:
|
||||
```bash
|
||||
sha256sum concelier-airgap.ndjson | diff - <(jq -r .bundleSha256 bundle.manifest.json)
|
||||
|
||||
Reference in New Issue
Block a user