spin_factor_wasi/
spin.rs

1use std::path::PathBuf;
2
3use spin_common::{ui::quoted_path, url::parse_file_url};
4use spin_factors::anyhow::{ensure, Context};
5
6use crate::FilesMounter;
7
8pub struct SpinFilesMounter {
9    working_dir: PathBuf,
10    allow_transient_writes: bool,
11}
12
13impl SpinFilesMounter {
14    pub fn new(working_dir: impl Into<PathBuf>, allow_transient_writes: bool) -> Self {
15        Self {
16            working_dir: working_dir.into(),
17            allow_transient_writes,
18        }
19    }
20}
21
22impl FilesMounter for SpinFilesMounter {
23    fn mount_files(
24        &self,
25        app_component: &spin_factors::AppComponent,
26        mut ctx: crate::MountFilesContext,
27    ) -> spin_factors::anyhow::Result<()> {
28        for content_dir in app_component.files() {
29            let source_uri = content_dir
30                .content
31                .source
32                .as_deref()
33                .with_context(|| format!("Missing 'source' on files mount {content_dir:?}"))?;
34            let source_path = self.working_dir.join(parse_file_url(source_uri)?);
35            ensure!(
36                source_path.is_dir(),
37                "SpinFilesMounter only supports directory mounts; {} is not a directory",
38                quoted_path(&source_path),
39            );
40            let guest_path = &content_dir.path;
41            let guest_path = guest_path
42                .to_str()
43                .with_context(|| format!("guest path {guest_path:?} not valid UTF-8"))?;
44            ctx.preopened_dir(source_path, guest_path, self.allow_transient_writes)?;
45        }
46        Ok(())
47    }
48}