Crates.io | net-shell |
lib.rs | net-shell |
version | 0.3.0 |
created_at | 2025-07-06 05:30:33.213475+00 |
updated_at | 2025-08-23 14:19:17.648904+00 |
description | A script execution and variable extraction framework with SSH remote execution and local execution support, pipeline orchestration, and flexible variable extraction via regex. |
homepage | https://github.com/winkb/net-shell |
repository | https://github.com/winkb/net-shell |
max_upload_size | |
id | 1739790 |
size | 106,571 |
A powerful script execution and variable extraction framework with SSH remote execution and local execution support, pipeline orchestration, and flexible variable extraction via regex.
Add this to your Cargo.toml
:
[dependencies]
net-shell = "0.2.0"
Or install the binary:
cargo install net-shell
Create a config.yaml
file:
# Global variables
variables:
master_ip: "192.168.0.199"
app_name: "myapp"
version: "1.0.0"
# SSH client configurations
clients:
mac_server:
name: "mac_server"
execution_method: ssh
ssh_config:
host: "{{ master_ip }}"
port: 22
username: "li"
private_key_path: "/Users/li/.ssh/id_rsa"
timeout_seconds: 2
# Pipeline definitions
pipelines:
- name: "deploy_app"
steps:
- name: "get_system_info"
script: "./scripts/get_system_info.sh"
timeout_seconds: 5
servers:
- mac_server
extract:
- name: "os_version_num"
patterns:
- "OS Version: (.+)"
- "(\\d+\\.\\d+\\.\\d+)"
source: "stdout"
- name: "os_version"
patterns: ["OS Version: (.+)"]
source: "stdout"
- name: "hostname"
patterns: ["Hostname: (.+)"]
source: "stdout"
- name: "current_user"
patterns: ["Current user: (.+)"]
source: "stdout"
- name: "deploy_application"
script: "./scripts/deploy.sh"
timeout_seconds: 10
servers:
- mac_server
extract:
- name: "deploy_path"
patterns: ["Deployed to: (.+)"]
source: "stdout"
- name: "deploy_status"
patterns: ["Status: (.+)"]
source: "stdout"
- name: "verify_deployment"
script: "./scripts/verify.sh"
timeout_seconds: 5
servers:
- mac_server
extract:
- name: "service_status"
patterns: ["Service Status: (.+)"]
source: "stdout"
- name: "verification_time"
patterns: ["Verification completed at (.+)"]
source: "stdout"
- name: "install_docker"
steps:
- name: "mock install docker"
script: "./scripts/mock_install_docker.sh"
timeout_seconds: 3
servers:
- mac_server
extract:
- name: "docker_version"
patterns: ["Docker version: (.+)"]
source: "stdout"
- name: "install_path"
patterns: ["Installed to: (.+)"]
source: "stdout"
- name: "start_docker"
script: "./scripts/mock_start_docker.sh"
timeout_seconds: 3
servers:
- mac_server
extract:
- name: "docker_status"
patterns: ["Docker status: (.+)"]
source: "stdout"
- name: "docker_pid"
patterns: ["Docker PID: (\\d+)"]
source: "stdout"
- name: "install_docker_compose"
steps:
- name: "mock install docker compose"
script: "./scripts/mock_install_docker_compose.sh"
servers:
- mac_server
extract:
- name: "compose_version"
patterns: ["Docker Compose version: (.+)"]
source: "stdout"
- name: "compose_path"
patterns: ["Compose installed to: (.+)"]
source: "stdout"
default_timeout: 60
For local execution, simply omit the servers
field or leave it empty:
steps:
- name: "local_check"
script: |
echo "Running locally on: $(hostname)"
echo "Current user: $(whoami)"
echo "Working directory: $(pwd)"
extract:
- name: "local_hostname"
patterns: ["Running locally on: (.+)"]
source: "stdout"
You can mix local and remote steps in the same pipeline:
steps:
- name: "local_prep"
script: |
echo "Preparing locally..."
echo "Timestamp: $(date)"
extract:
- name: "timestamp"
patterns: ["Timestamp: (.+)"]
source: "stdout"
- name: "remote_execution"
script: |
echo "Executing remotely with timestamp: ${timestamp}"
echo "Remote host: $(hostname)"
servers:
- mac_server
Run with default configuration (config.yaml
):
cargo run
Or specify a custom configuration file:
cargo run config_custom.yaml
use net_shell::{RemoteExecutor, models::*};
use std::collections::HashMap;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create variables
let mut variables = HashMap::new();
variables.insert("new_master_ip".to_string(), "192.168.1.100".to_string());
// Create executor
let executor = RemoteExecutor::from_yaml_file("config.yaml", Some(variables))?;
// Execute all pipelines
let results = executor.execute_all_pipelines().await?;
Ok(())
}
Define global variables that can be referenced throughout the configuration:
variables:
master_ip: "192.168.0.199"
app_name: "myapp"
version: "1.0.0"
Define SSH clients for remote execution:
clients:
server_name:
name: "server_name"
execution_method: ssh
ssh_config:
host: "{{ master_ip }}" # Can reference variables
port: 22
username: "user"
password: "password" # Or use private_key_path
private_key_path: "/path/to/key"
timeout_seconds: 30
Each pipeline contains multiple steps:
pipelines:
- name: "pipeline_name"
steps:
- name: "step_name"
script: "/path/to/script.sh"
timeout_seconds: 30
servers:
- server_name
extract:
- name: "variable_name"
patterns: ["Pattern: (.+)"]
source: "stdout" # or "stderr"
Variables are extracted using regex patterns. Multiple patterns can be chained:
extract:
- name: "extracted_value"
patterns:
- "Value: (.+)"
- "(\\d+\\.\\d+\\.\\d+)" # Extract version number
source: "stdout"
steps:
- name: "extract_multiple"
script: |
echo "CPU: $(nproc) cores"
echo "Memory: $(free -h | grep Mem | awk '{print $2}')"
echo "Disk: $(df -h / | tail -1 | awk '{print $4}') available"
extract:
- name: "cpu_cores"
patterns: ["CPU: (.+) cores"]
source: "stdout"
- name: "memory_total"
patterns: ["Memory: (.+)"]
source: "stdout"
- name: "disk_available"
patterns: ["Disk: (.+) available"]
source: "stdout"
steps:
- name: "step1"
script: |
echo "Step 1 output"
echo "Value: 42"
extract:
- name: "step1_value"
patterns: ["Value: (.+)"]
source: "stdout"
- name: "step2"
script: |
echo "Using value from step1: ${step1_value}"
echo "Processing..."
servers:
- remote_server
The framework provides real-time output streaming with detailed event information:
🚀 [STEP_STARTED] deploy_app@get_system_info@mac_server: Starting step
[STDOUT] deploy_app@get_system_info@mac_server: System: Darwin
[STDOUT] deploy_app@get_system_info@mac_server: Hostname: macbook-pro
[VARS] Current variables: {"os_version": "macOS 13.0", "hostname": "macbook-pro"}
✅ [STEP_COMPLETED] deploy_app@get_system_info@mac_server: Step completed successfully
The framework provides comprehensive error handling and logging:
All errors are logged with detailed context and stack traces for debugging.
This project is licensed under the MIT License.