about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Klink <flokli@flokli.de>2023-05-28T07·32+0200
committerflokli <flokli@flokli.de>2023-06-10T15·33+0000
commitb3ca1a78eb780e427a85dd1bbe1c649f998dee65 (patch)
tree1604d8c6d18a1ba72d745c3286c0f009014b86b5
parent365937cd08879098f53edcf42695271deaccfb23 (diff)
feat(tvix/store): add mount command to entrypoint and fuse mod r/6263
`tvix-store mount PATH` will mount the tvix-store to the given path.

Change-Id: Icb82a6b3cb8a22eec856c375a28ae5580403833f
Reviewed-on: https://cl.tvl.fyi/c/depot/+/8665
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
Autosubmit: flokli <flokli@flokli.de>
-rw-r--r--tvix/store/src/bin/tvix-store.rs26
-rw-r--r--tvix/store/src/fuse/mod.rs24
-rw-r--r--tvix/store/src/lib.rs5
3 files changed, 55 insertions, 0 deletions
diff --git a/tvix/store/src/bin/tvix-store.rs b/tvix/store/src/bin/tvix-store.rs
index 8c278c433997..ce2701157110 100644
--- a/tvix/store/src/bin/tvix-store.rs
+++ b/tvix/store/src/bin/tvix-store.rs
@@ -25,6 +25,7 @@ use tvix_store::proto::GRPCBlobServiceWrapper;
 use tvix_store::proto::GRPCDirectoryServiceWrapper;
 use tvix_store::proto::GRPCPathInfoServiceWrapper;
 use tvix_store::TvixStoreIO;
+use tvix_store::FUSE;
 
 #[cfg(feature = "reflection")]
 use tvix_store::proto::FILE_DESCRIPTOR_SET;
@@ -59,6 +60,12 @@ enum Commands {
         #[clap(value_name = "PATH")]
         paths: Vec<PathBuf>,
     },
+    /// Mounts a tvix-store at the given mountpoint
+    #[cfg(feature = "fuse")]
+    Mount {
+        #[clap(value_name = "PATH")]
+        dest: PathBuf,
+    },
 }
 
 #[tokio::main]
@@ -172,6 +179,25 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
 
             try_join_all(tasks).await?;
         }
+        #[cfg(feature = "fuse")]
+        Commands::Mount { dest } => {
+            let blob_service = GRPCBlobService::from_client(
+                BlobServiceClient::connect("http://[::1]:8000").await?,
+            );
+            let directory_service = GRPCDirectoryService::from_client(
+                DirectoryServiceClient::connect("http://[::1]:8000").await?,
+            );
+            let path_info_service_client =
+                PathInfoServiceClient::connect("http://[::1]:8000").await?;
+            let path_info_service =
+                GRPCPathInfoService::from_client(path_info_service_client.clone());
+
+            tokio::task::spawn_blocking(move || {
+                let f = FUSE::new(path_info_service, directory_service, blob_service);
+                fuser::mount2(f, &dest, &[])
+            })
+            .await??
+        }
     };
     Ok(())
 }
diff --git a/tvix/store/src/fuse/mod.rs b/tvix/store/src/fuse/mod.rs
new file mode 100644
index 000000000000..a93f482ebff6
--- /dev/null
+++ b/tvix/store/src/fuse/mod.rs
@@ -0,0 +1,24 @@
+use crate::{
+    blobservice::BlobService, directoryservice::DirectoryService, pathinfoservice::PathInfoService,
+};
+
+pub struct FUSE<BS: BlobService, DS: DirectoryService, PS: PathInfoService> {
+    blob_service: BS,
+    directory_service: DS,
+    path_info_service: PS,
+}
+
+impl<BS: BlobService, DS: DirectoryService, PS: PathInfoService> FUSE<BS, DS, PS> {
+    pub fn new(path_info_service: PS, directory_service: DS, blob_service: BS) -> Self {
+        Self {
+            blob_service,
+            path_info_service,
+            directory_service,
+        }
+    }
+}
+
+impl<BS: BlobService, DS: DirectoryService, PS: PathInfoService> fuser::Filesystem
+    for FUSE<BS, DS, PS>
+{
+}
diff --git a/tvix/store/src/lib.rs b/tvix/store/src/lib.rs
index 7ae8587f8b26..9ac36ac94f0b 100644
--- a/tvix/store/src/lib.rs
+++ b/tvix/store/src/lib.rs
@@ -1,5 +1,7 @@
 mod digests;
 mod errors;
+#[cfg(feature = "fuse")]
+mod fuse;
 mod store_io;
 
 pub mod blobservice;
@@ -13,5 +15,8 @@ pub use digests::B3Digest;
 pub use errors::Error;
 pub use store_io::TvixStoreIO;
 
+#[cfg(feature = "fuse")]
+pub use fuse::FUSE;
+
 #[cfg(test)]
 mod tests;