12 KiB
SAL nerdctl
Module (sal::virt::nerdctl
)
Overview
The sal::virt::nerdctl
module provides a comprehensive Rust interface for interacting with nerdctl
, a command-line tool for containerd
.
It allows for managing container lifecycles, images, and other nerdctl
functionalities programmatically from Rust and through Rhai scripts via herodo
.
This module offers two primary ways to interact with nerdctl
:
- A fluent
Container
builder pattern for defining, creating, and managing containers with detailed configurations. - Direct static functions that wrap common
nerdctl
commands for quick operations on containers and images.
Core Components
1. NerdctlError
(in mod.rs
)
An enum defining specific error types for nerdctl
operations:
CommandExecutionFailed(io::Error)
:nerdctl
command failed to start (e.g., not found).CommandFailed(String)
:nerdctl
command executed but returned an error.JsonParseError(String)
: Failure to parse JSON output fromnerdctl
.ConversionError(String)
: Error during data type conversions.Other(String)
: Generic errors.
2. execute_nerdctl_command
(in cmd.rs
)
The core function for executing nerdctl
commands. It takes an array of string arguments, runs the command, and returns a CommandResult
or NerdctlError
.
// Example (internal usage)
// use sal::virt::nerdctl::execute_nerdctl_command;
// let result = execute_nerdctl_command(&["ps", "-a"]);
3. Container
Struct (defined in container_types.rs
, builder in container_builder.rs
, operations in container_operations.rs
)
Represents a nerdctl
container and is the centerpiece of the builder pattern.
Fields (Configuration):
name: String
: Name of the container.container_id: Option<String>
: ID of the container (populated after creation).image: Option<String>
: Base image for the container.ports: Vec<String>
: Port mappings (e.g.,"8080:80"
).volumes: Vec<String>
: Volume mounts (e.g.,"/host/path:/container/path"
).env_vars: HashMap<String, String>
: Environment variables.network: Option<String>
: Network to connect to.network_aliases: Vec<String>
: Network aliases.cpu_limit: Option<String>
,memory_limit: Option<String>
,memory_swap_limit: Option<String>
,cpu_shares: Option<String>
: Resource limits.restart_policy: Option<String>
: Restart policy (e.g.,"always"
).health_check: Option<HealthCheck>
: Health check configuration.detach: bool
: Whether to run in detached mode (default:false
, but Rhaicontainer_build
impliestrue
often).snapshotter: Option<String>
: Snapshotter to use.
Builder Methods (Fluent Interface - impl Container
in container_builder.rs
):
These methods configure the Container
object and return Self
for chaining.
Container::new(name: &str, image: &str)
: Constructor (Note: Rhai usesnerdctl_container_new(name)
andnerdctl_container_from_image(name, image)
which call underlying Rust constructors).reset()
: Resets configuration, stops/removes existing container with the same name.with_port(port: &str)
,with_ports(ports: &[&str])
with_volume(volume: &str)
,with_volumes(volumes: &[&str])
with_env(key: &str, value: &str)
,with_envs(env_map: &HashMap<&str, &str>)
with_network(network: &str)
with_network_alias(alias: &str)
,with_network_aliases(aliases: &[&str])
with_cpu_limit(cpus: &str)
with_memory_limit(memory: &str)
with_memory_swap_limit(memory_swap: &str)
with_cpu_shares(shares: &str)
with_restart_policy(policy: &str)
with_health_check(cmd: &str)
with_health_check_options(cmd, interval, timeout, retries, start_period)
with_snapshotter(snapshotter: &str)
with_detach(detach: bool)
**Action Methods (on Container
instances):
build()
(incontainer_builder.rs
): Assembles and executesnerdctl run
with all configured options. Populatescontainer_id
on success.start()
(incontainer_operations.rs
): Starts the container. If not yet built, it attempts to pull the image and build the container first. Verifies the container is running and provides detailed logs/status on failure.stop()
(incontainer_operations.rs
): Stops the container.remove()
(incontainer_operations.rs
): Removes the container.exec(command: &str)
(incontainer_operations.rs
): Executes a command in the container.copy(source: &str, dest: &str)
(incontainer_operations.rs
): Copies files/folders.source
/dest
must be formatted likecontainer_name_or_id:/path
or/local/path
.status()
(incontainer_operations.rs
): ReturnsContainerStatus
by parsingnerdctl inspect
.health_status()
(incontainer_operations.rs
): Returns the health status string fromnerdctl inspect
.logs()
(incontainer_operations.rs
): Fetches container logs.resources()
(incontainer_operations.rs
): ReturnsResourceUsage
by parsingnerdctl stats
.commit(image_name: &str)
(incontainer_operations.rs
): Commits the container to a new image.export(path: &str)
(incontainer_operations.rs
): Exports the container's filesystem as a tarball.
4. HealthCheck
Struct (in container_types.rs
)
Defines health check parameters:
cmd: String
: Command to execute.interval: Option<String>
timeout: Option<String>
retries: Option<u32>
start_period: Option<String>
5. prepare_health_check_command
(in health_check_script.rs
)
A helper function that takes a health check command string. If it's multi-line, it attempts to save it as an executable script in /root/hero/var/containers/healthcheck_<container_name>.sh
and returns the script path. Otherwise, returns the command as is. The path /root/hero/var/containers
implies this script needs to be accessible from within the target container at that specific location if a multi-line script is used.
6. Image
Struct (in images.rs
)
Represents a nerdctl
image, typically from nerdctl images
output.
id: String
repository: String
tag: String
size: String
created: String
7. Static Image Functions (in images.rs
)
These functions operate on images:
images() -> Result<CommandResult, NerdctlError>
: Lists images (nerdctl images
).image_remove(image: &str)
: Removes an image (nerdctl rmi
).image_push(image: &str, destination: &str)
: Pushes an image (nerdctl push
).image_tag(image: &str, new_name: &str)
: Tags an image (nerdctl tag
).image_pull(image: &str)
: Pulls an image (nerdctl pull
).image_commit(container: &str, image_name: &str)
: Commits a container to an image (nerdctl commit
).image_build(tag: &str, context_path: &str)
: Builds an image from a Dockerfile (nerdctl build -t <tag> <context_path>
).
8. Static Container Functions (in container_functions.rs
)
Direct wrappers for nerdctl
commands, an alternative to the builder pattern:
run(image: &str, name: Option<&str>, detach: bool, ports: Option<&[&str]>, snapshotter: Option<&str>)
: Runs a container.exec(container: &str, command: &str)
: Executes a command in a running container.copy(source: &str, dest: &str)
: Copies files.stop(container: &str)
: Stops a container.remove(container: &str)
: Removes a container.list(all: bool)
: Lists containers (nerdctl ps
).logs(container: &str)
: Fetches logs for a container.
9. ContainerStatus
and ResourceUsage
Structs (in container_types.rs
)
ContainerStatus
: Holds parsed data fromnerdctl inspect
(state, status, created, started, health info).ResourceUsage
: Holds parsed data fromnerdctl stats
(CPU, memory, network, block I/O, PIDs).
Usage Examples
Rust Example (Builder Pattern)
use sal::virt::nerdctl::{Container, NerdctlError};
use std::collections::HashMap;
fn main() -> Result<(), NerdctlError> {
let mut envs = HashMap::new();
envs.insert("MY_VAR", "my_value");
let container_config = Container::new("my_nginx_container", "nginx:latest") // Assuming a constructor like this exists or is adapted
.with_port("8080:80")
.with_envs(&envs)
.with_detach(true)
.with_restart_policy("always");
// Build (create and run) the container
let built_container = container_config.build()?;
println!("Container {} created with ID: {:?}", built_container.name, built_container.container_id);
// Perform operations
let status = built_container.status()?;
println!("Status: {}, State: {}", status.status, status.state);
// Stop and remove
built_container.stop()?;
built_container.remove()?;
println!("Container stopped and removed.");
Ok(())
}
Note: The direct Container::new(name, image)
constructor isn't explicitly shown in the provided Rust code snippets for Container
itself, but the Rhai bindings nerdctl_container_new
and nerdctl_container_from_image
imply underlying Rust constructors that initialize a Container
struct. The build()
method is the primary way to run it after configuration.
Rhai Script Example (using herodo
)
// Create and configure a container using the builder pattern
let c = nerdctl_container_from_image("my_redis", "redis:alpine")
.with_port("6379:6379")
.with_restart_policy("unless-stopped");
// Build and run the container
let running_container = c.build();
if running_container.is_ok() {
print(`Container ${running_container.name} ID: ${running_container.container_id}`);
// Get status
let status = running_container.status();
if status.is_ok() {
print(`Status: ${status.state}, Health: ${status.health_status}`);
}
// Stop the container (example, might need a mutable borrow or re-fetch)
// running_container.stop(); // Assuming stop is available and works on the result
// running_container.remove();
} else {
print(`Error building container: ${running_container.error()}`);
}
// Direct command example
let images = nerdctl_images();
print(images.stdout);
nerdctl_image_pull("alpine:latest");
Key Design Points
- Fluent Builder: The
Container
struct uses a builder pattern, allowing for clear and chainable configuration of container parameters before execution. - Comprehensive Operations: Covers most common
nerdctl
functionalities for containers and images. - Error Handling:
NerdctlError
provides typed errors. The Rhai layer adds more descriptive error messages for common scenarios. - Dual API: Offers both a detailed builder pattern and simpler static functions for flexibility.
- Health Check Scripting: Supports multi-line shell scripts for health checks by saving them to a file, though care must be taken regarding the script's accessibility from within the target container.
- Resource Parsing: Includes parsing for
nerdctl inspect
(JSON) andnerdctl stats
(tabular text) to provide structured information.
File Structure
src/virt/nerdctl/mod.rs
: Main module file, error definitions, sub-module declarations.src/virt/nerdctl/cmd.rs
: Coreexecute_nerdctl_command
function.src/virt/nerdctl/container_types.rs
: Definitions forContainer
,HealthCheck
,ContainerStatus
,ResourceUsage
.src/virt/nerdctl/container_builder.rs
: Implements the builder pattern methods for theContainer
struct.src/virt/nerdctl/container_operations.rs
: Implements instance methods onContainer
(start, stop, status, etc.).src/virt/nerdctl/images.rs
:Image
struct and static functions for image management.src/virt/nerdctl/container_functions.rs
: Static functions for direct container commands.src/virt/nerdctl/health_check_script.rs
: Logic forprepare_health_check_command
.src/rhai/nerdctl.rs
: Rhai script bindings forherodo
.