1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
use async_std::os::unix::net::UnixListener; use std::error::Error; use std::fs::Permissions; use std::path::PathBuf; use std::os::unix::fs::PermissionsExt; use tempfile::TempDir; const TEMP_DIR_PREFIX: &'static str = "rect-socket."; const TEMP_DIR_MODE: u32 = 0o700; pub struct SocketPool { pub mount_args: Vec<String>, dir: TempDir, } pub struct Socket { pub socket_path: PathBuf, pub listener: UnixListener, } impl SocketPool { pub fn new() -> Result<SocketPool, Box<dyn Error>> { let dir = tempfile::Builder::new().prefix(TEMP_DIR_PREFIX).tempdir()?; std::fs::set_permissions(&dir, Permissions::from_mode(TEMP_DIR_MODE))?; Ok(SocketPool { mount_args: vec![], dir }) } pub async fn bind(&mut self, path_in_container: &str) -> Result<Socket, Box<dyn Error>> { let arbitrary_id = self.mount_args.len().to_string(); let socket_path = self.dir.path().join(arbitrary_id); let socket_path_str = socket_path.to_str().unwrap(); self.mount_args.push(format!("-v={}:{}", socket_path_str, path_in_container)); let listener = UnixListener::bind(&socket_path).await?; Ok(Socket{ listener, socket_path }) } }