Files
start-os/core/startos/src/service/cli.rs
2024-06-25 18:34:47 +00:00

70 lines
1.9 KiB
Rust

use std::path::{Path, PathBuf};
use std::sync::Arc;
use clap::Parser;
use imbl_value::Value;
use once_cell::sync::OnceCell;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{call_remote_socket, yajrc, CallRemote, Context, Empty};
use tokio::runtime::Runtime;
use crate::lxc::HOST_RPC_SERVER_SOCKET;
use crate::service::service_effect_handler::EffectContext;
#[derive(Debug, Default, Parser)]
pub struct ContainerClientConfig {
#[arg(long = "socket")]
pub socket: Option<PathBuf>,
}
pub struct ContainerCliSeed {
socket: PathBuf,
runtime: OnceCell<Arc<Runtime>>,
}
#[derive(Clone)]
pub struct ContainerCliContext(Arc<ContainerCliSeed>);
impl ContainerCliContext {
pub fn init(cfg: ContainerClientConfig) -> Self {
Self(Arc::new(ContainerCliSeed {
socket: cfg
.socket
.unwrap_or_else(|| Path::new("/media/startos/rpc").join(HOST_RPC_SERVER_SOCKET)),
runtime: OnceCell::new(),
}))
}
}
impl Context for ContainerCliContext {
fn runtime(&self) -> Option<Arc<Runtime>> {
Some(
self.0
.runtime
.get_or_init(|| {
Arc::new(
tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap(),
)
})
.clone(),
)
}
}
impl CallRemote<EffectContext> for ContainerCliContext {
async fn call_remote(&self, method: &str, params: Value, _: Empty) -> Result<Value, RpcError> {
call_remote_socket(
tokio::net::UnixStream::connect(&self.0.socket)
.await
.map_err(|e| RpcError {
data: Some(e.to_string().into()),
..yajrc::INTERNAL_ERROR
})?,
method,
params,
)
.await
}
}