Compare commits
	
		
			3 Commits
		
	
	
		
			network_se
			...
			developmen
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					0e63efda61 | ||
| 
						 | 
					568a5b0a49 | ||
| 
						 | 
					d431705501 | 
@@ -21,12 +21,8 @@ fn assert_eq(actual, expected, message) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Helper function to check if buildah is available
 | 
					// Helper function to check if buildah is available
 | 
				
			||||||
fn is_buildah_available() {
 | 
					fn is_buildah_available() {
 | 
				
			||||||
    try {
 | 
					    let command = run("which buildah");
 | 
				
			||||||
        let result = run("which buildah");
 | 
					    return command.silent().execute().success;
 | 
				
			||||||
        return result.success;
 | 
					 | 
				
			||||||
    } catch(err) {
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print("=== Testing Buildah Builder Pattern ===");
 | 
					print("=== Testing Buildah Builder Pattern ===");
 | 
				
			||||||
@@ -35,8 +31,7 @@ print("=== Testing Buildah Builder Pattern ===");
 | 
				
			|||||||
let buildah_available = is_buildah_available();
 | 
					let buildah_available = is_buildah_available();
 | 
				
			||||||
if !buildah_available {
 | 
					if !buildah_available {
 | 
				
			||||||
    print("Buildah is not available. Skipping Buildah tests.");
 | 
					    print("Buildah is not available. Skipping Buildah tests.");
 | 
				
			||||||
    // Exit gracefully without error
 | 
					    throw err;
 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print("✓ Buildah is available");
 | 
					print("✓ Buildah is available");
 | 
				
			||||||
@@ -121,7 +116,7 @@ try {
 | 
				
			|||||||
    // Test committing to an image
 | 
					    // Test committing to an image
 | 
				
			||||||
    print("Testing commit()...");
 | 
					    print("Testing commit()...");
 | 
				
			||||||
    let image_name = "rhai_test_image:latest";
 | 
					    let image_name = "rhai_test_image:latest";
 | 
				
			||||||
    builder.commit(image_name);
 | 
					    builder.commit(image_name, []);
 | 
				
			||||||
    print("✓ commit(): Container committed to image successfully");
 | 
					    print("✓ commit(): Container committed to image successfully");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Test removing the container
 | 
					    // Test removing the container
 | 
				
			||||||
@@ -154,19 +149,21 @@ try {
 | 
				
			|||||||
    // Clean up in case of error
 | 
					    // Clean up in case of error
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
        // Remove test container if it exists
 | 
					        // Remove test container if it exists
 | 
				
			||||||
        run("buildah rm rhai_test_container");
 | 
					        let command = run("buildah rm rhai_test_container");
 | 
				
			||||||
    } catch(_) {}
 | 
					        command.execute();
 | 
				
			||||||
 | 
					    } catch(err) {}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
        // Remove test image if it exists
 | 
					        // Remove test image if it exists
 | 
				
			||||||
        run("buildah rmi rhai_test_image:latest");
 | 
					        let command = run("buildah rmi alpine");
 | 
				
			||||||
    } catch(_) {}
 | 
					        command.execute();
 | 
				
			||||||
 | 
					    } catch(err) {}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
        // Remove test files if they exist
 | 
					        // Remove test files if they exist
 | 
				
			||||||
        delete("test_add_file.txt");
 | 
					        delete("test_add_file.txt");
 | 
				
			||||||
        delete("test_copy_file.txt");
 | 
					        delete("test_copy_file.txt");
 | 
				
			||||||
    } catch(_) {}
 | 
					    } catch(err) {}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    throw err;
 | 
					    throw err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,19 +21,25 @@ fn assert_eq(actual, expected, message) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Helper function to check if buildah is available
 | 
					// Helper function to check if buildah is available
 | 
				
			||||||
fn is_buildah_available() {
 | 
					fn is_buildah_available() {
 | 
				
			||||||
    try {
 | 
					    let command = run("which buildah");
 | 
				
			||||||
        let result = run("which buildah");
 | 
					    return command.silent().execute().success;
 | 
				
			||||||
        return result.success;
 | 
					 | 
				
			||||||
    } catch(err) {
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Helper function to check if an image exists
 | 
					// Helper function to check if an image exists
 | 
				
			||||||
fn image_exists(image_name) {
 | 
					fn image_exists(image_name) {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
        let result = run(`buildah images -q ${image_name}`);
 | 
					        // First, check for the exact image name
 | 
				
			||||||
        return result.success && result.stdout.trim() != "";
 | 
					        let command = run(`buildah images -q ${image_name}`);
 | 
				
			||||||
 | 
					        let result = command.execute();
 | 
				
			||||||
 | 
					        if result.success && result.stdout.trim() != "" {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // If not found, check for the localhost-prefixed version
 | 
				
			||||||
 | 
					        let prefixed_image_name = `localhost/${image_name}`;
 | 
				
			||||||
 | 
					        let command = run(`buildah images -q ${prefixed_image_name}`);
 | 
				
			||||||
 | 
					        let result_prefixed = command.execute();
 | 
				
			||||||
 | 
					        return result_prefixed.success && result_prefixed.stdout.trim() != "";
 | 
				
			||||||
    } catch(err) {
 | 
					    } catch(err) {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -45,8 +51,7 @@ print("=== Testing Buildah Image Operations ===");
 | 
				
			|||||||
let buildah_available = is_buildah_available();
 | 
					let buildah_available = is_buildah_available();
 | 
				
			||||||
if !buildah_available {
 | 
					if !buildah_available {
 | 
				
			||||||
    print("Buildah is not available. Skipping Buildah tests.");
 | 
					    print("Buildah is not available. Skipping Buildah tests.");
 | 
				
			||||||
    // Exit gracefully without error
 | 
					    throw err;
 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print("✓ Buildah is available");
 | 
					print("✓ Buildah is available");
 | 
				
			||||||
@@ -82,8 +87,10 @@ try {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    // Find our tagged image
 | 
					    // Find our tagged image
 | 
				
			||||||
    let found_tag = false;
 | 
					    let found_tag = false;
 | 
				
			||||||
 | 
					    let expected_tag = "rhai_test_tag:latest";
 | 
				
			||||||
    for image in images {
 | 
					    for image in images {
 | 
				
			||||||
        if image.names.contains("rhai_test_tag:latest") {
 | 
					        // The tag might be prefixed with 'localhost/' if no registry is specified.
 | 
				
			||||||
 | 
					        if image.names.contains(expected_tag) || image.names.contains("localhost/" + expected_tag) {
 | 
				
			||||||
            found_tag = true;
 | 
					            found_tag = true;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -95,10 +102,11 @@ try {
 | 
				
			|||||||
    print("Testing build()...");
 | 
					    print("Testing build()...");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Create a simple Dockerfile
 | 
					    // Create a simple Dockerfile
 | 
				
			||||||
    let dockerfile_content = `FROM alpine:latest
 | 
					    let dockerfile_content = `
 | 
				
			||||||
RUN echo "Hello from Dockerfile" > /hello.txt
 | 
					        FROM alpine:latest
 | 
				
			||||||
CMD ["cat", "/hello.txt"]
 | 
					        RUN echo "Hello from Dockerfile" > /hello.txt
 | 
				
			||||||
`;
 | 
					        CMD ["cat", "/hello.txt"]
 | 
				
			||||||
 | 
					    `;
 | 
				
			||||||
    file_write(`${test_dir}/Dockerfile`, dockerfile_content);
 | 
					    file_write(`${test_dir}/Dockerfile`, dockerfile_content);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Build the image
 | 
					    // Build the image
 | 
				
			||||||
@@ -133,18 +141,23 @@ CMD ["cat", "/hello.txt"]
 | 
				
			|||||||
    // Clean up in case of error
 | 
					    // Clean up in case of error
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
        // Remove test container if it exists
 | 
					        // Remove test container if it exists
 | 
				
			||||||
        run("buildah rm rhai_test_container");
 | 
					        let command = run("buildah rm rhai_test_container");
 | 
				
			||||||
    } catch(_) {}
 | 
					        command.execute();
 | 
				
			||||||
 | 
					    } catch(err) {}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
        // Remove test images if they exist
 | 
					        // Remove test images if they exist
 | 
				
			||||||
        run("buildah rmi rhai_test_tag:latest");
 | 
					        let command = run("buildah rmi rhai_test_tag:latest");
 | 
				
			||||||
        run("buildah rmi rhai_test_build:latest");
 | 
					        command.execute();
 | 
				
			||||||
    } catch(_) {}
 | 
					        let command = run("buildah rmi rhai_test_build:latest");
 | 
				
			||||||
 | 
					        command.execute();
 | 
				
			||||||
 | 
					    } catch(err) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    throw err;
 | 
					    try {
 | 
				
			||||||
} finally {
 | 
					        // Remove test directory if it exists
 | 
				
			||||||
    // Clean up test directory
 | 
					 | 
				
			||||||
        delete(test_dir);
 | 
					        delete(test_dir);
 | 
				
			||||||
        print("✓ Cleanup: Test directory removed");
 | 
					        print("✓ Cleanup: Test directory removed");
 | 
				
			||||||
 | 
					    } catch (err) {}
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    throw err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,12 +21,8 @@ fn assert_eq(actual, expected, message) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Helper function to check if buildah is available
 | 
					// Helper function to check if buildah is available
 | 
				
			||||||
fn is_buildah_available() {
 | 
					fn is_buildah_available() {
 | 
				
			||||||
    try {
 | 
					    let command = run("which buildah");
 | 
				
			||||||
        let result = run("which buildah");
 | 
					    return command.silent().execute().success;
 | 
				
			||||||
        return result.success;
 | 
					 | 
				
			||||||
    } catch(err) {
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print("=== Testing Buildah Container Operations ===");
 | 
					print("=== Testing Buildah Container Operations ===");
 | 
				
			||||||
@@ -35,8 +31,7 @@ print("=== Testing Buildah Container Operations ===");
 | 
				
			|||||||
let buildah_available = is_buildah_available();
 | 
					let buildah_available = is_buildah_available();
 | 
				
			||||||
if !buildah_available {
 | 
					if !buildah_available {
 | 
				
			||||||
    print("Buildah is not available. Skipping Buildah tests.");
 | 
					    print("Buildah is not available. Skipping Buildah tests.");
 | 
				
			||||||
    // Exit gracefully without error
 | 
					    throw err;
 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print("✓ Buildah is available");
 | 
					print("✓ Buildah is available");
 | 
				
			||||||
@@ -59,10 +54,12 @@ try {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    // Test config
 | 
					    // Test config
 | 
				
			||||||
    print("Testing config()...");
 | 
					    print("Testing config()...");
 | 
				
			||||||
    let config_options = #{
 | 
					    let config_options = [
 | 
				
			||||||
        "LABEL": "rhai_test=true",
 | 
					        ["label", "rhai_test_true"],
 | 
				
			||||||
        "ENV": "TEST_VAR=test_value"
 | 
					        ["env", "TEST_VAR=test_value"],
 | 
				
			||||||
    };
 | 
					        ["env", "ANOTHER_VAR=another_value"],
 | 
				
			||||||
 | 
					        ["author", "Rhai Test With Spaces"]
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
    builder.config(config_options);
 | 
					    builder.config(config_options);
 | 
				
			||||||
    print("✓ config(): Container configured successfully");
 | 
					    print("✓ config(): Container configured successfully");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@@ -77,9 +74,10 @@ try {
 | 
				
			|||||||
    print("Testing content operations...");
 | 
					    print("Testing content operations...");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Write content to a file
 | 
					    // Write content to a file
 | 
				
			||||||
    let script_content = `#!/bin/sh
 | 
					    let script_content = `
 | 
				
			||||||
echo "Hello from script"
 | 
					        #!/bin/sh
 | 
				
			||||||
`;
 | 
					        echo "Hello from script"
 | 
				
			||||||
 | 
					    `;
 | 
				
			||||||
    builder.write_content(script_content, "/script.sh");
 | 
					    builder.write_content(script_content, "/script.sh");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Make the script executable
 | 
					    // Make the script executable
 | 
				
			||||||
@@ -91,14 +89,10 @@ echo "Hello from script"
 | 
				
			|||||||
    assert_true(script_result.stdout.contains("Hello from script"), "Script output should contain expected text");
 | 
					    assert_true(script_result.stdout.contains("Hello from script"), "Script output should contain expected text");
 | 
				
			||||||
    print("✓ Content operations: Script created and executed successfully");
 | 
					    print("✓ Content operations: Script created and executed successfully");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Test commit with config
 | 
					    // Test commit
 | 
				
			||||||
    print("Testing commit with config...");
 | 
					    print("Testing commit...");
 | 
				
			||||||
    let commit_options = #{
 | 
					    builder.commit("rhai_test_commit:latest", [["q", ""]]);
 | 
				
			||||||
        "author": "Rhai Test",
 | 
					    print("✓ commit(): Container committed successfully");
 | 
				
			||||||
        "message": "Test commit"
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    builder.commit("rhai_test_commit:latest", commit_options);
 | 
					 | 
				
			||||||
    print("✓ commit(): Container committed with config successfully");
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Clean up
 | 
					    // Clean up
 | 
				
			||||||
    builder.remove();
 | 
					    builder.remove();
 | 
				
			||||||
@@ -115,13 +109,15 @@ echo "Hello from script"
 | 
				
			|||||||
    // Clean up in case of error
 | 
					    // Clean up in case of error
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
        // Remove test container if it exists
 | 
					        // Remove test container if it exists
 | 
				
			||||||
        run("buildah rm rhai_test_container");
 | 
					        let command = run("buildah rm rhai_test_container");
 | 
				
			||||||
    } catch(_) {}
 | 
					        command.execute();
 | 
				
			||||||
 | 
					    } catch(err) {}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
        // Remove test image if it exists
 | 
					        // Remove test image if it exists
 | 
				
			||||||
        run("buildah rmi rhai_test_commit:latest");
 | 
					        let command = run("buildah rmi rhai_test_commit:latest");
 | 
				
			||||||
    } catch(_) {}
 | 
					        command.execute();
 | 
				
			||||||
 | 
					    } catch(err) {}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    throw err;
 | 
					    throw err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,155 +0,0 @@
 | 
				
			|||||||
// run_all_tests.rhai
 | 
					 | 
				
			||||||
// Runs all Buildah module tests
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
print("=== Running Buildah Module Tests ===");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Custom assert function
 | 
					 | 
				
			||||||
fn assert_true(condition, message) {
 | 
					 | 
				
			||||||
    if !condition {
 | 
					 | 
				
			||||||
        print(`ASSERTION FAILED: ${message}`);
 | 
					 | 
				
			||||||
        throw message;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Helper function to check if buildah is available
 | 
					 | 
				
			||||||
fn is_buildah_available() {
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
        let result = run("which buildah");
 | 
					 | 
				
			||||||
        return result.success;
 | 
					 | 
				
			||||||
    } catch(e) {
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Run each test directly
 | 
					 | 
				
			||||||
let passed = 0;
 | 
					 | 
				
			||||||
let failed = 0;
 | 
					 | 
				
			||||||
let skipped = 0;
 | 
					 | 
				
			||||||
let total = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Check if buildah is available
 | 
					 | 
				
			||||||
let buildah_available = is_buildah_available();
 | 
					 | 
				
			||||||
if !buildah_available {
 | 
					 | 
				
			||||||
    print("Buildah is not available. Skipping all Buildah tests.");
 | 
					 | 
				
			||||||
    skipped = 3; // Skip all three tests
 | 
					 | 
				
			||||||
    total = 3;
 | 
					 | 
				
			||||||
} else {
 | 
					 | 
				
			||||||
    // Test 1: Builder Pattern
 | 
					 | 
				
			||||||
    print("\n--- Running Builder Pattern Tests ---");
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
        // Create a builder
 | 
					 | 
				
			||||||
        let builder = bah_new("rhai_test_container", "alpine:latest");
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Test basic properties
 | 
					 | 
				
			||||||
        assert_true(builder.container_id != "", "Container ID should not be empty");
 | 
					 | 
				
			||||||
        assert_true(builder.name == "rhai_test_container", "Container name should match");
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Run a simple command
 | 
					 | 
				
			||||||
        let result = builder.run("echo 'Hello from container'");
 | 
					 | 
				
			||||||
        assert_true(result.success, "Command should succeed");
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Clean up
 | 
					 | 
				
			||||||
        builder.remove();
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        print("--- Builder Pattern Tests completed successfully ---");
 | 
					 | 
				
			||||||
        passed += 1;
 | 
					 | 
				
			||||||
    } catch(err) {
 | 
					 | 
				
			||||||
        print(`!!! Error in Builder Pattern Tests: ${err}`);
 | 
					 | 
				
			||||||
        failed += 1;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Clean up in case of error
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            run("buildah rm rhai_test_container");
 | 
					 | 
				
			||||||
        } catch(e) {
 | 
					 | 
				
			||||||
            // Ignore errors during cleanup
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    total += 1;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    // Test 2: Image Operations
 | 
					 | 
				
			||||||
    print("\n--- Running Image Operations Tests ---");
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
        // Create a temporary directory for testing
 | 
					 | 
				
			||||||
        let test_dir = "rhai_test_buildah";
 | 
					 | 
				
			||||||
        mkdir(test_dir);
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Create a builder
 | 
					 | 
				
			||||||
        let builder = bah_new("rhai_test_container", "alpine:latest");
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // List images
 | 
					 | 
				
			||||||
        let images = builder.images();
 | 
					 | 
				
			||||||
        assert_true(images.len() > 0, "There should be at least one image");
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Clean up
 | 
					 | 
				
			||||||
        builder.remove();
 | 
					 | 
				
			||||||
        delete(test_dir);
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        print("--- Image Operations Tests completed successfully ---");
 | 
					 | 
				
			||||||
        passed += 1;
 | 
					 | 
				
			||||||
    } catch(err) {
 | 
					 | 
				
			||||||
        print(`!!! Error in Image Operations Tests: ${err}`);
 | 
					 | 
				
			||||||
        failed += 1;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Clean up in case of error
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            run("buildah rm rhai_test_container");
 | 
					 | 
				
			||||||
            delete("rhai_test_buildah");
 | 
					 | 
				
			||||||
        } catch(e) {
 | 
					 | 
				
			||||||
            // Ignore errors during cleanup
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    total += 1;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    // Test 3: Container Operations
 | 
					 | 
				
			||||||
    print("\n--- Running Container Operations Tests ---");
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
        // Create a builder
 | 
					 | 
				
			||||||
        let builder = bah_new("rhai_test_container", "alpine:latest");
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Test reset
 | 
					 | 
				
			||||||
        builder.reset();
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Create a new container
 | 
					 | 
				
			||||||
        builder = bah_new("rhai_test_container", "alpine:latest");
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Run a command
 | 
					 | 
				
			||||||
        let result = builder.run("echo 'Hello from container'");
 | 
					 | 
				
			||||||
        assert_true(result.success, "Command should succeed");
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Clean up
 | 
					 | 
				
			||||||
        builder.remove();
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        print("--- Container Operations Tests completed successfully ---");
 | 
					 | 
				
			||||||
        passed += 1;
 | 
					 | 
				
			||||||
    } catch(err) {
 | 
					 | 
				
			||||||
        print(`!!! Error in Container Operations Tests: ${err}`);
 | 
					 | 
				
			||||||
        failed += 1;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Clean up in case of error
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            run("buildah rm rhai_test_container");
 | 
					 | 
				
			||||||
        } catch(e) {
 | 
					 | 
				
			||||||
            // Ignore errors during cleanup
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    total += 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
print("\n=== Test Summary ===");
 | 
					 | 
				
			||||||
print(`Passed: ${passed}`);
 | 
					 | 
				
			||||||
print(`Failed: ${failed}`);
 | 
					 | 
				
			||||||
print(`Skipped: ${skipped}`);
 | 
					 | 
				
			||||||
print(`Total: ${total}`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if failed == 0 {
 | 
					 | 
				
			||||||
    if skipped > 0 {
 | 
					 | 
				
			||||||
        print("\n⚠️ All tests skipped or passed!");
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        print("\n✅ All tests passed!");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
} else {
 | 
					 | 
				
			||||||
    print("\n❌ Some tests failed!");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Return the number of failed tests (0 means success)
 | 
					 | 
				
			||||||
failed;
 | 
					 | 
				
			||||||
@@ -21,22 +21,31 @@ fn assert_eq(actual, expected, message) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Helper function to check if nerdctl is available
 | 
					// Helper function to check if nerdctl is available
 | 
				
			||||||
fn is_nerdctl_available() {
 | 
					fn is_nerdctl_available() {
 | 
				
			||||||
    try {
 | 
					    let command = run("which nerdctl");
 | 
				
			||||||
        let result = run("which nerdctl");
 | 
					    return command.silent().execute().success;
 | 
				
			||||||
        return result.success;
 | 
					 | 
				
			||||||
    } catch(err) {
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Helper function to check if a container exists
 | 
					// Helper function to check if a container exists
 | 
				
			||||||
fn container_exists(container_name) {
 | 
					fn container_exists(container_name) {
 | 
				
			||||||
    try {
 | 
					    // let command = run(`nerdctl ps -a --format "{{.Names}}" | grep -w ${container_name}`);
 | 
				
			||||||
        let result = run(`nerdctl ps -a --format "{{.Names}}" | grep -w ${container_name}`);
 | 
					    let command = run(`nerdctl ps -a --format "{{.Names}}"`);
 | 
				
			||||||
        return result.success;
 | 
					    let result = command.silent().execute();
 | 
				
			||||||
    } catch(err) {
 | 
					
 | 
				
			||||||
 | 
					    // Check if the command was successful
 | 
				
			||||||
 | 
					    if !result.success {
 | 
				
			||||||
 | 
					        print(`Error executing 'nerdctl ps': ${result.stderr}`);
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Split the output into individual lines (names)
 | 
				
			||||||
 | 
					    // and check if any of them is an exact match for our container name.
 | 
				
			||||||
 | 
					    for line in result.stdout.split('\n') {
 | 
				
			||||||
 | 
					        if line.trim() == container_name {
 | 
				
			||||||
 | 
					            return true; // Found the container
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return false; // Did not find the container
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Helper function to clean up a container if it exists
 | 
					// Helper function to clean up a container if it exists
 | 
				
			||||||
@@ -49,6 +58,8 @@ fn cleanup_container(container_name) {
 | 
				
			|||||||
        } catch(err) {
 | 
					        } catch(err) {
 | 
				
			||||||
            print(`Error cleaning up container ${container_name}: ${err}`);
 | 
					            print(`Error cleaning up container ${container_name}: ${err}`);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        print!(`No container with name ${container_name} found. Nothing to clean up.`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -58,8 +69,7 @@ print("=== Testing Nerdctl Container Operations ===");
 | 
				
			|||||||
let nerdctl_available = is_nerdctl_available();
 | 
					let nerdctl_available = is_nerdctl_available();
 | 
				
			||||||
if !nerdctl_available {
 | 
					if !nerdctl_available {
 | 
				
			||||||
    print("nerdctl is not available. Skipping Nerdctl tests.");
 | 
					    print("nerdctl is not available. Skipping Nerdctl tests.");
 | 
				
			||||||
    // Exit gracefully without error
 | 
					    throw err;
 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
print("✓ nerdctl is available");
 | 
					print("✓ nerdctl is available");
 | 
				
			||||||
@@ -81,84 +91,132 @@ try {
 | 
				
			|||||||
    assert_eq(container.container_id, "", "Container ID should be empty initially");
 | 
					    assert_eq(container.container_id, "", "Container ID should be empty initially");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Test setting container image
 | 
					    // Test setting container image
 | 
				
			||||||
    print("Testing with_image()...");
 | 
					    print("Testing image setter..."); 
 | 
				
			||||||
    container.with_image("alpine:latest");
 | 
					    container.image = "alpine:latest";
 | 
				
			||||||
    assert_eq(container.image, "alpine:latest", "Container image should match");
 | 
					    assert_eq(container.image, "alpine:latest", "Container image should match");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Test setting detach mode
 | 
					    // Test setting container config
 | 
				
			||||||
    print("Testing with_detach()...");
 | 
					    print("Testing config setter...");
 | 
				
			||||||
    container.with_detach(true);
 | 
					    let config_options = #{"key1": "value1", "key2": "value2"};
 | 
				
			||||||
    assert_true(container.detach, "Container detach mode should be true");
 | 
					    container.config = config_options;
 | 
				
			||||||
 | 
					    assert_eq(container.config, config_options, "Container config options should match");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Test setting environment variables
 | 
					    // Test container_id setter and getter
 | 
				
			||||||
    print("Testing with_env()...");
 | 
					    print("Testing container_id setter...");
 | 
				
			||||||
    container.with_env("TEST_VAR", "test_value");
 | 
					    container.container_id = "test-id";
 | 
				
			||||||
 | 
					    assert_eq(container.container_id, "test-id", "Container ID should be 'test-id'");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Test setting multiple environment variables
 | 
					    // Test ports setter and getter
 | 
				
			||||||
    print("Testing with_envs()...");
 | 
					    print("Testing ports setter and getter...");
 | 
				
			||||||
    let env_map = #{
 | 
					    let ports_list = ["1234", "2345"];
 | 
				
			||||||
        "VAR1": "value1",
 | 
					    container.ports = ports_list;
 | 
				
			||||||
        "VAR2": "value2"
 | 
					    assert_eq(container.ports, ports_list, "Container ports should match");
 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    container.with_envs(env_map);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Test setting ports
 | 
					    // Test volumes setter and getter
 | 
				
			||||||
    print("Testing with_port()...");
 | 
					    print("Testing volumes setter and getter...");
 | 
				
			||||||
    container.with_port("8080:80");
 | 
					    let volumes_list = ["/tmp:/tmp"];
 | 
				
			||||||
 | 
					    container.volumes = volumes_list;
 | 
				
			||||||
 | 
					    assert_eq(container.volumes, volumes_list, "Container volumes should match");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Test setting multiple ports
 | 
					    // Test env_vars setter and getter
 | 
				
			||||||
    print("Testing with_ports()...");
 | 
					    print("Testing env_vars setter and getter...");
 | 
				
			||||||
    container.with_ports(["9090:90", "7070:70"]);
 | 
					    let env_vars_map = #{"VAR1": "value1", "VAR2": "value2"};
 | 
				
			||||||
 | 
					    container.env_vars = env_vars_map;
 | 
				
			||||||
 | 
					    assert_eq(container.env_vars, env_vars_map, "Container env_vars should match");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Test setting volumes
 | 
					    // Test network setter and getter
 | 
				
			||||||
    print("Testing with_volume()...");
 | 
					    print("Testing network setter and getter...");
 | 
				
			||||||
    // Create a test directory for volume mounting
 | 
					    container.network = "test-net";
 | 
				
			||||||
    let test_dir = "rhai_test_nerdctl_volume";
 | 
					    assert_eq(container.network, "test-net", "Container network should match");
 | 
				
			||||||
    mkdir(test_dir);
 | 
					 | 
				
			||||||
    container.with_volume(`${test_dir}:/data`);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Test setting resource limits
 | 
					    // Test network_aliases setter and getter
 | 
				
			||||||
    print("Testing with_cpu_limit() and with_memory_limit()...");
 | 
					    print("Testing network_aliases setter and getter...");
 | 
				
			||||||
    container.with_cpu_limit("0.5");
 | 
					    let aliases = ["alias1", "alias2"];
 | 
				
			||||||
    container.with_memory_limit("256m");
 | 
					    container.network_aliases = aliases;
 | 
				
			||||||
 | 
					    assert_eq(container.network_aliases, aliases, "Container network_aliases should match");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Test running the container
 | 
					    // Test cpu_limit setter and getter
 | 
				
			||||||
    print("Testing run()...");
 | 
					    print("Testing cpu_limit setter and getter...");
 | 
				
			||||||
    let run_result = container.run();
 | 
					    container.cpu_limit = "0.5";
 | 
				
			||||||
    assert_true(run_result.success, "Container run should succeed");
 | 
					    assert_eq(container.cpu_limit, "0.5", "Container cpu_limit should match");
 | 
				
			||||||
    assert_true(container.container_id != "", "Container ID should not be empty after run");
 | 
					 | 
				
			||||||
    print(`✓ run(): Container started with ID: ${container.container_id}`);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Test executing a command in the container
 | 
					    // Test memory_limit setter and getter
 | 
				
			||||||
    print("Testing exec()...");
 | 
					    print("Testing memory_limit setter and getter...");
 | 
				
			||||||
    let exec_result = container.exec("echo 'Hello from container'");
 | 
					    container.memory_limit = "512m";
 | 
				
			||||||
    assert_true(exec_result.success, "Container exec should succeed");
 | 
					    assert_eq(container.memory_limit, "512m", "Container memory_limit should match");
 | 
				
			||||||
    assert_true(exec_result.stdout.contains("Hello from container"), "Exec output should contain expected text");
 | 
					 | 
				
			||||||
    print("✓ exec(): Command executed successfully");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Test getting container logs
 | 
					    // Test memory_swap_limit setter and getter
 | 
				
			||||||
    print("Testing logs()...");
 | 
					    print("Testing memory_swap_limit setter and getter...");
 | 
				
			||||||
    let logs_result = container.logs();
 | 
					    container.memory_swap_limit = "1g";
 | 
				
			||||||
    assert_true(logs_result.success, "Container logs should succeed");
 | 
					    assert_eq(container.memory_swap_limit, "1g", "Container memory_swap_limit should match");
 | 
				
			||||||
    print("✓ logs(): Logs retrieved successfully");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Test stopping the container
 | 
					    // Test cpu_shares setter and getter
 | 
				
			||||||
    print("Testing stop()...");
 | 
					    print("Testing cpu_shares setter and getter...");
 | 
				
			||||||
    let stop_result = container.stop();
 | 
					    container.cpu_shares = "1024";
 | 
				
			||||||
    assert_true(stop_result.success, "Container stop should succeed");
 | 
					    assert_eq(container.cpu_shares, "1024", "Container cpu_shares should match");
 | 
				
			||||||
    print("✓ stop(): Container stopped successfully");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Test removing the container
 | 
					    // Test restart_policy setter and getter
 | 
				
			||||||
    print("Testing remove()...");
 | 
					    print("Testing restart_policy setter and getter...");
 | 
				
			||||||
    let remove_result = container.remove();
 | 
					    container.restart_policy = "always";
 | 
				
			||||||
    assert_true(remove_result.success, "Container remove should succeed");
 | 
					    assert_eq(container.restart_policy, "always", "Container restart_policy should match");
 | 
				
			||||||
    print("✓ remove(): Container removed successfully");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Clean up test directory
 | 
					    // Test detach setter and getter
 | 
				
			||||||
    delete(test_dir);
 | 
					    print("Testing detach setter and getter...");
 | 
				
			||||||
    print("✓ Cleanup: Test directory removed");
 | 
					    container.detach = false;
 | 
				
			||||||
 | 
					    assert_eq(container.detach, false, "Container detach should be false");
 | 
				
			||||||
 | 
					    container.detach = true;
 | 
				
			||||||
 | 
					    assert_eq(container.detach, true, "Container detach should be true");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    print("All container operations tests completed successfully!");
 | 
					    // Test health_check setter and getter
 | 
				
			||||||
 | 
					    print("Testing health_check setter and getter...");
 | 
				
			||||||
 | 
					    let health_check_new = health_check_new("example_cmd");
 | 
				
			||||||
 | 
					    container.health_check = health_check_new;
 | 
				
			||||||
 | 
					    container.health_check.interval = "example_interval";
 | 
				
			||||||
 | 
					    assert_eq(container.health_check.cmd, "example_cmd", "Container health check cmd should match");
 | 
				
			||||||
 | 
					    assert_eq(container.health_check.interval, "example_interval", "Container health check interval should match");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Test snapshotter setter and getter
 | 
				
			||||||
 | 
					    print("Testing snapshotter setter and getter...");
 | 
				
			||||||
 | 
					    container.snapshotter = "stargz";
 | 
				
			||||||
 | 
					    assert_eq(container.snapshotter, "stargz", "Container snapshotter should match");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // // Test running the container
 | 
				
			||||||
 | 
					    // print("Testing run()...");
 | 
				
			||||||
 | 
					    // let run_result = container.run();
 | 
				
			||||||
 | 
					    // assert_true(run_result.success, "Container run should succeed");
 | 
				
			||||||
 | 
					    // assert_true(container.container_id != "", "Container ID should not be empty after run");
 | 
				
			||||||
 | 
					    // print(`✓ run(): Container started with ID: ${container.container_id}`);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // // Test executing a command in the container
 | 
				
			||||||
 | 
					    // print("Testing exec()...");
 | 
				
			||||||
 | 
					    // let exec_result = container.exec("echo 'Hello from container'");
 | 
				
			||||||
 | 
					    // assert_true(exec_result.success, "Container exec should succeed");
 | 
				
			||||||
 | 
					    // assert_true(exec_result.stdout.contains("Hello from container"), "Exec output should contain expected text");
 | 
				
			||||||
 | 
					    // print("✓ exec(): Command executed successfully");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // // Test getting container logs
 | 
				
			||||||
 | 
					    // print("Testing logs()...");
 | 
				
			||||||
 | 
					    // let logs_result = container.logs();
 | 
				
			||||||
 | 
					    // assert_true(logs_result.success, "Container logs should succeed");
 | 
				
			||||||
 | 
					    // print("✓ logs(): Logs retrieved successfully");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // // Test stopping the container
 | 
				
			||||||
 | 
					    // print("Testing stop()...");
 | 
				
			||||||
 | 
					    // let stop_result = container.stop();
 | 
				
			||||||
 | 
					    // assert_true(stop_result.success, "Container stop should succeed");
 | 
				
			||||||
 | 
					    // print("✓ stop(): Container stopped successfully");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // // Test removing the container
 | 
				
			||||||
 | 
					    // print("Testing remove()...");
 | 
				
			||||||
 | 
					    // let remove_result = container.remove();
 | 
				
			||||||
 | 
					    // assert_true(remove_result.success, "Container remove should succeed");
 | 
				
			||||||
 | 
					    // print("✓ remove(): Container removed successfully");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // // Clean up test directory
 | 
				
			||||||
 | 
					    // delete(test_dir);
 | 
				
			||||||
 | 
					    // print("✓ Cleanup: Test directory removed");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // print("All container operations tests completed successfully!");
 | 
				
			||||||
} catch(err) {
 | 
					} catch(err) {
 | 
				
			||||||
    print(`Error: ${err}`);
 | 
					    print(`Error: ${err}`);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@ use crate::buildah::{
 | 
				
			|||||||
    execute_buildah_command, set_thread_local_debug, thread_local_debug, BuildahError, Image,
 | 
					    execute_buildah_command, set_thread_local_debug, thread_local_debug, BuildahError, Image,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use sal_process::CommandResult;
 | 
					use sal_process::CommandResult;
 | 
				
			||||||
use std::collections::HashMap;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Builder struct for buildah operations
 | 
					/// Builder struct for buildah operations
 | 
				
			||||||
#[derive(Clone)]
 | 
					#[derive(Clone)]
 | 
				
			||||||
@@ -249,8 +248,32 @@ impl Builder {
 | 
				
			|||||||
    /// # Returns
 | 
					    /// # Returns
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// * `Result<CommandResult, BuildahError>` - Command result or error
 | 
					    /// * `Result<CommandResult, BuildahError>` - Command result or error
 | 
				
			||||||
    pub fn commit(&self, image_name: &str) -> Result<CommandResult, BuildahError> {
 | 
					    pub fn commit(&self, image_name: &str, options: Option<Vec<(String, String)>>) -> Result<CommandResult, BuildahError> {
 | 
				
			||||||
        if let Some(container_id) = &self.container_id {
 | 
					        if let Some(container_id) = &self.container_id {
 | 
				
			||||||
 | 
					            let mut args_owned: Vec<String> = Vec::new();
 | 
				
			||||||
 | 
					            args_owned.push("commit".to_string());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Process options
 | 
				
			||||||
 | 
					            if let Some(options_vec) = options {
 | 
				
			||||||
 | 
					                for (key, value) in options_vec.iter() {
 | 
				
			||||||
 | 
					                    let option_name = if key.len() == 1 {
 | 
				
			||||||
 | 
					                        format!("-{}", key)
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        format!("--{}", key)
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					                    args_owned.push(option_name);
 | 
				
			||||||
 | 
					                    if !value.is_empty() {
 | 
				
			||||||
 | 
					                        args_owned.push(value.clone());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            args_owned.push(container_id.clone());
 | 
				
			||||||
 | 
					            args_owned.push(image_name.to_string());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Convert Vec<String> to Vec<&str> for execute_buildah_command
 | 
				
			||||||
 | 
					            let args: Vec<&str> = args_owned.iter().map(|s| s.as_str()).collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Save the current debug flag
 | 
					            // Save the current debug flag
 | 
				
			||||||
            let previous_debug = thread_local_debug();
 | 
					            let previous_debug = thread_local_debug();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -258,7 +281,7 @@ impl Builder {
 | 
				
			|||||||
            set_thread_local_debug(self.debug);
 | 
					            set_thread_local_debug(self.debug);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Execute the command
 | 
					            // Execute the command
 | 
				
			||||||
            let result = execute_buildah_command(&["commit", container_id, image_name]);
 | 
					            let result = execute_buildah_command(&args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Restore the previous debug flag
 | 
					            // Restore the previous debug flag
 | 
				
			||||||
            set_thread_local_debug(previous_debug);
 | 
					            set_thread_local_debug(previous_debug);
 | 
				
			||||||
@@ -336,17 +359,23 @@ impl Builder {
 | 
				
			|||||||
    /// # Returns
 | 
					    /// # Returns
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// * `Result<CommandResult, BuildahError>` - Command result or error
 | 
					    /// * `Result<CommandResult, BuildahError>` - Command result or error
 | 
				
			||||||
    pub fn config(&self, options: HashMap<String, String>) -> Result<CommandResult, BuildahError> {
 | 
					    pub fn config(&self, options: Vec<(String, String)>) -> Result<CommandResult, BuildahError> {
 | 
				
			||||||
        if let Some(container_id) = &self.container_id {
 | 
					        if let Some(container_id) = &self.container_id {
 | 
				
			||||||
            let mut args_owned: Vec<String> = Vec::new();
 | 
					            let mut args_owned: Vec<String> = Vec::new();
 | 
				
			||||||
            args_owned.push("config".to_string());
 | 
					            args_owned.push("config".to_string());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Process options map
 | 
					            // Process options
 | 
				
			||||||
            for (key, value) in options.iter() {
 | 
					            for (key, value) in options.iter() {
 | 
				
			||||||
                let option_name = format!("--{}", key);
 | 
					                let option_name = if key.len() == 1 {
 | 
				
			||||||
 | 
					                    format!("-{}", key)
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    format!("--{}", key)
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
                args_owned.push(option_name);
 | 
					                args_owned.push(option_name);
 | 
				
			||||||
 | 
					                if !value.is_empty() {
 | 
				
			||||||
                    args_owned.push(value.clone());
 | 
					                    args_owned.push(value.clone());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            args_owned.push(container_id.clone());
 | 
					            args_owned.push(container_id.clone());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -380,8 +409,19 @@ impl Builder {
 | 
				
			|||||||
    /// # Returns
 | 
					    /// # Returns
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// * `Result<CommandResult, BuildahError>` - Command result or error
 | 
					    /// * `Result<CommandResult, BuildahError>` - Command result or error
 | 
				
			||||||
    pub fn set_entrypoint(&self, entrypoint: &str) -> Result<CommandResult, BuildahError> {
 | 
					    pub fn set_entrypoint(&self, entrypoint: Vec<String>) -> Result<CommandResult, BuildahError> {
 | 
				
			||||||
        if let Some(container_id) = &self.container_id {
 | 
					        if let Some(container_id) = &self.container_id {
 | 
				
			||||||
 | 
					            // Serialize the entrypoint vector to a JSON string
 | 
				
			||||||
 | 
					            let entrypoint_json = match serde_json::to_string(&entrypoint) {
 | 
				
			||||||
 | 
					                Ok(json) => json,
 | 
				
			||||||
 | 
					                Err(e) => {
 | 
				
			||||||
 | 
					                    return Err(BuildahError::JsonParseError(format!(
 | 
				
			||||||
 | 
					                        "Failed to serialize entrypoint to JSON: {}",
 | 
				
			||||||
 | 
					                        e
 | 
				
			||||||
 | 
					                    )));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Save the current debug flag
 | 
					            // Save the current debug flag
 | 
				
			||||||
            let previous_debug = thread_local_debug();
 | 
					            let previous_debug = thread_local_debug();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -390,7 +430,7 @@ impl Builder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            // Execute the command
 | 
					            // Execute the command
 | 
				
			||||||
            let result =
 | 
					            let result =
 | 
				
			||||||
                execute_buildah_command(&["config", "--entrypoint", entrypoint, container_id]);
 | 
					                execute_buildah_command(&["config", "--entrypoint", &entrypoint_json, container_id]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Restore the previous debug flag
 | 
					            // Restore the previous debug flag
 | 
				
			||||||
            set_thread_local_debug(previous_debug);
 | 
					            set_thread_local_debug(previous_debug);
 | 
				
			||||||
@@ -410,8 +450,19 @@ impl Builder {
 | 
				
			|||||||
    /// # Returns
 | 
					    /// # Returns
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// * `Result<CommandResult, BuildahError>` - Command result or error
 | 
					    /// * `Result<CommandResult, BuildahError>` - Command result or error
 | 
				
			||||||
    pub fn set_cmd(&self, cmd: &str) -> Result<CommandResult, BuildahError> {
 | 
					    pub fn set_cmd(&self, cmd: Vec<String>) -> Result<CommandResult, BuildahError> {
 | 
				
			||||||
        if let Some(container_id) = &self.container_id {
 | 
					        if let Some(container_id) = &self.container_id {
 | 
				
			||||||
 | 
					            // Serialize the cmd vector to a JSON string
 | 
				
			||||||
 | 
					            let cmd_json = match serde_json::to_string(&cmd) {
 | 
				
			||||||
 | 
					                Ok(json) => json,
 | 
				
			||||||
 | 
					                Err(e) => {
 | 
				
			||||||
 | 
					                    return Err(BuildahError::JsonParseError(format!(
 | 
				
			||||||
 | 
					                        "Failed to serialize cmd to JSON: {}",
 | 
				
			||||||
 | 
					                        e
 | 
				
			||||||
 | 
					                    )));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Save the current debug flag
 | 
					            // Save the current debug flag
 | 
				
			||||||
            let previous_debug = thread_local_debug();
 | 
					            let previous_debug = thread_local_debug();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -419,7 +470,7 @@ impl Builder {
 | 
				
			|||||||
            set_thread_local_debug(self.debug);
 | 
					            set_thread_local_debug(self.debug);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Execute the command
 | 
					            // Execute the command
 | 
				
			||||||
            let result = execute_buildah_command(&["config", "--cmd", cmd, container_id]);
 | 
					            let result = execute_buildah_command(&["config", "--cmd", &cmd_json, container_id]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Restore the previous debug flag
 | 
					            // Restore the previous debug flag
 | 
				
			||||||
            set_thread_local_debug(previous_debug);
 | 
					            set_thread_local_debug(previous_debug);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,34 +55,44 @@ impl ContentOperations {
 | 
				
			|||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// * `Result<String, BuildahError>` - File content or error
 | 
					    /// * `Result<String, BuildahError>` - File content or error
 | 
				
			||||||
    pub fn read_content(container_id: &str, source_path: &str) -> Result<String, BuildahError> {
 | 
					    pub fn read_content(container_id: &str, source_path: &str) -> Result<String, BuildahError> {
 | 
				
			||||||
        // Create a temporary file
 | 
					        // Create a temporary file to store the content from the container.
 | 
				
			||||||
        let temp_file = NamedTempFile::new()
 | 
					        let temp_file = NamedTempFile::new()
 | 
				
			||||||
            .map_err(|e| BuildahError::Other(format!("Failed to create temporary file: {}", e)))?;
 | 
					            .map_err(|e| BuildahError::Other(format!("Failed to create temporary file: {}", e)))?;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        let temp_path = temp_file.path().to_string_lossy().to_string();
 | 
					        let temp_path = temp_file.path().to_string_lossy().to_string();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Copy the file from the container to the temporary file
 | 
					        // In rootless mode, `buildah mount` must run inside `buildah unshare`.
 | 
				
			||||||
        // Use mount to access the container's filesystem
 | 
					        // We create a script to mount, copy the file, and unmount, all within the unshare session.
 | 
				
			||||||
        let mount_result = execute_buildah_command(&["mount", container_id])?;
 | 
					        let script = format!(
 | 
				
			||||||
        let mount_point = mount_result.stdout.trim();
 | 
					            r#"
 | 
				
			||||||
 | 
					                set -e
 | 
				
			||||||
 | 
					                mount_point=$(buildah mount '{container_id}')
 | 
				
			||||||
 | 
					                if [ -z "$mount_point" ]; then
 | 
				
			||||||
 | 
					                    echo "Error: Failed to mount container '{container_id}'." >&2
 | 
				
			||||||
 | 
					                    exit 1
 | 
				
			||||||
 | 
					                fi
 | 
				
			||||||
 | 
					                trap 'buildah umount '{container_id}'' EXIT
 | 
				
			||||||
 | 
					                cp "${{mount_point}}{source_path}" '{temp_path}'
 | 
				
			||||||
 | 
					            "#,
 | 
				
			||||||
 | 
					            container_id = container_id,
 | 
				
			||||||
 | 
					            source_path = source_path,
 | 
				
			||||||
 | 
					            temp_path = &temp_path
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Construct the full path to the file in the container
 | 
					        let result = execute_buildah_command(&["unshare", "sh", "-c", &script])?;
 | 
				
			||||||
        let full_source_path = format!("{}{}", mount_point, source_path);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Copy the file from the mounted container to the temporary file
 | 
					        if !result.success {
 | 
				
			||||||
        execute_buildah_command(&["copy", container_id, &full_source_path, &temp_path])?;
 | 
					            return Err(BuildahError::Other(format!(
 | 
				
			||||||
 | 
					                "Failed to execute read_content script in unshare session: {}",
 | 
				
			||||||
        // Unmount the container
 | 
					                result.stderr
 | 
				
			||||||
        execute_buildah_command(&["umount", container_id])?;
 | 
					            )));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        // Read the content from the temporary file
 | 
					 | 
				
			||||||
        let mut file = File::open(temp_file.path())
 | 
					 | 
				
			||||||
            .map_err(|e| BuildahError::Other(format!("Failed to open temporary file: {}", e)))?;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // The script has copied the file content to our temporary file.
 | 
				
			||||||
 | 
					        // Now, we read it.
 | 
				
			||||||
        let mut content = String::new();
 | 
					        let mut content = String::new();
 | 
				
			||||||
        file.read_to_string(&mut content).map_err(|e| {
 | 
					        File::open(&temp_path)
 | 
				
			||||||
            BuildahError::Other(format!("Failed to read from temporary file: {}", e))
 | 
					            .and_then(|mut f| f.read_to_string(&mut content))
 | 
				
			||||||
        })?;
 | 
					            .map_err(|e| BuildahError::Other(format!("Failed to read from temporary file: {}", e)))?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(content)
 | 
					        Ok(content)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,6 +52,20 @@ impl Container {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Add an image
 | 
				
			||||||
 | 
					    /// 
 | 
				
			||||||
 | 
					    /// # Arguments
 | 
				
			||||||
 | 
					    /// 
 | 
				
			||||||
 | 
					    /// * `image` - Image to create the container from
 | 
				
			||||||
 | 
					    /// 
 | 
				
			||||||
 | 
					    /// # Returns
 | 
				
			||||||
 | 
					    /// 
 | 
				
			||||||
 | 
					    /// * `Self` - The container instance for method chaining
 | 
				
			||||||
 | 
					    pub fn with_image(mut self, image: &str) -> Self {
 | 
				
			||||||
 | 
					        self.image = Some(image.to_string());
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Add a port mapping
 | 
					    /// Add a port mapping
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// # Arguments
 | 
					    /// # Arguments
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,7 +42,7 @@ pub struct Container {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Health check configuration for a container
 | 
					/// Health check configuration for a container
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Clone, PartialEq)]
 | 
				
			||||||
pub struct HealthCheck {
 | 
					pub struct HealthCheck {
 | 
				
			||||||
    /// Command to run for health check
 | 
					    /// Command to run for health check
 | 
				
			||||||
    pub cmd: String,
 | 
					    pub cmd: String,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,9 +3,8 @@
 | 
				
			|||||||
//! This module provides Rhai wrappers for the functions in the Buildah module.
 | 
					//! This module provides Rhai wrappers for the functions in the Buildah module.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::buildah::{BuildahError, Builder, ContentOperations, Image};
 | 
					use crate::buildah::{BuildahError, Builder, ContentOperations, Image};
 | 
				
			||||||
use rhai::{Array, Dynamic, Engine, EvalAltResult, Map};
 | 
					use rhai::{Array, Dynamic, Engine, EvalAltResult};
 | 
				
			||||||
use sal_process::CommandResult;
 | 
					use sal_process::CommandResult;
 | 
				
			||||||
use std::collections::HashMap;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Register Buildah module functions with the Rhai engine
 | 
					/// Register Buildah module functions with the Rhai engine
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
@@ -45,7 +44,6 @@ pub fn register_bah_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>
 | 
				
			|||||||
    engine.register_fn("image_push", builder_image_push);
 | 
					    engine.register_fn("image_push", builder_image_push);
 | 
				
			||||||
    engine.register_fn("image_tag", builder_image_tag);
 | 
					    engine.register_fn("image_tag", builder_image_tag);
 | 
				
			||||||
    engine.register_fn("build", builder_build);
 | 
					    engine.register_fn("build", builder_build);
 | 
				
			||||||
    engine.register_fn("read_content", builder_read_content);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -89,29 +87,51 @@ fn register_bah_types(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Helper functions for error conversion
 | 
					// Helper functions for error conversion
 | 
				
			||||||
fn bah_error_to_rhai_error<T>(result: Result<T, BuildahError>) -> Result<T, Box<EvalAltResult>> {
 | 
					impl From<BuildahError> for Box<EvalAltResult> {
 | 
				
			||||||
    result.map_err(|e| {
 | 
					    fn from(err: BuildahError) -> Self {
 | 
				
			||||||
        Box::new(EvalAltResult::ErrorRuntime(
 | 
					        Box::new(EvalAltResult::ErrorRuntime(
 | 
				
			||||||
            format!("Buildah error: {}", e).into(),
 | 
					            format!("Buildah error: {}", err).into(),
 | 
				
			||||||
            rhai::Position::NONE,
 | 
					            rhai::Position::NONE,
 | 
				
			||||||
        ))
 | 
					        ))
 | 
				
			||||||
    })
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Helper function to convert Rhai Map to Rust HashMap
 | 
					// Helper function to convert Rhai Array of pairs to a Vec of tuples
 | 
				
			||||||
fn convert_map_to_hashmap(options: Map) -> Result<HashMap<String, String>, Box<EvalAltResult>> {
 | 
					fn convert_array_to_vec(
 | 
				
			||||||
    let mut config_options = HashMap::<String, String>::new();
 | 
					    options: Array,
 | 
				
			||||||
 | 
					) -> Result<Vec<(String, String)>, Box<EvalAltResult>> {
 | 
				
			||||||
 | 
					    let mut config_options: Vec<(String, String)> = Vec::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (key, value) in options.iter() {
 | 
					    for option_pair_dynamic in options {
 | 
				
			||||||
        if let Ok(value_str) = value.clone().into_string() {
 | 
					        let pair = option_pair_dynamic.into_array().map_err(|_e| {
 | 
				
			||||||
            // Convert SmartString to String
 | 
					            Box::new(EvalAltResult::ErrorRuntime(
 | 
				
			||||||
            config_options.insert(key.to_string(), value_str);
 | 
					                "Each option must be an array of [key, value]".into(),
 | 
				
			||||||
        } else {
 | 
					                rhai::Position::NONE,
 | 
				
			||||||
 | 
					            ))
 | 
				
			||||||
 | 
					        })?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if pair.len() != 2 {
 | 
				
			||||||
            return Err(Box::new(EvalAltResult::ErrorRuntime(
 | 
					            return Err(Box::new(EvalAltResult::ErrorRuntime(
 | 
				
			||||||
                format!("Option '{}' must be a string", key).into(),
 | 
					                "Each option must be an array of [key, value] with 2 elements".into(),
 | 
				
			||||||
                rhai::Position::NONE,
 | 
					                rhai::Position::NONE,
 | 
				
			||||||
            )));
 | 
					            )));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let key = pair[0].clone().into_string().map_err(|_e| {
 | 
				
			||||||
 | 
					            Box::new(EvalAltResult::ErrorRuntime(
 | 
				
			||||||
 | 
					                "Option key must be a string".into(),
 | 
				
			||||||
 | 
					                rhai::Position::NONE,
 | 
				
			||||||
 | 
					            ))
 | 
				
			||||||
 | 
					        })?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let value = pair[1].clone().into_string().map_err(|_e| {
 | 
				
			||||||
 | 
					            Box::new(EvalAltResult::ErrorRuntime(
 | 
				
			||||||
 | 
					                "Option value must be a string".into(),
 | 
				
			||||||
 | 
					                rhai::Position::NONE,
 | 
				
			||||||
 | 
					            ))
 | 
				
			||||||
 | 
					        })?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        config_options.push((key, value));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(config_options)
 | 
					    Ok(config_options)
 | 
				
			||||||
@@ -119,7 +139,7 @@ fn convert_map_to_hashmap(options: Map) -> Result<HashMap<String, String>, Box<E
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// Create a new Builder
 | 
					/// Create a new Builder
 | 
				
			||||||
pub fn bah_new(name: &str, image: &str) -> Result<Builder, Box<EvalAltResult>> {
 | 
					pub fn bah_new(name: &str, image: &str) -> Result<Builder, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(Builder::new(name, image))
 | 
					    Builder::new(name, image).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Builder instance methods
 | 
					// Builder instance methods
 | 
				
			||||||
@@ -127,7 +147,7 @@ pub fn builder_run(
 | 
				
			|||||||
    builder: &mut Builder,
 | 
					    builder: &mut Builder,
 | 
				
			||||||
    command: &str,
 | 
					    command: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(builder.run(command))
 | 
					    builder.run(command).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn builder_run_with_isolation(
 | 
					pub fn builder_run_with_isolation(
 | 
				
			||||||
@@ -135,7 +155,9 @@ pub fn builder_run_with_isolation(
 | 
				
			|||||||
    command: &str,
 | 
					    command: &str,
 | 
				
			||||||
    isolation: &str,
 | 
					    isolation: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(builder.run_with_isolation(command, isolation))
 | 
					    builder
 | 
				
			||||||
 | 
					        .run_with_isolation(command, isolation)
 | 
				
			||||||
 | 
					        .map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn builder_copy(
 | 
					pub fn builder_copy(
 | 
				
			||||||
@@ -143,7 +165,7 @@ pub fn builder_copy(
 | 
				
			|||||||
    source: &str,
 | 
					    source: &str,
 | 
				
			||||||
    dest: &str,
 | 
					    dest: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(builder.copy(source, dest))
 | 
					    builder.copy(source, dest).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn builder_add(
 | 
					pub fn builder_add(
 | 
				
			||||||
@@ -151,43 +173,54 @@ pub fn builder_add(
 | 
				
			|||||||
    source: &str,
 | 
					    source: &str,
 | 
				
			||||||
    dest: &str,
 | 
					    dest: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(builder.add(source, dest))
 | 
					    builder.add(source, dest).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn builder_commit(
 | 
					pub fn builder_commit(
 | 
				
			||||||
    builder: &mut Builder,
 | 
					    builder: &mut Builder,
 | 
				
			||||||
    image_name: &str,
 | 
					    image_name: &str,
 | 
				
			||||||
 | 
					    options: Array,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(builder.commit(image_name))
 | 
					    let commit_options = convert_array_to_vec(options)?;
 | 
				
			||||||
 | 
					    builder
 | 
				
			||||||
 | 
					        .commit(image_name, Some(commit_options))
 | 
				
			||||||
 | 
					        .map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn builder_remove(builder: &mut Builder) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn builder_remove(builder: &mut Builder) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(builder.remove())
 | 
					    builder.remove().map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn builder_config(
 | 
					pub fn builder_config(
 | 
				
			||||||
    builder: &mut Builder,
 | 
					    builder: &mut Builder,
 | 
				
			||||||
    options: Map,
 | 
					    options: Array,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    // Convert Rhai Map to Rust HashMap
 | 
					    let config_options = convert_array_to_vec(options)?;
 | 
				
			||||||
    let config_options = convert_map_to_hashmap(options)?;
 | 
					    builder.config(config_options).map_err(Into::into)
 | 
				
			||||||
    bah_error_to_rhai_error(builder.config(config_options))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Set the entrypoint for the container
 | 
					/// Set the entrypoint for the container
 | 
				
			||||||
pub fn builder_set_entrypoint(
 | 
					pub fn builder_set_entrypoint(
 | 
				
			||||||
    builder: &mut Builder,
 | 
					    builder: &mut Builder,
 | 
				
			||||||
    entrypoint: &str,
 | 
					    entrypoint: Array,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(builder.set_entrypoint(entrypoint))
 | 
					    let entrypoint_vec: Vec<String> = entrypoint
 | 
				
			||||||
 | 
					        .into_iter()
 | 
				
			||||||
 | 
					        .map(|item| item.into_string().unwrap_or_default())
 | 
				
			||||||
 | 
					        .collect();
 | 
				
			||||||
 | 
					    builder.set_entrypoint(entrypoint_vec).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Set the default command for the container
 | 
					/// Set the default command for the container
 | 
				
			||||||
pub fn builder_set_cmd(
 | 
					pub fn builder_set_cmd(
 | 
				
			||||||
    builder: &mut Builder,
 | 
					    builder: &mut Builder,
 | 
				
			||||||
    cmd: &str,
 | 
					    cmd: Array,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(builder.set_cmd(cmd))
 | 
					    let cmd_vec: Vec<String> = cmd
 | 
				
			||||||
 | 
					        .into_iter()
 | 
				
			||||||
 | 
					        .map(|item| item.into_string().unwrap_or_default())
 | 
				
			||||||
 | 
					        .collect();
 | 
				
			||||||
 | 
					    builder.set_cmd(cmd_vec).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Write content to a file in the container
 | 
					/// Write content to a file in the container
 | 
				
			||||||
@@ -197,11 +230,7 @@ pub fn builder_write_content(
 | 
				
			|||||||
    dest_path: &str,
 | 
					    dest_path: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    if let Some(container_id) = builder.container_id() {
 | 
					    if let Some(container_id) = builder.container_id() {
 | 
				
			||||||
        bah_error_to_rhai_error(ContentOperations::write_content(
 | 
					        ContentOperations::write_content(container_id, content, dest_path).map_err(Into::into)
 | 
				
			||||||
            container_id,
 | 
					 | 
				
			||||||
            content,
 | 
					 | 
				
			||||||
            dest_path,
 | 
					 | 
				
			||||||
        ))
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        Err(Box::new(EvalAltResult::ErrorRuntime(
 | 
					        Err(Box::new(EvalAltResult::ErrorRuntime(
 | 
				
			||||||
            "No container ID available".into(),
 | 
					            "No container ID available".into(),
 | 
				
			||||||
@@ -216,7 +245,7 @@ pub fn builder_read_content(
 | 
				
			|||||||
    source_path: &str,
 | 
					    source_path: &str,
 | 
				
			||||||
) -> Result<String, Box<EvalAltResult>> {
 | 
					) -> Result<String, Box<EvalAltResult>> {
 | 
				
			||||||
    if let Some(container_id) = builder.container_id() {
 | 
					    if let Some(container_id) = builder.container_id() {
 | 
				
			||||||
        bah_error_to_rhai_error(ContentOperations::read_content(container_id, source_path))
 | 
					        ContentOperations::read_content(container_id, source_path).map_err(Into::into)
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        Err(Box::new(EvalAltResult::ErrorRuntime(
 | 
					        Err(Box::new(EvalAltResult::ErrorRuntime(
 | 
				
			||||||
            "No container ID available".into(),
 | 
					            "No container ID available".into(),
 | 
				
			||||||
@@ -227,7 +256,7 @@ pub fn builder_read_content(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Builder static methods
 | 
					// Builder static methods
 | 
				
			||||||
pub fn builder_images(_builder: &mut Builder) -> Result<Array, Box<EvalAltResult>> {
 | 
					pub fn builder_images(_builder: &mut Builder) -> Result<Array, Box<EvalAltResult>> {
 | 
				
			||||||
    let images = bah_error_to_rhai_error(Builder::images())?;
 | 
					    let images = Builder::images()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Convert Vec<Image> to Rhai Array
 | 
					    // Convert Vec<Image> to Rhai Array
 | 
				
			||||||
    let mut array = Array::new();
 | 
					    let mut array = Array::new();
 | 
				
			||||||
@@ -242,7 +271,7 @@ pub fn builder_image_remove(
 | 
				
			|||||||
    _builder: &mut Builder,
 | 
					    _builder: &mut Builder,
 | 
				
			||||||
    image: &str,
 | 
					    image: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(Builder::image_remove(image))
 | 
					    Builder::image_remove(image).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn builder_image_pull(
 | 
					pub fn builder_image_pull(
 | 
				
			||||||
@@ -250,7 +279,7 @@ pub fn builder_image_pull(
 | 
				
			|||||||
    image: &str,
 | 
					    image: &str,
 | 
				
			||||||
    tls_verify: bool,
 | 
					    tls_verify: bool,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(Builder::image_pull(image, tls_verify))
 | 
					    Builder::image_pull(image, tls_verify).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn builder_image_push(
 | 
					pub fn builder_image_push(
 | 
				
			||||||
@@ -259,7 +288,7 @@ pub fn builder_image_push(
 | 
				
			|||||||
    destination: &str,
 | 
					    destination: &str,
 | 
				
			||||||
    tls_verify: bool,
 | 
					    tls_verify: bool,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(Builder::image_push(image, destination, tls_verify))
 | 
					    Builder::image_push(image, destination, tls_verify).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn builder_image_tag(
 | 
					pub fn builder_image_tag(
 | 
				
			||||||
@@ -267,7 +296,7 @@ pub fn builder_image_tag(
 | 
				
			|||||||
    image: &str,
 | 
					    image: &str,
 | 
				
			||||||
    new_name: &str,
 | 
					    new_name: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(Builder::image_tag(image, new_name))
 | 
					    Builder::image_tag(image, new_name).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Getter functions for Builder properties
 | 
					// Getter functions for Builder properties
 | 
				
			||||||
@@ -298,7 +327,7 @@ pub fn set_builder_debug(builder: &mut Builder, debug: bool) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Reset function for Builder
 | 
					// Reset function for Builder
 | 
				
			||||||
pub fn builder_reset(builder: &mut Builder) -> Result<(), Box<EvalAltResult>> {
 | 
					pub fn builder_reset(builder: &mut Builder) -> Result<(), Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(builder.reset())
 | 
					    builder.reset().map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Build function for Builder
 | 
					// Build function for Builder
 | 
				
			||||||
@@ -309,10 +338,5 @@ pub fn builder_build(
 | 
				
			|||||||
    file: &str,
 | 
					    file: &str,
 | 
				
			||||||
    isolation: &str,
 | 
					    isolation: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    bah_error_to_rhai_error(Builder::build(
 | 
					    Builder::build(Some(tag), context_dir, file, Some(isolation)).map_err(Into::into)
 | 
				
			||||||
        Some(tag),
 | 
					 | 
				
			||||||
        context_dir,
 | 
					 | 
				
			||||||
        file,
 | 
					 | 
				
			||||||
        Some(isolation),
 | 
					 | 
				
			||||||
    ))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,38 +2,37 @@
 | 
				
			|||||||
//!
 | 
					//!
 | 
				
			||||||
//! 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 crate::nerdctl::{self, Container, Image, NerdctlError};
 | 
					use crate::nerdctl::{self, Container, HealthCheck, Image, NerdctlError};
 | 
				
			||||||
use rhai::{Array, Dynamic, Engine, EvalAltResult, Map};
 | 
					use rhai::{Array, Dynamic, Engine, EvalAltResult, Map};
 | 
				
			||||||
use sal_process::CommandResult;
 | 
					use sal_process::CommandResult;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Helper functions for error conversion with improved context
 | 
					// Helper functions for error conversion with improved context
 | 
				
			||||||
fn nerdctl_error_to_rhai_error<T>(
 | 
					impl From<NerdctlError> for Box<EvalAltResult> {
 | 
				
			||||||
    result: Result<T, NerdctlError>,
 | 
					    fn from(err: NerdctlError) -> Self {
 | 
				
			||||||
) -> Result<T, Box<EvalAltResult>> {
 | 
					        let error_message = match err {
 | 
				
			||||||
    result.map_err(|e| {
 | 
					            NerdctlError::CommandExecutionFailed(io_err) => format!(
 | 
				
			||||||
        // Create a more detailed error message based on the error type
 | 
					                "Failed to execute nerdctl command: {}. This may indicate nerdctl is not installed or not in PATH.",
 | 
				
			||||||
        let error_message = match &e {
 | 
					                io_err
 | 
				
			||||||
            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.",
 | 
				
			||||||
            NerdctlError::CommandFailed(msg) => {
 | 
					                msg
 | 
				
			||||||
                format!("Nerdctl command failed: {}. Check container status and logs for more details.", msg)
 | 
					            ),
 | 
				
			||||||
            },
 | 
					            NerdctlError::JsonParseError(msg) => format!(
 | 
				
			||||||
            NerdctlError::JsonParseError(msg) => {
 | 
					                "Failed to parse nerdctl JSON output: {}. This may indicate an incompatible nerdctl version.",
 | 
				
			||||||
                format!("Failed to parse nerdctl JSON output: {}. This may indicate an incompatible nerdctl version.", msg)
 | 
					                msg
 | 
				
			||||||
            },
 | 
					            ),
 | 
				
			||||||
            NerdctlError::ConversionError(msg) => {
 | 
					            NerdctlError::ConversionError(msg) => format!(
 | 
				
			||||||
                format!("Data conversion error: {}. This may indicate unexpected output format from nerdctl.", msg)
 | 
					                "Data conversion error: {}. This may indicate unexpected output format from nerdctl.",
 | 
				
			||||||
            },
 | 
					                msg
 | 
				
			||||||
            NerdctlError::Other(msg) => {
 | 
					            ),
 | 
				
			||||||
                format!("Nerdctl error: {}. This is an unexpected error.", msg)
 | 
					            NerdctlError::Other(msg) => format!("Nerdctl error: {}. This is an unexpected error.", msg),
 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        Box::new(EvalAltResult::ErrorRuntime(
 | 
					        Box::new(EvalAltResult::ErrorRuntime(
 | 
				
			||||||
            error_message.into(),
 | 
					            error_message.into(),
 | 
				
			||||||
            rhai::Position::NONE
 | 
					            rhai::Position::NONE,
 | 
				
			||||||
        ))
 | 
					        ))
 | 
				
			||||||
    })
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@@ -42,12 +41,7 @@ fn nerdctl_error_to_rhai_error<T>(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// Create a new Container
 | 
					/// Create a new Container
 | 
				
			||||||
pub fn container_new(name: &str) -> Result<Container, Box<EvalAltResult>> {
 | 
					pub fn container_new(name: &str) -> Result<Container, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(Container::new(name))
 | 
					    Container::new(name).map_err(Into::into)
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// 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
 | 
					/// Reset the container configuration to defaults while keeping the name and image
 | 
				
			||||||
@@ -55,127 +49,10 @@ pub fn container_reset(container: Container) -> Container {
 | 
				
			|||||||
    container.reset()
 | 
					    container.reset()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Add a port mapping to a Container
 | 
					pub fn health_check_new(cmd: &str) -> Result<HealthCheck, Box<EvalAltResult>> {
 | 
				
			||||||
pub fn container_with_port(container: Container, port: &str) -> Container {
 | 
					    let health_check = HealthCheck::new(cmd);
 | 
				
			||||||
    container.with_port(port)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Add a volume mount to a Container
 | 
					    Ok(health_check)
 | 
				
			||||||
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
 | 
					/// Build and run the Container
 | 
				
			||||||
@@ -242,7 +119,7 @@ pub fn container_build(container: Container) -> Result<Container, Box<EvalAltRes
 | 
				
			|||||||
                _ => err,
 | 
					                _ => err,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            nerdctl_error_to_rhai_error(Err(enhanced_error))
 | 
					            Err(enhanced_error.into())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -299,19 +176,19 @@ pub fn container_start(container: &mut Container) -> Result<CommandResult, Box<E
 | 
				
			|||||||
                _ => err,
 | 
					                _ => err,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            nerdctl_error_to_rhai_error(Err(enhanced_error))
 | 
					            Err(enhanced_error.into())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Stop the Container
 | 
					/// Stop the Container
 | 
				
			||||||
pub fn container_stop(container: &mut Container) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn container_stop(container: &mut Container) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(container.stop())
 | 
					    container.stop().map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Remove the Container
 | 
					/// Remove the Container
 | 
				
			||||||
pub fn container_remove(container: &mut Container) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn container_remove(container: &mut Container) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(container.remove())
 | 
					    container.remove().map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Execute a command in the Container
 | 
					/// Execute a command in the Container
 | 
				
			||||||
@@ -319,7 +196,7 @@ pub fn container_exec(
 | 
				
			|||||||
    container: &mut Container,
 | 
					    container: &mut Container,
 | 
				
			||||||
    command: &str,
 | 
					    command: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(container.exec(command))
 | 
					    container.exec(command).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Get container logs
 | 
					/// Get container logs
 | 
				
			||||||
@@ -343,7 +220,7 @@ pub fn container_logs(container: &mut Container) -> Result<CommandResult, Box<Ev
 | 
				
			|||||||
                container_name, container_id, err
 | 
					                container_name, container_id, err
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            nerdctl_error_to_rhai_error(Err(enhanced_error))
 | 
					            Err(enhanced_error.into())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -354,7 +231,7 @@ pub fn container_copy(
 | 
				
			|||||||
    source: &str,
 | 
					    source: &str,
 | 
				
			||||||
    dest: &str,
 | 
					    dest: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(container.copy(source, dest))
 | 
					    container.copy(source, dest).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Create a new Map with default run options
 | 
					/// Create a new Map with default run options
 | 
				
			||||||
@@ -375,12 +252,12 @@ pub fn new_run_options() -> Map {
 | 
				
			|||||||
///
 | 
					///
 | 
				
			||||||
/// Run a container from an image.
 | 
					/// Run a container from an image.
 | 
				
			||||||
pub fn nerdctl_run(image: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn nerdctl_run(image: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::run(image, None, true, None, None))
 | 
					    nerdctl::run(image, None, true, None, None).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Run a container with a name
 | 
					/// Run a container with a name
 | 
				
			||||||
pub fn nerdctl_run_with_name(image: &str, name: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					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))
 | 
					    nerdctl::run(image, Some(name), true, None, None).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Run a container with a port mapping
 | 
					/// Run a container with a port mapping
 | 
				
			||||||
@@ -390,49 +267,49 @@ pub fn nerdctl_run_with_port(
 | 
				
			|||||||
    port: &str,
 | 
					    port: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    let ports = vec![port];
 | 
					    let ports = vec![port];
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::run(image, Some(name), true, Some(&ports), None))
 | 
					    nerdctl::run(image, Some(name), true, Some(&ports), None).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wrapper for nerdctl::exec
 | 
					/// Wrapper for nerdctl::exec
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Execute a command in a container.
 | 
					/// Execute a command in a container.
 | 
				
			||||||
pub fn nerdctl_exec(container: &str, command: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn nerdctl_exec(container: &str, command: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::exec(container, command))
 | 
					    nerdctl::exec(container, command).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wrapper for nerdctl::copy
 | 
					/// Wrapper for nerdctl::copy
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Copy files between container and local filesystem.
 | 
					/// Copy files between container and local filesystem.
 | 
				
			||||||
pub fn nerdctl_copy(source: &str, dest: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn nerdctl_copy(source: &str, dest: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::copy(source, dest))
 | 
					    nerdctl::copy(source, dest).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wrapper for nerdctl::stop
 | 
					/// Wrapper for nerdctl::stop
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Stop a container.
 | 
					/// Stop a container.
 | 
				
			||||||
pub fn nerdctl_stop(container: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn nerdctl_stop(container: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::stop(container))
 | 
					    nerdctl::stop(container).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wrapper for nerdctl::remove
 | 
					/// Wrapper for nerdctl::remove
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Remove a container.
 | 
					/// Remove a container.
 | 
				
			||||||
pub fn nerdctl_remove(container: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn nerdctl_remove(container: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::remove(container))
 | 
					    nerdctl::remove(container).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wrapper for nerdctl::list
 | 
					/// Wrapper for nerdctl::list
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// List containers.
 | 
					/// List containers.
 | 
				
			||||||
pub fn nerdctl_list(all: bool) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn nerdctl_list(all: bool) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::list(all))
 | 
					    nerdctl::list(all).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wrapper for nerdctl::logs
 | 
					/// Wrapper for nerdctl::logs
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Get container logs.
 | 
					/// Get container logs.
 | 
				
			||||||
pub fn nerdctl_logs(container: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn nerdctl_logs(container: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::logs(container))
 | 
					    nerdctl::logs(container).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@@ -443,14 +320,14 @@ pub fn nerdctl_logs(container: &str) -> Result<CommandResult, Box<EvalAltResult>
 | 
				
			|||||||
///
 | 
					///
 | 
				
			||||||
/// List images in local storage.
 | 
					/// List images in local storage.
 | 
				
			||||||
pub fn nerdctl_images() -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn nerdctl_images() -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::images())
 | 
					    nerdctl::images().map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wrapper for nerdctl::image_remove
 | 
					/// Wrapper for nerdctl::image_remove
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Remove one or more images.
 | 
					/// Remove one or more images.
 | 
				
			||||||
pub fn nerdctl_image_remove(image: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn nerdctl_image_remove(image: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::image_remove(image))
 | 
					    nerdctl::image_remove(image).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wrapper for nerdctl::image_push
 | 
					/// Wrapper for nerdctl::image_push
 | 
				
			||||||
@@ -460,21 +337,21 @@ pub fn nerdctl_image_push(
 | 
				
			|||||||
    image: &str,
 | 
					    image: &str,
 | 
				
			||||||
    destination: &str,
 | 
					    destination: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::image_push(image, destination))
 | 
					    nerdctl::image_push(image, destination).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wrapper for nerdctl::image_tag
 | 
					/// Wrapper for nerdctl::image_tag
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Add an additional name to a local image.
 | 
					/// Add an additional name to a local image.
 | 
				
			||||||
pub fn nerdctl_image_tag(image: &str, new_name: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					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))
 | 
					    nerdctl::image_tag(image, new_name).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wrapper for nerdctl::image_pull
 | 
					/// Wrapper for nerdctl::image_pull
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Pull an image from a registry.
 | 
					/// Pull an image from a registry.
 | 
				
			||||||
pub fn nerdctl_image_pull(image: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					pub fn nerdctl_image_pull(image: &str) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::image_pull(image))
 | 
					    nerdctl::image_pull(image).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wrapper for nerdctl::image_commit
 | 
					/// Wrapper for nerdctl::image_commit
 | 
				
			||||||
@@ -484,7 +361,7 @@ pub fn nerdctl_image_commit(
 | 
				
			|||||||
    container: &str,
 | 
					    container: &str,
 | 
				
			||||||
    image_name: &str,
 | 
					    image_name: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::image_commit(container, image_name))
 | 
					    nerdctl::image_commit(container, image_name).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wrapper for nerdctl::image_build
 | 
					/// Wrapper for nerdctl::image_build
 | 
				
			||||||
@@ -494,7 +371,7 @@ pub fn nerdctl_image_build(
 | 
				
			|||||||
    tag: &str,
 | 
					    tag: &str,
 | 
				
			||||||
    context_path: &str,
 | 
					    context_path: &str,
 | 
				
			||||||
) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
					) -> Result<CommandResult, Box<EvalAltResult>> {
 | 
				
			||||||
    nerdctl_error_to_rhai_error(nerdctl::image_build(tag, context_path))
 | 
					    nerdctl::image_build(tag, context_path).map_err(Into::into)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Register Nerdctl module functions with the Rhai engine
 | 
					/// Register Nerdctl module functions with the Rhai engine
 | 
				
			||||||
@@ -512,31 +389,13 @@ pub fn register_nerdctl_module(engine: &mut Engine) -> Result<(), Box<EvalAltRes
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Register Container constructor
 | 
					    // Register Container constructor
 | 
				
			||||||
    engine.register_fn("nerdctl_container_new", container_new);
 | 
					    engine.register_fn("nerdctl_container_new", container_new);
 | 
				
			||||||
    engine.register_fn("nerdctl_container_from_image", container_from_image);
 | 
					    
 | 
				
			||||||
 | 
					    // Register HealthCheck constructor
 | 
				
			||||||
 | 
					    engine.register_fn("health_check_new", health_check_new);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Register Container instance methods
 | 
					    // Register Container instance methods
 | 
				
			||||||
    engine.register_fn("reset", container_reset);
 | 
					    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("build", container_build);
 | 
				
			||||||
    engine.register_fn("start", container_start);
 | 
					    engine.register_fn("start", container_start);
 | 
				
			||||||
    engine.register_fn("stop", container_stop);
 | 
					    engine.register_fn("stop", container_stop);
 | 
				
			||||||
@@ -571,11 +430,18 @@ pub fn register_nerdctl_module(engine: &mut Engine) -> Result<(), Box<EvalAltRes
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// Register Nerdctl module types with the Rhai engine
 | 
					/// Register Nerdctl module types with the Rhai engine
 | 
				
			||||||
fn register_nerdctl_types(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
 | 
					fn register_nerdctl_types(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Register Container type
 | 
					    // Register Container type
 | 
				
			||||||
    engine.register_type_with_name::<Container>("NerdctlContainer");
 | 
					    engine.register_type_with_name::<Container>("NerdctlContainer");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Register getters for Container properties
 | 
					    // Register getters & setters for Container properties
 | 
				
			||||||
 | 
					    // -- name
 | 
				
			||||||
    engine.register_get("name", |container: &mut Container| container.name.clone());
 | 
					    engine.register_get("name", |container: &mut Container| container.name.clone());
 | 
				
			||||||
 | 
					    engine.register_set("image", |container: &mut Container, image: &str| {
 | 
				
			||||||
 | 
					        container.image = Some(image.to_string());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- container_id
 | 
				
			||||||
    engine.register_get(
 | 
					    engine.register_get(
 | 
				
			||||||
        "container_id",
 | 
					        "container_id",
 | 
				
			||||||
        |container: &mut Container| match &container.container_id {
 | 
					        |container: &mut Container| match &container.container_id {
 | 
				
			||||||
@@ -583,12 +449,37 @@ fn register_nerdctl_types(engine: &mut Engine) -> Result<(), Box<EvalAltResult>>
 | 
				
			|||||||
            None => "".to_string(),
 | 
					            None => "".to_string(),
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					    engine.register_set("container_id", |container: &mut Container, container_id: &str| {
 | 
				
			||||||
 | 
					        container.container_id = Some(container_id.to_string());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- image
 | 
				
			||||||
    engine.register_get("image", |container: &mut Container| {
 | 
					    engine.register_get("image", |container: &mut Container| {
 | 
				
			||||||
        match &container.image {
 | 
					        match &container.image {
 | 
				
			||||||
            Some(img) => img.clone(),
 | 
					            Some(img) => img.clone(),
 | 
				
			||||||
            None => "".to_string(),
 | 
					            None => "".to_string(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("image", |container: &mut Container, image: &str| {
 | 
				
			||||||
 | 
					        container.image = Some(image.to_string());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- config
 | 
				
			||||||
 | 
					    engine.register_get("config", |container: &mut Container| {
 | 
				
			||||||
 | 
					        container
 | 
				
			||||||
 | 
					            .config
 | 
				
			||||||
 | 
					            .iter()
 | 
				
			||||||
 | 
					            .map(|(k, v)| (k.clone().into(), v.clone().into()))
 | 
				
			||||||
 | 
					            .collect::<Map>()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("config", |container: &mut Container, config: Map| {
 | 
				
			||||||
 | 
					        container.config = config
 | 
				
			||||||
 | 
					            .into_iter()
 | 
				
			||||||
 | 
					            .map(|(k, v)| (k.to_string(), v.into_string().unwrap_or_default()))
 | 
				
			||||||
 | 
					            .collect();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- ports
 | 
				
			||||||
    engine.register_get("ports", |container: &mut Container| {
 | 
					    engine.register_get("ports", |container: &mut Container| {
 | 
				
			||||||
        let mut array = Array::new();
 | 
					        let mut array = Array::new();
 | 
				
			||||||
        for port in &container.ports {
 | 
					        for port in &container.ports {
 | 
				
			||||||
@@ -596,6 +487,14 @@ fn register_nerdctl_types(engine: &mut Engine) -> Result<(), Box<EvalAltResult>>
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        array
 | 
					        array
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("ports", |container: &mut Container, ports: Array| {
 | 
				
			||||||
 | 
					        container.ports = ports
 | 
				
			||||||
 | 
					            .into_iter()
 | 
				
			||||||
 | 
					            .map(|v| v.into_string().unwrap_or_default())
 | 
				
			||||||
 | 
					            .collect();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- volumes
 | 
				
			||||||
    engine.register_get("volumes", |container: &mut Container| {
 | 
					    engine.register_get("volumes", |container: &mut Container| {
 | 
				
			||||||
        let mut array = Array::new();
 | 
					        let mut array = Array::new();
 | 
				
			||||||
        for volume in &container.volumes {
 | 
					        for volume in &container.volumes {
 | 
				
			||||||
@@ -603,11 +502,161 @@ fn register_nerdctl_types(engine: &mut Engine) -> Result<(), Box<EvalAltResult>>
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        array
 | 
					        array
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("volumes", |container: &mut Container, volumes: Array| {
 | 
				
			||||||
 | 
					        container.volumes = volumes
 | 
				
			||||||
 | 
					            .into_iter()
 | 
				
			||||||
 | 
					            .map(|v| v.into_string().unwrap_or_default())
 | 
				
			||||||
 | 
					            .collect();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- env_vars
 | 
				
			||||||
 | 
					    engine.register_get("env_vars", |container: &mut Container| {
 | 
				
			||||||
 | 
					        container
 | 
				
			||||||
 | 
					            .env_vars
 | 
				
			||||||
 | 
					            .iter()
 | 
				
			||||||
 | 
					            .map(|(k, v)| (k.clone().into(), v.clone().into()))
 | 
				
			||||||
 | 
					            .collect::<Map>()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("env_vars", |container: &mut Container, env_vars: Map| {
 | 
				
			||||||
 | 
					        container.env_vars = env_vars
 | 
				
			||||||
 | 
					            .into_iter()
 | 
				
			||||||
 | 
					            .map(|(k, v)| (k.to_string(), v.into_string().unwrap_or_default()))
 | 
				
			||||||
 | 
					            .collect();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- network
 | 
				
			||||||
 | 
					    engine.register_get("network", |container: &mut Container| {
 | 
				
			||||||
 | 
					        container.network.clone().unwrap_or_default()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("network", |container: &mut Container, network: &str| {
 | 
				
			||||||
 | 
					        container.network = Some(network.to_string());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- network_aliases
 | 
				
			||||||
 | 
					    engine.register_get("network_aliases", |container: &mut Container| {
 | 
				
			||||||
 | 
					        container
 | 
				
			||||||
 | 
					            .network_aliases
 | 
				
			||||||
 | 
					            .iter()
 | 
				
			||||||
 | 
					            .map(|alias| Dynamic::from(alias.clone()))
 | 
				
			||||||
 | 
					            .collect::<Array>()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set(
 | 
				
			||||||
 | 
					        "network_aliases",
 | 
				
			||||||
 | 
					        |container: &mut Container, aliases: Array| {
 | 
				
			||||||
 | 
					            container.network_aliases = aliases
 | 
				
			||||||
 | 
					                .into_iter()
 | 
				
			||||||
 | 
					                .map(|a| a.into_string().unwrap_or_default())
 | 
				
			||||||
 | 
					                .collect();
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- cpu_limit
 | 
				
			||||||
 | 
					    engine.register_get("cpu_limit", |container: &mut Container| {
 | 
				
			||||||
 | 
					        container.cpu_limit.clone().unwrap_or_default()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("cpu_limit", |container: &mut Container, limit: &str| {
 | 
				
			||||||
 | 
					        container.cpu_limit = Some(limit.to_string());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- memory_limit
 | 
				
			||||||
 | 
					    engine.register_get("memory_limit", |container: &mut Container| {
 | 
				
			||||||
 | 
					        container.memory_limit.clone().unwrap_or_default()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("memory_limit", |container: &mut Container, limit: &str| {
 | 
				
			||||||
 | 
					        container.memory_limit = Some(limit.to_string());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- memory_swap_limit
 | 
				
			||||||
 | 
					    engine.register_get("memory_swap_limit", |container: &mut Container| {
 | 
				
			||||||
 | 
					        container.memory_swap_limit.clone().unwrap_or_default()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set(
 | 
				
			||||||
 | 
					        "memory_swap_limit",
 | 
				
			||||||
 | 
					        |container: &mut Container, limit: &str| {
 | 
				
			||||||
 | 
					            container.memory_swap_limit = Some(limit.to_string());
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- cpu_shares
 | 
				
			||||||
 | 
					    engine.register_get("cpu_shares", |container: &mut Container| {
 | 
				
			||||||
 | 
					        container.cpu_shares.clone().unwrap_or_default()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("cpu_shares", |container: &mut Container, shares: &str| {
 | 
				
			||||||
 | 
					        container.cpu_shares = Some(shares.to_string());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- restart_policy
 | 
				
			||||||
 | 
					    engine.register_get("restart_policy", |container: &mut Container| {
 | 
				
			||||||
 | 
					        container.restart_policy.clone().unwrap_or_default()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set(
 | 
				
			||||||
 | 
					        "restart_policy",
 | 
				
			||||||
 | 
					        |container: &mut Container, policy: &str| {
 | 
				
			||||||
 | 
					            container.restart_policy = Some(policy.to_string());
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- health_check
 | 
				
			||||||
 | 
					    engine.register_type_with_name::<HealthCheck>("NerdctlHealthCheck");
 | 
				
			||||||
 | 
					    engine.register_get("health_check", |container: &mut Container| {
 | 
				
			||||||
 | 
					        if let Some(health_check) = container.health_check.clone() {
 | 
				
			||||||
 | 
					            Dynamic::from(health_check)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            Dynamic::UNIT
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set(
 | 
				
			||||||
 | 
					        "health_check",
 | 
				
			||||||
 | 
					        |container: &mut Container, health_check: HealthCheck| {
 | 
				
			||||||
 | 
					            container.health_check = Some(health_check);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    // Register getters & setters for HealthCheck properties
 | 
				
			||||||
 | 
					    engine.register_get("cmd", |hc: &mut HealthCheck| hc.cmd.clone());
 | 
				
			||||||
 | 
					    engine.register_set("cmd", |hc: &mut HealthCheck, cmd: &str| {
 | 
				
			||||||
 | 
					        hc.cmd = cmd.to_string();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_get("interval", |hc: &mut HealthCheck| {
 | 
				
			||||||
 | 
					        hc.interval.clone().unwrap_or_default()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("interval", |hc: &mut HealthCheck, interval: &str| {
 | 
				
			||||||
 | 
					        hc.interval = Some(interval.to_string());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_get("timeout", |hc: &mut HealthCheck| {
 | 
				
			||||||
 | 
					        hc.timeout.clone().unwrap_or_default()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("timeout", |hc: &mut HealthCheck, timeout: &str| {
 | 
				
			||||||
 | 
					        hc.timeout = Some(timeout.to_string());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_get("retries", |hc: &mut HealthCheck| {
 | 
				
			||||||
 | 
					        hc.retries.map_or(0, |r| r as i64)
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("retries", |hc: &mut HealthCheck, retries: i64| {
 | 
				
			||||||
 | 
					        hc.retries = Some(retries as u32);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_get("start_period", |hc: &mut HealthCheck| {
 | 
				
			||||||
 | 
					        hc.start_period.clone().unwrap_or_default()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("start_period", |hc: &mut HealthCheck, start_period: &str| {
 | 
				
			||||||
 | 
					        hc.start_period = Some(start_period.to_string());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- detach
 | 
				
			||||||
    engine.register_get("detach", |container: &mut Container| container.detach);
 | 
					    engine.register_get("detach", |container: &mut Container| container.detach);
 | 
				
			||||||
 | 
					    engine.register_set("detach", |container: &mut Container, detach: bool| {
 | 
				
			||||||
 | 
					        container.detach = detach;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -- snapshotter
 | 
				
			||||||
 | 
					    engine.register_get("snapshotter", |container: &mut Container| {
 | 
				
			||||||
 | 
					        container.snapshotter.clone().unwrap_or_default()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    engine.register_set("snapshotter", |container: &mut Container, snapshotter: &str| {
 | 
				
			||||||
 | 
					        container.snapshotter = Some(snapshotter.to_string());
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Register Image type and methods
 | 
					    // Register Image type and methods
 | 
				
			||||||
    engine.register_type_with_name::<Image>("NerdctlImage");
 | 
					    engine.register_type_with_name::<Image>("NerdctlImage");
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Register getters for Image properties
 | 
					    // Register getters for Image properties
 | 
				
			||||||
    engine.register_get("id", |img: &mut Image| img.id.clone());
 | 
					    engine.register_get("id", |img: &mut Image| img.id.clone());
 | 
				
			||||||
    engine.register_get("repository", |img: &mut Image| img.repository.clone());
 | 
					    engine.register_get("repository", |img: &mut Image| img.repository.clone());
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user