herolib-virt 0.3.13

Virtualization and container management for herolib (buildah, nerdctl, kubernetes)
Documentation
//! Nerdctl: Container Lifecycle Management
//!
//! This module provides a comprehensive Rust interface for managing containers with `nerdctl`,
//! which is a Docker-compatible CLI for containerd. Nerdctl provides access to containerd's
//! functionality without requiring Docker daemon.
//!
//! # Features
//!
//! - **Container Management**: Create, start, stop, remove containers
//! - **Image Operations**: Pull, push, list, and manage container images
//! - **Container Builder**: Fluent API for building complex container configurations
//! - **Health Checks**: Configure and monitor container health status
//! - **Resource Limits**: Set CPU, memory, and other resource constraints
//! - **Port Mapping**: Configure port forwarding for network access
//! - **Environment Variables**: Manage container environment configuration
//! - **Volumes**: Mount volumes and manage data persistence
//! - **Networking**: Configure container networking and DNS
//! - **Log Access**: Retrieve container logs for debugging
//!
//! # Requirements
//!
//! - `nerdctl` command-line tool must be installed and on PATH
//! - containerd runtime properly configured
//! - Sufficient permissions to manage containers
//!
//! # Quick Start
//!
//! ## Creating and Running a Container
//!
//! ```rust,no_run
//! use herolib_virt::nerdctl;
//!
//! // Run a simple container
//! let result = nerdctl::run(
//!     "nginx:latest",
//!     Some("my-nginx"),
//!     true, // detach
//!     None, // ports
//!     None, // snapshotter
//! )?;
//!
//! println!("Container run result: {:?}", result);
//! # Ok::<(), nerdctl::NerdctlError>(())
//! ```
//!
//! ## Using the Container Builder
//!
//! ```rust,no_run
//! use herolib_virt::nerdctl;
//!
//! let container = nerdctl::Container::from_image("my-app", "node:18")?
//!     .with_port("3000:3000")
//!     .with_env("NODE_ENV", "production")
//!     .with_memory_limit("512m")
//!     .with_cpu_limit("1.0")
//!     .build()?;
//!
//! println!("Created: {}", container.name);
//! # Ok::<(), nerdctl::NerdctlError>(())
//! ```
//!
//! ## Managing Container Lifecycle
//!
//! ```rust,no_run
//! use herolib_virt::nerdctl;
//!
//! // Create a container instance
//! let container = nerdctl::Container::from_image("my-container", "nginx:latest")?;
//!
//! // Start the container
//! container.start()?;
//!
//! // Stop the container
//! container.stop()?;
//!
//! // Remove the container
//! container.remove()?;
//!
//! // Get container status
//! let info = container.status()?;
//! println!("Status: {:?}", info.state);
//! # Ok::<(), nerdctl::NerdctlError>(())
//! ```
//!
//! ## Working with Images
//!
//! ```rust,no_run
//! use herolib_virt::nerdctl;
//!
//! // Pull an image from registry
//! nerdctl::image_pull("docker.io/library/nginx:latest")?;
//!
//! // List available images
//! let images = nerdctl::images()?;
//! println!("Images result: {:?}", images);
//!
//! // Remove an image
//! nerdctl::image_remove("nginx:latest")?;
//! # Ok::<(), nerdctl::NerdctlError>(())
//! ```
//!
//! # Module Organization
//!
//! - `cmd` - Low-level command execution and parsing
//! - `container` - Core container type and operations
//! - `container_builder` - Fluent builder for container creation
//! - `container_functions` - High-level container management functions
//! - `container_operations` - Direct container operations
//! - `container_types` - Data types for containers and statuses
//! - `health_check` - Health check configuration
//! - `health_check_script` - Health check script generation
//! - `images` - Image management operations
//!
//! # Common Patterns
//!
//! ## Pattern: Simple Web Server
//!
//! ```rust,no_run
//! use herolib_virt::nerdctl;
//!
//! // Create and run a web server
//! let container = nerdctl::Container::from_image("web", "nginx:latest")?
//!     .with_port("8080:80")  // Map host port 8080 to container port 80
//!     .with_env("TZ", "UTC")
//!     .with_restart_policy("unless-stopped")
//!     .build()?;
//!
//! println!("Web server running on: http://localhost:8080");
//! # Ok::<(), nerdctl::NerdctlError>(())
//! ```
//!
//! ## Pattern: Database with Persistent Storage
//!
//! ```rust,no_run
//! use herolib_virt::nerdctl;
//!
//! let container = nerdctl::Container::from_image("db", "postgres:15")?
//!     .with_env("POSTGRES_PASSWORD", "secret123")
//!     .with_env("POSTGRES_DB", "myapp")
//!     .with_volume("/var/lib/postgresql/data:db-volume")
//!     .with_memory_limit("1g")
//!     .build()?;
//!
//! println!("Database container created with persistent volume");
//! # Ok::<(), nerdctl::NerdctlError>(())
//! ```
//!
//! ## Pattern: Multi-Container Application Stack
//!
//! ```rust,no_run
//! use herolib_virt::nerdctl;
//!
//! // Web server
//! let web = nerdctl::Container::from_image("web", "nginx:latest")?
//!     .with_port("8080:80")
//!     .build()?;
//!
//! // Application server
//! let app = nerdctl::Container::from_image("app", "node:18")?
//!     .with_env("NODE_ENV", "production")
//!     .with_env("DATABASE_URL", "postgres://db:5432/myapp")
//!     .build()?;
//!
//! // Database
//! let db = nerdctl::Container::from_image("db", "postgres:15")?
//!     .with_env("POSTGRES_PASSWORD", "secret")
//!     .with_volume("/var/lib/postgresql/data:db-volume")
//!     .build()?;
//!
//! println!("Application stack deployed");
//! # Ok::<(), nerdctl::NerdctlError>(())
//! ```
//!
//! # Error Handling
//!
//! All operations return `Result<T, NerdctlError>`. Common errors include:
//!
//! - **CommandExecutionFailed**: `nerdctl` not found or cannot execute
//! - **CommandFailed**: Nerdctl command returned an error
//! - **JsonParseError**: Failed to parse nerdctl JSON output
//! - **ConversionError**: Type conversion failed
//! - **Other**: Various validation or runtime errors
//!
//! # Health Checks
//!
//! Configure container health monitoring:
//!
//! ```rust,no_run
//! use herolib_virt::nerdctl;
//!
//! let container = nerdctl::Container::from_image("web", "nginx:latest")?
//!     .with_health_check("curl localhost:80")
//!     .build()?;
//! # Ok::<(), nerdctl::NerdctlError>(())
//! ```
//!
//! # Rhai Integration
//!
//! Nerdctl operations are fully accessible from Rhai scripts:
//!
//! ```rhai
//! // Create and run a container
//! let container = ndc("my-web", "nginx:latest");
//! print("Container created: " + container.id);
//!
//! // Start and stop
//! ndc_start("my-web");
//! ndc_stop("my-web", 30);
//!
//! // List containers
//! let containers = ndc_ps();
//! for c in containers {
//!     print("Container: " + c.id + " - " + c.status);
//! }
//! ```

