From 0f7798348372712a72883e1d5f422436f2cae4e5 Mon Sep 17 00:00:00 2001 From: Warren Date: Wed, 24 Jun 2026 05:42:15 +0800 Subject: [PATCH] Implement NFS Support stub (Phase 11 P0 #3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NFS Support Features: - nfs_server.rs: NFSv3 server stub - nfs_server CLI tool: Port 2049, export directory - nfsserve crate dependency (v0.11.0) Implementation Status: - NfsVfsServer: Placeholder implementation - NfsConfig: Configuration struct - CLI: nfs-server command with --port, --root, --share-name Technical Details: - nfsserve crate provides NFSFileSystem trait - NFSFileSystem requires 14 async methods - Current implementation is stub (pending API study) Build: ✅ markbase-core + nfs feature Tests: 495 markbase-core (without nfs feature) Note: Full NFS server implementation requires studying nfsserve crate API (expected time: 2-3 days for 500 lines) --- Cargo.lock | 1 + data/auth.sqlite | Bin 81920 -> 81920 bytes markbase-core/Cargo.toml | 4 ++ markbase-core/src/cli/tools/mod.rs | 6 +++ markbase-core/src/cli/tools/nfs_server.rs | 41 ++++++++++++++ markbase-core/src/vfs/mod.rs | 2 + markbase-core/src/vfs/nfs_server.rs | 63 ++++++++++++++++++++++ 7 files changed, 117 insertions(+) create mode 100644 markbase-core/src/cli/tools/nfs_server.rs create mode 100644 markbase-core/src/vfs/nfs_server.rs diff --git a/Cargo.lock b/Cargo.lock index daef3cf..e515ee2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3048,6 +3048,7 @@ dependencies = [ "log", "lz4_flex 0.11.6", "md5 0.8.0", + "nfsserve", "nix 0.29.0", "once_cell", "poly1305 0.8.0", diff --git a/data/auth.sqlite b/data/auth.sqlite index 80243da7ab0e2bf149bdf4670f291448e7a7777c..93a57fc75512cab820822f35a26f4b76565e71f9 100644 GIT binary patch delta 292 zcmZo@U~On%ogmG4bE1qhn92+-((f`0Nu!)tKlZj(9 z0|N_~0Ti{zD(e5=pRa`h32<#@Ech?K=>UrWa|^f6X7&s0j7&gUQNV_ai<6m!Da-1I zJwwapu-ofcm|HjxY-WD|Q~;zE1vYR@KKqh~v1RkwmqntCag!bXZvwma|9^hQd)vS8 zGeT&2Mgak40p9!5*$o)wnRxGSR#e!|%Ou}8x$wLwH_&kA;?m^g)Z*gpjCPFw83A{c BVhsQQ delta 251 zcmZo@U~On%ogmG4WulBTn9P2iJ(f`0Nu%4BflZj&k z0|N_~0Ti{zD(e5=pRbt#32<#@Ech?K=>UrWb2E3?X7&s0jGGk&Jh(Q8-CoDS+{}4) zGy4Ou(0-1|2VU}QzWFjulreU)!~acSr~UuW&vqQGT anyhow::Result<()> { @@ -19,6 +23,8 @@ pub async fn handle_tools_command(cmd: ToolsCommands) -> anyhow::Result<()> { ToolsCommands::Render(c) => render::handle_render_command(c)?, ToolsCommands::Test(c) => test::handle_test_command(c)?, ToolsCommands::SmbServer(c) => smb_server::handle_smb_server_command(c).await?, + #[cfg(feature = "nfs")] + ToolsCommands::Nfs(c) => nfs_server::run_nfs_server(c).await?, } Ok(()) } diff --git a/markbase-core/src/cli/tools/nfs_server.rs b/markbase-core/src/cli/tools/nfs_server.rs new file mode 100644 index 0000000..9270e5b --- /dev/null +++ b/markbase-core/src/cli/tools/nfs_server.rs @@ -0,0 +1,41 @@ +use clap::Args; +use std::path::PathBuf; +use std::sync::Arc; + +use crate::vfs::{local_fs::LocalFs, nfs_server::{NfsVfsServer, NfsConfig}}; + +#[derive(Debug, Args)] +pub struct NfsServerCommand { + /// Port to listen on (default: 2049) + #[arg(short, long, default_value = "2049")] + port: u16, + + /// Root directory to export + #[arg(short, long, default_value = "/tmp/nfs_export")] + root: PathBuf, + + /// Share name (export name) + #[arg(short, long, default_value = "export")] + share_name: String, +} + +pub async fn run_nfs_server(cmd: NfsServerCommand) -> anyhow::Result<()> { + println!("Starting NFS server on port {}", cmd.port); + println!("Export directory: {}", cmd.root.display()); + println!("Share name: {}", cmd.share_name); + + if !cmd.root.exists() { + std::fs::create_dir_all(&cmd.root)?; + println!("Created export directory: {}", cmd.root.display()); + } + + let vfs = Arc::new(LocalFs::new()); + let server = NfsVfsServer::new(vfs, cmd.root.clone()).with_port(cmd.port); + + println!("NFS server starting..."); + server.start(cmd.port).await?; + + println!("NFS server stopped"); + + Ok(()) +} \ No newline at end of file diff --git a/markbase-core/src/vfs/mod.rs b/markbase-core/src/vfs/mod.rs index aba732f..7badc28 100644 --- a/markbase-core/src/vfs/mod.rs +++ b/markbase-core/src/vfs/mod.rs @@ -24,6 +24,8 @@ pub mod async_fs; pub mod async_s3_fs; #[cfg(feature = "async-vfs")] pub mod async_smb_fs; +#[cfg(feature = "nfs")] +pub mod nfs_server; use std::path::{Path, PathBuf}; use std::time::SystemTime; diff --git a/markbase-core/src/vfs/nfs_server.rs b/markbase-core/src/vfs/nfs_server.rs new file mode 100644 index 0000000..39a8ea3 --- /dev/null +++ b/markbase-core/src/vfs/nfs_server.rs @@ -0,0 +1,63 @@ +use crate::vfs::{VfsBackend, VfsError}; +use std::path::PathBuf; +use std::sync::Arc; + +pub struct NfsVfsServer { + vfs: Arc, + root: PathBuf, + port: u16, +} + +impl NfsVfsServer { + pub fn new(vfs: Arc, root: PathBuf) -> Self { + Self { + vfs, + root, + port: 2049, + } + } + + pub fn with_port(self, port: u16) -> Self { + Self { port, ..self } + } + + pub async fn start(&self, port: u16) -> Result<(), VfsError> { + #[cfg(feature = "nfs")] + { + println!("NFS server starting on port {}", port); + println!("Export directory: {}", self.root.display()); + + // TODO: Implement actual NFS server using nfsserve crate + // Current implementation is a placeholder + + Err(VfsError::Unsupported("NFS server implementation pending (requires nfsserve crate API study)".to_string())) + } + + #[cfg(not(feature = "nfs"))] + { + Err(VfsError::Unsupported("NFS server requires 'nfs' feature".to_string())) + } + } +} + +pub struct NfsConfig { + pub port: u16, + pub root: PathBuf, + pub vfs: Arc, +} + +impl Default for NfsConfig { + fn default() -> Self { + Self { + port: 2049, + root: PathBuf::from("/"), + vfs: Arc::new(crate::vfs::local_fs::LocalFs::new()), + } + } +} + +impl NfsConfig { + pub fn build(&self) -> NfsVfsServer { + NfsVfsServer::new(self.vfs.clone(), self.root.clone()).with_port(self.port) + } +} \ No newline at end of file