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" | name = "detee-sgx-daemon" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  |  "anyhow", | ||||||
|  "chrono", |  "chrono", | ||||||
|  "detee-shared", |  "detee-shared", | ||||||
|  "env_logger", |  "env_logger", | ||||||
| @ -314,6 +315,7 @@ dependencies = [ | |||||||
| [[package]] | [[package]] | ||||||
| name = "detee-shared" | name = "detee-shared" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
|  | source = "git+ssh://git@gitea.detee.cloud/noormohammedb/detee-shared#358c2d84ca092cad5df69ac19cc6acbfb85ee8d7" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "base64", |  "base64", | ||||||
|  "prost", |  "prost", | ||||||
|  | |||||||
| @ -10,12 +10,13 @@ prost-types = "0.13.4" | |||||||
| tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "fs"] } | tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "fs"] } | ||||||
| tonic = "0.12.3" | tonic = "0.12.3" | ||||||
| 
 | 
 | ||||||
| # detee-shared = { git = "ssh://git@gitea.detee.cloud/noormohammedb/detee-shared" } | detee-shared = { git = "ssh://git@gitea.detee.cloud/noormohammedb/detee-shared" } | ||||||
| detee-shared = { path = "../detee-shared" } | # detee-shared = { path = "../detee-shared" } | ||||||
| chrono = "0.4.39" | chrono = "0.4.39" | ||||||
| reqwest = "0.12.12" | reqwest = "0.12.12" | ||||||
| flate2 = "1.0.35" | flate2 = "1.0.35" | ||||||
| tar = "0.4.43" | tar = "0.4.43" | ||||||
|  | anyhow = "1.0.95" | ||||||
| 
 | 
 | ||||||
| [build-dependencies] | [build-dependencies] | ||||||
| tonic-build = "0.12.3" | tonic-build = "0.12.3" | ||||||
|  | |||||||
							
								
								
									
										8
									
								
								build.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										8
									
								
								build.rs
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | |||||||
| fn main() -> Result<(), Box<dyn std::error::Error>> { | fn main() -> Result<(), Box<dyn std::error::Error>> { | ||||||
|     tonic_build::configure() |     // tonic_build::configure()
 | ||||||
|         .build_server(true) |     //     .build_server(true)
 | ||||||
|         .compile_protos(&["daemon.proto"], &["proto"]) |     //     .compile_protos(&["daemon.proto"], &["proto"])
 | ||||||
|         .unwrap_or_else(|e| panic!("Failed to compile protos {:?}", e)); |     //     .unwrap_or_else(|e| panic!("Failed to compile protos {:?}", e));
 | ||||||
|     Ok(()) |     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 anyhow::Result; | ||||||
| use flate2::read::GzDecoder; | use prost::Message; | ||||||
| use reqwest::Client; | 
 | ||||||
| use std::io::BufReader; |  | ||||||
| use std::path::Path; |  | ||||||
| use std::process::Command; |  | ||||||
| use std::sync::Arc; | use std::sync::Arc; | ||||||
| use std::{net::SocketAddr, str::FromStr}; | use std::{net::SocketAddr, str::FromStr}; | ||||||
| use tar::Archive; |  | ||||||
| use tokio::io::AsyncWriteExt; |  | ||||||
| use tokio::sync::RwLock; | use tokio::sync::RwLock; | ||||||
| use tokio::{fs, fs::File}; |  | ||||||
| use tonic::transport::Server; | use tonic::transport::Server; | ||||||
| 
 | 
 | ||||||
| use detee_shared::pb::daemon::daemon_service_server::{ | use detee_shared::pb::daemon::daemon_service_server::{ | ||||||
|     DaemonService as DaemonServicePB, DaemonServiceServer as DaemonServiceServerPB, |     DaemonService as DaemonServicePB, DaemonServiceServer as DaemonServiceServerPB, | ||||||
| }; | }; | ||||||
| use detee_shared::pb::daemon::NewContainerRes; | 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; | use crate::DaemonState; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone)] | #[derive(Debug, Clone)] | ||||||
| @ -30,7 +27,7 @@ impl DaemonServer { | |||||||
|         Self { data } |         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 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())?; |         let addr = SocketAddr::from_str(format!("0.0.0.0:{port}").as_str())?; | ||||||
| @ -51,19 +48,24 @@ impl DaemonServer { | |||||||
| impl DaemonServicePB for DaemonServer { | impl DaemonServicePB for DaemonServer { | ||||||
|     async fn create_container( |     async fn create_container( | ||||||
|         &self, |         &self, | ||||||
|         request: tonic::Request<Container>, |         request: tonic::Request<ContainerPB>, | ||||||
|     ) -> Result<tonic::Response<NewContainerRes>, tonic::Status> { |     ) -> Result<tonic::Response<NewContainerRes>, tonic::Status> { | ||||||
|  |         let req_ip = request.remote_addr().unwrap().to_string(); | ||||||
|         let req_data = request.into_inner(); |         let req_data = request.into_inner(); | ||||||
| 
 | 
 | ||||||
|         if req_data.package_url.is_none() { |         if req_data.package_url.is_none() || req_data.resource.is_none() { | ||||||
|             return Err(tonic::Status::data_loss("Package URL not provided")); |             return Err(tonic::Status::data_loss("missing some data in request")); | ||||||
|         } |         } | ||||||
| 
 |         let unarchive_dir = handle_package(req_data.package_url.clone().unwrap_or_default()) | ||||||
|         let package_url = req_data.package_url.unwrap_or_default(); |  | ||||||
|         let unarchive_dir = handle_package(package_url) |  | ||||||
|             .await |             .await | ||||||
|             .map_err(|err| tonic::Status::internal(err.to_string()))?; |             .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 |             .await | ||||||
|             .map_err(|err| tonic::Status::internal(err.to_string()))?; |             .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 std::sync::Arc; | ||||||
| 
 | 
 | ||||||
| use grpc::DaemonServer; | use grpc::DaemonServer; | ||||||
| use tokio::sync::RwLock; | use tokio::sync::RwLock; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Default)] |  | ||||||
| pub struct DaemonState { |  | ||||||
|     pub containers: Vec<String>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[tokio::main] | #[tokio::main] | ||||||
| async fn main() -> Result<(), Box<dyn std::error::Error>> { | async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||||||
|     println!("Detee daemon"); |     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