Skip to content

Commit

Permalink
Merge pull request #8 from Hirevo/feature/recursive-walk
Browse files Browse the repository at this point in the history
Added Git-like daemon discovery + `init` subcommand
  • Loading branch information
Hirevo authored Mar 23, 2021
2 parents 2e11b1e + 9bd6ffd commit a112b6a
Show file tree
Hide file tree
Showing 16 changed files with 200 additions and 128 deletions.
51 changes: 14 additions & 37 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 13 additions & 3 deletions persist-core/src/daemon/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,19 @@ pub static PIDS_DIR: &str = "pids";
pub static LOGS_DIR: &str = "logs";

pub fn home_dir() -> Result<PathBuf, Error> {
fn recursive_search() -> Result<PathBuf, Error> {
let current_dir = env::current_dir()?;

let found = current_dir
.ancestors()
.map(|path| path.join(".persist"))
.find(|path| path.is_dir())
.ok_or(PersistError::DaemonNotFound)?;

Ok(found)
}

env::var("PERSIST_HOME")
.ok()
.map(PathBuf::from)
.or_else(|| dirs::home_dir().map(|home| home.join(".persist")))
.ok_or_else(|| Error::from(PersistError::HomeDirNotFound))
.or_else(|_| recursive_search())
}
2 changes: 2 additions & 0 deletions persist-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ pub enum PersistError {
ProcessNotFound,
#[error("could not find home directory")]
HomeDirNotFound,
#[error("could not find any running daemon")]
DaemonNotFound,
}

#[derive(Debug, Error)]
Expand Down
15 changes: 15 additions & 0 deletions persist-core/src/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,21 @@ pub struct ProcessInfo {
pub created_at: chrono::NaiveDateTime,
}

impl From<ProcessInfo> for ProcessSpec {
fn from(info: ProcessInfo) -> ProcessSpec {
ProcessSpec {
name: info.name,
cmd: info.cmd,
cwd: info.cwd,
env: info.env,
pid_path: info.pid_path,
stdout_path: info.stdout_path,
stderr_path: info.stderr_path,
created_at: info.created_at,
}
}
}

/// The log stream source.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
Expand Down
6 changes: 0 additions & 6 deletions persist-daemon/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::env;

use nix::unistd::ForkResult;
use serde::{Deserialize, Serialize};
use structopt::StructOpt;
Expand Down Expand Up @@ -37,10 +35,6 @@ fn main() -> Result<(), Error> {
std::process::exit(0);
}

let home_dir = persist_core::daemon::home_dir()?;
let _ = std::fs::create_dir(&home_dir);
env::set_current_dir(home_dir)?;

let mut runtime = Runtime::new()?;
let outcome = runtime.block_on(server::start());
if let Err(err) = outcome {
Expand Down
5 changes: 3 additions & 2 deletions persist-daemon/src/server/request/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ pub async fn handle(
let names = match req.filters {
Some(filters) => filters,
None => {
let future = state.with_handles(|handles| handles.keys().cloned().collect());
future.await
state
.with_handles(|handles| handles.keys().cloned().collect())
.await
}
};

Expand Down
5 changes: 3 additions & 2 deletions persist-daemon/src/server/request/restart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ pub async fn handle(
let names = match request.filters {
Some(names) => names,
None => {
let future = state.with_handles(|handles| handles.keys().cloned().collect());
future.await
state
.with_handles(|handles| handles.keys().cloned().collect())
.await
}
};
let updated_env = request.env;
Expand Down
33 changes: 0 additions & 33 deletions persist-daemon/src/server/request/restore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use futures::sink::SinkExt;
use tokio::net::UnixStream;
use tokio_util::codec::{Framed, LinesCodec};

use persist_core::daemon::{self, LOGS_DIR, PIDS_DIR};
use persist_core::error::Error;
use persist_core::protocol::{Response, RestoreRequest, RestoreResponse};

Expand All @@ -19,38 +18,6 @@ pub async fn handle(
let futures = req.specs.into_iter().map(|spec| async {
let name = spec.name.clone();

//? get dirs paths
let home_dir = daemon::home_dir()?;
let pids_dir = home_dir.join(PIDS_DIR);
let logs_dir = home_dir.join(LOGS_DIR);

//? ensure they exists
let future = future::join(
tokio::fs::create_dir(&pids_dir),
tokio::fs::create_dir(&logs_dir),
);
let _ = future.await;

//? get PID file path
let pid_path = format!("{}.pid", spec.name);
let pid_path = pids_dir.join(pid_path);

//? get stdout file path
let stdout_path = format!("{}-out.log", spec.name);
let stdout_path = logs_dir.join(stdout_path);

//? get stderr file path
let stderr_path = format!("{}-err.log", spec.name);
let stderr_path = logs_dir.join(stderr_path);

//? ensure they exists
let future = future::join3(
tokio::fs::File::create(pid_path.as_path()),
tokio::fs::File::create(stdout_path.as_path()),
tokio::fs::File::create(stderr_path.as_path()),
);
let _ = future.await;

let res = state.clone().start(spec).await;
let error = res.err().map(|err| err.to_string());

Expand Down
47 changes: 7 additions & 40 deletions persist-daemon/src/server/request/start.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use std::path::PathBuf;
use std::sync::Arc;

use futures::future;
use futures::sink::SinkExt;
use tokio::net::UnixStream;
use tokio_util::codec::{Framed, LinesCodec};

use persist_core::daemon::{self, LOGS_DIR, PIDS_DIR};
use persist_core::error::Error;
use persist_core::protocol::{ProcessSpec, Response, StartRequest, StartResponse};

Expand All @@ -16,55 +15,23 @@ pub async fn handle(
conn: &mut Framed<UnixStream, LinesCodec>,
spec: StartRequest,
) -> Result<(), Error> {
//? get dirs paths
let home_dir = daemon::home_dir()?;
let pids_dir = home_dir.join(PIDS_DIR);
let logs_dir = home_dir.join(LOGS_DIR);

//? ensure they exists
let future = future::join(
tokio::fs::create_dir(&pids_dir),
tokio::fs::create_dir(&logs_dir),
);
let _ = future.await;

//? get PID file path
let pid_path = format!("{}.pid", spec.name);
let pid_path = pids_dir.join(pid_path);

//? get stdout file path
let stdout_path = format!("{}-out.log", spec.name);
let stdout_path = logs_dir.join(stdout_path);

//? get stderr file path
let stderr_path = format!("{}-err.log", spec.name);
let stderr_path = logs_dir.join(stderr_path);

//? ensure they exists
let future = future::join3(
tokio::fs::File::create(pid_path.as_path()),
tokio::fs::File::create(stdout_path.as_path()),
tokio::fs::File::create(stderr_path.as_path()),
);
let _ = future.await;

//? construct process spec
let now = chrono::Local::now().naive_local();

let spec = ProcessSpec {
name: spec.name,
cmd: spec.cmd,
env: spec.env,
cwd: spec.cwd,
created_at: now,
pid_path: pid_path.canonicalize()?,
stdout_path: stdout_path.canonicalize()?,
stderr_path: stderr_path.canonicalize()?,
pid_path: PathBuf::new(),
stdout_path: PathBuf::new(),
stderr_path: PathBuf::new(),
};

//? start the process according to that spec
state.start(spec.clone()).await?;
let info = state.start(spec).await?;

let response = Response::Start(StartResponse { spec });
let response = Response::Start(StartResponse { spec: info.into() });
let serialized = json::to_string(&response)?;
conn.send(serialized).await?;

Expand Down
Loading

0 comments on commit a112b6a

Please sign in to comment.