Skip to content

feat: cache NAR upload + interactive CLI (#261) - #301

Merged
DerDennisOP merged 35 commits into
mainfrom
feat/261-cache-upload-interactive-cli
Jun 2, 2026
Merged

feat: cache NAR upload + interactive CLI (#261)#301
DerDennisOP merged 35 commits into
mainfrom
feat/261-cache-upload-interactive-cli

Conversation

@DerDennisOP

Copy link
Copy Markdown
Member

Closes #261.

Part A — Cache NAR upload

Push local store paths or raw .nar files to a Gradient cache.

  • Shared ingest (gradient_core::cache::ingest): ingest_nar (blob write + cached_path upsert + signature placeholders) and ingest_metadata_only, parameterised by SignTargets::{OrgCaches, Cache, None}. The worker NarUploaded path now delegates its cached_path/signature work here (blob write + abort-on-failure stays worker-side, preserving the storage→abort / DB→warn split). derivation_output linking stays worker-only.
  • Endpoint POST /api/v1/caches/{cache}/nars: multipart (narinfo JSON + nar bytes), requires writeStore, validates byte length vs declared file_size, signs asynchronously via the existing sweep, writes an audit row. Per-route body limit GRADIENT_MAX_NAR_UPLOAD_SIZE (default 512 MiB) — added to LimitsArgs, the nix module, and docs.
  • CLI gradient cache upload:
    • No-nix path (always available): --nar-file <f.nar> --narinfo <f.narinfo> <cache>.
    • Nix path (optional nix Cargo feature, default off): resolves store paths via harmonia LocalNixStore, dumps NARs, --full-closure walks the runtime closure.
  • narinfo parser, connector nar_upload, OpenAPI, docs, tests.

Part B — Interactive CLI (ratatui)

Per-command -i/--interactive flags (no-op under --json):

  • gradient cache nar list -i — searchable/scrollable NAR browser.
  • gradient builds graph <id> -i — nix-tree-style collapsible dependency-graph browser (new builds command group).
  • gradient builds log <id> -i — less-style log pager (scroll, follow-tail, / search).

Panic-safe terminal restore; view-models are unit-tested independently of the terminal.

Tests

core::cache::ingest (mock DB + temp store), web caches_upload (auth surface; mutation cases #[ignore] per the repo's MockDatabase precedent), connector nar_upload (wiremock), CLI narinfo parser, cache upload integration (assert_cmd), and TUI view-model tests. Catalogued in docs/src/tests.md. Verified locally with cargo clippy (backend workspace + CLI both feature sets, all targets) — clean; full suite runs in CI.

Follow-ups (deliberately out of scope)

  • Server-side NAR content-hash verification on upload before signing (the worker path also trusts the reported hash; nix clients verify NarHash on download). Worth adding as defence-in-depth.
  • In-TUI NAR detail pane + delete action (browser currently does search/scroll).
  • --full-closure issues query_path_info twice per path (BFS + metadata); collapse into one pass.
  • The CLI workspace pins a different harmonia git rev than the backend (separate lockfiles); align if desired.

Replace the curl-only script with a single-node test (no worker, no test
store) that exercises the management + cache-NAR API surface both directly
and via the gradient CLI: auth, user/keys, orgs, projects, workers, caches,
and the new cache NAR upload/list/show/stats/delete flow (synthetic NAR, no
nix needed). Build-dependent endpoints are checked for empty/not-found
behaviour. OIDC/SMTP/forge/proto/build-request endpoints remain covered by
their dedicated tests.
@DerDennisOP

Copy link
Copy Markdown
Member Author

Reworked the gradient-api NixOS integration test (nix/tests/gradient/api/) in this PR:

  • Deleted the old curl-only (cmd) script.
  • New single-node test (no worker, no test store), modeled on the cache test's CLI-driven style.
  • Exercises the management + cache-NAR API surface both directly (curl) and via the gradient CLI: auth (register/login/check-username/logout), user + API keys, orgs (CRUD/ssh/roles/users/subscribe), projects (CRUD/details/triggers/active/actions), workers (register/list/patch/delete), caches (CRUD/key/stats/members/roles/upstreams/public/active).
  • Fully covers the new cache NAR upload flow on one node via a synthetic NAR (the endpoint validates length + store-path shape, not content): cache upload → list → show → stats → available → delete, via CLI and direct multipart.
  • Build-dependent endpoints (evals/builds/commits) are checked for empty/not-found behaviour since there's no worker.
  • --interactive flags are not exercised (as requested).
  • Out of scope (dedicated tests / external services): OIDC, SMTP e-mail verification, forge webhooks, proto websockets, build-request dispatch.

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

Add a second user and exercise org/cache membership (add/re-role/remove),
project transfer to a second org, custom cache-role lifecycle, HTTP upstream
CRUD, and org subscription remove/restore. Document the NixOS API surface
test in docs/src/tests.md.
@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

…on checks

Negative coverage: duplicate org/project/cache/role/cache-role/api-key/member/
subscription creates (enveloped 409), reserved project name and empty key
permission mask (enveloped 400). New permissions phase logs in the second user
and asserts View-role denials (403) on settings edit, project create, member
add, and org delete, then confirms Admin promotion unlocks them.
@DerDennisOP

Copy link
Copy Markdown
Member Author

/gradient run checks.x86_64-linux.gradient-api

@DerDennisOP
DerDennisOP merged commit 87e8c8a into main Jun 2, 2026
11 checks passed
@DerDennisOP
DerDennisOP deleted the feat/261-cache-upload-interactive-cli branch June 2, 2026 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gradient CLI cache NAR upload and make CLI Highly interactive

1 participant