@@ -100,6 +100,9 @@ enum Command {
100100 interactive : bool ,
101101 #[ arg( long = "fs-deny" , value_name = "PATH" ) ]
102102 fs_deny : Vec < String > ,
103+ /// Mount a host path inside the sandbox (e.g. --fs-mount /work:/host/path)
104+ #[ arg( long = "fs-mount" , value_name = "VIRTUAL:HOST" ) ]
105+ fs_mount : Vec < String > ,
103106 /// CPU cores to pin the sandbox to (e.g. --cpu-cores 0,2,3)
104107 #[ arg( long = "cpu-cores" , value_delimiter = ',' ) ]
105108 cpu_cores : Vec < u32 > ,
@@ -156,7 +159,7 @@ async fn main() -> Result<()> {
156159 fs_isolation, fs_storage, max_disk, net_allow, net_deny,
157160 http_allow, http_deny, http_ports, https_ca, https_key,
158161 port_remap, no_randomize_memory, no_huge_pages, deterministic_dirs, hostname, no_coredump,
159- env_vars, exec_shell, interactive : _, fs_deny, cpu_cores, gpu_devices, image, dry_run, no_supervisor, cmd } =>
162+ env_vars, exec_shell, interactive : _, fs_deny, fs_mount , cpu_cores, gpu_devices, image, dry_run, no_supervisor, cmd } =>
160163 {
161164 if no_supervisor {
162165 validate_no_supervisor (
@@ -167,7 +170,7 @@ async fn main() -> Result<()> {
167170 no_huge_pages, deterministic_dirs, & hostname, & chroot,
168171 & image, & uid, & workdir, & cwd, & fs_isolation, & fs_storage,
169172 & max_disk, port_remap, & cpu_cores, & gpu_devices, dry_run,
170- & status_fd, & fs_deny,
173+ & status_fd, & fs_deny, & fs_mount ,
171174 ) ?;
172175
173176 // Build a minimal policy with only fs rules
@@ -267,6 +270,11 @@ async fn main() -> Result<()> {
267270 if let Some ( cpu) = max_cpu { builder = builder. max_cpu ( cpu) ; }
268271 if let Some ( n) = max_open_files { builder = builder. max_open_files ( n) ; }
269272 for p in & fs_deny { builder = builder. fs_deny ( p) ; }
273+ for spec in & fs_mount {
274+ let ( virt, host) = spec. split_once ( ':' )
275+ . ok_or_else ( || anyhow ! ( "--fs-mount requires VIRTUAL:HOST, got: {}" , spec) ) ?;
276+ builder = builder. fs_mount ( virt, host) ;
277+ }
270278 if let Some ( ref path) = chroot { builder = builder. chroot ( path) ; }
271279 if let Some ( id) = uid { builder = builder. uid ( id) ; }
272280 if let Some ( ref path) = workdir { builder = builder. workdir ( path) ; }
@@ -496,6 +504,7 @@ fn validate_no_supervisor(
496504 dry_run : bool ,
497505 status_fd : & Option < i32 > ,
498506 fs_deny : & [ String ] ,
507+ fs_mount : & [ String ] ,
499508) -> Result < ( ) > {
500509 let mut bad = Vec :: new ( ) ;
501510
@@ -533,6 +542,7 @@ fn validate_no_supervisor(
533542 if dry_run { bad. push ( "--dry-run" ) ; }
534543 if status_fd. is_some ( ) { bad. push ( "--status-fd" ) ; }
535544 if !fs_deny. is_empty ( ) { bad. push ( "--fs-deny" ) ; }
545+ if !fs_mount. is_empty ( ) { bad. push ( "--fs-mount" ) ; }
536546
537547 if !bad. is_empty ( ) {
538548 return Err ( anyhow ! (
0 commit comments