346 lines
9.7 KiB
Rust
346 lines
9.7 KiB
Rust
//! Rhai wrappers for Zinit client module functions
|
|
//!
|
|
//! This module provides Rhai wrappers for the functions in the Zinit client module.
|
|
|
|
use rhai::{Engine, EvalAltResult, Array, Dynamic, Map};
|
|
use crate::zinit_client as client;
|
|
use tokio::runtime::Runtime;
|
|
use serde_json::{json, Value};
|
|
use crate::rhai::error::ToRhaiError;
|
|
|
|
/// Register Zinit module functions with the Rhai engine
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `engine` - The Rhai engine to register the functions with
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// * `Result<(), Box<EvalAltResult>>` - Ok if registration was successful, Err otherwise
|
|
pub fn register_zinit_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
|
|
// Register Zinit client functions
|
|
engine.register_fn("zinit_list", zinit_list);
|
|
engine.register_fn("zinit_status", zinit_status);
|
|
engine.register_fn("zinit_start", zinit_start);
|
|
engine.register_fn("zinit_stop", zinit_stop);
|
|
engine.register_fn("zinit_restart", zinit_restart);
|
|
engine.register_fn("zinit_monitor", zinit_monitor);
|
|
engine.register_fn("zinit_forget", zinit_forget);
|
|
engine.register_fn("zinit_kill", zinit_kill);
|
|
engine.register_fn("zinit_create_service", zinit_create_service);
|
|
engine.register_fn("zinit_delete_service", zinit_delete_service);
|
|
engine.register_fn("zinit_get_service", zinit_get_service);
|
|
engine.register_fn("zinit_logs", zinit_logs);
|
|
engine.register_fn("zinit_logs_all", zinit_logs_all);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
impl<T> ToRhaiError<T> for Result<T, zinit_client::ClientError> {
|
|
fn to_rhai_error(self) -> Result<T, Box<EvalAltResult>> {
|
|
self.map_err(|e| {
|
|
Box::new(EvalAltResult::ErrorRuntime(
|
|
format!("Zinit error: {}", e).into(),
|
|
rhai::Position::NONE
|
|
))
|
|
})
|
|
}
|
|
}
|
|
|
|
// Helper function to get a runtime
|
|
fn get_runtime() -> Result<Runtime, Box<EvalAltResult>> {
|
|
tokio::runtime::Runtime::new().map_err(|e| {
|
|
Box::new(EvalAltResult::ErrorRuntime(
|
|
format!("Failed to create Tokio runtime: {}", e).into(),
|
|
rhai::Position::NONE
|
|
))
|
|
})
|
|
}
|
|
|
|
//
|
|
// Zinit Client Function Wrappers
|
|
//
|
|
|
|
/// Wrapper for zinit_client::list
|
|
///
|
|
/// Lists all services managed by Zinit.
|
|
pub fn zinit_list(socket_path: &str) -> Result<Map, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
client::list(socket_path).await
|
|
});
|
|
|
|
let services = result.to_rhai_error()?;
|
|
|
|
// Convert HashMap<String, String> to Rhai Map
|
|
let mut map = Map::new();
|
|
for (name, state) in services {
|
|
map.insert(name.into(), Dynamic::from(state));
|
|
}
|
|
|
|
Ok(map)
|
|
}
|
|
|
|
/// Wrapper for zinit_client::status
|
|
///
|
|
/// Gets the status of a specific service.
|
|
pub fn zinit_status(socket_path: &str, name: &str) -> Result<Map, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
client::status(socket_path, name).await
|
|
});
|
|
|
|
let status = result.to_rhai_error()?;
|
|
|
|
// Convert Status to Rhai Map
|
|
let mut map = Map::new();
|
|
map.insert("name".into(), Dynamic::from(status.name));
|
|
map.insert("pid".into(), Dynamic::from(status.pid));
|
|
map.insert("state".into(), Dynamic::from(status.state));
|
|
map.insert("target".into(), Dynamic::from(status.target));
|
|
|
|
// Convert dependencies
|
|
let mut deps_map = Map::new();
|
|
for (dep, state) in status.after {
|
|
deps_map.insert(dep.into(), Dynamic::from(state));
|
|
}
|
|
map.insert("after".into(), Dynamic::from_map(deps_map));
|
|
|
|
Ok(map)
|
|
}
|
|
|
|
/// Wrapper for zinit_client::start
|
|
///
|
|
/// Starts a service.
|
|
pub fn zinit_start(socket_path: &str, name: &str) -> Result<bool, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
client::start(socket_path, name).await
|
|
});
|
|
|
|
result.to_rhai_error()?;
|
|
Ok(true)
|
|
}
|
|
|
|
/// Wrapper for zinit_client::stop
|
|
///
|
|
/// Stops a service.
|
|
pub fn zinit_stop(socket_path: &str, name: &str) -> Result<bool, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
client::stop(socket_path, name).await
|
|
});
|
|
|
|
result.to_rhai_error()?;
|
|
Ok(true)
|
|
}
|
|
|
|
/// Wrapper for zinit_client::restart
|
|
///
|
|
/// Restarts a service.
|
|
pub fn zinit_restart(socket_path: &str, name: &str) -> Result<bool, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
client::restart(socket_path, name).await
|
|
});
|
|
|
|
result.to_rhai_error()?;
|
|
Ok(true)
|
|
}
|
|
|
|
/// Wrapper for zinit_client::monitor
|
|
///
|
|
/// Starts monitoring a service.
|
|
pub fn zinit_monitor(socket_path: &str, name: &str) -> Result<bool, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
let client = client::get_zinit_client(socket_path).await?;
|
|
client.monitor(name).await
|
|
});
|
|
|
|
result.to_rhai_error()?;
|
|
Ok(true)
|
|
}
|
|
|
|
/// Wrapper for zinit_client::forget
|
|
///
|
|
/// Stops monitoring a service.
|
|
pub fn zinit_forget(socket_path: &str, name: &str) -> Result<bool, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
let client = client::get_zinit_client(socket_path).await?;
|
|
client.forget(name).await
|
|
});
|
|
|
|
result.to_rhai_error()?;
|
|
Ok(true)
|
|
}
|
|
|
|
/// Wrapper for zinit_client::kill
|
|
///
|
|
/// Sends a signal to a service.
|
|
pub fn zinit_kill(socket_path: &str, name: &str, signal: &str) -> Result<bool, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
let client = client::get_zinit_client(socket_path).await?;
|
|
client.kill(name, signal).await
|
|
});
|
|
|
|
result.to_rhai_error()?;
|
|
Ok(true)
|
|
}
|
|
|
|
/// Wrapper for zinit_client::create_service
|
|
///
|
|
/// Creates a new service.
|
|
pub fn zinit_create_service(socket_path: &str, name: &str, exec: &str, oneshot: bool) -> Result<String, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
// Create service configuration
|
|
let content = serde_json::from_value(json!({
|
|
"exec": exec,
|
|
"oneshot": oneshot
|
|
})).map_err(|e| {
|
|
Box::new(EvalAltResult::ErrorRuntime(
|
|
format!("Failed to create service configuration: {}", e).into(),
|
|
rhai::Position::NONE
|
|
))
|
|
})?;
|
|
|
|
let result = rt.block_on(async {
|
|
let client = client::get_zinit_client(socket_path).await?;
|
|
client.create_service(name, content).await
|
|
});
|
|
|
|
result.to_rhai_error()
|
|
}
|
|
|
|
/// Wrapper for zinit_client::delete_service
|
|
///
|
|
/// Deletes a service.
|
|
pub fn zinit_delete_service(socket_path: &str, name: &str) -> Result<String, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
let client = client::get_zinit_client(socket_path).await?;
|
|
client.delete_service(name).await
|
|
});
|
|
|
|
result.to_rhai_error()
|
|
}
|
|
|
|
/// Wrapper for zinit_client::get_service
|
|
///
|
|
/// Gets a service configuration.
|
|
pub fn zinit_get_service(socket_path: &str, name: &str) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
let client = client::get_zinit_client(socket_path).await?;
|
|
client.get_service(name).await
|
|
});
|
|
|
|
let value = result.to_rhai_error()?;
|
|
|
|
// Convert Value to Dynamic
|
|
match value {
|
|
Value::Object(map) => {
|
|
let mut rhai_map = Map::new();
|
|
for (k, v) in map {
|
|
rhai_map.insert(k.into(), value_to_dynamic(v));
|
|
}
|
|
Ok(Dynamic::from_map(rhai_map))
|
|
},
|
|
_ => Err(Box::new(EvalAltResult::ErrorRuntime(
|
|
"Expected object from get_service".into(),
|
|
rhai::Position::NONE
|
|
)))
|
|
}
|
|
}
|
|
|
|
/// Wrapper for zinit_client::logs with a filter
|
|
///
|
|
/// Gets logs for a specific service.
|
|
pub fn zinit_logs(socket_path: &str, filter: &str) -> Result<Array, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let filter_string = Some(filter.to_string());
|
|
|
|
let result = rt.block_on(async {
|
|
let client = client::get_zinit_client(socket_path).await?;
|
|
client.logs(filter_string).await
|
|
});
|
|
|
|
let logs = result.to_rhai_error()?;
|
|
|
|
// Convert Vec<String> to Rhai Array
|
|
let mut array = Array::new();
|
|
for log in logs {
|
|
array.push(Dynamic::from(log));
|
|
}
|
|
|
|
Ok(array)
|
|
}
|
|
|
|
/// Wrapper for zinit_client::logs without a filter
|
|
///
|
|
/// Gets all logs.
|
|
pub fn zinit_logs_all(socket_path: &str) -> Result<Array, Box<EvalAltResult>> {
|
|
let rt = get_runtime()?;
|
|
|
|
let result = rt.block_on(async {
|
|
let client = client::get_zinit_client(socket_path).await?;
|
|
client.logs(None).await
|
|
});
|
|
|
|
let logs = result.to_rhai_error()?;
|
|
|
|
// Convert Vec<String> to Rhai Array
|
|
let mut array = Array::new();
|
|
for log in logs {
|
|
array.push(Dynamic::from(log));
|
|
}
|
|
|
|
Ok(array)
|
|
}
|
|
|
|
// Helper function to convert serde_json::Value to rhai::Dynamic
|
|
fn value_to_dynamic(value: Value) -> Dynamic {
|
|
match value {
|
|
Value::Null => Dynamic::UNIT,
|
|
Value::Bool(b) => Dynamic::from(b),
|
|
Value::Number(n) => {
|
|
if let Some(i) = n.as_i64() {
|
|
Dynamic::from(i)
|
|
} else if let Some(f) = n.as_f64() {
|
|
Dynamic::from(f)
|
|
} else {
|
|
Dynamic::from(n.to_string())
|
|
}
|
|
},
|
|
Value::String(s) => Dynamic::from(s),
|
|
Value::Array(arr) => {
|
|
let mut rhai_arr = Array::new();
|
|
for item in arr {
|
|
rhai_arr.push(value_to_dynamic(item));
|
|
}
|
|
Dynamic::from(rhai_arr)
|
|
},
|
|
Value::Object(map) => {
|
|
let mut rhai_map = Map::new();
|
|
for (k, v) in map {
|
|
rhai_map.insert(k.into(), value_to_dynamic(v));
|
|
}
|
|
Dynamic::from_map(rhai_map)
|
|
}
|
|
}
|
|
}
|