Compare commits
	
		
			3 Commits
		
	
	
		
			d8b5a50a04
			...
			f3e1792dc2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f3e1792dc2 | |||
| d753358795 | |||
| 6b6c7b2356 | 
							
								
								
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -1184,7 +1184,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/testnet/proto.git?branch=offers#4753a17fa29393b3f99b6dfcdcec48d935e6ebd9"
 | 
					source = "git+ssh://git@gitea.detee.cloud/testnet/proto.git?branch=remove_uuid#8b38d9a2b3406173fc7de2241c0e316c3e19e2b4"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "bincode",
 | 
					 "bincode",
 | 
				
			||||||
 "prost",
 | 
					 "prost",
 | 
				
			||||||
 | 
				
			|||||||
@ -37,7 +37,7 @@ detee-sgx = { git = "ssh://git@gitea.detee.cloud/testnet/detee-sgx.git", branch
 | 
				
			|||||||
shadow-rs = { version = "1.1.1", features = ["metadata"] }
 | 
					shadow-rs = { version = "1.1.1", features = ["metadata"] }
 | 
				
			||||||
serde_default_utils = "0.3.1"
 | 
					serde_default_utils = "0.3.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto.git", branch = "offers" }
 | 
					detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto.git", branch = "remove_uuid" }
 | 
				
			||||||
# detee-shared = { path = "../detee-shared" }
 | 
					# detee-shared = { path = "../detee-shared" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[build-dependencies]
 | 
					[build-dependencies]
 | 
				
			||||||
 | 
				
			|||||||
