From e7fb8105b4b643b2a28091fdf05c11a2535c2020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=AB=E8=8A=B1?= Date: Fri, 25 Apr 2025 14:05:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=91=BD=E5=90=8D=E7=A9=BA?= =?UTF-8?q?=E9=97=B4=E7=AE=A1=E7=90=86=20(#89)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/service/src/lib.rs | 1 + crates/service/src/namespace_manager.rs | 81 +++++++++++++++++++++++++ crates/service/src/spec.rs | 2 +- 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 crates/service/src/namespace_manager.rs diff --git a/crates/service/src/lib.rs b/crates/service/src/lib.rs index cf64e36..c9e1b76 100644 --- a/crates/service/src/lib.rs +++ b/crates/service/src/lib.rs @@ -1,5 +1,6 @@ pub mod containerd_manager; pub mod image_manager; +pub mod namespace_manager; pub mod spec; pub mod systemd; diff --git a/crates/service/src/namespace_manager.rs b/crates/service/src/namespace_manager.rs new file mode 100644 index 0000000..5babcc7 --- /dev/null +++ b/crates/service/src/namespace_manager.rs @@ -0,0 +1,81 @@ +use crate::containerd_manager::CLIENT; +use containerd_client::{ + Client, + services::v1::{CreateNamespaceRequest, DeleteNamespaceRequest, Namespace}, +}; +use std::sync::Arc; + +pub struct NSManager { + namespaces: Vec, +} + +impl NSManager { + async fn get_client() -> Arc { + CLIENT + .get() + .unwrap_or_else(|| panic!("Client not initialized, Please run init first")) + .clone() + } + + pub async fn create_namespace(&mut self, name: &str) -> Result<(), NameSpaceError> { + let client = Self::get_client().await; + let mut ns_client = client.namespaces(); + + let request = CreateNamespaceRequest { + namespace: Some(Namespace { + name: name.to_string(), + ..Default::default() + }), + }; + + let response = ns_client.create(request).await.map_err(|e| { + NameSpaceError::CreateError(format!("Failed to create namespace {}: {}", name, e)) + })?; + + self.namespaces + .push(response.into_inner().namespace.unwrap()); + Ok(()) + } + + pub async fn delete_namespace(&mut self, name: &str) -> Result<(), NameSpaceError> { + let client = Self::get_client().await; + let mut ns_client = client.namespaces(); + + let req = DeleteNamespaceRequest { + name: name.to_string(), + }; + + ns_client.delete(req).await.map_err(|e| { + NameSpaceError::DeleteError(format!("Failed to delete namespace {}: {}", name, e)) + })?; + + self.namespaces.retain(|ns| ns.name != name); + Ok(()) + } + + pub async fn list_namespace(&self) -> Result, NameSpaceError> { + // 这里没有选择直接列举所有的命名空间,而是返回当前对象中存储的命名空间 + // 觉得应该只能看见自己创建的命名空间而不能看见其他人的命名空间 + // 是不是应该把namespaces做持久化存储,作为一个用户自己的namespace + Ok(self.namespaces.clone()) + } +} + +#[derive(Debug)] +pub enum NameSpaceError { + CreateError(String), + DeleteError(String), + ListError(String), +} + +impl std::fmt::Display for NameSpaceError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + NameSpaceError::CreateError(msg) => write!(f, "Create Namespace Error: {}", msg), + NameSpaceError::DeleteError(msg) => write!(f, "Delete Namespace Error: {}", msg), + NameSpaceError::ListError(msg) => write!(f, "List Namespace Error: {}", msg), + } + } +} + +impl std::error::Error for NameSpaceError {} diff --git a/crates/service/src/spec.rs b/crates/service/src/spec.rs index b7cfe05..1213d1f 100644 --- a/crates/service/src/spec.rs +++ b/crates/service/src/spec.rs @@ -295,7 +295,7 @@ pub fn populate_default_unix_spec(id: &str, ns: &str) -> Spec { linux: Linux { masked_paths: default_masked_parhs(), readonly_paths: default_readonly_paths(), - cgroups_path: format!("{}/{}", ns, id), + cgroups_path: format!("/{}/{}", ns, id), resources: LinuxResources { devices: vec![LinuxDeviceCgroup { allow: false,