Skip to content

Commit

Permalink
Trying to implement From<MappedDirectory> for MountedDirectory
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael-F-Bryan committed Dec 14, 2023
1 parent 93f5e3a commit 29746d1
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 45 deletions.
36 changes: 4 additions & 32 deletions lib/wasix/src/runners/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,7 @@ mod wasi_common;
#[cfg(feature = "webc_runner_rt_wcgi")]
pub mod wcgi;

pub use self::{runner::Runner, wasi_common::MappedCommand};

use std::sync::Arc;

use virtual_fs::FileSystem;

/// A directory that should be mapped from the host filesystem into a WASI
/// instance (the "guest").
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct MappedDirectory {
/// The absolute path for a directory on the host filesystem.
pub host: std::path::PathBuf,
/// The absolute path specifying where the host directory should be mounted
/// inside the guest.
pub guest: String,
}

#[derive(Debug, Clone)]
pub struct MountedDirectory {
pub guest: String,
pub fs: Arc<dyn FileSystem + Send + Sync>,
}

impl From<MappedDirectory> for MountedDirectory {
fn from(value: MappedDirectory) -> Self {
let MappedDirectory { host: _, guest } = value;
// TODO: Mount just the directory
let fs = Arc::new(crate::default_fs_backing());

MountedDirectory { guest, fs }
}
}
pub use self::{
runner::Runner,
wasi_common::{MappedCommand, MappedDirectory, MountedDirectory},
};
55 changes: 44 additions & 11 deletions lib/wasix/src/runners/wasi_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ use futures::future::BoxFuture;
use virtual_fs::{FileSystem, FsError, OverlayFileSystem, RootFileSystemBuilder, TmpFileSystem};
use webc::metadata::annotations::Wasi as WasiAnnotation;

use crate::{
bin_factory::BinaryPackage, capabilities::Capabilities, runners::MountedDirectory,
WasiEnvBuilder,
};
use crate::{bin_factory::BinaryPackage, capabilities::Capabilities, WasiEnvBuilder};

#[derive(Debug, Clone)]
pub struct MappedCommand {
Expand Down Expand Up @@ -43,7 +40,7 @@ impl CommonWasiOptions {
root_fs: Option<TmpFileSystem>,
) -> Result<(), anyhow::Error> {
let root_fs = root_fs.unwrap_or_else(|| RootFileSystemBuilder::default().build());
let fs = prepare_filesystem(root_fs, &self.mounts, container_fs, builder)?;
let fs = prepare_filesystem(root_fs, &self.mounts, container_fs)?;

builder.add_preopen_dir("/")?;

Expand Down Expand Up @@ -107,7 +104,6 @@ impl CommonWasiOptions {
// OverlayFileSystem<TmpFileSystem, [RelativeOrAbsolutePathHack<Arc<dyn FileSystem>>; 1]>;

fn build_directory_mappings(
builder: &mut WasiEnvBuilder,
root_fs: &mut TmpFileSystem,
mounted_dirs: &[MountedDirectory],
) -> Result<(), anyhow::Error> {
Expand Down Expand Up @@ -159,10 +155,9 @@ fn prepare_filesystem(
mut root_fs: TmpFileSystem,
mounted_dirs: &[MountedDirectory],
container_fs: Option<Arc<dyn FileSystem + Send + Sync>>,
builder: &mut WasiEnvBuilder,
) -> Result<Box<dyn FileSystem + Send + Sync>, Error> {
if !mounted_dirs.is_empty() {
build_directory_mappings(builder, &mut root_fs, mounted_dirs)?;
build_directory_mappings(&mut root_fs, mounted_dirs)?;
}

// HACK(Michael-F-Bryan): The WebcVolumeFileSystem only accepts relative
Expand Down Expand Up @@ -230,6 +225,46 @@ fn create_dir_all(fs: &dyn FileSystem, path: &Path) -> Result<(), Error> {
Ok(())
}

/// A directory that should be mapped from the host filesystem into a WASI
/// instance (the "guest").
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct MappedDirectory {
/// The absolute path for a directory on the host filesystem.
pub host: std::path::PathBuf,
/// The absolute path specifying where the host directory should be mounted
/// inside the guest.
pub guest: String,
}

#[derive(Debug, Clone)]
pub struct MountedDirectory {
pub guest: String,
pub fs: Arc<dyn FileSystem + Send + Sync>,
}

impl From<MappedDirectory> for MountedDirectory {
fn from(value: MappedDirectory) -> Self {
let MappedDirectory { host, guest } = value;

// HACK: We don't have a FileSystem implementation that lets you mount
// just a single folder, so we're going to work around that using a mem
// fs and its mounting infrastructure.
let host_fs = Arc::new(crate::default_fs_backing()) as Arc<dyn FileSystem + Send + Sync>;
let temp_fs = virtual_fs::mem_fs::FileSystem::default();
if let Some(parent) = Path::new(&guest).parent() {
create_dir_all(&temp_fs, parent).unwrap();
}
temp_fs
.mount(PathBuf::from(&guest), &host_fs, host)
.unwrap();

MountedDirectory {
guest,
fs: Arc::new(temp_fs),
}
}
}

#[derive(Debug)]
struct RelativeOrAbsolutePathHack<F>(F);

Expand Down Expand Up @@ -381,11 +416,9 @@ mod tests {
})];
let container = Container::from_bytes(PYTHON).unwrap();
let webc_fs = WebcVolumeFileSystem::mount_all(&container);
let mut builder = WasiEnvBuilder::new("");

let root_fs = RootFileSystemBuilder::default().build();
let fs =
prepare_filesystem(root_fs, &mapping, Some(Arc::new(webc_fs)), &mut builder).unwrap();
let fs = prepare_filesystem(root_fs, &mapping, Some(Arc::new(webc_fs))).unwrap();

assert!(fs.metadata("/home/file.txt".as_ref()).unwrap().is_file());
assert!(fs.metadata("lib".as_ref()).unwrap().is_dir());
Expand Down
6 changes: 4 additions & 2 deletions lib/wasix/src/runners/wcgi/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,17 @@ impl Config {
}

pub fn map_directory(&mut self, dir: MappedDirectory) -> &mut Self {
self.wasi.mapped_dirs.push(dir);
self.wasi.mounts.push(dir.into());
self
}

pub fn map_directories(
&mut self,
mappings: impl IntoIterator<Item = MappedDirectory>,
) -> &mut Self {
self.wasi.mapped_dirs.extend(mappings.into_iter());
for mapping in mappings {
self.map_directory(mapping);
}
self
}

Expand Down

0 comments on commit 29746d1

Please sign in to comment.