Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions cli/src/sandbox/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,11 @@ pub async fn run_cmd(
let base = Arc::new(HostFS::new(&fd_path).context("Failed to create HostFS")?);
let overlay = OverlayFS::new(base, agentfs.fs);

let cwd_str = cwd
.to_str()
.context("Current directory path contains non-UTF8 characters")?;
overlay
.init()
.init(cwd_str)
.await
.context("Failed to initialize overlay")?;

Expand Down Expand Up @@ -185,7 +188,7 @@ pub async fn run_cmd(
cwd_fd,
&session.fuse_mountpoint,
fuse_handle,
&session.run_dir,
&session.db_path,
);
}
}
Expand All @@ -211,8 +214,6 @@ fn print_welcome_banner(cwd: &Path, allowed_paths: &[PathBuf]) {
struct RunSession {
/// Unique identifier for this run.
run_id: String,
/// Directory containing session artifacts (database, mountpoint).
run_dir: PathBuf,
/// Path to the delta database.
db_path: PathBuf,
/// Path where FUSE filesystem will be mounted.
Expand All @@ -232,7 +233,6 @@ fn setup_run_directory() -> Result<RunSession> {

Ok(RunSession {
run_id,
run_dir,
db_path,
fuse_mountpoint,
})
Expand Down Expand Up @@ -696,7 +696,7 @@ fn run_parent(
cwd_fd: std::fs::File,
fuse_mountpoint: &Path,
_fuse_handle: std::thread::JoinHandle<anyhow::Result<()>>,
run_dir: &Path,
db_path: &Path,
) -> ! {
// Wait for child process to exit
let mut status: libc::c_int = 0;
Expand All @@ -722,15 +722,22 @@ fn run_parent(
std::process::exit(exit_code);
}

// Clean up run directory
if let Err(e) = std::fs::remove_dir_all(run_dir) {
// Clean up the FUSE mountpoint directory (but keep the delta database)
if let Err(e) = std::fs::remove_dir_all(fuse_mountpoint) {
eprintln!(
"Warning: Failed to clean up run directory {}: {}",
run_dir.display(),
"Warning: Failed to clean up mountpoint {}: {}",
fuse_mountpoint.display(),
e
);
}

// Print the location of the delta layer for the user
eprintln!();
eprintln!("Delta layer saved to: {}", db_path.display());
eprintln!();
eprintln!("To see what changed:");
eprintln!(" agentfs diff {}", db_path.display());

std::process::exit(exit_code);
}

Expand Down
5 changes: 4 additions & 1 deletion sdk/rust/benches/overlayfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ fn bench_remove_file(c: &mut Criterion) {
.expect("Failed to create AgentFS");

let overlay = OverlayFS::new(base, delta);
overlay.init().await.expect("Failed to init overlay");
overlay
.init(base_dir.path().to_str().unwrap())
.await
.expect("Failed to init overlay");

(overlay, base_dir, delta_dir)
})
Expand Down
29 changes: 25 additions & 4 deletions sdk/rust/src/filesystem/overlayfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ impl OverlayFS {
///
/// This must be called before using the overlay filesystem to ensure
/// the whiteout tracking table exists in the delta layer.
pub async fn init(&self) -> Result<()> {
///
/// The `base_path` parameter specifies the actual filesystem path that the
/// base layer represents. This is stored in the delta database so that
/// tools like `agentfs diff` can determine what files were modified.
pub async fn init(&self, base_path: &str) -> Result<()> {
let conn = self.delta.get_connection();
conn.execute(
"CREATE TABLE IF NOT EXISTS fs_whiteout (
Expand All @@ -59,6 +63,20 @@ impl OverlayFS {
(),
)
.await?;
// Store overlay configuration so tools can identify this as an overlay database
conn.execute(
"CREATE TABLE IF NOT EXISTS fs_overlay_config (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
)",
(),
)
.await?;
conn.execute(
"INSERT OR REPLACE INTO fs_overlay_config (key, value) VALUES ('base_path', ?1)",
[Value::Text(base_path.to_string())],
)
.await?;
Ok(())
}

Expand Down Expand Up @@ -650,7 +668,7 @@ mod tests {
let delta = AgentFS::new(db_path.to_str().unwrap()).await?;

let overlay = OverlayFS::new(base, delta);
overlay.init().await?;
overlay.init(base_dir.path().to_str().unwrap()).await?;

Ok((overlay, base_dir, delta_dir))
}
Expand Down Expand Up @@ -1039,7 +1057,7 @@ mod prop_tests {
let delta = AgentFS::new(db_path.to_str().unwrap()).await?;

let overlay = OverlayFS::new(base, delta);
overlay.init().await?;
overlay.init(base_dir.path().to_str().unwrap()).await?;

Ok((overlay, base_dir, delta_dir))
}
Expand Down Expand Up @@ -1416,7 +1434,10 @@ mod prop_tests {
let db_path = delta_dir.path().join("delta.db");
let delta = AgentFS::new(db_path.to_str().unwrap()).await.unwrap();
let overlay = OverlayFS::new(base, delta);
overlay.init().await.unwrap();
overlay
.init(base_dir.path().to_str().unwrap())
.await
.unwrap();

// Create /subdir/nested.txt
overlay
Expand Down