From 8bac357dc6191f280ed54d98b9656b059cb33cfe Mon Sep 17 00:00:00 2001 From: donpat1to Date: Sun, 28 Sep 2025 00:36:52 +0200 Subject: [PATCH] added debugging for docker image --- WatcherAgent/Cargo.toml | 2 + WatcherAgent/src/serverclientcomm.rs | 156 +++++++++++++++++---------- 2 files changed, 101 insertions(+), 57 deletions(-) diff --git a/WatcherAgent/Cargo.toml b/WatcherAgent/Cargo.toml index 917b1b0..beaf41a 100644 --- a/WatcherAgent/Cargo.toml +++ b/WatcherAgent/Cargo.toml @@ -19,6 +19,8 @@ nvml-wrapper = "0.11" nvml-wrapper-sys = "0.9.0" anyhow = "1.0.98" +regex = "1.11.3" + # Docker .env loading # config = "0.13" diff --git a/WatcherAgent/src/serverclientcomm.rs b/WatcherAgent/src/serverclientcomm.rs index c4ed4cd..c802011 100644 --- a/WatcherAgent/src/serverclientcomm.rs +++ b/WatcherAgent/src/serverclientcomm.rs @@ -75,70 +75,88 @@ pub async fn update_docker_image(docker: &Docker, image: &str) -> Result<(), Box } pub async fn get_current_image(docker: &Docker) -> Result, Box> { - // Try multiple methods to get container ID - let container_id = get_container_id().await; - - let container_id = match container_id { - Some(id) => { - println!("Found container ID: {}", id); - id + // Get the current container ID from /proc/self/cgroup + let container_id = match std::fs::read_to_string("/proc/self/cgroup") { + Ok(content) => { + content + .lines() + .find_map(|line| { + // Look for any line that might contain container information + if line.contains("docker") || line.contains("crio") || line.contains("containerd") || line.contains("kubepods") { + // Extract the container ID from the line + extract_container_id(line) + } else { + None + } + }) } - None => { - eprintln!("Could not determine container ID"); + Err(e) => { + eprintln!("Error reading cgroup file: {}", e); return Ok(None); } }; - // Inspect the current container to get its image - match docker.inspect_container(&container_id, None::).await { - Ok(container_info) => { - Ok(container_info.config.map(|config| config.image.unwrap_or_else(|| "unknown".to_string()))) - } - Err(e) => { - eprintln!("Error inspecting container: {}", e); - Ok(None) - } - } -} + // Debug: Print what we found + println!("Container ID search result: {:?}", container_id); -async fn get_container_id() -> Option { - // Method 1: Try /proc/self/cgroup with various patterns - if let Ok(content) = std::fs::read_to_string("/proc/self/cgroup") { - for line in content.lines() { - // Try different container runtime identifiers - let patterns = ["docker", "crio", "containerd", "kubepods"]; - if patterns.iter().any(|&p| line.contains(p)) { - if let Some(id) = extract_container_id(line) { - return Some(id); + let container_id = match container_id { + Some(id) if !id.is_empty() => { + println!("Found container ID: '{}'", id); + id + } + _ => { + // Debug the cgroup file content + if let Ok(content) = std::fs::read_to_string("/proc/self/cgroup") { + eprintln!("Cgroup file content for debugging:"); + for (i, line) in content.lines().enumerate() { + eprintln!("Line {}: {}", i, line); } } + eprintln!("Could not find valid container ID in cgroup"); + return Ok(None); } + }; + + // Clean up the container ID - remove any non-hex characters + let clean_container_id: String = container_id + .chars() + .filter(|c| c.is_ascii_hexdigit()) + .collect(); + + // Validate the container ID (should be 64 characters for full ID, but short ID might work too) + if clean_container_id.is_empty() { + eprintln!("Container ID contains no hex characters: '{}'", container_id); + return Ok(None); } + + println!("Using container ID: '{}' (cleaned: '{}')", container_id, clean_container_id); + + // Try with both the original and cleaned ID + let ids_to_try = vec![&clean_container_id, &container_id]; - // Method 2: Try /proc/self/mountinfo - if let Ok(content) = std::fs::read_to_string("/proc/self/mountinfo") { - for line in content.lines() { - if line.contains("/docker/containers/") { - if let Some(start) = line.find("/docker/containers/") { - let rest = &line[start + 18..]; // 18 = len("/docker/containers/") - if let Some(end) = rest.find('/') { - return Some(rest[..end].to_string()); + for id in ids_to_try { + println!("Attempting to inspect container with ID: '{}'", id); + + match docker.inspect_container(id, None::).await { + Ok(container_info) => { + if let Some(config) = container_info.config { + if let Some(image) = config.image { + println!("Successfully found image: {}", image); + return Ok(Some(image)); } } + eprintln!("Container inspected but no image found in config"); + return Ok(Some("unknown".to_string())); + } + Err(e) => { + eprintln!("Error inspecting container with ID '{}': {}", id, e); + // Continue to try the next ID } } } - - // Method 3: Try hostname (works if container ID is used as hostname) - if let Ok(hostname) = std::fs::read_to_string("/etc/hostname") { - let hostname = hostname.trim(); - // Container IDs are typically 64-character hex strings - if hostname.len() == 64 && hostname.chars().all(|c| c.is_ascii_hexdigit()) { - return Some(hostname.to_string()); - } - } - - None + + eprintln!("All attempts to inspect container failed"); + Ok(None) } fn extract_container_id(line: &str) -> Option { @@ -147,21 +165,45 @@ fn extract_container_id(line: &str) -> Option { if let Some(last_part) = parts.last() { let last_part = last_part.trim(); - // Pattern 1: docker-.scope - if last_part.starts_with("docker-") && last_part.ends_with(".scope") { - return Some(last_part - .trim_start_matches("docker-") - .trim_end_matches(".scope") - .to_string()); - } + println!("Processing cgroup line part: '{}'", last_part); - // Pattern 2: (64-character hex) + // Common patterns for container IDs in cgroups: + + // Pattern 1: Full container ID (64-character hex) if last_part.len() == 64 && last_part.chars().all(|c| c.is_ascii_hexdigit()) { + println!("Found full container ID: {}", last_part); return Some(last_part.to_string()); } - // Pattern 3: Just take the last part as fallback + // Pattern 2: docker-.scope + if last_part.starts_with("docker-") && last_part.ends_with(".scope") { + let id = last_part + .trim_start_matches("docker-") + .trim_end_matches(".scope") + .to_string(); + println!("Found docker scope ID: {}", id); + return Some(id); + } + + // Pattern 3: (12-character hex or similar) + if last_part.chars().all(|c| c.is_ascii_hexdigit()) && last_part.len() >= 12 { + println!("Found hex ID: {}", last_part); + return Some(last_part.to_string()); + } + + // Pattern 4: Try to extract ID from any string that looks like it contains a hex ID + if let Some(caps) = regex::Regex::new(r"[a-fA-F0-9]{12,64}") + .ok() + .and_then(|re| re.find(last_part)) + { + let id = caps.as_str().to_string(); + println!("Extracted ID via regex: {}", id); + return Some(id); + } + + // Pattern 5: If nothing else matches, try the last part as-is if !last_part.is_empty() { + println!("Using last part as ID: {}", last_part); return Some(last_part.to_string()); } }