Compare commits

..

No commits in common. "bb39f3e3f24e08742fb4cd847791b49befb5f95d" and "a9255de679b70fbf3af60a94939b2c70ff8b3bf6" have entirely different histories.

8 changed files with 207 additions and 228 deletions

View File

@ -3,12 +3,9 @@
"gitea": {
"command": "/Users/despiegk/hero/bin/mcpgitea",
"args": [
"-t",
"stdio",
"--host",
"https://gitea.com",
"--token",
"5bd13c898368a2edbfcef43f898a34857b51b37a"
"-t", "stdio",
"--host", "https://gitea.com",
"--token", "5bd13c898368a2edbfcef43f898a34857b51b37a"
],
"env": {
"GITEA_HOST": "https://git.threefold.info/",

View File

@ -53,9 +53,9 @@ tokio = "1.45.0"
tokio-postgres = "0.7.8" # Async PostgreSQL client
tokio-test = "0.4.4"
uuid = { version = "1.16.0", features = ["v4"] }
zinit-client = { path = "/Users/timurgordon/code/github/threefoldtech/zinit/zinit-client" }
reqwest = { version = "0.12.15", features = ["json"] }
urlencoding = "2.1.3"
zinit-client = "0.3.0"
# Optional features for specific OS functionality
[target.'cfg(unix)'.dependencies]

View File

@ -1,9 +1,8 @@
//! Rhai bindings for SAL crypto functionality
use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _};
use crate::vault::CryptoError;
use ethers::types::{Address, U256};
use hex;
use once_cell::sync::Lazy;
use rhai::{Dynamic, Engine, EvalAltResult};
use std::collections::HashMap;
@ -11,6 +10,7 @@ use std::fs;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::Mutex;
use hex;
use tokio::runtime::Runtime;
use crate::vault::{ethereum, keyspace};
@ -268,9 +268,7 @@ fn create_keyspace(name: &str, password: &str) -> bool {
}
fn select_keyspace(name: &str) -> bool {
let session = crate::vault::keyspace::session_manager::SESSION
.lock()
.unwrap();
let session = crate::vault::keyspace::session_manager::SESSION.lock().unwrap();
if let Some(ref current_space_obj) = session.current_space {
if current_space_obj.name == name {
log::debug!("Keyspace '{}' is already selected.", name);
@ -286,10 +284,7 @@ fn rhai_list_keyspaces_actual() -> Vec<String> {
let key_spaces_dir = home_dir.join(".hero-vault").join("key-spaces");
if !key_spaces_dir.exists() {
log::debug!(
"Key spaces directory does not exist: {}",
key_spaces_dir.display()
);
log::debug!("Key spaces directory does not exist: {}", key_spaces_dir.display());
return Vec::new();
}

View File

@ -2,11 +2,11 @@
//!
//! This module provides Rhai wrappers for the functions in the Zinit client module.
use crate::rhai::error::ToRhaiError;
use rhai::{Engine, EvalAltResult, Array, Dynamic, Map};
use crate::zinit_client as client;
use rhai::{Array, Dynamic, Engine, EvalAltResult, Map};
use serde_json::{json, Value};
use tokio::runtime::Runtime;
use serde_json::{json, Value};
use crate::rhai::error::ToRhaiError;
/// Register Zinit module functions with the Rhai engine
///
@ -36,12 +36,12 @@ pub fn register_zinit_module(engine: &mut Engine) -> Result<(), Box<EvalAltResul
Ok(())
}
impl<T> ToRhaiError<T> for Result<T, zinit_client::ZinitError> {
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,
rhai::Position::NONE
))
})
}
@ -52,7 +52,7 @@ 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,
rhai::Position::NONE
))
})
}
@ -67,7 +67,9 @@ fn get_runtime() -> Result<Runtime, Box<EvalAltResult>> {
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 result = rt.block_on(async {
client::list(socket_path).await
});
let services = result.to_rhai_error()?;
@ -86,7 +88,9 @@ pub fn zinit_list(socket_path: &str) -> Result<Map, Box<EvalAltResult>> {
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 result = rt.block_on(async {
client::status(socket_path, name).await
});
let status = result.to_rhai_error()?;
@ -113,7 +117,9 @@ pub fn zinit_status(socket_path: &str, name: &str) -> Result<Map, Box<EvalAltRes
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 });
let result = rt.block_on(async {
client::start(socket_path, name).await
});
result.to_rhai_error()?;
Ok(true)
@ -125,7 +131,9 @@ pub fn zinit_start(socket_path: &str, name: &str) -> Result<bool, Box<EvalAltRes
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 });
let result = rt.block_on(async {
client::stop(socket_path, name).await
});
result.to_rhai_error()?;
Ok(true)
@ -137,7 +145,9 @@ pub fn zinit_stop(socket_path: &str, name: &str) -> Result<bool, Box<EvalAltResu
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 });
let result = rt.block_on(async {
client::restart(socket_path, name).await
});
result.to_rhai_error()?;
Ok(true)
@ -191,23 +201,17 @@ pub fn zinit_kill(socket_path: &str, name: &str, signal: &str) -> Result<bool, B
/// 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>> {
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| {
})).map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to create service configuration: {}", e).into(),
rhai::Position::NONE,
rhai::Position::NONE
))
})?;
@ -216,9 +220,7 @@ pub fn zinit_create_service(
client.create_service(name, content).await
});
// Convert () result to success message
result.to_rhai_error()?;
Ok(format!("Service '{}' created successfully", name))
result.to_rhai_error()
}
/// Wrapper for zinit_client::delete_service
@ -232,9 +234,7 @@ pub fn zinit_delete_service(socket_path: &str, name: &str) -> Result<String, Box
client.delete_service(name).await
});
// Convert () result to success message
result.to_rhai_error()?;
Ok(format!("Service '{}' deleted successfully", name))
result.to_rhai_error()
}
/// Wrapper for zinit_client::get_service
@ -258,11 +258,11 @@ pub fn zinit_get_service(socket_path: &str, name: &str) -> Result<Dynamic, Box<E
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,
))),
rhai::Position::NONE
)))
}
}
@ -325,7 +325,7 @@ fn value_to_dynamic(value: Value) -> Dynamic {
} else {
Dynamic::from(n.to_string())
}
}
},
Value::String(s) => Dynamic::from(s),
Value::Array(arr) => {
let mut rhai_arr = Array::new();
@ -333,7 +333,7 @@ fn value_to_dynamic(value: Value) -> Dynamic {
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 {

View File

@ -1,9 +1,9 @@
// File: /root/code/git.threefold.info/herocode/sal/src/virt/nerdctl/container_builder.rs
use std::collections::HashMap;
use crate::virt::nerdctl::{execute_nerdctl_command, NerdctlError};
use super::container_types::{Container, HealthCheck};
use super::health_check_script::prepare_health_check_command;
use crate::virt::nerdctl::{execute_nerdctl_command, NerdctlError};
use std::collections::HashMap;
impl Container {
/// Reset the container configuration to defaults while keeping the name and image
@ -18,10 +18,7 @@ impl Container {
// If container exists, stop and remove it
if let Some(container_id) = &self.container_id {
println!(
"Container exists. Stopping and removing container '{}'...",
name
);
println!("Container exists. Stopping and removing container '{}'...", name);
// Try to stop the container
let _ = execute_nerdctl_command(&["stop", container_id]);
@ -374,11 +371,7 @@ impl Container {
// If no image is specified, return an error
let image = match &self.image {
Some(img) => img,
None => {
return Err(NerdctlError::Other(
"No image specified for container creation".to_string(),
))
}
None => return Err(NerdctlError::Other("No image specified for container creation".to_string())),
};
// Build the command arguments as strings

View File

@ -1,8 +1,8 @@
// File: /root/code/git.threefold.info/herocode/sal/src/virt/nerdctl/images.rs
use super::NerdctlError;
use crate::process::CommandResult;
use crate::virt::nerdctl::execute_nerdctl_command;
use crate::process::CommandResult;
use super::NerdctlError;
use serde::{Deserialize, Serialize};
/// Represents a container image

View File

@ -1,9 +1,9 @@
use lazy_static::lazy_static;
use serde_json::{Map, Value};
use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex, Once};
use zinit_client::{ServiceState, ServiceStatus as Status, ZinitClient, ZinitError};
use std::sync::atomic::{AtomicBool, Ordering};
use lazy_static::lazy_static;
use zinit_client::{Client as ZinitClient, ClientError, Status};
use std::collections::HashMap;
use serde_json::{Map, Value};
// Global Zinit client instance using lazy_static
lazy_static! {
@ -27,7 +27,7 @@ impl ZinitClientWrapper {
}
// Initialize the client
async fn initialize(&self) -> Result<(), ZinitError> {
async fn initialize(&self) -> Result<(), ClientError> {
if self.initialized.load(Ordering::Relaxed) {
return Ok(());
}
@ -43,86 +43,88 @@ impl ZinitClientWrapper {
}
// List all services
pub async fn list(&self) -> Result<HashMap<String, ServiceState>, ZinitError> {
pub async fn list(&self) -> Result<HashMap<String, String>, ClientError> {
self.client.list().await
}
// Get status of a service
pub async fn status(&self, name: &str) -> Result<Status, ZinitError> {
pub async fn status(&self, name: &str) -> Result<Status, ClientError> {
self.client.status(name).await
}
// Start a service
pub async fn start(&self, name: &str) -> Result<(), ZinitError> {
pub async fn start(&self, name: &str) -> Result<(), ClientError> {
self.client.start(name).await
}
// Stop a service
pub async fn stop(&self, name: &str) -> Result<(), ZinitError> {
pub async fn stop(&self, name: &str) -> Result<(), ClientError> {
self.client.stop(name).await
}
// Restart a service
pub async fn restart(&self, name: &str) -> Result<(), ZinitError> {
pub async fn restart(&self, name: &str) -> Result<(), ClientError> {
self.client.restart(name).await
}
// Monitor a service
pub async fn monitor(&self, name: &str) -> Result<(), ZinitError> {
pub async fn monitor(&self, name: &str) -> Result<(), ClientError> {
self.client.monitor(name).await
}
// Forget a service
pub async fn forget(&self, name: &str) -> Result<(), ZinitError> {
pub async fn forget(&self, name: &str) -> Result<(), ClientError> {
self.client.forget(name).await
}
// Send a signal to a service
pub async fn kill(&self, name: &str, signal: &str) -> Result<(), ZinitError> {
pub async fn kill(&self, name: &str, signal: &str) -> Result<(), ClientError> {
self.client.kill(name, signal).await
}
// Create a new service
pub async fn create_service(
&self,
name: &str,
content: Map<String, Value>,
) -> Result<(), ZinitError> {
self.client
.create_service(name, Value::Object(content))
.await
pub async fn create_service(&self, name: &str, content: Map<String, Value>) -> Result<String, ClientError> {
self.client.create_service(name, content).await
}
// Delete a service
pub async fn delete_service(&self, name: &str) -> Result<(), ZinitError> {
pub async fn delete_service(&self, name: &str) -> Result<String, ClientError> {
self.client.delete_service(name).await
}
// Get a service configuration
pub async fn get_service(&self, name: &str) -> Result<Value, ZinitError> {
pub async fn get_service(&self, name: &str) -> Result<Value, ClientError> {
self.client.get_service(name).await
}
// Shutdown the system
pub async fn shutdown(&self) -> Result<(), ZinitError> {
pub async fn shutdown(&self) -> Result<(), ClientError> {
self.client.shutdown().await
}
// Reboot the system
pub async fn reboot(&self) -> Result<(), ZinitError> {
pub async fn reboot(&self) -> Result<(), ClientError> {
self.client.reboot().await
}
// Get logs (simplified implementation - returns empty for now due to LogStream complexity)
pub async fn logs(&self, _filter: Option<String>) -> Result<Vec<String>, ZinitError> {
// TODO: Implement proper LogStream handling when tokio-stream is available
// For now, return empty logs to avoid compilation errors
Ok(Vec::new())
// Start HTTP server
pub async fn start_http_server(&self, address: &str) -> Result<String, ClientError> {
self.client.start_http_server(address).await
}
// Stop HTTP server
pub async fn stop_http_server(&self) -> Result<(), ClientError> {
self.client.stop_http_server().await
}
// Get logs
pub async fn logs(&self, filter: Option<String>) -> Result<Vec<String>, ClientError> {
self.client.logs(filter).await
}
}
// Get the Zinit client instance
pub async fn get_zinit_client(socket_path: &str) -> Result<Arc<ZinitClientWrapper>, ZinitError> {
pub async fn get_zinit_client(socket_path: &str) -> Result<Arc<ZinitClientWrapper>, ClientError> {
// Check if we already have a client
{
let guard = ZINIT_CLIENT.lock().unwrap();
@ -144,9 +146,9 @@ pub async fn get_zinit_client(socket_path: &str) -> Result<Arc<ZinitClientWrappe
}
// Create a new Zinit client
async fn create_zinit_client(socket_path: &str) -> Result<Arc<ZinitClientWrapper>, ZinitError> {
// Connect via Unix socket - use new() instead of unix_socket()
let client = ZinitClient::new(socket_path);
async fn create_zinit_client(socket_path: &str) -> Result<Arc<ZinitClientWrapper>, ClientError> {
// Connect via Unix socket
let client = ZinitClient::unix_socket(socket_path).await?;
let wrapper = Arc::new(ZinitClientWrapper::new(client));
// Initialize the client
@ -156,7 +158,7 @@ async fn create_zinit_client(socket_path: &str) -> Result<Arc<ZinitClientWrapper
}
// Reset the Zinit client
pub async fn reset(socket_path: &str) -> Result<(), ZinitError> {
pub async fn reset(socket_path: &str) -> Result<(), ClientError> {
// Clear the existing client
{
let mut client_guard = ZINIT_CLIENT.lock().unwrap();
@ -170,40 +172,32 @@ pub async fn reset(socket_path: &str) -> Result<(), ZinitError> {
// Convenience functions for common operations
// List all services - convert ServiceState to String for compatibility
pub async fn list(socket_path: &str) -> Result<HashMap<String, String>, ZinitError> {
// List all services
pub async fn list(socket_path: &str) -> Result<HashMap<String, String>, ClientError> {
let client = get_zinit_client(socket_path).await?;
let services = client.list().await?;
// Convert HashMap<String, ServiceState> to HashMap<String, String>
let mut result = HashMap::new();
for (name, state) in services {
result.insert(name, format!("{:?}", state));
}
Ok(result)
client.list().await
}
// Get status of a service
pub async fn status(socket_path: &str, name: &str) -> Result<Status, ZinitError> {
pub async fn status(socket_path: &str, name: &str) -> Result<Status, ClientError> {
let client = get_zinit_client(socket_path).await?;
client.status(name).await
}
// Start a service
pub async fn start(socket_path: &str, name: &str) -> Result<(), ZinitError> {
pub async fn start(socket_path: &str, name: &str) -> Result<(), ClientError> {
let client = get_zinit_client(socket_path).await?;
client.start(name).await
}
// Stop a service
pub async fn stop(socket_path: &str, name: &str) -> Result<(), ZinitError> {
pub async fn stop(socket_path: &str, name: &str) -> Result<(), ClientError> {
let client = get_zinit_client(socket_path).await?;
client.stop(name).await
}
// Restart a service
pub async fn restart(socket_path: &str, name: &str) -> Result<(), ZinitError> {
pub async fn restart(socket_path: &str, name: &str) -> Result<(), ClientError> {
let client = get_zinit_client(socket_path).await?;
client.restart(name).await
}

View File

@ -17,6 +17,6 @@ serde_json = "1.0.140"
chacha20poly1305 = "0.10.1"
k256 = { version = "0.13.4", features = ["ecdh"] }
sha2 = "0.10.9"
kv = { git = "https://git.threefold.info/samehabouelsaad/sal-modular", package = "kvstore", rev = "9dce815daa" }
kv = { git = "https://git.ourworld.tf/samehabouelsaad/sal-modular", package = "kvstore", rev = "9dce815daa" }
bincode = { version = "2.0.1", features = ["serde"] }
pbkdf2 = "0.12.2"