This commit is contained in:
2025-04-05 07:23:07 +02:00
parent 6de7bf9b56
commit 6d4c1742e7
14 changed files with 533 additions and 455 deletions

View File

@@ -3,6 +3,7 @@
use std::collections::HashMap;
use crate::process::CommandResult;
use crate::virt::nerdctl::{execute_nerdctl_command, NerdctlError};
use crate::os;
use super::container_types::{Container, HealthCheck, ContainerStatus, ResourceUsage};
impl Container {
@@ -16,6 +17,15 @@ impl Container {
///
/// * `Result<Self, NerdctlError>` - Container instance or error
pub fn new(name: &str) -> Result<Self, NerdctlError> {
// Check if required commands exist
match os::cmd_ensure_exists("nerdctl,runc,buildah") {
Err(e) => return Err(NerdctlError::CommandExecutionFailed(
std::io::Error::new(std::io::ErrorKind::NotFound,
format!("Required commands not found: {}", e))
)),
_ => {}
}
// Check if container exists
let result = execute_nerdctl_command(&["ps", "-a", "--format", "{{.Names}} {{.ID}}"])?;

View File

@@ -3,6 +3,7 @@
use std::collections::HashMap;
use crate::virt::nerdctl::{execute_nerdctl_command, NerdctlError};
use super::container_types::{Container, HealthCheck};
use super::health_check_script::prepare_health_check_command;
impl Container {
/// Add a port mapping
@@ -220,8 +221,11 @@ impl Container {
///
/// * `Self` - The container instance for method chaining
pub fn with_health_check(mut self, cmd: &str) -> Self {
// Use the health check script module to prepare the command
let prepared_cmd = prepare_health_check_command(cmd, &self.name);
self.health_check = Some(HealthCheck {
cmd: cmd.to_string(),
cmd: prepared_cmd,
interval: None,
timeout: None,
retries: None,
@@ -251,8 +255,11 @@ impl Container {
retries: Option<u32>,
start_period: Option<&str>,
) -> Self {
// Use the health check script module to prepare the command
let prepared_cmd = prepare_health_check_command(cmd, &self.name);
let mut health_check = HealthCheck {
cmd: cmd.to_string(),
cmd: prepared_cmd,
interval: None,
timeout: None,
retries: None,

View File

@@ -288,18 +288,18 @@ impl Container {
} else {
Err(NerdctlError::Other("No container ID available".to_string()))
}
/// Get container logs
///
/// # Returns
///
/// * `Result<CommandResult, NerdctlError>` - Command result or error
pub fn logs(&self) -> Result<CommandResult, NerdctlError> {
if let Some(container_id) = &self.container_id {
execute_nerdctl_command(&["logs", container_id])
} else {
Err(NerdctlError::Other("No container ID available".to_string()))
}
}
/// Get container logs
///
/// # Returns
///
/// * `Result<CommandResult, NerdctlError>` - Command result or error
pub fn logs(&self) -> Result<CommandResult, NerdctlError> {
if let Some(container_id) = &self.container_id {
execute_nerdctl_command(&["logs", container_id])
} else {
Err(NerdctlError::Other("No container ID available".to_string()))
}
}

View File

@@ -0,0 +1,79 @@
// File: /root/code/git.ourworld.tf/herocode/sal/src/virt/nerdctl/health_check_script.rs
use std::fs;
use std::path::Path;
use std::os::unix::fs::PermissionsExt;
/// Handles health check scripts for containers
///
/// This module provides functionality to create and manage health check scripts
/// for containers, allowing for more complex health checks than simple commands.
/// Converts a health check command or script to a usable command
///
/// If the input is a single-line command, it is returned as is.
/// If the input is a multi-line script, it is written to a file in the
/// /root/hero/var/containers directory and the path to that file is returned.
///
/// # Arguments
///
/// * `cmd` - The command or script to convert
/// * `container_name` - The name of the container, used to create a unique script name
///
/// # Returns
///
/// * `String` - The command to use for the health check
pub fn prepare_health_check_command(cmd: &str, container_name: &str) -> String {
// If the command is a multiline script, write it to a file
if cmd.contains("\n") {
// Create the directory if it doesn't exist
let dir_path = "/root/hero/var/containers";
if let Err(_) = fs::create_dir_all(dir_path) {
// If we can't create the directory, just use the command as is
return cmd.to_string();
}
// Create a unique filename based on container name
let script_path = format!("{}/healthcheck_{}.sh", dir_path, container_name);
// Write the script to the file
if let Err(_) = fs::write(&script_path, cmd) {
// If we can't write the file, just use the command as is
return cmd.to_string();
}
// Make the script executable
if let Ok(metadata) = fs::metadata(&script_path) {
let mut perms = metadata.permissions();
perms.set_mode(0o755);
if let Err(_) = fs::set_permissions(&script_path, perms) {
// If we can't set permissions, just use the script path with sh
return format!("sh {}", script_path);
}
} else {
// If we can't get metadata, just use the script path with sh
return format!("sh {}", script_path);
}
// Use the script path as the command
script_path
} else {
// If it's a single line command, use it as is
cmd.to_string()
}
}
/// Cleans up health check scripts for a container
///
/// # Arguments
///
/// * `container_name` - The name of the container whose health check scripts should be cleaned up
pub fn cleanup_health_check_scripts(container_name: &str) {
let dir_path = "/root/hero/var/containers";
let script_path = format!("{}/healthcheck_{}.sh", dir_path, container_name);
// Try to remove the script file if it exists
if Path::new(&script_path).exists() {
let _ = fs::remove_file(script_path);
}
}

View File

@@ -4,6 +4,7 @@ mod container_types;
mod container;
mod container_builder;
mod health_check;
mod health_check_script;
mod container_operations;
mod container_functions;
#[cfg(test)]
@@ -52,4 +53,5 @@ impl Error for NerdctlError {
pub use images::*;
pub use cmd::*;
pub use container_types::{Container, HealthCheck, ContainerStatus, ResourceUsage};
pub use container_functions::*;
pub use container_functions::*;
pub use health_check_script::*;