fix: tokio block on error

replace retry crate with tokio-retry for asynchronous app deployment and config updates
change hratls and sign key data to Config
refactor mr_signer format to save in config
modularized deploy and config update functionality for better code arrangements
This commit is contained in:
Noor 2025-03-20 21:33:01 +05:30
parent 4d17ba6667
commit daff2fd533
Signed by: noormohammedb
GPG Key ID: D83EFB8B3B967146
8 changed files with 70 additions and 45 deletions

22
Cargo.lock generated

@ -1058,7 +1058,6 @@ dependencies = [
"rand", "rand",
"rand_core", "rand_core",
"reqwest", "reqwest",
"retry",
"rustls", "rustls",
"serde", "serde",
"serde_json", "serde_json",
@ -1066,6 +1065,7 @@ dependencies = [
"tabled", "tabled",
"thiserror 2.0.11", "thiserror 2.0.11",
"tokio", "tokio",
"tokio-retry",
"tokio-stream", "tokio-stream",
"tonic", "tonic",
"tonic-build", "tonic-build",
@ -2756,15 +2756,6 @@ dependencies = [
"windows-registry", "windows-registry",
] ]
[[package]]
name = "retry"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9166d72162de3575f950507683fac47e30f6f2c3836b71b7fbc61aa517c9c5f4"
dependencies = [
"rand",
]
[[package]] [[package]]
name = "rfc6979" name = "rfc6979"
version = "0.4.0" version = "0.4.0"
@ -3511,6 +3502,17 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "tokio-retry"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f"
dependencies = [
"pin-project",
"rand",
"tokio",
]
[[package]] [[package]]
name = "tokio-rustls" name = "tokio-rustls"
version = "0.26.1" version = "0.26.1"

@ -31,7 +31,7 @@ rustls = "0.23.23"
tower = "0.5.2" tower = "0.5.2"
hyper-rustls = { version = "0.27.5", features = ["http2"] } hyper-rustls = { version = "0.27.5", features = ["http2"] }
openssl = { version = "0.10.71", features = ["vendored"] } openssl = { version = "0.10.71", features = ["vendored"] }
retry = "2.0.0" tokio-retry = "0.3.0"
detee-sgx = { git = "ssh://git@gitea.detee.cloud/testnet/detee-sgx.git", branch = "hratls", features=["hratls", "qvl"] } detee-sgx = { git = "ssh://git@gitea.detee.cloud/testnet/detee-sgx.git", branch = "hratls", features=["hratls", "qvl"] }
detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto.git", branch = "main" } detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto.git", branch = "main" }

