Improved app deployment process
deploying and uploading launch config on app deploy subcommand fetch launch config from package index disable package-type and package subcommand modified samples
This commit is contained in:
parent
aeca70e062
commit
4f1ae72727
@ -1,7 +1,7 @@
|
|||||||
node_pubkey: 3mWjE6FnKQ8f9WRjGHdj1Jtyewsri87GXQpqLWpwtjhr
|
node_pubkey: 3mWjE6FnKQ8f9WRjGHdj1Jtyewsri87GXQpqLWpwtjhr
|
||||||
package_url: https://registry.detee.ltd/sgx/packages/actix-env-info_public-package_2025-03-06_00-53-30.tar.gz
|
package_url: https://registry.detee.ltd/sgx/packages/actix-app-info_package_2025-03-19_13-49-56.tar.gz
|
||||||
private_package: false
|
private_package: false
|
||||||
public_package_mr_enclave: [ 152, 174, 10, 201, 41, 45, 15, 100, 123, 209, 103, 181, 205, 70, 145, 159, 134, 130, 140, 238, 196, 87, 145, 63, 222, 1, 230, 140, 118, 26, 238, 86]
|
# public_package_mr_enclave: [ 152, 174, 10, 201, 41, 45, 15, 100, 123, 209, 103, 181, 205, 70, 145, 159, 134, 130, 140, 238, 196, 87, 145, 63, 222, 1, 230, 140, 118, 26, 238, 86]
|
||||||
hours: 1
|
hours: 1
|
||||||
node_unit_price: 200000
|
node_unit_price: 200000
|
||||||
resource:
|
resource:
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
filesystems:
|
filesystems:
|
||||||
- path: /bin/actix-hello-world
|
# - path: /bin/actix-hello-world
|
||||||
content: !path "./samples/new_app/binaries/actix-test-app.bin"
|
# content: !path "./samples/new_app/binaries/actix-test-app.bin"
|
||||||
environments:
|
environments:
|
||||||
- name: APP_NAME
|
- name: APP_NAME
|
||||||
value: actix-test-dtpm-foo-bar-koo
|
value: actix-test
|
||||||
- name: PORT
|
- name: PORT
|
||||||
value: 8080
|
value: 8080
|
||||||
child_processes:
|
child_processes:
|
||||||
|
@ -45,6 +45,7 @@ fn main() {
|
|||||||
)
|
)
|
||||||
.subcommand(Command::new("app")
|
.subcommand(Command::new("app")
|
||||||
.about("a lightweight service that run on Intel SGX")
|
.about("a lightweight service that run on Intel SGX")
|
||||||
|
/*
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("package")
|
Command::new("package")
|
||||||
.about("package new app from x86_64-linux-musl binary")
|
.about("package new app from x86_64-linux-musl binary")
|
||||||
@ -69,6 +70,7 @@ fn main() {
|
|||||||
.value_delimiter(' ')
|
.value_delimiter(' ')
|
||||||
|
|
||||||
))
|
))
|
||||||
|
*/
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("deploy")
|
Command::new("deploy")
|
||||||
.about("create new app from a YAML configuration file")
|
.about("create new app from a YAML configuration file")
|
||||||
@ -119,6 +121,7 @@ fn main() {
|
|||||||
)
|
)
|
||||||
.required(true)
|
.required(true)
|
||||||
)
|
)
|
||||||
|
/*
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("package-type")
|
Arg::new("package-type")
|
||||||
.long("package-type")
|
.long("package-type")
|
||||||
@ -130,6 +133,7 @@ fn main() {
|
|||||||
.default_value("public")
|
.default_value("public")
|
||||||
.value_parser(["public", "private"])
|
.value_parser(["public", "private"])
|
||||||
)
|
)
|
||||||
|
*/
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("name")
|
Arg::new("name")
|
||||||
.long("name")
|
.long("name")
|
||||||
@ -190,6 +194,7 @@ fn main() {
|
|||||||
Arg::new("config")
|
Arg::new("config")
|
||||||
.help("App config yaml file path to validate")
|
.help("App config yaml file path to validate")
|
||||||
.long_help("Validate YAML configuration file for the app which you want to run in the enclave")
|
.long_help("Validate YAML configuration file for the app which you want to run in the enclave")
|
||||||
|
.long("from-yaml")
|
||||||
.required(true)
|
.required(true)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -199,7 +204,9 @@ fn main() {
|
|||||||
.long_about("Update the YAML configuration file for the app which you want to run in the enclave")
|
.long_about("Update the YAML configuration file for the app which you want to run in the enclave")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("config")
|
Arg::new("config")
|
||||||
.required(true),
|
.help("Path to yaml file")
|
||||||
|
.long("from-yaml")
|
||||||
|
.required(true)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("uuid")
|
Arg::new("uuid")
|
||||||
|
@ -4,7 +4,7 @@ use crate::sgx::grpc_brain::{delete_app, new_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::AppDeleteResponse;
|
use crate::sgx::AppDeleteResponse;
|
||||||
use crate::utils::block_on;
|
use crate::utils::{block_on, fetch_config_and_mr_enclave};
|
||||||
use crate::{cli_print, SimpleOutput};
|
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;
|
||||||
@ -55,14 +55,15 @@ fn handle_deploy(
|
|||||||
let port =
|
let port =
|
||||||
deploy_match.get_many::<u32>("port").unwrap_or_default().cloned().collect::<Vec<_>>();
|
deploy_match.get_many::<u32>("port").unwrap_or_default().cloned().collect::<Vec<_>>();
|
||||||
let package_url = deploy_match.get_one::<String>("package-url").unwrap().clone();
|
let package_url = deploy_match.get_one::<String>("package-url").unwrap().clone();
|
||||||
let package_type = deploy_match.get_one::<String>("package-type").unwrap().clone();
|
// let package_type = deploy_match.get_one::<String>("package-type").unwrap().clone();
|
||||||
let hours = deploy_match.get_one::<u64>("hours").unwrap().clone();
|
let hours = deploy_match.get_one::<u64>("hours").unwrap().clone();
|
||||||
let node_unit_price = deploy_match.get_one::<u64>("price").unwrap().clone();
|
let node_unit_price = deploy_match.get_one::<u64>("price").unwrap().clone();
|
||||||
let location = deploy_match.get_one::<String>("location").unwrap().as_str();
|
let location = deploy_match.get_one::<String>("location").unwrap().as_str();
|
||||||
let app_name =
|
let app_name =
|
||||||
deploy_match.get_one::<String>("name").cloned().unwrap_or_else(|| random_app_name());
|
deploy_match.get_one::<String>("name").cloned().unwrap_or_else(|| random_app_name());
|
||||||
|
|
||||||
let private_package = package_type == "private";
|
// let private_package = package_type == "private";
|
||||||
|
let private_package = false;
|
||||||
let resource = Resource { vcpu, memory_mb, disk_mb, port };
|
let resource = Resource { vcpu, memory_mb, disk_mb, port };
|
||||||
let node_pubkey = match block_on(get_app_node(resource.clone(), location.into())) {
|
let node_pubkey = match block_on(get_app_node(resource.clone(), location.into())) {
|
||||||
Ok(node) => node.node_pubkey,
|
Ok(node) => node.node_pubkey,
|
||||||
@ -89,8 +90,17 @@ fn handle_deploy(
|
|||||||
app_deploy_config.app_name = random_app_name();
|
app_deploy_config.app_name = random_app_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (mr_enclave, launch_config) =
|
||||||
|
block_on(fetch_config_and_mr_enclave(&app_deploy_config.package_url))?;
|
||||||
|
app_deploy_config.public_package_mr_enclave = Some(mr_enclave.to_vec());
|
||||||
|
|
||||||
match block_on(new_app(app_deploy_config)) {
|
match block_on(new_app(app_deploy_config)) {
|
||||||
Ok(new_app_res) if new_app_res.error == "" => Ok(new_app_res.into()),
|
Ok(new_app_res) if new_app_res.error == "" => {
|
||||||
|
println!("Deploying...");
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(8));
|
||||||
|
block_on(attest_and_send_config(launch_config, &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)),
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ use detee_shared::sgx::types::brain::AppDeployConfig;
|
|||||||
use tokio_stream::StreamExt;
|
use tokio_stream::StreamExt;
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::utils::{self, calculate_nanolp_for_app, mr_enclave_from_public_registry, sign_request};
|
use crate::utils::{self, calculate_nanolp_for_app, sign_request};
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
@ -40,11 +40,6 @@ pub async fn new_app(app_deploy_config: AppDeployConfig) -> Result<NewAppRes> {
|
|||||||
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::get_hratls_pubkey_hex();
|
||||||
|
|
||||||
if !app_deploy_config.private_package && app_deploy_config.public_package_mr_enclave.is_none() {
|
|
||||||
let mr_enclave: [u8; 32] = mr_enclave_from_public_registry(&req.package_url).await?;
|
|
||||||
req.public_package_mr_enclave = Some(mr_enclave.to_vec());
|
|
||||||
}
|
|
||||||
|
|
||||||
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?;
|
||||||
Ok(res.into_inner())
|
Ok(res.into_inner())
|
||||||
|
@ -18,7 +18,7 @@ use crate::{config::Config, utils::hratls_url_and_mr_enclave_from_app_id};
|
|||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("Failed to connect to the brain: {0}")]
|
#[error("Failed to connect to the brain: {0}")]
|
||||||
BrainConnection(#[from] tonic::transport::Error),
|
BrainConnection(#[from] tonic::transport::Error),
|
||||||
#[error("Received error from brain: {}", _0.message())]
|
#[error("Received error from dtpm: {}", _0.message())]
|
||||||
ResponseStatus(#[from] tonic::Status),
|
ResponseStatus(#[from] tonic::Status),
|
||||||
#[error("Hex: {0}")]
|
#[error("Hex: {0}")]
|
||||||
HexDecode(#[from] hex::FromHexError),
|
HexDecode(#[from] hex::FromHexError),
|
||||||
|
@ -18,7 +18,7 @@ pub fn package_enclave(
|
|||||||
format!(
|
format!(
|
||||||
r#"docker run --rm -it -v ./:/app/ \
|
r#"docker run --rm -it -v ./:/app/ \
|
||||||
-v {signing_key_path}:/keys/app_signing_key.pem:ro \
|
-v {signing_key_path}:/keys/app_signing_key.pem:ro \
|
||||||
noormohammedb/enclave_packager_01:pub_v1 {package_items}"#
|
noormohammedb/enclave_packager_01:pub_v2 {package_items}"#
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
|
33
src/utils.rs
33
src/utils.rs
@ -1,6 +1,7 @@
|
|||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
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 detee_shared::sgx::types::dtpm::DtpmConfig;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tonic::metadata::errors::InvalidMetadataValue;
|
use tonic::metadata::errors::InvalidMetadataValue;
|
||||||
use tonic::metadata::AsciiMetadataValue;
|
use tonic::metadata::AsciiMetadataValue;
|
||||||
@ -73,23 +74,33 @@ struct PublicIndex {
|
|||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
struct PackageElement {
|
struct PackageElement {
|
||||||
package_url: String,
|
package_url: String,
|
||||||
|
launch_config_url: String,
|
||||||
mr_enclave: [u8; 32],
|
mr_enclave: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn mr_enclave_from_public_registry(package_url: &str) -> Result<[u8; 32], Error> {
|
pub async fn fetch_config_and_mr_enclave(
|
||||||
let public_index =
|
package_url: &str,
|
||||||
reqwest::get("https://registry.detee.ltd/sgx/public_index.yaml").await?.text().await?;
|
) -> Result<([u8; 32], DtpmConfig), Error> {
|
||||||
|
let public_packages_index =
|
||||||
|
reqwest::get("https://registry.detee.ltd/sgx/public_packages_index.yaml")
|
||||||
|
.await?
|
||||||
|
.text()
|
||||||
|
.await?;
|
||||||
|
|
||||||
let index = serde_yaml::from_str::<PublicIndex>(&public_index)?;
|
let index = serde_yaml::from_str::<PublicIndex>(&public_packages_index)?;
|
||||||
|
|
||||||
let pub_package_mr_enclave = index
|
let index_package_entry =
|
||||||
.packages
|
index.packages.iter().find(|package| package.package_url == package_url).ok_or(
|
||||||
.iter()
|
Error::PublicPackage("mr_enclave not found for this public package".to_string()),
|
||||||
.find(|package| package.package_url == package_url)
|
)?;
|
||||||
.ok_or(Error::PublicPackage("mr_enclave not found for this public package".to_string()))?
|
|
||||||
.mr_enclave;
|
|
||||||
|
|
||||||
Ok(pub_package_mr_enclave)
|
let PackageElement { launch_config_url, mr_enclave, .. } = index_package_entry;
|
||||||
|
|
||||||
|
let launch_config_str = reqwest::get(launch_config_url).await?.text().await?;
|
||||||
|
|
||||||
|
let launch_config = serde_yaml::from_str::<DtpmConfig>(&launch_config_str)?;
|
||||||
|
|
||||||
|
Ok((*mr_enclave, launch_config))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn calculate_nanolp_for_app(
|
pub fn calculate_nanolp_for_app(
|
||||||
|
Loading…
Reference in New Issue
Block a user