Add daemon management commands
Signed-off-by: trivernis <trivernis@protonmail.com>pull/4/head
parent
aab7f71e12
commit
305ac256d1
@ -0,0 +1,82 @@
|
|||||||
|
use crate::daemon_management::error::{DaemonError, DaemonResult};
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
use tokio::process::{Child, Command};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DaemonCli {
|
||||||
|
daemon_path: String,
|
||||||
|
repo_path: String,
|
||||||
|
child: Option<Child>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DaemonCli {
|
||||||
|
pub fn new(daemon_path: String, repo_path: String) -> Self {
|
||||||
|
Self {
|
||||||
|
daemon_path,
|
||||||
|
repo_path,
|
||||||
|
child: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initializes a repository at the specified path
|
||||||
|
#[tracing::instrument]
|
||||||
|
pub async fn init_repo(&self) -> DaemonResult<()> {
|
||||||
|
let output = self
|
||||||
|
.run_command(vec!["--repo", self.repo_path.as_str(), "init"])
|
||||||
|
.await?;
|
||||||
|
tracing::debug!("Response: {}", String::from_utf8(output).unwrap());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Starts a daemon for the given repository
|
||||||
|
#[tracing::instrument]
|
||||||
|
pub fn start_daemon(&mut self) -> DaemonResult<()> {
|
||||||
|
let child = self.run_daemon_process(vec!["--repo", self.repo_path.as_str(), "start"])?;
|
||||||
|
self.child = Some(child);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns if the daemon is currently running
|
||||||
|
pub fn daemon_running(&mut self) -> bool {
|
||||||
|
if let Some(child) = &mut self.child {
|
||||||
|
child.try_wait().map(|e| e.is_some()).unwrap_or(true)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the path the daemon is serving
|
||||||
|
pub fn repo_path(&self) -> &String {
|
||||||
|
&self.repo_path
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Runs a daemon subcommand
|
||||||
|
async fn run_command<S: AsRef<OsStr>, I: IntoIterator<Item = S>>(
|
||||||
|
&self,
|
||||||
|
args: I,
|
||||||
|
) -> DaemonResult<Vec<u8>> {
|
||||||
|
let child = self.run_daemon_process(args)?;
|
||||||
|
let output = child.wait_with_output().await?;
|
||||||
|
|
||||||
|
if output.status.success() {
|
||||||
|
Ok(output.stdout)
|
||||||
|
} else {
|
||||||
|
let stdout = String::from_utf8(output.stdout).map_err(|e| e.to_string())?;
|
||||||
|
let stderr = String::from_utf8(output.stderr).map_err(|e| e.to_string())?;
|
||||||
|
Err(DaemonError::from(format!("{}\n{}", stdout, stderr)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Runs a daemon process with the given args
|
||||||
|
fn run_daemon_process<S: AsRef<OsStr>, I: IntoIterator<Item = S>>(
|
||||||
|
&self,
|
||||||
|
args: I,
|
||||||
|
) -> DaemonResult<Child> {
|
||||||
|
Command::new(&self.daemon_path)
|
||||||
|
.args(args)
|
||||||
|
.spawn()
|
||||||
|
.map_err(DaemonError::from)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
pub type DaemonResult<T> = Result<T, DaemonError>;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DaemonError {
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for DaemonError {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
self.message.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for DaemonError {}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for DaemonError {
|
||||||
|
fn from(e: std::io::Error) -> Self {
|
||||||
|
Self {
|
||||||
|
message: e.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for DaemonError {
|
||||||
|
fn from(s: String) -> Self {
|
||||||
|
Self { message: s }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
pub mod cli;
|
||||||
|
pub mod error;
|
@ -0,0 +1,25 @@
|
|||||||
|
use crate::client_api::ApiClient;
|
||||||
|
use crate::tauri_plugin::commands::AppAccess;
|
||||||
|
use crate::tauri_plugin::error::PluginResult;
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn init_repository(app_state: AppAccess<'_>, repo_path: String) -> PluginResult<()> {
|
||||||
|
let daemon = app_state.get_daemon_cli(repo_path).await;
|
||||||
|
daemon.init_repo().await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn start_daemon(app_state: AppAccess<'_>, repo_path: String) -> PluginResult<()> {
|
||||||
|
let mut daemon = app_state.get_daemon_cli(repo_path).await;
|
||||||
|
daemon.start_daemon()?;
|
||||||
|
app_state.add_started_daemon(daemon).await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn check_daemon_running(address: String) -> PluginResult<bool> {
|
||||||
|
Ok(ApiClient::connect(&address).await.is_ok())
|
||||||
|
}
|
Loading…
Reference in New Issue