diff --git a/Cargo.lock b/Cargo.lock index 5d4ee6f..9cb6597 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -316,7 +316,7 @@ dependencies = [ [[package]] name = "detee-shared" version = "0.1.0" -source = "git+ssh://git@gitea.detee.cloud/noormohammedb/detee-shared#bb553f08af6178d1b0da57234311eaf2809ca648" +source = "git+ssh://git@gitea.detee.cloud/noormohammedb/detee-shared#b162dd99c0fe6f53e192eeb3576845b15d851934" dependencies = [ "base64", "prost", diff --git a/src/container.rs b/src/container.rs new file mode 100644 index 0000000..db7b753 --- /dev/null +++ b/src/container.rs @@ -0,0 +1,40 @@ +use anyhow::Result; +use std::process::Command; + +use crate::utils::prepare_port_map; + +pub async fn deploy_enclave( + enclave_path: &str, + container_name_uuid: String, + publishing_ports: Vec, + // ... +) -> Result> { + let port_map = prepare_port_map(publishing_ports).await; + + let port_maping_string = port_map + .iter() + .map(|(host, container)| format!("-p {host}:{container}")) + .collect::>() + .join(" "); + + println!("Deploying enclave: {:?}", enclave_path); + let docker_deploy_str = format!( + r#"docker run --name {container_name_uuid} -v {enclave_path}/enclave_packager:/enclave_packager \ + --device /dev/sgx/enclave --device /dev/sgx/provision {port_maping_string} noormohammedb/occlum-enclave:v1"# + ); + + let _child = Command::new("sh") + .arg("-c") + .arg(docker_deploy_str) + .spawn()?; + + Ok(port_map) +} + +pub fn delete_enclave(container_name_uuid: String) -> Result<()> { + println!("Deleting enclave: {:?}", &container_name_uuid); + let docker_rm_str = format!(r#"docker container rm -f {container_name_uuid}"#); + let _child = Command::new("sh").arg("-c").arg(docker_rm_str).spawn()?; + + Ok(()) +} diff --git a/src/data.rs b/src/data.rs index 3e46a10..de43b66 100644 --- a/src/data.rs +++ b/src/data.rs @@ -1,9 +1,9 @@ -use anyhow::Result; - +use anyhow::{anyhow, Result}; use detee_shared::pb_types::shared::Container as ContainerConfig; use detee_shared::pb_types::shared::Resource as ResourceConfig; -use crate::package::deploy_enclave; +use crate::container::delete_enclave; +use crate::container::deploy_enclave; #[derive(Debug, Default)] pub struct DaemonState { @@ -33,11 +33,13 @@ impl DaemonState { ) -> Result, Box> { let publishing_ports = req_data.resource.clone().unwrap().port; let uuid = req_data.uuid.unwrap_or_default().uuid; - let mapped_ports = deploy_enclave(&unarchive_dir, uuid.clone(), publishing_ports).await?; + let container_name = format!("dtpm-{uuid}"); + let mapped_ports = + deploy_enclave(&unarchive_dir, container_name.clone(), publishing_ports).await?; let container = Container { uuid, - name: "".to_string(), + name: container_name, package_path: unarchive_dir, status: "running".to_string(), admin: req_data.admin_pubkey, @@ -49,4 +51,32 @@ impl DaemonState { Ok(mapped_ports) } + + pub async fn delete_container( + &mut self, + admin_pubkey: String, + container_uuid: String, + ) -> Result<()> { + let Some(container_position) = self + .containers + .iter() + .position(|c| c.uuid == container_uuid) + else { + println!("Container \"{container_uuid}\" not found"); + return Err(anyhow!("Container not found")); + }; + + let container = &self.containers[container_position]; + + if container.admin != admin_pubkey { + return Err(anyhow!("Unauthorized")); + } + + let container_name = format!("dtpm-{}", container.uuid); + delete_enclave(container_name)?; + + self.containers.remove(container_position); + + Ok(()) + } } diff --git a/src/grpc.rs b/src/grpc.rs index 8eb89fe..d5549f7 100644 --- a/src/grpc.rs +++ b/src/grpc.rs @@ -16,7 +16,7 @@ use detee_shared::pb::shared::Container as ContainerPB; use detee_shared::pb_types::shared::Container as ContainerConfig; -use crate::package::handle_package; +use crate::utils::handle_package; use crate::DaemonState; #[derive(Debug, Clone)] @@ -89,6 +89,29 @@ impl DaemonServicePB for DaemonServer { })); } + async fn delete_container( + &self, + req: tonic::Request, + ) -> Result, tonic::Status> { + let req_data = req.into_inner(); + if req_data.container_id.is_none() { + return Err(tonic::Status::data_loss("missing container id")); + } + self.data + .write() + .await + .delete_container( + req_data.admin_pubkey, + req_data.container_id.unwrap_or_default().uuid, + ) + .await + .map_err(|err| tonic::Status::internal(err.to_string()))?; + + return Ok(tonic::Response::new(DeleteContainerRes { + ..Default::default() + })); + } + async fn inspect_container( &self, req: tonic::Request, @@ -115,14 +138,4 @@ impl DaemonServicePB for DaemonServer { ..Default::default() })); } - - async fn delete_container( - &self, - req: tonic::Request, - ) -> Result, tonic::Status> { - dbg!(req); - return Ok(tonic::Response::new(DeleteContainerRes { - ..Default::default() - })); - } } diff --git a/src/main.rs b/src/main.rs index f23b7d7..3e04e8a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ +pub mod container; pub mod data; pub mod grpc; -pub mod package; +pub mod utils; pub use data::DaemonState; use std::sync::Arc; diff --git a/src/package.rs b/src/utils.rs similarity index 70% rename from src/package.rs rename to src/utils.rs index 95d7c4b..c1513ae 100644 --- a/src/package.rs +++ b/src/utils.rs @@ -5,7 +5,6 @@ use rand::Rng; use reqwest::Client; use std::io::BufReader; use std::path::Path; -use std::process::Command; use tar::Archive; use tokio::io::AsyncWriteExt; use tokio::net::TcpListener; @@ -40,36 +39,6 @@ pub async fn handle_package(package_url: String) -> Result { Ok(unarchive_dir) } -pub async fn deploy_enclave( - enclave_path: &str, - container_name_uuid: String, - publishing_ports: Vec, - // ... -) -> Result, Box> { - let port_map = prepare_port_map(publishing_ports).await; - - let port_maping_string = port_map - .iter() - .map(|(host, container)| format!("-p {host}:{container}")) - .collect::>() - .join(" "); - - println!("Deploying enclave: {:?}", enclave_path); - let docker_deploy_str = format!( - r#"docker run --name dtpm-{container_name_uuid} -v {enclave_path}/enclave_packager:/enclave_packager \ - --device /dev/sgx/enclave --device /dev/sgx/provision {port_maping_string} noormohammedb/occlum-enclave:v1"# - ); - - println!("{}", &docker_deploy_str); - - let _child = Command::new("sh") - .arg("-c") - .arg(docker_deploy_str) - .spawn()?; - - Ok(port_map) -} - pub async fn download_file(url: &str, file_path: &Path) -> Result<(), Box> { let client = Client::new(); let response = client.get(url).send().await?; @@ -81,7 +50,7 @@ pub async fn download_file(url: &str, file_path: &Path) -> Result<(), Box) -> Vec<(u16, u16)> { +pub async fn prepare_port_map(mut publishing_ports: Vec) -> Vec<(u16, u16)> { publishing_ports.insert(0, 34500); let mut maped_ports = vec![]; for port in publishing_ports {