sbox 0.2.4

Tiny Linux containers implementation
Documentation
use std::fmt::Debug;
use std::fs::File;
use std::io::Write as _;
use std::panic::RefUnwindSafe;
use std::path::PathBuf;

use crate::{Error, Pid};

pub trait NetworkHandle: Send + Sync + Debug + RefUnwindSafe {}

pub trait NetworkManager: Send + Sync + Debug + RefUnwindSafe {
    fn run_network(&self, pid: Pid) -> Result<Option<Box<dyn NetworkHandle>>, Error>;

    fn set_network(&self) -> Result<(), Error>;
}

#[derive(Debug)]
pub struct Slirp4NetnsManager {
    pub binary: PathBuf,
}

impl Slirp4NetnsManager {
    pub fn new() -> Self {
        Self {
            binary: "/bin/slirp4netns".into(),
        }
    }
}

impl Default for Slirp4NetnsManager {
    fn default() -> Self {
        Slirp4NetnsManager::new()
    }
}

impl NetworkManager for Slirp4NetnsManager {
    fn run_network(&self, pid: Pid) -> Result<Option<Box<dyn NetworkHandle>>, Error> {
        let handle = std::process::Command::new(&self.binary)
            .arg("--configure")
            .arg("--mtu=65520")
            .arg("--disable-host-loopback")
            .arg(pid.to_string())
            .arg("tap0")
            .spawn()?;
        Ok(Some(Box::new(Slirp4NetnsHandle { handle })))
    }

    fn set_network(&self) -> Result<(), Error> {
        Ok(File::create("/etc/resolv.conf")?.write_all("nameserver 10.0.2.3".as_bytes())?)
    }
}

#[derive(Debug)]
pub struct Slirp4NetnsHandle {
    handle: std::process::Child,
}

impl NetworkHandle for Slirp4NetnsHandle {}

impl Drop for Slirp4NetnsHandle {
    fn drop(&mut self) {
        let _ = self.handle.kill();
        let _ = self.handle.wait();
    }
}