use agentos_kernel::mount_plugin::{
FileSystemPluginFactory, OpenFileSystemPluginRequest, PluginError,
};
use agentos_kernel::mount_table::{
MountedFileSystem, MountedVirtualFileSystem, ReadOnlyFileSystem,
};
use serde::Deserialize;
use crate::plugins::host_dir::{HostDirFilesystem, HostDirReadLimitContext};
#[derive(Debug, Deserialize)]
#[serde(tag = "kind", rename_all = "camelCase")]
enum AgentosPackagesMountConfig {
Tar {
#[serde(rename = "tarPath")]
tar_path: String,
#[serde(default)]
root: Option<String>,
#[serde(rename = "readOnly")]
read_only: Option<bool>,
},
HostDir {
#[serde(rename = "hostPath")]
host_path: String,
#[serde(rename = "readOnly")]
read_only: Option<bool>,
},
SingleSymlink {
target: String,
#[serde(rename = "readOnly")]
read_only: Option<bool>,
},
}
#[derive(Debug)]
pub(crate) struct AgentosPackagesMountPlugin;
impl<Context> FileSystemPluginFactory<Context> for AgentosPackagesMountPlugin
where
Context: HostDirReadLimitContext,
{
fn plugin_id(&self) -> &'static str {
"agentos_packages"
}
fn open(
&self,
request: OpenFileSystemPluginRequest<'_, Context>,
) -> Result<Box<dyn MountedFileSystem>, PluginError> {
let config: AgentosPackagesMountConfig = serde_json::from_value(request.config.clone())
.map_err(|error| PluginError::invalid_input(error.to_string()))?;
match config {
AgentosPackagesMountConfig::Tar {
tar_path,
root,
read_only,
} => {
let filesystem =
vfs::posix::TarFileSystem::open_at(&tar_path, root.as_deref().unwrap_or("/"))
.map_err(|error| PluginError::invalid_input(error.to_string()))?;
let mounted = MountedVirtualFileSystem::new(filesystem);
if read_only.unwrap_or(true) {
Ok(Box::new(ReadOnlyFileSystem::new(mounted)))
} else {
Ok(Box::new(mounted))
}
}
AgentosPackagesMountConfig::HostDir {
host_path,
read_only,
} => {
let filesystem = HostDirFilesystem::new_with_read_limit(
&host_path,
request.context.host_dir_max_read_bytes(),
)
.map_err(|error| PluginError::invalid_input(error.to_string()))?;
let mounted = MountedVirtualFileSystem::new(filesystem);
if read_only.unwrap_or(true) {
Ok(Box::new(ReadOnlyFileSystem::new(mounted)))
} else {
Ok(Box::new(mounted))
}
}
AgentosPackagesMountConfig::SingleSymlink { target, read_only } => {
let mounted =
MountedVirtualFileSystem::new(vfs::posix::SingleSymlinkFileSystem::new(target));
if read_only.unwrap_or(true) {
Ok(Box::new(ReadOnlyFileSystem::new(mounted)))
} else {
Ok(Box::new(mounted))
}
}
}
}
}