Read, write, list, and manipulate files inside a running sandbox. Obtained via sb.fs(). Every op dispatches through the same host-guest channel as command execution, so there is no SSH and no network involved. Path-style helpers are the usual choice; handle-style helpers are available for callers that need POSIX-like file descriptor reuse. For bulk file movement, prefer a volume that gives the guest direct filesystem access. See Filesystem for conceptual usage.
Typical flow
use microsandbox::Sandbox;let sb = Sandbox::builder("api").image("python").create().await?;let fs = sb.fs();fs.write("/tmp/config.json", r#"{"debug": true}"#).await?;let text = fs.read_to_string("/tmp/config.json").await?;println!("{text}");for entry in fs.list("/tmp").await? { println!("{} ({} bytes)", entry.path, entry.size);}
sb.fs() is synchronous and just borrows the sandbox’s backend and name; the work happens on the awaited methods below, every one of which is async.
let mut stream = sb.fs().read_stream("/var/log/big.log").await?;let mut total = 0;while let Some(chunk) = stream.recv().await? { total += chunk.len();}println!("read {total} bytes");
Open a streaming reader that yields chunks of file data as they arrive. Use this for files too large to hold in memory, or to process data incrementally.
let sink = sb.fs().write_stream("/tmp/out.bin").await?;sink.write(&[0u8; 4096]).await?;sink.write(&[1u8; 4096]).await?;sink.close().await?;
Open a streaming writer for large files. Write chunks incrementally, then call FsWriteSink::close() to flush and finalize. The file is created if missing and truncated if it exists.
Handle operations expose agentd-side file and directory handles. Use them when you need repeated reads/writes against the same open file, directory iteration state, or handle-based metadata updates. They require Sandbox::fs() on a live local sandbox because agentd scopes handles to the relay client; SandboxFsOps::with_backend() can run path-style methods but returns Unsupported for handle methods.
let meta = sb.fs().stat("/app/config.json").await?;println!("{} bytes, mode {:o}", meta.size, meta.mode);
Get metadata for a file or directory: kind, size, mode, read-only flag, and timestamps. A final symlink is followed (equivalent to stat_with_follow(path, true)); use stat_with_follow() to control that.
let link_meta = sb.fs().stat_with_follow("/app/current", false).await?;println!("{:?}", link_meta.kind);
Get metadata, choosing whether to follow a final symlink. With follow_symlink = false you stat the link itself rather than its target. Local backend only; cloud returns Unsupported.
Parameters
path&str
Absolute path inside the guest.
follow_symlinkbool
When false, stat the symlink itself instead of its target.
use microsandbox::sandbox::FsSetAttrs;sb.fs().set_stat("/app/run.sh", true, FsSetAttrs { mode: Some(0o755), ..Default::default()}).await?;
Update metadata on a file or directory: mode, owner uid/gid, size, and access/modification times. Only the fields you set on FsSetAttrs are applied. Local backend only; cloud returns Unsupported.
Parameters
path&str
Absolute path inside the guest.
follow_symlinkbool
When false, target the symlink itself instead of its target.
if sb.fs().exists("/app/config.json").await? { println!("config present");}
Check whether a file or directory exists at the given path in the guest. Implemented as a stat() probe: a successful stat yields true, a filesystem-op error yields false, and transport errors still propagate.
Filesystem operations handle for a running sandbox, borrowing the parent sandbox’s backend and name (it is generic over a lifetime, SandboxFsOps<'a>). Every method dispatches through the same host-guest channel as command execution. Local routes to core.fs.* agent messages; cloud returns Unsupported per method until cloud guest-fs lands. All operations are listed in the sections above.with_backend(backend, name) is a public constructor for FFI shims that re-assemble a SandboxFsOps per call; most callers obtain one via sb.fs().
Attributes accepted by set_stat(). Re-exported from microsandbox_protocol::fs. Derives Default, so set only the fields you want to change and spread the rest with ..Default::default(). Each field is Option: None leaves that attribute unchanged.
Type alias for an agentd-side filesystem handle. Handles are valid only for the live relay client that opened them; close directly opened handles with close_handle().