@ -148,7 +148,7 @@ fn clap_cmd() -> Command {
 | 
				
			|||||||
                    )
 | 
					                    )
 | 
				
			||||||
                    .arg(
 | 
					                    .arg(
 | 
				
			||||||
                        Arg::new("port")
 | 
					                        Arg::new("port")
 | 
				
			||||||
                        .long("port")
 | 
					                        .long("expose-port")
 | 
				
			||||||
                        .value_parser(clap::value_parser!(u32).range(0..65535))
 | 
					                        .value_parser(clap::value_parser!(u32).range(0..65535))
 | 
				
			||||||
                        .action(clap::ArgAction::Append)
 | 
					                        .action(clap::ArgAction::Append)
 | 
				
			||||||
                        .help("Application exposing port")
 | 
					                        .help("Application exposing port")
 | 
				
			||||||
@ -210,8 +210,8 @@ fn clap_cmd() -> Command {
 | 
				
			|||||||
                )
 | 
					                )
 | 
				
			||||||
                .subcommand(Command::new("inspect").about("list all available information about a App")
 | 
					                .subcommand(Command::new("inspect").about("list all available information about a App")
 | 
				
			||||||
                    .arg(
 | 
					                    .arg(
 | 
				
			||||||
                        Arg::new("uuid")
 | 
					                        Arg::new("id")
 | 
				
			||||||
                        .help("supply the uuid of the App contract")
 | 
					                        .help("supply the long ID of the App contract")
 | 
				
			||||||
                        .required(true)
 | 
					                        .required(true)
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                    .arg(
 | 
					                    .arg(
 | 
				
			||||||
@ -225,8 +225,8 @@ fn clap_cmd() -> Command {
 | 
				
			|||||||
                    Command::new("delete")
 | 
					                    Command::new("delete")
 | 
				
			||||||
                    .about("delete deployed app")
 | 
					                    .about("delete deployed app")
 | 
				
			||||||
                    .arg(
 | 
					                    .arg(
 | 
				
			||||||
                        Arg::new("uuid")
 | 
					                        Arg::new("id")
 | 
				
			||||||
                        .help("supply the uuid of the App contract")
 | 
					                        .help("supply the long ID of the App contract")
 | 
				
			||||||
                        .required(true)
 | 
					                        .required(true)
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
@ -256,8 +256,8 @@ fn clap_cmd() -> Command {
 | 
				
			|||||||
                                .required(true)
 | 
					                                .required(true)
 | 
				
			||||||
                            )
 | 
					                            )
 | 
				
			||||||
                            .arg(
 | 
					                            .arg(
 | 
				
			||||||
                                Arg::new("uuid")
 | 
					                                Arg::new("id")
 | 
				
			||||||
                                .help("supply the uuid of the App contract")
 | 
					                                .help("supply the long ID of the App contract")
 | 
				
			||||||
                                .required(true)
 | 
					                                .required(true)
 | 
				
			||||||
                            )
 | 
					                            )
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
@ -271,8 +271,8 @@ fn clap_cmd() -> Command {
 | 
				
			|||||||
                                .required(true),
 | 
					                                .required(true),
 | 
				
			||||||
                            )
 | 
					                            )
 | 
				
			||||||
                            .arg(
 | 
					                            .arg(
 | 
				
			||||||
                                Arg::new("uuid")
 | 
					                                Arg::new("id")
 | 
				
			||||||
                                .help("supply the uuid of the App contract")
 | 
					                                .help("supply the ID of the App contract")
 | 
				
			||||||
                                .required(true)
 | 
					                                .required(true)
 | 
				
			||||||
                            )
 | 
					                            )
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
@ -310,7 +310,7 @@ fn clap_cmd() -> Command {
 | 
				
			|||||||
                .arg(
 | 
					                .arg(
 | 
				
			||||||
                    Arg::new("contract")
 | 
					                    Arg::new("contract")
 | 
				
			||||||
                    .long("contract")
 | 
					                    .long("contract")
 | 
				
			||||||
                    .help("UUID of the active contract with this node")
 | 
					                    .help("ID of the active contract with this node")
 | 
				
			||||||
                    .required(true)
 | 
					                    .required(true)
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                .arg(
 | 
					                .arg(
 | 
				
			||||||
@ -394,12 +394,22 @@ fn clap_cmd() -> Command {
 | 
				
			|||||||
                    .long("public-ip")
 | 
					                    .long("public-ip")
 | 
				
			||||||
                    .help("get a public IPv4 address for this VM")
 | 
					                    .help("get a public IPv4 address for this VM")
 | 
				
			||||||
                    .action(clap::ArgAction::SetTrue)
 | 
					                    .action(clap::ArgAction::SetTrue)
 | 
				
			||||||
 | 
					                    .conflicts_with("port")
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                .arg(
 | 
				
			||||||
 | 
					                    Arg::new("port")
 | 
				
			||||||
 | 
					                    .long("expose-port")
 | 
				
			||||||
 | 
					                    .value_parser(clap::value_parser!(u32).range(0..65535))
 | 
				
			||||||
 | 
					                    .action(clap::ArgAction::Append)
 | 
				
			||||||
 | 
					                    .help("vm exposing port")
 | 
				
			||||||
 | 
					                    .long_help("Port to expose on the vm which mapped into the host's public IP's port")
 | 
				
			||||||
 | 
					                    .conflicts_with("public-ip")
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            .subcommand(Command::new("inspect").about("list all available information about a VM")
 | 
					            .subcommand(Command::new("inspect").about("list all available information about a VM")
 | 
				
			||||||
                .arg(
 | 
					                .arg(
 | 
				
			||||||
                    Arg::new("uuid")
 | 
					                    Arg::new("id")
 | 
				
			||||||
                    .help("supply the uuid of the VM contract")
 | 
					                    .help("supply the long ID of the VM contract")
 | 
				
			||||||
                    .required(true)
 | 
					                    .required(true)
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                .arg(
 | 
					                .arg(
 | 
				
			||||||
@ -411,8 +421,8 @@ fn clap_cmd() -> Command {
 | 
				
			|||||||
            )
 | 
					            )
 | 
				
			||||||
            .subcommand(Command::new("ssh").about("connect to the VM using SSH")
 | 
					            .subcommand(Command::new("ssh").about("connect to the VM using SSH")
 | 
				
			||||||
                .arg(
 | 
					                .arg(
 | 
				
			||||||
                    Arg::new("uuid")
 | 
					                    Arg::new("id")
 | 
				
			||||||
                    .help("supply the uuid of the VM contract")
 | 
					                    .help("supply the ID of the VM contract")
 | 
				
			||||||
                    .required(true)
 | 
					                    .required(true)
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                .arg(
 | 
					                .arg(
 | 
				
			||||||
@ -432,8 +442,8 @@ fn clap_cmd() -> Command {
 | 
				
			|||||||
            )
 | 
					            )
 | 
				
			||||||
            .subcommand(Command::new("delete").about("delete a VM from the DeTEE network")
 | 
					            .subcommand(Command::new("delete").about("delete a VM from the DeTEE network")
 | 
				
			||||||
                .arg(
 | 
					                .arg(
 | 
				
			||||||
                    Arg::new("uuid")
 | 
					                    Arg::new("id")
 | 
				
			||||||
                    .help("uuid of the VM that you wish to delete")
 | 
					                    .help("the (long) ID of the VM that you wish to delete")
 | 
				
			||||||
                    .required(true)
 | 
					                    .required(true)
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@ -444,8 +454,8 @@ fn clap_cmd() -> Command {
 | 
				
			|||||||
                    "\nChanging the lifetime of a VM will not restart." +
 | 
					                    "\nChanging the lifetime of a VM will not restart." +
 | 
				
			||||||
                    "\nIf changing the lifetime to a higher value, credits will locked accordingly.")
 | 
					                    "\nIf changing the lifetime to a higher value, credits will locked accordingly.")
 | 
				
			||||||
                .arg(
 | 
					                .arg(
 | 
				
			||||||
                    Arg::new("uuid")
 | 
					                    Arg::new("id")
 | 
				
			||||||
                    .help("supply the uuid of the VM you wish to upgrade")
 | 
					                    .help("supply the ID of the VM you wish to upgrade")
 | 
				
			||||||
                    .required(true)
 | 
					                    .required(true)
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                .arg(
 | 
					                .arg(
 | 
				
			||||||
@ -542,7 +552,7 @@ fn clap_cmd() -> Command {
 | 
				
			|||||||
                .arg(
 | 
					                .arg(
 | 
				
			||||||
                    Arg::new("contract")
 | 
					                    Arg::new("contract")
 | 
				
			||||||
                    .long("contract")
 | 
					                    .long("contract")
 | 
				
			||||||
                    .help("UUID of the active contract with this node")
 | 
					                    .help("ID of the active contract with this node")
 | 
				
			||||||
                    .required(true)
 | 
					                    .required(true)
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                .arg(
 | 
					                .arg(
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
// SPDX-License-Identifier: Apache-2.0
 | 
					// SPDX-License-Identifier: Apache-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::constants::{BRAIN_STAGING, BRAIN_TESTING};
 | 
					use crate::constants::{BRAIN_STAGING, BRAIN_TESTING, CONFIG_OVERRIDE_PATH_ENV};
 | 
				
			||||||
use crate::general;
 | 
					use crate::general;
 | 
				
			||||||
use crate::utils::block_on;
 | 
					use crate::utils::block_on;
 | 
				
			||||||
use ed25519_dalek::SigningKey;
 | 
					use ed25519_dalek::SigningKey;
 | 
				
			||||||
@ -178,16 +178,18 @@ impl Config {
 | 
				
			|||||||
        Ok(dir)
 | 
					        Ok(dir)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn vm_uuid_list_path() -> Result<String, Error> {
 | 
					    pub fn vm_id_list_path() -> Result<String, Error> {
 | 
				
			||||||
        let dir = Self::home_dir() + ("/.detee/cli/vms");
 | 
					        let dir = Self::home_dir() + ("/.detee/cli/vms");
 | 
				
			||||||
        if !Path::new(&dir).exists() {
 | 
					        if !Path::new(&dir).exists() {
 | 
				
			||||||
            std::fs::create_dir_all(dir.clone())?;
 | 
					            std::fs::create_dir_all(dir.clone())?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Ok(dir + "/uuid_list")
 | 
					        Ok(dir + "/vm_id_list")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn cli_dir_path() -> Result<String, Error> {
 | 
					    pub fn cli_dir_path() -> Result<String, Error> {
 | 
				
			||||||
        let dir = Self::home_dir() + ("/.detee/cli");
 | 
					        let dir = std::env::var(CONFIG_OVERRIDE_PATH_ENV)
 | 
				
			||||||
 | 
					            .unwrap_or_else(|_| Self::home_dir() + ("/.detee/cli"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if !Path::new(&dir).exists() {
 | 
					        if !Path::new(&dir).exists() {
 | 
				
			||||||
            warn!("Could not config dir. Creating {dir}");
 | 
					            warn!("Could not config dir. Creating {dir}");
 | 
				
			||||||
            std::fs::create_dir_all(dir.clone())?;
 | 
					            std::fs::create_dir_all(dir.clone())?;
 | 
				
			||||||
@ -525,11 +527,11 @@ impl Config {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Config {
 | 
					impl Config {
 | 
				
			||||||
    pub fn app_uuid_list_path() -> Result<String, Error> {
 | 
					    pub fn app_id_list_path() -> Result<String, Error> {
 | 
				
			||||||
        let dir = Self::home_dir() + ("/.detee/cli/apps");
 | 
					        let dir = Self::home_dir() + ("/.detee/cli/apps");
 | 
				
			||||||
        if !Path::new(&dir).exists() {
 | 
					        if !Path::new(&dir).exists() {
 | 
				
			||||||
            std::fs::create_dir_all(dir.clone())?;
 | 
					            std::fs::create_dir_all(dir.clone())?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Ok(dir + "/uuid_list")
 | 
					        Ok(dir + "/app_id_list")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,7 @@ use std::sync::LazyLock;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub const HRATLS_APP_PORT: u32 = 34500;
 | 
					pub const HRATLS_APP_PORT: u32 = 34500;
 | 
				
			||||||
pub const MAX_REDIRECTS: u16 = 3;
 | 
					pub const MAX_REDIRECTS: u16 = 3;
 | 
				
			||||||
 | 
					pub const CONFIG_OVERRIDE_PATH_ENV: &str = "DETEE_API_USER_PATH";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub const STAGING_BRAIN_URLS: [&str; 3] = [
 | 
					pub const STAGING_BRAIN_URLS: [&str; 3] = [
 | 
				
			||||||
    "https://156.146.63.216:31337", // staging brain 1
 | 
					    "https://156.146.63.216:31337", // staging brain 1
 | 
				
			||||||
 | 
				
			|||||||
@ -25,9 +25,9 @@ pub fn handle_operators(matches: &ArgMatches) {
 | 
				
			|||||||
            cli_print(operators::inspect_operator(wallet).map_err(Into::into));
 | 
					            cli_print(operators::inspect_operator(wallet).map_err(Into::into));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Some(("kick", subcom_args)) => {
 | 
					        Some(("kick", subcom_args)) => {
 | 
				
			||||||
            let uuid: String = subcom_args.get_one::<String>("contract").unwrap().clone();
 | 
					            let app_id: String = subcom_args.get_one::<String>("contract").unwrap().clone();
 | 
				
			||||||
            let reason: String = subcom_args.get_one::<String>("reason").unwrap().clone();
 | 
					            let reason: String = subcom_args.get_one::<String>("reason").unwrap().clone();
 | 
				
			||||||
            cli_print(operators::kick(uuid, reason).map_err(Into::into));
 | 
					            cli_print(operators::kick(app_id, reason).map_err(Into::into));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Some(("ban-user", subcom_args)) => {
 | 
					        Some(("ban-user", subcom_args)) => {
 | 
				
			||||||
            let user_wallet: String = subcom_args.get_one::<String>("wallet").unwrap().clone();
 | 
					            let user_wallet: String = subcom_args.get_one::<String>("wallet").unwrap().clone();
 | 
				
			||||||
@ -64,14 +64,14 @@ pub fn handle_account(matches: &ArgMatches) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const FISH_COMPLETION: &str = r#"
 | 
					const FISH_COMPLETION: &str = r#"
 | 
				
			||||||
complete -c detee-cli -n '__fish_detee_cli_using_subcommand vm; and __fish_seen_subcommand_from delete' -a '(cat ~/.detee/cli/vms/uuid_list)' -f
 | 
					complete -c detee-cli -n '__fish_detee_cli_using_subcommand vm; and __fish_seen_subcommand_from delete' -a '(cat ~/.detee/cli/vms/vm_id_list)' -f
 | 
				
			||||||
complete -c detee-cli -n '__fish_detee_cli_using_subcommand vm; and __fish_seen_subcommand_from update' -a '(cat ~/.detee/cli/vms/uuid_list)' -f
 | 
					complete -c detee-cli -n '__fish_detee_cli_using_subcommand vm; and __fish_seen_subcommand_from update' -a '(cat ~/.detee/cli/vms/vm_id_list)' -f
 | 
				
			||||||
complete -c detee-cli -n '__fish_detee_cli_using_subcommand vm; and __fish_seen_subcommand_from inspect' -a '(cat ~/.detee/cli/vms/uuid_list)' -f
 | 
					complete -c detee-cli -n '__fish_detee_cli_using_subcommand vm; and __fish_seen_subcommand_from inspect' -a '(cat ~/.detee/cli/vms/vm_id_list)' -f
 | 
				
			||||||
complete -c detee-cli -n '__fish_detee_cli_using_subcommand vm; and __fish_seen_subcommand_from ssh' -a '(cat ~/.detee/cli/vms/uuid_list)' -f
 | 
					complete -c detee-cli -n '__fish_detee_cli_using_subcommand vm; and __fish_seen_subcommand_from ssh' -a '(cat ~/.detee/cli/vms/vm_id_list)' -f
 | 
				
			||||||
complete -c detee-cli -n '__fish_detee_cli_using_subcommand app; and __fish_seen_subcommand_from update' -a '(cat ~/.detee/cli/apps/uuid_list)' -f
 | 
					complete -c detee-cli -n '__fish_detee_cli_using_subcommand app; and __fish_seen_subcommand_from update' -a '(cat ~/.detee/cli/apps/app_id_list)' -f
 | 
				
			||||||
complete -c detee-cli -n '__fish_detee_cli_using_subcommand app; and __fish_seen_subcommand_from get' -a '(cat ~/.detee/cli/apps/uuid_list)' -f
 | 
					complete -c detee-cli -n '__fish_detee_cli_using_subcommand app; and __fish_seen_subcommand_from get' -a '(cat ~/.detee/cli/apps/app_id_list)' -f
 | 
				
			||||||
complete -c detee-cli -n '__fish_detee_cli_using_subcommand app; and __fish_seen_subcommand_from delete' -a '(cat ~/.detee/cli/apps/uuid_list)' -f
 | 
					complete -c detee-cli -n '__fish_detee_cli_using_subcommand app; and __fish_seen_subcommand_from delete' -a '(cat ~/.detee/cli/apps/app_id_list)' -f
 | 
				
			||||||
complete -c detee-cli -n '__fish_detee_cli_using_subcommand app; and __fish_seen_subcommand_from inspect' -a '(cat ~/.detee/cli/apps/uuid_list)' -f
 | 
					complete -c detee-cli -n '__fish_detee_cli_using_subcommand app; and __fish_seen_subcommand_from inspect' -a '(cat ~/.detee/cli/apps/app_id_list)' -f
 | 
				
			||||||
"#;
 | 
					"#;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn handle_completion(matches: &ArgMatches, cmd: Command) {
 | 
					pub fn handle_completion(matches: &ArgMatches, cmd: Command) {
 | 
				
			||||||
 | 
				
			|||||||
@ -85,13 +85,13 @@ pub async fn list_operators() -> Result<Vec<ListOperatorsResp>, Error> {
 | 
				
			|||||||
    Ok(operators)
 | 
					    Ok(operators)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn kick_contract(contract_uuid: String, reason: String) -> Result<u64, Error> {
 | 
					pub async fn kick_contract(contract_id: String, reason: String) -> Result<u64, Error> {
 | 
				
			||||||
    debug!("gRPC module: connecting to brain and kicking contract {contract_uuid} for reason: {reason}");
 | 
					    debug!("gRPC module: connecting to brain and kicking contract {contract_id} for reason: {reason}");
 | 
				
			||||||
    Ok(client()
 | 
					    Ok(client()
 | 
				
			||||||
        .await?
 | 
					        .await?
 | 
				
			||||||
        .kick_contract(sign_request(KickReq {
 | 
					        .kick_contract(sign_request(KickReq {
 | 
				
			||||||
            operator_wallet: Config::get_detee_wallet()?,
 | 
					            operator_wallet: Config::get_detee_wallet()?,
 | 
				
			||||||
            contract_uuid,
 | 
					            contract_id,
 | 
				
			||||||
            reason,
 | 
					            reason,
 | 
				
			||||||
        })?)
 | 
					        })?)
 | 
				
			||||||
        .await?
 | 
					        .await?
 | 
				
			||||||
 | 
				
			|||||||
@ -74,8 +74,8 @@ pub fn print_operators() -> Result<Vec<grpc::proto::ListOperatorsResp>, grpc::Er
 | 
				
			|||||||
    block_on(grpc::list_operators())
 | 
					    block_on(grpc::list_operators())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn kick(contract_uuid: String, reason: String) -> Result<crate::SimpleOutput, grpc::Error> {
 | 
					pub fn kick(contract_id: String, reason: String) -> Result<crate::SimpleOutput, grpc::Error> {
 | 
				
			||||||
    let nano_lp = block_on(grpc::kick_contract(contract_uuid, reason))?;
 | 
					    let nano_lp = block_on(grpc::kick_contract(contract_id, reason))?;
 | 
				
			||||||
    Ok(crate::SimpleOutput::from(
 | 
					    Ok(crate::SimpleOutput::from(
 | 
				
			||||||
        format!("Successfully terminated contract. Refunded {} nanocredits.", nano_lp).as_str(),
 | 
					        format!("Successfully terminated contract. Refunded {} nanocredits.", nano_lp).as_str(),
 | 
				
			||||||
    ))
 | 
					    ))
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@ use crate::sgx::grpc_brain::{delete_app, list_contracts};
 | 
				
			|||||||
use crate::sgx::grpc_dtpm::{get_config, update_config};
 | 
					use crate::sgx::grpc_dtpm::{get_config, update_config};
 | 
				
			||||||
use crate::sgx::packaging::package_enclave;
 | 
					use crate::sgx::packaging::package_enclave;
 | 
				
			||||||
use crate::sgx::{
 | 
					use crate::sgx::{
 | 
				
			||||||
    get_app_node_by_contract, get_one_contract, inspect_node, print_nodes, write_uuid_list,
 | 
					    get_app_node_by_contract, get_one_contract, inspect_node, print_nodes, write_app_id_list,
 | 
				
			||||||
    AppContract, AppDeleteResponse, AppDeployResponse,
 | 
					    AppContract, AppDeleteResponse, AppDeployResponse,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use crate::utils::block_on;
 | 
					use crate::utils::block_on;
 | 
				
			||||||
@ -37,10 +37,10 @@ pub fn handle_app_nodes(matches: &ArgMatches) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        Some(("report", subcom_args)) => {
 | 
					        Some(("report", subcom_args)) => {
 | 
				
			||||||
            let node_pubkey: String = subcom_args.get_one::<String>("pubkey").unwrap().clone();
 | 
					            let node_pubkey: String = subcom_args.get_one::<String>("pubkey").unwrap().clone();
 | 
				
			||||||
            let contract_uuid: String = subcom_args.get_one::<String>("contract").unwrap().clone();
 | 
					            let contract_id: String = subcom_args.get_one::<String>("contract").unwrap().clone();
 | 
				
			||||||
            let reason: String = subcom_args.get_one::<String>("reason").unwrap().clone();
 | 
					            let reason: String = subcom_args.get_one::<String>("reason").unwrap().clone();
 | 
				
			||||||
            cli_print(
 | 
					            cli_print(
 | 
				
			||||||
                crate::general::report_node(node_pubkey, contract_uuid, reason).map_err(Into::into),
 | 
					                crate::general::report_node(node_pubkey, contract_id, reason).map_err(Into::into),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        _ => {
 | 
					        _ => {
 | 
				
			||||||
@ -104,26 +104,26 @@ fn handle_deploy(
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn handle_inspect(inspect_match: &ArgMatches) {
 | 
					fn handle_inspect(inspect_match: &ArgMatches) {
 | 
				
			||||||
    let uuid: String = inspect_match.get_one::<String>("uuid").unwrap().clone();
 | 
					    let app_id: String = inspect_match.get_one::<String>("id").unwrap().clone();
 | 
				
			||||||
    if *inspect_match.get_one::<bool>("show-node").unwrap() {
 | 
					    if *inspect_match.get_one::<bool>("show-node").unwrap() {
 | 
				
			||||||
        cli_print(block_on(get_app_node_by_contract(&uuid)).map_err(Into::into));
 | 
					        cli_print(block_on(get_app_node_by_contract(&app_id)).map_err(Into::into));
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        cli_print(block_on(get_one_contract(&uuid)).map_err(Into::into))
 | 
					        cli_print(block_on(get_one_contract(&app_id)).map_err(Into::into))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn handle_delete(
 | 
					fn handle_delete(
 | 
				
			||||||
    delete_match: &ArgMatches,
 | 
					    delete_match: &ArgMatches,
 | 
				
			||||||
) -> Result<AppDeleteResponse, Box<dyn std::error::Error>> {
 | 
					) -> Result<AppDeleteResponse, Box<dyn std::error::Error>> {
 | 
				
			||||||
    let app_uuid = delete_match
 | 
					    let app_id = delete_match
 | 
				
			||||||
        .get_one::<String>("uuid")
 | 
					        .get_one::<String>("id")
 | 
				
			||||||
        .ok_or_else(|| panic!("uuid argument required"))
 | 
					        .ok_or_else(|| panic!("app ID argument required"))
 | 
				
			||||||
        .unwrap()
 | 
					        .unwrap()
 | 
				
			||||||
        .to_owned();
 | 
					        .to_owned();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    match block_on(delete_app(app_uuid.clone())) {
 | 
					    match block_on(delete_app(app_id.clone())) {
 | 
				
			||||||
        Ok(_) => Ok(AppDeleteResponse {
 | 
					        Ok(_) => Ok(AppDeleteResponse {
 | 
				
			||||||
            uuid: app_uuid,
 | 
					            app_id,
 | 
				
			||||||
            message: "App deleted successfully".to_string(),
 | 
					            message: "App deleted successfully".to_string(),
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        Err(e) => {
 | 
					        Err(e) => {
 | 
				
			||||||
@ -148,7 +148,7 @@ fn handle_list(list_matche: &ArgMatches) -> Result<Vec<AppContract>, Box<dyn std
 | 
				
			|||||||
    let contracts: Vec<AppContract> =
 | 
					    let contracts: Vec<AppContract> =
 | 
				
			||||||
        block_on(list_contracts(req))?.into_iter().map(|n| n.into()).collect();
 | 
					        block_on(list_contracts(req))?.into_iter().map(|n| n.into()).collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    write_uuid_list(&contracts)?;
 | 
					    write_app_id_list(&contracts)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(contracts)
 | 
					    Ok(contracts)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -178,28 +178,28 @@ fn handle_config_sub_validate(
 | 
				
			|||||||
fn handle_config_sub_update(
 | 
					fn handle_config_sub_update(
 | 
				
			||||||
    update_matche: &ArgMatches,
 | 
					    update_matche: &ArgMatches,
 | 
				
			||||||
) -> Result<SimpleOutput, Box<dyn std::error::Error>> {
 | 
					) -> Result<SimpleOutput, Box<dyn std::error::Error>> {
 | 
				
			||||||
    if let (Some(file_path), Some(uuid)) =
 | 
					    if let (Some(file_path), Some(app_id)) =
 | 
				
			||||||
        (update_matche.get_one::<String>("config"), update_matche.get_one::<String>("uuid"))
 | 
					        (update_matche.get_one::<String>("config"), update_matche.get_one::<String>("id"))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        let loaded_config = validate_yaml(file_path).unwrap();
 | 
					        let loaded_config = validate_yaml(file_path).unwrap();
 | 
				
			||||||
        match block_on(update_config(uuid, loaded_config)) {
 | 
					        match block_on(update_config(app_id, loaded_config)) {
 | 
				
			||||||
            Ok(_) => Ok(SimpleOutput::from("App launch config updated successfully")),
 | 
					            Ok(_) => Ok(SimpleOutput::from("App launch config updated successfully")),
 | 
				
			||||||
            Err(e) => Err(Box::new(std::io::Error::other(format!(
 | 
					            Err(e) => Err(Box::new(std::io::Error::other(format!(
 | 
				
			||||||
                "Could not attest and update app launch config due to error: {e}"
 | 
					                "Could not attest and update app launch config due to error: {e}"
 | 
				
			||||||
            )))),
 | 
					            )))),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        Err(Box::new(std::io::Error::other("uuid and config arguments required")))
 | 
					        Err(Box::new(std::io::Error::other("id and config arguments required")))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn handle_config_sub_get(
 | 
					fn handle_config_sub_get(
 | 
				
			||||||
    get_matche: &ArgMatches,
 | 
					    get_matche: &ArgMatches,
 | 
				
			||||||
) -> Result<SimpleOutput, Box<dyn std::error::Error>> {
 | 
					) -> Result<SimpleOutput, Box<dyn std::error::Error>> {
 | 
				
			||||||
    if let (Some(file_path_to_save), Some(uuid)) =
 | 
					    if let (Some(file_path_to_save), Some(app_id)) =
 | 
				
			||||||
        (get_matche.get_one::<String>("path"), get_matche.get_one::<String>("uuid"))
 | 
					        (get_matche.get_one::<String>("path"), get_matche.get_one::<String>("id"))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        match block_on(get_config(uuid)) {
 | 
					        match block_on(get_config(app_id)) {
 | 
				
			||||||
            Ok(config) => {
 | 
					            Ok(config) => {
 | 
				
			||||||
                let config_yaml = serde_yaml::to_string(&config).unwrap();
 | 
					                let config_yaml = serde_yaml::to_string(&config).unwrap();
 | 
				
			||||||
                std::fs::write(file_path_to_save, config_yaml).unwrap();
 | 
					                std::fs::write(file_path_to_save, config_yaml).unwrap();
 | 
				
			||||||
@ -212,6 +212,6 @@ fn handle_config_sub_get(
 | 
				
			|||||||
            )))),
 | 
					            )))),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        Err(Box::new(std::io::Error::other("path and uuid arguments required")))
 | 
					        Err(Box::new(std::io::Error::other("path and id arguments required")))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,7 @@ use crate::sgx::utils::{
 | 
				
			|||||||
    calculate_nanocredits_for_app, fetch_config, hratls_url_and_mr_enclave_from_app_id,
 | 
					    calculate_nanocredits_for_app, fetch_config, hratls_url_and_mr_enclave_from_app_id,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use crate::sgx::{
 | 
					use crate::sgx::{
 | 
				
			||||||
    append_uuid_list, package_entry_from_name, AppDeployResponse, Error, PackageElement,
 | 
					    append_app_id_list, package_entry_from_name, AppDeployResponse, Error, PackageElement,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use crate::snp;
 | 
					use crate::snp;
 | 
				
			||||||
use detee_shared::app_proto::{AppNodeFilters, AppNodeListResp, AppResource, NewAppReq};
 | 
					use detee_shared::app_proto::{AppNodeFilters, AppNodeListResp, AppResource, NewAppReq};
 | 
				
			||||||
@ -65,7 +65,7 @@ impl Reqwest {
 | 
				
			|||||||
        tokio::time::sleep(tokio::time::Duration::from_millis(2500)).await;
 | 
					        tokio::time::sleep(tokio::time::Duration::from_millis(2500)).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (hratls_uri, mr_enclave) =
 | 
					        let (hratls_uri, mr_enclave) =
 | 
				
			||||||
            hratls_url_and_mr_enclave_from_app_id(&new_app_res.uuid).await?;
 | 
					            hratls_url_and_mr_enclave_from_app_id(&new_app_res.app_id).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mr_enclave = mr_enclave.expect("App contract does not have a mr_enclave");
 | 
					        let mr_enclave = mr_enclave.expect("App contract does not have a mr_enclave");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -88,7 +88,7 @@ impl Reqwest {
 | 
				
			|||||||
            let req = DtpmSetConfigReq { config_data, ..Default::default() };
 | 
					            let req = DtpmSetConfigReq { config_data, ..Default::default() };
 | 
				
			||||||
            set_config_pb(req, &dtpm_client).await?;
 | 
					            set_config_pb(req, &dtpm_client).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            append_uuid_list(&new_app_res.uuid, &self.app_name)?;
 | 
					            append_app_id_list(&new_app_res.app_id, &self.app_name)?;
 | 
				
			||||||
            Ok((new_app_res, self.app_name).into())
 | 
					            Ok((new_app_res, self.app_name).into())
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            Err(Error::Deployment(new_app_res.error))
 | 
					            Err(Error::Deployment(new_app_res.error))
 | 
				
			||||||
@ -159,7 +159,7 @@ impl Reqwest {
 | 
				
			|||||||
        let new_app_req = NewAppReq {
 | 
					        let new_app_req = NewAppReq {
 | 
				
			||||||
            node_pubkey: node.node_pubkey.clone(),
 | 
					            node_pubkey: node.node_pubkey.clone(),
 | 
				
			||||||
            resource,
 | 
					            resource,
 | 
				
			||||||
            uuid: "".to_string(),
 | 
					            app_id: "".to_string(),
 | 
				
			||||||
            price_per_unit: node.price,
 | 
					            price_per_unit: node.price,
 | 
				
			||||||
            locked_nano: nano_credits,
 | 
					            locked_nano: nano_credits,
 | 
				
			||||||
            app_name: self.app_name.clone(),
 | 
					            app_name: self.app_name.clone(),
 | 
				
			||||||
 | 
				
			|||||||
@ -57,8 +57,8 @@ impl crate::HumanOutput for AppContract {
 | 
				
			|||||||
            .collect::<Vec<_>>()
 | 
					            .collect::<Vec<_>>()
 | 
				
			||||||
            .join(", ");
 | 
					            .join(", ");
 | 
				
			||||||
        println!(
 | 
					        println!(
 | 
				
			||||||
            "The App {} has the UUID {}, and it runs on the node {}",
 | 
					            "The App {} has the ID {}, and it runs on the node {}",
 | 
				
			||||||
            self.app_name, self.uuid, self.node_pubkey
 | 
					            self.app_name, self.app_id, self.node_pubkey
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        println!("The app has mapped ports by the node are: {mapped_ports}");
 | 
					        println!("The app has mapped ports by the node are: {mapped_ports}");
 | 
				
			||||||
        println!(
 | 
					        println!(
 | 
				
			||||||
@ -92,9 +92,9 @@ pub async fn new_app(req: NewAppReq) -> Result<NewAppRes> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn delete_app(app_uuid: String) -> Result<()> {
 | 
					pub async fn delete_app(app_id: String) -> Result<()> {
 | 
				
			||||||
    let admin_pubkey = Config::get_detee_wallet()?;
 | 
					    let admin_pubkey = Config::get_detee_wallet()?;
 | 
				
			||||||
    let delete_req = DelAppReq { uuid: app_uuid, admin_pubkey };
 | 
					    let delete_req = DelAppReq { app_id: app_id, admin_pubkey };
 | 
				
			||||||
    let client = client().await?;
 | 
					    let client = client().await?;
 | 
				
			||||||
    let _ = call_with_follow_redirect!(client, delete_req, delete_app).await?;
 | 
					    let _ = call_with_follow_redirect!(client, delete_req, delete_app).await?;
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
 | 
				
			|||||||
@ -64,8 +64,8 @@ pub async fn dtpm_client(
 | 
				
			|||||||
    Ok(DtpmConfigManagerClient::new(channel).send_compressed(CompressionEncoding::Zstd))
 | 
					    Ok(DtpmConfigManagerClient::new(channel).send_compressed(CompressionEncoding::Zstd))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn update_config(app_uuid: &str, config: DtpmConfig) -> Result<()> {
 | 
					pub async fn update_config(app_id: &str, config: DtpmConfig) -> Result<()> {
 | 
				
			||||||
    let (hratls_uri, mr_enclave) = hratls_url_and_mr_enclave_from_app_id(app_uuid).await?;
 | 
					    let (hratls_uri, mr_enclave) = hratls_url_and_mr_enclave_from_app_id(app_id).await?;
 | 
				
			||||||
    let mr_enclave = mr_enclave.expect("App contract does not have a mr_enclave");
 | 
					    let mr_enclave = mr_enclave.expect("App contract does not have a mr_enclave");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let dtpm_client = dtpm_client(&hratls_uri, &mr_enclave).await?;
 | 
					    let dtpm_client = dtpm_client(&hratls_uri, &mr_enclave).await?;
 | 
				
			||||||
@ -76,8 +76,8 @@ pub async fn update_config(app_uuid: &str, config: DtpmConfig) -> Result<()> {
 | 
				
			|||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn get_config(app_uuid: &str) -> Result<DtpmConfig> {
 | 
					pub async fn get_config(app_id: &str) -> Result<DtpmConfig> {
 | 
				
			||||||
    let (hratls_uri, mr_enclave) = hratls_url_and_mr_enclave_from_app_id(app_uuid).await?;
 | 
					    let (hratls_uri, mr_enclave) = hratls_url_and_mr_enclave_from_app_id(app_id).await?;
 | 
				
			||||||
    let mr_enclave = mr_enclave.expect("App contract does not have a mr_enclave");
 | 
					    let mr_enclave = mr_enclave.expect("App contract does not have a mr_enclave");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let dtpm_client = dtpm_client(&hratls_uri, &mr_enclave).await?;
 | 
					    let dtpm_client = dtpm_client(&hratls_uri, &mr_enclave).await?;
 | 
				
			||||||
 | 
				
			|||||||
@ -46,8 +46,8 @@ pub enum Error {
 | 
				
			|||||||
pub struct AppContract {
 | 
					pub struct AppContract {
 | 
				
			||||||
    #[tabled(rename = "Location")]
 | 
					    #[tabled(rename = "Location")]
 | 
				
			||||||
    pub location: String,
 | 
					    pub location: String,
 | 
				
			||||||
    #[tabled(rename = "UUID pfx", display_with = "shorten_string")]
 | 
					    #[tabled(rename = "Short ID", display_with = "shorten_string")]
 | 
				
			||||||
    pub uuid: String,
 | 
					    pub app_id: String,
 | 
				
			||||||
    pub name: String,
 | 
					    pub name: String,
 | 
				
			||||||
    #[tabled(rename = "Cores")]
 | 
					    #[tabled(rename = "Cores")]
 | 
				
			||||||
    pub vcpus: u32,
 | 
					    pub vcpus: u32,
 | 
				
			||||||
@ -157,7 +157,7 @@ impl From<AppContractPB> for AppContract {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            location,
 | 
					            location,
 | 
				
			||||||
            uuid: brain_app_contract.uuid,
 | 
					            app_id: brain_app_contract.app_id,
 | 
				
			||||||
            name: brain_app_contract.app_name,
 | 
					            name: brain_app_contract.app_name,
 | 
				
			||||||
            vcpus,
 | 
					            vcpus,
 | 
				
			||||||
            memory_mib,
 | 
					            memory_mib,
 | 
				
			||||||
@ -173,24 +173,24 @@ impl From<AppContractPB> for AppContract {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn get_one_contract(uuid: &str) -> Result<AppContractPB, Error> {
 | 
					pub async fn get_one_contract(app_id: &str) -> Result<AppContractPB, Error> {
 | 
				
			||||||
    let req = ListAppContractsReq {
 | 
					    let req = ListAppContractsReq {
 | 
				
			||||||
        admin_pubkey: Config::get_detee_wallet()?,
 | 
					        admin_pubkey: Config::get_detee_wallet()?,
 | 
				
			||||||
        uuid: uuid.to_string(),
 | 
					        app_id: app_id.to_string(),
 | 
				
			||||||
        ..Default::default()
 | 
					        ..Default::default()
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    let contracts = grpc_brain::list_contracts(req).await?;
 | 
					    let contracts = grpc_brain::list_contracts(req).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if contracts.is_empty() {
 | 
					    if contracts.is_empty() {
 | 
				
			||||||
        return Err(Error::AppContractNotFound(uuid.to_string()));
 | 
					        return Err(Error::AppContractNotFound(app_id.to_string()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // let _ = write_uuid_list(&contracts);
 | 
					    // let _ = write_app_id_list(&contracts);
 | 
				
			||||||
    Ok(contracts[0].clone())
 | 
					    Ok(contracts[0].clone())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Serialize, Deserialize)]
 | 
					#[derive(Debug, Serialize, Deserialize)]
 | 
				
			||||||
pub struct AppDeployResponse {
 | 
					pub struct AppDeployResponse {
 | 
				
			||||||
    pub uuid: String,
 | 
					    pub app_id: String,
 | 
				
			||||||
    pub name: String,
 | 
					    pub name: String,
 | 
				
			||||||
    pub node_ip: String,
 | 
					    pub node_ip: String,
 | 
				
			||||||
    pub hratls_port: u32,
 | 
					    pub hratls_port: u32,
 | 
				
			||||||
@ -199,14 +199,14 @@ pub struct AppDeployResponse {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl crate::HumanOutput for AppDeployResponse {
 | 
					impl crate::HumanOutput for AppDeployResponse {
 | 
				
			||||||
    fn human_cli_print(&self) {
 | 
					    fn human_cli_print(&self) {
 | 
				
			||||||
        println!("The application got deployed under the UUID: {}", self.uuid);
 | 
					        println!("The application got deployed under the ID: {}", self.app_id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl From<(NewAppRes, String)> for AppDeployResponse {
 | 
					impl From<(NewAppRes, String)> for AppDeployResponse {
 | 
				
			||||||
    fn from((value, name): (NewAppRes, String)) -> Self {
 | 
					    fn from((value, name): (NewAppRes, String)) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            uuid: value.uuid,
 | 
					            app_id: value.app_id,
 | 
				
			||||||
            name,
 | 
					            name,
 | 
				
			||||||
            node_ip: value.ip_address,
 | 
					            node_ip: value.ip_address,
 | 
				
			||||||
            hratls_port: value
 | 
					            hratls_port: value
 | 
				
			||||||
@ -222,13 +222,13 @@ impl From<(NewAppRes, String)> for AppDeployResponse {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Serialize, Deserialize)]
 | 
					#[derive(Debug, Serialize, Deserialize)]
 | 
				
			||||||
pub struct AppDeleteResponse {
 | 
					pub struct AppDeleteResponse {
 | 
				
			||||||
    pub uuid: String,
 | 
					    pub app_id: String,
 | 
				
			||||||
    pub message: String,
 | 
					    pub message: String,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl crate::HumanOutput for AppDeleteResponse {
 | 
					impl crate::HumanOutput for AppDeleteResponse {
 | 
				
			||||||
    fn human_cli_print(&self) {
 | 
					    fn human_cli_print(&self) {
 | 
				
			||||||
        println!("App deleted successfully: UUID: {}", self.uuid);
 | 
					        println!("App deleted successfully: ID: {}", self.app_id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -279,18 +279,18 @@ pub fn print_nodes() -> Result<Vec<AppNodeListResp>, Error> {
 | 
				
			|||||||
    Ok(block_on(grpc_brain::get_app_node_list(req))?)
 | 
					    Ok(block_on(grpc_brain::get_app_node_list(req))?)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn get_app_node_by_contract(uuid: &str) -> Result<AppNodeListResp, Error> {
 | 
					pub async fn get_app_node_by_contract(app_id: &str) -> Result<AppNodeListResp, Error> {
 | 
				
			||||||
    let contract = get_one_contract(uuid).await?;
 | 
					    let contract = get_one_contract(app_id).await?;
 | 
				
			||||||
    Ok(get_one_app_node(AppNodeFilters { node_pubkey: contract.node_pubkey, ..Default::default() })
 | 
					    Ok(get_one_app_node(AppNodeFilters { node_pubkey: contract.node_pubkey, ..Default::default() })
 | 
				
			||||||
        .await?)
 | 
					        .await?)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn write_uuid_list(app_contracts: &[AppContract]) -> Result<(), Error> {
 | 
					fn write_app_id_list(app_contracts: &[AppContract]) -> Result<(), Error> {
 | 
				
			||||||
    let app_uuid_list_path = Config::app_uuid_list_path()?;
 | 
					    let app_app_id_list_path = Config::app_id_list_path()?;
 | 
				
			||||||
    let mut file = std::fs::File::create(app_uuid_list_path)?;
 | 
					    let mut file = std::fs::File::create(app_app_id_list_path)?;
 | 
				
			||||||
    let output: String = app_contracts
 | 
					    let output: String = app_contracts
 | 
				
			||||||
        .iter()
 | 
					        .iter()
 | 
				
			||||||
        .map(|app| format!("{}\t{}", app.uuid, app.name).to_string())
 | 
					        .map(|app| format!("{}\t{}", app.app_id, app.name).to_string())
 | 
				
			||||||
        .collect::<Vec<String>>()
 | 
					        .collect::<Vec<String>>()
 | 
				
			||||||
        .join("\n");
 | 
					        .join("\n");
 | 
				
			||||||
    let output = output + "\n";
 | 
					    let output = output + "\n";
 | 
				
			||||||
@ -298,11 +298,11 @@ fn write_uuid_list(app_contracts: &[AppContract]) -> Result<(), Error> {
 | 
				
			|||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn append_uuid_list(uuid: &str, app_name: &str) -> Result<(), Error> {
 | 
					pub fn append_app_id_list(app_id: &str, app_name: &str) -> Result<(), Error> {
 | 
				
			||||||
    use std::fs::OpenOptions;
 | 
					    use std::fs::OpenOptions;
 | 
				
			||||||
    use std::io::prelude::*;
 | 
					    use std::io::prelude::*;
 | 
				
			||||||
    let mut file =
 | 
					    let mut file =
 | 
				
			||||||
        OpenOptions::new().create(true).append(true).open(Config::app_uuid_list_path()?).unwrap();
 | 
					        OpenOptions::new().create(true).append(true).open(Config::app_id_list_path()?).unwrap();
 | 
				
			||||||
    writeln!(file, "{uuid}\t{app_name}")?;
 | 
					    writeln!(file, "{app_id}\t{app_name}")?;
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -10,11 +10,11 @@ pub fn handle_vm(matches: &ArgMatches) {
 | 
				
			|||||||
        Some(("ssh", args)) => cli_print(handle_vm_ssh(args)),
 | 
					        Some(("ssh", args)) => cli_print(handle_vm_ssh(args)),
 | 
				
			||||||
        Some(("list", args)) => cli_print(handle_vm_list(args)),
 | 
					        Some(("list", args)) => cli_print(handle_vm_list(args)),
 | 
				
			||||||
        Some(("inspect", inspect_args)) => {
 | 
					        Some(("inspect", inspect_args)) => {
 | 
				
			||||||
            let uuid: String = inspect_args.get_one::<String>("uuid").unwrap().clone();
 | 
					            let vm_id: String = inspect_args.get_one::<String>("id").unwrap().clone();
 | 
				
			||||||
            if *inspect_args.get_one::<bool>("show-node").unwrap() {
 | 
					            if *inspect_args.get_one::<bool>("show-node").unwrap() {
 | 
				
			||||||
                cli_print(snp::get_node_by_contract(&uuid).map_err(Into::into));
 | 
					                cli_print(snp::get_node_by_contract(&vm_id).map_err(Into::into));
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                cli_print(snp::get_one_contract(&uuid).map_err(Into::into));
 | 
					                cli_print(snp::get_one_contract(&vm_id).map_err(Into::into));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Some(("update", args)) => cli_print(handle_vm_update(args)),
 | 
					        Some(("update", args)) => cli_print(handle_vm_update(args)),
 | 
				
			||||||
@ -41,10 +41,10 @@ pub fn handle_vm_nodes(matches: &ArgMatches) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        Some(("report", path_subcommand)) => {
 | 
					        Some(("report", path_subcommand)) => {
 | 
				
			||||||
            let node_pubkey: String = path_subcommand.get_one::<String>("pubkey").unwrap().clone();
 | 
					            let node_pubkey: String = path_subcommand.get_one::<String>("pubkey").unwrap().clone();
 | 
				
			||||||
            let contract_uuid: String =
 | 
					            let contract_id: String =
 | 
				
			||||||
                path_subcommand.get_one::<String>("contract").unwrap().clone();
 | 
					                path_subcommand.get_one::<String>("contract").unwrap().clone();
 | 
				
			||||||
            let reason: String = path_subcommand.get_one::<String>("reason").unwrap().clone();
 | 
					            let reason: String = path_subcommand.get_one::<String>("reason").unwrap().clone();
 | 
				
			||||||
            cli_print(general::report_node(node_pubkey, contract_uuid, reason).map_err(Into::into))
 | 
					            cli_print(general::report_node(node_pubkey, contract_id, reason).map_err(Into::into))
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        _ => {
 | 
					        _ => {
 | 
				
			||||||
            println!("Available commands are search, inspect and report. Use --help for more information.")
 | 
					            println!("Available commands are search, inspect and report. Use --help for more information.")
 | 
				
			||||||
@ -63,8 +63,13 @@ fn handle_vm_deploy(matches: &ArgMatches) -> Result<snp::VmSshArgs, Box<dyn Erro
 | 
				
			|||||||
    let location = matches.get_one::<String>("location").unwrap().as_str();
 | 
					    let location = matches.get_one::<String>("location").unwrap().as_str();
 | 
				
			||||||
    let ipv4: crate::snp::deploy::IPv4Config = match matches.get_one::<bool>("public-ip").unwrap() {
 | 
					    let ipv4: crate::snp::deploy::IPv4Config = match matches.get_one::<bool>("public-ip").unwrap() {
 | 
				
			||||||
        true => crate::snp::deploy::IPv4Config::PublicIPv4,
 | 
					        true => crate::snp::deploy::IPv4Config::PublicIPv4,
 | 
				
			||||||
        false => crate::snp::deploy::IPv4Config::PublishPorts(Vec::new()),
 | 
					        false => {
 | 
				
			||||||
 | 
					            let exposing_port =
 | 
				
			||||||
 | 
					                matches.get_many::<u32>("port").unwrap_or_default().cloned().collect::<Vec<_>>();
 | 
				
			||||||
 | 
					            crate::snp::deploy::IPv4Config::PublishPorts(exposing_port)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let distro =
 | 
					    let distro =
 | 
				
			||||||
        crate::snp::Distro::from_string(matches.get_one::<String>("distribution").unwrap());
 | 
					        crate::snp::Distro::from_string(matches.get_one::<String>("distribution").unwrap());
 | 
				
			||||||
    let vm_config = snp::deploy::Request {
 | 
					    let vm_config = snp::deploy::Request {
 | 
				
			||||||
@ -84,8 +89,8 @@ fn handle_vm_deploy(matches: &ArgMatches) -> Result<snp::VmSshArgs, Box<dyn Erro
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn handle_vm_ssh(ssh_args: &ArgMatches) -> Result<snp::VmSshArgs, Box<dyn Error>> {
 | 
					fn handle_vm_ssh(ssh_args: &ArgMatches) -> Result<snp::VmSshArgs, Box<dyn Error>> {
 | 
				
			||||||
    let uuid: String = ssh_args.get_one::<String>("uuid").unwrap().clone();
 | 
					    let vm_id: String = ssh_args.get_one::<String>("id").unwrap().clone();
 | 
				
			||||||
    Ok(snp::ssh(&uuid, *ssh_args.get_one::<bool>("just-print").unwrap())?)
 | 
					    Ok(snp::ssh(&vm_id, *ssh_args.get_one::<bool>("just-print").unwrap())?)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn handle_vm_list(update_vm_args: &ArgMatches) -> Result<Vec<snp::VmContract>, Box<dyn Error>> {
 | 
					fn handle_vm_list(update_vm_args: &ArgMatches) -> Result<Vec<snp::VmContract>, Box<dyn Error>> {
 | 
				
			||||||
@ -93,12 +98,12 @@ fn handle_vm_list(update_vm_args: &ArgMatches) -> Result<Vec<snp::VmContract>, B
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn handle_vm_update(update_vm_args: &ArgMatches) -> Result<SimpleOutput, Box<dyn Error>> {
 | 
					fn handle_vm_update(update_vm_args: &ArgMatches) -> Result<SimpleOutput, Box<dyn Error>> {
 | 
				
			||||||
    let uuid = update_vm_args.get_one::<String>("uuid").unwrap().clone();
 | 
					    let vm_id = update_vm_args.get_one::<String>("id").unwrap().clone();
 | 
				
			||||||
    let hostname = update_vm_args.get_one::<String>("hostname").unwrap().clone();
 | 
					    let hostname = update_vm_args.get_one::<String>("hostname").unwrap().clone();
 | 
				
			||||||
    let memory = *update_vm_args.get_one::<u32>("memory").unwrap();
 | 
					    let memory = *update_vm_args.get_one::<u32>("memory").unwrap();
 | 
				
			||||||
    snp::update::Request::process_request(
 | 
					    snp::update::Request::process_request(
 | 
				
			||||||
        hostname,
 | 
					        hostname,
 | 
				
			||||||
        &uuid,
 | 
					        &vm_id,
 | 
				
			||||||
        *update_vm_args.get_one::<u32>("vcpus").unwrap(),
 | 
					        *update_vm_args.get_one::<u32>("vcpus").unwrap(),
 | 
				
			||||||
        memory,
 | 
					        memory,
 | 
				
			||||||
        *update_vm_args.get_one::<u32>("disk").unwrap(),
 | 
					        *update_vm_args.get_one::<u32>("disk").unwrap(),
 | 
				
			||||||
@ -106,14 +111,14 @@ fn handle_vm_update(update_vm_args: &ArgMatches) -> Result<SimpleOutput, Box<dyn
 | 
				
			|||||||
    )?;
 | 
					    )?;
 | 
				
			||||||
    let hours = *update_vm_args.get_one::<u32>("hours").unwrap();
 | 
					    let hours = *update_vm_args.get_one::<u32>("hours").unwrap();
 | 
				
			||||||
    if hours != 0 {
 | 
					    if hours != 0 {
 | 
				
			||||||
        snp::update::expand_vm_hours(&uuid, hours)?;
 | 
					        snp::update::expand_vm_hours(&vm_id, hours)?;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Ok(SimpleOutput::from("VM successfully updated."))
 | 
					    Ok(SimpleOutput::from("VM successfully updated."))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn handle_vm_delete(delete_args: &ArgMatches) -> Result<SimpleOutput, Box<dyn Error>> {
 | 
					fn handle_vm_delete(delete_args: &ArgMatches) -> Result<SimpleOutput, Box<dyn Error>> {
 | 
				
			||||||
    let uuid: String = delete_args.get_one::<String>("uuid").unwrap().clone();
 | 
					    let vm_id: String = delete_args.get_one::<String>("id").unwrap().clone();
 | 
				
			||||||
    snp::delete_contract(&uuid)?;
 | 
					    snp::delete_contract(&vm_id)?;
 | 
				
			||||||
    Ok(SimpleOutput::from("VM successfully deleted."))
 | 
					    Ok(SimpleOutput::from("VM successfully deleted."))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -56,7 +56,7 @@ impl Request {
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
        let args = new_vm_resp.args.ok_or(Error::NoMeasurement)?;
 | 
					        let args = new_vm_resp.args.ok_or(Error::NoMeasurement)?;
 | 
				
			||||||
        let measurement_args = injector::Args {
 | 
					        let measurement_args = injector::Args {
 | 
				
			||||||
            uuid: new_vm_resp.uuid.clone(),
 | 
					            vm_id: new_vm_resp.vm_id.clone(),
 | 
				
			||||||
            vcpus,
 | 
					            vcpus,
 | 
				
			||||||
            kernel: kernel_sha,
 | 
					            kernel: kernel_sha,
 | 
				
			||||||
            initrd: dtrfs_sha,
 | 
					            initrd: dtrfs_sha,
 | 
				
			||||||
@ -75,9 +75,9 @@ impl Request {
 | 
				
			|||||||
            Some((&template_url, &template_sha)),
 | 
					            Some((&template_url, &template_sha)),
 | 
				
			||||||
            &self.hostname,
 | 
					            &self.hostname,
 | 
				
			||||||
        )?;
 | 
					        )?;
 | 
				
			||||||
        ssh_args.uuid = new_vm_resp.uuid;
 | 
					        ssh_args.vm_id = new_vm_resp.vm_id;
 | 
				
			||||||
        ssh_args.hostname = self.hostname.clone();
 | 
					        ssh_args.hostname = self.hostname.clone();
 | 
				
			||||||
        let _ = super::append_uuid_list(&ssh_args.uuid, &ssh_args.hostname);
 | 
					        let _ = super::append_vm_id_list(&ssh_args.vm_id, &ssh_args.hostname);
 | 
				
			||||||
        Ok(ssh_args)
 | 
					        Ok(ssh_args)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -168,7 +168,7 @@ impl Request {
 | 
				
			|||||||
        node_pubkey: &str,
 | 
					        node_pubkey: &str,
 | 
				
			||||||
        offer: &proto::VmNodeOffer,
 | 
					        offer: &proto::VmNodeOffer,
 | 
				
			||||||
    ) -> Option<proto::NewVmReq> {
 | 
					    ) -> Option<proto::NewVmReq> {
 | 
				
			||||||
        if offer.vcpus == 0 {
 | 
					        if offer.vcpus == 0 || offer.memory_mib == 0 || offer.disk_mib == 0 {
 | 
				
			||||||
            return None;
 | 
					            return None;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        let memory_per_cpu = offer.memory_mib / offer.vcpus;
 | 
					        let memory_per_cpu = offer.memory_mib / offer.vcpus;
 | 
				
			||||||
@ -215,7 +215,7 @@ impl Request {
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let brain_req = proto::NewVmReq {
 | 
					        let brain_req = proto::NewVmReq {
 | 
				
			||||||
            uuid: String::new(),
 | 
					            vm_id: String::new(),
 | 
				
			||||||
            hostname: self.hostname.clone(),
 | 
					            hostname: self.hostname.clone(),
 | 
				
			||||||
            admin_pubkey,
 | 
					            admin_pubkey,
 | 
				
			||||||
            node_pubkey: node_pubkey.to_string(),
 | 
					            node_pubkey: node_pubkey.to_string(),
 | 
				
			||||||
 | 
				
			|||||||
@ -55,8 +55,8 @@ pub enum Error {
 | 
				
			|||||||
impl crate::HumanOutput for VmContract {
 | 
					impl crate::HumanOutput for VmContract {
 | 
				
			||||||
    fn human_cli_print(&self) {
 | 
					    fn human_cli_print(&self) {
 | 
				
			||||||
        println!(
 | 
					        println!(
 | 
				
			||||||
            "The VM {} has the UUID {}, and it runs on the node {}",
 | 
					            "The VM {} has the ID {}, and it runs on the node {}",
 | 
				
			||||||
            self.hostname, self.uuid, self.node_pubkey
 | 
					            self.hostname, self.vm_id, self.node_pubkey
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        if self.vm_public_ipv4.is_empty() {
 | 
					        if self.vm_public_ipv4.is_empty() {
 | 
				
			||||||
            println!(
 | 
					            println!(
 | 
				
			||||||
@ -168,9 +168,9 @@ pub async fn list_contracts(req: ListVmContractsReq) -> Result<Vec<VmContract>,
 | 
				
			|||||||
    Ok(contracts)
 | 
					    Ok(contracts)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn delete_vm(uuid: &str) -> Result<(), Error> {
 | 
					pub async fn delete_vm(vm_id: &str) -> Result<(), Error> {
 | 
				
			||||||
    let client = client().await?;
 | 
					    let client = client().await?;
 | 
				
			||||||
    let req = DeleteVmReq { uuid: uuid.to_string(), admin_pubkey: Config::get_detee_wallet()? };
 | 
					    let req = DeleteVmReq { vm_id: vm_id.to_string(), admin_pubkey: Config::get_detee_wallet()? };
 | 
				
			||||||
    match call_with_follow_redirect!(client, req, delete_vm).await {
 | 
					    match call_with_follow_redirect!(client, req, delete_vm).await {
 | 
				
			||||||
        Ok(confirmation) => {
 | 
					        Ok(confirmation) => {
 | 
				
			||||||
            log::debug!("VM deletion confirmation: {confirmation:?}");
 | 
					            log::debug!("VM deletion confirmation: {confirmation:?}");
 | 
				
			||||||
@ -183,9 +183,9 @@ pub async fn delete_vm(uuid: &str) -> Result<(), Error> {
 | 
				
			|||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn extend_vm(uuid: String, admin_pubkey: String, locked_nano: u64) -> Result<(), Error> {
 | 
					pub async fn extend_vm(vm_id: String, admin_pubkey: String, locked_nano: u64) -> Result<(), Error> {
 | 
				
			||||||
    let mut client = client().await?;
 | 
					    let mut client = client().await?;
 | 
				
			||||||
    let req = ExtendVmReq { admin_pubkey, uuid, locked_nano };
 | 
					    let req = ExtendVmReq { admin_pubkey, vm_id, locked_nano };
 | 
				
			||||||
    let result = client.extend_vm(sign_request(req)?).await;
 | 
					    let result = client.extend_vm(sign_request(req)?).await;
 | 
				
			||||||
    match result {
 | 
					    match result {
 | 
				
			||||||
        Ok(confirmation) => {
 | 
					        Ok(confirmation) => {
 | 
				
			||||||
@ -225,16 +225,16 @@ pub async fn update_vm(req: UpdateVmReq) -> Result<UpdateVmResp, Error> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn get_contract_by_uuid(uuid: &str) -> Result<VmContract, Error> {
 | 
					pub async fn get_contract_by_id(vm_id: &str) -> Result<VmContract, Error> {
 | 
				
			||||||
    let req = ListVmContractsReq {
 | 
					    let req = ListVmContractsReq {
 | 
				
			||||||
        wallet: Config::get_detee_wallet()?,
 | 
					        wallet: Config::get_detee_wallet()?,
 | 
				
			||||||
        uuid: uuid.to_string(),
 | 
					        vm_id: vm_id.to_string(),
 | 
				
			||||||
        ..Default::default()
 | 
					        ..Default::default()
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    let contracts = list_contracts(req).await?;
 | 
					    let contracts = list_contracts(req).await?;
 | 
				
			||||||
    if contracts.is_empty() {
 | 
					    if contracts.is_empty() {
 | 
				
			||||||
        log::error!("Could not find any contract by ID {uuid}");
 | 
					        log::error!("Could not find any contract by ID {vm_id}");
 | 
				
			||||||
        return Err(Error::VmContractNotFound(uuid.to_string()));
 | 
					        return Err(Error::VmContractNotFound(vm_id.to_string()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Ok(contracts[0].clone())
 | 
					    Ok(contracts[0].clone())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ use std::net::IpAddr;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub struct Args {
 | 
					pub struct Args {
 | 
				
			||||||
    pub uuid: String,
 | 
					    pub vm_id: String,
 | 
				
			||||||
    pub vcpus: u32,
 | 
					    pub vcpus: u32,
 | 
				
			||||||
    pub kernel: String,
 | 
					    pub kernel: String,
 | 
				
			||||||
    pub initrd: String,
 | 
					    pub initrd: String,
 | 
				
			||||||
@ -100,9 +100,9 @@ impl Args {
 | 
				
			|||||||
            ip_string = "detee_net_eth0=10.0.2.15_24_10.0.2.2 ".to_string() + &ip_string;
 | 
					            ip_string = "detee_net_eth0=10.0.2.15_24_10.0.2.2 ".to_string() + &ip_string;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        let admin_key = format!("detee_admin={} ", Config::get_detee_wallet()?);
 | 
					        let admin_key = format!("detee_admin={} ", Config::get_detee_wallet()?);
 | 
				
			||||||
        let hostname = format!("detee_uuid={}", self.uuid);
 | 
					        let hostname = format!("detee_vm_id={}", self.vm_id);
 | 
				
			||||||
        let params = format!("{}{}{}", ip_string, admin_key, hostname);
 | 
					        let params = format!("{}{}{}", ip_string, admin_key, hostname);
 | 
				
			||||||
        debug!("Calculated kernel params for {} to: {}", self.uuid, params);
 | 
					        debug!("Calculated kernel params for {} to: {}", self.vm_id, params);
 | 
				
			||||||
        Ok(params)
 | 
					        Ok(params)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -64,7 +64,7 @@ impl From<&str> for Location {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[derive(Serialize, Default)]
 | 
					#[derive(Serialize, Default)]
 | 
				
			||||||
pub struct VmSshArgs {
 | 
					pub struct VmSshArgs {
 | 
				
			||||||
    uuid: String,
 | 
					    vm_id: String,
 | 
				
			||||||
    hostname: String,
 | 
					    hostname: String,
 | 
				
			||||||
    ip: String,
 | 
					    ip: String,
 | 
				
			||||||
    port: String,
 | 
					    port: String,
 | 
				
			||||||
@ -74,7 +74,7 @@ pub struct VmSshArgs {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl crate::HumanOutput for VmSshArgs {
 | 
					impl crate::HumanOutput for VmSshArgs {
 | 
				
			||||||
    fn human_cli_print(&self) {
 | 
					    fn human_cli_print(&self) {
 | 
				
			||||||
        println!("To SSH into {} (UUID: {}), run the following command:", self.hostname, self.uuid);
 | 
					        println!("To SSH into {} (ID: {}), run the following command:", self.hostname, self.vm_id);
 | 
				
			||||||
        println!("    ssh -i {} -p {} {}@{}", self.key_path, self.port, self.user, self.ip);
 | 
					        println!("    ssh -i {} -p {} {}@{}", self.key_path, self.port, self.user, self.ip);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -84,7 +84,7 @@ impl TryFrom<grpc::proto::VmContract> for VmSshArgs {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    fn try_from(contract: grpc::proto::VmContract) -> Result<Self, Self::Error> {
 | 
					    fn try_from(contract: grpc::proto::VmContract) -> Result<Self, Self::Error> {
 | 
				
			||||||
        let mut args = VmSshArgs { ..Default::default() };
 | 
					        let mut args = VmSshArgs { ..Default::default() };
 | 
				
			||||||
        args.uuid = contract.uuid;
 | 
					        args.vm_id = contract.vm_id;
 | 
				
			||||||
        args.hostname = contract.hostname;
 | 
					        args.hostname = contract.hostname;
 | 
				
			||||||
        args.user = "root".to_string();
 | 
					        args.user = "root".to_string();
 | 
				
			||||||
        args.key_path =
 | 
					        args.key_path =
 | 
				
			||||||
@ -176,8 +176,8 @@ impl Distro {
 | 
				
			|||||||
pub struct VmContract {
 | 
					pub struct VmContract {
 | 
				
			||||||
    #[tabled(rename = "Location")]
 | 
					    #[tabled(rename = "Location")]
 | 
				
			||||||
    pub location: String,
 | 
					    pub location: String,
 | 
				
			||||||
    #[tabled(rename = "UUID pfx", display_with = "shorten_string")]
 | 
					    #[tabled(rename = "short ID", display_with = "shorten_string")]
 | 
				
			||||||
    pub uuid: String,
 | 
					    pub vm_id: String,
 | 
				
			||||||
    pub hostname: String,
 | 
					    pub hostname: String,
 | 
				
			||||||
    #[tabled(rename = "Cores")]
 | 
					    #[tabled(rename = "Cores")]
 | 
				
			||||||
    pub vcpus: u64,
 | 
					    pub vcpus: u64,
 | 
				
			||||||
@ -210,7 +210,7 @@ fn display_mins(minutes: &u64) -> String {
 | 
				
			|||||||
impl From<proto::VmContract> for VmContract {
 | 
					impl From<proto::VmContract> for VmContract {
 | 
				
			||||||
    fn from(brain_contract: proto::VmContract) -> Self {
 | 
					    fn from(brain_contract: proto::VmContract) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            uuid: brain_contract.uuid,
 | 
					            vm_id: brain_contract.vm_id,
 | 
				
			||||||
            hostname: brain_contract.hostname,
 | 
					            hostname: brain_contract.hostname,
 | 
				
			||||||
            vcpus: brain_contract.vcpus as u64,
 | 
					            vcpus: brain_contract.vcpus as u64,
 | 
				
			||||||
            mem: brain_contract.memory_mb as u64,
 | 
					            mem: brain_contract.memory_mb as u64,
 | 
				
			||||||
@ -273,16 +273,16 @@ impl From<proto::VmNodeListResp> for TabledVmNode {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn ssh(uuid: &str, just_print: bool) -> Result<VmSshArgs, Error> {
 | 
					pub fn ssh(vm_id: &str, just_print: bool) -> Result<VmSshArgs, Error> {
 | 
				
			||||||
    log::info!("Getting VM information about {uuid} from brain...");
 | 
					    log::info!("Getting VM information about {vm_id} from brain...");
 | 
				
			||||||
    let req = proto::ListVmContractsReq {
 | 
					    let req = proto::ListVmContractsReq {
 | 
				
			||||||
        wallet: Config::get_detee_wallet()?,
 | 
					        wallet: Config::get_detee_wallet()?,
 | 
				
			||||||
        uuid: uuid.to_string(),
 | 
					        vm_id: vm_id.to_string(),
 | 
				
			||||||
        ..Default::default()
 | 
					        ..Default::default()
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    let contracts = block_on(snp::grpc::list_contracts(req))?;
 | 
					    let contracts = block_on(snp::grpc::list_contracts(req))?;
 | 
				
			||||||
    if contracts.is_empty() {
 | 
					    if contracts.is_empty() {
 | 
				
			||||||
        return Err(Error::VmContractNotFound(uuid.to_string()));
 | 
					        return Err(Error::VmContractNotFound(vm_id.to_string()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let args: VmSshArgs = contracts[0].clone().try_into()?;
 | 
					    let args: VmSshArgs = contracts[0].clone().try_into()?;
 | 
				
			||||||
    if just_print {
 | 
					    if just_print {
 | 
				
			||||||
@ -308,30 +308,30 @@ pub fn ssh(uuid: &str, just_print: bool) -> Result<VmSshArgs, Error> {
 | 
				
			|||||||
    std::process::exit(2);
 | 
					    std::process::exit(2);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn get_one_contract(uuid: &str) -> Result<proto::VmContract, Error> {
 | 
					pub fn get_one_contract(vm_id: &str) -> Result<proto::VmContract, Error> {
 | 
				
			||||||
    log::debug!("Getting contract {uuid} from brain...");
 | 
					    log::debug!("Getting contract {vm_id} from brain...");
 | 
				
			||||||
    let req = proto::ListVmContractsReq {
 | 
					    let req = proto::ListVmContractsReq {
 | 
				
			||||||
        wallet: Config::get_detee_wallet()?,
 | 
					        wallet: Config::get_detee_wallet()?,
 | 
				
			||||||
        uuid: uuid.to_string(),
 | 
					        vm_id: vm_id.to_string(),
 | 
				
			||||||
        ..Default::default()
 | 
					        ..Default::default()
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    let contracts = block_on(snp::grpc::list_contracts(req))?;
 | 
					    let contracts = block_on(snp::grpc::list_contracts(req))?;
 | 
				
			||||||
    if contracts.is_empty() {
 | 
					    if contracts.is_empty() {
 | 
				
			||||||
        return Err(Error::VmContractNotFound(uuid.to_string()));
 | 
					        return Err(Error::VmContractNotFound(vm_id.to_string()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Ok(contracts[0].clone())
 | 
					    Ok(contracts[0].clone())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn get_node_by_contract(uuid: &str) -> Result<proto::VmNodeListResp, Error> {
 | 
					pub fn get_node_by_contract(vm_id: &str) -> Result<proto::VmNodeListResp, Error> {
 | 
				
			||||||
    let contract = get_one_contract(uuid)?;
 | 
					    let contract = get_one_contract(vm_id)?;
 | 
				
			||||||
    Ok(block_on(snp::grpc::get_one_node(proto::VmNodeFilters {
 | 
					    Ok(block_on(snp::grpc::get_one_node(proto::VmNodeFilters {
 | 
				
			||||||
        node_pubkey: contract.node_pubkey,
 | 
					        node_pubkey: contract.node_pubkey,
 | 
				
			||||||
        ..Default::default()
 | 
					        ..Default::default()
 | 
				
			||||||
    }))?)
 | 
					    }))?)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn delete_contract(uuid: &str) -> Result<(), Error> {
 | 
					pub fn delete_contract(vm_id: &str) -> Result<(), Error> {
 | 
				
			||||||
    Ok(block_on(snp::grpc::delete_vm(uuid))?)
 | 
					    Ok(block_on(snp::grpc::delete_vm(vm_id))?)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn list_contracts(as_operator: bool) -> Result<Vec<VmContract>, Error> {
 | 
					pub fn list_contracts(as_operator: bool) -> Result<Vec<VmContract>, Error> {
 | 
				
			||||||
@ -342,16 +342,16 @@ pub fn list_contracts(as_operator: bool) -> Result<Vec<VmContract>, Error> {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
    let contracts: Vec<VmContract> =
 | 
					    let contracts: Vec<VmContract> =
 | 
				
			||||||
        block_on(grpc::list_contracts(req))?.into_iter().map(|n| n.into()).collect();
 | 
					        block_on(grpc::list_contracts(req))?.into_iter().map(|n| n.into()).collect();
 | 
				
			||||||
    let _ = write_uuid_list(&contracts);
 | 
					    let _ = write_vm_id_list(&contracts);
 | 
				
			||||||
    Ok(contracts)
 | 
					    Ok(contracts)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn write_uuid_list(contracts: &[VmContract]) -> Result<(), Error> {
 | 
					fn write_vm_id_list(contracts: &[VmContract]) -> Result<(), Error> {
 | 
				
			||||||
    let vm_uuid_list_path = Config::vm_uuid_list_path()?;
 | 
					    let vm_id_list_path = Config::vm_id_list_path()?;
 | 
				
			||||||
    let mut file = std::fs::File::create(vm_uuid_list_path)?;
 | 
					    let mut file = std::fs::File::create(vm_id_list_path)?;
 | 
				
			||||||
    let output: String = contracts
 | 
					    let output: String = contracts
 | 
				
			||||||
        .iter()
 | 
					        .iter()
 | 
				
			||||||
        .map(|vm| format!("{}\t{}", vm.uuid, vm.hostname).to_string())
 | 
					        .map(|vm| format!("{}\t{}", vm.vm_id, vm.hostname).to_string())
 | 
				
			||||||
        .collect::<Vec<String>>()
 | 
					        .collect::<Vec<String>>()
 | 
				
			||||||
        .join("\n");
 | 
					        .join("\n");
 | 
				
			||||||
    let output = output + "\n";
 | 
					    let output = output + "\n";
 | 
				
			||||||
@ -359,12 +359,12 @@ fn write_uuid_list(contracts: &[VmContract]) -> Result<(), Error> {
 | 
				
			|||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn append_uuid_list(uuid: &str, hostname: &str) -> Result<(), Error> {
 | 
					pub fn append_vm_id_list(vm_id: &str, hostname: &str) -> Result<(), Error> {
 | 
				
			||||||
    use std::fs::OpenOptions;
 | 
					    use std::fs::OpenOptions;
 | 
				
			||||||
    use std::io::prelude::*;
 | 
					    use std::io::prelude::*;
 | 
				
			||||||
    let mut file =
 | 
					    let mut file =
 | 
				
			||||||
        OpenOptions::new().create(true).append(true).open(Config::vm_uuid_list_path()?)?;
 | 
					        OpenOptions::new().create(true).append(true).open(Config::vm_id_list_path()?)?;
 | 
				
			||||||
    writeln!(file, "{uuid}\t{hostname}")?;
 | 
					    writeln!(file, "{vm_id}\t{hostname}")?;
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ pub struct Request {
 | 
				
			|||||||
impl Request {
 | 
					impl Request {
 | 
				
			||||||
    pub fn process_request(
 | 
					    pub fn process_request(
 | 
				
			||||||
        hostname: String,
 | 
					        hostname: String,
 | 
				
			||||||
        uuid: &str,
 | 
					        vm_id: &str,
 | 
				
			||||||
        vcpus: u32,
 | 
					        vcpus: u32,
 | 
				
			||||||
        memory_mb: u32,
 | 
					        memory_mb: u32,
 | 
				
			||||||
        disk_size_gb: u32,
 | 
					        disk_size_gb: u32,
 | 
				
			||||||
@ -39,19 +39,19 @@ impl Request {
 | 
				
			|||||||
            return Ok(());
 | 
					            return Ok(());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        log::info!("Starting VM updated based on req: {req:#?}");
 | 
					        log::info!("Starting VM updated based on req: {req:#?}");
 | 
				
			||||||
        req.update(uuid)
 | 
					        req.update(vm_id)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn update(&self, uuid: &str) -> Result<(), Error> {
 | 
					    fn update(&self, vm_id: &str) -> Result<(), Error> {
 | 
				
			||||||
        info!("Starting the process of updating the VM. {self:?}");
 | 
					        info!("Starting the process of updating the VM. {self:?}");
 | 
				
			||||||
        let update_vm_resp = self.send_update_vm_request(uuid)?;
 | 
					        let update_vm_resp = self.send_update_vm_request(vm_id)?;
 | 
				
			||||||
        debug!("The response for Update VM is: {update_vm_resp:#?}");
 | 
					        debug!("The response for Update VM is: {update_vm_resp:#?}");
 | 
				
			||||||
        if !update_vm_resp.error.is_empty() {
 | 
					        if !update_vm_resp.error.is_empty() {
 | 
				
			||||||
            return Err(Error::Node(update_vm_resp.error));
 | 
					            return Err(Error::Node(update_vm_resp.error));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        eprintln!("The modifications got approved. Proceeding with update...");
 | 
					        eprintln!("The modifications got approved. Proceeding with update...");
 | 
				
			||||||
        let updated_contract = block_on(grpc::get_contract_by_uuid(uuid))?;
 | 
					        let updated_contract = block_on(grpc::get_contract_by_id(vm_id))?;
 | 
				
			||||||
        debug!("Got the current contract for the VM after update. {updated_contract:#?}");
 | 
					        debug!("Got the current contract for the VM after update. {updated_contract:#?}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if !(self.vcpus != 0 || self.memory_mib != 0 || self.dtrfs.is_some()) {
 | 
					        if !(self.vcpus != 0 || self.memory_mib != 0 || self.dtrfs.is_some()) {
 | 
				
			||||||
@ -61,7 +61,7 @@ impl Request {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        let args = update_vm_resp.args.ok_or(Error::NoMeasurement)?;
 | 
					        let args = update_vm_resp.args.ok_or(Error::NoMeasurement)?;
 | 
				
			||||||
        let measurement_args = injector::Args {
 | 
					        let measurement_args = injector::Args {
 | 
				
			||||||
            uuid: update_vm_resp.uuid,
 | 
					            vm_id: update_vm_resp.vm_id,
 | 
				
			||||||
            vcpus: updated_contract.vcpus,
 | 
					            vcpus: updated_contract.vcpus,
 | 
				
			||||||
            kernel: updated_contract.kernel_sha,
 | 
					            kernel: updated_contract.kernel_sha,
 | 
				
			||||||
            initrd: updated_contract.dtrfs_sha,
 | 
					            initrd: updated_contract.dtrfs_sha,
 | 
				
			||||||
@ -75,13 +75,13 @@ impl Request {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // returns node IP and data regarding the new VM
 | 
					    // returns node IP and data regarding the new VM
 | 
				
			||||||
    fn send_update_vm_request(&self, uuid: &str) -> Result<proto::UpdateVmResp, Error> {
 | 
					    fn send_update_vm_request(&self, vm_id: &str) -> Result<proto::UpdateVmResp, Error> {
 | 
				
			||||||
        let (kernel_url, kernel_sha, dtrfs_url, dtrfs_sha) = match self.dtrfs.clone() {
 | 
					        let (kernel_url, kernel_sha, dtrfs_url, dtrfs_sha) = match self.dtrfs.clone() {
 | 
				
			||||||
            Some(dtrfs) => (dtrfs.kernel_url, dtrfs.kernel_sha, dtrfs.dtrfs_url, dtrfs.dtrfs_sha),
 | 
					            Some(dtrfs) => (dtrfs.kernel_url, dtrfs.kernel_sha, dtrfs.dtrfs_url, dtrfs.dtrfs_sha),
 | 
				
			||||||
            None => (String::new(), String::new(), String::new(), String::new()),
 | 
					            None => (String::new(), String::new(), String::new(), String::new()),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        Ok(block_on(grpc::update_vm(proto::UpdateVmReq {
 | 
					        Ok(block_on(grpc::update_vm(proto::UpdateVmReq {
 | 
				
			||||||
            uuid: uuid.to_string(),
 | 
					            vm_id: vm_id.to_string(),
 | 
				
			||||||
            hostname: self.hostname.clone(),
 | 
					            hostname: self.hostname.clone(),
 | 
				
			||||||
            admin_pubkey: Config::get_detee_wallet()?,
 | 
					            admin_pubkey: Config::get_detee_wallet()?,
 | 
				
			||||||
            disk_size_mib: self.disk_size_mib * 1024,
 | 
					            disk_size_mib: self.disk_size_mib * 1024,
 | 
				
			||||||
@ -95,10 +95,10 @@ impl Request {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn expand_vm_hours(uuid: &str, hours: u32) -> Result<(), Error> {
 | 
					pub fn expand_vm_hours(vm_id: &str, hours: u32) -> Result<(), Error> {
 | 
				
			||||||
    let contract = super::get_one_contract(uuid)?;
 | 
					    let contract = super::get_one_contract(vm_id)?;
 | 
				
			||||||
    // vcpus: u32, memory_mb: u32, disk_size_gb: u32, public_ipv4: bool, hours: u32, node_price:
 | 
					    // vcpus: u32, memory_mb: u32, disk_size_gb: u32, public_ipv4: bool, hours: u32, node_price:
 | 
				
			||||||
    let locked_nano = contract.nano_per_minute * 60 * (hours as u64);
 | 
					    let locked_nano = contract.nano_per_minute * 60 * (hours as u64);
 | 
				
			||||||
    block_on(grpc::extend_vm(uuid.to_string(), Config::get_detee_wallet()?, locked_nano))?;
 | 
					    block_on(grpc::extend_vm(vm_id.to_string(), Config::get_detee_wallet()?, locked_nano))?;
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user