...
This commit is contained in:
parent
3803a54529
commit
d336153247
@ -23,17 +23,16 @@ When you get information about a running process, you can see:
|
|||||||
- `cpu`: How much CPU the process is using
|
- `cpu`: How much CPU the process is using
|
||||||
|
|
||||||
## Run Functions
|
## Run Functions
|
||||||
|
|
||||||
### `run(command)`
|
### `run(command)`
|
||||||
|
|
||||||
Runs a command or multiline script with arguments.
|
Runs a command or multiline script with arguments.
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
- `command` (string): The command to run
|
- `command` (string): The command to run (can be a single command or a multiline script)
|
||||||
|
|
||||||
**Returns:** The result of the command, including output and whether it succeeded.
|
**Returns:** The result of the command, including output and whether it succeeded.
|
||||||
|
|
||||||
**Example:**
|
**Example 1: Running a simple command**
|
||||||
```rhai
|
```rhai
|
||||||
// Run a simple command
|
// Run a simple command
|
||||||
let result = run("ls -la");
|
let result = run("ls -la");
|
||||||
@ -46,6 +45,28 @@ if result.success {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Example 2: Running a multiline script**
|
||||||
|
```rhai
|
||||||
|
// Create a multiline script using backtick string literals
|
||||||
|
let setup_script = `
|
||||||
|
# Create directories
|
||||||
|
mkdir -p /tmp/test_project
|
||||||
|
cd /tmp/test_project
|
||||||
|
|
||||||
|
# Initialize git repository
|
||||||
|
git init
|
||||||
|
echo 'Initial content' > README.md
|
||||||
|
git add README.md
|
||||||
|
git config --local user.email 'test@example.com'
|
||||||
|
git config --local user.name 'Test User'
|
||||||
|
git commit -m 'Initial commit'
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Execute the multiline script
|
||||||
|
let result = run(setup_script);
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### `run_silent(command)`
|
### `run_silent(command)`
|
||||||
@ -110,6 +131,24 @@ options.log = true; // Log the command execution
|
|||||||
let result = run_with_options("npm install", options);
|
let result = run_with_options("npm install", options);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Working with Multiline Scripts
|
||||||
|
|
||||||
|
The Process module allows you to execute multiline scripts, which is particularly useful for complex operations that require multiple commands to be executed in sequence.
|
||||||
|
|
||||||
|
### Creating Multiline Scripts
|
||||||
|
|
||||||
|
Multiline scripts can be created using backtick (`) string literals in Rhai:
|
||||||
|
|
||||||
|
```rhai
|
||||||
|
let my_script = `
|
||||||
|
# This is a multiline bash script
|
||||||
|
echo "Hello, World!"
|
||||||
|
mkdir -p /tmp/my_project
|
||||||
|
cd /tmp/my_project
|
||||||
|
touch example.txt
|
||||||
|
`;
|
||||||
|
```
|
||||||
|
|
||||||
## Process Management Functions
|
## Process Management Functions
|
||||||
|
|
||||||
### `which(cmd)`
|
### `which(cmd)`
|
||||||
|
@ -185,7 +185,7 @@ fn handle_child_output(mut child: Child, silent: bool) -> Result<CommandResult,
|
|||||||
if let Ok(l) = line {
|
if let Ok(l) = line {
|
||||||
// Print the line if not silent and flush immediately
|
// Print the line if not silent and flush immediately
|
||||||
if !silent_clone {
|
if !silent_clone {
|
||||||
// Print stderr with error prefix
|
// Print all stderr messages
|
||||||
eprintln!("\x1b[31mERROR: {}\x1b[0m", l); // Red color for errors
|
eprintln!("\x1b[31mERROR: {}\x1b[0m", l); // Red color for errors
|
||||||
std::io::stderr().flush().unwrap_or(());
|
std::io::stderr().flush().unwrap_or(());
|
||||||
}
|
}
|
||||||
@ -288,7 +288,7 @@ fn execute_script_internal(interpreter: &str, script_path: &Path, silent: bool)
|
|||||||
let command_args = vec!["/c", script_path.to_str().unwrap_or("")];
|
let command_args = vec!["/c", script_path.to_str().unwrap_or("")];
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||||
let command_args = vec![script_path.to_str().unwrap_or("")];
|
let command_args = vec!["-e", script_path.to_str().unwrap_or("")];
|
||||||
|
|
||||||
if silent {
|
if silent {
|
||||||
// For silent execution, use output() which captures but doesn't display
|
// For silent execution, use output() which captures but doesn't display
|
||||||
@ -334,16 +334,28 @@ fn execute_script_internal(interpreter: &str, script_path: &Path, silent: bool)
|
|||||||
|
|
||||||
/// Run a multiline script with optional silent mode
|
/// Run a multiline script with optional silent mode
|
||||||
fn run_script_internal(script: &str, silent: bool) -> Result<CommandResult, RunError> {
|
fn run_script_internal(script: &str, silent: bool) -> Result<CommandResult, RunError> {
|
||||||
|
// Prepare the script file first to get the content with shebang
|
||||||
|
let (script_path, interpreter, _temp_dir) = prepare_script_file(script)?;
|
||||||
|
|
||||||
// Print the script being executed if not silent
|
// Print the script being executed if not silent
|
||||||
if !silent {
|
if !silent {
|
||||||
println!("\x1b[36mExecuting script:\x1b[0m");
|
println!("\x1b[36mExecuting script:\x1b[0m");
|
||||||
|
|
||||||
|
// Read the script file to get the content with shebang
|
||||||
|
if let Ok(script_content) = fs::read_to_string(&script_path) {
|
||||||
|
for (i, line) in script_content.lines().enumerate() {
|
||||||
|
println!("\x1b[36m{:3}: {}\x1b[0m", i + 1, line);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Fallback to original script if reading fails
|
||||||
for (i, line) in script.lines().enumerate() {
|
for (i, line) in script.lines().enumerate() {
|
||||||
println!("\x1b[36m{:3}: {}\x1b[0m", i + 1, line);
|
println!("\x1b[36m{:3}: {}\x1b[0m", i + 1, line);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
println!("\x1b[36m---\x1b[0m");
|
println!("\x1b[36m---\x1b[0m");
|
||||||
}
|
}
|
||||||
|
|
||||||
let (script_path, interpreter, _temp_dir) = prepare_script_file(script)?;
|
|
||||||
// _temp_dir is kept in scope until the end of this function to ensure
|
// _temp_dir is kept in scope until the end of this function to ensure
|
||||||
// it's not dropped prematurely, which would clean up the directory
|
// it's not dropped prematurely, which would clean up the directory
|
||||||
|
|
||||||
|
@ -3,60 +3,10 @@
|
|||||||
//! This module provides Rhai wrappers for the functions in the Nerdctl module.
|
//! This module provides Rhai wrappers for the functions in the Nerdctl module.
|
||||||
|
|
||||||
use rhai::{Engine, EvalAltResult, Array, Dynamic, Map};
|
use rhai::{Engine, EvalAltResult, Array, Dynamic, Map};
|
||||||
use crate::virt::nerdctl::{self, NerdctlError, Image};
|
use std::collections::HashMap;
|
||||||
|
use crate::virt::nerdctl::{self, NerdctlError, Image, Container};
|
||||||
use crate::process::CommandResult;
|
use crate::process::CommandResult;
|
||||||
|
|
||||||
/// 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 functions
|
|
||||||
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);
|
|
||||||
|
|
||||||
// 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 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(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper functions for error conversion
|
// Helper functions for error conversion
|
||||||
fn nerdctl_error_to_rhai_error<T>(result: Result<T, NerdctlError>) -> Result<T, Box<EvalAltResult>> {
|
fn nerdctl_error_to_rhai_error<T>(result: Result<T, NerdctlError>) -> Result<T, Box<EvalAltResult>> {
|
||||||
result.map_err(|e| {
|
result.map_err(|e| {
|
||||||
@ -67,6 +17,100 @@ fn nerdctl_error_to_rhai_error<T>(result: Result<T, NerdctlError>) -> Result<T,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a port mapping to a Container
|
||||||
|
pub fn container_with_port(mut container: Container, port: &str) -> Container {
|
||||||
|
container.with_port(port)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a volume mount to a Container
|
||||||
|
pub fn container_with_volume(mut container: Container, volume: &str) -> Container {
|
||||||
|
container.with_volume(volume)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add an environment variable to a Container
|
||||||
|
pub fn container_with_env(mut container: Container, key: &str, value: &str) -> Container {
|
||||||
|
container.with_env(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the network for a Container
|
||||||
|
pub fn container_with_network(mut container: Container, network: &str) -> Container {
|
||||||
|
container.with_network(network)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a network alias to a Container
|
||||||
|
pub fn container_with_network_alias(mut container: Container, alias: &str) -> Container {
|
||||||
|
container.with_network_alias(alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set CPU limit for a Container
|
||||||
|
pub fn container_with_cpu_limit(mut container: Container, cpus: &str) -> Container {
|
||||||
|
container.with_cpu_limit(cpus)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set memory limit for a Container
|
||||||
|
pub fn container_with_memory_limit(mut container: Container, memory: &str) -> Container {
|
||||||
|
container.with_memory_limit(memory)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set restart policy for a Container
|
||||||
|
pub fn container_with_restart_policy(mut container: Container, policy: &str) -> Container {
|
||||||
|
container.with_restart_policy(policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set health check for a Container
|
||||||
|
pub fn container_with_health_check(mut container: Container, cmd: &str) -> Container {
|
||||||
|
container.with_health_check(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set detach mode for a Container
|
||||||
|
pub fn container_with_detach(mut container: Container, detach: bool) -> Container {
|
||||||
|
container.with_detach(detach)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build and run the Container
|
||||||
|
pub fn container_build(container: Container) -> Result<Container, Box<EvalAltResult>> {
|
||||||
|
nerdctl_error_to_rhai_error(container.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start the Container
|
||||||
|
pub fn container_start(container: &mut Container) -> Result<CommandResult, Box<EvalAltResult>> {
|
||||||
|
nerdctl_error_to_rhai_error(container.start())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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
|
/// Create a new Map with default run options
|
||||||
pub fn new_run_options() -> Map {
|
pub fn new_run_options() -> Map {
|
||||||
let mut map = Map::new();
|
let mut map = Map::new();
|
||||||
@ -186,3 +230,109 @@ pub fn nerdctl_image_commit(container: &str, image_name: &str) -> Result<Command
|
|||||||
pub fn nerdctl_image_build(tag: &str, context_path: &str) -> Result<CommandResult, Box<EvalAltResult>> {
|
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))
|
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("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_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("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);
|
||||||
|
|
||||||
|
// 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(())
|
||||||
|
}
|
@ -29,6 +29,7 @@ println(`- snapshotter: ${run_options.snapshotter}`);
|
|||||||
// Test function availability
|
// Test function availability
|
||||||
println("\nTesting function availability:");
|
println("\nTesting function availability:");
|
||||||
let functions = [
|
let functions = [
|
||||||
|
// Legacy functions
|
||||||
"nerdctl_run",
|
"nerdctl_run",
|
||||||
"nerdctl_run_with_name",
|
"nerdctl_run_with_name",
|
||||||
"nerdctl_run_with_port",
|
"nerdctl_run_with_port",
|
||||||
@ -43,7 +44,27 @@ let functions = [
|
|||||||
"nerdctl_image_tag",
|
"nerdctl_image_tag",
|
||||||
"nerdctl_image_pull",
|
"nerdctl_image_pull",
|
||||||
"nerdctl_image_commit",
|
"nerdctl_image_commit",
|
||||||
"nerdctl_image_build"
|
"nerdctl_image_build",
|
||||||
|
|
||||||
|
// Builder pattern functions
|
||||||
|
"nerdctl_container_new",
|
||||||
|
"nerdctl_container_from_image",
|
||||||
|
"with_port",
|
||||||
|
"with_volume",
|
||||||
|
"with_env",
|
||||||
|
"with_network",
|
||||||
|
"with_network_alias",
|
||||||
|
"with_cpu_limit",
|
||||||
|
"with_memory_limit",
|
||||||
|
"with_restart_policy",
|
||||||
|
"with_health_check",
|
||||||
|
"with_detach",
|
||||||
|
"build",
|
||||||
|
"start",
|
||||||
|
"stop",
|
||||||
|
"remove",
|
||||||
|
"exec",
|
||||||
|
"copy"
|
||||||
];
|
];
|
||||||
|
|
||||||
// Try to access each function (this will throw an error if the function doesn't exist)
|
// Try to access each function (this will throw an error if the function doesn't exist)
|
||||||
@ -52,6 +73,107 @@ for func in functions {
|
|||||||
println(`Function ${func} registered: ${exists}`);
|
println(`Function ${func} registered: ${exists}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to get current timestamp in seconds
|
||||||
|
fn timestamp() {
|
||||||
|
// Use the current time in seconds since epoch as a unique identifier
|
||||||
|
return now();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test the builder pattern with actual container creation and execution
|
||||||
|
println("\nTesting container builder pattern with actual container:");
|
||||||
|
try {
|
||||||
|
// Generate a unique container name based on timestamp
|
||||||
|
let container_name = "test-alpine-container";
|
||||||
|
|
||||||
|
// First, try to remove any existing container with this name
|
||||||
|
println(`Cleaning up any existing container named '${container_name}'...`);
|
||||||
|
try {
|
||||||
|
// Try to stop the container first (in case it's running)
|
||||||
|
nerdctl_stop(container_name);
|
||||||
|
println("Stopped existing container");
|
||||||
|
} catch(e) {
|
||||||
|
println("No running container to stop");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Try to remove the container
|
||||||
|
nerdctl_remove(container_name);
|
||||||
|
println("Removed existing container");
|
||||||
|
} catch(e) {
|
||||||
|
println("No container to remove");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a container with builder pattern using Alpine image with a command that keeps it running
|
||||||
|
println("\nCreating new container from Alpine image...");
|
||||||
|
let container = nerdctl_container_from_image(container_name, "alpine:latest");
|
||||||
|
println(`Created container from image: ${container.name} (${container.image})`);
|
||||||
|
|
||||||
|
// Configure the container
|
||||||
|
container = container
|
||||||
|
.with_port("8080:80")
|
||||||
|
.with_volume("/tmp:/data")
|
||||||
|
.with_env("TEST_ENV", "test_value")
|
||||||
|
.with_detach(true);
|
||||||
|
|
||||||
|
// Print container properties before building
|
||||||
|
println("Container properties before building:");
|
||||||
|
println(`- name: ${container.name}`);
|
||||||
|
println(`- image: ${container.image}`);
|
||||||
|
println(`- ports: ${container.ports}`);
|
||||||
|
println(`- volumes: ${container.volumes}`);
|
||||||
|
println(`- detach: ${container.detach}`);
|
||||||
|
|
||||||
|
// Build the container
|
||||||
|
println("\nBuilding the container...");
|
||||||
|
container = container.build();
|
||||||
|
|
||||||
|
// Print container ID after building
|
||||||
|
println(`Container built successfully with ID: ${container.container_id}`);
|
||||||
|
|
||||||
|
// Start the container
|
||||||
|
println("\nStarting the container...");
|
||||||
|
let start_result = container.start();
|
||||||
|
println(`Start result: ${start_result.success}`);
|
||||||
|
|
||||||
|
// Execute a command in the running container
|
||||||
|
println("\nExecuting command in the container...");
|
||||||
|
let run_cmd = container.exec("echo 'Hello from Alpine container'");
|
||||||
|
println(`Command output: ${run_cmd.stdout}`);
|
||||||
|
|
||||||
|
// List all containers to verify it's running
|
||||||
|
println("\nListing all containers:");
|
||||||
|
let list_result = nerdctl_list(true);
|
||||||
|
println(`Container list: ${list_result.stdout}`);
|
||||||
|
|
||||||
|
// Stop and remove the container
|
||||||
|
println("\nStopping and removing the container...");
|
||||||
|
let stop_result = container.stop();
|
||||||
|
println(`Stop result: ${stop_result.success}`);
|
||||||
|
|
||||||
|
let remove_result = container.remove();
|
||||||
|
println(`Remove result: ${remove_result.success}`);
|
||||||
|
println("Container stopped and removed successfully");
|
||||||
|
|
||||||
|
// Return success message only if everything worked
|
||||||
|
return "Container builder pattern test completed successfully!";
|
||||||
|
} catch(e) {
|
||||||
|
// Print the error and return a failure message
|
||||||
|
println(`ERROR: ${e}`);
|
||||||
|
|
||||||
|
// Try to clean up if possible
|
||||||
|
try {
|
||||||
|
println("Attempting to clean up after error...");
|
||||||
|
nerdctl_stop("test-alpine-container");
|
||||||
|
nerdctl_remove("test-alpine-container");
|
||||||
|
println("Cleanup completed");
|
||||||
|
} catch(cleanup_error) {
|
||||||
|
println(`Cleanup failed: ${cleanup_error}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return failure message
|
||||||
|
return "Container builder pattern test FAILED!";
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function to check if a function is registered
|
// Helper function to check if a function is registered
|
||||||
fn is_function_registered(name) {
|
fn is_function_registered(name) {
|
||||||
try {
|
try {
|
||||||
@ -63,4 +185,4 @@ fn is_function_registered(name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"Nerdctl wrapper test completed successfully!"
|
// The final result depends on the outcome of the container test
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
// Create a bash script to set up the test environment
|
// Create a bash script to set up the test environment
|
||||||
let setup_script = `
|
let setup_script = `
|
||||||
|
# Configure git to suppress the default branch name warning
|
||||||
|
git config --global advice.initDefaultBranch false
|
||||||
|
|
||||||
rm -rf /tmp/code
|
rm -rf /tmp/code
|
||||||
mkdir -p /tmp/code
|
mkdir -p /tmp/code
|
||||||
cd /tmp/code
|
cd /tmp/code
|
||||||
@ -17,7 +20,7 @@ git config --local user.email 'test@example.com'
|
|||||||
git config --local user.name 'Test User'
|
git config --local user.name 'Test User'
|
||||||
git commit -m 'Initial commit'
|
git commit -m 'Initial commit'
|
||||||
|
|
||||||
cd myserver.com/myaccount/repored
|
cd /tmp/code/myserver.com/myaccount/repored
|
||||||
git init
|
git init
|
||||||
echo 'Initial test file' > test2.txt
|
echo 'Initial test file' > test2.txt
|
||||||
git add test2.txt
|
git add test2.txt
|
||||||
@ -25,7 +28,7 @@ git config --local user.email 'test@example.com'
|
|||||||
git config --local user.name 'Test User'
|
git config --local user.name 'Test User'
|
||||||
git commit -m 'Initial commit'
|
git commit -m 'Initial commit'
|
||||||
|
|
||||||
//now we have 2 repos
|
# now we have 2 repos
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user