From 72f260c4e579e3d7561d48afbe7fda63e73325ac Mon Sep 17 00:00:00 2001 From: petarjuki7 Date: Sun, 10 Nov 2024 01:41:31 +0100 Subject: [PATCH] Added update command --- crates/meroctl/src/cli/context.rs | 4 + crates/meroctl/src/cli/context/update.rs | 144 +++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 crates/meroctl/src/cli/context/update.rs diff --git a/crates/meroctl/src/cli/context.rs b/crates/meroctl/src/cli/context.rs index 42ebfde65..47c68c49c 100644 --- a/crates/meroctl/src/cli/context.rs +++ b/crates/meroctl/src/cli/context.rs @@ -9,6 +9,7 @@ use crate::cli::context::get::GetCommand; use crate::cli::context::invite::InviteCommand; use crate::cli::context::join::JoinCommand; use crate::cli::context::list::ListCommand; +use crate::cli::context::update::UpdateCommand; use crate::cli::context::watch::WatchCommand; use crate::cli::Environment; use crate::output::Report; @@ -19,6 +20,7 @@ mod get; mod invite; mod join; mod list; +mod update; mod watch; pub const EXAMPLES: &str = r" @@ -55,6 +57,7 @@ pub enum ContextSubCommands { Delete(DeleteCommand), #[command(alias = "ws")] Watch(WatchCommand), + Update(UpdateCommand), } impl Report for Context { @@ -75,6 +78,7 @@ impl ContextCommand { ContextSubCommands::Join(join) => join.run(environment).await, ContextSubCommands::List(list) => list.run(environment).await, ContextSubCommands::Watch(watch) => watch.run(environment).await, + ContextSubCommands::Update(update) => update.run(environment).await, } } } diff --git a/crates/meroctl/src/cli/context/update.rs b/crates/meroctl/src/cli/context/update.rs new file mode 100644 index 000000000..c997e8600 --- /dev/null +++ b/crates/meroctl/src/cli/context/update.rs @@ -0,0 +1,144 @@ +use calimero_primitives::application::ApplicationId; +use calimero_primitives::context::ContextId; +use calimero_primitives::identity::PublicKey; +use calimero_server_primitives::admin::{ + InstallApplicationResponse, InstallDevApplicationRequest, UpdateContextApplicationRequest, + UpdateContextApplicationResponse, +}; +use camino::Utf8PathBuf; +use clap::Parser; +use eyre::Result as EyreResult; +use libp2p::identity::Keypair; +use libp2p::Multiaddr; +use reqwest::Client; + +use crate::cli::Environment; +use crate::common::{do_request, fetch_multiaddr, load_config, multiaddr_to_url, RequestType}; + +#[derive(Debug, Parser)] +#[command(about = "Update app in context")] +pub struct UpdateCommand { + #[clap( + long, + short = 'a', + help = "The application ID to attach to the context" + )] + application_id: Option, + + #[clap(help = "Metadata needed for the application installation")] + metadata: Option, + + #[clap(help = "ContextId where to install the application")] + context_id: ContextId, + + #[clap(help = "Metadata needed for the application installation")] + member_public_key: PublicKey, + + #[clap( + long, + help = "Path to the application file to watch and install locally" + )] + path: Utf8PathBuf, +} + +impl UpdateCommand { + pub async fn run(self, environment: &Environment) -> EyreResult<()> { + let config = load_config(&environment.args.home, &environment.args.node_name)?; + let multiaddr = fetch_multiaddr(&config)?; + let client = Client::new(); + + let metadata = self.metadata.map(String::into_bytes); + + install_app_and_update_context( + environment, + &client, + multiaddr, + self.path, + self.context_id, + metadata, + &config.identity, + self.member_public_key, + ) + .await?; + + Ok(()) + } +} + +async fn install_app_and_update_context( + environment: &Environment, + client: &Client, + base_multiaddr: &Multiaddr, + path: Utf8PathBuf, + context_id: ContextId, + metadata: Option>, + keypair: &Keypair, + member_public_key: PublicKey, +) -> EyreResult<()> { + let application_id = install_app( + environment, + client, + base_multiaddr, + path.clone(), + metadata.clone(), + keypair, + ) + .await?; + + update_context_application( + environment, + client, + base_multiaddr, + context_id, + application_id, + keypair, + member_public_key, + ) + .await?; + + Ok(()) +} + +async fn update_context_application( + environment: &Environment, + client: &Client, + base_multiaddr: &Multiaddr, + context_id: ContextId, + application_id: ApplicationId, + keypair: &Keypair, + member_public_key: PublicKey, +) -> EyreResult<()> { + let url = multiaddr_to_url( + base_multiaddr, + &format!("admin-api/dev/contexts/{context_id}/application"), + )?; + + let request = UpdateContextApplicationRequest::new(application_id, member_public_key); + + let response: UpdateContextApplicationResponse = + do_request(client, url, Some(request), keypair, RequestType::Post).await?; + + environment.output.write(&response); + + Ok(()) +} + +async fn install_app( + environment: &Environment, + client: &Client, + base_multiaddr: &Multiaddr, + path: Utf8PathBuf, + metadata: Option>, + keypair: &Keypair, +) -> EyreResult { + let url = multiaddr_to_url(base_multiaddr, "admin-api/dev/install-dev-application")?; + + let request = InstallDevApplicationRequest::new(path, metadata.unwrap_or_default()); + + let response: InstallApplicationResponse = + do_request(client, url, Some(request), keypair, RequestType::Post).await?; + + environment.output.write(&response); + + Ok(response.data.application_id) +}