mongo_embedded/
process.rs1use anyhow::{anyhow, Result};
2use std::process::{Child, Command};
3use std::path::{Path, PathBuf};
4use crate::downloader::Os;
5
6pub struct MongoProcess {
7 child: Child,
8 db_path: PathBuf,
9}
10
11impl MongoProcess {
12 pub fn start(
13 extracted_path: &Path,
14 port: u16,
15 db_path: &Path,
16 os: &Os,
17 bind_ip: &str,
18 ) -> Result<Self> {
19 let binary_name = match os {
20 Os::Windows => "mongod.exe",
21 _ => "mongod",
22 };
23
24 let binary_path = find_binary(extracted_path, binary_name)
25 .ok_or_else(|| anyhow!("Could not find {} in extracted directory", binary_name))?;
26
27 #[cfg(unix)]
29 {
30 use std::os::unix::fs::PermissionsExt;
31 let mut perms = std::fs::metadata(&binary_path)?.permissions();
32 perms.set_mode(0o755);
33 std::fs::set_permissions(&binary_path, perms)?;
34 }
35
36 if !db_path.exists() {
37 std::fs::create_dir_all(db_path)?;
38 }
39
40 let child = Command::new(binary_path)
41 .arg("--port")
42 .arg(port.to_string())
43 .arg("--dbpath")
44 .arg(db_path)
45 .arg("--bind_ip")
46 .arg(bind_ip)
47 .spawn()?;
48
49 Ok(Self { child, db_path: db_path.to_path_buf() })
50 }
51
52 pub fn kill(&mut self) -> Result<()> {
53 self.child.kill()?;
54 self.child.wait()?;
55 Ok(())
56 }
57}
58
59fn find_binary(root: &Path, name: &str) -> Option<PathBuf> {
60 if root.is_file() {
61 if root.file_name()?.to_str()? == name {
62 return Some(root.to_path_buf());
63 }
64 return None;
65 }
66
67 if root.is_dir() {
68 for entry in std::fs::read_dir(root).ok()? {
69 let entry = entry.ok()?;
70 let path = entry.path();
71 if let Some(found) = find_binary(&path, name) {
72 return Some(found);
73 }
74 }
75 }
76 None
77}