Refactor daemon state
configuring to make it persistance changing code architecture to same node state into disk
This commit is contained in:
		
							parent
							
								
									83fa4728c6
								
							
						
					
					
						commit
						557376dc08
					
				
							
								
								
									
										3
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -280,6 +280,7 @@ dependencies = [ | |||||||
|  "reqwest", |  "reqwest", | ||||||
|  "serde", |  "serde", | ||||||
|  "serde_json", |  "serde_json", | ||||||
|  |  "serde_yml", | ||||||
|  "tar", |  "tar", | ||||||
|  "tokio", |  "tokio", | ||||||
|  "tokio-stream", |  "tokio-stream", | ||||||
| @ -290,7 +291,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?branch=stable_01#df3a4631dd919e0cb35f6238f91f262c999c93b8" | source = "git+ssh://git@gitea.detee.cloud/noormohammedb/detee-shared?branch=stable_01#fce57884937a4ec02acbf2f5b370ab879b1af657" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "base64", |  "base64", | ||||||
|  "prost", |  "prost", | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ detee-shared = { git = "ssh://git@gitea.detee.cloud/noormohammedb/detee-shared", | |||||||
| log = "0.4.25" | log = "0.4.25" | ||||||
| serde = "1.0.217" | serde = "1.0.217" | ||||||
| serde_json = "1.0.138" | serde_json = "1.0.138" | ||||||
|  | serde_yml = "0.0.12" | ||||||
| 
 | 
 | ||||||
| [build-dependencies] | [build-dependencies] | ||||||
| tonic-build = "0.12.3" | tonic-build = "0.12.3" | ||||||
|  | |||||||
| @ -1,12 +1,43 @@ | |||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct Config { | pub struct HostConfig { | ||||||
|     pub brain_url: String, |     pub brain_url: String, | ||||||
|  |     pub host_ip_address: String, | ||||||
|  |     pub owner_wallet: String, | ||||||
|  |     pub max_cores_per_app: u32, | ||||||
|  |     pub max_vcpu_reservation: u32, | ||||||
|  |     pub max_mem_reservation_mb: u32, | ||||||
|  |     pub max_ports_per_app: u16, | ||||||
|  |     // price per unit per minute
 | ||||||
|  |     pub price: u64, | ||||||
|  | 
 | ||||||
|  |     pub delete_archive: bool, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Default for Config { | impl Default for HostConfig { | ||||||
|     fn default() -> Self { |     fn default() -> Self { | ||||||
|  |         // TODO: load from config file
 | ||||||
|         let brain_url = |         let brain_url = | ||||||
|             std::env::var("BRAIN_URL").unwrap_or_else(|_| "http://127.0.0.1:31337".to_string()); |             std::env::var("BRAIN_URL").unwrap_or_else(|_| "http://127.0.0.1:31337".to_string()); | ||||||
|         Self { brain_url } |         let owner_wallet = "0x".to_string(); | ||||||
|  |         let host_ip_address = "127.0.0.1".to_string(); | ||||||
|  | 
 | ||||||
|  |         let max_cores_per_app = 1; | ||||||
|  |         let max_vcpu_reservation = 8; | ||||||
|  |         let max_mem_reservation_mb = 8192; | ||||||
|  |         let max_ports_per_app = 9; | ||||||
|  |         let price = 0; | ||||||
|  | 
 | ||||||
|  |         Self { | ||||||
|  |             brain_url, | ||||||
|  |             host_ip_address, | ||||||
|  |             owner_wallet, | ||||||
|  |             max_cores_per_app, | ||||||
|  |             max_ports_per_app, | ||||||
|  |             max_vcpu_reservation, | ||||||
|  |             max_mem_reservation_mb, | ||||||
|  |             price, | ||||||
|  | 
 | ||||||
|  |             delete_archive: true, | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,16 +1,11 @@ | |||||||
| use anyhow::Result; | use anyhow::{anyhow, Result}; | ||||||
| use std::process::Command; | use std::process::Command; | ||||||
| 
 | 
 | ||||||
| use crate::utils::prepare_port_map; |  | ||||||
| 
 |  | ||||||
| pub async fn deploy_enclave( | pub async fn deploy_enclave( | ||||||
|     enclave_path: &str, |     enclave_path: &str, | ||||||
|     container_name_uuid: String, |     container_name_uuid: String, | ||||||
|     publishing_ports: Vec<u32>, |     port_map: Vec<(u16, u16)>, | ||||||
|     // ...
 | ) -> Result<i32> { | ||||||
| ) -> Result<Vec<(u16, u16)>> { |  | ||||||
|     let port_map = prepare_port_map(publishing_ports).await; |  | ||||||
| 
 |  | ||||||
|     let port_maping_string = port_map |     let port_maping_string = port_map | ||||||
|         .iter() |         .iter() | ||||||
|         .map(|(host, container)| format!("-p {host}:{container}")) |         .map(|(host, container)| format!("-p {host}:{container}")) | ||||||
| @ -23,12 +18,17 @@ pub async fn deploy_enclave( | |||||||
|         --device /dev/sgx/enclave --device /dev/sgx/provision {port_maping_string} noormohammedb/occlum-enclave:v1"#
 |         --device /dev/sgx/enclave --device /dev/sgx/provision {port_maping_string} noormohammedb/occlum-enclave:v1"#
 | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     let _child = Command::new("sh") |     let mut child = Command::new("sh") | ||||||
|         .arg("-c") |         .arg("-c") | ||||||
|         .arg(docker_deploy_str) |         .arg(docker_deploy_str) | ||||||
|         .spawn()?; |         .spawn()?; | ||||||
| 
 | 
 | ||||||
|     Ok(port_map) |     let exit = child.wait()?; | ||||||
|  |     let exit_code = exit | ||||||
|  |         .code() | ||||||
|  |         .ok_or(anyhow!("No exit code, process terminated by a signal"))?; | ||||||
|  | 
 | ||||||
|  |     Ok(exit_code) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn delete_enclave(container_name_uuid: String) -> Result<()> { | pub fn delete_enclave(container_name_uuid: String) -> Result<()> { | ||||||
|  | |||||||
							
								
								
									
										114
									
								
								src/data.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										114
									
								
								src/data.rs
									
									
									
									
									
								
							| @ -1,56 +1,115 @@ | |||||||
| use anyhow::{anyhow, Result}; | use anyhow::{anyhow, Result}; | ||||||
| use detee_shared::types::brain::AppDeployConfig; | use detee_shared::types::brain::AppDeployConfig; | ||||||
| use detee_shared::types::brain::Resource as ResourceConfig; | use detee_shared::types::brain::Resource as ResourceConfig; | ||||||
|  | use std::collections::HashSet; | ||||||
|  | use std::fs::File; | ||||||
|  | use std::io::Write; | ||||||
|  | 
 | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
| 
 | 
 | ||||||
| use crate::container::delete_enclave; |  | ||||||
| use crate::container::deploy_enclave; | use crate::container::deploy_enclave; | ||||||
|  | use crate::global::APP_CONFIG_DIR; | ||||||
|  | use crate::global::APP_NAME_PREFIX; | ||||||
|  | use crate::utils::handle_package; | ||||||
|  | use crate::utils::prepare_port_map; | ||||||
|  | use crate::HostConfig; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Default)] | #[derive(Debug, Default)] | ||||||
| pub struct DaemonState { | pub struct HostResources { | ||||||
|     pub containers: Vec<Container>, |     pub existing_apps: HashSet<String>, | ||||||
|  |     pub reserved_vcpus: u32, | ||||||
|  |     pub reserved_memory: u32, | ||||||
|  |     pub reserved_host_ports: HashSet<u16>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Default)] | impl HostResources { | ||||||
| pub struct Container { |     // TODO: implement load and save
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Default, Serialize, Deserialize)] | ||||||
|  | pub struct App { | ||||||
|     pub uuid: String, |     pub uuid: String, | ||||||
|     pub name: String, |     pub name: String, | ||||||
|     pub package_path: String, |     pub package_path: String, | ||||||
|     pub status: String, |     pub status: String, | ||||||
|     pub admin: String, |     pub admin: String, | ||||||
|     pub container_resource: ResourceConfig, |     pub app_resource: ResourceConfig, | ||||||
|     pub mapped_ports: Vec<(u16, u16)>, |     pub mapped_ports: Vec<(u16, u16)>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl DaemonState { | impl App { | ||||||
|     pub async fn create_new_container( |     pub async fn new( | ||||||
|         &mut self, |         new_app_req: AppDeployConfig, | ||||||
|         req_data: AppDeployConfig, |         host_config: &HostConfig, | ||||||
|         unarchive_dir: String, |         host_resource: &mut HostResources, | ||||||
|     ) -> Result<Vec<(u16, u16)>> { |     ) -> Result<Self> { | ||||||
|         let publishing_ports = req_data.resource.clone().port; |         let app_uuid = new_app_req.uuid.clone(); | ||||||
|         let uuid = req_data.uuid; |  | ||||||
|         let container_name = format!("dtpm-{uuid}"); |  | ||||||
|         let mapped_ports = |  | ||||||
|             deploy_enclave(&unarchive_dir, container_name.clone(), publishing_ports).await?; |  | ||||||
| 
 | 
 | ||||||
|         let container = Container { |         if host_config.max_cores_per_app < new_app_req.resource.vcpu { | ||||||
|             uuid, |             return Err(anyhow!("too many vcpus for app")); | ||||||
|             name: container_name, |         } | ||||||
|  |         if host_config.max_vcpu_reservation | ||||||
|  |             < host_resource | ||||||
|  |                 .reserved_vcpus | ||||||
|  |                 .saturating_add(new_app_req.resource.vcpu) | ||||||
|  |         { | ||||||
|  |             return Err(anyhow!("vcpus not available")); | ||||||
|  |         } | ||||||
|  |         if host_config.max_mem_reservation_mb | ||||||
|  |             < host_resource | ||||||
|  |                 .reserved_memory | ||||||
|  |                 .saturating_add(new_app_req.resource.memory_mb) | ||||||
|  |         { | ||||||
|  |             return Err(anyhow!("not enough memory available")); | ||||||
|  |         } | ||||||
|  |         if new_app_req.resource.disk_mb < 128 { | ||||||
|  |             return Err(anyhow!("disk too small")); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let package_url = new_app_req.package_url.clone(); | ||||||
|  |         let mapped_ports = prepare_port_map(new_app_req.resource.port.clone()).await; | ||||||
|  |         let app_name = format!("{APP_NAME_PREFIX}-{app_uuid}"); | ||||||
|  | 
 | ||||||
|  |         let unarchive_dir = | ||||||
|  |             handle_package(package_url, app_uuid.clone(), host_config.delete_archive).await?; | ||||||
|  | 
 | ||||||
|  |         let exit_code = | ||||||
|  |             deploy_enclave(&unarchive_dir, app_name.clone(), mapped_ports.clone()).await?; | ||||||
|  | 
 | ||||||
|  |         if exit_code != 0 { | ||||||
|  |             // TODO: cleanup unarchive_dir
 | ||||||
|  |             return Err(anyhow!("Failed to deploy enclave")); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let app_instance = Self { | ||||||
|  |             uuid: app_uuid, | ||||||
|  |             name: app_name, | ||||||
|             package_path: unarchive_dir, |             package_path: unarchive_dir, | ||||||
|             status: "running".to_string(), |             status: "running".to_string(), | ||||||
|             admin: req_data.admin_pubkey, |             admin: new_app_req.admin_pubkey, | ||||||
|             container_resource: req_data.resource, |             app_resource: new_app_req.resource, | ||||||
|             mapped_ports: mapped_ports.clone(), |             mapped_ports, | ||||||
|         }; |         }; | ||||||
|  |         app_instance.write_config()?; | ||||||
|  |         host_resource | ||||||
|  |             .existing_apps | ||||||
|  |             .insert(app_instance.uuid.clone()); | ||||||
| 
 | 
 | ||||||
|         self.containers.push(container); |         Ok(app_instance) | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|         Ok(mapped_ports) |     fn write_config(&self) -> Result<()> { | ||||||
|  |         let mut file = File::create(APP_CONFIG_DIR.to_string() + &self.uuid + ".yaml")?; | ||||||
|  |         file.write_all(serde_yml::to_string(self)?.as_bytes())?; | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub async fn delete_container(&mut self, container_uuid: String) -> Result<()> { |     pub async fn delete_container(&mut self, container_uuid: String) -> Result<()> { | ||||||
|  |         let _ = container_uuid; | ||||||
|  |         // TODO: implement delete
 | ||||||
|  |         /* | ||||||
|         let Some(container_position) = self |         let Some(container_position) = self | ||||||
|             .containers |             .existing_apps | ||||||
|             .iter() |             .iter() | ||||||
|             .position(|c| c.uuid == container_uuid) |             .position(|c| c.uuid == container_uuid) | ||||||
|         else { |         else { | ||||||
| @ -60,10 +119,11 @@ impl DaemonState { | |||||||
| 
 | 
 | ||||||
|         let container = &self.containers[container_position]; |         let container = &self.containers[container_position]; | ||||||
| 
 | 
 | ||||||
|         let container_name = format!("dtpm-{}", container.uuid); |         let container_name = format!("{APP_NAME_PREFIX}-{}", container.uuid); | ||||||
|         delete_enclave(container_name)?; |         delete_enclave(container_name)?; | ||||||
| 
 | 
 | ||||||
|         self.containers.remove(container_position); |         self.containers.remove(container_position); | ||||||
|  |          */ | ||||||
| 
 | 
 | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -4,3 +4,7 @@ pub const ADMIN_PUBKEY: &str = "0x28a3a71197250b0fa4dd0f86288e07ec9cc78ce3338e21 | |||||||
| pub const PACKAGE_ARCHIVE_POSTFIX: &str = "-enclave_packager.tar.gz"; | pub const PACKAGE_ARCHIVE_POSTFIX: &str = "-enclave_packager.tar.gz"; | ||||||
| pub const PACKAGE_ARCHIVE_DIR_PATH: &str = "./enclave_archives"; | pub const PACKAGE_ARCHIVE_DIR_PATH: &str = "./enclave_archives"; | ||||||
| pub const PACKAGE_DIR_PATH: &str = "./enclaves"; | pub const PACKAGE_DIR_PATH: &str = "./enclaves"; | ||||||
|  | 
 | ||||||
|  | pub const APP_NAME_PREFIX: &str = "dtpm"; | ||||||
|  | // TODO: handle this home directory properly
 | ||||||
|  | pub const APP_CONFIG_DIR: &str = "~/.dtpm/app_daemon/"; | ||||||
|  | |||||||
| @ -1,6 +1,5 @@ | |||||||
| use anyhow::Result; | use anyhow::Result; | ||||||
| use detee_shared::pb::brain::brain_app_daemon_client::BrainAppDaemonClient; | use detee_shared::pb::brain::brain_app_daemon_client::BrainAppDaemonClient; | ||||||
| use detee_shared::pb::brain::daemon_message_app; |  | ||||||
| use detee_shared::pb::brain::{ | use detee_shared::pb::brain::{ | ||||||
|     AppContract, BrainMessageApp, DaemonMessageApp, Pubkey, RegisterAppNodeReq, |     AppContract, BrainMessageApp, DaemonMessageApp, Pubkey, RegisterAppNodeReq, | ||||||
| }; | }; | ||||||
| @ -21,7 +20,7 @@ pub struct ConnectionData { | |||||||
|     pub daemon_msg_tx: Sender<DaemonMessageApp>, |     pub daemon_msg_tx: Sender<DaemonMessageApp>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub async fn register_node(config: &crate::Config) -> Result<Vec<AppContract>> { | pub async fn register_node(config: &crate::HostConfig) -> Result<Vec<AppContract>> { | ||||||
|     let mut client = BrainAppDaemonClient::connect(config.brain_url.clone()).await?; |     let mut client = BrainAppDaemonClient::connect(config.brain_url.clone()).await?; | ||||||
| 
 | 
 | ||||||
|     log::debug!("registering node with brain"); |     log::debug!("registering node with brain"); | ||||||
| @ -105,10 +104,8 @@ pub async fn send_messages( | |||||||
|     let pubkey = NODE_PUBKEY.to_string(); |     let pubkey = NODE_PUBKEY.to_string(); | ||||||
| 
 | 
 | ||||||
|     let rx_stream = ReceiverStream::new(rx); |     let rx_stream = ReceiverStream::new(rx); | ||||||
|     tx.send(DaemonMessageApp { | 
 | ||||||
|         msg: Some(daemon_message_app::Msg::Pubkey(pubkey)), |     tx.send(pubkey.into()).await?; | ||||||
|     }) |  | ||||||
|     .await?; |  | ||||||
|     client.daemon_messages(rx_stream).await?; |     client.daemon_messages(rx_stream).await?; | ||||||
|     log::debug!("daemon_messages is about to exit"); |     log::debug!("daemon_messages is about to exit"); | ||||||
|     Ok(()) |     Ok(()) | ||||||
|  | |||||||
							
								
								
									
										125
									
								
								src/main.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										125
									
								
								src/main.rs
									
									
									
									
									
								
							| @ -5,40 +5,43 @@ pub mod global; | |||||||
| pub mod grpc; | pub mod grpc; | ||||||
| pub mod utils; | pub mod utils; | ||||||
| 
 | 
 | ||||||
|  | use data::App; | ||||||
| use detee_shared::pb::brain::brain_message_app; | use detee_shared::pb::brain::brain_message_app; | ||||||
| use detee_shared::pb::brain::daemon_message_app; |  | ||||||
| use detee_shared::pb::brain::AppContract; | use detee_shared::pb::brain::AppContract; | ||||||
| use detee_shared::pb::brain::BrainMessageApp; | use detee_shared::pb::brain::BrainMessageApp; | ||||||
| use detee_shared::pb::brain::DaemonMessageApp; | use detee_shared::pb::brain::DaemonMessageApp; | ||||||
| use detee_shared::pb::brain::MappedPort; | use detee_shared::pb::brain::MappedPort; | ||||||
| use detee_shared::pb::brain::NewAppRes; | use detee_shared::pb::brain::NewAppRes; | ||||||
| use detee_shared::types::brain::AppDeployConfig; | use detee_shared::types::brain::AppDeployConfig; | ||||||
|  | use log::info; | ||||||
| use std::time::Duration; | use std::time::Duration; | ||||||
| use tokio::sync::mpsc::Receiver; | use tokio::sync::mpsc::Receiver; | ||||||
| use tokio::sync::mpsc::Sender; | use tokio::sync::mpsc::Sender; | ||||||
| use tokio::time::sleep; | use tokio::time::sleep; | ||||||
| 
 | 
 | ||||||
| use utils::cleanup_enclave_disk_and_package; | use utils::cleanup_enclave_disk_and_package; | ||||||
| use utils::handle_package; |  | ||||||
| 
 | 
 | ||||||
| pub use crate::config::Config; | pub use crate::config::HostConfig; | ||||||
| pub use crate::data::DaemonState; | pub use crate::data::HostResources; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct AppHandler { | pub struct AppHandler { | ||||||
|     pub receiver: Receiver<BrainMessageApp>, |     pub receiver: Receiver<BrainMessageApp>, | ||||||
|     pub sender: Sender<DaemonMessageApp>, |     pub sender: Sender<DaemonMessageApp>, | ||||||
|     pub config: Config, |     pub host_config: HostConfig, | ||||||
|     pub data: DaemonState, |     pub host_resource: HostResources, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl AppHandler { | impl AppHandler { | ||||||
|     pub fn new(receiver: Receiver<BrainMessageApp>, sender: Sender<DaemonMessageApp>) -> Self { |     pub fn new(receiver: Receiver<BrainMessageApp>, sender: Sender<DaemonMessageApp>) -> Self { | ||||||
|  |         // TODO: load from config and resources from file,
 | ||||||
|  |         //       if not found use default and save host resources to file
 | ||||||
|  | 
 | ||||||
|         Self { |         Self { | ||||||
|             receiver, |             receiver, | ||||||
|             sender, |             sender, | ||||||
|             config: Config::default(), |             host_config: HostConfig::default(), | ||||||
|             data: DaemonState::default(), |             host_resource: HostResources::default(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -50,11 +53,11 @@ impl AppHandler { | |||||||
|         while let Some(brain_msg) = self.receiver.recv().await { |         while let Some(brain_msg) = self.receiver.recv().await { | ||||||
|             match brain_msg.msg { |             match brain_msg.msg { | ||||||
|                 Some(brain_message_app::Msg::NewAppReq(msg)) => { |                 Some(brain_message_app::Msg::NewAppReq(msg)) => { | ||||||
|                     self.handle_new_container_req(msg.into()).await; |                     self.handle_new_app_req(msg.into()).await; | ||||||
|                 } |                 } | ||||||
|                 Some(brain_message_app::Msg::DeleteAppReq(msg)) => { |                 Some(brain_message_app::Msg::DeleteAppReq(msg)) => { | ||||||
|                     let app_id = msg.uuid; |                     let app_id = msg.uuid; | ||||||
|                     self.handle_del_container_req(app_id).await; |                     self.handle_del_app_req(app_id).await; | ||||||
|                 } |                 } | ||||||
|                 None => { |                 None => { | ||||||
|                     log::error!("Brain disconnected"); |                     log::error!("Brain disconnected"); | ||||||
| @ -64,76 +67,50 @@ impl AppHandler { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async fn handle_new_container_req(&mut self, new_container_req: AppDeployConfig) { |     async fn handle_new_app_req(&mut self, new_app_req: AppDeployConfig) { | ||||||
|         let container_uuid = new_container_req.uuid.clone(); |         let uuid = new_app_req.uuid.clone(); | ||||||
|  |         let app_result = App::new(new_app_req, &self.host_config, &mut self.host_resource).await; | ||||||
| 
 | 
 | ||||||
|         let unarchive_dir = match handle_package( |         match app_result { | ||||||
|             new_container_req.package_url.clone(), |             Ok(app) => { | ||||||
|             container_uuid.clone(), |                 // TODO: update host resources to brain
 | ||||||
|         ) |                 self.send_node_resources().await; | ||||||
|         .await |  | ||||||
|         { |  | ||||||
|             Ok(unarchive_dir) => unarchive_dir, |  | ||||||
|             Err(e) => { |  | ||||||
|                 let res = DaemonMessageApp { |  | ||||||
|                     msg: Some(daemon_message_app::Msg::NewAppRes(NewAppRes { |  | ||||||
|                         uuid: new_container_req.uuid, |  | ||||||
|                         status: "failed".to_string(), |  | ||||||
|                         error: e.to_string(), |  | ||||||
|                         ..Default::default() |  | ||||||
|                     })), |  | ||||||
|                 }; |  | ||||||
| 
 | 
 | ||||||
|                 println!("sending response {:?}", res); |                 info!("Succesfully started VM {uuid}"); | ||||||
|                 let _ = self.sender.send(res).await; |                 let res = NewAppRes { | ||||||
|                 return; |                     uuid, | ||||||
|             } |                     status: "success".to_string(), | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         let mapped_ports = match self |  | ||||||
|             .data |  | ||||||
|             .create_new_container(new_container_req, unarchive_dir) |  | ||||||
|             .await |  | ||||||
|         { |  | ||||||
|             Ok(mapped_ports) => mapped_ports.into_iter().map(MappedPort::from).collect(), |  | ||||||
|             Err(e) => { |  | ||||||
|                 let res = DaemonMessageApp { |  | ||||||
|                     msg: Some(daemon_message_app::Msg::NewAppRes(NewAppRes { |  | ||||||
|                         uuid: container_uuid, |  | ||||||
|                         status: "failed".to_string(), |  | ||||||
|                         error: e.to_string(), |  | ||||||
|                         ..Default::default() |  | ||||||
|                     })), |  | ||||||
|                 }; |  | ||||||
| 
 |  | ||||||
|                 println!("sending response {:?}", res); |  | ||||||
|                 let _ = self.sender.send(res).await; |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         let res = DaemonMessageApp { |  | ||||||
|             msg: Some(daemon_message_app::Msg::NewAppRes(NewAppRes { |  | ||||||
|                 uuid: container_uuid, |  | ||||||
|                 status: "Success".to_string(), |  | ||||||
|                     error: "".to_string(), |                     error: "".to_string(), | ||||||
|                 ip_address: "".to_string(), |                     mapped_ports: app.mapped_ports.into_iter().map(MappedPort::from).collect(), | ||||||
|                 mapped_ports, |                     ip_address: self.host_config.host_ip_address.clone(), | ||||||
|             })), |                 }; | ||||||
|  |                 let _ = self.sender.send(res.into()).await; | ||||||
|  |             } | ||||||
|  |             Err(e) => { | ||||||
|  |                 let res = NewAppRes { | ||||||
|  |                     uuid, | ||||||
|  |                     status: "failed".to_string(), | ||||||
|  |                     error: e.to_string(), | ||||||
|  |                     ..Default::default() | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|         println!("sending response {:?}", res); |                 log::error!("sending response {:?}", res); | ||||||
|         let _ = self.sender.send(res).await; |                 let _ = self.sender.send(res.into()).await; | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async fn handle_del_container_req(&mut self, container_uuid: String) { |     async fn handle_del_app_req(&mut self, container_uuid: String) { | ||||||
|         if let Err(e) = self.data.delete_container(container_uuid.clone()).await { |         // if let Err(e) = self.data.delete_container(container_uuid.clone()).await { log::error!("Failed to delete container:\n{e}"); }
 | ||||||
|             log::error!("Failed to delete container:\n{e}"); | 
 | ||||||
|         } |  | ||||||
|         if let Err(er) = cleanup_enclave_disk_and_package(container_uuid).await { |         if let Err(er) = cleanup_enclave_disk_and_package(container_uuid).await { | ||||||
|             log::error!("Failed to cleanup disk:\n{er}"); |             log::error!("Failed to cleanup disk:\n{er}"); | ||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     async fn send_node_resources(&self) { | ||||||
|  |         // TODO: send host resources to brain
 | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[tokio::main] | #[tokio::main] | ||||||
| @ -145,17 +122,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { | |||||||
|         let (brain_msg_tx, brain_msg_rx) = tokio::sync::mpsc::channel(6); |         let (brain_msg_tx, brain_msg_rx) = tokio::sync::mpsc::channel(6); | ||||||
|         let (daemon_msg_tx, daemon_msg_rx) = tokio::sync::mpsc::channel(6); |         let (daemon_msg_tx, daemon_msg_rx) = tokio::sync::mpsc::channel(6); | ||||||
| 
 | 
 | ||||||
|         let mut container_handler = AppHandler::new(brain_msg_rx, daemon_msg_tx.clone()); |         let mut app_handler = AppHandler::new(brain_msg_rx, daemon_msg_tx.clone()); | ||||||
|         let brain_url = container_handler.config.brain_url.clone(); |         let brain_url = app_handler.host_config.brain_url.clone(); | ||||||
| 
 | 
 | ||||||
|         match grpc::register_node(&container_handler.config).await { |         match grpc::register_node(&app_handler.host_config).await { | ||||||
|             Ok(container_contracts) => container_handler.handle_contracts(container_contracts), |             Ok(app_contracts) => app_handler.handle_contracts(app_contracts), | ||||||
| 
 | 
 | ||||||
|             Err(e) => log::error!("Failed to connect to brain: {e}"), |             Err(e) => log::error!("Failed to connect to brain: {e}"), | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         tokio::spawn(async move { |         tokio::spawn(async move { | ||||||
|             container_handler.run().await; |             app_handler.run().await; | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         log::info!("Connecting to brain..."); |         log::info!("Connecting to brain..."); | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								src/utils.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										12
									
								
								src/utils.rs
									
									
									
									
									
								
							| @ -14,7 +14,11 @@ use crate::global::{PACKAGE_ARCHIVE_DIR_PATH, PACKAGE_ARCHIVE_POSTFIX, PACKAGE_D | |||||||
| 
 | 
 | ||||||
| pub static IP_INFO: LazyLock<IPInfo> = LazyLock::new(|| get_ip_info().unwrap()); | pub static IP_INFO: LazyLock<IPInfo> = LazyLock::new(|| get_ip_info().unwrap()); | ||||||
| 
 | 
 | ||||||
| pub async fn handle_package(package_url: String, container_uuid: String) -> Result<String> { | pub async fn handle_package( | ||||||
|  |     package_url: String, | ||||||
|  |     container_uuid: String, | ||||||
|  |     delete_archive: bool, | ||||||
|  | ) -> Result<String> { | ||||||
|     let dir_path = Path::new(PACKAGE_ARCHIVE_DIR_PATH); |     let dir_path = Path::new(PACKAGE_ARCHIVE_DIR_PATH); | ||||||
|     fs::create_dir_all(dir_path).await?; |     fs::create_dir_all(dir_path).await?; | ||||||
| 
 | 
 | ||||||
| @ -25,7 +29,7 @@ pub async fn handle_package(package_url: String, container_uuid: String) -> Resu | |||||||
|         return Err(anyhow!("Error downloading file")); |         return Err(anyhow!("Error downloading file")); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     let downloaded_file = std::fs::File::open(file_path)?; |     let downloaded_file = std::fs::File::open(&file_path)?; | ||||||
|     let mut reader = BufReader::new(downloaded_file); |     let mut reader = BufReader::new(downloaded_file); | ||||||
|     let mut archive = Archive::new(GzDecoder::new(&mut reader)); |     let mut archive = Archive::new(GzDecoder::new(&mut reader)); | ||||||
| 
 | 
 | ||||||
| @ -38,6 +42,10 @@ pub async fn handle_package(package_url: String, container_uuid: String) -> Resu | |||||||
|     fs::create_dir_all(Path::new(&unarchive_dir)).await?; |     fs::create_dir_all(Path::new(&unarchive_dir)).await?; | ||||||
|     archive.unpack(&unarchive_dir)?; |     archive.unpack(&unarchive_dir)?; | ||||||
| 
 | 
 | ||||||
|  |     if delete_archive { | ||||||
|  |         let _ = fs::remove_file(file_path).await; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     Ok(unarchive_dir) |     Ok(unarchive_dir) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user