239 lines
7.5 KiB
Markdown
239 lines
7.5 KiB
Markdown
# 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
|
|
|
|
```mermaid
|
|
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
|
|
|
|
```rust
|
|
// 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
|
|
|
|
```rust
|
|
// 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
|