You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mediarepo/mediarepo-api/src/daemon_management/cli.rs

96 lines
2.7 KiB
Rust

use crate::daemon_management::error::{DaemonError, DaemonResult};
use std::ffi::OsStr;
use std::mem;
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(())
}
/// Kills the running daemon process if there's one associated with the
/// daemon cli
#[tracing::instrument]
pub async fn stop_daemon(&mut self) -> DaemonResult<()> {
if let Some(mut child) = mem::take(&mut self.child) {
child.kill().await?;
}
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)
.kill_on_drop(true)
.spawn()
.map_err(DaemonError::from)
}
}