@ -16,10 +16,6 @@ pub struct AccountData {
locked_funds: f64, locked_funds: f64,
wallet_address: String, wallet_address: String,
wallet_path: String, wallet_path: String,
pub hratls_pubkey: String,
pub hratls_path: String,
pub mrsigner: [u8; 32],
pub signing_key_path: String,
} }
impl super::HumanOutput for AccountData { impl super::HumanOutput for AccountData {
@ -52,6 +48,10 @@ pub struct Config {
default_dtrfs: String, default_dtrfs: String,
default_kernel: String, default_kernel: String,
brain_url: String, brain_url: String,
pub hratls_pubkey: String,
pub hratls_path: String,
pub mrsigner: String,
pub signing_key_path: String,
} }
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
@ -191,7 +191,11 @@ impl Config {
Err(e) => { Err(e) => {
debug!("Could not load config due to error: {e}"); debug!("Could not load config due to error: {e}");
eprintln!("Config file not found. Creating new config file!"); eprintln!("Config file not found. Creating new config file!");
let config = Self::default(); let mut config = Self::default();
config.hratls_pubkey = Self::get_hratls_pubkey_hex();
config.hratls_path = Self::hratls_private_key_path();
config.mrsigner = Self::get_mr_signer();
config.signing_key_path = Self::signing_key_path();
if let Err(e) = config.save_to_disk() { if let Err(e) = config.save_to_disk() {
log::error!("Could not save config to disk: {e}"); log::error!("Could not save config to disk: {e}");
panic!("Could not initialize config."); panic!("Could not initialize config.");
@ -336,11 +340,6 @@ impl Config {
Err(_) => log::error!("This error should never happen. Please report this bug."), Err(_) => log::error!("This error should never happen. Please report this bug."),
} }
account_data.hratls_pubkey = Self::get_hratls_pubkey_hex();
account_data.hratls_path = Self::hratls_private_key_path();
account_data.mrsigner = Self::get_mr_signer();
account_data.signing_key_path = Self::signing_key_path();
account_data account_data
} }
} }
@ -377,7 +376,7 @@ impl Config {
} }
impl Config { impl Config {
fn get_mr_signer() -> [u8; 32] { pub fn get_mr_signer() -> String {
let mut signing_key_mod = Self::get_signing_key().n().to_vec(); let mut signing_key_mod = Self::get_signing_key().n().to_vec();
signing_key_mod.reverse(); // make it little endian signing_key_mod.reverse(); // make it little endian
@ -389,7 +388,7 @@ impl Config {
let mut mr_signer = [0u8; 32]; let mut mr_signer = [0u8; 32];
mr_signer.copy_from_slice(&mr_signer_raw[..32]); mr_signer.copy_from_slice(&mr_signer_raw[..32]);
mr_signer mr_signer.iter().fold(String::new(), |acc, x| acc + &format!("{:02X?}", x))
} }
fn get_signing_key() -> Rsa<Private> { fn get_signing_key() -> Rsa<Private> {
@ -441,8 +440,7 @@ mod tests {
#[test] #[test]
fn test_mr_signer() { fn test_mr_signer() {
let mr_signer = let mr_signer = Config::get_mr_signer();
Config::get_mr_signer().iter().fold(String::new(), |acc, x| acc + &format!("{:X?}", x));
println!("mr_signer: {mr_signer}",); println!("mr_signer: {mr_signer}",);
} }
} }

@ -1,6 +1,10 @@
use super::grpc_brain::list_apps;
use super::utils::deploy_new_app_and_update_config;
use super::{get_app_node, AppContract, AppDeployResponse};
use crate::name_generator::random_app_name; use crate::name_generator::random_app_name;
use crate::sgx::config::{validate_yaml, DeteeCliExt}; use crate::sgx::config::{validate_yaml, DeteeCliExt};
use crate::sgx::grpc_brain::{delete_app, new_app}; use crate::sgx::grpc_brain::delete_app;
use crate::sgx::grpc_dtpm::{attest_and_send_config, get_config_from_enclave}; use crate::sgx::grpc_dtpm::{attest_and_send_config, get_config_from_enclave};
use crate::sgx::packaging::package_enclave; use crate::sgx::packaging::package_enclave;
use crate::sgx::utils::{fetch_config_and_mr_enclave, override_envs_and_args_launch_config}; use crate::sgx::utils::{fetch_config_and_mr_enclave, override_envs_and_args_launch_config};
@ -10,11 +14,6 @@ use crate::{cli_print, SimpleOutput};
use clap::ArgMatches; use clap::ArgMatches;
use detee_shared::sgx::types::brain::AppDeployConfig; use detee_shared::sgx::types::brain::AppDeployConfig;
use detee_shared::sgx::types::brain::Resource; use detee_shared::sgx::types::brain::Resource;
use retry::delay::Fixed;
use retry::retry;
use super::grpc_brain::list_apps;
use super::{get_app_node, AppContract, AppDeployResponse};
pub fn handle_app(app_matche: &ArgMatches) { pub fn handle_app(app_matche: &ArgMatches) {
match app_matche.subcommand() { match app_matche.subcommand() {
@ -104,15 +103,8 @@ fn handle_deploy(
override_envs_and_args_launch_config(&mut launch_config, envs, args); override_envs_and_args_launch_config(&mut launch_config, envs, args);
match block_on(new_app(app_deploy_config)) { match block_on(deploy_new_app_and_update_config(app_deploy_config, launch_config)) {
Ok(new_app_res) if new_app_res.error == "" => { Ok(new_app_res) if new_app_res.error == "" => Ok(new_app_res.into()),
println!("Deploying...");
std::thread::sleep(std::time::Duration::from_millis(3100));
retry(Fixed::from_millis(500).take(4), || {
block_on(attest_and_send_config(launch_config.clone(), &new_app_res.uuid))
})?;
Ok(new_app_res.into())
}
Ok(new_app_res) => Err(Box::new(std::io::Error::other(new_app_res.error))), Ok(new_app_res) => Err(Box::new(std::io::Error::other(new_app_res.error))),
Err(e) => Err(Box::new(e)), Err(e) => Err(Box::new(e)),
} }

@ -39,7 +39,7 @@ pub async fn new_app(app_deploy_config: AppDeployConfig) -> Result<NewAppRes> {
req.uuid = "".to_string(); req.uuid = "".to_string();
req.locked_nano = locked_nano; req.locked_nano = locked_nano;
req.admin_pubkey = Config::get_detee_wallet().expect("No wallet found"); req.admin_pubkey = Config::get_detee_wallet().expect("No wallet found");
req.hratls_pubkey = Config::get_hratls_pubkey_hex(); req.hratls_pubkey = Config::init_config().hratls_pubkey;
let mut daemon_serivce = BrainAppCliClient::connect(Config::get_brain_url()).await?; let mut daemon_serivce = BrainAppCliClient::connect(Config::get_brain_url()).await?;
let res = daemon_serivce.deploy_app(sign_request(req)?).await?; let res = daemon_serivce.deploy_app(sign_request(req)?).await?;

@ -38,13 +38,15 @@ pub async fn connect_dtpm_grpc_client(
package_mr_enclave: Option<[u8; 32]>, package_mr_enclave: Option<[u8; 32]>,
) -> Result<DtpmConfigManagerClient<Channel>> { ) -> Result<DtpmConfigManagerClient<Channel>> {
let private_key_pem = Config::get_hratls_private_key(); let private_key_pem = Config::get_hratls_private_key();
let mr_signer = vec![Config::get_account_data().mrsigner]; let mut mr_signer = [0u8; 32];
hex::decode_to_slice(Config::init_config().mrsigner, &mut mr_signer)?;
let mr_signers = vec![mr_signer];
let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
let hratls_config = Arc::new(RwLock::new( let hratls_config = Arc::new(RwLock::new(
HRaTlsConfig::new() HRaTlsConfig::new()
.allow_instance_measurement(InstanceMeasurement::new().with_mrsigners(mr_signer)) .allow_instance_measurement(InstanceMeasurement::new().with_mrsigners(mr_signers))
.with_hratls_private_key_pem(private_key_pem), .with_hratls_private_key_pem(private_key_pem),
)); ));

@ -11,8 +11,8 @@ pub fn package_enclave(
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(" "); .join(" ");
let signing_key_path = Config::get_account_data().signing_key_path; let signing_key_path = Config::init_config().signing_key_path;
let hratls_key_path = Config::get_account_data().hratls_path; let hratls_key_path = Config::init_config().hratls_path;
let docker_package_str = if package_type == "public" { let docker_package_str = if package_type == "public" {
format!( format!(

@ -1,8 +1,14 @@
use super::grpc_brain::new_app;
use crate::constants::HRATLS_APP_PORT; use crate::constants::HRATLS_APP_PORT;
use crate::sgx::grpc_brain::list_apps; use crate::sgx::grpc_brain::list_apps;
use crate::sgx::grpc_dtpm::attest_and_send_config;
use detee_shared::app_proto::NewAppRes;
use detee_shared::sgx::types::brain::AppDeployConfig;
use detee_shared::sgx::types::dtpm::DtpmConfig; use detee_shared::sgx::types::dtpm::DtpmConfig;
use detee_shared::sgx::types::dtpm::EnvironmentEntry; use detee_shared::sgx::types::dtpm::EnvironmentEntry;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio_retry::strategy::FixedInterval;
use tokio_retry::Retry;
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum Error { pub enum Error {
@ -12,6 +18,12 @@ pub enum Error {
Serde(#[from] serde_yaml::Error), Serde(#[from] serde_yaml::Error),
#[error("{0}")] #[error("{0}")]
PublicPackage(std::string::String), PublicPackage(std::string::String),
#[error("{0}")]
Brain(#[from] crate::sgx::grpc_brain::Error),
#[error("{0}")]
Dtpm(#[from] crate::sgx::grpc_dtpm::Error),
#[error("{0}")]
Deployment(String),
} }
pub async fn hratls_url_and_mr_enclave_from_app_id(app_id: &str) -> (String, Option<[u8; 32]>) { pub async fn hratls_url_and_mr_enclave_from_app_id(app_id: &str) -> (String, Option<[u8; 32]>) {
@ -127,3 +139,22 @@ pub fn override_envs_and_args_launch_config(
launch_config.child_processes.first_mut().unwrap().arguments.push(arg); launch_config.child_processes.first_mut().unwrap().arguments.push(arg);
} }
} }
pub async fn deploy_new_app_and_update_config(
app_deploy_config: AppDeployConfig,
launch_config: DtpmConfig,
) -> Result<NewAppRes, Error> {
let new_app_res = new_app(app_deploy_config).await?;
if new_app_res.error == "" {
println!("Deploying...");
tokio::time::sleep(tokio::time::Duration::from_millis(3100)).await;
Retry::spawn(FixedInterval::from_millis(500).take(5), || {
log::debug!("retrying attestation and launch config update");
attest_and_send_config(launch_config.clone(), &new_app_res.uuid)
})
.await?;
Ok(new_app_res.into())
} else {
Err(Error::Deployment(new_app_res.error))
}
}