bind mounts
This commit is contained in:
parent
04c2a85e3a
commit
bb28c74833
@ -10,6 +10,7 @@ use std::ffi::CString;
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use nix::unistd;
|
use nix::unistd;
|
||||||
|
|
||||||
@ -29,10 +30,15 @@ impl<'a> Spawner<'a> {
|
|||||||
|
|
||||||
match &entrypoint.trigger {
|
match &entrypoint.trigger {
|
||||||
Trigger::Startup => {
|
Trigger::Startup => {
|
||||||
|
let binary = PathBuf::from(self.binary).canonicalize()?;
|
||||||
|
|
||||||
|
let mut builder = VoidBuilder::new();
|
||||||
|
builder.mount(binary, "/entrypoint");
|
||||||
|
|
||||||
let closure = || {
|
let closure = || {
|
||||||
let args = self.prepare_args(name, &entrypoint.args, None);
|
let args = self.prepare_args(name, &entrypoint.args, None);
|
||||||
|
|
||||||
if let Err(e) = unistd::execv(&CString::new(self.binary).unwrap(), &args)
|
if let Err(e) = unistd::execv(&CString::new("/entrypoint").unwrap(), &args)
|
||||||
.map_err(|e| Error::Nix {
|
.map_err(|e| Error::Nix {
|
||||||
msg: "execv",
|
msg: "execv",
|
||||||
src: e,
|
src: e,
|
||||||
@ -45,14 +51,15 @@ impl<'a> Spawner<'a> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut builder = VoidBuilder::new();
|
|
||||||
builder.spawn(closure)?;
|
builder.spawn(closure)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Trigger::Pipe(s) => {
|
Trigger::Pipe(s) => {
|
||||||
let pipe = self.pipes.get_mut(s).unwrap().take_read();
|
let pipe = self.pipes.get_mut(s).unwrap().take_read();
|
||||||
|
let binary = PathBuf::from(self.binary).canonicalize()?;
|
||||||
|
|
||||||
let mut builder = VoidBuilder::new();
|
let mut builder = VoidBuilder::new();
|
||||||
|
builder.mount(binary, "/entrypoint");
|
||||||
builder.keep_fd(&pipe);
|
builder.keep_fd(&pipe);
|
||||||
|
|
||||||
let closure = || match self.pipe_trigger(pipe, entrypoint, name) {
|
let closure = || match self.pipe_trigger(pipe, entrypoint, name) {
|
||||||
@ -87,7 +94,7 @@ impl<'a> Spawner<'a> {
|
|||||||
let pipe_trigger = std::str::from_utf8(&buf[0..read_bytes]).unwrap();
|
let pipe_trigger = std::str::from_utf8(&buf[0..read_bytes]).unwrap();
|
||||||
let args = self.prepare_args_ref(name, &spec.args, Some(pipe_trigger));
|
let args = self.prepare_args_ref(name, &spec.args, Some(pipe_trigger));
|
||||||
|
|
||||||
if let Err(e) = unistd::execv(&CString::new(self.binary).unwrap(), &args)
|
if let Err(e) = unistd::execv(&CString::new("/entrypoint").unwrap(), &args)
|
||||||
.map_err(|e| Error::Nix {
|
.map_err(|e| Error::Nix {
|
||||||
msg: "execv",
|
msg: "execv",
|
||||||
src: e,
|
src: e,
|
||||||
|
37
src/void.rs
37
src/void.rs
@ -6,7 +6,7 @@ use crate::{Error, Result};
|
|||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use nix::mount::{mount, umount2, MntFlags, MsFlags};
|
use nix::mount::{mount, umount2, MntFlags, MsFlags};
|
||||||
use nix::sched::unshare;
|
use nix::sched::unshare;
|
||||||
@ -31,8 +31,8 @@ impl VoidBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn mount(&mut self, src: PathBuf, dst: PathBuf) -> &mut Self {
|
pub fn mount<T1: AsRef<Path>, T2: AsRef<Path>>(&mut self, src: T1, dst: T2) -> &mut Self {
|
||||||
self.mounts.insert(src, dst);
|
self.mounts.insert(src.as_ref().into(), dst.as_ref().into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,10 +144,37 @@ impl VoidBuilder {
|
|||||||
// chdir after
|
// chdir after
|
||||||
std::env::set_current_dir("/")?;
|
std::env::set_current_dir("/")?;
|
||||||
|
|
||||||
// TODO: mount requested mounts
|
// mount paths before unmounting old_root
|
||||||
|
for (src, dst) in &self.mounts {
|
||||||
|
let src = PathBuf::from("/old_root/").join(src.strip_prefix("/").unwrap_or(src));
|
||||||
|
let dst = PathBuf::from("/").join(dst);
|
||||||
|
|
||||||
|
debug!("mounting `{:?}` as `{:?}`", src, dst);
|
||||||
|
|
||||||
|
// create the target
|
||||||
|
let src_data = fs::metadata(&src)?;
|
||||||
|
if src_data.is_dir() {
|
||||||
|
fs::create_dir_all(&dst)?;
|
||||||
|
} else {
|
||||||
|
fs::write(&dst, b"")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind mount
|
||||||
|
mount(
|
||||||
|
Some(&src),
|
||||||
|
&dst,
|
||||||
|
Option::<&str>::None,
|
||||||
|
MsFlags::MS_BIND,
|
||||||
|
Option::<&str>::None,
|
||||||
|
)
|
||||||
|
.map_err(|e| Error::Nix {
|
||||||
|
msg: "mount",
|
||||||
|
src: e,
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
// unmount the old root
|
// unmount the old root
|
||||||
umount2("old_root/", MntFlags::MNT_DETACH).map_err(|e| Error::Nix {
|
umount2("/old_root/", MntFlags::MNT_DETACH).map_err(|e| Error::Nix {
|
||||||
msg: "umount2",
|
msg: "umount2",
|
||||||
src: e,
|
src: e,
|
||||||
})?;
|
})?;
|
||||||
|
Loading…
Reference in New Issue
Block a user