Enhance Docker integration and API for container management

- Implemented Docker container scanning and periodic updates in the Server initialization.
- Added new RPC endpoints for managing Docker containers, including start, stop, and restart functionalities.
- Updated the API to handle package management for Docker-based applications.
- Improved environment variable handling for user-specific configurations in Podman and Docker clients.
- Enhanced the development startup script to include Docker container management and provide clearer instructions for full stack setup.
This commit is contained in:
Dorian
2026-01-27 23:21:26 +00:00
parent 3b3f70276f
commit 30ed48ad1b
17 changed files with 2076 additions and 20 deletions
+8 -3
View File
@@ -65,8 +65,10 @@ impl PodmanClient {
fn podman_command(&self) -> Command {
let mut cmd = Command::new("podman");
if self.rootless {
// Run as the specified user
cmd.env("HOME", format!("/home/{}", self.user));
// Use actual HOME environment variable instead of hardcoded /home
if let Ok(home) = std::env::var("HOME") {
cmd.env("HOME", home);
}
}
cmd
}
@@ -74,7 +76,10 @@ impl PodmanClient {
fn podman_async(&self) -> TokioCommand {
let mut cmd = TokioCommand::new("podman");
if self.rootless {
cmd.env("HOME", format!("/home/{}", self.user));
// Use actual HOME environment variable instead of hardcoded /home
if let Ok(home) = std::env::var("HOME") {
cmd.env("HOME", home);
}
}
cmd
}
+28 -7
View File
@@ -92,14 +92,20 @@ impl DockerRuntime {
fn docker_async(&self) -> TokioCommand {
let mut cmd = TokioCommand::new("docker");
cmd.env("HOME", format!("/home/{}", self.user));
// Use actual HOME environment variable instead of hardcoded /home
if let Ok(home) = std::env::var("HOME") {
cmd.env("HOME", home);
}
cmd
}
#[allow(dead_code)]
fn docker_command(&self) -> Command {
let mut cmd = Command::new("docker");
cmd.env("HOME", format!("/home/{}", self.user));
// Use actual HOME environment variable instead of hardcoded /home
if let Ok(home) = std::env::var("HOME") {
cmd.env("HOME", home);
}
cmd
}
}
@@ -332,11 +338,26 @@ impl ContainerRuntime for DockerRuntime {
}
let json = String::from_utf8_lossy(&output.stdout);
let containers: Vec<serde_json::Value> = serde_json::from_str(&json)
.context("Failed to parse container list")?;
let mut result = Vec::new();
for container in containers {
// Docker returns NDJSON (newline-delimited JSON), not a JSON array
for line in json.lines() {
if line.trim().is_empty() {
continue;
}
let container: serde_json::Value = serde_json::from_str(line)
.context(format!("Failed to parse container JSON: {}", line))?;
// Extract ports from JSON
let ports_value = &container["Ports"];
let ports_str = ports_value.as_str().unwrap_or("");
let ports: Vec<String> = if !ports_str.is_empty() {
ports_str.split(", ").map(|s| s.to_string()).collect()
} else {
vec![]
};
result.push(ContainerStatus {
id: container["ID"].as_str().unwrap_or("").to_string(),
name: container["Names"].as_str().unwrap_or("").to_string(),
@@ -345,7 +366,7 @@ impl ContainerRuntime for DockerRuntime {
),
image: container["Image"].as_str().unwrap_or("").to_string(),
created: container["CreatedAt"].as_str().unwrap_or("").to_string(),
ports: vec![],
ports,
});
}