mongo_embedded/
process.rs

1use 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        // Ensure binary is executable on Unix
28        #[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}