mod cmd;
mod container;
mod container_builder;
mod container_functions;
mod container_operations;
#[cfg(test)]
mod container_test;
mod container_types;
mod health_check;
mod health_check_script;
mod images;
pub mod rhai;

use std::error::Error;
use std::fmt;
use std::io;

/// Error type for nerdctl operations
///
/// Represents various errors that can occur during container management operations.
#[derive(Debug)]
pub enum NerdctlError {
    /// The nerdctl command failed to execute
    CommandExecutionFailed(io::Error),
    /// The nerdctl command executed but returned an error
    CommandFailed(String),
    /// Failed to parse JSON output
    JsonParseError(String),
    /// Failed to convert data
    ConversionError(String),
    /// Generic error
    Other(String),
}

impl fmt::Display for NerdctlError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            NerdctlError::CommandExecutionFailed(e) => {
                write!(f, "Failed to execute nerdctl command: {}", e)
            }
            NerdctlError::CommandFailed(e) => write!(f, "Nerdctl command failed: {}", e),
            NerdctlError::JsonParseError(e) => write!(f, "Failed to parse JSON: {}", e),
            NerdctlError::ConversionError(e) => write!(f, "Conversion error: {}", e),
            NerdctlError::Other(e) => write!(f, "{}", e),
        }
    }
}

impl Error for NerdctlError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match self {
            NerdctlError::CommandExecutionFailed(e) => Some(e),
            _ => None,
        }
    }
}

pub use cmd::*;
pub use container_functions::*;
pub use container_types::{Container, ContainerStatus, HealthCheck, ResourceUsage};
pub use health_check_script::*;
pub use images::*;