feat(tvix/store/fuse): allow listing

This provides an additional configuration flag to the tvix-store mount
subcommand, and logic in the fuse module to request listing for the
root of the mountpoint.

Change-Id: I05a8bc11f7991b574696f27a30afe0f4e718a58c
Reviewed-on: https://cl.tvl.fyi/c/depot/+/9217
Autosubmit: flokli <flokli@flokli.de>
Reviewed-by: adisbladis <adisbladis@gmail.com>
Tested-by: BuildkiteCI
This commit is contained in:
Florian Klink 2023-09-03 17:10:06 +03:00 committed by clbot
parent da9d706e0a
commit f9b5fc49b1
3 changed files with 111 additions and 4 deletions

View file

@ -25,6 +25,17 @@ fn setup_and_mount<P: AsRef<Path>, F>(
mountpoint: P,
setup_fn: F,
) -> Result<fuser::BackgroundSession, std::io::Error>
where
F: Fn(Arc<dyn BlobService>, Arc<dyn DirectoryService>, Arc<dyn PathInfoService>),
{
setup_and_mount_with_listing(mountpoint, setup_fn, false)
}
fn setup_and_mount_with_listing<P: AsRef<Path>, F>(
mountpoint: P,
setup_fn: F,
list_root: bool,
) -> Result<fuser::BackgroundSession, std::io::Error>
where
F: Fn(Arc<dyn BlobService>, Arc<dyn DirectoryService>, Arc<dyn PathInfoService>),
{
@ -38,7 +49,12 @@ where
path_info_service.clone(),
);
let fs = FUSE::new(blob_service, directory_service, path_info_service);
let fs = FUSE::new(
blob_service,
directory_service,
path_info_service,
list_root,
);
fuser::spawn_mount2(fs, mountpoint, &[])
}
@ -280,6 +296,34 @@ fn root() {
fuser_session.join()
}
/// Ensure listing the root is allowed if configured explicitly
#[test]
fn root_with_listing() {
// https://plume.benboeckel.net/~/JustAnotherBlog/skipping-tests-in-rust
if !std::path::Path::new("/dev/fuse").exists() {
eprintln!("skipping test");
return;
}
let tmpdir = TempDir::new().unwrap();
let fuser_session =
setup_and_mount_with_listing(tmpdir.path(), populate_blob_a, true).expect("must succeed");
{
// read_dir succeeds, but getting the first element will fail.
let mut it = fs::read_dir(tmpdir).expect("must succeed");
let e = it.next().expect("must be some").expect("must succeed");
let metadata = e.metadata().expect("must succeed");
assert!(metadata.is_file());
assert!(metadata.permissions().readonly());
assert_eq!(fixtures::BLOB_A.len() as u64, metadata.len());
}
fuser_session.join()
}
/// Ensure we can stat a file at the root
#[test]
fn stat_file_at_root() {