pub struct VirtualOverlayBackend { /* private fields */ }Expand description
Backend that overlays virtual paths (/v/*) on top of a custom backend.
This enables embedders to provide their own storage backend while still
getting kaish’s virtual filesystem features like /v/jobs for job observability.
Implementations§
Source§impl VirtualOverlayBackend
impl VirtualOverlayBackend
Trait Implementations§
Source§impl Debug for VirtualOverlayBackend
impl Debug for VirtualOverlayBackend
Source§impl KernelBackend for VirtualOverlayBackend
impl KernelBackend for VirtualOverlayBackend
Source§fn canonicalize<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
allow_missing_final: bool,
) -> Pin<Box<dyn Future<Output = BackendResult<PathBuf>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn canonicalize<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
allow_missing_final: bool,
) -> Pin<Box<dyn Future<Output = BackendResult<PathBuf>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
The same three-way split every other operation here uses: a
kaish-owned virtual path canonicalizes through self.vfs; a shared
ancestor (/v, /, …) is a directory this backend synthesizes,
never a symlink, so it canonicalizes to itself; everything else
canonicalizes through the embedder’s own backend.
Delegating rather than inheriting the trait default matters here
specifically: the default’s per-hop walk calls lstat/read_link on
this type for every component, re-running is_virtual_path /
is_shared_ancestor at each hop instead of asking the owning side
once for the whole path. A symlink that lives entirely under the
embedder’s backend must resolve — and be contained — through that one
backend’s own resolver, not be re-routed through this split hop by
hop.
Source§fn path_access<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<PathAccess>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn path_access<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<PathAccess>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Routes the same way stat does, so the answer comes from the layer
that owns the path. The trait default would use read_only() above,
which is the AND of both layers and belongs to neither path.
Source§fn read<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
range: Option<ReadRange>,
) -> Pin<Box<dyn Future<Output = BackendResult<Vec<u8>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
range: Option<ReadRange>,
) -> Pin<Box<dyn Future<Output = BackendResult<Vec<u8>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
content: &'life2 [u8],
mode: WriteMode,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn write<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
content: &'life2 [u8],
mode: WriteMode,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn set_mtime<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
mtime: SystemTime,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn set_mtime<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
mtime: SystemTime,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn append<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
content: &'life2 [u8],
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn append<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
content: &'life2 [u8],
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn patch<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
ops: &'life2 [PatchOp],
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn patch<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 Path,
ops: &'life2 [PatchOp],
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn list<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<Vec<DirEntry>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn list<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<Vec<DirEntry>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn stat<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<DirEntry>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn stat<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<DirEntry>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn mkdir<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn mkdir<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn remove<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
recursive: bool,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn remove<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
recursive: bool,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
recursive descends into a
directory. The final component is never followed: a symlink is
unlinked and its target kept, and a link to a directory is not
descended into.Source§fn rename<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
from: &'life1 Path,
to: &'life2 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn rename<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
from: &'life1 Path,
to: &'life2 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn exists<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn exists<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
false. Use lstat to ask whether a
link is present.Source§fn lstat<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<DirEntry>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn lstat<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<DirEntry>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn read_link<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<PathBuf>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn read_link<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<PathBuf>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn symlink<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
target: &'life1 Path,
link: &'life2 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn symlink<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
target: &'life1 Path,
link: &'life2 Path,
) -> Pin<Box<dyn Future<Output = BackendResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
link pointing to target. The target is stored
verbatim; a relative target resolves from the link’s directory. An
absolute target is rewritten relative to the link when both are on one
mount, and refused when they are not.Source§fn call_tool<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
name: &'life1 str,
args: ToolArgs,
ctx: &'life2 mut dyn ToolCtx,
) -> Pin<Box<dyn Future<Output = BackendResult<ToolResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn call_tool<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
name: &'life1 str,
args: ToolArgs,
ctx: &'life2 mut dyn ToolCtx,
) -> Pin<Box<dyn Future<Output = BackendResult<ToolResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn list_tools<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = BackendResult<Vec<ToolInfo>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_tools<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = BackendResult<Vec<ToolInfo>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn get_tool<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = BackendResult<Option<ToolInfo>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_tool<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = BackendResult<Option<ToolInfo>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn backend_type(&self) -> &str
fn backend_type(&self) -> &str
Auto Trait Implementations§
impl !RefUnwindSafe for VirtualOverlayBackend
impl !UnwindSafe for VirtualOverlayBackend
impl Freeze for VirtualOverlayBackend
impl Send for VirtualOverlayBackend
impl Sync for VirtualOverlayBackend
impl Unpin for VirtualOverlayBackend
impl UnsafeUnpin for VirtualOverlayBackend
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T, S> SpanWrap<S> for Twhere
S: WrappingSpan<T>,
impl<T, S> SpanWrap<S> for Twhere
S: WrappingSpan<T>,
Source§fn with_span(self, span: S) -> <S as WrappingSpan<Self>>::Spanned
fn with_span(self, span: S) -> <S as WrappingSpan<Self>>::Spanned
WrappingSpan::make_wrapped to wrap an AST node in a span.