- Migrate individual modules to independent crates - Refactor dependencies for improved modularity - Update build system and testing infrastructure - Update documentation to reflect new structure
620 lines
22 KiB
Rust
620 lines
22 KiB
Rust
//! Rhai wrappers for Nerdctl module functions
|
|
//!
|
|
//! This module provides Rhai wrappers for the functions in the Nerdctl module.
|
|
|
|
use crate::nerdctl::{self, Container, Image, NerdctlError};
|
|
use rhai::{Array, Dynamic, Engine, EvalAltResult, Map};
|
|
use sal_process::CommandResult;
|
|
|
|
// Helper functions for error conversion with improved context
|
|
fn nerdctl_error_to_rhai_error<T>(
|
|
result: Result<T, NerdctlError>,
|
|
) -> Result<T, Box<EvalAltResult>> {
|
|
result.map_err(|e| {
|
|
// Create a more detailed error message based on the error type
|
|
let error_message = match &e {
|
|
NerdctlError::CommandExecutionFailed(io_err) => {
|
|
format!("Failed to execute nerdctl command: {}. This may indicate nerdctl is not installed or not in PATH.", io_err)
|
|
},
|
|
NerdctlError::CommandFailed(msg) => {
|
|
format!("Nerdctl command failed: {}. Check container status and logs for more details.", msg)
|
|
},
|
|
NerdctlError::JsonParseError(msg) => {
|
|
format!("Failed to parse nerdctl JSON output: {}. This may indicate an incompatible nerdctl version.", msg)
|
|
},
|
|
NerdctlError::ConversionError(msg) => {
|
|
format!("Data conversion error: {}. This may indicate unexpected output format from nerdctl.", msg)
|
|
},
|
|
NerdctlError::Other(msg) => {
|
|
format!("Nerdctl error: {}. This is an unexpected error.", msg)
|
|
},
|
|
};
|
|
Box::new(EvalAltResult::ErrorRuntime(
|
|
error_message.into(),
|
|
rhai::Position::NONE
|
|
))
|
|
})
|
|
}
|
|
|
|
//
|
|
// Container Builder Pattern Implementation
|
|
//
|
|
|
|
/// Create a new Container
|
|
pub fn container_new(name: &str) -> Result<Container, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(Container::new(name))
|
|
}
|
|
|
|
/// Create a Container from an image
|
|
pub fn container_from_image(name: &str, image: &str) -> Result<Container, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(Container::from_image(name, image))
|
|
}
|
|
|
|
/// Reset the container configuration to defaults while keeping the name and image
|
|
pub fn container_reset(container: Container) -> Container {
|
|
container.reset()
|
|
}
|
|
|
|
/// Add a port mapping to a Container
|
|
pub fn container_with_port(container: Container, port: &str) -> Container {
|
|
container.with_port(port)
|
|
}
|
|
|
|
/// Add a volume mount to a Container
|
|
pub fn container_with_volume(container: Container, volume: &str) -> Container {
|
|
container.with_volume(volume)
|
|
}
|
|
|
|
/// Add an environment variable to a Container
|
|
pub fn container_with_env(container: Container, key: &str, value: &str) -> Container {
|
|
container.with_env(key, value)
|
|
}
|
|
|
|
/// Set the network for a Container
|
|
pub fn container_with_network(container: Container, network: &str) -> Container {
|
|
container.with_network(network)
|
|
}
|
|
|
|
/// Add a network alias to a Container
|
|
pub fn container_with_network_alias(container: Container, alias: &str) -> Container {
|
|
container.with_network_alias(alias)
|
|
}
|
|
|
|
/// Set CPU limit for a Container
|
|
pub fn container_with_cpu_limit(container: Container, cpus: &str) -> Container {
|
|
container.with_cpu_limit(cpus)
|
|
}
|
|
|
|
/// Set memory limit for a Container
|
|
pub fn container_with_memory_limit(container: Container, memory: &str) -> Container {
|
|
container.with_memory_limit(memory)
|
|
}
|
|
|
|
/// Set restart policy for a Container
|
|
pub fn container_with_restart_policy(container: Container, policy: &str) -> Container {
|
|
container.with_restart_policy(policy)
|
|
}
|
|
|
|
/// Set health check for a Container
|
|
pub fn container_with_health_check(container: Container, cmd: &str) -> Container {
|
|
container.with_health_check(cmd)
|
|
}
|
|
|
|
/// Add multiple port mappings to a Container
|
|
pub fn container_with_ports(mut container: Container, ports: Array) -> Container {
|
|
for port in ports.iter() {
|
|
if port.is_string() {
|
|
let port_str = port.clone().cast::<String>();
|
|
container = container.with_port(&port_str);
|
|
}
|
|
}
|
|
container
|
|
}
|
|
|
|
/// Add multiple volume mounts to a Container
|
|
pub fn container_with_volumes(mut container: Container, volumes: Array) -> Container {
|
|
for volume in volumes.iter() {
|
|
if volume.is_string() {
|
|
let volume_str = volume.clone().cast::<String>();
|
|
container = container.with_volume(&volume_str);
|
|
}
|
|
}
|
|
container
|
|
}
|
|
|
|
/// Add multiple environment variables to a Container
|
|
pub fn container_with_envs(mut container: Container, env_map: Map) -> Container {
|
|
for (key, value) in env_map.iter() {
|
|
if value.is_string() {
|
|
let value_str = value.clone().cast::<String>();
|
|
container = container.with_env(&key, &value_str);
|
|
}
|
|
}
|
|
container
|
|
}
|
|
|
|
/// Add multiple network aliases to a Container
|
|
pub fn container_with_network_aliases(mut container: Container, aliases: Array) -> Container {
|
|
for alias in aliases.iter() {
|
|
if alias.is_string() {
|
|
let alias_str = alias.clone().cast::<String>();
|
|
container = container.with_network_alias(&alias_str);
|
|
}
|
|
}
|
|
container
|
|
}
|
|
|
|
/// Set memory swap limit for a Container
|
|
pub fn container_with_memory_swap_limit(container: Container, memory_swap: &str) -> Container {
|
|
container.with_memory_swap_limit(memory_swap)
|
|
}
|
|
|
|
/// Set CPU shares for a Container
|
|
pub fn container_with_cpu_shares(container: Container, shares: &str) -> Container {
|
|
container.with_cpu_shares(shares)
|
|
}
|
|
|
|
/// Set health check with options for a Container
|
|
pub fn container_with_health_check_options(
|
|
container: Container,
|
|
cmd: &str,
|
|
interval: Option<&str>,
|
|
timeout: Option<&str>,
|
|
retries: Option<i64>,
|
|
start_period: Option<&str>,
|
|
) -> Container {
|
|
// Convert i64 to u32 for retries
|
|
let retries_u32 = retries.map(|r| r as u32);
|
|
container.with_health_check_options(cmd, interval, timeout, retries_u32, start_period)
|
|
}
|
|
|
|
/// Set snapshotter for a Container
|
|
pub fn container_with_snapshotter(container: Container, snapshotter: &str) -> Container {
|
|
container.with_snapshotter(snapshotter)
|
|
}
|
|
|
|
/// Set detach mode for a Container
|
|
pub fn container_with_detach(container: Container, detach: bool) -> Container {
|
|
container.with_detach(detach)
|
|
}
|
|
|
|
/// Build and run the Container
|
|
///
|
|
/// This function builds and runs the container using the configured options.
|
|
/// It provides detailed error information if the build fails.
|
|
pub fn container_build(container: Container) -> Result<Container, Box<EvalAltResult>> {
|
|
// Get container details for better error reporting
|
|
let container_name = container.name.clone();
|
|
let image = container
|
|
.image
|
|
.clone()
|
|
.unwrap_or_else(|| "none".to_string());
|
|
let ports = container.ports.clone();
|
|
let volumes = container.volumes.clone();
|
|
let env_vars = container.env_vars.clone();
|
|
|
|
// Try to build the container
|
|
let build_result = container.build();
|
|
|
|
// Handle the result with improved error context
|
|
match build_result {
|
|
Ok(built_container) => {
|
|
// Container built successfully
|
|
Ok(built_container)
|
|
}
|
|
Err(err) => {
|
|
// Add more context to the error
|
|
let enhanced_error = match err {
|
|
NerdctlError::CommandFailed(msg) => {
|
|
// Provide more detailed error information
|
|
let mut enhanced_msg = format!(
|
|
"Failed to build container '{}' from image '{}': {}",
|
|
container_name, image, msg
|
|
);
|
|
|
|
// Add information about configured options that might be relevant
|
|
if !ports.is_empty() {
|
|
enhanced_msg.push_str(&format!("\nConfigured ports: {:?}", ports));
|
|
}
|
|
|
|
if !volumes.is_empty() {
|
|
enhanced_msg.push_str(&format!("\nConfigured volumes: {:?}", volumes));
|
|
}
|
|
|
|
if !env_vars.is_empty() {
|
|
enhanced_msg.push_str(&format!(
|
|
"\nConfigured environment variables: {:?}",
|
|
env_vars
|
|
));
|
|
}
|
|
|
|
// Add suggestions for common issues
|
|
if msg.contains("not found") || msg.contains("no such image") {
|
|
enhanced_msg.push_str("\nSuggestion: The specified image may not exist or may not be pulled yet. Try pulling the image first with nerdctl_image_pull().");
|
|
} else if msg.contains("port is already allocated") {
|
|
enhanced_msg.push_str("\nSuggestion: One of the specified ports is already in use. Try using a different port or stopping the container using that port.");
|
|
} else if msg.contains("permission denied") {
|
|
enhanced_msg.push_str("\nSuggestion: Permission issues detected. Check if you have the necessary permissions to create containers or access the specified volumes.");
|
|
}
|
|
|
|
NerdctlError::CommandFailed(enhanced_msg)
|
|
}
|
|
_ => err,
|
|
};
|
|
|
|
nerdctl_error_to_rhai_error(Err(enhanced_error))
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Start the Container and verify it's running
|
|
///
|
|
/// This function starts the container and verifies that it's actually running.
|
|
/// It returns detailed error information if the container fails to start or
|
|
/// if it starts but stops immediately.
|
|
pub fn container_start(container: &mut Container) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
// Get container details for better error reporting
|
|
let container_name = container.name.clone();
|
|
let container_id = container
|
|
.container_id
|
|
.clone()
|
|
.unwrap_or_else(|| "unknown".to_string());
|
|
|
|
// Try to start the container
|
|
let start_result = container.start();
|
|
|
|
// Handle the result with improved error context
|
|
match start_result {
|
|
Ok(result) => {
|
|
// Container started successfully
|
|
Ok(result)
|
|
}
|
|
Err(err) => {
|
|
// Add more context to the error
|
|
let enhanced_error = match err {
|
|
NerdctlError::CommandFailed(msg) => {
|
|
// Check if this is a "container already running" error, which is not really an error
|
|
if msg.contains("already running") {
|
|
return Ok(CommandResult {
|
|
stdout: format!("Container {} is already running", container_name),
|
|
stderr: "".to_string(),
|
|
success: true,
|
|
code: 0,
|
|
});
|
|
}
|
|
|
|
// Try to get more information about why the container might have failed to start
|
|
let mut enhanced_msg = format!(
|
|
"Failed to start container '{}' (ID: {}): {}",
|
|
container_name, container_id, msg
|
|
);
|
|
|
|
// Try to check if the image exists
|
|
if let Some(image) = &container.image {
|
|
enhanced_msg.push_str(&format!("\nContainer was using image: {}", image));
|
|
}
|
|
|
|
NerdctlError::CommandFailed(enhanced_msg)
|
|
}
|
|
_ => err,
|
|
};
|
|
|
|
nerdctl_error_to_rhai_error(Err(enhanced_error))
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Stop the Container
|
|
pub fn container_stop(container: &mut Container) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(container.stop())
|
|
}
|
|
|
|
/// Remove the Container
|
|
pub fn container_remove(container: &mut Container) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(container.remove())
|
|
}
|
|
|
|
/// Execute a command in the Container
|
|
pub fn container_exec(
|
|
container: &mut Container,
|
|
command: &str,
|
|
) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(container.exec(command))
|
|
}
|
|
|
|
/// Get container logs
|
|
pub fn container_logs(container: &mut Container) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
// Get container details for better error reporting
|
|
let container_name = container.name.clone();
|
|
let container_id = container
|
|
.container_id
|
|
.clone()
|
|
.unwrap_or_else(|| "unknown".to_string());
|
|
|
|
// Use the nerdctl::logs function
|
|
let logs_result = nerdctl::logs(&container_id);
|
|
|
|
match logs_result {
|
|
Ok(result) => Ok(result),
|
|
Err(err) => {
|
|
// Add more context to the error
|
|
let enhanced_error = NerdctlError::CommandFailed(format!(
|
|
"Failed to get logs for container '{}' (ID: {}): {}",
|
|
container_name, container_id, err
|
|
));
|
|
|
|
nerdctl_error_to_rhai_error(Err(enhanced_error))
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Copy files between the Container and local filesystem
|
|
pub fn container_copy(
|
|
container: &mut Container,
|
|
source: &str,
|
|
dest: &str,
|
|
) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(container.copy(source, dest))
|
|
}
|
|
|
|
/// Create a new Map with default run options
|
|
pub fn new_run_options() -> Map {
|
|
let mut map = Map::new();
|
|
map.insert("name".into(), Dynamic::UNIT);
|
|
map.insert("detach".into(), Dynamic::from(true));
|
|
map.insert("ports".into(), Dynamic::from(Array::new()));
|
|
map.insert("snapshotter".into(), Dynamic::from("native"));
|
|
map
|
|
}
|
|
|
|
//
|
|
// Container Function Wrappers
|
|
//
|
|
|
|
/// Wrapper for nerdctl::run
|
|
///
|
|
/// Run a container from an image.
|
|
pub fn nerdctl_run(image: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::run(image, None, true, None, None))
|
|
}
|
|
|
|
/// Run a container with a name
|
|
pub fn nerdctl_run_with_name(image: &str, name: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::run(image, Some(name), true, None, None))
|
|
}
|
|
|
|
/// Run a container with a port mapping
|
|
pub fn nerdctl_run_with_port(
|
|
image: &str,
|
|
name: &str,
|
|
port: &str,
|
|
) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
let ports = vec![port];
|
|
nerdctl_error_to_rhai_error(nerdctl::run(image, Some(name), true, Some(&ports), None))
|
|
}
|
|
|
|
/// Wrapper for nerdctl::exec
|
|
///
|
|
/// Execute a command in a container.
|
|
pub fn nerdctl_exec(container: &str, command: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::exec(container, command))
|
|
}
|
|
|
|
/// Wrapper for nerdctl::copy
|
|
///
|
|
/// Copy files between container and local filesystem.
|
|
pub fn nerdctl_copy(source: &str, dest: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::copy(source, dest))
|
|
}
|
|
|
|
/// Wrapper for nerdctl::stop
|
|
///
|
|
/// Stop a container.
|
|
pub fn nerdctl_stop(container: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::stop(container))
|
|
}
|
|
|
|
/// Wrapper for nerdctl::remove
|
|
///
|
|
/// Remove a container.
|
|
pub fn nerdctl_remove(container: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::remove(container))
|
|
}
|
|
|
|
/// Wrapper for nerdctl::list
|
|
///
|
|
/// List containers.
|
|
pub fn nerdctl_list(all: bool) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::list(all))
|
|
}
|
|
|
|
/// Wrapper for nerdctl::logs
|
|
///
|
|
/// Get container logs.
|
|
pub fn nerdctl_logs(container: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::logs(container))
|
|
}
|
|
|
|
//
|
|
// Image Function Wrappers
|
|
//
|
|
|
|
/// Wrapper for nerdctl::images
|
|
///
|
|
/// List images in local storage.
|
|
pub fn nerdctl_images() -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::images())
|
|
}
|
|
|
|
/// Wrapper for nerdctl::image_remove
|
|
///
|
|
/// Remove one or more images.
|
|
pub fn nerdctl_image_remove(image: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::image_remove(image))
|
|
}
|
|
|
|
/// Wrapper for nerdctl::image_push
|
|
///
|
|
/// Push an image to a registry.
|
|
pub fn nerdctl_image_push(
|
|
image: &str,
|
|
destination: &str,
|
|
) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::image_push(image, destination))
|
|
}
|
|
|
|
/// Wrapper for nerdctl::image_tag
|
|
///
|
|
/// Add an additional name to a local image.
|
|
pub fn nerdctl_image_tag(image: &str, new_name: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::image_tag(image, new_name))
|
|
}
|
|
|
|
/// Wrapper for nerdctl::image_pull
|
|
///
|
|
/// Pull an image from a registry.
|
|
pub fn nerdctl_image_pull(image: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::image_pull(image))
|
|
}
|
|
|
|
/// Wrapper for nerdctl::image_commit
|
|
///
|
|
/// Commit a container to an image.
|
|
pub fn nerdctl_image_commit(
|
|
container: &str,
|
|
image_name: &str,
|
|
) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::image_commit(container, image_name))
|
|
}
|
|
|
|
/// Wrapper for nerdctl::image_build
|
|
///
|
|
/// Build an image using a Dockerfile.
|
|
pub fn nerdctl_image_build(
|
|
tag: &str,
|
|
context_path: &str,
|
|
) -> Result<CommandResult, Box<EvalAltResult>> {
|
|
nerdctl_error_to_rhai_error(nerdctl::image_build(tag, context_path))
|
|
}
|
|
|
|
/// Register Nerdctl module functions with the Rhai engine
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `engine` - The Rhai engine to register the functions with
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// * `Result<(), Box<EvalAltResult>>` - Ok if registration was successful, Err otherwise
|
|
pub fn register_nerdctl_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
|
|
// Register types
|
|
register_nerdctl_types(engine)?;
|
|
|
|
// Register Container constructor
|
|
engine.register_fn("nerdctl_container_new", container_new);
|
|
engine.register_fn("nerdctl_container_from_image", container_from_image);
|
|
|
|
// Register Container instance methods
|
|
engine.register_fn("reset", container_reset);
|
|
engine.register_fn("with_port", container_with_port);
|
|
engine.register_fn("with_volume", container_with_volume);
|
|
engine.register_fn("with_env", container_with_env);
|
|
engine.register_fn("with_network", container_with_network);
|
|
engine.register_fn("with_network_alias", container_with_network_alias);
|
|
engine.register_fn("with_cpu_limit", container_with_cpu_limit);
|
|
engine.register_fn("with_memory_limit", container_with_memory_limit);
|
|
engine.register_fn("with_restart_policy", container_with_restart_policy);
|
|
engine.register_fn("with_health_check", container_with_health_check);
|
|
engine.register_fn("with_ports", container_with_ports);
|
|
engine.register_fn("with_volumes", container_with_volumes);
|
|
engine.register_fn("with_envs", container_with_envs);
|
|
engine.register_fn("with_network_aliases", container_with_network_aliases);
|
|
engine.register_fn("with_memory_swap_limit", container_with_memory_swap_limit);
|
|
engine.register_fn("with_cpu_shares", container_with_cpu_shares);
|
|
engine.register_fn(
|
|
"with_health_check_options",
|
|
container_with_health_check_options,
|
|
);
|
|
engine.register_fn("with_snapshotter", container_with_snapshotter);
|
|
engine.register_fn("with_detach", container_with_detach);
|
|
engine.register_fn("build", container_build);
|
|
engine.register_fn("start", container_start);
|
|
engine.register_fn("stop", container_stop);
|
|
engine.register_fn("remove", container_remove);
|
|
engine.register_fn("exec", container_exec);
|
|
engine.register_fn("logs", container_logs);
|
|
engine.register_fn("copy", container_copy);
|
|
|
|
// Register legacy container functions (for backward compatibility)
|
|
engine.register_fn("nerdctl_run", nerdctl_run);
|
|
engine.register_fn("nerdctl_run_with_name", nerdctl_run_with_name);
|
|
engine.register_fn("nerdctl_run_with_port", nerdctl_run_with_port);
|
|
engine.register_fn("new_run_options", new_run_options);
|
|
engine.register_fn("nerdctl_exec", nerdctl_exec);
|
|
engine.register_fn("nerdctl_copy", nerdctl_copy);
|
|
engine.register_fn("nerdctl_stop", nerdctl_stop);
|
|
engine.register_fn("nerdctl_remove", nerdctl_remove);
|
|
engine.register_fn("nerdctl_list", nerdctl_list);
|
|
engine.register_fn("nerdctl_logs", nerdctl_logs);
|
|
|
|
// Register image functions
|
|
engine.register_fn("nerdctl_images", nerdctl_images);
|
|
engine.register_fn("nerdctl_image_remove", nerdctl_image_remove);
|
|
engine.register_fn("nerdctl_image_push", nerdctl_image_push);
|
|
engine.register_fn("nerdctl_image_tag", nerdctl_image_tag);
|
|
engine.register_fn("nerdctl_image_pull", nerdctl_image_pull);
|
|
engine.register_fn("nerdctl_image_commit", nerdctl_image_commit);
|
|
engine.register_fn("nerdctl_image_build", nerdctl_image_build);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Register Nerdctl module types with the Rhai engine
|
|
fn register_nerdctl_types(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
|
|
// Register Container type
|
|
engine.register_type_with_name::<Container>("NerdctlContainer");
|
|
|
|
// Register getters for Container properties
|
|
engine.register_get("name", |container: &mut Container| container.name.clone());
|
|
engine.register_get(
|
|
"container_id",
|
|
|container: &mut Container| match &container.container_id {
|
|
Some(id) => id.clone(),
|
|
None => "".to_string(),
|
|
},
|
|
);
|
|
engine.register_get("image", |container: &mut Container| {
|
|
match &container.image {
|
|
Some(img) => img.clone(),
|
|
None => "".to_string(),
|
|
}
|
|
});
|
|
engine.register_get("ports", |container: &mut Container| {
|
|
let mut array = Array::new();
|
|
for port in &container.ports {
|
|
array.push(Dynamic::from(port.clone()));
|
|
}
|
|
array
|
|
});
|
|
engine.register_get("volumes", |container: &mut Container| {
|
|
let mut array = Array::new();
|
|
for volume in &container.volumes {
|
|
array.push(Dynamic::from(volume.clone()));
|
|
}
|
|
array
|
|
});
|
|
engine.register_get("detach", |container: &mut Container| container.detach);
|
|
|
|
// Register Image type and methods
|
|
engine.register_type_with_name::<Image>("NerdctlImage");
|
|
|
|
// Register getters for Image properties
|
|
engine.register_get("id", |img: &mut Image| img.id.clone());
|
|
engine.register_get("repository", |img: &mut Image| img.repository.clone());
|
|
engine.register_get("tag", |img: &mut Image| img.tag.clone());
|
|
engine.register_get("size", |img: &mut Image| img.size.clone());
|
|
engine.register_get("created", |img: &mut Image| img.created.clone());
|
|
|
|
Ok(())
|
|
}
|