fix: dashboard — docker namespaced repos, npm proxy cache, upstream display (v0.2.30)

This commit is contained in:
2026-03-16 08:55:33 +00:00
parent 2cca9919ff
commit a9996b6b54
5 changed files with 434 additions and 11 deletions

View File

@@ -173,9 +173,12 @@ async fn build_docker_index(storage: &Storage) -> Vec<RepoInfo> {
}
if let Some(rest) = key.strip_prefix("docker/") {
let parts: Vec<_> = rest.split('/').collect();
if parts.len() >= 3 && parts[1] == "manifests" && key.ends_with(".json") {
let name = parts[0].to_string();
// Support namespaced repos: docker/{ns}/{name}/manifests/{tag}.json
// and flat repos: docker/{name}/manifests/{tag}.json
if let Some(manifests_pos) = rest.find("/manifests/") {
let name = rest[..manifests_pos].to_string();
let after_manifests = &rest[manifests_pos + "/manifests/".len()..];
if !after_manifests.is_empty() && key.ends_with(".json") {
let entry = repos.entry(name).or_insert((0, 0, 0));
entry.0 += 1;
@@ -204,7 +207,7 @@ async fn build_docker_index(storage: &Storage) -> Vec<RepoInfo> {
entry.2 = meta.modified;
}
}
}
}}
}
}
@@ -240,11 +243,11 @@ async fn build_npm_index(storage: &Storage) -> Vec<RepoInfo> {
let keys = storage.list("npm/").await;
let mut packages: HashMap<String, (usize, u64, u64)> = HashMap::new();
// Count tarballs instead of parsing metadata.json (faster than parsing JSON)
// Count tarballs first, then fall back to metadata.json for proxy-cached packages
for key in &keys {
if let Some(rest) = key.strip_prefix("npm/") {
// Pattern: npm/{package}/tarballs/{file}.tgz
if rest.contains("/tarballs/") && key.ends_with(".tgz") {
// Pattern: npm/{package}/tarballs/{file}.tgz
let parts: Vec<_> = rest.split('/').collect();
if !parts.is_empty() {
let name = parts[0].to_string();
@@ -258,6 +261,21 @@ async fn build_npm_index(storage: &Storage) -> Vec<RepoInfo> {
}
}
}
} else if rest.ends_with("/metadata.json") {
// Proxy-cached package: npm/{package}/metadata.json
// Show package in list but don't inflate version count from upstream metadata
if let Some(name) = rest.strip_suffix("/metadata.json") {
if !name.contains('/') {
packages.entry(name.to_string()).or_insert((0, 0, 0));
if let Some(stat) = storage.stat(key).await {
let entry = packages.get_mut(name).unwrap();
entry.1 += stat.size;
if stat.modified > entry.2 {
entry.2 = stat.modified;
}
}
}
}
}
}
}

View File

@@ -200,7 +200,12 @@ pub async fn api_dashboard(State(state): State<Arc<AppState>>) -> Json<Dashboard
MountPoint {
registry: "Docker".to_string(),
mount_path: "/v2/".to_string(),
proxy_upstream: None,
proxy_upstream: state
.config
.docker
.upstreams
.first()
.map(|u| u.url.clone()),
},
MountPoint {
registry: "Maven".to_string(),