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