added example for nerdctl + testing nerdctl (still a bug with running container from image)
This commit is contained in:
parent
d6b53a72bb
commit
119d7ee50e
@ -17,7 +17,8 @@ pub fn run_nerdctl_example() -> Result<(), NerdctlError> {
|
|||||||
|
|
||||||
// Step 2: Create a container from the image
|
// Step 2: Create a container from the image
|
||||||
println!("\n=== Creating container from nginx:latest ===");
|
println!("\n=== Creating container from nginx:latest ===");
|
||||||
let run_result = nerdctl::run("nginx:latest", Some("my-nginx"), true, Some(&["8080:80"]))?;
|
// Use "native" snapshotter to avoid overlay mount issues
|
||||||
|
let run_result = nerdctl::run("nginx:latest", Some("my-nginx"), true, Some(&["8080:80"]), Some("native"))?;
|
||||||
println!("Container created: {}", run_result.stdout.trim());
|
println!("Container created: {}", run_result.stdout.trim());
|
||||||
let container_id = "my-nginx"; // Using the name we specified
|
let container_id = "my-nginx"; // Using the name we specified
|
||||||
|
|
||||||
@ -47,7 +48,8 @@ pub fn run_nerdctl_example() -> Result<(), NerdctlError> {
|
|||||||
|
|
||||||
// Step 7: Create a new container from our custom image
|
// Step 7: Create a new container from our custom image
|
||||||
println!("\n=== Creating container from custom image ===");
|
println!("\n=== Creating container from custom image ===");
|
||||||
nerdctl::run(image_name, Some("nginx-custom"), true, Some(&["8081:80"]))?;
|
// Use "native" snapshotter to avoid overlay mount issues
|
||||||
|
nerdctl::run(image_name, Some("nginx-custom"), true, Some(&["8081:80"]), Some("native"))?;
|
||||||
println!("Custom container created");
|
println!("Custom container created");
|
||||||
|
|
||||||
// Step 8: List images
|
// Step 8: List images
|
||||||
@ -78,5 +80,5 @@ pub fn run_all_examples() -> Result<(), NerdctlError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
run_all_examples();
|
let _ = run_all_examples().unwrap();
|
||||||
}
|
}
|
37
src/virt/nerdctl/cmd.rs
Normal file
37
src/virt/nerdctl/cmd.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// File: /root/code/git.ourworld.tf/herocode/sal/src/virt/nerdctl/cmd.rs
|
||||||
|
|
||||||
|
// Basic nerdctl operations for container management
|
||||||
|
use std::process::Command;
|
||||||
|
use crate::process::CommandResult;
|
||||||
|
use super::NerdctlError;
|
||||||
|
|
||||||
|
/// Execute a nerdctl command and return the result
|
||||||
|
pub fn execute_nerdctl_command(args: &[&str]) -> Result<CommandResult, NerdctlError> {
|
||||||
|
let output = Command::new("nerdctl")
|
||||||
|
.args(args)
|
||||||
|
.output();
|
||||||
|
|
||||||
|
match output {
|
||||||
|
Ok(output) => {
|
||||||
|
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
|
||||||
|
|
||||||
|
let result = CommandResult {
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
|
success: output.status.success(),
|
||||||
|
code: output.status.code().unwrap_or(-1),
|
||||||
|
};
|
||||||
|
|
||||||
|
if result.success {
|
||||||
|
Ok(result)
|
||||||
|
} else {
|
||||||
|
Err(NerdctlError::CommandFailed(format!("Command failed with code {}: {}",
|
||||||
|
result.code, result.stderr.trim())))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
Err(NerdctlError::CommandExecutionFailed(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
105
src/virt/nerdctl/containers.rs
Normal file
105
src/virt/nerdctl/containers.rs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// File: /root/code/git.ourworld.tf/herocode/sal/src/virt/nerdctl/containers.rs
|
||||||
|
|
||||||
|
use crate::virt::nerdctl::execute_nerdctl_command;
|
||||||
|
use crate::process::CommandResult;
|
||||||
|
use super::NerdctlError;
|
||||||
|
|
||||||
|
/// Run a container from an image
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `image` - The image to run
|
||||||
|
/// * `name` - Optional container name
|
||||||
|
/// * `detach` - Whether to run in detached mode
|
||||||
|
/// * `ports` - Optional port mappings (e.g., ["8080:80"])
|
||||||
|
/// * `snapshotter` - Optional snapshotter to use (e.g., "native", "fuse-overlayfs")
|
||||||
|
pub fn run(image: &str, name: Option<&str>, detach: bool, ports: Option<&[&str]>, snapshotter: Option<&str>) -> Result<CommandResult, NerdctlError> {
|
||||||
|
// First, try to remove any existing container with the same name to avoid conflicts
|
||||||
|
if let Some(name_str) = name {
|
||||||
|
// Ignore errors since the container might not exist
|
||||||
|
let _ = execute_nerdctl_command(&["rm", "-f", name_str]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut args = vec!["run"];
|
||||||
|
|
||||||
|
if detach {
|
||||||
|
args.push("-d");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(name_str) = name {
|
||||||
|
args.push("--name");
|
||||||
|
args.push(name_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(port_mappings) = ports {
|
||||||
|
for port in port_mappings {
|
||||||
|
args.push("-p");
|
||||||
|
args.push(port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(snapshotter_value) = snapshotter {
|
||||||
|
args.push("--snapshotter");
|
||||||
|
args.push(snapshotter_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add flags to avoid BPF issues
|
||||||
|
args.push("--cgroup-manager=cgroupfs");
|
||||||
|
|
||||||
|
args.push(image);
|
||||||
|
|
||||||
|
execute_nerdctl_command(&args)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Execute a command in a container
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `container` - The container ID or name
|
||||||
|
/// * [command](cci:1://file:///root/code/git.ourworld.tf/herocode/sal/src/process/run.rs:303:0-324:1) - The command to run
|
||||||
|
pub fn exec(container: &str, command: &str) -> Result<CommandResult, NerdctlError> {
|
||||||
|
execute_nerdctl_command(&["exec", container, "sh", "-c", command])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copy files between container and local filesystem
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * [source](cci:1://file:///root/code/git.ourworld.tf/herocode/sal/src/process/run.rs:55:4-64:5) - Source path (can be container:path or local path)
|
||||||
|
/// * `dest` - Destination path (can be container:path or local path)
|
||||||
|
pub fn copy(source: &str, dest: &str) -> Result<CommandResult, NerdctlError> {
|
||||||
|
execute_nerdctl_command(&["cp", source, dest])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stop a container
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `container` - The container ID or name
|
||||||
|
pub fn stop(container: &str) -> Result<CommandResult, NerdctlError> {
|
||||||
|
execute_nerdctl_command(&["stop", container])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove a container
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `container` - The container ID or name
|
||||||
|
pub fn remove(container: &str) -> Result<CommandResult, NerdctlError> {
|
||||||
|
execute_nerdctl_command(&["rm", container])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// List containers
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `all` - Whether to show all containers (including stopped ones)
|
||||||
|
pub fn list(all: bool) -> Result<CommandResult, NerdctlError> {
|
||||||
|
let mut args = vec!["ps"];
|
||||||
|
|
||||||
|
if all {
|
||||||
|
args.push("-a");
|
||||||
|
}
|
||||||
|
|
||||||
|
execute_nerdctl_command(&args)
|
||||||
|
}
|
86
src/virt/nerdctl/images.rs
Normal file
86
src/virt/nerdctl/images.rs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// File: /root/code/git.ourworld.tf/herocode/sal/src/virt/nerdctl/images.rs
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use crate::virt::nerdctl::execute_nerdctl_command;
|
||||||
|
use crate::process::CommandResult;
|
||||||
|
use super::NerdctlError;
|
||||||
|
use serde_json::{self, Value};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// Represents a container image
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Image {
|
||||||
|
/// Image ID
|
||||||
|
pub id: String,
|
||||||
|
/// Image repository
|
||||||
|
pub repository: String,
|
||||||
|
/// Image tag
|
||||||
|
pub tag: String,
|
||||||
|
/// Image size
|
||||||
|
pub size: String,
|
||||||
|
/// Creation timestamp
|
||||||
|
pub created: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// List images in local storage
|
||||||
|
pub fn images() -> Result<CommandResult, NerdctlError> {
|
||||||
|
execute_nerdctl_command(&["images"])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove one or more images
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `image` - Image ID or name
|
||||||
|
pub fn image_remove(image: &str) -> Result<CommandResult, NerdctlError> {
|
||||||
|
execute_nerdctl_command(&["rmi", image])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Push an image to a registry
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `image` - Image name
|
||||||
|
/// * `destination` - Destination registry URL
|
||||||
|
pub fn image_push(image: &str, destination: &str) -> Result<CommandResult, NerdctlError> {
|
||||||
|
execute_nerdctl_command(&["push", image, destination])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add an additional name to a local image
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `image` - Image ID or name
|
||||||
|
/// * `new_name` - New name for the image
|
||||||
|
pub fn image_tag(image: &str, new_name: &str) -> Result<CommandResult, NerdctlError> {
|
||||||
|
execute_nerdctl_command(&["tag", image, new_name])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pull an image from a registry
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `image` - Image name
|
||||||
|
pub fn image_pull(image: &str) -> Result<CommandResult, NerdctlError> {
|
||||||
|
execute_nerdctl_command(&["pull", image])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Commit a container to an image
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `container` - Container ID or name
|
||||||
|
/// * `image_name` - New name for the image
|
||||||
|
pub fn image_commit(container: &str, image_name: &str) -> Result<CommandResult, NerdctlError> {
|
||||||
|
execute_nerdctl_command(&["commit", container, image_name])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build an image using a Dockerfile
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `tag` - Tag for the new image
|
||||||
|
/// * `context_path` - Path to the build context
|
||||||
|
pub fn image_build(tag: &str, context_path: &str) -> Result<CommandResult, NerdctlError> {
|
||||||
|
execute_nerdctl_command(&["build", "-t", tag, context_path])
|
||||||
|
}
|
47
src/virt/nerdctl/mod.rs
Normal file
47
src/virt/nerdctl/mod.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
mod containers;
|
||||||
|
mod images;
|
||||||
|
mod cmd;
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
/// Error type for nerdctl 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 containers::*;
|
||||||
|
pub use images::*;
|
||||||
|
pub use cmd::*;
|
@ -465,3 +465,39 @@ nerdctl supports various security features:
|
|||||||
- `--security-opt apparmor=profile`: Apply an AppArmor profile
|
- `--security-opt apparmor=profile`: Apply an AppArmor profile
|
||||||
- `--cap-add`/`--cap-drop`: Add or drop Linux capabilities
|
- `--cap-add`/`--cap-drop`: Add or drop Linux capabilities
|
||||||
- `--privileged`: Give extended privileges to the container
|
- `--privileged`: Give extended privileges to the container
|
||||||
|
|
||||||
|
## Typical Workflow Example
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create a container from an existing image
|
||||||
|
container=$(nerdctl run -d --name my-nginx nginx:latest)
|
||||||
|
|
||||||
|
# Execute a command in the container
|
||||||
|
nerdctl exec $container apt-get update
|
||||||
|
nerdctl exec $container apt-get install -y curl
|
||||||
|
|
||||||
|
# Copy local configuration files to the container
|
||||||
|
nerdctl cp ./nginx.conf $container:/etc/nginx/nginx.conf
|
||||||
|
|
||||||
|
# Commit the container to create a new image
|
||||||
|
nerdctl commit $container my-custom-nginx:latest
|
||||||
|
|
||||||
|
# Stop and remove the container
|
||||||
|
nerdctl stop $container
|
||||||
|
nerdctl rm $container
|
||||||
|
|
||||||
|
# Create a new container from our custom image
|
||||||
|
nerdctl run -d --name nginx-custom -p 8080:80 my-custom-nginx:latest
|
||||||
|
|
||||||
|
# Build an image using a Dockerfile
|
||||||
|
nerdctl build -t my-app:latest .
|
||||||
|
|
||||||
|
# Push the image to a registry
|
||||||
|
nerdctl push my-custom-nginx:latest docker.io/username/my-custom-nginx:latest
|
||||||
|
|
||||||
|
# List images
|
||||||
|
nerdctl images
|
||||||
|
|
||||||
|
# List containers
|
||||||
|
nerdctl ps -a
|
||||||
|
```
|
Loading…
Reference in New Issue
Block a user