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:
master
2026-04-07 15:33:21 +03:00
parent 6e72ad844e
commit 3a95f315bd
11 changed files with 1641 additions and 882 deletions

View File

@@ -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: