feat: reorganize examples and add signature support to JobBuilder
- Reorganized examples into osiris/, sal/, and utils/ folders - Moved hardcoded scripts to separate .rhai files - Added signature() method to JobBuilder for job signing - Updated OSIRIS context to use block_in_place instead of runtime - Removed runtime field from OsirisContext - Added typed save() methods for Note and Event objects - Updated all examples to use new structure and APIs
This commit is contained in:
		
							
								
								
									
										64
									
								
								examples/sal/scripts/_archive/03_process_management.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								examples/sal/scripts/_archive/03_process_management.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
// 03_process_management.rhai
 | 
			
		||||
// Demonstrates process management operations using SAL
 | 
			
		||||
 | 
			
		||||
// Check if common commands exist
 | 
			
		||||
println("Checking if common commands exist:");
 | 
			
		||||
let commands = ["ls", "echo", "cat", "grep"];
 | 
			
		||||
for cmd in commands {
 | 
			
		||||
    let exists = which(cmd);
 | 
			
		||||
    println(`  - ${cmd}: ${exists}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run a simple command
 | 
			
		||||
println("\nRunning a simple echo command:");
 | 
			
		||||
let echo_result = run_command("echo 'Hello from Rhai process management!'");
 | 
			
		||||
println(`Command output: ${echo_result.stdout}`);
 | 
			
		||||
// The CommandResult type doesn't have an exit_code property
 | 
			
		||||
println(`Success: ${echo_result.success}`);
 | 
			
		||||
 | 
			
		||||
// Run a command silently (no output to console)
 | 
			
		||||
println("\nRunning a command silently:");
 | 
			
		||||
let silent_result = run_silent("ls -la");
 | 
			
		||||
println(`Command success: ${silent_result.success}`);
 | 
			
		||||
println(`Command output length: ${silent_result.stdout.len()} characters`);
 | 
			
		||||
 | 
			
		||||
// Create custom run options
 | 
			
		||||
println("\nRunning a command with custom options:");
 | 
			
		||||
let options = new_run_options();
 | 
			
		||||
options["die"] = false;       // Don't return error if command fails
 | 
			
		||||
options["silent"] = true;     // Suppress output to stdout/stderr
 | 
			
		||||
options["async_exec"] = false; // Run synchronously
 | 
			
		||||
options["log"] = true;        // Log command execution
 | 
			
		||||
 | 
			
		||||
let custom_result = run("echo 'Custom options test'", options);
 | 
			
		||||
println(`Command success: ${custom_result.success}`);
 | 
			
		||||
println(`Command output: ${custom_result.stdout}`);
 | 
			
		||||
 | 
			
		||||
// List processes
 | 
			
		||||
println("\nListing processes (limited to 5):");
 | 
			
		||||
let processes = process_list("");
 | 
			
		||||
let count = 0;
 | 
			
		||||
for proc in processes {
 | 
			
		||||
    if count >= 5 {
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    // Just print the PID since we're not sure what other properties are available
 | 
			
		||||
    println(`  - PID: ${proc.pid}`);
 | 
			
		||||
    count += 1;
 | 
			
		||||
}
 | 
			
		||||
println(`Total processes: ${processes.len()}`);
 | 
			
		||||
 | 
			
		||||
// Run a command that will create a background process
 | 
			
		||||
// Note: This is just for demonstration, the process will be short-lived
 | 
			
		||||
println("\nRunning a background process:");
 | 
			
		||||
let bg_options = new_run_options();
 | 
			
		||||
bg_options["async_exec"] = true;
 | 
			
		||||
// Fix the command to avoid issues with shell interpretation
 | 
			
		||||
let bg_result = run("sleep 1", bg_options);
 | 
			
		||||
println("Background process started");
 | 
			
		||||
 | 
			
		||||
// Wait a moment to let the background process run
 | 
			
		||||
run_command("sleep 0.5");
 | 
			
		||||
println("Main script continuing while background process runs");
 | 
			
		||||
 | 
			
		||||
"Process management script completed successfully!"
 | 
			
		||||
							
								
								
									
										65
									
								
								examples/sal/scripts/_archive/06_file_read_write.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								examples/sal/scripts/_archive/06_file_read_write.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
// 06_file_read_write.rhai
 | 
			
		||||
// Demonstrates file read and write operations using SAL
 | 
			
		||||
 | 
			
		||||
// Create a test directory
 | 
			
		||||
let test_dir = "rhai_file_test_dir";
 | 
			
		||||
println(`Creating directory: ${test_dir}`);
 | 
			
		||||
let mkdir_result = mkdir(test_dir);
 | 
			
		||||
println(`Directory creation result: ${mkdir_result}`);
 | 
			
		||||
 | 
			
		||||
// Define file paths
 | 
			
		||||
let test_file = test_dir + "/test_file.txt";
 | 
			
		||||
let append_file = test_dir + "/append_file.txt";
 | 
			
		||||
 | 
			
		||||
// 1. Write to a file
 | 
			
		||||
println(`\n--- Writing to file: ${test_file} ---`);
 | 
			
		||||
let content = "This is the first line of text.\nThis is the second line of text.";
 | 
			
		||||
let write_result = file_write(test_file, content);
 | 
			
		||||
println(`Write result: ${write_result}`);
 | 
			
		||||
 | 
			
		||||
// 2. Read from a file
 | 
			
		||||
println(`\n--- Reading from file: ${test_file} ---`);
 | 
			
		||||
let read_content = file_read(test_file);
 | 
			
		||||
println("File content:");
 | 
			
		||||
println(read_content);
 | 
			
		||||
 | 
			
		||||
// 3. Append to a file
 | 
			
		||||
println(`\n--- Creating and appending to file: ${append_file} ---`);
 | 
			
		||||
// First create the file with initial content
 | 
			
		||||
let initial_content = "Initial content - line 1\nInitial content - line 2\n";
 | 
			
		||||
let create_result = file_write(append_file, initial_content);
 | 
			
		||||
println(`Create result: ${create_result}`);
 | 
			
		||||
 | 
			
		||||
// Now append to the file
 | 
			
		||||
let append_content = "Appended content - line 3\nAppended content - line 4\n";
 | 
			
		||||
let append_result = file_write_append(append_file, append_content);
 | 
			
		||||
println(`Append result: ${append_result}`);
 | 
			
		||||
 | 
			
		||||
// Read the appended file to verify
 | 
			
		||||
println(`\n--- Reading appended file: ${append_file} ---`);
 | 
			
		||||
let appended_content = file_read(append_file);
 | 
			
		||||
println("Appended file content:");
 | 
			
		||||
println(appended_content);
 | 
			
		||||
 | 
			
		||||
// 4. Demonstrate multiple appends
 | 
			
		||||
println(`\n--- Demonstrating multiple appends ---`);
 | 
			
		||||
for i in range(1, 4) {
 | 
			
		||||
    // Use a simple counter instead of timestamp to avoid issues
 | 
			
		||||
    let log_entry = `Log entry #${i} - appended at iteration ${i}\n`;
 | 
			
		||||
    file_write_append(append_file, log_entry);
 | 
			
		||||
    println(`Added log entry #${i}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Read the final file content
 | 
			
		||||
println(`\n--- Final file content after multiple appends ---`);
 | 
			
		||||
let final_content = file_read(append_file);
 | 
			
		||||
println(final_content);
 | 
			
		||||
 | 
			
		||||
// Clean up (uncomment to actually delete the files)
 | 
			
		||||
// println("\nCleaning up...");
 | 
			
		||||
// delete(test_file);
 | 
			
		||||
// delete(append_file);
 | 
			
		||||
// delete(test_dir);
 | 
			
		||||
// println("Cleanup complete");
 | 
			
		||||
 | 
			
		||||
"File read/write operations script completed successfully!"
 | 
			
		||||
							
								
								
									
										62
									
								
								examples/sal/scripts/_archive/container_example.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								examples/sal/scripts/_archive/container_example.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
// File: /root/code/git.threefold.info/herocode/sal/examples/container_example.rs
 | 
			
		||||
 | 
			
		||||
use std::error::Error;
 | 
			
		||||
use sal::virt::nerdctl::Container;
 | 
			
		||||
 | 
			
		||||
fn main() -> Result<(), Box<dyn Error>> {
 | 
			
		||||
    // Create a container from an image
 | 
			
		||||
    println!("Creating container from image...");
 | 
			
		||||
    let container = Container::from_image("my-nginx", "nginx:latest")?
 | 
			
		||||
        .with_port("8080:80")
 | 
			
		||||
        .with_env("NGINX_HOST", "example.com")
 | 
			
		||||
        .with_volume("/tmp/nginx:/usr/share/nginx/html")
 | 
			
		||||
        .with_health_check("curl -f http://localhost/ || exit 1")
 | 
			
		||||
        .with_detach(true)
 | 
			
		||||
        .build()?;
 | 
			
		||||
    
 | 
			
		||||
    println!("Container created successfully");
 | 
			
		||||
    
 | 
			
		||||
    // Execute a command in the container
 | 
			
		||||
    println!("Executing command in container...");
 | 
			
		||||
    let result = container.exec("echo 'Hello from container'")?;
 | 
			
		||||
    println!("Command output: {}", result.stdout);
 | 
			
		||||
    
 | 
			
		||||
    // Get container status
 | 
			
		||||
    println!("Getting container status...");
 | 
			
		||||
    let status = container.status()?;
 | 
			
		||||
    println!("Container status: {}", status.status);
 | 
			
		||||
    
 | 
			
		||||
    // Get resource usage
 | 
			
		||||
    println!("Getting resource usage...");
 | 
			
		||||
    let resources = container.resources()?;
 | 
			
		||||
    println!("CPU usage: {}", resources.cpu_usage);
 | 
			
		||||
    println!("Memory usage: {}", resources.memory_usage);
 | 
			
		||||
    
 | 
			
		||||
    // Stop and remove the container
 | 
			
		||||
    println!("Stopping and removing container...");
 | 
			
		||||
    container.stop()?;
 | 
			
		||||
    container.remove()?;
 | 
			
		||||
    
 | 
			
		||||
    println!("Container stopped and removed");
 | 
			
		||||
    
 | 
			
		||||
    // Get a container by name (if it exists)
 | 
			
		||||
    println!("\nGetting a container by name...");
 | 
			
		||||
    match Container::new("existing-container") {
 | 
			
		||||
        Ok(container) => {
 | 
			
		||||
            if container.container_id.is_some() {
 | 
			
		||||
                println!("Found container with ID: {}", container.container_id.as_ref().unwrap());
 | 
			
		||||
                
 | 
			
		||||
                // Perform operations on the existing container
 | 
			
		||||
                let status = container.status()?;
 | 
			
		||||
                println!("Container status: {}", status.status);
 | 
			
		||||
            } else {
 | 
			
		||||
                println!("Container exists but has no ID");
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            println!("Error getting container: {}", e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										210
									
								
								examples/sal/scripts/_archive/containerd_grpc_setup.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								examples/sal/scripts/_archive/containerd_grpc_setup.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,210 @@
 | 
			
		||||
// containerd_grpc_setup.rhai
 | 
			
		||||
//
 | 
			
		||||
// This script sets up a Rust project with gRPC connectivity to containerd
 | 
			
		||||
// Following the steps from the instructions document
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
run("apt-get -y protobuf-compiler ");
 | 
			
		||||
 | 
			
		||||
// Step 1: Set up project directory
 | 
			
		||||
let project_dir = "/tmp/containerd-rust-client";
 | 
			
		||||
print(`Setting up project in: ${project_dir}`);
 | 
			
		||||
 | 
			
		||||
// Clean up any existing directory
 | 
			
		||||
if exist(project_dir) {
 | 
			
		||||
    print("Found existing project directory, removing it...");
 | 
			
		||||
    delete(project_dir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create our project directory
 | 
			
		||||
mkdir(project_dir);
 | 
			
		||||
 | 
			
		||||
// Change to the project directory
 | 
			
		||||
chdir(project_dir);
 | 
			
		||||
 | 
			
		||||
// Step 2: Clone containerd's gRPC proto files
 | 
			
		||||
print("Cloning containerd repository to get proto files...");
 | 
			
		||||
let git_tree = gittree_new(project_dir);
 | 
			
		||||
let repos = git_tree.get("https://github.com/containerd/containerd.git");
 | 
			
		||||
let repo = repos[0];
 | 
			
		||||
print(`Cloned containerd repository to: ${repo.path()}`);
 | 
			
		||||
 | 
			
		||||
// Step 3: Create necessary project files
 | 
			
		||||
print("Creating Cargo.toml file...");
 | 
			
		||||
// Using raw string with # for multiline content
 | 
			
		||||
let cargo_toml = #"
 | 
			
		||||
[package]
 | 
			
		||||
name = "containerd-rust-client"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
tonic = "0.11"
 | 
			
		||||
prost = "0.12"
 | 
			
		||||
tokio = { version = "1", features = ["full"] }
 | 
			
		||||
hyper-unix-connector = "0.2.0"
 | 
			
		||||
tower = "0.4"
 | 
			
		||||
 | 
			
		||||
[build-dependencies]
 | 
			
		||||
tonic-build = "0.11"
 | 
			
		||||
"#;
 | 
			
		||||
 | 
			
		||||
file_write("Cargo.toml", cargo_toml);
 | 
			
		||||
print("Created Cargo.toml file");
 | 
			
		||||
 | 
			
		||||
// Step 4: Set up build.rs to compile protos
 | 
			
		||||
print("Creating build.rs file...");
 | 
			
		||||
let build_rs = #"
 | 
			
		||||
fn main() {
 | 
			
		||||
    println!("cargo:rerun-if-changed=containerd/api/services/images/v1/images.proto");
 | 
			
		||||
    println!("cargo:rerun-if-changed=containerd/api/services/containers/v1/containers.proto");
 | 
			
		||||
    
 | 
			
		||||
    tonic_build::configure()
 | 
			
		||||
        .build_server(false)
 | 
			
		||||
        .compile(
 | 
			
		||||
            &[
 | 
			
		||||
                "containerd/api/services/images/v1/images.proto", 
 | 
			
		||||
                "containerd/api/services/containers/v1/containers.proto",
 | 
			
		||||
                // Add more proto files as needed
 | 
			
		||||
            ],
 | 
			
		||||
            &[
 | 
			
		||||
                "containerd", 
 | 
			
		||||
                "containerd/api", 
 | 
			
		||||
                "containerd/api/types"
 | 
			
		||||
            ],
 | 
			
		||||
        )
 | 
			
		||||
        .unwrap();
 | 
			
		||||
}
 | 
			
		||||
"#;
 | 
			
		||||
 | 
			
		||||
file_write("build.rs", build_rs);
 | 
			
		||||
print("Created build.rs file");
 | 
			
		||||
 | 
			
		||||
// Step 5: Create src directory and main.rs file
 | 
			
		||||
mkdir("src");
 | 
			
		||||
 | 
			
		||||
// Create a helper function for Unix socket connection
 | 
			
		||||
print("Creating src/main.rs file...");
 | 
			
		||||
let main_rs = #"
 | 
			
		||||
use tonic::transport::{Channel, Endpoint, Uri};
 | 
			
		||||
use tower::service_fn;
 | 
			
		||||
use std::convert::TryFrom;
 | 
			
		||||
 | 
			
		||||
// The proto-generated modules will be available after build
 | 
			
		||||
// use containerd::services::images::v1::{
 | 
			
		||||
//     images_client::ImagesClient,
 | 
			
		||||
//     GetImageRequest,
 | 
			
		||||
// };
 | 
			
		||||
 | 
			
		||||
#[tokio::main]
 | 
			
		||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
 | 
			
		||||
    println!("Connecting to containerd gRPC...");
 | 
			
		||||
    
 | 
			
		||||
    // Path to containerd socket
 | 
			
		||||
    let socket_path = "/run/containerd/containerd.sock";
 | 
			
		||||
    
 | 
			
		||||
    // Connect to the Unix socket
 | 
			
		||||
    let channel = unix_socket_channel(socket_path).await?;
 | 
			
		||||
    
 | 
			
		||||
    // Now we'd create a client and use it
 | 
			
		||||
    // let mut client = ImagesClient::new(channel);
 | 
			
		||||
    // let response = client.get(GetImageRequest {
 | 
			
		||||
    //     name: "docker.io/library/ubuntu:latest".to_string(),
 | 
			
		||||
    // }).await?;
 | 
			
		||||
    // println!("Image: {:?}", response.into_inner());
 | 
			
		||||
    
 | 
			
		||||
    println!("Connection to containerd socket established successfully!");
 | 
			
		||||
    println!("This is a template - uncomment the client code after building.");
 | 
			
		||||
    
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Helper function to connect to Unix socket
 | 
			
		||||
async fn unix_socket_channel(path: &str) -> Result<Channel, Box<dyn std::error::Error>> {
 | 
			
		||||
    // Use a placeholder URI since Unix sockets don't have URIs
 | 
			
		||||
    let endpoint = Endpoint::try_from("http://[::]:50051")?;
 | 
			
		||||
    
 | 
			
		||||
    // The socket path to connect to
 | 
			
		||||
    let path_to_connect = path.to_string();
 | 
			
		||||
    
 | 
			
		||||
    // Create a connector function that connects to the Unix socket
 | 
			
		||||
    let channel = endpoint
 | 
			
		||||
        .connect_with_connector(service_fn(move |_: Uri| {
 | 
			
		||||
            let path = path_to_connect.clone();
 | 
			
		||||
            async move {
 | 
			
		||||
                tokio::net::UnixStream::connect(path)
 | 
			
		||||
                    .await
 | 
			
		||||
                    .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))
 | 
			
		||||
            }
 | 
			
		||||
        }))
 | 
			
		||||
        .await?;
 | 
			
		||||
    
 | 
			
		||||
    Ok(channel)
 | 
			
		||||
}
 | 
			
		||||
"#;
 | 
			
		||||
 | 
			
		||||
file_write("src/main.rs", main_rs);
 | 
			
		||||
print("Created src/main.rs file");
 | 
			
		||||
 | 
			
		||||
// Step 6: Create a README.md file
 | 
			
		||||
print("Creating README.md file...");
 | 
			
		||||
// Using raw string with # for multiline content containing markdown backticks
 | 
			
		||||
let readme = #"# containerd Rust gRPC Client
 | 
			
		||||
 | 
			
		||||
A Rust client for interacting with containerd via gRPC.
 | 
			
		||||
 | 
			
		||||
## Prerequisites
 | 
			
		||||
 | 
			
		||||
- Rust and Cargo installed
 | 
			
		||||
- containerd running on your system
 | 
			
		||||
 | 
			
		||||
## Building
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
cargo build
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Running
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
cargo run
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Features
 | 
			
		||||
 | 
			
		||||
- Connect to containerd via Unix socket
 | 
			
		||||
- Query image information
 | 
			
		||||
- Work with containers
 | 
			
		||||
 | 
			
		||||
## Structure
 | 
			
		||||
 | 
			
		||||
- `src/main.rs` - Example client code
 | 
			
		||||
- `build.rs` - Proto compilation script
 | 
			
		||||
"#;
 | 
			
		||||
 | 
			
		||||
file_write("README.md", readme);
 | 
			
		||||
print("Created README.md file");
 | 
			
		||||
 | 
			
		||||
// Step 7: Build the project
 | 
			
		||||
print("Building the project...");
 | 
			
		||||
let build_result = run("cargo build");
 | 
			
		||||
 | 
			
		||||
if build_result.success {
 | 
			
		||||
    print("Project built successfully!");
 | 
			
		||||
} else {
 | 
			
		||||
    print(`Build failed with error: ${build_result.stderr}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
print(`
 | 
			
		||||
--------------------------------------
 | 
			
		||||
🎉 Setup complete!
 | 
			
		||||
 | 
			
		||||
Project created at: ${project_dir}
 | 
			
		||||
 | 
			
		||||
To use the project:
 | 
			
		||||
1. cd ${project_dir}
 | 
			
		||||
2. cargo run
 | 
			
		||||
 | 
			
		||||
Note: Make sure containerd is running and the socket exists at /run/containerd/containerd.sock
 | 
			
		||||
--------------------------------------
 | 
			
		||||
`);
 | 
			
		||||
							
								
								
									
										105
									
								
								examples/sal/scripts/_archive/download_test.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								examples/sal/scripts/_archive/download_test.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
 | 
			
		||||
print("\n=== Test download() Functionality ===");
 | 
			
		||||
 | 
			
		||||
// Create test directory
 | 
			
		||||
let download_dir = "/tmp/downloadtest";
 | 
			
		||||
 | 
			
		||||
// Clean up any previous test files
 | 
			
		||||
delete(download_dir);
 | 
			
		||||
mkdir(download_dir);
 | 
			
		||||
print("Created test directory for downloads at " + download_dir);
 | 
			
		||||
 | 
			
		||||
// Test URLs
 | 
			
		||||
let zip_url = "https://github.com/freeflowuniverse/herolib/archive/refs/tags/v1.0.24.zip";
 | 
			
		||||
let targz_url = "https://github.com/freeflowuniverse/herolib/archive/refs/tags/v1.0.24.tar.gz";
 | 
			
		||||
let binary_url = "https://github.com/freeflowuniverse/herolib/releases/download/v1.0.24/hero-aarch64-unknown-linux-musl";
 | 
			
		||||
 | 
			
		||||
// Create destinations
 | 
			
		||||
let zip_dest = `${download_dir}/zip`;
 | 
			
		||||
let targz_dest = `${download_dir}/targz`;
 | 
			
		||||
let binary_dest = `${download_dir}/hero-binary`;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//PART 1
 | 
			
		||||
 | 
			
		||||
// Download and extract .zip file
 | 
			
		||||
print("\nTesting .zip download:");
 | 
			
		||||
// Download function now extracts zip files automatically
 | 
			
		||||
let result = download(zip_url, zip_dest, 0);
 | 
			
		||||
 | 
			
		||||
// Check if files were extracted
 | 
			
		||||
let file_count = find_files(zip_dest, "*").len();
 | 
			
		||||
print(`  Files found after extraction: ${file_count}`);
 | 
			
		||||
let success_msg = if file_count > 0 { "yes" } else { "no" };
 | 
			
		||||
print(`  Extraction successful: ${success_msg}`);
 | 
			
		||||
 | 
			
		||||
//PART 2
 | 
			
		||||
 | 
			
		||||
// Download and extract .tar.gz file
 | 
			
		||||
print("\nTesting .tar.gz download:");
 | 
			
		||||
let result = download(targz_url, targz_dest, 0);
 | 
			
		||||
 | 
			
		||||
// Check if files were extracted (download function should extract tar.gz automatically)
 | 
			
		||||
let file_count = find_files(targz_dest, "*").len();
 | 
			
		||||
print(`  Files found after extraction: ${file_count}`);
 | 
			
		||||
let success_msg = if file_count > 100 { "yes" } else { "no" };
 | 
			
		||||
print(`  Extraction successful: ${success_msg}`);
 | 
			
		||||
 | 
			
		||||
//PART 3
 | 
			
		||||
 | 
			
		||||
// Download binary file and check size
 | 
			
		||||
print("\nTesting binary download:");
 | 
			
		||||
download_file(binary_url, binary_dest, 8000);
 | 
			
		||||
 | 
			
		||||
// Check file size using our new file_size function
 | 
			
		||||
let size_bytes = file_size(binary_dest);
 | 
			
		||||
let size_mb = size_bytes / (1024 * 1024);
 | 
			
		||||
print(`  File size: ${size_mb} MB`);
 | 
			
		||||
let size_check = if size_mb > 5 { "yes" } else { "no" };
 | 
			
		||||
print(`  Size > 5MB: ${size_check}`);
 | 
			
		||||
let success_msg = if size_mb >= 8 > 100 { "yes" } else { "no" };
 | 
			
		||||
print(`  Minimum size check passed:${success_msg}`);
 | 
			
		||||
 | 
			
		||||
// Clean up test files
 | 
			
		||||
delete(download_dir);
 | 
			
		||||
print("Cleaned up test directory");
 | 
			
		||||
//PART 4
 | 
			
		||||
 | 
			
		||||
// Test the new download_file function
 | 
			
		||||
print("\nTesting download_file function:");
 | 
			
		||||
let text_url = "https://raw.githubusercontent.com/freeflowuniverse/herolib/main/README.md";
 | 
			
		||||
let text_file_dest = `${download_dir}/README.md`;
 | 
			
		||||
 | 
			
		||||
// Create the directory again for this test
 | 
			
		||||
mkdir(download_dir);
 | 
			
		||||
 | 
			
		||||
// Download a text file using the new download_file function
 | 
			
		||||
let file_result = download_file(text_url, text_file_dest, 0);
 | 
			
		||||
print(`  File downloaded to: ${file_result}`);
 | 
			
		||||
 | 
			
		||||
// Check if the file exists and has content
 | 
			
		||||
let file_exists = exist(text_file_dest);
 | 
			
		||||
print(`  File exists: ${file_exists}`);
 | 
			
		||||
let file_content = file_read(text_file_dest);
 | 
			
		||||
let content_check = if file_content.len() > 100 { "yes" } else { "no" };
 | 
			
		||||
print(`  File has content: ${content_check}`);
 | 
			
		||||
 | 
			
		||||
//PART 5
 | 
			
		||||
 | 
			
		||||
// Test the new chmod_exec function
 | 
			
		||||
print("\nTesting chmod_exec function:");
 | 
			
		||||
// Create a simple shell script
 | 
			
		||||
let script_path = `${download_dir}/test_script.sh`;
 | 
			
		||||
file_write(script_path, "#!/bin/sh\necho 'Hello from test script'");
 | 
			
		||||
 | 
			
		||||
// Make it executable
 | 
			
		||||
let chmod_result = chmod_exec(script_path);
 | 
			
		||||
print(`  ${chmod_result}`);
 | 
			
		||||
 | 
			
		||||
// Clean up test files again
 | 
			
		||||
delete(download_dir);
 | 
			
		||||
print("Cleaned up test directory");
 | 
			
		||||
 | 
			
		||||
print("\nAll Download Tests completed successfully!");
 | 
			
		||||
"Download Tests Success"
 | 
			
		||||
"Download Tests Success"
 | 
			
		||||
							
								
								
									
										217
									
								
								examples/sal/scripts/_archive/fs_test.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								examples/sal/scripts/_archive/fs_test.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,217 @@
 | 
			
		||||
// Comprehensive file system operations test script with assertions
 | 
			
		||||
 | 
			
		||||
print("===== File System Operations Test =====");
 | 
			
		||||
 | 
			
		||||
// Helper functions for testing
 | 
			
		||||
fn assert(condition, message) {
 | 
			
		||||
    if (condition == false) {
 | 
			
		||||
        print(`FAILED: ${message}`);
 | 
			
		||||
        throw `Assertion failed: ${message}`;
 | 
			
		||||
    } else {
 | 
			
		||||
        print(`PASSED: ${message}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn assert_equal(actual, expected, message) {
 | 
			
		||||
    // Convert numbers to strings before comparison to avoid type issues
 | 
			
		||||
    let actual_str = actual.to_string();
 | 
			
		||||
    let expected_str = expected.to_string();
 | 
			
		||||
    
 | 
			
		||||
    if (actual_str != expected_str) {
 | 
			
		||||
        print(`FAILED: ${message} - Expected '${expected}', got '${actual}'`);
 | 
			
		||||
        throw `Assertion failed: ${message}`;
 | 
			
		||||
    } else {
 | 
			
		||||
        print(`PASSED: ${message}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn assert_true(value, message) {
 | 
			
		||||
    assert(value, message);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn assert_false(value, message) {
 | 
			
		||||
    assert(value == false, message);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Directory for tests
 | 
			
		||||
let test_dir = "/tmp/herodo_test_fs";
 | 
			
		||||
let tests_total = 0;
 | 
			
		||||
 | 
			
		||||
// Setup - create test directory
 | 
			
		||||
print("\n=== Setup ===");
 | 
			
		||||
if exist(test_dir) {
 | 
			
		||||
    print(`Test directory exists, removing it first...`);
 | 
			
		||||
    let result = delete(test_dir);
 | 
			
		||||
    // Function will throw an error if it fails
 | 
			
		||||
    assert_false(exist(test_dir), "Test directory should not exist after deletion");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test mkdir
 | 
			
		||||
print("\n=== Test mkdir() ===");
 | 
			
		||||
print(`Creating test directory: ${test_dir}`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
let mkdir_result = mkdir(test_dir);
 | 
			
		||||
// Now can directly use the returned success message
 | 
			
		||||
assert_true(exist(test_dir), "Test directory should exist after creation");
 | 
			
		||||
 | 
			
		||||
// Test mkdir with nested paths
 | 
			
		||||
print(`Creating nested directory: ${test_dir}/subdir/nested`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
let nested_result = mkdir(`${test_dir}/subdir/nested`);
 | 
			
		||||
assert_true(exist(`${test_dir}/subdir/nested`), "Nested directory should exist after creation");
 | 
			
		||||
 | 
			
		||||
// Test duplicate mkdir (should not error)
 | 
			
		||||
print(`Creating existing directory again: ${test_dir}`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
let duplicate_result = mkdir(test_dir);
 | 
			
		||||
// This should just return a message that directory already exists
 | 
			
		||||
 | 
			
		||||
// Test file creation using run
 | 
			
		||||
print("\n=== Test file creation ===");
 | 
			
		||||
let file1 = `${test_dir}/file1.txt`;
 | 
			
		||||
let file2 = `${test_dir}/file2.txt`;
 | 
			
		||||
let file3 = `${test_dir}/subdir/file3.txt`;
 | 
			
		||||
 | 
			
		||||
// Create files
 | 
			
		||||
print(`Creating test files...`);
 | 
			
		||||
let touch_cmd = `touch ${file1} ${file2} ${file3}`;
 | 
			
		||||
let touch_result = run(touch_cmd);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(touch_result.success, "File creation using touch should succeed");
 | 
			
		||||
 | 
			
		||||
// Verify files exist
 | 
			
		||||
print(`Verifying files exist...`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(exist(file1), "File 1 should exist after creation");
 | 
			
		||||
assert_true(exist(file2), "File 2 should exist after creation");
 | 
			
		||||
assert_true(exist(file3), "File 3 should exist after creation");
 | 
			
		||||
print("All test files were created successfully");
 | 
			
		||||
 | 
			
		||||
// Test copy
 | 
			
		||||
print("\n=== Test copy() ===");
 | 
			
		||||
let copy_file = `${test_dir}/file1_copy.txt`;
 | 
			
		||||
print(`Copying ${file1} to ${copy_file}`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
let copy_result = copy(file1, copy_file);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(exist(copy_file), "Copied file should exist");
 | 
			
		||||
 | 
			
		||||
// Test directory copy
 | 
			
		||||
print(`Copying directory ${test_dir}/subdir to ${test_dir}/subdir_copy`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
let dir_copy_result = copy(`${test_dir}/subdir`, `${test_dir}/subdir_copy`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(exist(`${test_dir}/subdir_copy`), "Copied directory should exist");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(exist(`${test_dir}/subdir_copy/file3.txt`), "Files in copied directory should exist");
 | 
			
		||||
 | 
			
		||||
// Test file searching
 | 
			
		||||
print("\n=== Test find_file() and find_files() ===");
 | 
			
		||||
 | 
			
		||||
// Create log files for testing search
 | 
			
		||||
print("Creating log files for testing search...");
 | 
			
		||||
let log_file1 = `${test_dir}/subdir/test1.log`;
 | 
			
		||||
let log_file2 = `${test_dir}/subdir/test2.log`;
 | 
			
		||||
let log_file3 = `${test_dir}/subdir_copy/test3.log`;
 | 
			
		||||
let log_touch_cmd = `touch ${log_file1} ${log_file2} ${log_file3}`;
 | 
			
		||||
let log_touch_result = run(log_touch_cmd);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(log_touch_result.success, "Log file creation should succeed");
 | 
			
		||||
 | 
			
		||||
// Verify log files exist
 | 
			
		||||
print("Verifying log files exist...");
 | 
			
		||||
assert_true(exist(log_file1), "Log file 1 should exist after creation");
 | 
			
		||||
assert_true(exist(log_file2), "Log file 2 should exist after creation");
 | 
			
		||||
assert_true(exist(log_file3), "Log file 3 should exist after creation");
 | 
			
		||||
print("All log files were created successfully");
 | 
			
		||||
 | 
			
		||||
// Test find_file
 | 
			
		||||
print("Testing find_file for a single file:");
 | 
			
		||||
let found_file = find_file(test_dir, "file1.txt");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(found_file.to_string().contains("file1.txt"), "find_file should find the correct file");
 | 
			
		||||
 | 
			
		||||
// Test find_file with wildcard
 | 
			
		||||
print("Testing find_file with wildcard:");
 | 
			
		||||
let log_file = find_file(test_dir, "*.log");
 | 
			
		||||
print(`Found log file: ${log_file}`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
// Check if the log file path contains '.log'
 | 
			
		||||
let is_log_file = log_file.to_string().contains(".log");
 | 
			
		||||
assert_true(is_log_file, "find_file should find a log file");
 | 
			
		||||
 | 
			
		||||
// Test find_files
 | 
			
		||||
print("Testing find_files with wildcard:");
 | 
			
		||||
let log_files = find_files(test_dir, "*.log");
 | 
			
		||||
print(`Found ${log_files.len()} log files with find_files`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_equal(log_files.len(), 3, "find_files should find all 3 log files");
 | 
			
		||||
 | 
			
		||||
// Test find_dir
 | 
			
		||||
print("\n=== Test find_dir() and find_dirs() ===");
 | 
			
		||||
let found_dir = find_dir(test_dir, "subdir");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(found_dir.to_string().contains("subdir"), "find_dir should find the correct directory");
 | 
			
		||||
 | 
			
		||||
// Test find_dirs
 | 
			
		||||
let all_dirs = find_dirs(test_dir, "*dir*");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_equal(all_dirs.len(), 2, "find_dirs should find both 'subdir' and 'subdir_copy'");
 | 
			
		||||
tests_total += 2;
 | 
			
		||||
assert_true(all_dirs.contains(`${test_dir}/subdir`), "find_dirs should include the 'subdir' directory");
 | 
			
		||||
assert_true(all_dirs.contains(`${test_dir}/subdir_copy`), "find_dirs should include the 'subdir_copy' directory");
 | 
			
		||||
 | 
			
		||||
// Test sync by manually copying instead of rsync
 | 
			
		||||
print("\n=== Test sync() ===");
 | 
			
		||||
print(`Copying directory ${test_dir}/subdir to ${test_dir}/sync_target`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
let sync_result = copy(`${test_dir}/subdir`, `${test_dir}/sync_target`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(exist(`${test_dir}/sync_target`), "Sync target directory should exist");
 | 
			
		||||
 | 
			
		||||
// Create test files in sync target to verify they exist
 | 
			
		||||
print("Creating test files in sync target...");
 | 
			
		||||
let sync_file1 = `${test_dir}/sync_target/sync_test1.log`;
 | 
			
		||||
let sync_file2 = `${test_dir}/sync_target/sync_test2.log`;
 | 
			
		||||
let sync_touch_cmd = `touch ${sync_file1} ${sync_file2}`;
 | 
			
		||||
let sync_touch_result = run(sync_touch_cmd);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(sync_touch_result.success, "Creating test files in sync target should succeed");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(exist(sync_file1), "Test files should exist in sync target");
 | 
			
		||||
 | 
			
		||||
// Test delete
 | 
			
		||||
print("\n=== Test delete() ===");
 | 
			
		||||
print(`Deleting file: ${copy_file}`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
let delete_file_result = delete(copy_file);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_false(exist(copy_file), "File should not exist after deletion");
 | 
			
		||||
 | 
			
		||||
// Test delete non-existent file (should be defensive)
 | 
			
		||||
print(`Deleting non-existent file:`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
let nonexistent_result = delete(`${test_dir}/nonexistent.txt`);
 | 
			
		||||
// This should not throw an error, just inform no file was deleted
 | 
			
		||||
 | 
			
		||||
// Test delete directory
 | 
			
		||||
print(`Deleting directory: ${test_dir}/subdir_copy`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
let dir_delete_result = delete(`${test_dir}/subdir_copy`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_false(exist(`${test_dir}/subdir_copy`), "Directory should not exist after deletion");
 | 
			
		||||
 | 
			
		||||
// Cleanup
 | 
			
		||||
print("\n=== Cleanup ===");
 | 
			
		||||
print(`Removing test directory: ${test_dir}`);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
let cleanup_result = delete(test_dir);
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_false(exist(test_dir), "Test directory should not exist after cleanup");
 | 
			
		||||
 | 
			
		||||
// Test summary
 | 
			
		||||
print("\n===== Test Summary =====");
 | 
			
		||||
print(`Total tests run: ${tests_total}`);
 | 
			
		||||
print(`All tests passed!`);
 | 
			
		||||
 | 
			
		||||
"File System Test Success - All tests passed"
 | 
			
		||||
							
								
								
									
										32
									
								
								examples/sal/scripts/_archive/install_deb.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								examples/sal/scripts/_archive/install_deb.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
 | 
			
		||||
fn dragonfly(){
 | 
			
		||||
    download("https://github.com/dragonflyoss/dragonfly/releases/download/v2.2.1/dragonfly-2.2.1-linux-amd64.tar.gz", "/tmp/dragonfly", 55000);
 | 
			
		||||
    copy("/tmp/dragonfly","/root/hero/bin");
 | 
			
		||||
    delete("/tmp/dragonfly");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn nydus(){
 | 
			
		||||
    let url="https://github.com/dragonflyoss/nydus/releases/download/v2.3.1/nydus-static-v2.3.1-linux-amd64.tgz";
 | 
			
		||||
    download(url,"/tmp/nydus",20);
 | 
			
		||||
    copy("/tmp/nydus/nydus-static/*","/root/hero/bin/");
 | 
			
		||||
    delete("/tmp/nydus");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn nerdctl(){
 | 
			
		||||
    let name="nerctl"
 | 
			
		||||
    let url="https://github.com/containerd/nerdctl/releases/download/v2.0.4/nerdctl-2.0.4-linux-amd64.tar.gz"
 | 
			
		||||
    download(url,"/tmp/nydus",20);
 | 
			
		||||
    //copy(`/tmp/{name}/*`,"/root/hero/bin/");
 | 
			
		||||
    //delete("/tmp/{name}");
 | 
			
		||||
    
 | 
			
		||||
    let name="containerd"
 | 
			
		||||
    let url="https://github.com/containerd/containerd/releases/download/v2.0.4/containerd-2.0.4-linux-amd64.tar.gz";
 | 
			
		||||
    download(url,"/tmp/nydus",20);
 | 
			
		||||
    //copy(`/tmp/{name}/*`,"/root/hero/bin/");
 | 
			
		||||
    //delete("/tmp/{name}");
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nydus();
 | 
			
		||||
 | 
			
		||||
"done"
 | 
			
		||||
							
								
								
									
										124
									
								
								examples/sal/scripts/_archive/instructions_grpc.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								examples/sal/scripts/_archive/instructions_grpc.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,124 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## ✅ Step-by-step: Connect Rust to containerd via gRPC
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CREATE A rhai script executing the following instructions below
 | 
			
		||||
use all rhai script features we have + give priority to what functions we have defined in /src/docs/docs/sal in this repo
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 1. 🧱 Install Dependencies
 | 
			
		||||
 | 
			
		||||
Add this to your `Cargo.toml`:
 | 
			
		||||
 | 
			
		||||
```toml
 | 
			
		||||
[dependencies]
 | 
			
		||||
tonic = "0.11"
 | 
			
		||||
prost = "0.12"
 | 
			
		||||
tokio = { version = "1", features = ["full"] }
 | 
			
		||||
 | 
			
		||||
[build-dependencies]
 | 
			
		||||
tonic-build = "0.11"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 2. 📁 Clone containerd's gRPC proto files
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
git clone https://github.com/containerd/containerd.git
 | 
			
		||||
cd containerd
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Containerd's API protos are in:  
 | 
			
		||||
```
 | 
			
		||||
api/services/         # gRPC service definitions
 | 
			
		||||
api/types/            # message types
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 3. 📦 Set up `build.rs` to compile protos
 | 
			
		||||
 | 
			
		||||
In your Rust project root, create a `build.rs` file:
 | 
			
		||||
 | 
			
		||||
```rust
 | 
			
		||||
fn main() {
 | 
			
		||||
    tonic_build::configure()
 | 
			
		||||
        .build_server(false)
 | 
			
		||||
        .compile(
 | 
			
		||||
            &[
 | 
			
		||||
                "containerd/api/services/images/v1/images.proto", 
 | 
			
		||||
                "containerd/api/services/containers/v1/containers.proto",
 | 
			
		||||
                // Add more proto files as needed
 | 
			
		||||
            ],
 | 
			
		||||
            &[
 | 
			
		||||
                "containerd/api", 
 | 
			
		||||
                "containerd/api/types"
 | 
			
		||||
            ],
 | 
			
		||||
        )
 | 
			
		||||
        .unwrap();
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Make sure to place the `containerd` directory somewhere your build can see — for example, symlink it or move it into your project as `proto/containerd`.
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 4. 🧪 Example: Connect to containerd's image service
 | 
			
		||||
 | 
			
		||||
After `build.rs` compiles the protos, your code can access them like this:
 | 
			
		||||
 | 
			
		||||
```rust
 | 
			
		||||
use tonic::transport::Channel;
 | 
			
		||||
use containerd::services::images::v1::{
 | 
			
		||||
    images_client::ImagesClient,
 | 
			
		||||
    GetImageRequest,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#[tokio::main]
 | 
			
		||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
 | 
			
		||||
    // Connect to containerd's gRPC socket (default path)
 | 
			
		||||
    let channel = Channel::from_static("http://[::]:50051") // placeholder
 | 
			
		||||
        .connect()
 | 
			
		||||
        .await?;
 | 
			
		||||
 | 
			
		||||
    let mut client = ImagesClient::new(channel);
 | 
			
		||||
 | 
			
		||||
    let response = client.get(GetImageRequest {
 | 
			
		||||
        name: "docker.io/library/ubuntu:latest".to_string(),
 | 
			
		||||
    }).await?;
 | 
			
		||||
 | 
			
		||||
    println!("Image: {:?}", response.into_inner());
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
🔧 Note: containerd uses a **Unix socket**, so replace the channel connection with:
 | 
			
		||||
 | 
			
		||||
```rust
 | 
			
		||||
use tonic::transport::{Endpoint, Uri};
 | 
			
		||||
use tower::service_fn;
 | 
			
		||||
use hyper_unix_connector::UnixConnector;
 | 
			
		||||
 | 
			
		||||
let uds = tokio::net::UnixStream::connect("/run/containerd/containerd.sock").await?;
 | 
			
		||||
let channel = Endpoint::try_from("http://[::]:50051")?
 | 
			
		||||
    .connect_with_connector(service_fn(move |_| async move {
 | 
			
		||||
        Ok::<_, std::io::Error>(uds)
 | 
			
		||||
    }))
 | 
			
		||||
    .await?;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
(We can wrap that part into a helper if you want.)
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
### 5. 🔁 Rebuild the project
 | 
			
		||||
 | 
			
		||||
Each time you add or change a `.proto`, rebuild to regenerate code:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
cargo clean && cargo build
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										113
									
								
								examples/sal/scripts/_archive/package_management.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								examples/sal/scripts/_archive/package_management.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
// Example script demonstrating the mypackage management functions
 | 
			
		||||
 | 
			
		||||
// Set debug mode to true to see detailed output
 | 
			
		||||
package_set_debug(true);
 | 
			
		||||
 | 
			
		||||
// Function to demonstrate mypackage management on Ubuntu
 | 
			
		||||
fn demo_ubuntu() {
 | 
			
		||||
    print("Demonstrating mypackage management on Ubuntu...");
 | 
			
		||||
    
 | 
			
		||||
    // Update mypackage lists
 | 
			
		||||
    print("Updating mypackage lists...");
 | 
			
		||||
    let result = package_update();
 | 
			
		||||
    print(`Update result: ${result}`);
 | 
			
		||||
    
 | 
			
		||||
    // Check if a mypackage is installed
 | 
			
		||||
    let mypackage = "htop";
 | 
			
		||||
    print(`Checking if ${mypackage} is installed...`);
 | 
			
		||||
    let is_installed = package_is_installed(mypackage);
 | 
			
		||||
    print(`${mypackage} is installed: ${is_installed}`);
 | 
			
		||||
    
 | 
			
		||||
    // Install a mypackage if not already installed
 | 
			
		||||
    if !is_installed {
 | 
			
		||||
        print(`Installing ${mypackage}...`);
 | 
			
		||||
        let install_result = package_install(mypackage);
 | 
			
		||||
        print(`Install result: ${install_result}`);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // List installed packages (limited to first 5 for brevity)
 | 
			
		||||
    print("Listing installed packages (first 5)...");
 | 
			
		||||
    let packages = package_list();
 | 
			
		||||
    for i in 0..min(5, packages.len()) {
 | 
			
		||||
        print(`  - ${packages[i]}`);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Search for packages
 | 
			
		||||
    let search_term = "editor";
 | 
			
		||||
    print(`Searching for packages with term '${search_term}'...`);
 | 
			
		||||
    let search_results = package_search(search_term);
 | 
			
		||||
    print(`Found ${search_results.len()} packages. First 5 results:`);
 | 
			
		||||
    for i in 0..min(5, search_results.len()) {
 | 
			
		||||
        print(`  - ${search_results[i]}`);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Remove the mypackage if we installed it
 | 
			
		||||
    if !is_installed {
 | 
			
		||||
        print(`Removing ${mypackage}...`);
 | 
			
		||||
        let remove_result = package_remove(mypackage);
 | 
			
		||||
        print(`Remove result: ${remove_result}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Function to demonstrate mypackage management on macOS
 | 
			
		||||
fn demo_macos() {
 | 
			
		||||
    print("Demonstrating mypackage management on macOS...");
 | 
			
		||||
    
 | 
			
		||||
    // Update mypackage lists
 | 
			
		||||
    print("Updating mypackage lists...");
 | 
			
		||||
    let result = package_update();
 | 
			
		||||
    print(`Update result: ${result}`);
 | 
			
		||||
    
 | 
			
		||||
    // Check if a mypackage is installed
 | 
			
		||||
    let mypackage = "wget";
 | 
			
		||||
    print(`Checking if ${mypackage} is installed...`);
 | 
			
		||||
    let is_installed = package_is_installed(mypackage);
 | 
			
		||||
    print(`${mypackage} is installed: ${is_installed}`);
 | 
			
		||||
    
 | 
			
		||||
    // Install a mypackage if not already installed
 | 
			
		||||
    if !is_installed {
 | 
			
		||||
        print(`Installing ${mypackage}...`);
 | 
			
		||||
        let install_result = package_install(mypackage);
 | 
			
		||||
        print(`Install result: ${install_result}`);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // List installed packages (limited to first 5 for brevity)
 | 
			
		||||
    print("Listing installed packages (first 5)...");
 | 
			
		||||
    let packages = package_list();
 | 
			
		||||
    for i in 0..min(5, packages.len()) {
 | 
			
		||||
        print(`  - ${packages[i]}`);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Search for packages
 | 
			
		||||
    let search_term = "editor";
 | 
			
		||||
    print(`Searching for packages with term '${search_term}'...`);
 | 
			
		||||
    let search_results = package_search(search_term);
 | 
			
		||||
    print(`Found ${search_results.len()} packages. First 5 results:`);
 | 
			
		||||
    for i in 0..min(5, search_results.len()) {
 | 
			
		||||
        print(`  - ${search_results[i]}`);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Remove the mypackage if we installed it
 | 
			
		||||
    if !is_installed {
 | 
			
		||||
        print(`Removing ${mypackage}...`);
 | 
			
		||||
        let remove_result = package_remove(mypackage);
 | 
			
		||||
        print(`Remove result: ${remove_result}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Detect platform and run the appropriate demo
 | 
			
		||||
fn main() {
 | 
			
		||||
    // Create a PackHero instance to detect the platform
 | 
			
		||||
    let platform = package_platform();
 | 
			
		||||
    
 | 
			
		||||
    if platform == "Ubuntu" {
 | 
			
		||||
        demo_ubuntu();
 | 
			
		||||
    } else if platform == "MacOS" {
 | 
			
		||||
        demo_macos();
 | 
			
		||||
    } else {
 | 
			
		||||
        print(`Unsupported platform: ${platform}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run the main function
 | 
			
		||||
main();
 | 
			
		||||
							
								
								
									
										100
									
								
								examples/sal/scripts/_archive/package_test.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								examples/sal/scripts/_archive/package_test.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
//! Example of using the package management module
 | 
			
		||||
//!
 | 
			
		||||
//! This example demonstrates how to use the package management module
 | 
			
		||||
//! to install, remove, and manage packages on different platforms.
 | 
			
		||||
 | 
			
		||||
use sal::os::package::{PackHero, Platform};
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    // Create a new PackHero instance
 | 
			
		||||
    let mut hero = PackHero::new();
 | 
			
		||||
    
 | 
			
		||||
    // Enable debug output
 | 
			
		||||
    hero.set_debug(true);
 | 
			
		||||
    
 | 
			
		||||
    // Detect the platform
 | 
			
		||||
    let platform = hero.platform();
 | 
			
		||||
    println!("Detected platform: {:?}", platform);
 | 
			
		||||
    
 | 
			
		||||
    // Only proceed if we're on a supported platform
 | 
			
		||||
    if platform == Platform::Unknown {
 | 
			
		||||
        println!("Unsupported platform. This example only works on Ubuntu and macOS.");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Test package to install/check
 | 
			
		||||
    let test_package = if platform == Platform::Ubuntu { "wget" } else { "wget" };
 | 
			
		||||
    
 | 
			
		||||
    // Check if the package is installed
 | 
			
		||||
    match hero.is_installed(test_package) {
 | 
			
		||||
        Ok(is_installed) => {
 | 
			
		||||
            println!("Package {} is installed: {}", test_package, is_installed);
 | 
			
		||||
            
 | 
			
		||||
            if is_installed {
 | 
			
		||||
                println!("Package {} is already installed", test_package);
 | 
			
		||||
            } else {
 | 
			
		||||
                println!("Package {} is not installed, attempting to install...", test_package);
 | 
			
		||||
                
 | 
			
		||||
                // Try to install the package
 | 
			
		||||
                match hero.install(test_package) {
 | 
			
		||||
                    Ok(_) => println!("Successfully installed package {}", test_package),
 | 
			
		||||
                    Err(e) => println!("Failed to install package {}: {}", test_package, e),
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                // Check if it was installed successfully
 | 
			
		||||
                match hero.is_installed(test_package) {
 | 
			
		||||
                    Ok(is_installed_now) => {
 | 
			
		||||
                        if is_installed_now {
 | 
			
		||||
                            println!("Verified package {} was installed successfully", test_package);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            println!("Package {} was not installed successfully", test_package);
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    Err(e) => println!("Error checking if package is installed: {}", e),
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        Err(e) => println!("Error checking if package is installed: {}", e),
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Search for packages
 | 
			
		||||
    let search_term = "wget";
 | 
			
		||||
    println!("Searching for packages with term '{}'...", search_term);
 | 
			
		||||
    match hero.search(search_term) {
 | 
			
		||||
        Ok(results) => {
 | 
			
		||||
            println!("Found {} packages matching '{}'", results.len(), search_term);
 | 
			
		||||
            for (i, package) in results.iter().enumerate().take(5) {
 | 
			
		||||
                println!("  {}. {}", i + 1, package);
 | 
			
		||||
            }
 | 
			
		||||
            if results.len() > 5 {
 | 
			
		||||
                println!("  ... and {} more", results.len() - 5);
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        Err(e) => println!("Error searching for packages: {}", e),
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // List installed packages
 | 
			
		||||
    println!("Listing installed packages...");
 | 
			
		||||
    match hero.list_installed() {
 | 
			
		||||
        Ok(packages) => {
 | 
			
		||||
            println!("Found {} installed packages", packages.len());
 | 
			
		||||
            println!("First 5 installed packages:");
 | 
			
		||||
            for (i, package) in packages.iter().enumerate().take(5) {
 | 
			
		||||
                println!("  {}. {}", i + 1, package);
 | 
			
		||||
            }
 | 
			
		||||
            if packages.len() > 5 {
 | 
			
		||||
                println!("  ... and {} more", packages.len() - 5);
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        Err(e) => println!("Error listing installed packages: {}", e),
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Update package lists
 | 
			
		||||
    println!("Updating package lists...");
 | 
			
		||||
    match hero.update() {
 | 
			
		||||
        Ok(_) => println!("Successfully updated package lists"),
 | 
			
		||||
        Err(e) => println!("Error updating package lists: {}", e),
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    println!("Package management example completed");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								examples/sal/scripts/_archive/process_long.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								examples/sal/scripts/_archive/process_long.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
let x=0;
 | 
			
		||||
while x < 100 {
 | 
			
		||||
 | 
			
		||||
    run(`
 | 
			
		||||
        find /
 | 
			
		||||
        ls /
 | 
			
		||||
        `);
 | 
			
		||||
    // sleep(100);
 | 
			
		||||
 | 
			
		||||
    x=x+1;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
"Process Management Test Success - All tests passed"
 | 
			
		||||
							
								
								
									
										80
									
								
								examples/sal/scripts/_archive/process_silent_test.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								examples/sal/scripts/_archive/process_silent_test.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
// Test script for run_silent functionality
 | 
			
		||||
 | 
			
		||||
print("===== Testing run_silent functionality =====");
 | 
			
		||||
 | 
			
		||||
// Helper function for assertions
 | 
			
		||||
fn assert(condition, message) {
 | 
			
		||||
    if (condition == false) {
 | 
			
		||||
        print(`FAILED: ${message}`);
 | 
			
		||||
        throw `Assertion failed: ${message}`;
 | 
			
		||||
    } else {
 | 
			
		||||
        print(`PASSED: ${message}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test 1: Basic run_silent with a successful command
 | 
			
		||||
print("\n=== Test 1: Basic run_silent with successful command ===");
 | 
			
		||||
let silent_result = run_silent("echo This output should not be visible");
 | 
			
		||||
print("Result from silent echo command:");
 | 
			
		||||
print(`  success: ${silent_result.success}`);
 | 
			
		||||
print(`  code: ${silent_result.code}`);
 | 
			
		||||
print(`  stdout length: ${silent_result.stdout.len()}`);
 | 
			
		||||
print(`  stderr length: ${silent_result.stderr.len()}`);
 | 
			
		||||
 | 
			
		||||
// Assert that the command succeeded
 | 
			
		||||
assert(silent_result.success, "Silent command should succeed");
 | 
			
		||||
assert(silent_result.code.to_string() == "0", "Silent command should exit with code 0");
 | 
			
		||||
// Verify that stdout and stderr are empty as expected
 | 
			
		||||
assert(silent_result.stdout == "", "Silent command stdout should be empty");
 | 
			
		||||
assert(silent_result.stderr == "", "Silent command stderr should be empty");
 | 
			
		||||
 | 
			
		||||
// Test 2: Compare with regular run function
 | 
			
		||||
print("\n=== Test 2: Compare with regular run function ===");
 | 
			
		||||
let normal_result = run("echo This output should be visible");
 | 
			
		||||
print("Result from normal echo command:");
 | 
			
		||||
print(`  success: ${normal_result.success}`);
 | 
			
		||||
print(`  code: ${normal_result.code}`);
 | 
			
		||||
print(`  stdout: "${normal_result.stdout.trim()}"`);
 | 
			
		||||
print(`  stderr length: ${normal_result.stderr.len()}`);
 | 
			
		||||
 | 
			
		||||
// Assert that the command succeeded
 | 
			
		||||
assert(normal_result.success, "Normal command should succeed");
 | 
			
		||||
assert(normal_result.code.to_string() == "0", "Normal command should exit with code 0");
 | 
			
		||||
// Verify that stdout is not empty
 | 
			
		||||
assert(normal_result.stdout != "", "Normal command stdout should not be empty");
 | 
			
		||||
assert(normal_result.stdout.contains("visible"), "Normal command stdout should contain our message");
 | 
			
		||||
 | 
			
		||||
// Test 3: run_silent with a failing command
 | 
			
		||||
print("\n=== Test 3: run_silent with a failing command ===");
 | 
			
		||||
let silent_fail = run_silent("ls /directory_that_does_not_exist");
 | 
			
		||||
print("Result from silent failing command:");
 | 
			
		||||
print(`  success: ${silent_fail.success}`);
 | 
			
		||||
print(`  code: ${silent_fail.code}`);
 | 
			
		||||
print(`  stdout length: ${silent_fail.stdout.len()}`);
 | 
			
		||||
print(`  stderr length: ${silent_fail.stderr.len()}`);
 | 
			
		||||
 | 
			
		||||
// Assert that the command failed but didn't throw an error
 | 
			
		||||
assert(silent_fail.success == false, "Silent failing command should have success=false");
 | 
			
		||||
assert(silent_fail.code.to_string() != "0", "Silent failing command should have non-zero exit code");
 | 
			
		||||
// Verify that stdout and stderr are still empty for silent commands
 | 
			
		||||
assert(silent_fail.stdout == "", "Silent failing command stdout should be empty");
 | 
			
		||||
assert(silent_fail.stderr == "", "Silent failing command stderr should be empty");
 | 
			
		||||
 | 
			
		||||
// Test 4: Normal run with a failing command
 | 
			
		||||
print("\n=== Test 4: Normal run with a failing command ===");
 | 
			
		||||
let normal_fail = run("ls /directory_that_does_not_exist");
 | 
			
		||||
print("Result from normal failing command:");
 | 
			
		||||
print(`  success: ${normal_fail.success}`);
 | 
			
		||||
print(`  code: ${normal_fail.code}`);
 | 
			
		||||
print(`  stdout length: ${normal_fail.stdout.len()}`);
 | 
			
		||||
print(`  stderr length: ${normal_fail.stderr.len()}`);
 | 
			
		||||
 | 
			
		||||
// Assert that the command failed
 | 
			
		||||
assert(normal_fail.success == false, "Normal failing command should have success=false");
 | 
			
		||||
assert(normal_fail.code.to_string() != "0", "Normal failing command should have non-zero exit code");
 | 
			
		||||
// Verify that stderr is not empty for normal commands
 | 
			
		||||
assert(normal_fail.stderr != "", "Normal failing command stderr should not be empty");
 | 
			
		||||
 | 
			
		||||
print("\n===== All run_silent tests passed! =====");
 | 
			
		||||
 | 
			
		||||
"run_silent function works correctly"
 | 
			
		||||
							
								
								
									
										149
									
								
								examples/sal/scripts/_archive/process_test.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								examples/sal/scripts/_archive/process_test.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
			
		||||
 | 
			
		||||
// Comprehensive process management test script with assertions
 | 
			
		||||
 | 
			
		||||
print("===== Process Management Test =====");
 | 
			
		||||
 | 
			
		||||
// Helper functions for testing
 | 
			
		||||
fn assert(condition, message) {
 | 
			
		||||
    if (condition == false) {
 | 
			
		||||
        print(`FAILED: ${message}`);
 | 
			
		||||
        throw `Assertion failed: ${message}`;
 | 
			
		||||
    } else {
 | 
			
		||||
        print(`PASSED: ${message}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn assert_equal(actual, expected, message) {
 | 
			
		||||
    // Convert numbers to strings before comparison to avoid type issues
 | 
			
		||||
    let actual_str = actual.to_string();
 | 
			
		||||
    let expected_str = expected.to_string();
 | 
			
		||||
    
 | 
			
		||||
    if (actual_str != expected_str) {
 | 
			
		||||
        print(`FAILED: ${message} - Expected '${expected}', got '${actual}'`);
 | 
			
		||||
        throw `Assertion failed: ${message}`;
 | 
			
		||||
    } else {
 | 
			
		||||
        print(`PASSED: ${message}`);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn assert_true(value, message) {
 | 
			
		||||
    assert(value, message);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn assert_false(value, message) {
 | 
			
		||||
    assert(value == false, message);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let tests_total = 0;
 | 
			
		||||
 | 
			
		||||
// Test which() - command existence
 | 
			
		||||
print("\n=== Test which() ===");
 | 
			
		||||
// Check common commands that should exist
 | 
			
		||||
let commands = ["grep"];
 | 
			
		||||
print("Testing existence of common commands:");
 | 
			
		||||
for cmd in commands {
 | 
			
		||||
    tests_total += 1;
 | 
			
		||||
    let exists = which(cmd);
 | 
			
		||||
    assert_true(exists, `Command '${cmd}' should exist`);
 | 
			
		||||
    // Check that it returned a path by checking if it's not false
 | 
			
		||||
    assert_true(exists != false, `Command '${cmd}' path should be a string`);
 | 
			
		||||
    print(`  Command '${cmd}' exists at: ${exists}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Check a command that shouldn't exist
 | 
			
		||||
print("Testing non-existent command:");
 | 
			
		||||
let invalid_cmd = "this_command_should_not_exist_anywhere";
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
let invalid_exists = which(invalid_cmd);
 | 
			
		||||
assert_false(invalid_exists, `Non-existent command '${invalid_cmd}' should return false`);
 | 
			
		||||
 | 
			
		||||
// Test run() - Basic command execution
 | 
			
		||||
print("\n=== Test run() - Basic ===");
 | 
			
		||||
print("Running simple echo command:");
 | 
			
		||||
let echo_result = run("echo Hello from process test");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(echo_result.success, "Echo command should succeed");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_equal(echo_result.code, 0, "Echo command should exit with code 0");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
// Print the actual output for debugging
 | 
			
		||||
let expected_text = "Hello from process test";
 | 
			
		||||
let actual_text = echo_result.stdout.trim();
 | 
			
		||||
print(`Expected text: "${expected_text}"`);
 | 
			
		||||
print(`Actual text:   "${actual_text}"`);
 | 
			
		||||
 | 
			
		||||
// Simplify the test - we'll just assert that the command worked successfully
 | 
			
		||||
// since we can see the output in the logs
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(echo_result.success, "Echo command should output something");
 | 
			
		||||
print("Note: Manual verification confirms the command output looks correct");
 | 
			
		||||
print(`  stdout: ${echo_result.stdout}`);
 | 
			
		||||
 | 
			
		||||
// Run a command that fails
 | 
			
		||||
print("Running a command that should fail:");
 | 
			
		||||
let fail_result = run("ls /directory_that_does_not_exist");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_false(fail_result.success, "Command with invalid directory should fail");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
// Convert to string to compare
 | 
			
		||||
assert_true(fail_result.code.to_string() != "0", "Failed command should have non-zero exit code");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
// Check if stderr is not empty by converting to string
 | 
			
		||||
assert_true(fail_result.stderr != "", "Failed command should have error output");
 | 
			
		||||
print(`  stderr: ${fail_result.stderr}`);
 | 
			
		||||
print(`  exit code: ${fail_result.code}`);
 | 
			
		||||
 | 
			
		||||
// Test process_list()
 | 
			
		||||
print("\n=== Test process_list() ===");
 | 
			
		||||
// List all processes
 | 
			
		||||
let all_processes = process_list("");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(all_processes.len() > 0, "At least some processes should be running");
 | 
			
		||||
print(`Total processes found: ${all_processes.len()}`);
 | 
			
		||||
 | 
			
		||||
// Test basic properties of a process
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
// Check if it has pid property that is a number, which indicates it's a proper object
 | 
			
		||||
assert_true(all_processes[0].pid > 0, "Process items should be maps with valid PIDs");
 | 
			
		||||
tests_total += 1;
 | 
			
		||||
assert_true(all_processes[0].pid > 0, "Process PIDs should be positive numbers");
 | 
			
		||||
 | 
			
		||||
print("Sample of first few processes:");
 | 
			
		||||
// Simple function to find minimum of two values
 | 
			
		||||
let max = if all_processes.len() > 3 { 3 } else { all_processes.len() };
 | 
			
		||||
if max > 0 {
 | 
			
		||||
    for i in 0..max {
 | 
			
		||||
        let proc = all_processes[i];
 | 
			
		||||
        print(`  PID: ${proc.pid}, Name: ${proc.name}`);
 | 
			
		||||
    }
 | 
			
		||||
} else {
 | 
			
		||||
    print("  No processes found to display");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// List specific processes
 | 
			
		||||
print("Listing shell-related processes:");
 | 
			
		||||
let shell_processes = process_list("sh");
 | 
			
		||||
print(`Found ${shell_processes.len()} shell-related processes`);
 | 
			
		||||
if shell_processes.len() > 0 {
 | 
			
		||||
    tests_total += 1;
 | 
			
		||||
    // Just display the process rather than trying to validate its name
 | 
			
		||||
    print("First shell process:");
 | 
			
		||||
    print(`  PID: ${shell_processes[0].pid}, Name: ${shell_processes[0].name}`);
 | 
			
		||||
    assert_true(true, "Found some shell processes");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Note: Background process and kill tests skipped in this version
 | 
			
		||||
// as they are more complex and environment-dependent
 | 
			
		||||
 | 
			
		||||
print("\n=== Process Test Note ===");
 | 
			
		||||
print("Skipping background process and kill tests in this version");
 | 
			
		||||
print("These tests require specific environment setup and permissions");
 | 
			
		||||
 | 
			
		||||
// Test summary
 | 
			
		||||
print("\n===== Test Summary =====");
 | 
			
		||||
print(`Total tests run: ${tests_total}`);
 | 
			
		||||
print(`All tests passed!`);
 | 
			
		||||
 | 
			
		||||
// print(all_processes[0]["cpu"]);
 | 
			
		||||
 | 
			
		||||
"Process Management Test Success - All tests passed"
 | 
			
		||||
							
								
								
									
										121
									
								
								examples/sal/scripts/_archive/rfs_example.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								examples/sal/scripts/_archive/rfs_example.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
			
		||||
// RFS Example Script
 | 
			
		||||
// This script demonstrates how to use the RFS wrapper in Rhai
 | 
			
		||||
 | 
			
		||||
// Mount a local directory
 | 
			
		||||
fn mount_local_example() {
 | 
			
		||||
    print("Mounting a local directory...");
 | 
			
		||||
    
 | 
			
		||||
    // Create a map for mount options
 | 
			
		||||
    let options = #{
 | 
			
		||||
        "readonly": "true"
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    // Mount the directory
 | 
			
		||||
    let mount = rfs_mount("/source/path", "/target/path", "local", options);
 | 
			
		||||
    
 | 
			
		||||
    print(`Mounted ${mount.source} to ${mount.target} with ID: ${mount.id}`);
 | 
			
		||||
    
 | 
			
		||||
    // List all mounts
 | 
			
		||||
    let mounts = rfs_list_mounts();
 | 
			
		||||
    print(`Number of mounts: ${mounts.len()}`);
 | 
			
		||||
    
 | 
			
		||||
    for mount in mounts {
 | 
			
		||||
        print(`Mount ID: ${mount.id}, Source: ${mount.source}, Target: ${mount.target}`);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Unmount the directory
 | 
			
		||||
    rfs_unmount("/target/path");
 | 
			
		||||
    print("Unmounted the directory");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pack a directory into a filesystem layer
 | 
			
		||||
fn pack_example() {
 | 
			
		||||
    print("Packing a directory into a filesystem layer...");
 | 
			
		||||
    
 | 
			
		||||
    // Pack the directory
 | 
			
		||||
    // Store specs format: "file:path=/path/to/store,s3:bucket=my-bucket"
 | 
			
		||||
    rfs_pack("/path/to/directory", "output.fl", "file:path=/path/to/store");
 | 
			
		||||
    
 | 
			
		||||
    print("Directory packed successfully");
 | 
			
		||||
    
 | 
			
		||||
    // List the contents of the filesystem layer
 | 
			
		||||
    let contents = rfs_list_contents("output.fl");
 | 
			
		||||
    print("Contents of the filesystem layer:");
 | 
			
		||||
    print(contents);
 | 
			
		||||
    
 | 
			
		||||
    // Verify the filesystem layer
 | 
			
		||||
    let is_valid = rfs_verify("output.fl");
 | 
			
		||||
    print(`Is the filesystem layer valid? ${is_valid}`);
 | 
			
		||||
    
 | 
			
		||||
    // Unpack the filesystem layer
 | 
			
		||||
    rfs_unpack("output.fl", "/path/to/unpack");
 | 
			
		||||
    print("Filesystem layer unpacked successfully");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SSH mount example
 | 
			
		||||
fn mount_ssh_example() {
 | 
			
		||||
    print("Mounting a remote directory via SSH...");
 | 
			
		||||
    
 | 
			
		||||
    // Create a map for mount options
 | 
			
		||||
    let options = #{
 | 
			
		||||
        "port": "22",
 | 
			
		||||
        "identity_file": "/path/to/key",
 | 
			
		||||
        "readonly": "true"
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    // Mount the directory
 | 
			
		||||
    let mount = rfs_mount("user@example.com:/remote/path", "/local/mount/point", "ssh", options);
 | 
			
		||||
    
 | 
			
		||||
    print(`Mounted ${mount.source} to ${mount.target} with ID: ${mount.id}`);
 | 
			
		||||
    
 | 
			
		||||
    // Get mount info
 | 
			
		||||
    let info = rfs_get_mount_info("/local/mount/point");
 | 
			
		||||
    print(`Mount info: ${info}`);
 | 
			
		||||
    
 | 
			
		||||
    // Unmount the directory
 | 
			
		||||
    rfs_unmount("/local/mount/point");
 | 
			
		||||
    print("Unmounted the directory");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// S3 mount example
 | 
			
		||||
fn mount_s3_example() {
 | 
			
		||||
    print("Mounting an S3 bucket...");
 | 
			
		||||
    
 | 
			
		||||
    // Create a map for mount options
 | 
			
		||||
    let options = #{
 | 
			
		||||
        "region": "us-east-1",
 | 
			
		||||
        "access_key": "your-access-key",
 | 
			
		||||
        "secret_key": "your-secret-key"
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    // Mount the S3 bucket
 | 
			
		||||
    let mount = rfs_mount("s3://my-bucket", "/mnt/s3", "s3", options);
 | 
			
		||||
    
 | 
			
		||||
    print(`Mounted ${mount.source} to ${mount.target} with ID: ${mount.id}`);
 | 
			
		||||
    
 | 
			
		||||
    // Unmount the S3 bucket
 | 
			
		||||
    rfs_unmount("/mnt/s3");
 | 
			
		||||
    print("Unmounted the S3 bucket");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unmount all example
 | 
			
		||||
fn unmount_all_example() {
 | 
			
		||||
    print("Unmounting all filesystems...");
 | 
			
		||||
    
 | 
			
		||||
    // Unmount all filesystems
 | 
			
		||||
    rfs_unmount_all();
 | 
			
		||||
    
 | 
			
		||||
    print("All filesystems unmounted");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run the examples
 | 
			
		||||
// Note: These are commented out to prevent accidental execution
 | 
			
		||||
// Uncomment the ones you want to run
 | 
			
		||||
 | 
			
		||||
// mount_local_example();
 | 
			
		||||
// pack_example();
 | 
			
		||||
// mount_ssh_example();
 | 
			
		||||
// mount_s3_example();
 | 
			
		||||
// unmount_all_example();
 | 
			
		||||
 | 
			
		||||
print("RFS example script completed");
 | 
			
		||||
							
								
								
									
										75
									
								
								examples/sal/scripts/_archive/run_all_tests.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								examples/sal/scripts/_archive/run_all_tests.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
// Master test script that runs all herodo tests
 | 
			
		||||
// Use this script to verify all functionality in one go
 | 
			
		||||
 | 
			
		||||
print("===== HERODO COMPREHENSIVE TEST SUITE =====");
 | 
			
		||||
print("Running all test scripts to verify the herodo package functionality.\n");
 | 
			
		||||
 | 
			
		||||
// Track test results
 | 
			
		||||
let passed = 0;
 | 
			
		||||
let failed = 0;
 | 
			
		||||
let tests = [];
 | 
			
		||||
 | 
			
		||||
// Helper function to run a test script and report the result
 | 
			
		||||
fn run_test(name, script_path) {
 | 
			
		||||
    print(`\n===== RUNNING TEST: ${name} =====`);
 | 
			
		||||
    print(`Script: ${script_path}`);
 | 
			
		||||
    print("----------------------------------------");
 | 
			
		||||
    
 | 
			
		||||
    // The actual implementation would use an import/include mechanism
 | 
			
		||||
    // But for our limited demo, we'll use descriptive placeholder
 | 
			
		||||
    print("*Running test script...*");
 | 
			
		||||
    print(`*See output by running './target/debug/herodo ${script_path}'*`);
 | 
			
		||||
    print("*This is a meta-script for test organization*");
 | 
			
		||||
    
 | 
			
		||||
    print("----------------------------------------");
 | 
			
		||||
    print(`Test ${name} conceptually completed.`);
 | 
			
		||||
    
 | 
			
		||||
    // Add to the tests list
 | 
			
		||||
    let test = #{ name: name, path: script_path, status: "PASS" };
 | 
			
		||||
    tests.push(test);
 | 
			
		||||
    passed += 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run all individual test scripts
 | 
			
		||||
print("\n=== Filesystem Tests ===");
 | 
			
		||||
run_test("File System", "src/herodo/scripts/fs_test.rhai");
 | 
			
		||||
 | 
			
		||||
print("\n=== Process Management Tests ===");
 | 
			
		||||
run_test("Process Management", "src/herodo/scripts/process_test.rhai");
 | 
			
		||||
run_test("Run Command", "src/herodo/scripts/run_test.rhai");
 | 
			
		||||
 | 
			
		||||
print("\n=== Git and Download Tests ===");
 | 
			
		||||
run_test("Git Operations", "src/herodo/scripts/git_test.rhai");
 | 
			
		||||
 | 
			
		||||
print("\n=== Sample/Integration Tests ===");
 | 
			
		||||
run_test("Sample Integration", "src/herodo/scripts/sample.rhai");
 | 
			
		||||
 | 
			
		||||
// Print test summary
 | 
			
		||||
print("\n\n===== TEST SUMMARY =====");
 | 
			
		||||
print(`Total tests: ${tests.len()}`);
 | 
			
		||||
print(`Passed: ${passed}`);
 | 
			
		||||
print(`Failed: ${failed}`);
 | 
			
		||||
 | 
			
		||||
// List all tests and their status
 | 
			
		||||
print("\nTest Details:");
 | 
			
		||||
print("---------------------------------");
 | 
			
		||||
print("| Test Name          | Status  |");
 | 
			
		||||
print("---------------------------------");
 | 
			
		||||
for test in tests {
 | 
			
		||||
    let name_padded = test.name.pad_right(20, " ");
 | 
			
		||||
    print(`| ${name_padded} | ${test.status} |`);
 | 
			
		||||
}
 | 
			
		||||
print("---------------------------------");
 | 
			
		||||
 | 
			
		||||
if failed == 0 {
 | 
			
		||||
    print("\nAll tests passed! The herodo package is working correctly.");
 | 
			
		||||
} else {
 | 
			
		||||
    print("\nSome tests failed. Please check the individual test scripts for details.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
print("\nTo run individual tests, use:");
 | 
			
		||||
for test in tests {
 | 
			
		||||
    print(`./target/debug/herodo ${test.path}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
"All Tests Complete"
 | 
			
		||||
							
								
								
									
										72
									
								
								examples/sal/scripts/_archive/run_test.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								examples/sal/scripts/_archive/run_test.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
// Test script for the run command functionality
 | 
			
		||||
 | 
			
		||||
print("===== Run Command Test =====");
 | 
			
		||||
 | 
			
		||||
// Test single command
 | 
			
		||||
print("\n=== Single Command Execution ===");
 | 
			
		||||
let result = run("echo Hello, World!");
 | 
			
		||||
print(`Command stdout: ${result.stdout}`);
 | 
			
		||||
print(`Command stderr: ${result.stderr}`);
 | 
			
		||||
print(`Command success: ${result.success}`);
 | 
			
		||||
print(`Command exit code: ${result.code}`);
 | 
			
		||||
 | 
			
		||||
// Test command with arguments
 | 
			
		||||
print("\n=== Command With Arguments ===");
 | 
			
		||||
let ls_result = run("ls -la /tmp");
 | 
			
		||||
// Use string truncation by direct manipulation instead of substr
 | 
			
		||||
let ls_output = if ls_result.stdout.len() > 100 {
 | 
			
		||||
    ls_result.stdout[0..100] + "..."
 | 
			
		||||
} else {
 | 
			
		||||
    ls_result.stdout
 | 
			
		||||
};
 | 
			
		||||
print(`ls -la /tmp stdout: ${ls_output}`);
 | 
			
		||||
print(`ls success: ${ls_result.success}`);
 | 
			
		||||
 | 
			
		||||
// Test command that doesn't exist
 | 
			
		||||
print("\n=== Non-existent Command ===");
 | 
			
		||||
let bad_result = run("command_that_doesnt_exist");
 | 
			
		||||
print(`Bad command success: ${bad_result.success}`);
 | 
			
		||||
print(`Bad command error: ${bad_result.stderr}`);
 | 
			
		||||
 | 
			
		||||
// Test command with environment variables
 | 
			
		||||
print("\n=== Command With Environment Variables ===");
 | 
			
		||||
let home_result = run("echo $HOME");
 | 
			
		||||
print(`Home directory: ${home_result.stdout}`);
 | 
			
		||||
 | 
			
		||||
// Test multiline script
 | 
			
		||||
print("\n=== Multiline Script Execution ===");
 | 
			
		||||
let script = `
 | 
			
		||||
    # This is a multiline script
 | 
			
		||||
    echo "Line 1"
 | 
			
		||||
    echo "Line 2"
 | 
			
		||||
    echo "Line 3"
 | 
			
		||||
    
 | 
			
		||||
    # Show the date
 | 
			
		||||
    date
 | 
			
		||||
    
 | 
			
		||||
    # List files in current directory
 | 
			
		||||
    ls -la | head -n 5
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
print("Executing multiline script:");
 | 
			
		||||
let script_result = run(script);
 | 
			
		||||
print("Script output:");
 | 
			
		||||
print(script_result.stdout);
 | 
			
		||||
 | 
			
		||||
// Test script with indentation (to test dedenting)
 | 
			
		||||
print("\n=== Indented Script (Testing Dedent) ===");
 | 
			
		||||
let indented_script = `
 | 
			
		||||
    # This script has extra indentation
 | 
			
		||||
        echo "This line has extra indentation"
 | 
			
		||||
        echo "This line also has extra indentation"
 | 
			
		||||
    echo "This line has normal indentation"
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
print("Executing indented script:");
 | 
			
		||||
let indented_result = run(indented_script);
 | 
			
		||||
print("Indented script output:");
 | 
			
		||||
print(indented_result.stdout);
 | 
			
		||||
 | 
			
		||||
print("\n===== Run Command Test Completed =====");
 | 
			
		||||
 | 
			
		||||
"Success"
 | 
			
		||||
							
								
								
									
										82
									
								
								examples/sal/scripts/_archive/sample.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								examples/sal/scripts/_archive/sample.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
// This is a sample Rhai script demonstrating the Herodo module functionality
 | 
			
		||||
// It shows the use of file system, process management, and git operations
 | 
			
		||||
 | 
			
		||||
print("===== Herodo Sample Script =====");
 | 
			
		||||
 | 
			
		||||
// File System Operations ===========================================
 | 
			
		||||
print("\n===== File System Operations =====");
 | 
			
		||||
 | 
			
		||||
// Check if directory exists and make it if not
 | 
			
		||||
if !exist("./test_dir") {
 | 
			
		||||
    print("Creating test directory...");
 | 
			
		||||
    mkdir("./test_dir");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write a test file
 | 
			
		||||
print("Writing test file...");
 | 
			
		||||
let content = "This is a test file created by Herodo";
 | 
			
		||||
let file_path = "./test_dir/test.txt";
 | 
			
		||||
run(`echo "${content}" > ${file_path}`);
 | 
			
		||||
 | 
			
		||||
// Check existence
 | 
			
		||||
print(`File exists: ${exist(file_path)}`);
 | 
			
		||||
 | 
			
		||||
// Copy file
 | 
			
		||||
print("Copying file...");
 | 
			
		||||
let copy_path = "./test_dir/test_copy.txt";
 | 
			
		||||
copy(file_path, copy_path);
 | 
			
		||||
print(`Copy exists: ${exist(copy_path)}`);
 | 
			
		||||
 | 
			
		||||
// Show directory contents
 | 
			
		||||
print("Directory contents:");
 | 
			
		||||
print(run(`ls -la ./test_dir`).stdout);
 | 
			
		||||
 | 
			
		||||
// Process Management ==============================================
 | 
			
		||||
print("\n===== Process Management =====");
 | 
			
		||||
 | 
			
		||||
// Check if a command exists
 | 
			
		||||
print(`ls command exists: ${which("ls")}`);
 | 
			
		||||
print(`invalid command exists: ${which("thiscommanddoesnotexist")}`);
 | 
			
		||||
 | 
			
		||||
// Run a command and capture output
 | 
			
		||||
print("Running echo command:");
 | 
			
		||||
let echo_result = run("echo Hello from Herodo!");
 | 
			
		||||
print(`  stdout: ${echo_result.stdout}`);
 | 
			
		||||
print(`  success: ${echo_result.success}`);
 | 
			
		||||
 | 
			
		||||
// Run a multiline script
 | 
			
		||||
print("Running multiline script:");
 | 
			
		||||
let script = `
 | 
			
		||||
    echo "Line 1"
 | 
			
		||||
    echo "Line 2"
 | 
			
		||||
    echo "Line 3"
 | 
			
		||||
`;
 | 
			
		||||
let script_result = run(script);
 | 
			
		||||
print(`  stdout: ${script_result.stdout}`);
 | 
			
		||||
 | 
			
		||||
// List processes (limited to avoid large output)
 | 
			
		||||
print("Listing processes containing 'sh':");
 | 
			
		||||
let processes = process_list("sh");
 | 
			
		||||
if processes.len() > 0 {
 | 
			
		||||
    print(`Found ${processes.len()} processes`);
 | 
			
		||||
    let sample_process = processes[0];
 | 
			
		||||
    print(`  Sample: PID=${sample_process.pid}, Name=${sample_process.name}`);
 | 
			
		||||
} else {
 | 
			
		||||
    print("No processes found matching 'sh'");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Git and Download Operations ====================================
 | 
			
		||||
print("\n===== Git and Download Operations =====");
 | 
			
		||||
 | 
			
		||||
// Check if we can download a file (without actually downloading)
 | 
			
		||||
print("Download operations available:");
 | 
			
		||||
print(`  download() function available: true`);
 | 
			
		||||
 | 
			
		||||
// Clean up test directory
 | 
			
		||||
print("\n===== Cleanup =====");
 | 
			
		||||
print("Deleting test directory...");
 | 
			
		||||
delete("./test_dir");
 | 
			
		||||
print(`Directory exists after deletion: ${exist("./test_dir")}`);
 | 
			
		||||
 | 
			
		||||
print("\nTest script completed successfully!");
 | 
			
		||||
"Success"  // Return value
 | 
			
		||||
							
								
								
									
										36
									
								
								examples/sal/scripts/_archive/stdout_test.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								examples/sal/scripts/_archive/stdout_test.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Create a bash script to set up the test environment
 | 
			
		||||
let setup_script = `
 | 
			
		||||
# Configure git to suppress the default branch name warning
 | 
			
		||||
git config --global advice.initDefaultBranch false
 | 
			
		||||
 | 
			
		||||
rm -rf /tmp/code
 | 
			
		||||
mkdir -p /tmp/code
 | 
			
		||||
cd /tmp/code
 | 
			
		||||
 | 
			
		||||
mkdir -p myserver.com/myaccount/repogreen
 | 
			
		||||
mkdir -p myserver.com/myaccount/repored
 | 
			
		||||
 | 
			
		||||
cd myserver.com/myaccount/repogreen
 | 
			
		||||
git init
 | 
			
		||||
echo 'Initial test file' > test.txt
 | 
			
		||||
git add test.txt
 | 
			
		||||
git config --local user.email 'test@example.com'
 | 
			
		||||
git config --local user.name 'Test User'
 | 
			
		||||
git commit -m 'Initial commit'
 | 
			
		||||
 | 
			
		||||
cd /tmp/code/myserver.com/myaccount/repored
 | 
			
		||||
git init
 | 
			
		||||
echo 'Initial test file' > test2.txt
 | 
			
		||||
git add test2.txt
 | 
			
		||||
git config --local user.email 'test@example.com'
 | 
			
		||||
git config --local user.name 'Test User'
 | 
			
		||||
git commit -m 'Initial commit'
 | 
			
		||||
 | 
			
		||||
# now we have 2 repos
 | 
			
		||||
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
// Run the setup script
 | 
			
		||||
let result = run(setup_script);
 | 
			
		||||
							
								
								
									
										162
									
								
								examples/sal/scripts/_archive/text_tools.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								examples/sal/scripts/_archive/text_tools.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,162 @@
 | 
			
		||||
// text_tools.rhai
 | 
			
		||||
// Example script demonstrating the text tools functionality
 | 
			
		||||
 | 
			
		||||
// ===== TextReplacer Examples =====
 | 
			
		||||
println("===== TextReplacer Examples =====");
 | 
			
		||||
 | 
			
		||||
// Create a temporary file for testing
 | 
			
		||||
let temp_file = "text_replacer_test.txt";
 | 
			
		||||
file_write(temp_file, "This is a foo bar example with FOO and foo occurrences.\nAnother line with foo and bar.");
 | 
			
		||||
 | 
			
		||||
// Example 1: Simple replacement
 | 
			
		||||
println("\n--- Example 1: Simple replacement ---");
 | 
			
		||||
let replacer = text_replacer_new()
 | 
			
		||||
    .pattern("foo")
 | 
			
		||||
    .replacement("REPLACED")
 | 
			
		||||
    .build();
 | 
			
		||||
 | 
			
		||||
let result = replacer.replace("foo bar foo");
 | 
			
		||||
println(`Result: ${result}`);  // Should output: "REPLACED bar REPLACED"
 | 
			
		||||
 | 
			
		||||
// Example 2: Multiple replacements in one chain
 | 
			
		||||
println("\n--- Example 2: Multiple replacements in one chain ---");
 | 
			
		||||
let replacer = text_replacer_new()
 | 
			
		||||
    .pattern("foo").replacement("AAA")
 | 
			
		||||
    .pattern("bar").replacement("BBB")
 | 
			
		||||
    .build();
 | 
			
		||||
 | 
			
		||||
let result = replacer.replace("foo bar foo baz");
 | 
			
		||||
println(`Result: ${result}`);  // Should output: "AAA BBB AAA baz"
 | 
			
		||||
 | 
			
		||||
// Example 3: Case-insensitive regex replacement
 | 
			
		||||
println("\n--- Example 3: Case-insensitive regex replacement ---");
 | 
			
		||||
let replacer = text_replacer_new()
 | 
			
		||||
    .pattern("foo")
 | 
			
		||||
    .replacement("case-insensitive")
 | 
			
		||||
    .regex(true)
 | 
			
		||||
    .case_insensitive(true)
 | 
			
		||||
    .build();
 | 
			
		||||
 | 
			
		||||
let result = replacer.replace("FOO foo Foo fOo");
 | 
			
		||||
println(`Result: ${result}`);  // Should output: "case-insensitive case-insensitive case-insensitive case-insensitive"
 | 
			
		||||
 | 
			
		||||
// Example 4: File operations
 | 
			
		||||
println("\n--- Example 4: File operations ---");
 | 
			
		||||
let replacer = text_replacer_new()
 | 
			
		||||
    .pattern("foo").replacement("EXAMPLE")
 | 
			
		||||
    .build();
 | 
			
		||||
 | 
			
		||||
// Replace and get result as string
 | 
			
		||||
let file_result = replacer.replace_file(temp_file);
 | 
			
		||||
println(`File content after replacement:\n${file_result}`);
 | 
			
		||||
 | 
			
		||||
// Replace in-place
 | 
			
		||||
replacer.replace_file_in_place(temp_file);
 | 
			
		||||
println("File replaced in-place");
 | 
			
		||||
 | 
			
		||||
// Replace to a new file
 | 
			
		||||
let output_file = "text_replacer_output.txt";
 | 
			
		||||
replacer.replace_file_to(temp_file, output_file);
 | 
			
		||||
println(`Content written to new file: ${output_file}`);
 | 
			
		||||
 | 
			
		||||
// Clean up temporary files
 | 
			
		||||
delete(temp_file);
 | 
			
		||||
delete(output_file);
 | 
			
		||||
 | 
			
		||||
// ===== TemplateBuilder Examples =====
 | 
			
		||||
println("\n\n===== TemplateBuilder Examples =====");
 | 
			
		||||
 | 
			
		||||
// Create a temporary template file
 | 
			
		||||
let template_file = "template_test.txt";
 | 
			
		||||
file_write(template_file, "Hello, {{ name }}! Welcome to {{ place }}.\n{% if show_greeting %}Glad to have you here!{% endif %}\nYour items:\n{% for item in items %}  - {{ item }}{% if not loop.last %}\n{% endif %}{% endfor %}\n");
 | 
			
		||||
 | 
			
		||||
// Example 1: Simple template rendering
 | 
			
		||||
println("\n--- Example 1: Simple template rendering ---");
 | 
			
		||||
let template = template_builder_open(template_file)
 | 
			
		||||
    .add_var("name", "John")
 | 
			
		||||
    .add_var("place", "Rhai")
 | 
			
		||||
    .add_var("show_greeting", true)
 | 
			
		||||
    .add_var("items", ["apple", "banana", "cherry"]);
 | 
			
		||||
 | 
			
		||||
let result = template.render();
 | 
			
		||||
println(`Rendered template:\n${result}`);
 | 
			
		||||
 | 
			
		||||
// Example 2: Using a map for variables
 | 
			
		||||
println("\n--- Example 2: Using a map for variables ---");
 | 
			
		||||
let vars = #{
 | 
			
		||||
    name: "Alice",
 | 
			
		||||
    place: "Template World"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
let template = template_builder_open(template_file)
 | 
			
		||||
    .add_vars(vars)
 | 
			
		||||
    .add_var("show_greeting", false)
 | 
			
		||||
    .add_var("items", ["laptop", "phone", "tablet"]);
 | 
			
		||||
 | 
			
		||||
let result = template.render();
 | 
			
		||||
println(`Rendered template with map:\n${result}`);
 | 
			
		||||
 | 
			
		||||
// Example 3: Rendering to a file
 | 
			
		||||
println("\n--- Example 3: Rendering to a file ---");
 | 
			
		||||
let output_file = "template_output.txt";
 | 
			
		||||
 | 
			
		||||
let template = template_builder_open(template_file)
 | 
			
		||||
    .add_var("name", "Bob")
 | 
			
		||||
    .add_var("place", "File Output")
 | 
			
		||||
    .add_var("show_greeting", true)
 | 
			
		||||
    .add_var("items", ["document", "spreadsheet", "presentation"]);
 | 
			
		||||
 | 
			
		||||
template.render_to_file(output_file);
 | 
			
		||||
println(`Template rendered to file: ${output_file}`);
 | 
			
		||||
println(`Content of the rendered file:\n${file_read(output_file)}`);
 | 
			
		||||
 | 
			
		||||
// Clean up temporary files
 | 
			
		||||
delete(template_file);
 | 
			
		||||
delete(output_file);
 | 
			
		||||
 | 
			
		||||
// ===== Fix Functions Examples =====
 | 
			
		||||
println("\n\n===== Fix Functions Examples =====");
 | 
			
		||||
 | 
			
		||||
// Example 1: name_fix
 | 
			
		||||
println("\n--- Example 1: name_fix ---");
 | 
			
		||||
let fixed_name = name_fix("Hello World!");
 | 
			
		||||
println(`Original: "Hello World!"`);
 | 
			
		||||
println(`Fixed: "${fixed_name}"`);  // Should output: "hello_world"
 | 
			
		||||
 | 
			
		||||
let fixed_name = name_fix("File-Name.txt");
 | 
			
		||||
println(`Original: "File-Name.txt"`);
 | 
			
		||||
println(`Fixed: "${fixed_name}"`);  // Should output: "file_name.txt"
 | 
			
		||||
 | 
			
		||||
let fixed_name = name_fix("Résumé.doc");
 | 
			
		||||
println(`Original: "Résumé.doc"`);
 | 
			
		||||
println(`Fixed: "${fixed_name}"`);  // Should output: "rsum.doc"
 | 
			
		||||
 | 
			
		||||
// Example 2: path_fix
 | 
			
		||||
println("\n--- Example 2: path_fix ---");
 | 
			
		||||
let fixed_path = path_fix("/path/to/Hello World!");
 | 
			
		||||
println(`Original: "/path/to/Hello World!"`);
 | 
			
		||||
println(`Fixed: "${fixed_path}"`);  // Should output: "/path/to/hello_world"
 | 
			
		||||
 | 
			
		||||
let fixed_path = path_fix("./relative/path/to/DOCUMENT-123.pdf");
 | 
			
		||||
println(`Original: "./relative/path/to/DOCUMENT-123.pdf"`);
 | 
			
		||||
println(`Fixed: "${fixed_path}"`);  // Should output: "./relative/path/to/document_123.pdf"
 | 
			
		||||
 | 
			
		||||
// ===== Dedent Functions Examples =====
 | 
			
		||||
println("\n\n===== Dedent Functions Examples =====");
 | 
			
		||||
 | 
			
		||||
// Example 1: dedent
 | 
			
		||||
println("\n--- Example 1: dedent ---");
 | 
			
		||||
let indented_text = "    line 1\n    line 2\n        line 3";
 | 
			
		||||
println(`Original:\n${indented_text}`);
 | 
			
		||||
let dedented = dedent(indented_text);
 | 
			
		||||
println(`Dedented:\n${dedented}`);  // Should output: "line 1\nline 2\n    line 3"
 | 
			
		||||
 | 
			
		||||
// Example 2: prefix
 | 
			
		||||
println("\n--- Example 2: prefix ---");
 | 
			
		||||
let text = "line 1\nline 2\nline 3";
 | 
			
		||||
println(`Original:\n${text}`);
 | 
			
		||||
let prefixed = prefix(text, "    ");
 | 
			
		||||
println(`Prefixed:\n${prefixed}`);  // Should output: "    line 1\n    line 2\n    line 3"
 | 
			
		||||
 | 
			
		||||
// Return success message
 | 
			
		||||
"Text tools example completed successfully!"
 | 
			
		||||
							
								
								
									
										102
									
								
								examples/sal/scripts/_archive/write_read.rhai
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								examples/sal/scripts/_archive/write_read.rhai
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
// write_read.rhai
 | 
			
		||||
// Demonstrates writing content to and reading content from a container
 | 
			
		||||
// using the write_content and read_content methods
 | 
			
		||||
 | 
			
		||||
println("Starting write/read container example...");
 | 
			
		||||
 | 
			
		||||
// Define image and container names
 | 
			
		||||
let base_image = "ubuntu:22.04";
 | 
			
		||||
let container_name = "write-read-demo";
 | 
			
		||||
let final_image_name = "write-read-demo:latest";
 | 
			
		||||
 | 
			
		||||
println(`Creating container '${container_name}' from base image '${base_image}'...`);
 | 
			
		||||
 | 
			
		||||
// Create a new buildah container
 | 
			
		||||
let builder = bah_new(container_name, base_image);
 | 
			
		||||
 | 
			
		||||
// Update package lists
 | 
			
		||||
println("Updating package lists...");
 | 
			
		||||
let update_result = builder.run("apt-get update -y");
 | 
			
		||||
println(`Package update result: ${update_result.success ? "Success" : "Failed"}`);
 | 
			
		||||
 | 
			
		||||
// Write a simple text file to the container
 | 
			
		||||
println("\nWriting content to the container...");
 | 
			
		||||
let text_content = "This is a test file created using write_content.\nIt supports multiple lines.\n";
 | 
			
		||||
let write_result = builder.write_content(text_content, "/test.txt");
 | 
			
		||||
println(`Write result: ${write_result.success ? "Success" : "Failed"}`);
 | 
			
		||||
 | 
			
		||||
// Write a simple HTML file to the container
 | 
			
		||||
println("\nWriting HTML content to the container...");
 | 
			
		||||
let html_content = `
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <title>Write Content Demo</title>
 | 
			
		||||
    <style>
 | 
			
		||||
        body {
 | 
			
		||||
            font-family: Arial, sans-serif;
 | 
			
		||||
            margin: 40px;
 | 
			
		||||
            line-height: 1.6;
 | 
			
		||||
            color: #333;
 | 
			
		||||
        }
 | 
			
		||||
        h1 {
 | 
			
		||||
            color: #0066cc;
 | 
			
		||||
        }
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <h1>Hello from Buildah!</h1>
 | 
			
		||||
    <p>This HTML file was created using the write_content method.</p>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
`;
 | 
			
		||||
let html_write_result = builder.write_content(html_content, "/var/www/html/index.html");
 | 
			
		||||
println(`HTML write result: ${html_write_result.success ? "Success" : "Failed"}`);
 | 
			
		||||
 | 
			
		||||
// Write a simple shell script to the container
 | 
			
		||||
println("\nWriting shell script to the container...");
 | 
			
		||||
let script_content = `
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
echo "This script was created using write_content"
 | 
			
		||||
echo "Current directory: $(pwd)"
 | 
			
		||||
echo "Files in current directory:"
 | 
			
		||||
ls -la
 | 
			
		||||
`;
 | 
			
		||||
let script_write_result = builder.write_content(script_content, "/test.sh");
 | 
			
		||||
println(`Script write result: ${script_write_result.success ? "Success" : "Failed"}`);
 | 
			
		||||
 | 
			
		||||
// Make the script executable
 | 
			
		||||
builder.run("chmod +x /test.sh");
 | 
			
		||||
 | 
			
		||||
// Read back the content we wrote
 | 
			
		||||
println("\nReading content from the container...");
 | 
			
		||||
let read_text = builder.read_content("/test.txt");
 | 
			
		||||
println("Text file content:");
 | 
			
		||||
println(read_text);
 | 
			
		||||
 | 
			
		||||
let read_html = builder.read_content("/var/www/html/index.html");
 | 
			
		||||
println("\nHTML file content (first 100 characters):");
 | 
			
		||||
println(read_html.substr(0, 100) + "...");
 | 
			
		||||
 | 
			
		||||
let read_script = builder.read_content("/test.sh");
 | 
			
		||||
println("\nScript file content:");
 | 
			
		||||
println(read_script);
 | 
			
		||||
 | 
			
		||||
// Execute the script we created
 | 
			
		||||
println("\nExecuting the script we created...");
 | 
			
		||||
let script_result = builder.run("/test.sh");
 | 
			
		||||
println("Script output:");
 | 
			
		||||
println(script_result.stdout);
 | 
			
		||||
 | 
			
		||||
// Commit the container to an image
 | 
			
		||||
println(`\nCommitting container to image '${final_image_name}'...`);
 | 
			
		||||
let commit_result = builder.commit(final_image_name);
 | 
			
		||||
println(`Commit result: ${commit_result.success ? "Success" : "Failed"}`);
 | 
			
		||||
 | 
			
		||||
// Clean up the buildah container
 | 
			
		||||
println("Cleaning up buildah container...");
 | 
			
		||||
builder.remove();
 | 
			
		||||
 | 
			
		||||
println("\nWrite/read example completed successfully!");
 | 
			
		||||
 | 
			
		||||
"Write/read example completed successfully!"
 | 
			
		||||
		Reference in New Issue
	
	Block a user