All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 1m9s
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a028f0-a42f-7582-89a8-ebaad7343834
95 lines
2.9 KiB
Markdown
95 lines
2.9 KiB
Markdown
# Operator guide
|
|
|
|
## Run locally
|
|
|
|
```bash
|
|
make install
|
|
make run
|
|
```
|
|
|
|
The API defaults to `127.0.0.1:8010` and `./sbom-nexus.db`. SQLite schema is
|
|
created automatically for local development.
|
|
|
|
For PostgreSQL, migrate before starting the API:
|
|
|
|
```bash
|
|
export SBOM_NEXUS_DATABASE_URL='postgresql+psycopg://user:password@host/sbom_nexus'
|
|
make migrate
|
|
make run
|
|
```
|
|
|
|
Production deployments should mount a Secret and set
|
|
`SBOM_NEXUS_DATABASE_URL_FILE` to its `url` file rather than exposing the DSN
|
|
in a manifest or command argument. The same file setting is consumed by both
|
|
Alembic and the API process.
|
|
|
|
PostgreSQL never auto-creates tables unless `SBOM_NEXUS_AUTO_CREATE=1` is set
|
|
explicitly. Normal production operation must use Alembic.
|
|
|
|
## Register and ingest a repository
|
|
|
|
```bash
|
|
curl -X PUT http://127.0.0.1:8010/repositories/example \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"checkout_path":"/srv/repos/example","active":true}'
|
|
|
|
curl -X POST http://127.0.0.1:8010/sbom/example/ingest
|
|
```
|
|
|
|
The ingest response is terminal: `ingested`, or `skipped` with one of
|
|
`no-checkout`, `no-manifest`, or `ingest-error`. A skip advances queue fairness
|
|
but does not advance `last_success_at`.
|
|
|
|
## Inspect catch-up
|
|
|
|
```bash
|
|
curl -s 'http://127.0.0.1:8010/sbom/catch-up?limit=3' | python3 -m json.tool
|
|
```
|
|
|
|
The default stale threshold is 30 days. Override it globally with
|
|
`SBOM_NEXUS_STALE_DAYS` or per query with `stale_days` during controlled
|
|
operation.
|
|
|
|
## Import State Hub history
|
|
|
|
Synchronize the minimum repository identity/path projection first. This command
|
|
does not call an ingest endpoint or create an SBOM snapshot:
|
|
|
|
```bash
|
|
uv run python scripts/sync_repository_projections.py \
|
|
--source-url http://127.0.0.1:8000 \
|
|
--target-url http://127.0.0.1:8010 \
|
|
--host-id bnt-lap001 \
|
|
--dry-run
|
|
```
|
|
|
|
Remove `--dry-run` only after the target is deployed. The apply path upserts all
|
|
active and inactive records, then reads them back and fails on a missing or
|
|
mismatched active/path projection. Extra target rows are reported but retained.
|
|
|
|
Run a read-only preview first:
|
|
|
|
```bash
|
|
uv run python scripts/import_state_hub.py --dry-run
|
|
```
|
|
|
|
Then run against a backed-up Nexus database:
|
|
|
|
```bash
|
|
uv run python scripts/import_state_hub.py \
|
|
--source-url http://127.0.0.1:8000 \
|
|
--target-url http://127.0.0.1:8010
|
|
```
|
|
|
|
Imports are idempotent on the State Hub snapshot UUID. Before cutover, compare
|
|
the source/target repository, snapshot, and entry counts described in the
|
|
extraction review. The command fails unless every legacy snapshot id, repository,
|
|
timestamp, entry count, licence group, and direct-production copyleft count
|
|
reconciles.
|
|
|
|
## Current production limitations
|
|
|
|
- Authentication and authorization are not yet integrated.
|
|
- Structured operational metrics, backup/restore proof, and retention policy are
|
|
required before authority cutover.
|
|
- State Hub and Repo Manager callers have not yet been retargeted.
|