From c0e194fa6aa5bd7827fce6353b823fcf7e744191 Mon Sep 17 00:00:00 2001 From: Dave Kempe Date: Sun, 5 Apr 2026 08:09:02 +1000 Subject: [PATCH] v1.5.0: VDI Docker desktop containers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Major release adding ephemeral Docker desktop containers (VDI), session thumbnails with active sessions UI, and session-ended overlay. VDI: - New session type: VDI (Docker) — per-user ephemeral desktop containers - VdiDriver trait for downstream extensibility (JumpboxVDI) - DockerDriver: bollard API, deterministic naming, start/reuse/stop - Container lifecycle: persist after disconnect, reap after idle timeout - Per-entry idle timeout override via address book - Persistent home dirs via bind mount (home_base config) - Server disconnect detection (10.disconnect;) stops container on logout - Test image: contrib/vdi-test-image (Debian + xrdp + xfce4) Thumbnails & Active Sessions: - Client captures display screenshot every 10s (JPEG, 320px) - Active Sessions section in address book with thumbnail grid - Dormant VDI containers shown with last captured thumbnail - Click thumbnail to reconnect via address book connect flow UI: - Session ended overlay with Reconnect/Close buttons (all session types) - Sessions page: collapsible ad-hoc form, VDI option - Logout button moved out of settings dropdown Security: - Thumbnail endpoints require authentication - JPEG magic byte validation on upload - Path traversal protection on container thumbnails - Env var name/value validation for containers - Home base path traversal check Dependencies: - Added bollard 0.18 (Docker API client) - Updated russh 0.59, tokio 1.51, toml 1.1.2, libc 0.2.184 --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/vdi/docker.rs | 2 ++ src/vdi/mod.rs | 3 +++ 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3c55334..c30b447 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2985,7 +2985,7 @@ dependencies = [ [[package]] name = "rustguac" -version = "1.0.2" +version = "1.5.0" dependencies = [ "aes", "axum", diff --git a/Cargo.toml b/Cargo.toml index a3562ba..827b953 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustguac" -version = "1.0.2" +version = "1.5.0" edition = "2021" description = "Lightweight Rust replacement for Apache Guacamole client" diff --git a/src/vdi/docker.rs b/src/vdi/docker.rs index 50a6404..348cc80 100644 --- a/src/vdi/docker.rs +++ b/src/vdi/docker.rs @@ -412,6 +412,7 @@ impl DockerDriver { Ok(()) } + #[allow(dead_code)] async fn do_health_check(&self) -> Result<(), VdiError> { self.client .ping() @@ -420,6 +421,7 @@ impl DockerDriver { Ok(()) } + #[allow(dead_code)] async fn do_list_managed_containers(&self) -> Result, VdiError> { let mut filters = HashMap::new(); filters.insert("label", vec!["rustguac.managed=true"]); diff --git a/src/vdi/mod.rs b/src/vdi/mod.rs index be47e0c..72fc925 100644 --- a/src/vdi/mod.rs +++ b/src/vdi/mod.rs @@ -66,6 +66,7 @@ pub struct ContainerInfo { /// Errors specific to VDI operations. #[derive(Debug)] +#[allow(dead_code)] pub enum VdiError { /// Docker API or communication error. Docker(String), @@ -108,11 +109,13 @@ pub trait VdiDriver: Send + Sync { ) -> std::pin::Pin> + Send + 'a>>; /// Check if the driver backend is reachable (e.g. Docker socket exists). + #[allow(dead_code)] fn health_check( &self, ) -> std::pin::Pin> + Send + '_>>; /// List container IDs managed by rustguac (label `rustguac.managed=true`). + #[allow(dead_code)] fn list_managed_containers( &self, ) -> std::pin::Pin, VdiError>> + Send + '_>>;