sal/container_builder_implementation_plan.md
2025-04-05 05:46:30 +02:00

7.5 KiB

Container Builder Implementation Plan

Overview

This document outlines the plan for redesigning the nerdctl interface in the src/virt/nerdctl directory to use an object-oriented approach with a Container struct that supports method chaining for the builder pattern. This will replace the existing function-based approach while maintaining all current functionality.

Architecture

classDiagram
    class Container {
        -String name
        -String container_id
        -String? image
        -HashMap~String, String~ config
        -Vec~String~ ports
        -Vec~String~ volumes
        -HashMap~String, String~ env_vars
        -Option~String~ network
        -Vec~String~ network_aliases
        -Option~String~ cpu_limit
        -Option~String~ memory_limit
        -Option~String~ memory_swap_limit
        -Option~String~ cpu_shares
        -Option~String~ restart_policy
        -Option~HealthCheck~ health_check
        +new(name: &str) -> Result~Container, NerdctlError~
        +from_image(name: &str, image: &str) -> Result~Container, NerdctlError~
        +with_port(port: &str) -> Container
        +with_ports(ports: &[&str]) -> Container
        +with_volume(volume: &str) -> Container
        +with_volumes(volumes: &[&str]) -> Container
        +with_env(key: &str, value: &str) -> Container
        +with_envs(env_map: &HashMap<&str, &str>) -> Container
        +with_network(network: &str) -> Container
        +with_network_alias(alias: &str) -> Container
        +with_network_aliases(aliases: &[&str]) -> Container
        +with_cpu_limit(cpus: &str) -> Container
        +with_memory_limit(memory: &str) -> Container
        +with_memory_swap_limit(memory_swap: &str) -> Container
        +with_cpu_shares(shares: &str) -> Container
        +with_restart_policy(policy: &str) -> Container
        +with_health_check(cmd: &str) -> Container
        +with_health_check_options(cmd: &str, interval: Option<&str>, timeout: Option<&str>, retries: Option<u32>, start_period: Option<&str>) -> Container
        +with_snapshotter(snapshotter: &str) -> Container
        +with_detach(detach: bool) -> Container
        +build() -> Result~Container, NerdctlError~
        +start() -> Result~CommandResult, NerdctlError~
        +stop() -> Result~CommandResult, NerdctlError~
        +remove() -> Result~CommandResult, NerdctlError~
        +exec(command: &str) -> Result~CommandResult, NerdctlError~
        +copy(source: &str, dest: &str) -> Result~CommandResult, NerdctlError~
        +export(path: &str) -> Result~CommandResult, NerdctlError~
        +commit(image_name: &str) -> Result~CommandResult, NerdctlError~
        +status() -> Result~ContainerStatus, NerdctlError~
        +health_status() -> Result~String, NerdctlError~
        +resources() -> Result~ResourceUsage, NerdctlError~
    }
    
    class HealthCheck {
        +String cmd
        +Option~String~ interval
        +Option~String~ timeout
        +Option~u32~ retries
        +Option~String~ start_period
    }
    
    class ContainerStatus {
        +String state
        +String status
        +String created
        +String started
        +Option~String~ health_status
        +Option~String~ health_output
    }
    
    class ResourceUsage {
        +String cpu_usage
        +String memory_usage
        +String memory_limit
        +String memory_percentage
        +String network_input
        +String network_output
        +String block_input
        +String block_output
        +String pids
    }
    
    class NerdctlError {
        +CommandExecutionFailed(io::Error)
        +CommandFailed(String)
        +JsonParseError(String)
        +ConversionError(String)
        +Other(String)
    }
    
    Container --> ContainerStatus : returns
    Container --> ResourceUsage : returns
    Container --> HealthCheck : contains
    Container --> NerdctlError : may throw

Implementation Steps

1. Create Container Struct and Basic Methods

Create a new file src/virt/nerdctl/container.rs with the Container struct and basic methods.

2. Implement Builder Pattern Methods

Add builder pattern methods to the Container struct for configuration.

3. Implement Container Operations

Add methods for container operations like start, stop, exec, etc.

4. Implement Status and Resource Usage Methods

Add methods for getting container status and resource usage information.

5. Update mod.rs to Export the New Container Struct

Update src/virt/nerdctl/mod.rs to include the new container module.

6. Create Example Usage

Create an example file to demonstrate the new Container API.

Key Features

Container Creation and Configuration

  • Method chaining for the builder pattern
  • Support for multiple ports and volumes
  • Environment variable configuration
  • Network configuration and aliases
  • Resource limits (CPU, memory)
  • Restart policies
  • Health checks

Container Operations

  • Start, stop, and remove containers
  • Execute commands in containers
  • Copy files between container and host
  • Export containers to tarballs
  • Commit containers to images

Container Monitoring

  • Get container status information
  • Get container health status
  • Get resource usage information

Example Usage

// Create a container with various configuration options
let container = Container::from_image("my-web-app", "nginx:latest")?
    .with_ports(&["8080:80", "8443:443"])
    .with_volumes(&[
        "./html:/usr/share/nginx/html",
        "./config/nginx.conf:/etc/nginx/nginx.conf"
    ])
    .with_env("NGINX_HOST", "example.com")
    .with_env("NGINX_PORT", "80")
    .with_network("app-network")
    .with_network_alias("web")
    .with_cpu_limit("0.5")
    .with_memory_limit("512m")
    .with_restart_policy("always")
    .with_health_check_options(
        "curl -f http://localhost/ || exit 1",
        Some("10s"),
        Some("5s"),
        Some(3),
        Some("30s")
    )
    .with_detach(true)
    .build()?;

// Start the container
container.start()?;

// Execute a command in the container
let result = container.exec("echo 'Hello from container'")?;
println!("Command output: {}", result.stdout);

// Get container status
let status = container.status()?;
println!("Container state: {}", status.state);
println!("Container status: {}", status.status);

// Get resource usage
let resources = container.resources()?;
println!("CPU usage: {}", resources.cpu_usage);
println!("Memory usage: {}", resources.memory_usage);

// Stop and remove the container
container.stop()?;
container.remove()?;

Network Management

// Create a network
Container::create_network("app-network", Some("bridge"))?;

// Create containers in the network
let db = Container::from_image("db", "postgres:latest")?
    .with_network("app-network")
    .with_network_alias("database")
    .with_env("POSTGRES_PASSWORD", "example")
    .build()?;

let app = Container::from_image("app", "my-app:latest")?
    .with_network("app-network")
    .with_env("DATABASE_URL", "postgres://postgres:example@database:5432/postgres")
    .build()?;

// Remove the network when done
Container::remove_network("app-network")?;

Migration Strategy

  1. Create the new Container struct and its methods
  2. Update the mod.rs file to export the new Container struct
  3. Create example usage to demonstrate the new API
  4. Deprecate the old function-based API (but keep it for backward compatibility)
  5. Update documentation to reflect the new API

Testing Strategy

  1. Unit tests for the Container struct and its methods
  2. Integration tests for the Container API
  3. Manual testing with real containers