dashboard-v2: DashboardStorage RPC + aggregated /storage/* endpoints
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Successful in 18s

Storage tabs 404'd because the aggregator only had /fleet + /node/:name
after the pivot. Adds:

* New RPC method DashboardStorage = 0x1d — one round trip returns
  tags (full), snapshots (full), ref-tracking (full), blobs
  (first 200 by id), refs (first 200 by fp) for the responding
  daemon.
* Client wrapper call_dashboard_storage.
* Aggregator fans out to every peer, tags each row with the
  originating node, sorts + returns:
    GET /api/v2/storage/blobs
    GET /api/v2/storage/tags
    GET /api/v2/storage/refs
    GET /api/v2/storage/snapshots
    GET /api/v2/storage/ref-tracking

QuicClient promoted to Arc<QuicClient> inside V2State so the
per-peer JoinSet can hand it to spawned tasks without recreating
the endpoint.
This commit is contained in:
Omar Sobh
2026-07-14 16:39:45 -07:00
parent 0231b2bb65
commit 1211f0d891
3 changed files with 364 additions and 6 deletions
+10
View File
@@ -182,6 +182,16 @@ pub async fn call_dashboard_status(conn: &Connection) -> Result<DashboardStatusR
serde_json::from_slice(&reply).context("decoding DashboardStatusReply JSON")
}
pub async fn call_dashboard_storage(conn: &Connection) -> Result<DashboardStorageReply> {
let reply = rpc_call(conn, Method::DashboardStorage, &[]).await?;
if reply.len() == 1 {
if let Some(code) = decode_error(reply[0]) {
bail!("peer replied with error: {}", code.describe());
}
}
serde_json::from_slice(&reply).context("decoding DashboardStorageReply JSON")
}
/// Recognise a single-byte reply as one of our error codes. Returns
/// `None` for any other single-byte value (which is a valid reply,
/// just an unusually short one).