123 lines
4.8 KiB
Rust
123 lines
4.8 KiB
Rust
use crate::{ServiceConfig, ServiceManager, ServiceManagerError, ServiceStatus};
|
|
use async_trait::async_trait;
|
|
use serde_json::json;
|
|
use std::sync::Arc;
|
|
use zinit_client::{get_zinit_client, ServiceStatus as ZinitServiceStatus, ZinitClientWrapper};
|
|
|
|
pub struct ZinitServiceManager {
|
|
client: Arc<ZinitClientWrapper>,
|
|
}
|
|
|
|
impl ZinitServiceManager {
|
|
pub fn new(socket_path: &str) -> Result<Self, ServiceManagerError> {
|
|
// This is a blocking call to get the async client.
|
|
// We might want to make this async in the future if the constructor can be async.
|
|
let client = tokio::runtime::Runtime::new()
|
|
.unwrap()
|
|
.block_on(get_zinit_client(socket_path))
|
|
.map_err(|e| ServiceManagerError::Other(e.to_string()))?;
|
|
Ok(ZinitServiceManager { client })
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl ServiceManager for ZinitServiceManager {
|
|
fn exists(&self, service_name: &str) -> Result<bool, ServiceManagerError> {
|
|
let status_res = self.status(service_name);
|
|
match status_res {
|
|
Ok(_) => Ok(true),
|
|
Err(ServiceManagerError::ServiceNotFound(_)) => Ok(false),
|
|
Err(e) => Err(e),
|
|
}
|
|
}
|
|
|
|
fn start(&self, config: &ServiceConfig) -> Result<(), ServiceManagerError> {
|
|
let service_config = json!({
|
|
"exec": config.binary_path,
|
|
"args": config.args,
|
|
"working_directory": config.working_directory,
|
|
"env": config.environment,
|
|
"restart": config.auto_restart,
|
|
});
|
|
|
|
tokio::runtime::Runtime::new()
|
|
.unwrap()
|
|
.block_on(self.client.create_service(&config.name, service_config))
|
|
.map_err(|e| ServiceManagerError::StartFailed(config.name.clone(), e.to_string()))?;
|
|
|
|
self.start_existing(&config.name)
|
|
}
|
|
|
|
fn start_existing(&self, service_name: &str) -> Result<(), ServiceManagerError> {
|
|
tokio::runtime::Runtime::new()
|
|
.unwrap()
|
|
.block_on(self.client.start(service_name))
|
|
.map_err(|e| ServiceManagerError::StartFailed(service_name.to_string(), e.to_string()))
|
|
}
|
|
|
|
async fn start_and_confirm(&self, config: &ServiceConfig, _timeout_secs: u64) -> Result<(), ServiceManagerError> {
|
|
self.start(config)
|
|
}
|
|
|
|
async fn run(&self, config: &ServiceConfig, _timeout_secs: u64) -> Result<(), ServiceManagerError> {
|
|
self.start(config)
|
|
}
|
|
|
|
async fn start_existing_and_confirm(&self, service_name: &str, _timeout_secs: u64) -> Result<(), ServiceManagerError> {
|
|
self.start_existing(service_name)
|
|
}
|
|
|
|
fn stop(&self, service_name: &str) -> Result<(), ServiceManagerError> {
|
|
tokio::runtime::Runtime::new()
|
|
.unwrap()
|
|
.block_on(self.client.stop(service_name))
|
|
.map_err(|e| ServiceManagerError::StopFailed(service_name.to_string(), e.to_string()))
|
|
}
|
|
|
|
fn restart(&self, service_name: &str) -> Result<(), ServiceManagerError> {
|
|
tokio::runtime::Runtime::new()
|
|
.unwrap()
|
|
.block_on(self.client.restart(service_name))
|
|
.map_err(|e| ServiceManagerError::RestartFailed(service_name.to_string(), e.to_string()))
|
|
}
|
|
|
|
fn status(&self, service_name: &str) -> Result<ServiceStatus, ServiceManagerError> {
|
|
let status: ZinitServiceStatus = tokio::runtime::Runtime::new()
|
|
.unwrap()
|
|
.block_on(self.client.status(service_name))
|
|
.map_err(|e| ServiceManagerError::Other(e.to_string()))?;
|
|
|
|
let service_status = match status {
|
|
ZinitServiceStatus::Running(_) => crate::ServiceStatus::Running,
|
|
ZinitServiceStatus::Stopped => crate::ServiceStatus::Stopped,
|
|
ZinitServiceStatus::Failed(_) => crate::ServiceStatus::Failed,
|
|
ZinitServiceStatus::Waiting(_) => crate::ServiceStatus::Unknown,
|
|
};
|
|
Ok(service_status)
|
|
}
|
|
|
|
fn logs(&self, service_name: &str, _lines: Option<usize>) -> Result<String, ServiceManagerError> {
|
|
let logs = tokio::runtime::Runtime::new()
|
|
.unwrap()
|
|
.block_on(self.client.logs(Some(service_name.to_string())))
|
|
.map_err(|e| ServiceManagerError::LogsFailed(service_name.to_string(), e.to_string()))?;
|
|
Ok(logs.join("\n"))
|
|
}
|
|
|
|
fn list(&self) -> Result<Vec<String>, ServiceManagerError> {
|
|
let services = tokio::runtime::Runtime::new()
|
|
.unwrap()
|
|
.block_on(self.client.list())
|
|
.map_err(|e| ServiceManagerError::Other(e.to_string()))?;
|
|
Ok(services.keys().cloned().collect())
|
|
}
|
|
|
|
fn remove(&self, service_name: &str) -> Result<(), ServiceManagerError> {
|
|
let _ = self.stop(service_name); // Best effort to stop before removing
|
|
tokio::runtime::Runtime::new()
|
|
.unwrap()
|
|
.block_on(self.client.delete_service(service_name))
|
|
.map_err(|e| ServiceManagerError::Other(e.to_string()))
|
|
}
|
|
}
|