Add lan_address support in RPC and container management

- Introduced a new `lan_address` field in the RPC response for containers, allowing for easier access to UI launch URLs based on container names.
- Updated the `ContainerStatus` struct to include `lan_address`, ensuring it is initialized and passed through relevant methods in both Podman and Docker runtimes.
- Enhanced the UI store to compute enriched bundled apps with their respective `lan_address`, improving the user experience for accessing containerized applications.
- Modified the `ContainerApps` view to utilize the enriched data, ensuring the correct launch URLs are displayed for bundled apps.
This commit is contained in:
Dorian
2026-02-04 16:20:09 +00:00
parent 59072bd16c
commit d988396111
5 changed files with 41 additions and 6 deletions
+12 -1
View File
@@ -322,15 +322,26 @@ impl RpcHandler {
_ => "unknown",
};
let name = c.get("Names").and_then(|v| v.as_array()).and_then(|a| a.first()).and_then(|v| v.as_str()).unwrap_or("");
// Determine lan_address based on container name
let lan_address = match name {
"bitcoin-knots" => Some("http://localhost:8334"),
"lnd" => Some("http://localhost:8081"),
"tailscale" => Some("http://localhost:8240"),
_ => None,
};
serde_json::json!({
"id": c.get("Id").and_then(|v| v.as_str()).unwrap_or(""),
"name": c.get("Names").and_then(|v| v.as_array()).and_then(|a| a.first()).and_then(|v| v.as_str()).unwrap_or(""),
"name": name,
"state": mapped_state,
"image": c.get("Image").and_then(|v| v.as_str()).unwrap_or(""),
"created": c.get("Created").and_then(|v| v.as_str()).unwrap_or(""),
"ports": c.get("Ports").and_then(|v| v.as_array()).map(|a|
a.iter().filter_map(|p| p.get("hostPort").and_then(|v| v.as_u64()).map(|p| p.to_string())).collect::<Vec<_>>()
).unwrap_or_default(),
"lan_address": lan_address,
})
})
.collect();
+4
View File
@@ -23,6 +23,7 @@ pub struct ContainerStatus {
pub image: String,
pub created: String,
pub ports: Vec<String>,
pub lan_address: Option<String>, // Launch URL for UI access
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
@@ -277,6 +278,7 @@ impl PodmanClient {
image: parts[3].to_string(),
created: parts[4].to_string(),
ports: vec![], // TODO: Parse ports from parts[5]
lan_address: None, // Set by docker_packages scanner
})
}
@@ -362,6 +364,7 @@ impl PodmanClient {
image: container["Image"].as_str().unwrap_or("").to_string(),
created: container["Created"].as_str().unwrap_or("").to_string(),
ports,
lan_address: None, // Set by docker_packages scanner
});
}
} else {
@@ -404,6 +407,7 @@ impl PodmanClient {
image: container["Image"].as_str().unwrap_or("").to_string(),
created: container["Created"].as_str().unwrap_or("").to_string(),
ports,
lan_address: None, // Set by docker_packages scanner
});
}
}
+2
View File
@@ -296,6 +296,7 @@ impl ContainerRuntime for DockerRuntime {
image: parts[3].to_string(),
created: parts[4].to_string(),
ports: vec![],
lan_address: None,
})
}
@@ -367,6 +368,7 @@ impl ContainerRuntime for DockerRuntime {
image: container["Image"].as_str().unwrap_or("").to_string(),
created: container["CreatedAt"].as_str().unwrap_or("").to_string(),
ports,
lan_address: None,
});
}