From d988396111421c2889bab4ac8c6a9f361eb031f6 Mon Sep 17 00:00:00 2001 From: Dorian Date: Wed, 4 Feb 2026 16:20:09 +0000 Subject: [PATCH] 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. --- core/archipelago/src/api/rpc.rs | 13 ++++++++++++- core/container/src/podman_client.rs | 4 ++++ core/container/src/runtime.rs | 2 ++ neode-ui/src/stores/container.ts | 12 ++++++++++++ neode-ui/src/views/ContainerApps.vue | 16 +++++++++++----- 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/core/archipelago/src/api/rpc.rs b/core/archipelago/src/api/rpc.rs index c2c4f54e..92587966 100644 --- a/core/archipelago/src/api/rpc.rs +++ b/core/archipelago/src/api/rpc.rs @@ -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::>() ).unwrap_or_default(), + "lan_address": lan_address, }) }) .collect(); diff --git a/core/container/src/podman_client.rs b/core/container/src/podman_client.rs index 0c557ffb..8c9368fd 100644 --- a/core/container/src/podman_client.rs +++ b/core/container/src/podman_client.rs @@ -23,6 +23,7 @@ pub struct ContainerStatus { pub image: String, pub created: String, pub ports: Vec, + pub lan_address: Option, // 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 }); } } diff --git a/core/container/src/runtime.rs b/core/container/src/runtime.rs index 16317eac..484f2735 100644 --- a/core/container/src/runtime.rs +++ b/core/container/src/runtime.rs @@ -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, }); } diff --git a/neode-ui/src/stores/container.ts b/neode-ui/src/stores/container.ts index 6d870f5a..1d237ce1 100644 --- a/neode-ui/src/stores/container.ts +++ b/neode-ui/src/stores/container.ts @@ -96,6 +96,17 @@ export const useContainerStore = defineStore('container', () => { return container.state }) + // Get enriched bundled apps with runtime data (like lan_address) + const enrichedBundledApps = computed(() => { + return BUNDLED_APPS.map(app => { + const container = getContainerForApp.value(app.id) + return { + ...app, + lan_address: container?.lan_address + } + }) + }) + // Actions async function fetchContainers() { loading.value = true @@ -240,6 +251,7 @@ export const useContainerStore = defineStore('container', () => { getContainerForApp, isAppLoading, getAppState, + enrichedBundledApps, // Actions fetchContainers, fetchHealthStatus, diff --git a/neode-ui/src/views/ContainerApps.vue b/neode-ui/src/views/ContainerApps.vue index c137ec29..548b46dc 100644 --- a/neode-ui/src/views/ContainerApps.vue +++ b/neode-ui/src/views/ContainerApps.vue @@ -184,13 +184,13 @@