refactor: restructured a bit and simple state handling
This commit is contained in:
		
							parent
							
								
									91180f90b7
								
							
						
					
					
						commit
						bd44c4bade
					
				
							
								
								
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -298,6 +298,7 @@ dependencies = [ | ||||
| name = "detee-sgx-daemon" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "anyhow", | ||||
|  "chrono", | ||||
|  "detee-shared", | ||||
|  "env_logger", | ||||
| @ -314,6 +315,7 @@ dependencies = [ | ||||
| [[package]] | ||||
| name = "detee-shared" | ||||
| version = "0.1.0" | ||||
| source = "git+ssh://git@gitea.detee.cloud/noormohammedb/detee-shared#358c2d84ca092cad5df69ac19cc6acbfb85ee8d7" | ||||
| dependencies = [ | ||||
|  "base64", | ||||
|  "prost", | ||||
|  | ||||
| @ -10,12 +10,13 @@ prost-types = "0.13.4" | ||||
| tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "fs"] } | ||||
| tonic = "0.12.3" | ||||
| 
 | ||||
| # detee-shared = { git = "ssh://git@gitea.detee.cloud/noormohammedb/detee-shared" } | ||||
| detee-shared = { path = "../detee-shared" } | ||||
| detee-shared = { git = "ssh://git@gitea.detee.cloud/noormohammedb/detee-shared" } | ||||
| # detee-shared = { path = "../detee-shared" } | ||||
| chrono = "0.4.39" | ||||
| reqwest = "0.12.12" | ||||
| flate2 = "1.0.35" | ||||
| tar = "0.4.43" | ||||
| anyhow = "1.0.95" | ||||
| 
 | ||||
| [build-dependencies] | ||||
| tonic-build = "0.12.3" | ||||
|  | ||||
							
								
								
									
										8
									
								
								build.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										8
									
								
								build.rs
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | ||||
| fn main() -> Result<(), Box<dyn std::error::Error>> { | ||||
|     tonic_build::configure() | ||||
|         .build_server(true) | ||||
|         .compile_protos(&["daemon.proto"], &["proto"]) | ||||
|         .unwrap_or_else(|e| panic!("Failed to compile protos {:?}", e)); | ||||
|     // tonic_build::configure()
 | ||||
|     //     .build_server(true)
 | ||||
|     //     .compile_protos(&["daemon.proto"], &["proto"])
 | ||||
|     //     .unwrap_or_else(|e| panic!("Failed to compile protos {:?}", e));
 | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
							
								
								
									
										49
									
								
								src/data.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										49
									
								
								src/data.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| use anyhow::Result; | ||||
| 
 | ||||
| use detee_shared::config::Container as ContainerConfig; | ||||
| use detee_shared::config::Resource as ResourceConfig; | ||||
| 
 | ||||
| use crate::package::deploy_enclave; | ||||
| 
 | ||||
| #[derive(Debug, Default)] | ||||
| pub struct DaemonState { | ||||
|     pub containers: Vec<Container>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Default)] | ||||
| pub struct Container { | ||||
|     pub id: String, | ||||
|     pub name: String, | ||||
|     pub package_path: String, | ||||
|     pub status: String, | ||||
|     pub admin: String, | ||||
|     pub container_resource: ResourceConfig, | ||||
| } | ||||
| 
 | ||||
| impl DaemonState { | ||||
|     pub fn new() -> Self { | ||||
|         Self::default() | ||||
|     } | ||||
| 
 | ||||
|     pub async fn create_new_container( | ||||
|         &mut self, | ||||
|         ip: String, | ||||
|         req_data: ContainerConfig, | ||||
|         unarchive_dir: String, | ||||
|     ) -> Result<(), Box<dyn std::error::Error>> { | ||||
|         deploy_enclave(&unarchive_dir).await?; | ||||
| 
 | ||||
|         let container = Container { | ||||
|             id: "123".to_string(), | ||||
|             name: "".to_string(), | ||||
|             package_path: unarchive_dir, | ||||
|             status: "running".to_string(), | ||||
|             admin: ip, | ||||
|             container_resource: req_data.resource.unwrap(), | ||||
|         }; | ||||
| 
 | ||||
|         self.containers.push(container); | ||||
| 
 | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										99
									
								
								src/grpc.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										99
									
								
								src/grpc.rs
									
									
									
									
									
								
							| @ -1,23 +1,20 @@ | ||||
| use chrono::Utc; | ||||
| use flate2::read::GzDecoder; | ||||
| use reqwest::Client; | ||||
| use std::io::BufReader; | ||||
| use std::path::Path; | ||||
| use std::process::Command; | ||||
| use anyhow::Result; | ||||
| use prost::Message; | ||||
| 
 | ||||
| use std::sync::Arc; | ||||
| use std::{net::SocketAddr, str::FromStr}; | ||||
| use tar::Archive; | ||||
| use tokio::io::AsyncWriteExt; | ||||
| use tokio::sync::RwLock; | ||||
| use tokio::{fs, fs::File}; | ||||
| use tonic::transport::Server; | ||||
| 
 | ||||
| use detee_shared::pb::daemon::daemon_service_server::{ | ||||
|     DaemonService as DaemonServicePB, DaemonServiceServer as DaemonServiceServerPB, | ||||
| }; | ||||
| use detee_shared::pb::daemon::NewContainerRes; | ||||
| use detee_shared::pb::shared::Container; | ||||
| use detee_shared::pb::shared::Container as ContainerPB; | ||||
| 
 | ||||
| use detee_shared::config::Container as ContainerConfig; | ||||
| 
 | ||||
| use crate::package::handle_package; | ||||
| use crate::DaemonState; | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| @ -30,7 +27,7 @@ impl DaemonServer { | ||||
|         Self { data } | ||||
|     } | ||||
| 
 | ||||
|     pub async fn start(&self) -> Result<(), Box<dyn std::error::Error>> { | ||||
|     pub async fn start(&self) -> Result<()> { | ||||
|         let port: String = std::env::var("PORT").unwrap_or_else(|_| "33400".to_string()); | ||||
| 
 | ||||
|         let addr = SocketAddr::from_str(format!("0.0.0.0:{port}").as_str())?; | ||||
| @ -51,19 +48,24 @@ impl DaemonServer { | ||||
| impl DaemonServicePB for DaemonServer { | ||||
|     async fn create_container( | ||||
|         &self, | ||||
|         request: tonic::Request<Container>, | ||||
|         request: tonic::Request<ContainerPB>, | ||||
|     ) -> Result<tonic::Response<NewContainerRes>, tonic::Status> { | ||||
|         let req_ip = request.remote_addr().unwrap().to_string(); | ||||
|         let req_data = request.into_inner(); | ||||
| 
 | ||||
|         if req_data.package_url.is_none() { | ||||
|             return Err(tonic::Status::data_loss("Package URL not provided")); | ||||
|         if req_data.package_url.is_none() || req_data.resource.is_none() { | ||||
|             return Err(tonic::Status::data_loss("missing some data in request")); | ||||
|         } | ||||
| 
 | ||||
|         let package_url = req_data.package_url.unwrap_or_default(); | ||||
|         let unarchive_dir = handle_package(package_url) | ||||
|         let unarchive_dir = handle_package(req_data.package_url.clone().unwrap_or_default()) | ||||
|             .await | ||||
|             .map_err(|err| tonic::Status::internal(err.to_string()))?; | ||||
|         deploy_enclave(unarchive_dir) | ||||
| 
 | ||||
|         let req_container = ContainerConfig::decode(&req_data.encode_to_vec()[..]).unwrap(); | ||||
| 
 | ||||
|         self.data | ||||
|             .write() | ||||
|             .await | ||||
|             .create_new_container(req_ip, req_container, unarchive_dir) | ||||
|             .await | ||||
|             .map_err(|err| tonic::Status::internal(err.to_string()))?; | ||||
| 
 | ||||
| @ -72,64 +74,3 @@ impl DaemonServicePB for DaemonServer { | ||||
|         })); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| async fn handle_package(package_url: String) -> Result<String, Box<dyn std::error::Error>> { | ||||
|     let dir_path = Path::new("./enclave_archives"); | ||||
|     fs::create_dir_all(dir_path).await?; | ||||
| 
 | ||||
|     let utc_time = Utc::now().format("%Y%m%d%H%M%S"); | ||||
| 
 | ||||
|     let file_name = format!("{}-enclave_packager.tar.gz", utc_time); | ||||
|     let file_path = dir_path.join(file_name); | ||||
|     if let Err(e) = download_file(&package_url, &file_path).await { | ||||
|         println!("Error downloading file: {:?}", e); | ||||
|         return Err("Error downloading file".into()); | ||||
|     } | ||||
| 
 | ||||
|     let downloaded_file = std::fs::File::open(file_path)?; | ||||
|     let mut reader = BufReader::new(downloaded_file); | ||||
|     let mut archive = Archive::new(GzDecoder::new(&mut reader)); | ||||
| 
 | ||||
|     if let Err(er) = archive.entries() { | ||||
|         dbg!(&er); | ||||
|         return Err(format!("Error: file not an archive: {er:?}").into()); | ||||
|     }; | ||||
| 
 | ||||
|     let unarchive_dir = format!("./enclaves/{}", utc_time); | ||||
|     fs::create_dir_all(Path::new(&unarchive_dir)).await?; | ||||
|     archive.unpack(&unarchive_dir)?; | ||||
| 
 | ||||
|     Ok(unarchive_dir) | ||||
| } | ||||
| 
 | ||||
| async fn deploy_enclave( | ||||
|     enclave_path: String, | ||||
|     // enclave_name: String,
 | ||||
|     // publishing_ports: Vec<u32>,
 | ||||
|     // ...
 | ||||
| ) -> Result<(), Box<dyn std::error::Error>> { | ||||
|     println!("Deploying enclave: {:?}", enclave_path); | ||||
|     let docker_deploy_str = format!( | ||||
|         "docker run -v {enclave_path}/enclave_packager:/enclave_packager --device /dev/sgx/enclave --device /dev/sgx/provision -p 34500:34500 noormohammedb/occlum-enclave:v1"); | ||||
| 
 | ||||
|     println!("{}", &docker_deploy_str); | ||||
| 
 | ||||
|     let child = Command::new("sh") | ||||
|         .arg("-c") | ||||
|         .arg(docker_deploy_str) | ||||
|         .spawn()?; | ||||
| 
 | ||||
|     dbg!(child); | ||||
|     Ok(()) | ||||
| } | ||||
| 
 | ||||
| async fn download_file(url: &str, file_path: &Path) -> Result<(), Box<dyn std::error::Error>> { | ||||
|     let client = Client::new(); | ||||
|     let response = client.get(url).send().await?; | ||||
|     let data = response.bytes().await?; | ||||
| 
 | ||||
|     let mut file = File::create(file_path).await?; | ||||
|     file.write_all(&data).await?; | ||||
| 
 | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
							
								
								
									
										10
									
								
								src/main.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										10
									
								
								src/main.rs
									
									
									
									
									
								
							| @ -1,15 +1,13 @@ | ||||
| mod grpc; | ||||
| pub mod data; | ||||
| pub mod grpc; | ||||
| pub mod package; | ||||
| 
 | ||||
| pub use data::DaemonState; | ||||
| use std::sync::Arc; | ||||
| 
 | ||||
| use grpc::DaemonServer; | ||||
| use tokio::sync::RwLock; | ||||
| 
 | ||||
| #[derive(Debug, Default)] | ||||
| pub struct DaemonState { | ||||
|     pub containers: Vec<String>, | ||||
| } | ||||
| 
 | ||||
| #[tokio::main] | ||||
| async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||||
|     println!("Detee daemon"); | ||||
|  | ||||
							
								
								
									
										71
									
								
								src/package.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										71
									
								
								src/package.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| use anyhow::{anyhow, Result}; | ||||
| use chrono::Utc; | ||||
| use flate2::read::GzDecoder; | ||||
| use reqwest::Client; | ||||
| use std::io::BufReader; | ||||
| use std::path::Path; | ||||
| use std::process::Command; | ||||
| use tar::Archive; | ||||
| use tokio::io::AsyncWriteExt; | ||||
| use tokio::{fs, fs::File}; | ||||
| 
 | ||||
| pub async fn handle_package(package_url: String) -> Result<String> { | ||||
|     let dir_path = Path::new("./enclave_archives"); | ||||
|     fs::create_dir_all(dir_path).await?; | ||||
| 
 | ||||
|     let utc_time = Utc::now().format("%Y%m%d%H%M%S"); | ||||
| 
 | ||||
|     let file_name = format!("{}-enclave_packager.tar.gz", utc_time); | ||||
|     let file_path = dir_path.join(file_name); | ||||
|     if let Err(e) = download_file(&package_url, &file_path).await { | ||||
|         println!("Error downloading file: {:?}", e); | ||||
|         return Err(anyhow!("Error downloading file")); | ||||
|     } | ||||
| 
 | ||||
|     let downloaded_file = std::fs::File::open(file_path)?; | ||||
|     let mut reader = BufReader::new(downloaded_file); | ||||
|     let mut archive = Archive::new(GzDecoder::new(&mut reader)); | ||||
| 
 | ||||
|     if let Err(er) = archive.entries() { | ||||
|         dbg!(&er); | ||||
|         return Err(anyhow!("Error: file not an archive: {er:?}")); | ||||
|     }; | ||||
| 
 | ||||
|     let unarchive_dir = format!("./enclaves/{}", utc_time); | ||||
|     fs::create_dir_all(Path::new(&unarchive_dir)).await?; | ||||
|     archive.unpack(&unarchive_dir)?; | ||||
| 
 | ||||
|     Ok(unarchive_dir) | ||||
| } | ||||
| 
 | ||||
| pub async fn deploy_enclave( | ||||
|     enclave_path: &str, | ||||
|     // enclave_name: String,
 | ||||
|     // publishing_ports: Vec<u32>,
 | ||||
|     // ...
 | ||||
| ) -> Result<(), Box<dyn std::error::Error>> { | ||||
|     println!("Deploying enclave: {:?}", enclave_path); | ||||
|     let docker_deploy_str = format!( | ||||
|         "docker run -v {enclave_path}/enclave_packager:/enclave_packager --device /dev/sgx/enclave --device /dev/sgx/provision -p 34500:34500 noormohammedb/occlum-enclave:v1"); | ||||
| 
 | ||||
|     println!("{}", &docker_deploy_str); | ||||
| 
 | ||||
|     let child = Command::new("sh") | ||||
|         .arg("-c") | ||||
|         .arg(docker_deploy_str) | ||||
|         .spawn()?; | ||||
| 
 | ||||
|     dbg!(child); | ||||
|     Ok(()) | ||||
| } | ||||
| 
 | ||||
| pub async fn download_file(url: &str, file_path: &Path) -> Result<(), Box<dyn std::error::Error>> { | ||||
|     let client = Client::new(); | ||||
|     let response = client.get(url).send().await?; | ||||
|     let data = response.bytes().await?; | ||||
| 
 | ||||
|     let mut file = File::create(file_path).await?; | ||||
|     file.write_all(&data).await?; | ||||
| 
 | ||||
|     Ok(()) | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user