From 8c8d7f2c18dc100c136b9f833747da89ce022d81 Mon Sep 17 00:00:00 2001 From: Oleksandr Deundiak Date: Wed, 15 Jan 2025 17:55:53 +0100 Subject: [PATCH] feat(rust): optimize node creation: - create tokio `Runtime` in a predictable way and reuse it - rework `Command` usage - add `no_logging` flag to the node - optimize node startup - replace readiness poll with a callback --- Cargo.lock | 1 - .../ockam_api/src/cli_state/cli_state.rs | 30 +- .../ockam/ockam_api/src/logs/env_variables.rs | 2 +- .../src/logs/exporting_configuration.rs | 100 +++---- .../rust/ockam/ockam_api/src/logs/setup.rs | 116 ++++---- .../ockam/ockam_api/src/logs/tracing_guard.rs | 26 +- .../nodes/service/background_node_client.rs | 33 +-- .../src/nodes/service/in_memory_node.rs | 2 + .../ockam_api/src/ui/terminal/notification.rs | 6 +- .../ockam_api/tests/common/trace_code.rs | 77 ------ .../rust/ockam/ockam_api/tests/journeys.rs | 70 +++-- .../ockam/ockam_api/tests/logging_tracing.rs | 27 +- .../ockam/ockam_app_lib/src/api/functions.rs | 8 +- .../rust/ockam/ockam_app_lib/src/log.rs | 16 +- .../rust/ockam/ockam_app_lib/src/state/mod.rs | 3 +- .../rust/ockam/ockam_command/src/admin/mod.rs | 6 +- .../ockam_command/src/admin/subscription.rs | 9 +- .../ockam/ockam_command/src/authenticated.rs | 0 .../ockam_command/src/authority/create.rs | 42 ++- .../ockam/ockam_command/src/authority/mod.rs | 6 +- .../rust/ockam/ockam_command/src/command.rs | 260 +++++++++++++++--- .../ockam/ockam_command/src/command_events.rs | 83 +++--- .../ockam_command/src/command_global_opts.rs | 192 +------------ .../ockam_command/src/credential/issue.rs | 9 +- .../ockam_command/src/credential/list.rs | 14 +- .../ockam/ockam_command/src/credential/mod.rs | 11 +- .../ockam_command/src/credential/store.rs | 9 +- .../ockam_command/src/credential/verify.rs | 9 +- .../ockam/ockam_command/src/enroll/command.rs | 9 +- .../ockam/ockam_command/src/entry_point.rs | 81 +++--- .../src/environment/static/env_info.txt | 2 +- .../src/flow_control/add_consumer.rs | 10 +- .../ockam_command/src/flow_control/mod.rs | 6 +- .../ockam_command/src/identity/create.rs | 2 +- .../ockam_command/src/identity/default.rs | 9 +- .../ockam_command/src/identity/delete.rs | 9 +- .../ockam/ockam_command/src/identity/list.rs | 9 +- .../ockam/ockam_command/src/identity/mod.rs | 14 +- .../ockam/ockam_command/src/identity/show.rs | 8 +- .../src/influxdb/inlet/create.rs | 4 +- .../ockam_command/src/influxdb/inlet/mod.rs | 8 +- .../src/influxdb/outlet/create.rs | 2 +- .../ockam_command/src/influxdb/outlet/mod.rs | 8 +- .../src/kafka/consumer/create.rs | 13 +- .../src/kafka/consumer/delete.rs | 7 +- .../ockam_command/src/kafka/consumer/list.rs | 7 +- .../ockam_command/src/kafka/consumer/mod.rs | 10 +- .../ockam_command/src/kafka/inlet/create.rs | 4 +- .../ockam_command/src/kafka/inlet/delete.rs | 4 +- .../ockam_command/src/kafka/inlet/list.rs | 2 +- .../ockam_command/src/kafka/inlet/mod.rs | 12 +- .../ockam_command/src/kafka/inlet/show.rs | 2 +- .../ockam_command/src/kafka/outlet/create.rs | 4 +- .../ockam_command/src/kafka/outlet/delete.rs | 4 +- .../ockam_command/src/kafka/outlet/list.rs | 2 +- .../ockam_command/src/kafka/outlet/mod.rs | 11 +- .../ockam_command/src/kafka/outlet/show.rs | 2 +- .../src/kafka/producer/create.rs | 13 +- .../src/kafka/producer/delete.rs | 7 +- .../ockam_command/src/kafka/producer/list.rs | 7 +- .../ockam_command/src/kafka/producer/mod.rs | 10 +- .../ockam/ockam_command/src/lease/create.rs | 2 +- .../ockam/ockam_command/src/lease/list.rs | 2 +- .../rust/ockam/ockam_command/src/lease/mod.rs | 20 +- .../ockam/ockam_command/src/lease/revoke.rs | 2 +- .../ockam/ockam_command/src/lease/show.rs | 2 +- .../ockam/ockam_command/src/message/mod.rs | 6 +- .../ockam/ockam_command/src/message/send.rs | 2 +- .../ockam_command/src/migrate_database/mod.rs | 9 +- .../ockam/ockam_command/src/node/create.rs | 164 ++++------- .../src/node/create/background.rs | 17 +- .../ockam_command/src/node/create/config.rs | 25 +- .../src/node/create/foreground.rs | 89 +++--- .../src/node/create/node_callback.rs | 55 ++++ .../ockam/ockam_command/src/node/default.rs | 9 +- .../ockam/ockam_command/src/node/delete.rs | 10 +- .../rust/ockam/ockam_command/src/node/list.rs | 9 +- .../rust/ockam/ockam_command/src/node/logs.rs | 8 +- .../rust/ockam/ockam_command/src/node/mod.rs | 19 +- .../rust/ockam/ockam_command/src/node/show.rs | 150 +--------- .../ockam/ockam_command/src/node/start.rs | 26 +- .../rust/ockam/ockam_command/src/node/stop.rs | 10 +- .../rust/ockam/ockam_command/src/node/util.rs | 26 +- .../ockam/ockam_command/src/policy/create.rs | 2 +- .../ockam/ockam_command/src/policy/delete.rs | 9 +- .../ockam/ockam_command/src/policy/list.rs | 9 +- .../ockam/ockam_command/src/policy/mod.rs | 15 +- .../ockam/ockam_command/src/policy/show.rs | 9 +- .../src/project/addon/configure_influxdb.rs | 9 +- .../src/project/addon/configure_kafka.rs | 9 +- .../project/addon/configure_kafka/aiven.rs | 17 +- .../addon/configure_kafka/confluent.rs | 17 +- .../addon/configure_kafka/instaclustr.rs | 17 +- .../project/addon/configure_kafka/redpanda.rs | 17 +- .../addon/configure_kafka/warpstream.rs | 17 +- .../src/project/addon/configure_okta.rs | 9 +- .../src/project/addon/disable.rs | 9 +- .../ockam_command/src/project/addon/list.rs | 9 +- .../ockam_command/src/project/addon/mod.rs | 26 +- .../ockam/ockam_command/src/project/create.rs | 13 +- .../ockam/ockam_command/src/project/delete.rs | 9 +- .../ockam/ockam_command/src/project/enroll.rs | 2 +- .../ockam/ockam_command/src/project/import.rs | 9 +- .../ockam/ockam_command/src/project/info.rs | 9 +- .../ockam/ockam_command/src/project/list.rs | 9 +- .../ockam/ockam_command/src/project/mod.rs | 25 +- .../ockam/ockam_command/src/project/show.rs | 6 +- .../ockam/ockam_command/src/project/ticket.rs | 6 +- .../ockam_command/src/project/version.rs | 9 +- .../ockam_command/src/project_admin/add.rs | 2 +- .../ockam_command/src/project_admin/delete.rs | 2 +- .../ockam_command/src/project_admin/list.rs | 2 +- .../ockam_command/src/project_admin/mod.rs | 10 +- .../ockam_command/src/project_member/add.rs | 2 +- .../src/project_member/delete.rs | 2 +- .../ockam_command/src/project_member/list.rs | 2 +- .../src/project_member/list_ids.rs | 2 +- .../ockam_command/src/project_member/mod.rs | 12 +- .../ockam_command/src/project_member/show.rs | 2 +- .../ockam/ockam_command/src/relay/create.rs | 2 +- .../ockam/ockam_command/src/relay/delete.rs | 9 +- .../ockam/ockam_command/src/relay/list.rs | 9 +- .../rust/ockam/ockam_command/src/relay/mod.rs | 12 +- .../ockam/ockam_command/src/relay/show.rs | 8 +- .../src/rendezvous/create/create.rs | 12 +- .../src/rendezvous/get_my_address.rs | 2 +- .../ockam/ockam_command/src/rendezvous/mod.rs | 8 +- .../rust/ockam/ockam_command/src/reset/mod.rs | 10 +- .../rust/ockam/ockam_command/src/run/mod.rs | 9 +- .../src/run/parser/resource/traits.rs | 2 +- .../src/secure_channel/create.rs | 10 +- .../src/secure_channel/delete.rs | 13 +- .../ockam_command/src/secure_channel/list.rs | 11 +- .../src/secure_channel/listener/create.rs | 48 +--- .../src/secure_channel/listener/delete.rs | 10 +- .../src/secure_channel/listener/list.rs | 9 +- .../src/secure_channel/listener/mod.rs | 15 +- .../src/secure_channel/listener/show.rs | 9 +- .../ockam_command/src/secure_channel/mod.rs | 11 +- .../ockam_command/src/secure_channel/show.rs | 9 +- .../ockam/ockam_command/src/service/list.rs | 10 +- .../ockam/ockam_command/src/service/mod.rs | 11 +- .../ockam/ockam_command/src/service/start.rs | 10 +- .../ockam/ockam_command/src/share/accept.rs | 9 +- .../ockam/ockam_command/src/share/create.rs | 9 +- .../ockam/ockam_command/src/share/list.rs | 9 +- .../rust/ockam/ockam_command/src/share/mod.rs | 14 +- .../ockam/ockam_command/src/share/service.rs | 9 +- .../ockam/ockam_command/src/share/show.rs | 9 +- .../ockam/ockam_command/src/sidecar/mod.rs | 8 +- .../src/sidecar/secure_relay_inlet.rs | 9 +- .../src/sidecar/secure_relay_outlet.rs | 9 +- .../ockam/ockam_command/src/space/create.rs | 2 +- .../ockam/ockam_command/src/space/delete.rs | 2 +- .../ockam/ockam_command/src/space/list.rs | 2 +- .../rust/ockam/ockam_command/src/space/mod.rs | 13 +- .../ockam/ockam_command/src/space/show.rs | 2 +- .../ockam_command/src/space_admin/add.rs | 2 +- .../ockam_command/src/space_admin/delete.rs | 2 +- .../ockam_command/src/space_admin/list.rs | 2 +- .../ockam_command/src/space_admin/mod.rs | 10 +- .../ockam/ockam_command/src/status/mod.rs | 4 +- .../ockam/ockam_command/src/subcommand.rs | 106 ++++--- .../ockam/ockam_command/src/subscription.rs | 9 +- .../src/tcp/connection/create.rs | 4 +- .../src/tcp/connection/delete.rs | 9 +- .../ockam_command/src/tcp/connection/list.rs | 10 +- .../ockam_command/src/tcp/connection/mod.rs | 12 +- .../ockam_command/src/tcp/connection/show.rs | 9 +- .../ockam_command/src/tcp/inlet/create.rs | 6 +- .../ockam_command/src/tcp/inlet/delete.rs | 4 +- .../ockam/ockam_command/src/tcp/inlet/list.rs | 9 +- .../ockam/ockam_command/src/tcp/inlet/mod.rs | 12 +- .../ockam/ockam_command/src/tcp/inlet/show.rs | 4 +- .../ockam_command/src/tcp/listener/create.rs | 9 +- .../ockam_command/src/tcp/listener/delete.rs | 9 +- .../ockam_command/src/tcp/listener/list.rs | 10 +- .../ockam_command/src/tcp/listener/mod.rs | 12 +- .../ockam_command/src/tcp/listener/show.rs | 9 +- .../ockam_command/src/tcp/outlet/create.rs | 6 +- .../ockam_command/src/tcp/outlet/delete.rs | 4 +- .../ockam_command/src/tcp/outlet/list.rs | 10 +- .../ockam/ockam_command/src/tcp/outlet/mod.rs | 11 +- .../ockam_command/src/tcp/outlet/show.rs | 6 +- .../rust/ockam/ockam_command/src/upgrade.rs | 22 +- .../rust/ockam/ockam_command/src/util/api.rs | 29 -- .../rust/ockam/ockam_command/src/util/mod.rs | 126 +-------- .../ockam/ockam_command/src/vault/create.rs | 2 +- .../ockam/ockam_command/src/vault/delete.rs | 9 +- .../ockam/ockam_command/src/vault/list.rs | 9 +- .../rust/ockam/ockam_command/src/vault/mod.rs | 14 +- .../ockam_command/src/vault/move_vault.rs | 9 +- .../ockam/ockam_command/src/vault/show.rs | 9 +- .../ockam/ockam_command/src/worker/list.rs | 10 +- .../ockam/ockam_command/src/worker/mod.rs | 6 +- .../tests/bats/local/authority.bats | 5 +- .../rust/ockam/ockam_node/Cargo.toml | 2 - .../rust/ockam/ockam_node/src/executor.rs | 23 -- .../rust/ockam/ockam_node/src/node.rs | 5 - .../src/storage/database/sqlx_database.rs | 2 + .../ockam/ockam_transport_core/src/error.rs | 4 + .../ockam/ockam_transport_tcp/src/options.rs | 20 ++ .../src/portal/portal_worker.rs | 2 +- .../src/transport/common.rs | 29 +- .../src/transport/connection.rs | 2 +- tools/stress-test/src/main.rs | 7 +- 206 files changed, 1369 insertions(+), 2108 deletions(-) delete mode 100644 implementations/rust/ockam/ockam_api/tests/common/trace_code.rs delete mode 100644 implementations/rust/ockam/ockam_command/src/authenticated.rs create mode 100644 implementations/rust/ockam/ockam_command/src/node/create/node_callback.rs diff --git a/Cargo.lock b/Cargo.lock index 595f72abdc7..cf228a2bb31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4903,7 +4903,6 @@ dependencies = [ "ockam_executor", "ockam_macros", "ockam_transport_core", - "once_cell", "opentelemetry", "percent-encoding", "regex", diff --git a/implementations/rust/ockam/ockam_api/src/cli_state/cli_state.rs b/implementations/rust/ockam/ockam_api/src/cli_state/cli_state.rs index bd96eec0e9b..8cc70d47a74 100644 --- a/implementations/rust/ockam/ockam_api/src/cli_state/cli_state.rs +++ b/implementations/rust/ockam/ockam_api/src/cli_state/cli_state.rs @@ -4,8 +4,7 @@ use tokio::sync::broadcast::{channel, Receiver, Sender}; use ockam::SqlxDatabase; use ockam_core::env::get_env_with_default; -use ockam_node::database::{DatabaseConfiguration, DatabaseType, OCKAM_SQLITE_IN_MEMORY}; -use ockam_node::Executor; +use ockam_node::database::{DatabaseConfiguration, DatabaseType}; use crate::cli_state::error::Result; use crate::cli_state::CliStateError; @@ -51,11 +50,6 @@ pub struct CliState { } impl CliState { - /// Create a new CliState in a given directory - pub fn new(mode: CliStateMode) -> Result { - Executor::execute_future(Self::create(mode))? - } - pub fn dir(&self) -> Result { match &self.mode { CliStateMode::Persistent(dir) => Ok(dir.to_path_buf()), @@ -127,14 +121,14 @@ impl CliState { impl CliState { /// Return a new CliState using a default directory to store its data or /// using an in-memory storage if the OCKAM_SQLITE_IN_MEMORY environment variable is set to true - pub fn from_env() -> Result { - let in_memory = get_env_with_default::(OCKAM_SQLITE_IN_MEMORY, false)?; + pub async fn new(in_memory: bool) -> Result { let mode = if in_memory { CliStateMode::InMemory } else { CliStateMode::with_default_dir()? }; - Self::new(mode) + + Self::create(mode).await } /// Stop nodes and remove all the directories storing state @@ -182,7 +176,7 @@ impl CliState { /// Backup and reset is used to save aside /// some corrupted local state for later inspection and then reset the state. /// The database is backed-up only if it is a SQLite database. - pub fn backup_and_reset() -> Result<()> { + pub async fn backup_and_reset() -> Result<()> { let dir = Self::default_dir()?; // Reset backup directory @@ -202,7 +196,7 @@ impl CliState { // Reset state Self::delete_at(&dir)?; - Self::new(CliStateMode::Persistent(dir.clone()))?; + Self::create(CliStateMode::Persistent(dir.clone())).await?; let backup_dir = CliState::backup_default_dir()?; eprintln!("The {dir:?} directory has been reset and has been backed up to {backup_dir:?}"); @@ -234,15 +228,20 @@ impl CliState { std::fs::create_dir_all(dir.as_path())?; } let database = SqlxDatabase::create(&Self::make_database_configuration(&mode)?).await?; - let configuration = Self::make_application_database_configuration(&mode)?; - let application_database = - SqlxDatabase::create_application_database(&configuration).await?; debug!("Opened the main database with options {:?}", database); + + // TODO: This should not be called unless we're running the App + let application_database = SqlxDatabase::create_application_database( + &Self::make_application_database_configuration(&mode)?, + ) + .await?; debug!( "Opened the application database with options {:?}", application_database ); + let (notifications, _) = channel::(NOTIFICATIONS_CHANNEL_CAPACITY); + let state = Self { mode, database, @@ -254,6 +253,7 @@ impl CliState { exporting_enabled: ExportingEnabled::Off, notifications, }; + Ok(state) } diff --git a/implementations/rust/ockam/ockam_api/src/logs/env_variables.rs b/implementations/rust/ockam/ockam_api/src/logs/env_variables.rs index 2f511b7dcb2..693fc1ce584 100644 --- a/implementations/rust/ockam/ockam_api/src/logs/env_variables.rs +++ b/implementations/rust/ockam/ockam_api/src/logs/env_variables.rs @@ -21,7 +21,7 @@ pub(crate) const OCKAM_LOG_MAX_FILES: &str = "OCKAM_LOG_MAX_FILES"; /// Log format. Accepted values, see LogFormat. For example: pretty, json, default pub(crate) const OCKAM_LOG_FORMAT: &str = "OCKAM_LOG_FORMAT"; -/// Filter for log messages based on crate names. Accepted values: 'all', 'default', 'comma-separated strings'. For example: ockam_core,ockam_api +/// Filter for log messages based on crate names. Accepted values: 'all' or 'comma-separated strings'. For example: ockam_core,ockam_api pub(crate) const OCKAM_LOG_CRATES_FILTER: &str = "OCKAM_LOG_CRATES_FILTER"; /// diff --git a/implementations/rust/ockam/ockam_api/src/logs/exporting_configuration.rs b/implementations/rust/ockam/ockam_api/src/logs/exporting_configuration.rs index f5cff5a5006..7846936c4a1 100644 --- a/implementations/rust/ockam/ockam_api/src/logs/exporting_configuration.rs +++ b/implementations/rust/ockam/ockam_api/src/logs/exporting_configuration.rs @@ -7,7 +7,6 @@ use crate::logs::ExportingEnabled; use crate::CliState; use ockam_core::env::{get_env_with_default, FromString}; use ockam_core::errcode::{Kind, Origin}; -use ockam_node::Executor; use std::env::current_exe; use std::fmt::{Display, Formatter}; use std::net::{SocketAddr, ToSocketAddrs}; @@ -116,14 +115,15 @@ impl ExportingConfiguration { /// Create a tracing configuration for a user command running in the foreground. /// (meaning that the process will shut down once the command has been executed) - pub fn foreground(state: &CliState) -> ockam_core::Result { - match opentelemetry_endpoint(state)? { + pub async fn foreground(state: &CliState) -> ockam_core::Result { + match opentelemetry_endpoint(state).await? { None => ExportingConfiguration::off(), Some(endpoint) => Ok(ExportingConfiguration { enabled: exporting_enabled( &endpoint, opentelemetry_endpoint_foreground_connection_timeout()?, - )?, + ) + .await?, span_export_timeout: span_export_timeout()?, log_export_timeout: log_export_timeout()?, span_export_scheduled_delay: foreground_span_export_scheduled_delay()?, @@ -139,14 +139,15 @@ impl ExportingConfiguration { } /// Create a tracing configuration for a background node - pub fn background(state: &CliState) -> ockam_core::Result { - match opentelemetry_endpoint(state)? { + pub async fn background(state: &CliState) -> ockam_core::Result { + match opentelemetry_endpoint(state).await? { None => ExportingConfiguration::off(), Some(endpoint) => Ok(ExportingConfiguration { enabled: exporting_enabled( &endpoint, opentelemetry_endpoint_background_connection_timeout()?, - )?, + ) + .await?, span_export_timeout: span_export_timeout()?, log_export_timeout: log_export_timeout()?, span_export_scheduled_delay: background_span_export_scheduled_delay()?, @@ -254,11 +255,11 @@ fn print_debug(message: impl Into) { /// - Exporting has not been deactivated by the user /// - The opentelemetry endpoint is accessible /// -fn exporting_enabled( +async fn exporting_enabled( endpoint: &OpenTelemetryEndpoint, connection_check_timeout: Duration, ) -> ockam_core::Result { - if is_endpoint_accessible(&endpoint.url(), connection_check_timeout) { + if is_endpoint_accessible(&endpoint.url(), connection_check_timeout).await { print_debug("Exporting is enabled"); Ok(ExportingEnabled::On) } else { @@ -275,23 +276,37 @@ fn exporting_enabled( } /// Return true if the endpoint can be accessed with a TCP connection -fn is_endpoint_accessible(url: &Url, connection_check_timeout: Duration) -> bool { +async fn is_endpoint_accessible(url: &Url, connection_check_timeout: Duration) -> bool { match to_socket_addr(url) { Some(address) => { let retries = FibonacciBackoff::from_millis(100); let now = Instant::now(); + // TODO: Not sure we need to retry really, also maybe it could happen in the background + // to not slow things down for timeout_duration in retries { print_debug(format!( "trying to connect to {address} in {timeout_duration:?}" )); - if std::net::TcpStream::connect_timeout(&address, timeout_duration).is_ok() { - return true; - } else { - if now.elapsed() >= connection_check_timeout { - return false; - }; - std::thread::sleep(timeout_duration); + + let res = tokio::time::timeout( + timeout_duration, + tokio::net::TcpStream::connect(&address), + ) + .await; + + match res { + Ok(res) => { + if res.is_ok() { + return true; + } + } + Err(_) => { + if now.elapsed() >= connection_check_timeout { + return false; + }; + tokio::time::sleep(timeout_duration).await; + } } } false @@ -324,36 +339,27 @@ fn to_socket_addr(url: &Url) -> Option { /// Return the tracing endpoint, defined by an environment variable /// If the endpoint can be established with an Ockam portal to the opentelemetry-relay created in the project /// use that URL, otherwise use the HTTPS endpoint -fn opentelemetry_endpoint(state: &CliState) -> ockam_core::Result> { - if !is_exporting_set()? { - print_debug("Exporting is turned off"); - Ok(None) - } else { - let state = state.clone(); - match Executor::execute_future(async move { - // if a project is defined try to use the OpenTelemetry portal - // and if we allow traces to be exported via a portal - if state.projects().get_default_project().await.is_ok() - && is_exporting_via_portal_set()? - { - print_debug("A default project exists. Getting the project export endpoint"); - get_project_endpoint_url(&state).await - } else { - print_debug("A default project does not exist. Getting the default HTTPs endpoint"); - get_https_endpoint() - } - }) { - Ok(Ok(url)) => Ok(Some(url)), - Ok(Err(e)) => { - print_debug(format!( - "There was an issue when setting up the exporting of traces: {e:?}" - )); - Ok(None) - } - Err(e) => { - print_debug(format!("There was an issue when running the code setting up the exporting of traces: {e:?}")); - Ok(None) - } +async fn opentelemetry_endpoint( + state: &CliState, +) -> ockam_core::Result> { + let res = { + // if a project is defined try to use the OpenTelemetry portal + // and if we allow traces to be exported via a portal + if state.projects().get_default_project().await.is_ok() && is_exporting_via_portal_set()? { + print_debug("A default project exists. Getting the project export endpoint"); + get_project_endpoint_url(state).await + } else { + print_debug("A default project does not exist. Getting the default HTTPs endpoint"); + get_https_endpoint() + } + }; + match res { + Ok(url) => Ok(Some(url)), + Err(e) => { + print_debug(format!( + "There was an issue when setting up the exporting of traces: {e:?}" + )); + Ok(None) } } } diff --git a/implementations/rust/ockam/ockam_api/src/logs/setup.rs b/implementations/rust/ockam/ockam_api/src/logs/setup.rs index 2d02ba0c43c..d5338debc81 100644 --- a/implementations/rust/ockam/ockam_api/src/logs/setup.rs +++ b/implementations/rust/ockam/ockam_api/src/logs/setup.rs @@ -24,7 +24,6 @@ use tracing_subscriber::util::SubscriberInitExt; use tracing_subscriber::{fmt, layer::SubscriberExt, registry}; use crate::cli_state::journeys::APP_NAME; -use ockam_node::Executor; use crate::logs::tracing_guard::TracingGuard; use crate::logs::{ @@ -189,17 +188,14 @@ fn create_log_exporter( let log_export_timeout = exporting_configuration.log_export_timeout(); let endpoint = exporting_configuration.opentelemetry_endpoint().to_string(); - Executor::execute_future(async move { - opentelemetry_otlp::new_exporter() - .tonic() - .with_endpoint(endpoint) - .with_timeout(log_export_timeout) - .with_metadata(get_otlp_headers()) - .with_tls_config(tonic::transport::ClientTlsConfig::new().with_native_roots()) - .build_log_exporter() - .expect("failed to create the log exporter") - }) - .expect("can't create a log exporter") + opentelemetry_otlp::new_exporter() + .tonic() + .with_endpoint(endpoint) + .with_timeout(log_export_timeout) + .with_metadata(get_otlp_headers()) + .with_tls_config(tonic::transport::ClientTlsConfig::new().with_native_roots()) + .build_log_exporter() + .expect("failed to create the log exporter") } /// Create a span exporter @@ -210,17 +206,14 @@ fn create_span_exporter( let trace_export_timeout = exporting_configuration.span_export_timeout(); let endpoint = exporting_configuration.opentelemetry_endpoint().to_string(); - Executor::execute_future(async move { - opentelemetry_otlp::new_exporter() - .tonic() - .with_endpoint(endpoint.clone()) - .with_timeout(trace_export_timeout) - .with_metadata(get_otlp_headers()) - .with_tls_config(tonic::transport::ClientTlsConfig::new().with_native_roots()) - .build_span_exporter() - .expect("failed to create the span exporter") - }) - .expect("can't create a span exporter") + opentelemetry_otlp::new_exporter() + .tonic() + .with_endpoint(endpoint.clone()) + .with_timeout(trace_export_timeout) + .with_metadata(get_otlp_headers()) + .with_tls_config(tonic::transport::ClientTlsConfig::new().with_native_roots()) + .build_span_exporter() + .expect("failed to create the span exporter") } /// Create the tracing layer for OpenTelemetry @@ -246,25 +239,23 @@ fn create_opentelemetry_tracing_layer< .build(); let is_ockam_developer = exporting_configuration.is_ockam_developer(); let span_export_cutoff = exporting_configuration.span_export_cutoff(); - Executor::execute_future(async move { - let trace_config = - opentelemetry_sdk::trace::Config::default().with_resource(make_resource(app)); - let (tracer, tracer_provider) = create_tracer( - trace_config, - batch_config, - OckamSpanExporter::new( - span_exporter, - node_name, - is_ockam_developer, - span_export_cutoff, - ), - ); - ( - tracing_opentelemetry::layer().with_tracer(tracer), - tracer_provider, - ) - }) - .expect("Failed to build the tracing layer") + + let trace_config = + opentelemetry_sdk::trace::Config::default().with_resource(make_resource(app)); + let (tracer, tracer_provider) = create_tracer( + trace_config, + batch_config, + OckamSpanExporter::new( + span_exporter, + node_name, + is_ockam_developer, + span_export_cutoff, + ), + ); + ( + tracing_opentelemetry::layer().with_tracer(tracer), + tracer_provider, + ) } /// Create the logging layer for OpenTelemetry @@ -282,28 +273,25 @@ fn create_opentelemetry_logging_layer( let log_export_scheduled_delay = exporting_configuration.log_export_scheduled_delay(); let log_export_queue_size = exporting_configuration.log_export_queue_size(); let log_export_cutoff = exporting_configuration.log_export_cutoff(); - Executor::execute_future(async move { - let resource = make_resource(app); - let batch_config = logs::BatchConfigBuilder::default() - .with_max_export_timeout(log_export_timeout) - .with_scheduled_delay(log_export_scheduled_delay) - .with_max_queue_size(log_export_queue_size as usize) - .build(); - - let log_exporter = OckamLogExporter::new(log_exporter, log_export_cutoff); - - let log_processor = - BatchLogProcessor::builder(log_exporter, opentelemetry_sdk::runtime::Tokio) - .with_batch_config(batch_config) - .build(); - let provider = LoggerProvider::builder() - .with_resource(resource) - .with_log_processor(log_processor) - .build(); - let layer = OpenTelemetryTracingBridge::new(&provider); - (layer, provider) - }) - .expect("Failed to build the logging layer") + + let resource = make_resource(app); + let batch_config = logs::BatchConfigBuilder::default() + .with_max_export_timeout(log_export_timeout) + .with_scheduled_delay(log_export_scheduled_delay) + .with_max_queue_size(log_export_queue_size as usize) + .build(); + + let log_exporter = OckamLogExporter::new(log_exporter, log_export_cutoff); + + let log_processor = BatchLogProcessor::builder(log_exporter, opentelemetry_sdk::runtime::Tokio) + .with_batch_config(batch_config) + .build(); + let provider = LoggerProvider::builder() + .with_resource(resource) + .with_log_processor(log_processor) + .build(); + let layer = OpenTelemetryTracingBridge::new(&provider); + (layer, provider) } /// Create the appending layer for OpenTelemetry diff --git a/implementations/rust/ockam/ockam_api/src/logs/tracing_guard.rs b/implementations/rust/ockam/ockam_api/src/logs/tracing_guard.rs index a69c7094e80..9060aa7bedc 100644 --- a/implementations/rust/ockam/ockam_api/src/logs/tracing_guard.rs +++ b/implementations/rust/ockam/ockam_api/src/logs/tracing_guard.rs @@ -45,19 +45,27 @@ impl TracingGuard { } } - pub fn shutdown(&self) { - global::shutdown_tracer_provider(); + pub async fn shutdown(self) { + _ = tokio::task::spawn_blocking(|| { + global::shutdown_tracer_provider(); + }) + .await } /// Export the current batches of spans and log records /// This is used right after a background node has started to get the first logs /// and in tests otherwise - pub fn force_flush(&self) { - if let Some(logger_provider) = self.logger_provider.as_ref() { - logger_provider.force_flush(); - } - if let Some(tracer_provider) = self.tracer_provider.as_ref() { - tracer_provider.force_flush(); - } + pub async fn force_flush(&self) { + let logger_provider = self.logger_provider.clone(); + let tracer_provider = self.tracer_provider.clone(); + _ = tokio::task::spawn_blocking(|| { + if let Some(logger_provider) = logger_provider { + logger_provider.force_flush(); + } + if let Some(tracer_provider) = tracer_provider { + tracer_provider.force_flush(); + } + }) + .await; } } diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/background_node_client.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/background_node_client.rs index c2985e48bf7..d8eedbdc014 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/background_node_client.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/background_node_client.rs @@ -80,7 +80,7 @@ impl BackgroundNodeClient { } pub async fn delete(&self) -> miette::Result<()> { - Ok(self.cli_state.delete_node(&self.node_name()).await?) + Ok(self.cli_state.delete_node(self.node_name()).await?) } // Set a different node name @@ -89,8 +89,8 @@ impl BackgroundNodeClient { self } - pub fn node_name(&self) -> String { - self.node_name.clone() + pub fn node_name(&self) -> &str { + &self.node_name } /// Use a default timeout for making requests @@ -195,24 +195,22 @@ impl BackgroundNodeClient { res } - /// This method succeeds if a TCP connection can be established with the node - pub async fn is_accessible(&self, ctx: &Context) -> miette::Result<()> { - self.create_tcp_connection() - .await? - .stop(ctx) - .into_diagnostic() - } - /// Make a route to the node and connect using TCP - async fn create_route(&self) -> miette::Result<(TcpConnection, Route)> { - let tcp_connection = self.create_tcp_connection().await?; + async fn create_route( + &self, + timeout: Option, + ) -> miette::Result<(TcpConnection, Route)> { + let tcp_connection = self.create_tcp_connection(timeout).await?; let route = tcp_connection.sender_address().clone() + self.to.clone(); debug!("Sending requests to {route}"); Ok((tcp_connection, route)) } /// Create a TCP connection to the node - async fn create_tcp_connection(&self) -> miette::Result { + async fn create_tcp_connection( + &self, + timeout: Option, + ) -> miette::Result { let node_info = self.cli_state.get_node(&self.node_name).await?; let tcp_listener_address = node_info .tcp_listener_address() @@ -223,7 +221,10 @@ impl BackgroundNodeClient { .to_string(); self.tcp_transport - .connect(&tcp_listener_address, TcpConnectionOptions::new()) + .connect( + &tcp_listener_address, + TcpConnectionOptions::new().set_timeout(timeout), + ) .await .map_err(|_| { miette!( @@ -245,7 +246,7 @@ impl BackgroundNodeClient { &self, timeout: Option, ) -> miette::Result<(TcpConnection, Client)> { - let (tcp_connection, route) = self.create_route().await?; + let (tcp_connection, route) = self.create_route(timeout).await?; Ok((tcp_connection, Client::new(&route, timeout))) } } diff --git a/implementations/rust/ockam/ockam_api/src/nodes/service/in_memory_node.rs b/implementations/rust/ockam/ockam_api/src/nodes/service/in_memory_node.rs index 8e9d6b86fe6..404b1c65cc0 100644 --- a/implementations/rust/ockam/ockam_api/src/nodes/service/in_memory_node.rs +++ b/implementations/rust/ockam/ockam_api/src/nodes/service/in_memory_node.rs @@ -60,6 +60,8 @@ impl Drop for InMemoryNode { // stops. Except if they have been started with the `ockam node create` command // because in that case they can be restarted if !self.persistent { + // TODO: Should be a better way to do that, e.g. send a signal to a background async + // task to do the job, or shutdown the node manually before dropping this value executor::block_on(async { let result = self.cli_state.remove_node(&self.node_name).await; if let Err(err) = result { diff --git a/implementations/rust/ockam/ockam_api/src/ui/terminal/notification.rs b/implementations/rust/ockam/ockam_api/src/ui/terminal/notification.rs index 7ab4c2d014b..968151b9e56 100644 --- a/implementations/rust/ockam/ockam_api/src/ui/terminal/notification.rs +++ b/implementations/rust/ockam/ockam_api/src/ui/terminal/notification.rs @@ -94,14 +94,14 @@ impl NotificationHandler { if self.stop.load(Acquire) { // Drain the channel while let Ok(notification) = self.rx.try_recv() { - self.handle_notification(notification).await; + self.handle_notification(notification); } break; } } notification = self.rx.recv() => { if let Ok(notification) = notification { - self.handle_notification(notification).await; + self.handle_notification(notification); } // The channel was closed else { @@ -113,7 +113,7 @@ impl NotificationHandler { }); } - async fn handle_notification(&mut self, notification: Notification) { + fn handle_notification(&mut self, notification: Notification) { match notification { Notification::Message(contents) => { let _ = self.terminal.write_line(contents); diff --git a/implementations/rust/ockam/ockam_api/tests/common/trace_code.rs b/implementations/rust/ockam/ockam_api/tests/common/trace_code.rs deleted file mode 100644 index 9d6a5a4e607..00000000000 --- a/implementations/rust/ockam/ockam_api/tests/common/trace_code.rs +++ /dev/null @@ -1,77 +0,0 @@ -use crate::common::test_spans::Trace; -use ockam_api::logs::{ExportingConfiguration, LoggingConfiguration, LoggingTracing}; -use ockam_api::CliState; -use ockam_core::{AsyncTryClone, OpenTelemetryContext}; -use ockam_node::{Context, NodeBuilder}; -use opentelemetry::global; -use opentelemetry::trace::{FutureExt, Tracer}; -use opentelemetry_sdk::export::trace::SpanData; -use opentelemetry_sdk::testing::logs::InMemoryLogsExporter; -use opentelemetry_sdk::testing::trace::InMemorySpanExporter; -use std::future::Future; - -/// Run an async function using a tracer and return: -/// -/// - the return value of the function -/// - all the exported spans -pub fn trace_code( - state: &CliState, - f: impl Fn(Context) -> F + Send + Sync + 'static, -) -> (F::Output, Vec) -where - F: Future + Send + 'static, - F::Output: Send + 'static, -{ - let spans_exporter = InMemorySpanExporter::default(); - let guard = LoggingTracing::setup_with_exporters( - spans_exporter.clone(), - InMemoryLogsExporter::default(), - &LoggingConfiguration::off() - .unwrap() - .set_all_crates() - .set_log_level(tracing_core::metadata::Level::TRACE), - &ExportingConfiguration::foreground(state).unwrap(), - "test", - None, - ); - - let (mut ctx, mut executor) = NodeBuilder::new().build(); - - let tracer = global::tracer("ockam-test"); - let result = executor - .execute_no_abort(async move { - let result = tracer - .in_span("root", |_| { - ctx.set_tracing_context(OpenTelemetryContext::current()); - async { f(ctx.async_try_clone().await.unwrap()).await }.with_current_context() - }) - .await; - let _ = ctx.stop().await; - result - }) - .unwrap(); - - // get the exported spans - guard.force_flush(); - let spans = spans_exporter.get_finished_spans().unwrap(); - (result, spans) -} - -/// Return a string displaying the traces for all the given spans -pub fn display_traces(spans: Vec) -> String { - let mut traces = Trace::from_span_data(spans); - traces.sort_by_key(|t| t.to_string()); - - // remove some uninteresting traces based on their root name - traces.retain(|t| { - !["start", "shutdown", "initialize", "process"] - .iter() - .any(|v| t.0.to_string().split('\n').collect::>()[0].ends_with(v)) - }); - - traces - .iter() - .map(|t| t.to_string()) - .collect::>() - .join("\n") -} diff --git a/implementations/rust/ockam/ockam_api/tests/journeys.rs b/implementations/rust/ockam/ockam_api/tests/journeys.rs index d96b699a836..aaa0482c474 100644 --- a/implementations/rust/ockam/ockam_api/tests/journeys.rs +++ b/implementations/rust/ockam/ockam_api/tests/journeys.rs @@ -4,9 +4,8 @@ use ockam_api::cli_state::journeys::{ }; use ockam_api::logs::{ExportingConfiguration, LoggingConfiguration, LoggingTracing}; use ockam_api::CliState; -use ockam_node::Executor; -use opentelemetry::global; -use opentelemetry::trace::{FutureExt, Tracer}; +use opentelemetry::trace::{FutureExt, TraceContextExt, Tracer}; +use opentelemetry::{global, Context}; use opentelemetry_sdk::export::trace::SpanData; use opentelemetry_sdk::testing::logs::InMemoryLogsExporter; use opentelemetry_sdk::testing::trace::InMemorySpanExporter; @@ -19,17 +18,14 @@ use tempfile::NamedTempFile; /// This test needs to be an integration test /// It needs to run in isolation because /// it sets up some global spans / logs exporters that might interact with other tests -#[test] -fn test_create_journey_event() { - let cli = Executor::execute_future(async { - let db_file = NamedTempFile::new().unwrap(); - let cli_state_directory = db_file.path().parent().unwrap().join(random_name()); - CliState::create(CliStateMode::Persistent(cli_state_directory)) - .await - .unwrap() - .set_tracing_enabled(true) - }) - .unwrap(); +#[tokio::test] +async fn test_create_journey_event() { + let db_file = NamedTempFile::new().unwrap(); + let cli_state_directory = db_file.path().parent().unwrap().join(random_name()); + let cli = CliState::create(CliStateMode::Persistent(cli_state_directory)) + .await + .unwrap() + .set_tracing_enabled(true); let spans_exporter = InMemorySpanExporter::default(); let logs_exporter = InMemoryLogsExporter::default(); @@ -40,37 +36,33 @@ fn test_create_journey_event() { &LoggingConfiguration::off() .unwrap() .set_crates(&["ockam_api"]), - &ExportingConfiguration::foreground(&cli).unwrap(), + &ExportingConfiguration::foreground(&cli).await.unwrap(), "test", None, ); let tracer = global::tracer("ockam-test"); - let result = tracer.in_span("user event", |cx| { - let _guard = cx.with_value(Utc::now()).attach(); + let span = tracer.start("user event"); + let cx = Context::current_with_span(span); - Executor::execute_future( - async move { - let mut map = HashMap::new(); - map.insert(USER_EMAIL, "etorreborre@yahoo.com".to_string()); - map.insert(USER_NAME, "eric".to_string()); - cli.add_journey_event(JourneyEvent::Enrolled, map.clone()) - .await - .unwrap(); - cli.add_journey_event(JourneyEvent::PortalCreated, map) - .await - .unwrap(); - cli.add_journey_error("command", "sorry".to_string(), HashMap::default()) - .await - .unwrap(); - } - .with_current_context(), - ) - }); - if let Err(e) = result { - panic!("{e:?}"); - } + let _guard = cx.with_value(Utc::now()).attach(); + + let mut map = HashMap::new(); + map.insert(USER_EMAIL, "etorreborre@yahoo.com".to_string()); + map.insert(USER_NAME, "eric".to_string()); + cli.add_journey_event(JourneyEvent::Enrolled, map.clone()) + .with_context(cx.clone()) + .await + .unwrap(); + cli.add_journey_event(JourneyEvent::PortalCreated, map) + .with_context(cx.clone()) + .await + .unwrap(); + cli.add_journey_error("command", "sorry".to_string(), HashMap::default()) + .with_context(cx.clone()) + .await + .unwrap(); - tracing_guard.force_flush(); + tracing_guard.force_flush().await; let mut spans = spans_exporter.get_finished_spans().unwrap(); spans.sort_by_key(|s| s.start_time); diff --git a/implementations/rust/ockam/ockam_api/tests/logging_tracing.rs b/implementations/rust/ockam/ockam_api/tests/logging_tracing.rs index a142e7126ac..eb319004878 100644 --- a/implementations/rust/ockam/ockam_api/tests/logging_tracing.rs +++ b/implementations/rust/ockam/ockam_api/tests/logging_tracing.rs @@ -12,25 +12,21 @@ use tempfile::NamedTempFile; use ockam_api::cli_state::{random_name, CliStateMode}; use ockam_api::CliState; -use ockam_node::Executor; use tracing::{error, info}; use tracing_core::Level; /// These tests need to be integration tests /// They need to run in isolation because /// they set up some global spans / logs exporters that might interact with other tests -#[test] -fn test_log_and_traces() { - let cli = Executor::execute_future(async { - let db_file = NamedTempFile::new().unwrap(); - let cli_state_directory = db_file.path().parent().unwrap().join(random_name()); - let mode = CliStateMode::Persistent(cli_state_directory); - CliState::create(mode) - .await - .unwrap() - .set_tracing_enabled(true) - }) - .unwrap(); +#[tokio::test] +async fn test_log_and_traces() { + let db_file = NamedTempFile::new().unwrap(); + let cli_state_directory = db_file.path().parent().unwrap().join(random_name()); + let mode = CliStateMode::Persistent(cli_state_directory); + let cli = CliState::create(mode) + .await + .unwrap() + .set_tracing_enabled(true); let temp_file = NamedTempFile::new().unwrap(); let log_directory = &temp_file.path().parent().unwrap().join(random_name()); @@ -42,7 +38,7 @@ fn test_log_and_traces() { &make_configuration() .unwrap() .set_log_directory(log_directory.into()), - &ExportingConfiguration::foreground(&cli).unwrap(), + &ExportingConfiguration::foreground(&cli).await.unwrap(), "test", None, ); @@ -54,7 +50,8 @@ fn test_log_and_traces() { }); // check that the spans are exported - guard.force_flush(); + guard.force_flush().await; + let spans = spans_exporter.get_finished_spans().unwrap(); assert_eq!(spans.len(), 1); let parent_span = spans.first().unwrap(); diff --git a/implementations/rust/ockam/ockam_app_lib/src/api/functions.rs b/implementations/rust/ockam/ockam_app_lib/src/api/functions.rs index e3c55396a0e..1150753afb1 100644 --- a/implementations/rust/ockam/ockam_app_lib/src/api/functions.rs +++ b/implementations/rust/ockam/ockam_app_lib/src/api/functions.rs @@ -302,10 +302,14 @@ extern "C" fn reset_application_state() { }); } None => { - // allow disk state reset even if we don't have an application state - CliState::backup_and_reset().expect( + let app_state = unsafe { APPLICATION_STATE.as_ref() }.expect(ERROR_NOT_INITIALIZED); + + app_state.context().runtime().block_on(async { + // allow disk state reset even if we don't have an application state + CliState::backup_and_reset().await.expect( "Failed to initialize CliState. Try to manually remove the '~/.ockam' directory", ); + }) } } } diff --git a/implementations/rust/ockam/ockam_app_lib/src/log.rs b/implementations/rust/ockam/ockam_app_lib/src/log.rs index 58d89150448..ad1580afc92 100644 --- a/implementations/rust/ockam/ockam_app_lib/src/log.rs +++ b/implementations/rust/ockam/ockam_app_lib/src/log.rs @@ -11,12 +11,14 @@ impl AppState { if self.tracing_guard.get().is_some() { return; } - let state = { - let this = self.clone(); - self.context() - .runtime() - .block_on(async move { this.state().await }) - }; + + self.context() + .runtime() + .block_on(async move { self.setup_logging_tracing_impl().await }); + } + + async fn setup_logging_tracing_impl(&self) { + let state = self.state().await; let node_dir = state .node_dir(NODE_NAME) .expect("Failed to get node directory"); @@ -25,7 +27,7 @@ impl AppState { .add_crates(vec!["ockam_app_lib"]); let tracing_guard = LoggingTracing::setup( &logging_configuration(level_and_crates, Some(node_dir), Colored::Off).unwrap(), - &ExportingConfiguration::foreground(&state).unwrap(), + &ExportingConfiguration::foreground(&state).await.unwrap(), "portals", Some("portals".to_string()), ); diff --git a/implementations/rust/ockam/ockam_app_lib/src/state/mod.rs b/implementations/rust/ockam/ockam_app_lib/src/state/mod.rs index 2477afe9fdf..9b16da86c89 100644 --- a/implementations/rust/ockam/ockam_app_lib/src/state/mod.rs +++ b/implementations/rust/ockam/ockam_app_lib/src/state/mod.rs @@ -96,8 +96,9 @@ impl AppState { application_state_callback: ApplicationStateCallback, notification_callback: NotificationCallback, ) -> Result { - let cli_state = CliState::new(CliStateMode::with_default_dir()?)?; let rt = Arc::new(Runtime::new().expect("cannot create a tokio runtime")); + let cli_state = + rt.block_on(async move { CliState::create(CliStateMode::with_default_dir()?).await })?; let (context, _executor) = NodeBuilder::new() .no_logging() .with_runtime(rt.clone()) diff --git a/implementations/rust/ockam/ockam_command/src/admin/mod.rs b/implementations/rust/ockam/ockam_command/src/admin/mod.rs index 1904a36ba3a..7740267eae8 100644 --- a/implementations/rust/ockam/ockam_command/src/admin/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/admin/mod.rs @@ -3,6 +3,8 @@ use clap::{Args, Subcommand}; use crate::shared_args::IdentityOpts; use crate::{docs, CommandGlobalOpts}; +use ockam_node::Context; + mod subscription; const HELP_DETAIL: &str = ""; @@ -24,9 +26,9 @@ pub enum AdminSubCommand { } impl AdminCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - AdminSubCommand::Subscription(c) => c.run(opts), + AdminSubCommand::Subscription(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/admin/subscription.rs b/implementations/rust/ockam/ockam_command/src/admin/subscription.rs index 8f6890cb77f..7347ff970b6 100644 --- a/implementations/rust/ockam/ockam_command/src/admin/subscription.rs +++ b/implementations/rust/ockam/ockam_command/src/admin/subscription.rs @@ -11,7 +11,6 @@ use ockam_api::output::Output; use crate::shared_args::IdentityOpts; use crate::subscription::get_subscription_by_id_or_space_id; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const HELP_DETAIL: &str = ""; @@ -132,17 +131,11 @@ enum SubscriptionUpdateSubcommand { } impl SubscriptionCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "admin subscription".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = InMemoryNode::start(ctx, &opts.state).await?; let controller = node.create_controller().await?; diff --git a/implementations/rust/ockam/ockam_command/src/authenticated.rs b/implementations/rust/ockam/ockam_command/src/authenticated.rs deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/implementations/rust/ockam/ockam_command/src/authority/create.rs b/implementations/rust/ockam/ockam_command/src/authority/create.rs index d3965af644c..5da85ddced3 100644 --- a/implementations/rust/ockam/ockam_command/src/authority/create.rs +++ b/implementations/rust/ockam/ockam_command/src/authority/create.rs @@ -3,7 +3,6 @@ use std::fmt::{Display, Formatter}; use clap::Args; use miette::{miette, IntoDiagnostic, WrapErr}; use serde::{Deserialize, Serialize}; -use tokio::process::Child; use ockam::identity::models::ChangeHistory; use ockam::identity::utils::now; @@ -18,11 +17,10 @@ use ockam_api::nodes::service::default_address::DefaultAddress; use ockam_core::compat::collections::BTreeMap; use ockam_core::compat::fmt; +use crate::node::node_callback::NodeCallback; use crate::node::util::run_ockam; -use crate::util::embedded_node_that_is_not_stopped; use crate::util::foreground_args::{wait_for_exit_signal, ForegroundArgs}; use crate::util::parsers::internet_address_parser; -use crate::util::{async_cmd, local_cmd}; use crate::{docs, CommandGlobalOpts, Result}; const LONG_ABOUT: &str = include_str!("./static/create/long_about.txt"); @@ -120,6 +118,11 @@ pub struct CreateCommand { /// TODO: Set to true after old clients are updated #[arg(long, value_name = "DISABLE_TRUST_CONTEXT_ID", default_value_t = false)] disable_trust_context_id: bool, + + /// Port that a node should connect to when it's up and running, as a way to signal + /// the parent process + #[arg(hide = true, long)] + pub tcp_callback_port: Option, } impl CreateCommand { @@ -130,7 +133,7 @@ impl CreateCommand { pub(crate) async fn spawn_background_node( &self, opts: &CommandGlobalOpts, - ) -> miette::Result { + ) -> miette::Result<()> { if !self.skip_is_running_check { self.guard_node_is_not_already_running(opts).await?; } @@ -213,23 +216,29 @@ impl CreateCommand { args.push("--disable_trust_context_id".to_string()); } - run_ockam(args, opts.global_args.quiet).await + let node_callback = NodeCallback::create().await?; + + args.push("--tcp-callback-port".to_string()); + args.push(node_callback.callback_port().to_string()); + + let handle = run_ockam(args, opts.global_args.quiet)?; + + tokio::select! { + _ = handle.wait_with_output() => { std::process::exit(1) } + _ = node_callback.wait_for_signal() => {} + } + + Ok(()) } } impl CreateCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { if self.foreground { // Create a new node in the foreground (i.e. in this OS process) - local_cmd(embedded_node_that_is_not_stopped( - opts.rt.clone(), - |ctx| async move { self.start_authority_node(&ctx, opts).await }, - )) + self.start_authority_node(ctx, opts).await } else { - // Create a new node running in the background (i.e. another, new OS process) - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.create_background_node(opts).await - }) + self.create_background_node(opts).await } } @@ -261,6 +270,7 @@ impl CreateCommand { async fn create_background_node(&self, opts: CommandGlobalOpts) -> miette::Result<()> { // Spawn node in another, new process self.spawn_background_node(&opts).await?; + Ok(()) } @@ -373,6 +383,10 @@ impl CreateCommand { .await .into_diagnostic()?; + if let Some(tcp_callback_port) = self.tcp_callback_port { + NodeCallback::signal(tcp_callback_port); + } + let foreground_args = ForegroundArgs { child_process: self.child_process, exit_on_eof: false, diff --git a/implementations/rust/ockam/ockam_command/src/authority/mod.rs b/implementations/rust/ockam/ockam_command/src/authority/mod.rs index 5a06845056e..6182c02b83e 100644 --- a/implementations/rust/ockam/ockam_command/src/authority/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/authority/mod.rs @@ -5,6 +5,8 @@ use create::CreateCommand; use crate::{docs, CommandGlobalOpts}; +use ockam_node::Context; + mod create; const LONG_ABOUT: &str = include_str!("./static/long_about.txt"); @@ -22,9 +24,9 @@ pub struct AuthorityCommand { } impl AuthorityCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - AuthoritySubcommand::Create(c) => c.run(opts), + AuthoritySubcommand::Create(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/command.rs b/implementations/rust/ockam/ockam_command/src/command.rs index 6f4645a318a..1260be9fd94 100644 --- a/implementations/rust/ockam/ockam_command/src/command.rs +++ b/implementations/rust/ockam/ockam_command/src/command.rs @@ -1,24 +1,36 @@ -use crate::branding::BrandingCompileEnvVars; -use crate::command_events::{add_command_error_event, add_command_event}; +use crate::branding::{load_compile_time_vars, BrandingCompileEnvVars}; +use crate::command_events::add_command_event; use crate::command_global_opts::CommandGlobalOpts; use crate::global_args::GlobalArgs; use crate::subcommand::OckamSubcommand; use crate::upgrade::check_if_an_upgrade_is_available; use crate::version::Version; -use crate::{docs, ErrorReportHandler}; +use crate::{add_command_error_event, docs, ErrorReportHandler}; use clap::Parser; use colorful::Colorful; -use ockam_api::fmt_warn; +use console::Term; +use miette::{miette, IntoDiagnostic}; +use ockam_api::colors::color_primary; +use ockam_api::logs::{ + is_exporting_set, logging_configuration, Colored, ExportingConfiguration, + LogLevelWithCratesFilter, LoggingConfiguration, LoggingTracing, TracingGuard, +}; +use ockam_api::terminal::Terminal; +use ockam_api::{fmt_err, fmt_log, fmt_ok, fmt_warn, CliState}; use ockam_core::OCKAM_TRACER_NAME; -use ockam_node::database::OCKAM_SQLITE_IN_MEMORY; -use opentelemetry::trace::{Link, SpanBuilder, TraceContextExt, Tracer}; -use opentelemetry::{global, Context}; -use tracing::{instrument, warn}; +use ockam_node::Context; +use opentelemetry::global; +use opentelemetry::trace::{FutureExt, Link, SpanBuilder, TraceContextExt, Tracer}; +use opentelemetry::Context as OtelContext; +use std::process::exit; +use tracing::{debug, info, instrument, warn}; const ABOUT: &str = include_str!("./static/about.txt"); const LONG_ABOUT: &str = include_str!("./static/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/after_long_help.txt"); +use crate::util::exitcode; + /// Top-level command, with: /// - Global arguments /// - A specific subcommand @@ -43,8 +55,114 @@ pub struct OckamCommand { } impl OckamCommand { + async fn init_cli_state(&self, in_memory: bool) -> CliState { + match CliState::new(in_memory).await { + Ok(state) => state, + Err(err) => { + // If the user is trying to run `ockam reset` and the local state is corrupted, + // we can try to hard reset the local state. + if let OckamSubcommand::Reset(c) = &self.subcommand { + c.hard_reset(); + println!( + "{}", + fmt_ok!( + "Local {} configuration deleted", + BrandingCompileEnvVars::bin_name() + ) + ); + exit(exitcode::OK); + } + eprintln!("{}", fmt_err!("Failed to initialize local state")); + eprintln!( + "{}", + fmt_log!( + "Consider upgrading to the latest version of {} Command", + BrandingCompileEnvVars::bin_name() + ) + ); + let ockam_home = std::env::var("OCKAM_HOME").unwrap_or("~/.ockam".to_string()); + eprintln!( + "{}", + fmt_log!( + "You can also try removing the local state using {} \ + or deleting the directory at {}", + color_primary("ockam reset"), + color_primary(ockam_home) + ) + ); + eprintln!("\n{:?}", miette!(err.to_string())); + exit(exitcode::SOFTWARE); + } + } + } + + /// Set up a logger and a tracer for the current node + /// If the node is a background node we always enable logging, regardless of environment variables + fn setup_logging_tracing( + &self, + logging_configuration: &LoggingConfiguration, + tracing_configuration: &ExportingConfiguration, + ) -> Option { + if !logging_configuration.is_enabled() && !tracing_configuration.is_enabled() { + return None; + }; + + let app_name = if self.subcommand.is_background_node() { + "local node" + } else { + "cli" + }; + let tracing_guard = LoggingTracing::setup( + logging_configuration, + tracing_configuration, + app_name, + self.subcommand.node_name(), + ); + + Some(tracing_guard) + } + + /// Create the logging configuration, depending on the command to execute + fn make_logging_configuration(&self, is_tty: bool) -> miette::Result { + let log_path = self.subcommand.log_path(); + if self.subcommand.is_background_node() { + Ok(LoggingConfiguration::background(log_path).into_diagnostic()?) + } else { + let level_and_crates = LogLevelWithCratesFilter::from_verbose(self.global_args.verbose) + .into_diagnostic()?; + let log_path = + if level_and_crates.explicit_verbose_flag || self.subcommand.is_foreground_node() { + None + } else { + Some(CliState::command_log_path(self.subcommand.name().as_str())?) + }; + let colored = if !self.global_args.no_color && is_tty && log_path.is_none() { + Colored::On + } else { + Colored::Off + }; + Ok(logging_configuration(level_and_crates, log_path, colored).into_diagnostic()?) + } + } + + /// Create the tracing configuration, depending on the command to execute + async fn make_tracing_configuration( + &self, + state: &CliState, + ) -> miette::Result { + if self.subcommand.is_background_node() { + ExportingConfiguration::background(state) + .await + .into_diagnostic() + } else { + ExportingConfiguration::foreground(state) + .await + .into_diagnostic() + } + } + /// Run the command - pub fn run(self, arguments: Vec) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, arguments: &[String]) -> miette::Result<()> { // If test_argument_parser is true, command arguments are checked // but the command is not executed. This is useful to test arguments // without having to execute their logic. @@ -52,73 +170,129 @@ impl OckamCommand { return Ok(()); } + load_compile_time_vars(); + // Sets a hook using our own Error Report Handler. // This allows us to customize how we format the error messages and their content. let _hook_result = miette::set_hook(Box::new(|_| Box::new(ErrorReportHandler::new()))); let command_name = self.subcommand.name(); - // Set the in-memory env var if needed + let mut in_memory = false; + if let OckamSubcommand::Node(cmd) = &self.subcommand { if let crate::node::NodeSubcommand::Create(c) = &cmd.subcommand { - if c.in_memory { - std::env::set_var(OCKAM_SQLITE_IN_MEMORY, "true"); - } + in_memory = c.in_memory; } } - let options = CommandGlobalOpts::new(&arguments, &self.global_args, &self.subcommand)?; + let logging_configuration = self.make_logging_configuration(Term::stdout().is_term())?; + + let (tracing_configuration, tracing_guard, cli_state) = if !is_exporting_set()? { + // Allows to have logging enabled before initializing CliState + let tracing_configuration = ExportingConfiguration::off().into_diagnostic()?; + let tracing_guard = + self.setup_logging_tracing(&logging_configuration, &tracing_configuration); + + (tracing_configuration, tracing_guard, None) + } else { + let cli_state = self.init_cli_state(in_memory).await; + let tracing_configuration = self.make_tracing_configuration(&cli_state).await?; + let tracing_guard = + self.setup_logging_tracing(&logging_configuration, &tracing_configuration); + let cli_state = cli_state.set_tracing_enabled(tracing_configuration.is_enabled()); + + (tracing_configuration, tracing_guard, Some(cli_state)) + }; + + info!("Tracing initialized"); + debug!("{:#?}", logging_configuration); + debug!("{:#?}", tracing_configuration); + + let tracer = global::tracer(OCKAM_TRACER_NAME); + + let span = if let Some(opentelemetry_context) = self.subcommand.get_opentelemetry_context() + { + let span_builder = + SpanBuilder::from_name(command_name.clone()).with_links(vec![Link::new( + opentelemetry_context + .extract() + .span() + .span_context() + .clone(), + vec![], + 0, + )]); + tracer.build(span_builder) + } else { + tracer.start(command_name.clone()) + }; + let cx = OtelContext::current_with_span(span); + + // TODO: Add another span here? + let cli_state = match cli_state { + Some(cli_state) => cli_state, + None => self + .init_cli_state(in_memory) + .with_context(cx.clone()) + .await + .set_tracing_enabled(tracing_configuration.is_enabled()), + }; + + let terminal = Terminal::new( + logging_configuration.is_enabled(), + logging_configuration.log_dir().is_some(), + self.global_args.quiet, + self.global_args.no_color, + self.global_args.no_input, + self.global_args.output_format(), + BrandingCompileEnvVars::bin_name(), + BrandingCompileEnvVars::brand_name(), + ); + + let options = CommandGlobalOpts::new(self.global_args.clone(), cli_state, terminal); - if let Err(err) = check_if_an_upgrade_is_available(&options) { + options.log_inputs(arguments, &self.subcommand); + + if let Err(err) = check_if_an_upgrade_is_available(&options).await { warn!("Failed to check for upgrade, error={err}"); options .terminal .write_line(fmt_warn!("Failed to check for upgrade"))?; } - let tracer = global::tracer(OCKAM_TRACER_NAME); - let result = - if let Some(opentelemetry_context) = self.subcommand.get_opentelemetry_context() { - let context = Context::current(); - let span_builder = SpanBuilder::from_name(command_name.clone().to_string()) - .with_links(vec![Link::new( - opentelemetry_context - .extract() - .span() - .span_context() - .clone(), - vec![], - 0, - )]); - let span = tracer.build_with_context(span_builder, &context); - let cx = Context::current_with_span(span); - let _guard = cx.clone().attach(); - self.run_command(options.clone(), &command_name, &arguments) - } else { - tracer.in_span(command_name.clone(), |_| { - self.run_command(options.clone(), &command_name, &arguments) - }) - }; + let result = self + .run_command(ctx, options.clone(), &command_name, arguments) + .with_context(cx) + .await; + if let Err(ref e) = result { add_command_error_event( options.state.clone(), &command_name, &format!("{e}"), arguments.join(" "), - )? + ) + .await?; }; - options.shutdown(); + + if let Some(tracing_guard) = tracing_guard { + tracing_guard.force_flush().await; + tracing_guard.shutdown().await; + }; + result } #[instrument(skip_all, fields(command = self.subcommand.name()))] - fn run_command( + async fn run_command( self, + ctx: &Context, opts: CommandGlobalOpts, command_name: &str, arguments: &[String], ) -> miette::Result<()> { - add_command_event(opts.state.clone(), command_name, arguments.join(" "))?; - self.subcommand.run(opts) + add_command_event(opts.state.clone(), command_name, arguments.join(" ")).await?; + self.subcommand.run(ctx, opts).await } } diff --git a/implementations/rust/ockam/ockam_command/src/command_events.rs b/implementations/rust/ockam/ockam_command/src/command_events.rs index 31ec9943837..74fd361f958 100644 --- a/implementations/rust/ockam/ockam_command/src/command_events.rs +++ b/implementations/rust/ockam/ockam_command/src/command_events.rs @@ -1,44 +1,41 @@ -use miette::IntoDiagnostic; use ockam_api::cli_state::journeys::{JourneyEvent, APPLICATION_EVENT_COMMAND}; use ockam_api::CliState; use ockam_core::OCKAM_TRACER_NAME; -use ockam_node::Executor; -use opentelemetry::trace::{TraceContextExt, Tracer}; +use opentelemetry::trace::{FutureExt, Span, TraceContextExt, Tracer}; use opentelemetry::{global, Context}; use std::collections::HashMap; -use tracing::{error, warn}; +use tracing::warn; /// This function creates a journey event describing the execution of a command -pub fn add_command_event( +pub async fn add_command_event( cli_state: CliState, command: &str, command_arguments: String, ) -> miette::Result<()> { let command_name = command.to_string(); let tracer = global::tracer(OCKAM_TRACER_NAME); - tracer - .in_span(command_name.clone(), |_| { - Executor::execute_future(async move { - let mut attributes = HashMap::new(); - attributes.insert( - APPLICATION_EVENT_COMMAND, - sanitize_command_arguments(command_arguments), - ); - if let Err(e) = cli_state - .add_journey_event(JourneyEvent::ok(command_name), attributes) - .await - { - warn!("cannot save a journey event: {}", e); - } - Ok::<(), ockam_core::Error>(()) - }) - }) - .into_diagnostic()??; + + let span = tracer.start(command_name.clone()); + let ctx = Context::current_with_span(span); + + let mut attributes = HashMap::new(); + attributes.insert( + APPLICATION_EVENT_COMMAND, + sanitize_command_arguments(command_arguments), + ); + if let Err(e) = cli_state + .add_journey_event(JourneyEvent::ok(command_name), attributes) + .with_context(ctx) + .await + { + warn!("cannot save a journey event: {}", e); + } + Ok(()) } /// This function creates a journey event describing the error resulting from the execution of a command -pub fn add_command_error_event( +pub async fn add_command_error_event( cli_state: CliState, command_name: &str, message: &str, @@ -47,29 +44,23 @@ pub fn add_command_error_event( let message = message.to_string(); let command = command_name.to_string(); let tracer = global::tracer(OCKAM_TRACER_NAME); - tracer - .in_span(format!("'{}' error", command), |_| { - Context::current() - .span() - .set_status(opentelemetry::trace::Status::error(message.clone())); - error!("{}", &message); + let mut span = tracer.start(format!("'{}' error", command)); + span.set_status(opentelemetry::trace::Status::error(message.clone())); + let ctx = Context::current_with_span(span); + + let mut attributes = HashMap::new(); + attributes.insert( + APPLICATION_EVENT_COMMAND, + sanitize_command_arguments(command_arguments), + ); + if let Err(e) = cli_state + .add_journey_error(&command, message, attributes) + .with_context(ctx) + .await + { + warn!("cannot save a journey event: {}", e); + } - Executor::execute_future(async move { - let mut attributes = HashMap::new(); - attributes.insert( - APPLICATION_EVENT_COMMAND, - sanitize_command_arguments(command_arguments), - ); - if let Err(e) = cli_state - .add_journey_error(&command, message, attributes) - .await - { - warn!("cannot save a journey event: {}", e); - } - Ok::<(), ockam_core::Error>(()) - }) - }) - .into_diagnostic()??; Ok(()) } diff --git a/implementations/rust/ockam/ockam_command/src/command_global_opts.rs b/implementations/rust/ockam/ockam_command/src/command_global_opts.rs index 27148ce111e..6038abd0b9a 100644 --- a/implementations/rust/ockam/ockam_command/src/command_global_opts.rs +++ b/implementations/rust/ockam/ockam_command/src/command_global_opts.rs @@ -1,23 +1,11 @@ -use colorful::Colorful; use console::Term; -use miette::{miette, IntoDiagnostic}; -use std::process::exit; -use std::sync::Arc; -use tokio::runtime::Runtime; -use tracing::{debug, info}; +use tracing::debug; -use crate::branding::{load_compile_time_vars, BrandingCompileEnvVars}; use crate::subcommand::OckamSubcommand; -use crate::util::exitcode; use crate::version::Version; use crate::GlobalArgs; -use ockam_api::colors::color_primary; -use ockam_api::logs::{ - logging_configuration, Colored, ExportingConfiguration, LogLevelWithCratesFilter, - LoggingConfiguration, LoggingTracing, TracingGuard, -}; use ockam_api::terminal::{Terminal, TerminalStream}; -use ockam_api::{fmt_err, fmt_log, fmt_ok, CliState}; +use ockam_api::CliState; /// This struct contains the main structs used to implement commands: /// @@ -28,10 +16,10 @@ use ockam_api::{fmt_err, fmt_log, fmt_ok, CliState}; #[derive(Clone, Debug)] pub struct CommandGlobalOpts { pub global_args: GlobalArgs, + // TODO: This is not the place for it. We could propagate it more granularly and even avoid + // creating it for some commands. pub state: CliState, pub terminal: Terminal>, - pub rt: Arc, - pub tracing_guard: Option>, } impl CommandGlobalOpts { @@ -42,166 +30,23 @@ impl CommandGlobalOpts { /// - Get the runtime /// pub fn new( - arguments: &[String], - global_args: &GlobalArgs, - cmd: &OckamSubcommand, - ) -> miette::Result { - load_compile_time_vars(); - let mut state = match CliState::from_env() { - Ok(state) => state, - Err(err) => { - // If the user is trying to run `ockam reset` and the local state is corrupted, - // we can try to hard reset the local state. - if let OckamSubcommand::Reset(c) = cmd { - c.hard_reset(); - println!( - "{}", - fmt_ok!( - "Local {} configuration deleted", - BrandingCompileEnvVars::bin_name() - ) - ); - exit(exitcode::OK); - } - eprintln!("{}", fmt_err!("Failed to initialize local state")); - eprintln!( - "{}", - fmt_log!( - "Consider upgrading to the latest version of {} Command", - BrandingCompileEnvVars::bin_name() - ) - ); - let ockam_home = std::env::var("OCKAM_HOME").unwrap_or("~/.ockam".to_string()); - eprintln!( - "{}", - fmt_log!( - "You can also try removing the local state using {} \ - or deleting the directory at {}", - color_primary("ockam reset"), - color_primary(ockam_home) - ) - ); - eprintln!("\n{:?}", miette!(err.to_string())); - exit(exitcode::SOFTWARE); - } - }; - - let logging_configuration = - Self::make_logging_configuration(global_args, cmd, Term::stdout().is_term())?; - let tracing_configuration = Self::make_tracing_configuration(&state, cmd)?; - let terminal = Terminal::new( - logging_configuration.is_enabled(), - logging_configuration.log_dir().is_some(), - global_args.quiet, - global_args.no_color, - global_args.no_input, - global_args.output_format(), - BrandingCompileEnvVars::bin_name(), - BrandingCompileEnvVars::brand_name(), - ); - let tracing_guard = - Self::setup_logging_tracing(cmd, &logging_configuration, &tracing_configuration); - - Self::log_inputs( - arguments, - global_args, - cmd, - &logging_configuration, - &tracing_configuration, - ); - - state = state.set_tracing_enabled(tracing_configuration.is_enabled()); - - let rt = Arc::new(Runtime::new().expect("cannot initialize the tokio runtime")); - - Ok(Self { + global_args: GlobalArgs, + state: CliState, + terminal: Terminal>, + ) -> Self { + Self { global_args: global_args.clone(), state, terminal, - rt, - tracing_guard, - }) - } - - /// Set up a logger and a tracer for the current node - /// If the node is a background node we always enable logging, regardless of environment variables - fn setup_logging_tracing( - cmd: &OckamSubcommand, - logging_configuration: &LoggingConfiguration, - tracing_configuration: &ExportingConfiguration, - ) -> Option> { - if !logging_configuration.is_enabled() && !tracing_configuration.is_enabled() { - return None; - }; - - let app_name = if cmd.is_background_node() { - "local node" - } else { - "cli" - }; - let tracing_guard = LoggingTracing::setup( - logging_configuration, - tracing_configuration, - app_name, - cmd.node_name(), - ); - Some(Arc::new(tracing_guard)) - } - - /// Create the logging configuration, depending on the command to execute - fn make_logging_configuration( - global_args: &GlobalArgs, - cmd: &OckamSubcommand, - is_tty: bool, - ) -> miette::Result { - let log_path = cmd.log_path(); - if cmd.is_background_node() { - Ok(LoggingConfiguration::background(log_path).into_diagnostic()?) - } else { - let level_and_crates = - LogLevelWithCratesFilter::from_verbose(global_args.verbose).into_diagnostic()?; - let log_path = if level_and_crates.explicit_verbose_flag || cmd.is_foreground_node() { - None - } else { - Some(CliState::command_log_path(cmd.name().as_str())?) - }; - let colored = if !global_args.no_color && is_tty && log_path.is_none() { - Colored::On - } else { - Colored::Off - }; - Ok(logging_configuration(level_and_crates, log_path, colored).into_diagnostic()?) } } - /// Create the tracing configuration, depending on the command to execute - fn make_tracing_configuration( - state: &CliState, - cmd: &OckamSubcommand, - ) -> miette::Result { - Ok(if cmd.is_background_node() { - ExportingConfiguration::background(state).into_diagnostic()? - } else { - ExportingConfiguration::foreground(state).into_diagnostic()? - }) - } - /// Log the inputs and configurations used to execute the command - fn log_inputs( - arguments: &[String], - global_args: &GlobalArgs, - cmd: &OckamSubcommand, - logging_configuration: &LoggingConfiguration, - tracing_configuration: &ExportingConfiguration, - ) { + pub(crate) fn log_inputs(&self, arguments: &[String], cmd: &OckamSubcommand) { debug!("Arguments: {}", arguments.join(" ")); - debug!("Global arguments: {:#?}", &global_args); + debug!("Global arguments: {:#?}", &self.global_args); debug!("Command: {:#?}", &cmd); debug!("Version: {}", Version::new().no_color()); - - info!("Tracing initialized"); - debug!("{:#?}", logging_configuration); - debug!("{:#?}", tracing_configuration); } pub fn set_quiet(&self) -> Self { @@ -210,19 +55,4 @@ impl CommandGlobalOpts { clone.terminal = clone.terminal.set_quiet(); clone } - - /// Flush spans and log records - pub fn force_flush(&self) { - if let Some(tracing_guard) = self.tracing_guard.clone() { - tracing_guard.force_flush(); - }; - } - - /// Shutdown resources - pub fn shutdown(&self) { - if let Some(tracing_guard) = self.tracing_guard.clone() { - tracing_guard.force_flush(); - tracing_guard.shutdown(); - }; - } } diff --git a/implementations/rust/ockam/ockam_command/src/credential/issue.rs b/implementations/rust/ockam/ockam_command/src/credential/issue.rs index feb6b6f2e9d..62d0f505fbb 100644 --- a/implementations/rust/ockam/ockam_command/src/credential/issue.rs +++ b/implementations/rust/ockam/ockam_command/src/credential/issue.rs @@ -9,7 +9,6 @@ use ockam_core::compat::collections::HashMap; use crate::credential::CredentialOutput; use crate::output::CredentialAndPurposeKeyDisplay; -use crate::util::async_cmd; use crate::util::parsers::duration_parser; use crate::{util::parsers::identity_identifier_parser, CommandGlobalOpts, Result}; @@ -41,12 +40,6 @@ pub struct IssueCommand { } impl IssueCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "credential issue".into() } @@ -62,7 +55,7 @@ impl IssueCommand { Ok(attributes) } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { let authority = opts .state .get_identifier_by_optional_name(&self.as_identity) diff --git a/implementations/rust/ockam/ockam_command/src/credential/list.rs b/implementations/rust/ockam/ockam_command/src/credential/list.rs index fead12078e7..66a58da745b 100644 --- a/implementations/rust/ockam/ockam_command/src/credential/list.rs +++ b/implementations/rust/ockam/ockam_command/src/credential/list.rs @@ -1,15 +1,13 @@ use clap::Args; use miette::IntoDiagnostic; -use ockam::identity::{CredentialSqlxDatabase, Identifier}; -use ockam_api::colors::color_primary; - use crate::credential::LocalCredentialOutput; use crate::node::NodeOpts; -use crate::util::async_cmd; use crate::util::parsers::identity_identifier_parser; use crate::CommandGlobalOpts; use crate::Result; +use ockam::identity::{CredentialSqlxDatabase, Identifier}; +use ockam_api::colors::color_primary; #[derive(Clone, Debug, Args)] pub struct ListCommand { @@ -26,17 +24,11 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "credential list".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { let node_name = match self.node_opts.at_node.clone() { Some(name) => name, None => opts.state.get_default_node().await?.name(), diff --git a/implementations/rust/ockam/ockam_command/src/credential/mod.rs b/implementations/rust/ockam/ockam_command/src/credential/mod.rs index 7d2374dfb27..5b743189c86 100644 --- a/implementations/rust/ockam/ockam_command/src/credential/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/credential/mod.rs @@ -10,6 +10,7 @@ use ockam::identity::{Identifier, TimestampInSeconds}; use ockam_api::output::Output; use ockam_api::terminal::fmt; use ockam_core::compat::collections::HashMap; +use ockam_node::Context; pub(crate) use store::StoreCommand; pub(crate) use verify::VerifyCommand; @@ -49,12 +50,12 @@ impl CredentialSubcommand { } impl CredentialCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - CredentialSubcommand::List(c) => c.run(opts), - CredentialSubcommand::Issue(c) => c.run(opts), - CredentialSubcommand::Store(c) => c.run(opts), - CredentialSubcommand::Verify(c) => c.run(opts), + CredentialSubcommand::List(c) => c.run(opts).await, + CredentialSubcommand::Issue(c) => c.run(opts).await, + CredentialSubcommand::Store(c) => c.run(ctx, opts).await, + CredentialSubcommand::Verify(c) => c.run(opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/credential/store.rs b/implementations/rust/ockam/ockam_command/src/credential/store.rs index 6a805f89841..f75bd2ade5e 100644 --- a/implementations/rust/ockam/ockam_command/src/credential/store.rs +++ b/implementations/rust/ockam/ockam_command/src/credential/store.rs @@ -14,7 +14,6 @@ use ockam_api::{fmt_log, fmt_ok}; use crate::credential::verify::verify_credential; use crate::node::util::initialize_default_node; use crate::node::NodeOpts; -use crate::util::async_cmd; use crate::util::parsers::identity_identifier_parser; #[derive(Clone, Debug, Args)] @@ -40,17 +39,11 @@ pub struct StoreCommand { } impl StoreCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "credential store".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { // Set node name in state to store identity attributes to it initialize_default_node(ctx, &opts).await?; let node_name = opts diff --git a/implementations/rust/ockam/ockam_command/src/credential/verify.rs b/implementations/rust/ockam/ockam_command/src/credential/verify.rs index b2f8a2cb594..aaa763d9913 100644 --- a/implementations/rust/ockam/ockam_command/src/credential/verify.rs +++ b/implementations/rust/ockam/ockam_command/src/credential/verify.rs @@ -14,7 +14,6 @@ use ockam::identity::{ use ockam_api::{fmt_err, fmt_log, fmt_ok}; use ockam_vault::{SoftwareVaultForVerifyingSignatures, VaultForVerifyingSignatures}; -use crate::util::async_cmd; use crate::util::parsers::identity_identifier_parser; use crate::CommandGlobalOpts; @@ -31,12 +30,6 @@ pub struct VerifyCommand { } impl VerifyCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "credential verify".into() } @@ -45,7 +38,7 @@ impl VerifyCommand { &self.issuer } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { let (is_valid, plain) = match verify_credential( &opts, self.issuer(), diff --git a/implementations/rust/ockam/ockam_command/src/enroll/command.rs b/implementations/rust/ockam/ockam_command/src/enroll/command.rs index bc60fa9146f..8057efa9e9f 100644 --- a/implementations/rust/ockam/ockam_command/src/enroll/command.rs +++ b/implementations/rust/ockam/ockam_command/src/enroll/command.rs @@ -19,7 +19,6 @@ use crate::enroll::OidcServiceExt; use crate::error::Error; use crate::operation::util::check_for_project_completion; use crate::project::util::check_project_readiness; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts, Result}; use ockam::Context; use ockam_api::cli_state::journeys::{JourneyEvent, USER_EMAIL, USER_NAME}; @@ -80,17 +79,11 @@ pub struct EnrollCommand { } impl EnrollCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "enroll".to_string() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { if opts.global_args.output_format().is_json() { return Err(miette::miette!( "This command is interactive and requires you to open a web browser to complete enrollment. \ diff --git a/implementations/rust/ockam/ockam_command/src/entry_point.rs b/implementations/rust/ockam/ockam_command/src/entry_point.rs index c8a0d20d084..91f3632c9aa 100644 --- a/implementations/rust/ockam/ockam_command/src/entry_point.rs +++ b/implementations/rust/ockam/ockam_command/src/entry_point.rs @@ -7,12 +7,13 @@ use crate::{ add_command_error_event, has_help_flag, has_version_flag, pager, replace_hyphen_with_stdin, util::exitcode, version::Version, OckamCommand, }; -use ockam_api::cli_state::CliState; +use ockam_api::cli_state::{CliState, CliStateMode}; use ockam_api::logs::{ logging_configuration, Colored, ExportingConfiguration, LogLevelWithCratesFilter, LoggingTracing, }; use ockam_api::output::Output; +use ockam_node::NodeBuilder; /// Main method for running the command executable: /// @@ -40,36 +41,54 @@ pub fn run() -> miette::Result<()> { print_version_and_exit(); } - match OckamCommand::try_parse_from(input.clone()) { - Err(help) => { - // the -h or --help flag must not be interpreted as an error - if !has_help_flag(&input) { - let command = input - .iter() - .take_while(|a| !a.starts_with('-')) - .collect::>() - .iter() - .map(|s| s.to_string()) - .collect::>() - .join(" "); - let cli_state = CliState::from_env()?; - let level_and_crates = LogLevelWithCratesFilter::new().into_diagnostic()?; - let logging_configuration = - logging_configuration(level_and_crates, None, Colored::On); - let _guard = LoggingTracing::setup( - &logging_configuration.into_diagnostic()?, - &ExportingConfiguration::foreground(&cli_state).into_diagnostic()?, - "local node", - None, - ); - - let message = format!("could not parse the command: {}", command); - add_command_error_event(cli_state, &command, &message, input.join(" "))?; - }; - pager::render_help(help); - } - Ok(command) => command.run(input)?, - } + let command_res = OckamCommand::try_parse_from(&input); + + let node_builder = NodeBuilder::new().no_logging(); + + let (ctx, mut executor) = node_builder.build(); + + executor.execute(async move { + let res = match command_res { + Ok(command) => command.run(&ctx, &input).await, + Err(err) => handle_invalid_command(&input, err).await, + }; + + ctx.shutdown_node().await?; + + res + })??; + + Ok(()) +} + +async fn handle_invalid_command(input: &[String], help: clap::Error) -> miette::Result<()> { + // the -h or --help flag must not be interpreted as an error + if !has_help_flag(input) { + let command = input + .iter() + .take_while(|a| !a.starts_with('-')) + .collect::>() + .iter() + .map(|s| s.to_string()) + .collect::>() + .join(" "); + let cli_state = CliState::create(CliStateMode::InMemory).await?; + let level_and_crates = LogLevelWithCratesFilter::new().into_diagnostic()?; + let logging_configuration = logging_configuration(level_and_crates, None, Colored::On); + let _guard = LoggingTracing::setup( + &logging_configuration.into_diagnostic()?, + &ExportingConfiguration::foreground(&cli_state) + .await + .into_diagnostic()?, + "local node", + None, + ); + + let message = format!("could not parse the command: {}", command); + add_command_error_event(cli_state, &command, &message, input.join(" ")).await?; + }; + pager::render_help(help); + Ok(()) } diff --git a/implementations/rust/ockam/ockam_command/src/environment/static/env_info.txt b/implementations/rust/ockam/ockam_command/src/environment/static/env_info.txt index 4b7ac58bbc3..3112d543235 100644 --- a/implementations/rust/ockam/ockam_command/src/environment/static/env_info.txt +++ b/implementations/rust/ockam/ockam_command/src/environment/static/env_info.txt @@ -19,7 +19,7 @@ Logging - OCKAM_LOG_FORMAT: a `string` that overrides the default format of the logs: `default`, `json`, or `pretty`. Default value: `default`. - OCKAM_LOG_MAX_SIZE_MB: an `integer` that defines the maximum size of a log file in MB. Default value `100`. - OCKAM_LOG_MAX_FILES: an `integer` that defines the maximum number of log files to keep per node. Default value `60`. -- OCKAM_LOG_CRATES_FILTER: a filter for log messages based on crate names: `all`, `default`, comma-separated list of crate names. Default value: `default`, i.e. the list of `ockam` crates. +- OCKAM_LOG_CRATES_FILTER: crates to use as a filter for log messages: `all`, `basic`, `core` or a comma-separated list of crate names. If no value is specified the filter used depends on the log level. The INFO level only displays `basic` messages, other levels display the core `ockam` crates. Database - OCKAM_SQLITE_IN_MEMORY: a `boolean` to set the SQLite mode to `memory`. This can only be used in the `node create` command with the `--foreground` flag. Default value: `false`. diff --git a/implementations/rust/ockam/ockam_command/src/flow_control/add_consumer.rs b/implementations/rust/ockam/ockam_command/src/flow_control/add_consumer.rs index 9e1fb45271c..cb5844ac095 100644 --- a/implementations/rust/ockam/ockam_command/src/flow_control/add_consumer.rs +++ b/implementations/rust/ockam/ockam_command/src/flow_control/add_consumer.rs @@ -6,7 +6,7 @@ use ockam_core::flow_control::FlowControlId; use ockam_multiaddr::MultiAddr; use crate::node::NodeOpts; -use crate::util::{api, async_cmd}; +use crate::util::api; use crate::CommandGlobalOpts; #[derive(Clone, Debug, Args)] @@ -23,17 +23,11 @@ pub struct AddConsumerCommand { } impl AddConsumerCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "add flowcontrol consumer".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; node.tell( ctx, diff --git a/implementations/rust/ockam/ockam_command/src/flow_control/mod.rs b/implementations/rust/ockam/ockam_command/src/flow_control/mod.rs index c4557d85d22..fc899d5aed9 100644 --- a/implementations/rust/ockam/ockam_command/src/flow_control/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/flow_control/mod.rs @@ -4,6 +4,8 @@ pub use add_consumer::AddConsumerCommand; use crate::CommandGlobalOpts; +use ockam_node::Context; + mod add_consumer; #[derive(Clone, Debug, Args)] @@ -20,9 +22,9 @@ pub enum FlowControlSubcommand { } impl FlowControlCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - FlowControlSubcommand::AddConsumer(c) => c.run(opts), + FlowControlSubcommand::AddConsumer(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/identity/create.rs b/implementations/rust/ockam/ockam_command/src/identity/create.rs index 3026fffe5eb..dee06ee32ac 100644 --- a/implementations/rust/ockam/ockam_command/src/identity/create.rs +++ b/implementations/rust/ockam/ockam_command/src/identity/create.rs @@ -45,7 +45,7 @@ pub struct CreateCommand { impl Command for CreateCommand { const NAME: &'static str = "identity create"; - async fn async_run(self, _ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, _ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let _notification_handler = NotificationHandler::start(&opts.state, opts.terminal.clone()); let vault = match &self.vault { Some(vault_name) => opts.state.get_or_create_named_vault(vault_name).await?, diff --git a/implementations/rust/ockam/ockam_command/src/identity/default.rs b/implementations/rust/ockam/ockam_command/src/identity/default.rs index 5c807c78c46..22b58ac9439 100644 --- a/implementations/rust/ockam/ockam_command/src/identity/default.rs +++ b/implementations/rust/ockam/ockam_command/src/identity/default.rs @@ -3,7 +3,6 @@ use colorful::Colorful; use miette::miette; use ockam_api::fmt_ok; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/default/long_about.txt"); @@ -21,17 +20,11 @@ pub struct DefaultCommand { } impl DefaultCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "identity default".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { match &self.name { Some(name) => { if opts.state.is_default_identity_by_name(name).await? { diff --git a/implementations/rust/ockam/ockam_command/src/identity/delete.rs b/implementations/rust/ockam/ockam_command/src/identity/delete.rs index 9760e318cfd..4c8ff6e9b54 100644 --- a/implementations/rust/ockam/ockam_command/src/identity/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/identity/delete.rs @@ -1,6 +1,5 @@ use crate::terminal::tui::DeleteCommandTui; use crate::tui::PluralTerm; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; use clap::Args; use colorful::Colorful; @@ -31,17 +30,11 @@ pub struct DeleteCommand { } impl DeleteCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "identity delete".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { DeleteTui::run(opts, self.clone()).await } } diff --git a/implementations/rust/ockam/ockam_command/src/identity/list.rs b/implementations/rust/ockam/ockam_command/src/identity/list.rs index 2f49e1cc09b..4ba3308f399 100644 --- a/implementations/rust/ockam/ockam_command/src/identity/list.rs +++ b/implementations/rust/ockam/ockam_command/src/identity/list.rs @@ -7,7 +7,6 @@ use ockam_api::output::Output; use serde::Serialize; use serde_json::json; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/list/long_about.txt"); @@ -24,17 +23,11 @@ const AFTER_LONG_HELP: &str = include_str!("./static/list/after_long_help.txt"); pub struct ListCommand {} impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "identity list".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { let mut identities_list: Vec = Vec::new(); let identities = opts.state.get_named_identities().await?; diff --git a/implementations/rust/ockam/ockam_command/src/identity/mod.rs b/implementations/rust/ockam/ockam_command/src/identity/mod.rs index 79e01333ac3..ba281f94593 100644 --- a/implementations/rust/ockam/ockam_command/src/identity/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/identity/mod.rs @@ -8,6 +8,8 @@ pub(crate) use show::ShowCommand; use crate::identity::default::DefaultCommand; use crate::{docs, Command, CommandGlobalOpts}; +use ockam_node::Context; + mod create; mod default; mod delete; @@ -38,13 +40,13 @@ pub enum IdentitySubcommand { } impl IdentityCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - IdentitySubcommand::Create(c) => c.run(opts), - IdentitySubcommand::Show(c) => c.run(opts), - IdentitySubcommand::List(c) => c.run(opts), - IdentitySubcommand::Delete(c) => c.run(opts), - IdentitySubcommand::Default(c) => c.run(opts), + IdentitySubcommand::Create(c) => c.run(ctx, opts).await, + IdentitySubcommand::Show(c) => c.run(opts).await, + IdentitySubcommand::List(c) => c.run(opts).await, + IdentitySubcommand::Delete(c) => c.run(opts).await, + IdentitySubcommand::Default(c) => c.run(opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/identity/show.rs b/implementations/rust/ockam/ockam_command/src/identity/show.rs index dadb668b5a6..a5a8f90a87c 100644 --- a/implementations/rust/ockam/ockam_command/src/identity/show.rs +++ b/implementations/rust/ockam/ockam_command/src/identity/show.rs @@ -12,7 +12,6 @@ use ockam_api::output::{EncodeFormat, Output}; use crate::identity::list::IdentityListOutput; use crate::output::{IdentifierDisplay, VerifyingPublicKeyDisplay}; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/show/long_about.txt"); @@ -43,16 +42,11 @@ pub struct ShowCommand { } impl ShowCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } pub fn name(&self) -> String { "identity show".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { if self.name.is_some() || !opts.terminal.can_ask_for_user_input() { ShowCommand::show_single_identity(&opts, &self.name, self.full, self.encoding.clone()) .await?; diff --git a/implementations/rust/ockam/ockam_command/src/influxdb/inlet/create.rs b/implementations/rust/ockam/ockam_command/src/influxdb/inlet/create.rs index b3eb4b985a6..acc737259a4 100644 --- a/implementations/rust/ockam/ockam_command/src/influxdb/inlet/create.rs +++ b/implementations/rust/ockam/ockam_command/src/influxdb/inlet/create.rs @@ -159,7 +159,7 @@ pub struct CreateCommand { impl Command for CreateCommand { const NAME: &'static str = "influxdb-inlet create"; - async fn async_run(mut self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(mut self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { initialize_default_node(ctx, &opts).await?; let cmd = self.parse_args(&opts).await?; @@ -229,7 +229,7 @@ impl Command for CreateCommand { let created_message = format!( "Created a new InfluxDB Inlet in the Node {} bound to {}", - color_primary(&node_name), + color_primary(node_name), color_primary(cmd.from.to_string()), ); diff --git a/implementations/rust/ockam/ockam_command/src/influxdb/inlet/mod.rs b/implementations/rust/ockam/ockam_command/src/influxdb/inlet/mod.rs index 0aae0c319f7..e39e4a07fda 100644 --- a/implementations/rust/ockam/ockam_command/src/influxdb/inlet/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/influxdb/inlet/mod.rs @@ -1,8 +1,10 @@ use clap::{Args, Subcommand}; +use crate::{docs, Command, CommandGlobalOpts}; + use create::CreateCommand; -use crate::{docs, Command, CommandGlobalOpts}; +use ockam_node::Context; pub(crate) mod create; @@ -26,9 +28,9 @@ pub enum InfluxDBInletSubCommand { } impl InfluxDBInletCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - InfluxDBInletSubCommand::Create(c) => c.run(opts), + InfluxDBInletSubCommand::Create(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/influxdb/outlet/create.rs b/implementations/rust/ockam/ockam_command/src/influxdb/outlet/create.rs index c5077703130..178ca1246e1 100644 --- a/implementations/rust/ockam/ockam_command/src/influxdb/outlet/create.rs +++ b/implementations/rust/ockam/ockam_command/src/influxdb/outlet/create.rs @@ -96,7 +96,7 @@ pub struct LeaseManagerConfigArgs { impl Command for CreateCommand { const NAME: &'static str = "influxdb-outlet create"; - async fn async_run(mut self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(mut self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { initialize_default_node(ctx, &opts).await?; let cmd = self.parse_args(&opts).await?; diff --git a/implementations/rust/ockam/ockam_command/src/influxdb/outlet/mod.rs b/implementations/rust/ockam/ockam_command/src/influxdb/outlet/mod.rs index d54f0cce49b..c5cdf78053e 100644 --- a/implementations/rust/ockam/ockam_command/src/influxdb/outlet/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/influxdb/outlet/mod.rs @@ -1,8 +1,10 @@ use clap::{Args, Subcommand}; +use crate::{docs, Command, CommandGlobalOpts}; + use create::CreateCommand; -use crate::{docs, Command, CommandGlobalOpts}; +use ockam_node::Context; pub(crate) mod create; @@ -26,9 +28,9 @@ pub enum InfluxDBOutletSubCommand { } impl InfluxDBOutletCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - InfluxDBOutletSubCommand::Create(c) => c.run(opts), + InfluxDBOutletSubCommand::Create(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/kafka/consumer/create.rs b/implementations/rust/ockam/ockam_command/src/kafka/consumer/create.rs index 247f959c8c4..8c796ba79d7 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/consumer/create.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/consumer/create.rs @@ -1,7 +1,4 @@ use clap::{command, Args}; -use ockam::transport::SchemeHostnamePort; -use ockam_api::port_range::PortRange; -use ockam_multiaddr::MultiAddr; use crate::util::print_warning_for_deprecated_flag_replaced; use crate::{ @@ -11,6 +8,11 @@ use crate::{ Command, CommandGlobalOpts, }; +use ockam::transport::SchemeHostnamePort; +use ockam_api::port_range::PortRange; +use ockam_multiaddr::MultiAddr; +use ockam_node::Context; + /// Create a new Kafka Consumer. Kafka clients v3.7.0 and earlier are supported. /// You can find the version you have with 'kafka-console-consumer.sh --version'. /// [DEPRECATED] @@ -38,7 +40,7 @@ pub struct CreateCommand { } impl CreateCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { print_warning_for_deprecated_flag_replaced(&opts, &self.name(), "kafka-inlet")?; crate::kafka::inlet::create::CreateCommand { name: self.addr.clone(), @@ -57,7 +59,8 @@ impl CreateCommand { consumer_policy_expression: None, producer_policy_expression: None, } - .run(opts) + .run(ctx, opts) + .await } pub fn name(&self) -> String { diff --git a/implementations/rust/ockam/ockam_command/src/kafka/consumer/delete.rs b/implementations/rust/ockam/ockam_command/src/kafka/consumer/delete.rs index cfd4dfb2db5..030c348f05d 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/consumer/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/consumer/delete.rs @@ -3,6 +3,8 @@ use clap::Args; use crate::util::print_warning_for_deprecated_flag_replaced; use crate::{docs, node::NodeOpts, Command, CommandGlobalOpts}; +use ockam_node::Context; + const AFTER_LONG_HELP: &str = include_str!("./static/delete/after_long_help.txt"); /// Delete a Kafka Consumer. @@ -18,7 +20,7 @@ pub struct DeleteCommand { } impl DeleteCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { print_warning_for_deprecated_flag_replaced(&opts, &self.name(), "kafka-inlet")?; crate::kafka::inlet::delete::DeleteCommand { node_opts: self.node_opts, @@ -26,7 +28,8 @@ impl DeleteCommand { all: false, yes: false, } - .run(opts) + .run(ctx, opts) + .await } pub fn name(&self) -> String { diff --git a/implementations/rust/ockam/ockam_command/src/kafka/consumer/list.rs b/implementations/rust/ockam/ockam_command/src/kafka/consumer/list.rs index 3ef59203c48..9377a037f5e 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/consumer/list.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/consumer/list.rs @@ -4,6 +4,8 @@ use crate::node::NodeOpts; use crate::util::print_warning_for_deprecated_flag_replaced; use crate::{docs, Command, CommandGlobalOpts}; +use ockam_node::Context; + const PREVIEW_TAG: &str = include_str!("../../static/preview_tag.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/list/after_long_help.txt"); @@ -20,12 +22,13 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { print_warning_for_deprecated_flag_replaced(&opts, &self.name(), "kafka-inlet")?; crate::kafka::inlet::list::ListCommand { node_opts: self.node_opts, } - .run(opts) + .run(ctx, opts) + .await } pub fn name(&self) -> String { diff --git a/implementations/rust/ockam/ockam_command/src/kafka/consumer/mod.rs b/implementations/rust/ockam/ockam_command/src/kafka/consumer/mod.rs index b7d4a142776..549f321d422 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/consumer/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/consumer/mod.rs @@ -5,6 +5,8 @@ use crate::kafka::consumer::delete::DeleteCommand; use crate::kafka::consumer::list::ListCommand; use crate::CommandGlobalOpts; +use ockam_node::Context; + mod create; mod delete; mod list; @@ -26,11 +28,11 @@ pub enum KafkaConsumerSubcommand { } impl KafkaConsumerCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - KafkaConsumerSubcommand::Create(c) => c.run(opts), - KafkaConsumerSubcommand::Delete(c) => c.run(opts), - KafkaConsumerSubcommand::List(c) => c.run(opts), + KafkaConsumerSubcommand::Create(c) => c.run(ctx, opts).await, + KafkaConsumerSubcommand::Delete(c) => c.run(ctx, opts).await, + KafkaConsumerSubcommand::List(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/kafka/inlet/create.rs b/implementations/rust/ockam/ockam_command/src/kafka/inlet/create.rs index 642d448864b..7121f4627f8 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/inlet/create.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/inlet/create.rs @@ -139,7 +139,7 @@ pub struct CreateCommand { impl Command for CreateCommand { const NAME: &'static str = "kafka-inlet create"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { initialize_default_node(ctx, &opts).await?; let cmd = self.parse_args(&opts).await?; @@ -194,7 +194,7 @@ impl Command for CreateCommand { .map_err(|e| miette!("Failed to start Kafka Inlet: {e}"))?; KafkaInletOutput { - node_name: node.node_name(), + node_name: node.node_name().to_string(), from: InternetAddress::new(&cmd.from.hostname_port().to_string()) .ok_or(miette!("Invalid address"))?, brokers_port_range: cmd.brokers_port_range(), diff --git a/implementations/rust/ockam/ockam_command/src/kafka/inlet/delete.rs b/implementations/rust/ockam/ockam_command/src/kafka/inlet/delete.rs index 8d21fb43a5b..f1a8f687eb1 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/inlet/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/inlet/delete.rs @@ -40,7 +40,7 @@ pub struct DeleteCommand { impl Command for DeleteCommand { const NAME: &'static str = "kafka-inlet delete"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(DeleteTui::run(ctx, opts, self).await?) } } @@ -116,7 +116,7 @@ impl DeleteCommandTui for DeleteTui { .plain(fmt_ok!( "Kafka Inlet with address {} on Node {} has been deleted", color_primary(item_name), - color_primary(&node_name) + color_primary(node_name) )) .json(serde_json::json!({ "address": item_name, "node": node_name })) .write_line()?; diff --git a/implementations/rust/ockam/ockam_command/src/kafka/inlet/list.rs b/implementations/rust/ockam/ockam_command/src/kafka/inlet/list.rs index 73309dfdfcc..23683fff242 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/inlet/list.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/inlet/list.rs @@ -24,7 +24,7 @@ pub struct ListCommand { impl Command for ListCommand { const NAME: &'static str = "kafka-inlet list"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let services: Vec = node .ask( diff --git a/implementations/rust/ockam/ockam_command/src/kafka/inlet/mod.rs b/implementations/rust/ockam/ockam_command/src/kafka/inlet/mod.rs index 64075bec7cf..bcbbca1710c 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/inlet/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/inlet/mod.rs @@ -6,6 +6,8 @@ use crate::kafka::inlet::list::ListCommand; use crate::kafka::inlet::show::ShowCommand; use crate::{Command, CommandGlobalOpts}; +use ockam_node::Context; + pub(crate) mod create; pub(crate) mod delete; pub(crate) mod list; @@ -28,12 +30,12 @@ pub enum KafkaInletSubcommand { } impl KafkaInletCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - KafkaInletSubcommand::Create(c) => c.run(opts), - KafkaInletSubcommand::Show(c) => c.run(opts), - KafkaInletSubcommand::Delete(c) => c.run(opts), - KafkaInletSubcommand::List(c) => c.run(opts), + KafkaInletSubcommand::Create(c) => c.run(ctx, opts).await, + KafkaInletSubcommand::Show(c) => c.run(ctx, opts).await, + KafkaInletSubcommand::Delete(c) => c.run(ctx, opts).await, + KafkaInletSubcommand::List(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/kafka/inlet/show.rs b/implementations/rust/ockam/ockam_command/src/kafka/inlet/show.rs index 6048fca2f01..92833dcb2dc 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/inlet/show.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/inlet/show.rs @@ -28,7 +28,7 @@ pub struct ShowCommand { impl Command for ShowCommand { const NAME: &'static str = "kafka-inlet show"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(ShowTui::run(ctx, opts, &self).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/kafka/outlet/create.rs b/implementations/rust/ockam/ockam_command/src/kafka/outlet/create.rs index 33403dfc7d4..91ffeca7821 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/outlet/create.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/outlet/create.rs @@ -66,7 +66,7 @@ pub struct CreateCommand { impl Command for CreateCommand { const NAME: &'static str = "kafka-outlet create"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { initialize_default_node(ctx, &opts).await?; let cmd = self.parse_args(&opts).await?; @@ -93,7 +93,7 @@ impl Command for CreateCommand { .map_err(|e| miette!("Failed to start Kafka Outlet: {e}"))?; KafkaOutletOutput { - node_name: node.node_name(), + node_name: node.node_name().to_string(), bootstrap_server: cmd.bootstrap_server.to_string(), } }; diff --git a/implementations/rust/ockam/ockam_command/src/kafka/outlet/delete.rs b/implementations/rust/ockam/ockam_command/src/kafka/outlet/delete.rs index c10e834b9cf..8447608c3db 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/outlet/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/outlet/delete.rs @@ -37,7 +37,7 @@ pub struct DeleteCommand { impl Command for DeleteCommand { const NAME: &'static str = "kafka-outlet delete"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(DeleteTui::run(ctx, opts, self).await?) } } @@ -113,7 +113,7 @@ impl DeleteCommandTui for DeleteTui { .plain(fmt_ok!( "Kafka Outlet with address {} on Node {} has been deleted", color_primary(item_name), - color_primary(&node_name) + color_primary(node_name) )) .json(serde_json::json!({ "address": item_name, "node": node_name })) .write_line()?; diff --git a/implementations/rust/ockam/ockam_command/src/kafka/outlet/list.rs b/implementations/rust/ockam/ockam_command/src/kafka/outlet/list.rs index c1d933ad361..285f061d00c 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/outlet/list.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/outlet/list.rs @@ -22,7 +22,7 @@ pub struct ListCommand { impl Command for ListCommand { const NAME: &'static str = "kafka-outlet list"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let services: Vec = node .ask( diff --git a/implementations/rust/ockam/ockam_command/src/kafka/outlet/mod.rs b/implementations/rust/ockam/ockam_command/src/kafka/outlet/mod.rs index 37a778bc1ba..4c271f889a0 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/outlet/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/outlet/mod.rs @@ -9,6 +9,7 @@ use self::list::ListCommand; use crate::kafka::outlet::show::ShowCommand; use crate::{Command, CommandGlobalOpts}; use clap::{command, Args, Subcommand}; +use ockam_node::Context; /// Manage Kafka Outlets #[derive(Clone, Debug, Args)] @@ -27,12 +28,12 @@ pub enum KafkaOutletSubcommand { } impl KafkaOutletCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - KafkaOutletSubcommand::Create(c) => c.run(opts), - KafkaOutletSubcommand::Show(c) => c.run(opts), - KafkaOutletSubcommand::Delete(c) => c.run(opts), - KafkaOutletSubcommand::List(c) => c.run(opts), + KafkaOutletSubcommand::Create(c) => c.run(ctx, opts).await, + KafkaOutletSubcommand::Show(c) => c.run(ctx, opts).await, + KafkaOutletSubcommand::Delete(c) => c.run(ctx, opts).await, + KafkaOutletSubcommand::List(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/kafka/outlet/show.rs b/implementations/rust/ockam/ockam_command/src/kafka/outlet/show.rs index ab3450cca90..da946cbd452 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/outlet/show.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/outlet/show.rs @@ -28,7 +28,7 @@ pub struct ShowCommand { impl Command for ShowCommand { const NAME: &'static str = "kafka-outlet show"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(ShowTui::run(ctx, opts, &self).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/kafka/producer/create.rs b/implementations/rust/ockam/ockam_command/src/kafka/producer/create.rs index cffed58c12d..5c7da8924e9 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/producer/create.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/producer/create.rs @@ -1,7 +1,4 @@ use clap::{command, Args}; -use ockam::transport::SchemeHostnamePort; -use ockam_api::port_range::PortRange; -use ockam_multiaddr::MultiAddr; use crate::util::print_warning_for_deprecated_flag_replaced; use crate::{ @@ -11,6 +8,11 @@ use crate::{ Command, CommandGlobalOpts, }; +use ockam::transport::SchemeHostnamePort; +use ockam_api::port_range::PortRange; +use ockam_multiaddr::MultiAddr; +use ockam_node::Context; + /// Create a new Kafka Producer. Kafka clients v3.7.0 and earlier are supported. /// You can find the version you have with 'kafka-console-producer.sh --version'. /// [DEPRECATED] @@ -38,7 +40,7 @@ pub struct CreateCommand { } impl CreateCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { print_warning_for_deprecated_flag_replaced(&opts, &self.name(), "kafka-inlet")?; crate::kafka::inlet::create::CreateCommand { name: self.addr.clone(), @@ -57,7 +59,8 @@ impl CreateCommand { consumer_policy_expression: None, producer_policy_expression: None, } - .run(opts) + .run(ctx, opts) + .await } pub fn name(&self) -> String { diff --git a/implementations/rust/ockam/ockam_command/src/kafka/producer/delete.rs b/implementations/rust/ockam/ockam_command/src/kafka/producer/delete.rs index 2828eb2c2e8..68cbc28f0ab 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/producer/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/producer/delete.rs @@ -3,6 +3,8 @@ use clap::Args; use crate::util::print_warning_for_deprecated_flag_replaced; use crate::{docs, node::NodeOpts, Command, CommandGlobalOpts}; +use ockam_node::Context; + const AFTER_LONG_HELP: &str = include_str!("./static/delete/after_long_help.txt"); /// Delete a Kafka Producer. @@ -18,7 +20,7 @@ pub struct DeleteCommand { } impl DeleteCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { print_warning_for_deprecated_flag_replaced(&opts, &self.name(), "kafka-inlet")?; crate::kafka::inlet::delete::DeleteCommand { node_opts: self.node_opts, @@ -26,7 +28,8 @@ impl DeleteCommand { all: false, yes: false, } - .run(opts) + .run(ctx, opts) + .await } pub fn name(&self) -> String { diff --git a/implementations/rust/ockam/ockam_command/src/kafka/producer/list.rs b/implementations/rust/ockam/ockam_command/src/kafka/producer/list.rs index 9eae7f5fc5c..6b4f5bdeaf7 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/producer/list.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/producer/list.rs @@ -4,6 +4,8 @@ use crate::node::NodeOpts; use crate::util::print_warning_for_deprecated_flag_replaced; use crate::{docs, Command, CommandGlobalOpts}; +use ockam_node::Context; + const PREVIEW_TAG: &str = include_str!("../../static/preview_tag.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/list/after_long_help.txt"); @@ -20,12 +22,13 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { print_warning_for_deprecated_flag_replaced(&opts, &self.name(), "kafka-inlet")?; crate::kafka::inlet::list::ListCommand { node_opts: self.node_opts, } - .run(opts) + .run(ctx, opts) + .await } pub fn name(&self) -> String { diff --git a/implementations/rust/ockam/ockam_command/src/kafka/producer/mod.rs b/implementations/rust/ockam/ockam_command/src/kafka/producer/mod.rs index 3e30a5ddd73..92f121eb4b0 100644 --- a/implementations/rust/ockam/ockam_command/src/kafka/producer/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/kafka/producer/mod.rs @@ -5,6 +5,8 @@ use crate::kafka::producer::delete::DeleteCommand; use crate::kafka::producer::list::ListCommand; use crate::CommandGlobalOpts; +use ockam_node::Context; + mod create; mod delete; mod list; @@ -25,11 +27,11 @@ pub enum KafkaProducerSubcommand { } impl KafkaProducerCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - KafkaProducerSubcommand::Create(c) => c.run(opts), - KafkaProducerSubcommand::Delete(c) => c.run(opts), - KafkaProducerSubcommand::List(c) => c.run(opts), + KafkaProducerSubcommand::Create(c) => c.run(ctx, opts).await, + KafkaProducerSubcommand::Delete(c) => c.run(ctx, opts).await, + KafkaProducerSubcommand::List(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/lease/create.rs b/implementations/rust/ockam/ockam_command/src/lease/create.rs index 343d1cf3dcf..20cf3ce4488 100644 --- a/implementations/rust/ockam/ockam_command/src/lease/create.rs +++ b/implementations/rust/ockam/ockam_command/src/lease/create.rs @@ -34,7 +34,7 @@ pub struct CreateCommand { impl Command for CreateCommand { const NAME: &'static str = "lease create"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let cmd = self.parse_args(&opts).await?; let node = InMemoryNode::start_with_identity_and_project_name( diff --git a/implementations/rust/ockam/ockam_command/src/lease/list.rs b/implementations/rust/ockam/ockam_command/src/lease/list.rs index 142b646d27e..a4a2ff47cf1 100644 --- a/implementations/rust/ockam/ockam_command/src/lease/list.rs +++ b/implementations/rust/ockam/ockam_command/src/lease/list.rs @@ -33,7 +33,7 @@ pub struct ListCommand { impl Command for ListCommand { const NAME: &'static str = "lease list"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let cmd = self.parse_args(&opts).await?; let node = InMemoryNode::start_with_identity_and_project_name( diff --git a/implementations/rust/ockam/ockam_command/src/lease/mod.rs b/implementations/rust/ockam/ockam_command/src/lease/mod.rs index 6f65025796f..40fab2b3e4b 100644 --- a/implementations/rust/ockam/ockam_command/src/lease/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/lease/mod.rs @@ -1,14 +1,18 @@ +use clap::{Args, Subcommand}; + use self::revoke::RevokeCommand; use crate::util::process_nodes_multiaddr; use crate::{Command, CommandGlobalOpts, Error}; -use clap::{Args, Subcommand}; pub use create::CreateCommand; pub use list::ListCommand; +pub use show::ShowCommand; + use miette::IntoDiagnostic; +use std::str::FromStr; + use ockam_api::CliState; use ockam_multiaddr::MultiAddr; -pub use show::ShowCommand; -use std::str::FromStr; +use ockam_node::Context; mod create; mod list; @@ -31,12 +35,12 @@ pub enum LeaseSubcommand { } impl LeaseCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - LeaseSubcommand::Create(c) => c.run(opts), - LeaseSubcommand::List(c) => c.run(opts), - LeaseSubcommand::Show(c) => c.run(opts), - LeaseSubcommand::Revoke(c) => c.run(opts), + LeaseSubcommand::Create(c) => c.run(ctx, opts).await, + LeaseSubcommand::List(c) => c.run(ctx, opts).await, + LeaseSubcommand::Show(c) => c.run(ctx, opts).await, + LeaseSubcommand::Revoke(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/lease/revoke.rs b/implementations/rust/ockam/ockam_command/src/lease/revoke.rs index b172809b256..36aefaaf33b 100644 --- a/implementations/rust/ockam/ockam_command/src/lease/revoke.rs +++ b/implementations/rust/ockam/ockam_command/src/lease/revoke.rs @@ -39,7 +39,7 @@ pub struct RevokeCommand { impl Command for RevokeCommand { const NAME: &'static str = "lease revoke"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let cmd = self.parse_args(&opts).await?; let node = InMemoryNode::start_with_identity_and_project_name( diff --git a/implementations/rust/ockam/ockam_command/src/lease/show.rs b/implementations/rust/ockam/ockam_command/src/lease/show.rs index 189c08a4ead..52c5a030f56 100644 --- a/implementations/rust/ockam/ockam_command/src/lease/show.rs +++ b/implementations/rust/ockam/ockam_command/src/lease/show.rs @@ -38,7 +38,7 @@ pub struct ShowCommand { impl Command for ShowCommand { const NAME: &'static str = "lease show"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let cmd = self.parse_args(&opts).await?; let node = InMemoryNode::start_with_identity_and_project_name( diff --git a/implementations/rust/ockam/ockam_command/src/message/mod.rs b/implementations/rust/ockam/ockam_command/src/message/mod.rs index e0506a71f12..fcd7368504f 100644 --- a/implementations/rust/ockam/ockam_command/src/message/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/message/mod.rs @@ -4,6 +4,8 @@ pub use send::SendCommand; use crate::{Command, CommandGlobalOpts}; +use ockam_node::Context; + mod send; /// Send and receive messages @@ -21,9 +23,9 @@ pub enum MessageSubcommand { } impl MessageCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - MessageSubcommand::Send(c) => c.run(opts), + MessageSubcommand::Send(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/message/send.rs b/implementations/rust/ockam/ockam_command/src/message/send.rs index 6f13261e53e..97b47de5728 100644 --- a/implementations/rust/ockam/ockam_command/src/message/send.rs +++ b/implementations/rust/ockam/ockam_command/src/message/send.rs @@ -64,7 +64,7 @@ impl Command for SendCommand { Some(self.retry_opts.clone()) } - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { // Process `--to` Multiaddr let (to, meta) = clean_nodes_multiaddr(&self.to, &opts.state) .await diff --git a/implementations/rust/ockam/ockam_command/src/migrate_database/mod.rs b/implementations/rust/ockam/ockam_command/src/migrate_database/mod.rs index b8a495ebce8..f6c681a632d 100644 --- a/implementations/rust/ockam/ockam_command/src/migrate_database/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/migrate_database/mod.rs @@ -1,5 +1,4 @@ use crate::docs; -use crate::util::async_cmd; use crate::CommandGlobalOpts; use clap::Args; use miette::miette; @@ -23,12 +22,6 @@ pub struct MigrateDatabaseCommand { } impl MigrateDatabaseCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "migrate_database".into() } @@ -38,7 +31,7 @@ impl MigrateDatabaseCommand { /// - Or execute all the possible migrations and return the status after migration. /// /// This command returns true when used in scripts if the command successfully executed. - async fn async_run(&self, _ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, _ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match DatabaseConfiguration::postgres()? { Some(configuration) => { let db = SqlxDatabase::create_no_migration(&configuration).await?; diff --git a/implementations/rust/ockam/ockam_command/src/node/create.rs b/implementations/rust/ockam/ockam_command/src/node/create.rs index 063f756c088..ab01a4e8050 100644 --- a/implementations/rust/ockam/ockam_command/src/node/create.rs +++ b/implementations/rust/ockam/ockam_command/src/node/create.rs @@ -3,9 +3,8 @@ use crate::node::create::config::ConfigArgs; use crate::node::util::NodeManagerDefaults; use crate::service::config::Config; use crate::shared_args::TrustOpts; -use crate::util::embedded_node_that_is_not_stopped; use crate::util::foreground_args::ForegroundArgs; -use crate::util::{async_cmd, local_cmd, print_warning_for_deprecated_flag_no_effect}; +use crate::util::print_warning_for_deprecated_flag_no_effect; use crate::value_parsers::is_url; use crate::{docs, Command, CommandGlobalOpts, Result}; use async_trait::async_trait; @@ -29,6 +28,7 @@ use tracing::instrument; pub mod background; pub mod config; pub mod foreground; +pub mod node_callback; const DEFAULT_NODE_NAME: &str = "_default_node_name"; const LONG_ABOUT: &str = include_str!("./static/create/long_about.txt"); @@ -45,6 +45,7 @@ after_long_help = docs::after_help(AFTER_LONG_HELP) pub struct CreateCommand { /// Name of the node or a configuration to set up the node. /// The configuration can be either a path to a local file or a URL. + /// TODO: Use Option #[arg(value_name = "NAME_OR_CONFIGURATION", hide_default_value = true, default_value = DEFAULT_NODE_NAME)] pub name: String, @@ -149,6 +150,11 @@ pub struct CreateCommand { env = "OCKAM_SQLITE_IN_MEMORY" )] pub in_memory: bool, + + /// Port that a node should connect to when it's up and running, as a way to signal + /// the parent process + #[arg(hide = true, long)] + pub tcp_callback_port: Option, } impl Default for CreateCommand { @@ -179,6 +185,7 @@ impl Default for CreateCommand { child_process: false, }, in_memory: false, + tcp_callback_port: None, } } } @@ -188,43 +195,22 @@ impl Command for CreateCommand { const NAME: &'static str = "node create"; #[instrument(skip_all)] - fn run(mut self, opts: CommandGlobalOpts) -> miette::Result<()> { + async fn run(mut self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + self.parse_args(&opts).await?; + if self.should_run_config() { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.parse_args(&opts).await?; - self.run_config(&ctx, opts).await - }) + self.run_config(ctx, opts).await } else if self.foreground_args.foreground { if self.foreground_args.child_process { opentelemetry::Context::current() .span() .set_attribute(KeyValue::new("background", "true")); } - local_cmd(embedded_node_that_is_not_stopped( - opts.rt.clone(), - |ctx| async move { - self.parse_args(&opts).await?; - self.foreground_mode(&ctx, opts).await - }, - )) - } else { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.parse_args(&opts).await?; - self.background_mode(&ctx, opts).await - }) - } - } - async fn async_run(mut self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { - self.parse_args(&opts).await?; - if self.should_run_config() { - self.run_config(ctx, opts).await? - } else if self.foreground_args.foreground { - self.foreground_mode(ctx, opts).await? + self.foreground_mode(ctx, opts).await } else { - self.background_mode(ctx, opts).await? + self.background_mode(opts).await } - Ok(()) } } @@ -266,11 +252,6 @@ impl CreateCommand { } async fn parse_args(&mut self, opts: &CommandGlobalOpts) -> miette::Result<()> { - // return error if trying to create an in-memory node in background mode - if !self.foreground_args.foreground && opts.state.is_using_in_memory_database()? { - return Err(miette!("Only foreground nodes can be created in-memory",)); - } - // return error if there are duplicated variables let mut variables = std::collections::HashMap::new(); for (key, value) in self.config_args.variables.iter() { @@ -318,16 +299,11 @@ impl CreateCommand { }; if name == DEFAULT_NODE_NAME { name = random_name(); - if let Ok(default_node) = opts.state.get_default_node().await { - if !default_node.is_running() { - // The default node was stopped, so we can reuse the name - name = default_node.name(); - } - } } name }; + // FIXME: Avoid this check to avoid parent process needing db to create a background node if !self.skip_is_running_check && opts .state @@ -563,7 +539,6 @@ mod tests { #[test] fn get_default_node_name_no_previous_state() { let rt = Arc::new(tokio::runtime::Runtime::new().unwrap()); - let rt_moved = rt.clone(); rt.block_on(async { let opts = CommandGlobalOpts { state: CliState::test().await.unwrap(), @@ -577,9 +552,7 @@ mod tests { "", "", ), - rt: rt_moved, global_args: GlobalArgs::default(), - tracing_guard: None, }; let mut cmd = CreateCommand::default(); cmd.parse_args(&opts).await.unwrap(); @@ -622,77 +595,50 @@ mod tests { }); } - #[test] - fn get_default_node_name_with_previous_state() { - let rt = Arc::new(tokio::runtime::Runtime::new().unwrap()); - let rt_moved = rt.clone(); - rt.block_on(async { - let opts = CommandGlobalOpts { - state: CliState::test().await.unwrap(), - terminal: Terminal::new( - false, - false, - false, - true, - false, - OutputFormat::Plain, - "", - "", - ), - rt: rt_moved, - global_args: GlobalArgs::default(), - tracing_guard: None, - }; - - let default_node_name = "n1"; - opts.state.create_node(default_node_name).await.unwrap(); - - let mut cmd = CreateCommand::default(); - cmd.parse_args(&opts).await.unwrap(); - assert_ne!(cmd.name, default_node_name); + #[ockam::test] + async fn get_default_node_name_with_previous_state( + _ctx: &mut Context, + ) -> ockam_core::Result<()> { + let opts = CommandGlobalOpts { + state: CliState::test().await.unwrap(), + terminal: Terminal::new( + false, + false, + false, + true, + false, + OutputFormat::Plain, + "", + "", + ), + global_args: GlobalArgs::default(), + }; - // There is a default node stored in the state, but it's stopped. - // All the later calls should return the default node name. - opts.state.stop_node(default_node_name).await.unwrap(); - let mut cmd = CreateCommand::default(); - cmd.parse_args(&opts).await.unwrap(); - assert_eq!(cmd.name, default_node_name); + let default_node_name = "n1"; + opts.state.create_node(default_node_name).await.unwrap(); - let mut cmd = CreateCommand { - name: r#"{tcp-outlet: {to: "5500"}}"#.to_string(), - ..Default::default() - }; - cmd.parse_args(&opts).await.unwrap(); - assert_eq!(cmd.name, default_node_name); + let mut cmd = CreateCommand::default(); + cmd.parse_args(&opts).await.unwrap(); + assert_ne!(cmd.name, default_node_name); - let mut cmd = CreateCommand { - config_args: ConfigArgs { - configuration: Some(r#"{tcp-outlet: {to: "5500"}}"#.to_string()), - ..Default::default() - }, - ..Default::default() - }; - cmd.parse_args(&opts).await.unwrap(); - assert_eq!(cmd.name, default_node_name); + let mut cmd = CreateCommand { + name: "n2".to_string(), + ..Default::default() + }; + cmd.parse_args(&opts).await.unwrap(); + assert_eq!(cmd.name, "n2"); - // Unless we explicitly set a name - let mut cmd = CreateCommand { - name: "n2".to_string(), + let mut cmd = CreateCommand { + name: "n2".to_string(), + config_args: ConfigArgs { + configuration: Some(r#"{tcp-outlet: {to: "5500"}}"#.to_string()), ..Default::default() - }; - cmd.parse_args(&opts).await.unwrap(); - assert_eq!(cmd.name, "n2"); + }, + ..Default::default() + }; + cmd.parse_args(&opts).await.unwrap(); + assert_eq!(cmd.name, "n2"); - let mut cmd = CreateCommand { - name: "n2".to_string(), - config_args: ConfigArgs { - configuration: Some(r#"{tcp-outlet: {to: "5500"}}"#.to_string()), - ..Default::default() - }, - ..Default::default() - }; - cmd.parse_args(&opts).await.unwrap(); - assert_eq!(cmd.name, "n2"); - }); + Ok(()) } } diff --git a/implementations/rust/ockam/ockam_command/src/node/create/background.rs b/implementations/rust/ockam/ockam_command/src/node/create/background.rs index a9c073610a7..362c6bff858 100644 --- a/implementations/rust/ockam/ockam_command/src/node/create/background.rs +++ b/implementations/rust/ockam/ockam_command/src/node/create/background.rs @@ -1,12 +1,11 @@ use miette::miette; use tracing::{debug, instrument}; -use ockam::Context; use ockam_api::cli_state::journeys::{JourneyEvent, NODE_NAME}; use ockam_api::logs::CurrentSpan; use ockam_core::OpenTelemetryContext; -use crate::node::show::wait_until_node_is_up; +use crate::node::node_callback::NodeCallback; use crate::node::util::spawn_node; use crate::node::CreateCommand; use crate::CommandGlobalOpts; @@ -14,11 +13,7 @@ use crate::CommandGlobalOpts; impl CreateCommand { // Create a new node running in the background (i.e. another, new OS process) #[instrument(skip_all)] - pub(crate) async fn background_mode( - &self, - ctx: &Context, - opts: CommandGlobalOpts, - ) -> miette::Result<()> { + pub(crate) async fn background_mode(&self, opts: CommandGlobalOpts) -> miette::Result<()> { let node_name = self.name.clone(); debug!(%node_name, "creating node in background mode"); CurrentSpan::set_attribute(NODE_NAME, node_name.as_str()); @@ -29,27 +24,31 @@ impl CreateCommand { )); } + let node_callback = NodeCallback::create().await?; + // Create node and wait for it to be up and configured let cmd = CreateCommand { opentelemetry_context: self .opentelemetry_context .clone() .or(Some(OpenTelemetryContext::current())), + tcp_callback_port: Some(node_callback.callback_port()), ..self.clone() }; // Run foreground node in a separate process // Output is handled in the foreground execution - let handle = spawn_node(&opts, cmd).await?; + let handle = spawn_node(&opts, cmd)?; tokio::select! { _ = handle.wait_with_output() => { std::process::exit(1) } - _ = wait_until_node_is_up(ctx, &opts.state, node_name.clone()) => {} + _ = node_callback.wait_for_signal() => {} } opts.state .add_journey_event(JourneyEvent::NodeCreated, [(NODE_NAME, node_name)].into()) .await?; + Ok(()) } } diff --git a/implementations/rust/ockam/ockam_command/src/node/create/config.rs b/implementations/rust/ockam/ockam_command/src/node/create/config.rs index 10177852e24..fd3624fe90d 100644 --- a/implementations/rust/ockam/ockam_command/src/node/create/config.rs +++ b/implementations/rust/ockam/ockam_command/src/node/create/config.rs @@ -1,4 +1,4 @@ -use crate::node::show::is_node_up; +use crate::node::node_callback::NodeCallback; use crate::node::CreateCommand; use crate::run::parser::config::ConfigParser; use crate::run::parser::resource::*; @@ -8,8 +8,7 @@ use crate::{docs, CommandGlobalOpts}; use clap::Args; use miette::{miette, IntoDiagnostic}; use ockam_api::cli_state::journeys::APPLICATION_EVENT_COMMAND_CONFIGURATION_FILE; -use ockam_api::nodes::BackgroundNodeClient; -use ockam_core::OpenTelemetryContext; +use ockam_core::{OpenTelemetryContext, TryClone}; use ockam_node::Context; use serde::{Deserialize, Serialize}; use tracing::{debug, instrument, trace, Span}; @@ -248,25 +247,25 @@ impl NodeConfig { // Next, run the 'node create' command in a separate tokio task, // where the foreground node will run until stopped - let node_handle = { - let node_command = self + let (node_handle, callback) = { + let mut node_command = self .node .into_parsed_commands()? .into_iter() .next() .ok_or(miette!("A node command should be defined"))?; let opts = opts.clone(); - tokio::task::spawn_blocking(move || crate::Command::run(node_command, opts)) + let ctx = ctx.try_clone()?; + let callback = NodeCallback::create().await?; + node_command.tcp_callback_port = Some(callback.callback_port()); + let node_handle = + tokio::spawn(async move { crate::Command::run(node_command, &ctx, opts).await }); + + (node_handle, callback) }; // Wait for the node to be up - let is_up = { - let mut node = BackgroundNodeClient::create_to_node(ctx, &opts.state, node_name)?; - is_node_up(ctx, &mut node, true).await? - }; - if !is_up { - return Err(miette!("Node failed to start")); - } + callback.wait_for_signal().await?; // Run the other sections let node_name = Some(node_name); diff --git a/implementations/rust/ockam/ockam_command/src/node/create/foreground.rs b/implementations/rust/ockam/ockam_command/src/node/create/foreground.rs index 5e887fe67f6..65346b17bed 100644 --- a/implementations/rust/ockam/ockam_command/src/node/create/foreground.rs +++ b/implementations/rust/ockam/ockam_command/src/node/create/foreground.rs @@ -1,4 +1,4 @@ -use crate::node::show::is_node_up; +use crate::node::node_callback::NodeCallback; use crate::node::CreateCommand; use crate::util::foreground_args::wait_for_exit_signal; use crate::CommandGlobalOpts; @@ -9,15 +9,15 @@ use ockam::udp::{UdpBindArguments, UdpBindOptions, UdpTransport}; use ockam::Address; use ockam::Context; use ockam_api::fmt_log; -use ockam_api::nodes::service::NodeManagerTransport; -use ockam_api::nodes::BackgroundNodeClient; +use ockam_api::nodes::service::{NodeManagerTransport, SecureChannelType}; use ockam_api::nodes::InMemoryNode; use ockam_api::nodes::{ service::{NodeManagerGeneralOptions, NodeManagerTransportOptions}, NodeManagerWorker, NODEMANAGER_ADDR, }; use ockam_api::terminal::notification::NotificationHandler; -use ockam_core::{route, LOCAL}; + +use ockam_core::LOCAL; use std::sync::Arc; use tokio::time::{sleep, Duration}; use tracing::{debug, info, instrument}; @@ -85,7 +85,7 @@ impl CreateCommand { None }; - let node_man = InMemoryNode::new( + let in_memory_node = InMemoryNode::new( ctx, NodeManagerGeneralOptions::new( opts.state.clone(), @@ -104,15 +104,19 @@ impl CreateCommand { .into_diagnostic()?; debug!("in-memory node created"); - let node_manager = Arc::new(node_man); - let node_manager_worker = NodeManagerWorker::new(node_manager.clone()); + let in_memory_node = Arc::new(in_memory_node); + let node_manager_worker = NodeManagerWorker::new(in_memory_node.clone()); ctx.flow_controls() .add_consumer(&NODEMANAGER_ADDR.into(), tcp_listener.flow_control_id()); ctx.start_worker(NODEMANAGER_ADDR, node_manager_worker) .into_diagnostic()?; debug!("node manager worker started"); - if self.start_services(ctx, &opts).await.is_err() { + if self + .start_secure_channel_listener(ctx, &in_memory_node, &opts) + .await + .is_err() + { //TODO: Process should terminate on any error during its setup phase, // not just during the start_services. //TODO: This sleep here is a workaround on some orchestrated environment, @@ -126,7 +130,7 @@ impl CreateCommand { return Err(miette!("Failed to start services")); } - let node_resources = node_manager.get_node_resources().await?; + let node_resources = in_memory_node.get_node_resources().await?; opts.terminal .clone() .stdout() @@ -135,6 +139,10 @@ impl CreateCommand { .json_obj(&node_resources)? .write_line()?; + if let Some(tcp_callback_port) = self.tcp_callback_port { + NodeCallback::signal(tcp_callback_port); + } + wait_for_exit_signal( &self.foreground_args, &opts, @@ -144,38 +152,47 @@ impl CreateCommand { // Clean up and exit let _ = opts.state.stop_node(&node_name).await; + Ok(()) } - async fn start_services(&self, ctx: &Context, opts: &CommandGlobalOpts) -> miette::Result<()> { - if let Some(config) = &self.launch_configuration { - if let Some(startup_services) = &config.startup_services { - // Wait until the node is fully started - let mut node = - BackgroundNodeClient::create(ctx, &opts.state, &Some(self.name.clone())) - .await?; - if !is_node_up(ctx, &mut node, true).await? { - return Err(miette!( - "Couldn't start services because the node is not up" - )); - } - - if let Some(cfg) = startup_services.secure_channel_listener.clone() { - if !cfg.disabled { - opts.terminal - .write_line(fmt_log!("Starting secure-channel listener ..."))?; - crate::secure_channel::listener::create::create_listener( - ctx, - Address::from((LOCAL, cfg.address)), - cfg.authorized_identifiers, - cfg.identity, - route![], - ) - .await?; - } - } + async fn start_secure_channel_listener( + &self, + ctx: &Context, + in_memory_node: &InMemoryNode, + opts: &CommandGlobalOpts, + ) -> miette::Result<()> { + let launch_configuration = if let Some(launch_configuration) = &self.launch_configuration { + launch_configuration + } else { + return Ok(()); + }; + + let startup_services = + if let Some(startup_services) = &launch_configuration.startup_services { + startup_services + } else { + return Ok(()); + }; + + if let Some(cfg) = startup_services.secure_channel_listener.as_ref() { + if cfg.disabled { + return Ok(()); } + + opts.terminal + .write_line(fmt_log!("Starting secure-channel listener ..."))?; + in_memory_node + .create_secure_channel_listener( + Address::from((LOCAL, cfg.address.clone())), + cfg.authorized_identifiers.clone(), + cfg.identity.clone(), + ctx, + SecureChannelType::KeyExchangeAndMessages, + ) + .await?; } + Ok(()) } } diff --git a/implementations/rust/ockam/ockam_command/src/node/create/node_callback.rs b/implementations/rust/ockam/ockam_command/src/node/create/node_callback.rs new file mode 100644 index 00000000000..84e78d925fb --- /dev/null +++ b/implementations/rust/ockam/ockam_command/src/node/create/node_callback.rs @@ -0,0 +1,55 @@ +use miette::miette; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + +/// A callback node should call when it's up and running, implemented via creating a localhost TCP +/// connection +pub struct NodeCallback { + tcp_listener: tokio::net::TcpListener, + callback_port: u16, +} + +impl NodeCallback { + /// Create a callback and listen for incoming signal from the child node via TCP + pub async fn create() -> miette::Result { + let tcp_listener = + tokio::net::TcpListener::bind(SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0)) + .await + .map_err(|_| miette!("Failed to bind callback listener"))?; + + let callback_port = tcp_listener + .local_addr() + .map_err(|_| miette!("Failed to get callback listener port"))? + .port(); + + Ok(Self { + tcp_listener, + callback_port, + }) + } + + /// Wait for a signal from the child process + pub async fn wait_for_signal(self) -> miette::Result<()> { + _ = self + .tcp_listener + .accept() + .await + .map_err(|_| miette!("Failed to accept node callback connection"))?; + + Ok(()) + } + + /// Send the signal to the parent process + pub fn signal(callback_port: u16) { + // let the parent process or whatever started us know that we're up and running + // no need to wait for that operation to complete, so spawn to the background + tokio::spawn(tokio::net::TcpStream::connect(SocketAddr::new( + IpAddr::V4(Ipv4Addr::LOCALHOST), + callback_port, + ))); + } + + /// TPC port used for the callback + pub fn callback_port(&self) -> u16 { + self.callback_port + } +} diff --git a/implementations/rust/ockam/ockam_command/src/node/default.rs b/implementations/rust/ockam/ockam_command/src/node/default.rs index 186ac62b52f..82d4cfc415d 100644 --- a/implementations/rust/ockam/ockam_command/src/node/default.rs +++ b/implementations/rust/ockam/ockam_command/src/node/default.rs @@ -3,7 +3,6 @@ use colorful::Colorful; use miette::miette; use ockam_api::fmt_ok; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/default/long_about.txt"); @@ -21,17 +20,11 @@ pub struct DefaultCommand { } impl DefaultCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "node default".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { if let Some(node_name) = &self.node_name { if opts .state diff --git a/implementations/rust/ockam/ockam_command/src/node/delete.rs b/implementations/rust/ockam/ockam_command/src/node/delete.rs index ebb2d2a4e9e..6f9e62d4fe0 100644 --- a/implementations/rust/ockam/ockam_command/src/node/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/node/delete.rs @@ -1,6 +1,6 @@ use crate::terminal::tui::DeleteCommandTui; use crate::tui::PluralTerm; -use crate::util::{async_cmd, print_warning_for_deprecated_flag_no_effect}; +use crate::util::print_warning_for_deprecated_flag_no_effect; use crate::{docs, CommandGlobalOpts}; use clap::Args; use colorful::Colorful; @@ -38,17 +38,11 @@ pub struct DeleteCommand { } impl DeleteCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "node delete".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { if self.force { print_warning_for_deprecated_flag_no_effect(&opts, "--force")?; } diff --git a/implementations/rust/ockam/ockam_command/src/node/list.rs b/implementations/rust/ockam/ockam_command/src/node/list.rs index 550c52f60cf..5d241bbccdb 100644 --- a/implementations/rust/ockam/ockam_command/src/node/list.rs +++ b/implementations/rust/ockam/ockam_command/src/node/list.rs @@ -10,7 +10,6 @@ use tokio::try_join; use ockam_api::cli_state::nodes::NodeInfo; use ockam_api::colors::OckamColor; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts, Result}; use ockam_api::output::Output; @@ -28,17 +27,11 @@ after_long_help = docs::after_help(AFTER_LONG_HELP) pub struct ListCommand {} impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "node list".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { // Before printing node states we verify them. // We send a QueryStatus request to every node on // record. If the response yields a different pid to the diff --git a/implementations/rust/ockam/ockam_command/src/node/logs.rs b/implementations/rust/ockam/ockam_command/src/node/logs.rs index 9f6f0ca3c92..174ecf82a49 100644 --- a/implementations/rust/ockam/ockam_command/src/node/logs.rs +++ b/implementations/rust/ockam/ockam_command/src/node/logs.rs @@ -2,7 +2,6 @@ use clap::Args; use colorful::Colorful; use ockam_api::fmt_ok; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/logs/long_about.txt"); @@ -22,16 +21,11 @@ pub struct LogCommand { } impl LogCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } pub fn name(&self) -> String { "node logs".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { let node_name = opts .state .get_node_or_default(&self.node_name) diff --git a/implementations/rust/ockam/ockam_command/src/node/mod.rs b/implementations/rust/ockam/ockam_command/src/node/mod.rs index da0e61a511d..35c919c5ee2 100644 --- a/implementations/rust/ockam/ockam_command/src/node/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/node/mod.rs @@ -7,6 +7,7 @@ use delete::DeleteCommand; use list::ListCommand; use logs::LogCommand; use ockam_api::address::extract_address_value; +use ockam_node::Context; use show::ShowCommand; use start::StartCommand; use stop::StopCommand; @@ -74,16 +75,16 @@ impl NodeSubcommand { } impl NodeCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - NodeSubcommand::Create(c) => c.run(opts), - NodeSubcommand::Delete(c) => c.run(opts), - NodeSubcommand::List(c) => c.run(opts), - NodeSubcommand::Show(c) => c.run(opts), - NodeSubcommand::Start(c) => c.run(opts), - NodeSubcommand::Stop(c) => c.run(opts), - NodeSubcommand::Logs(c) => c.run(opts), - NodeSubcommand::Default(c) => c.run(opts), + NodeSubcommand::Create(c) => c.run(ctx, opts).await, + NodeSubcommand::Delete(c) => c.run(opts).await, + NodeSubcommand::List(c) => c.run(opts).await, + NodeSubcommand::Show(c) => c.run(ctx, opts).await, + NodeSubcommand::Start(c) => c.run(ctx, opts).await, + NodeSubcommand::Stop(c) => c.run(opts).await, + NodeSubcommand::Logs(c) => c.run(opts).await, + NodeSubcommand::Default(c) => c.run(opts).await, } } } diff --git a/implementations/rust/ockam/ockam_command/src/node/show.rs b/implementations/rust/ockam/ockam_command/src/node/show.rs index 7e2b6b189e0..a4cf422571d 100644 --- a/implementations/rust/ockam/ockam_command/src/node/show.rs +++ b/implementations/rust/ockam/ockam_command/src/node/show.rs @@ -1,18 +1,13 @@ use async_trait::async_trait; -use std::ops::Add; use std::time::Duration; use clap::Args; use console::Term; use miette::IntoDiagnostic; - -use ockam_api::CliState; -use tokio_retry::strategy::FixedInterval; -use tracing::{debug, info, trace, warn}; - -use ockam_api::nodes::models::node::{NodeResources, NodeStatus}; +use ockam_api::nodes::models::node::NodeResources; use ockam_api::nodes::BackgroundNodeClient; use ockam_api::terminal::{Terminal, TerminalStream}; +use ockam_api::CliState; use ockam_core::TryClone; use ockam_node::Context; @@ -25,12 +20,6 @@ const LONG_ABOUT: &str = include_str!("./static/show/long_about.txt"); const PREVIEW_TAG: &str = include_str!("../static/preview_tag.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/show/after_long_help.txt"); -const IS_NODE_ACCESSIBLE_TIME_BETWEEN_CHECKS_MS: u64 = 25; -const IS_NODE_ACCESSIBLE_TIMEOUT: Duration = Duration::from_secs(5); - -const IS_NODE_READY_TIME_BETWEEN_CHECKS_MS: u64 = 25; -const IS_NODE_READY_TIMEOUT: Duration = Duration::from_secs(10); - /// Show the details of a node #[derive(Clone, Debug, Args)] #[command( @@ -48,7 +37,7 @@ pub struct ShowCommand { impl Command for ShowCommand { const NAME: &'static str = "node show"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { Ok(ShowTui::run(ctx, opts, self.node_name.clone()).await?) } } @@ -110,8 +99,7 @@ impl ShowCommandTui for ShowTui { let mut node = BackgroundNodeClient::create(&self.ctx, &self.opts.state, &Some(item_name.to_string())) .await?; - let node_resources = - get_node_resources(&self.ctx, &self.opts.state, &mut node, false).await?; + let node_resources = get_node_resources(&self.ctx, &self.opts.state, &mut node).await?; self.opts .terminal .clone() @@ -127,131 +115,17 @@ pub async fn get_node_resources( ctx: &Context, cli_state: &CliState, node: &mut BackgroundNodeClient, - wait_until_ready: bool, ) -> miette::Result { - let node_name = node.node_name(); - if is_node_up(ctx, node, wait_until_ready).await? { - Ok(node.ask(ctx, api::get_node_resources()).await?) - } else { - let node_info = cli_state.get_node(&node_name).await?; - let identity = cli_state - .get_named_identity_by_identifier(&node_info.identifier()) - .await?; - NodeResources::empty(node_info, identity.name()).into_diagnostic() - } -} - -/// Wait for a node to be up. We wait until the IS_NODE_ACCESSIBLE_TIMEOUT is passed and return `false` -/// if the node is not up after that time. -pub async fn wait_until_node_is_up( - ctx: &Context, - cli_state: &CliState, - node_name: String, -) -> Result { - let mut node = BackgroundNodeClient::create(ctx, cli_state, &Some(node_name)).await?; - is_node_up(ctx, &mut node, true).await -} - -/// Send message(s) to a node to determine if it is 'up' and -/// responding to requests. -/// -/// If `wait_until_ready` is `true` and the node does not -/// appear to be 'up', retry the test at time intervals up to -/// a maximum number of retries. A use case for this is to -/// allow a node time to start up and become ready. -pub async fn is_node_up( - ctx: &Context, - node: &mut BackgroundNodeClient, - wait_until_ready: bool, -) -> Result { - debug!("waiting for node to be up"); - let node_name = node.node_name(); - // Check if node is already up and running to skip the accessible/ready checks - if let Ok(status) = node - .ask_with_timeout::<(), NodeStatus>(ctx, api::query_status(), Duration::from_secs(1)) + if let Ok(resources) = node + .ask_with_timeout(ctx, api::get_node_resources(), Duration::from_secs(1)) .await { - if status.process_status.is_running() { - return Ok(true); - } - } - if !is_node_accessible(ctx, node, wait_until_ready).await? { - warn!(%node_name, "the node was not accessible in time"); - return Ok(false); - } - if !is_node_ready(ctx, node, wait_until_ready).await? { - warn!(%node_name, "the node was not ready in time"); - return Ok(false); - } - Ok(true) -} - -/// Return true if the node is accessible via TCP -async fn is_node_accessible( - ctx: &Context, - node: &mut BackgroundNodeClient, - wait_until_ready: bool, -) -> Result { - let node_name = node.node_name(); - let retries = FixedInterval::from_millis(IS_NODE_ACCESSIBLE_TIME_BETWEEN_CHECKS_MS); - let mut total_time = Duration::from_secs(0); - for timeout_duration in retries { - // Max time exceeded - if total_time >= IS_NODE_ACCESSIBLE_TIMEOUT { - return Ok(false); - }; - // We don't wait and didn't succeed in the first try - if !wait_until_ready && !total_time.is_zero() { - return Ok(false); - } - // Check if node is accessible - if node.is_accessible(ctx).await.is_ok() { - info!(%node_name, "node is accessible"); - return Ok(true); - } - trace!(%node_name, "node is not accessible"); - tokio::time::sleep(timeout_duration).await; - total_time = total_time.add(timeout_duration) + return Ok(resources); } - Ok(false) -} -/// Return true if the node has been initialized and is ready to accept requests -async fn is_node_ready( - ctx: &Context, - node: &mut BackgroundNodeClient, - wait_until_ready: bool, -) -> Result { - let node_name = node.node_name(); - let retries = FixedInterval::from_millis(IS_NODE_READY_TIME_BETWEEN_CHECKS_MS); - let now = std::time::Instant::now(); - let mut total_time = Duration::from_secs(0); - for timeout_duration in retries { - // Max time exceeded - if total_time >= IS_NODE_READY_TIMEOUT { - return Ok(false); - }; - // We don't wait and didn't succeed in the first try - if !wait_until_ready && !total_time.is_zero() { - return Ok(false); - } - // Check if node is ready - let result = node - .ask_with_timeout::<(), NodeStatus>(ctx, api::query_status(), Duration::from_secs(1)) - .await; - if let Ok(node_status) = result { - if node_status.process_status.is_running() { - let elapsed = now.elapsed(); - info!(%node_name, ?elapsed, "node is ready"); - return Ok(true); - } else { - trace!(%node_name, "node is initializing"); - } - } else { - trace!(%node_name, "node is initializing"); - } - tokio::time::sleep(timeout_duration).await; - total_time = total_time.add(timeout_duration) - } - Ok(false) + let node_info = cli_state.get_node(node.node_name()).await?; + let identity = cli_state + .get_named_identity_by_identifier(&node_info.identifier()) + .await?; + NodeResources::empty(node_info, identity.name()).into_diagnostic() } diff --git a/implementations/rust/ockam/ockam_command/src/node/start.rs b/implementations/rust/ockam/ockam_command/src/node/start.rs index 5cad5e3a02c..35480f6503f 100644 --- a/implementations/rust/ockam/ockam_command/src/node/start.rs +++ b/implementations/rust/ockam/ockam_command/src/node/start.rs @@ -8,10 +8,10 @@ use ockam_api::nodes::BackgroundNodeClient; use ockam_node::Context; +use crate::node::node_callback::NodeCallback; use crate::node::show::get_node_resources; use crate::node::util::spawn_node; use crate::node::CreateCommand; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/start/long_about.txt"); @@ -31,17 +31,11 @@ pub struct StartCommand { } impl StartCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "node start".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { if self.node_name.is_some() || !opts.terminal.can_ask_for_user_input() { let node_name = opts .state @@ -126,8 +120,8 @@ async fn start_single_node( return Ok(()); } - let mut node: BackgroundNodeClient = run_node(node_name, ctx, &opts).await?; - let node_status = get_node_resources(ctx, &opts.state, &mut node, true).await?; + let mut node = run_node(node_name, ctx, &opts).await?; + let node_status = get_node_resources(ctx, &opts.state, &mut node).await?; opts.terminal .stdout() .plain(&node_status) @@ -173,17 +167,27 @@ async fn run_node( .map(|a| a.to_string()) .unwrap_or("no transport address".to_string()); + let node_callback = NodeCallback::create().await?; + // Restart node #[allow(clippy::field_reassign_with_default)] let cmd = { let mut cmd = CreateCommand::default(); cmd.name = node_name.to_string(); cmd.tcp_listener_address = node_address; + cmd.tcp_callback_port = Some(node_callback.callback_port()); cmd }; - spawn_node(opts, cmd).await?; + + let handle = spawn_node(opts, cmd)?; + + tokio::select! { + _ = handle.wait_with_output() => { std::process::exit(1) } + _ = node_callback.wait_for_signal() => {} + } let node = BackgroundNodeClient::create_to_node(ctx, &opts.state, node_name)?; + Ok(node) } diff --git a/implementations/rust/ockam/ockam_command/src/node/stop.rs b/implementations/rust/ockam/ockam_command/src/node/stop.rs index 970472ae01a..b7cc3cc971f 100644 --- a/implementations/rust/ockam/ockam_command/src/node/stop.rs +++ b/implementations/rust/ockam/ockam_command/src/node/stop.rs @@ -4,7 +4,7 @@ use miette::miette; use ockam_api::colors::OckamColor; use ockam_api::{color, fmt_info, fmt_ok, fmt_warn}; -use crate::util::{async_cmd, print_warning_for_deprecated_flag_no_effect}; +use crate::util::print_warning_for_deprecated_flag_no_effect; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/stop/long_about.txt"); @@ -28,17 +28,11 @@ pub struct StopCommand { } impl StopCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "node stop".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { if self.force { print_warning_for_deprecated_flag_no_effect(&opts, "--force")?; } diff --git a/implementations/rust/ockam/ockam_command/src/node/util.rs b/implementations/rust/ockam/ockam_command/src/node/util.rs index d03dd5a96f1..5996581f7c5 100644 --- a/implementations/rust/ockam/ockam_command/src/node/util.rs +++ b/implementations/rust/ockam/ockam_command/src/node/util.rs @@ -1,16 +1,15 @@ -use crate::node::show::wait_until_node_is_up; use crate::node::CreateCommand; use crate::run::parser::resource::utils::subprocess_stdio; use crate::shared_args::TrustOpts; -use crate::{Command as CommandTrait, CommandGlobalOpts}; -use miette::Context as _; +use crate::{Command, CommandGlobalOpts}; use miette::IntoDiagnostic; +use miette::{miette, Context as _}; use ockam_core::env::get_env_with_default; use ockam_node::Context; use rand::random; use std::env::current_exe; use std::process::Stdio; -use tokio::process::{Child, Command}; +use tokio::process::{Child, Command as TokioCommand}; use tracing::info; pub struct NodeManagerDefaults { @@ -39,12 +38,12 @@ pub async fn initialize_default_node( return Ok(()); } else if opts.state.get_default_node().await.is_err() { let cmd = CreateCommand::default(); - cmd.async_run(ctx, opts.clone()).await?; + cmd.run(ctx, opts.clone()).await?; opts.terminal.write_line("")?; } else { let node = opts.state.get_default_node().await?; if !node.is_running() { - wait_until_node_is_up(ctx, &opts.state, node.name()).await?; + return Err(miette!("Default node exists but is not running")); } } Ok(()) @@ -52,8 +51,7 @@ pub async fn initialize_default_node( /// Construct the argument list and re-execute the ockam /// CLI in foreground mode to start the newly created node -#[allow(clippy::too_many_arguments)] -pub async fn spawn_node(opts: &CommandGlobalOpts, cmd: CreateCommand) -> miette::Result { +pub fn spawn_node(opts: &CommandGlobalOpts, cmd: CreateCommand) -> miette::Result { info!( "preparing to spawn a new node with name {} in the background", &cmd.name @@ -75,6 +73,7 @@ pub async fn spawn_node(opts: &CommandGlobalOpts, cmd: CreateCommand) -> miette: trust_opts, opentelemetry_context, in_memory, + tcp_callback_port, } = cmd; let mut args = vec![ @@ -185,13 +184,18 @@ pub async fn spawn_node(opts: &CommandGlobalOpts, cmd: CreateCommand) -> miette: args.push("--in-memory".to_string()); } + if let Some(tcp_callback_port) = tcp_callback_port { + args.push("--tcp-callback-port".to_string()); + args.push(tcp_callback_port.to_string()); + } + args.push(name.to_owned()); - run_ockam(args, opts.global_args.quiet).await + run_ockam(args, opts.global_args.quiet) } /// Run the ockam command line with specific arguments -pub async fn run_ockam(args: Vec, quiet: bool) -> miette::Result { +pub fn run_ockam(args: Vec, quiet: bool) -> miette::Result { info!("spawning a new process"); // On systems with non-obvious path setups (or during @@ -204,7 +208,7 @@ pub async fn run_ockam(args: Vec, quiet: bool) -> miette::Result }); unsafe { - Command::new(ockam_exe) + TokioCommand::new(ockam_exe) .args(args) .stdout(subprocess_stdio(quiet)) .stderr(subprocess_stdio(quiet)) diff --git a/implementations/rust/ockam/ockam_command/src/policy/create.rs b/implementations/rust/ockam/ockam_command/src/policy/create.rs index 833070669e3..6123bd826b7 100644 --- a/implementations/rust/ockam/ockam_command/src/policy/create.rs +++ b/implementations/rust/ockam/ockam_command/src/policy/create.rs @@ -48,7 +48,7 @@ pub struct CreateCommand { impl Command for CreateCommand { const NAME: &'static str = "policy create"; - async fn async_run(mut self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(mut self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { initialize_default_node(ctx, &opts).await?; // Backwards compatibility diff --git a/implementations/rust/ockam/ockam_command/src/policy/delete.rs b/implementations/rust/ockam/ockam_command/src/policy/delete.rs index ac95fa061ee..3c14609ba08 100644 --- a/implementations/rust/ockam/ockam_command/src/policy/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/policy/delete.rs @@ -17,7 +17,6 @@ use ockam_core::TryClone; use crate::terminal::tui::DeleteCommandTui; use crate::tui::PluralTerm; -use crate::util::async_cmd; #[derive(Clone, Debug, Args)] pub struct DeleteCommand { @@ -32,17 +31,11 @@ pub struct DeleteCommand { } impl DeleteCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "policy delete".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { DeleteTui::run(ctx, opts, self.clone()).await } } diff --git a/implementations/rust/ockam/ockam_command/src/policy/list.rs b/implementations/rust/ockam/ockam_command/src/policy/list.rs index 1c340e2baee..a7b5928b3dc 100644 --- a/implementations/rust/ockam/ockam_command/src/policy/list.rs +++ b/implementations/rust/ockam/ockam_command/src/policy/list.rs @@ -9,7 +9,6 @@ use ockam_api::colors::color_primary; use ockam_api::nodes::models::policies::ResourceTypeOrName; use ockam_api::nodes::{BackgroundNodeClient, Policies}; -use crate::util::async_cmd; use crate::CommandGlobalOpts; #[derive(Clone, Debug, Args)] @@ -21,17 +20,11 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "policy list".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.at).await?; let is_finished: Mutex = Mutex::new(false); diff --git a/implementations/rust/ockam/ockam_command/src/policy/mod.rs b/implementations/rust/ockam/ockam_command/src/policy/mod.rs index dbe1e980bb0..a59b385c1db 100644 --- a/implementations/rust/ockam/ockam_command/src/policy/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/policy/mod.rs @@ -3,14 +3,15 @@ use std::str::FromStr; use clap::{Args, Subcommand}; use miette::miette; -use ockam_abac::ResourceType; - pub use crate::policy::create::CreateCommand; use crate::policy::delete::DeleteCommand; use crate::policy::list::ListCommand; use crate::policy::show::ShowCommand; use crate::{Command, CommandGlobalOpts}; +use ockam_abac::ResourceType; +use ockam_node::Context; + mod create; mod delete; mod list; @@ -43,12 +44,12 @@ impl PolicySubcommand { } impl PolicyCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - PolicySubcommand::Create(c) => c.run(opts), - PolicySubcommand::Show(c) => c.run(opts), - PolicySubcommand::Delete(c) => c.run(opts), - PolicySubcommand::List(c) => c.run(opts), + PolicySubcommand::Create(c) => c.run(ctx, opts).await, + PolicySubcommand::Show(c) => c.run(ctx, opts).await, + PolicySubcommand::Delete(c) => c.run(ctx, opts).await, + PolicySubcommand::List(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/policy/show.rs b/implementations/rust/ockam/ockam_command/src/policy/show.rs index f1660520ddc..2df01bf4133 100644 --- a/implementations/rust/ockam/ockam_command/src/policy/show.rs +++ b/implementations/rust/ockam/ockam_command/src/policy/show.rs @@ -17,7 +17,6 @@ use ockam_core::TryClone; use crate::terminal::tui::ShowCommandTui; use crate::tui::PluralTerm; -use crate::util::async_cmd; #[derive(Clone, Debug, Args)] pub struct ShowCommand { @@ -28,17 +27,11 @@ pub struct ShowCommand { } impl ShowCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "policy show".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { ShowTui::run(ctx, opts, self.clone()).await } } diff --git a/implementations/rust/ockam/ockam_command/src/project/addon/configure_influxdb.rs b/implementations/rust/ockam/ockam_command/src/project/addon/configure_influxdb.rs index f6478c1d59e..74034743b20 100644 --- a/implementations/rust/ockam/ockam_command/src/project/addon/configure_influxdb.rs +++ b/implementations/rust/ockam/ockam_command/src/project/addon/configure_influxdb.rs @@ -12,7 +12,6 @@ use ockam_api::orchestrator::addon::Addons; use ockam_api::orchestrator::project::models::InfluxDBTokenLeaseManagerConfig; use crate::project::addon::check_configuration_completion; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/configure_influxdb/long_about.txt"); @@ -114,17 +113,11 @@ pub struct AddonConfigureInfluxdbSubcommand { } impl AddonConfigureInfluxdbSubcommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "project addon configure influxdb".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let project_id = opts .state .projects() diff --git a/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka.rs b/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka.rs index 6bc32a7c982..7bc25dbde3b 100644 --- a/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka.rs +++ b/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka.rs @@ -13,7 +13,6 @@ pub use redpanda::AddonConfigureRedpandaSubcommand; pub use warpstream::AddonConfigureWarpstreamSubcommand; use crate::project::addon::check_configuration_completion; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; pub mod aiven; @@ -59,17 +58,11 @@ pub struct AddonConfigureKafkaSubcommand { } impl AddonConfigureKafkaSubcommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts, "Apache Kafka").await - }) - } - pub fn name(&self) -> String { "configure kafka addon".into() } - async fn async_run( + pub async fn run( &self, ctx: &Context, opts: CommandGlobalOpts, diff --git a/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/aiven.rs b/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/aiven.rs index 5db123cc23e..ccc6ea2056f 100644 --- a/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/aiven.rs +++ b/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/aiven.rs @@ -1,9 +1,10 @@ use clap::Args; use crate::project::addon::configure_kafka::{AddonConfigureKafkaSubcommand, KafkaCommandConfig}; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; +use ockam_node::Context; + const LONG_ABOUT: &str = include_str!("../static/configure_aiven/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("../static/configure_aiven/after_long_help.txt"); @@ -19,14 +20,12 @@ pub struct AddonConfigureAivenSubcommand { } impl AddonConfigureAivenSubcommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - AddonConfigureKafkaSubcommand { - config: self.config, - } - .async_run(&ctx, opts, "Aiven (Kafka)") - .await - }) + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + AddonConfigureKafkaSubcommand { + config: self.config, + } + .run(ctx, opts, "Aiven (Kafka)") + .await } pub fn name(&self) -> String { diff --git a/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/confluent.rs b/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/confluent.rs index 313cd128801..98aebbcd674 100644 --- a/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/confluent.rs +++ b/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/confluent.rs @@ -1,9 +1,10 @@ use clap::Args; use crate::project::addon::configure_kafka::{AddonConfigureKafkaSubcommand, KafkaCommandConfig}; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; +use ockam_node::Context; + const LONG_ABOUT: &str = include_str!("../static/configure_confluent/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("../static/configure_confluent/after_long_help.txt"); @@ -19,14 +20,12 @@ pub struct AddonConfigureConfluentSubcommand { } impl AddonConfigureConfluentSubcommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - AddonConfigureKafkaSubcommand { - config: self.config, - } - .async_run(&ctx, opts, "Confluent") - .await - }) + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + AddonConfigureKafkaSubcommand { + config: self.config, + } + .run(ctx, opts, "Confluent") + .await } pub fn name(&self) -> String { diff --git a/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/instaclustr.rs b/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/instaclustr.rs index 6ff05d24d5f..8c3598dde2a 100644 --- a/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/instaclustr.rs +++ b/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/instaclustr.rs @@ -1,9 +1,10 @@ use clap::Args; use crate::project::addon::configure_kafka::{AddonConfigureKafkaSubcommand, KafkaCommandConfig}; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; +use ockam_node::Context; + const LONG_ABOUT: &str = include_str!("../static/configure_instaclustr/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("../static/configure_instaclustr/after_long_help.txt"); @@ -19,14 +20,12 @@ pub struct AddonConfigureInstaclustrSubcommand { } impl AddonConfigureInstaclustrSubcommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - AddonConfigureKafkaSubcommand { - config: self.config, - } - .async_run(&ctx, opts, "Instaclustr (Kafka)") - .await - }) + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + AddonConfigureKafkaSubcommand { + config: self.config, + } + .run(ctx, opts, "Instaclustr (Kafka)") + .await } pub fn name(&self) -> String { diff --git a/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/redpanda.rs b/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/redpanda.rs index d1c2c9b8a66..d0745aada83 100644 --- a/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/redpanda.rs +++ b/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/redpanda.rs @@ -1,9 +1,10 @@ use clap::Args; use crate::project::addon::configure_kafka::{AddonConfigureKafkaSubcommand, KafkaCommandConfig}; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; +use ockam_node::Context; + const LONG_ABOUT: &str = include_str!("../static/configure_redpanda/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("../static/configure_redpanda/after_long_help.txt"); @@ -19,14 +20,12 @@ pub struct AddonConfigureRedpandaSubcommand { } impl AddonConfigureRedpandaSubcommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - AddonConfigureKafkaSubcommand { - config: self.config, - } - .async_run(&ctx, opts, "Redpanda") - .await - }) + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + AddonConfigureKafkaSubcommand { + config: self.config, + } + .run(ctx, opts, "Redpanda") + .await } pub fn name(&self) -> String { diff --git a/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/warpstream.rs b/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/warpstream.rs index d45d6ac63c2..201cd94dd1e 100644 --- a/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/warpstream.rs +++ b/implementations/rust/ockam/ockam_command/src/project/addon/configure_kafka/warpstream.rs @@ -1,9 +1,10 @@ use clap::Args; use crate::project::addon::configure_kafka::{AddonConfigureKafkaSubcommand, KafkaCommandConfig}; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; +use ockam_node::Context; + const LONG_ABOUT: &str = include_str!("../static/configure_warpstream/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("../static/configure_warpstream/after_long_help.txt"); @@ -19,14 +20,12 @@ pub struct AddonConfigureWarpstreamSubcommand { } impl AddonConfigureWarpstreamSubcommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - AddonConfigureKafkaSubcommand { - config: self.config, - } - .async_run(&ctx, opts, "Warpstream") - .await - }) + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + AddonConfigureKafkaSubcommand { + config: self.config, + } + .run(ctx, opts, "Warpstream") + .await } pub fn name(&self) -> String { diff --git a/implementations/rust/ockam/ockam_command/src/project/addon/configure_okta.rs b/implementations/rust/ockam/ockam_command/src/project/addon/configure_okta.rs index b662721932c..e5255b951fa 100644 --- a/implementations/rust/ockam/ockam_command/src/project/addon/configure_okta.rs +++ b/implementations/rust/ockam/ockam_command/src/project/addon/configure_okta.rs @@ -21,7 +21,6 @@ use ockam_core::errcode::{Kind, Origin}; use ockam_core::Error; use crate::project::addon::check_configuration_completion; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts, Result}; const LONG_ABOUT: &str = include_str!("./static/configure_influxdb/long_about.txt"); @@ -83,17 +82,11 @@ pub struct AddonConfigureOktaSubcommand { } impl AddonConfigureOktaSubcommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "project addon configure okta".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let project_id = opts .state .projects() diff --git a/implementations/rust/ockam/ockam_command/src/project/addon/disable.rs b/implementations/rust/ockam/ockam_command/src/project/addon/disable.rs index 28fba2c2f19..d94f6c8821e 100644 --- a/implementations/rust/ockam/ockam_command/src/project/addon/disable.rs +++ b/implementations/rust/ockam/ockam_command/src/project/addon/disable.rs @@ -8,7 +8,6 @@ use ockam_api::nodes::InMemoryNode; use ockam_api::orchestrator::addon::Addons; use crate::operation::util::check_for_operation_completion; -use crate::util::async_cmd; use crate::CommandGlobalOpts; /// Disable an addon for a project @@ -34,17 +33,11 @@ pub struct AddonDisableSubcommand { } impl AddonDisableSubcommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "project addon disable".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let project_id = opts .state .projects() diff --git a/implementations/rust/ockam/ockam_command/src/project/addon/list.rs b/implementations/rust/ockam/ockam_command/src/project/addon/list.rs index 2cdcb1e5d7b..eb971f9cda6 100644 --- a/implementations/rust/ockam/ockam_command/src/project/addon/list.rs +++ b/implementations/rust/ockam/ockam_command/src/project/addon/list.rs @@ -5,7 +5,6 @@ use ockam::Context; use ockam_api::nodes::InMemoryNode; use ockam_api::orchestrator::addon::Addons; -use crate::util::async_cmd; use crate::CommandGlobalOpts; /// List available addons for a project @@ -22,17 +21,11 @@ pub struct AddonListSubcommand { } impl AddonListSubcommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "project addon list".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let project_name = self.project_name.clone(); let project_id = opts .state diff --git a/implementations/rust/ockam/ockam_command/src/project/addon/mod.rs b/implementations/rust/ockam/ockam_command/src/project/addon/mod.rs index 4a420b0f67c..4107dc71944 100644 --- a/implementations/rust/ockam/ockam_command/src/project/addon/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/project/addon/mod.rs @@ -43,11 +43,11 @@ pub enum AddonSubcommand { } impl AddonCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - AddonSubcommand::List(cmd) => cmd.run(opts), - AddonSubcommand::Disable(cmd) => cmd.run(opts), - AddonSubcommand::Configure(cmd) => cmd.run(opts), + AddonSubcommand::List(cmd) => cmd.run(ctx, opts).await, + AddonSubcommand::Disable(cmd) => cmd.run(ctx, opts).await, + AddonSubcommand::Configure(cmd) => cmd.run(ctx, opts).await, } } @@ -74,16 +74,16 @@ pub enum ConfigureAddonCommand { } impl ConfigureAddonCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self { - ConfigureAddonCommand::Okta(cmd) => cmd.run(opts), - ConfigureAddonCommand::Influxdb(cmd) => cmd.run(opts), - ConfigureAddonCommand::Confluent(cmd) => cmd.run(opts), - ConfigureAddonCommand::InstaclustrKafka(cmd) => cmd.run(opts), - ConfigureAddonCommand::AivenKafka(cmd) => cmd.run(opts), - ConfigureAddonCommand::Redpanda(cmd) => cmd.run(opts), - ConfigureAddonCommand::Warpstream(cmd) => cmd.run(opts), - ConfigureAddonCommand::Kafka(cmd) => cmd.run(opts), + ConfigureAddonCommand::Okta(cmd) => cmd.run(ctx, opts).await, + ConfigureAddonCommand::Influxdb(cmd) => cmd.run(ctx, opts).await, + ConfigureAddonCommand::Confluent(cmd) => cmd.run(ctx, opts).await, + ConfigureAddonCommand::InstaclustrKafka(cmd) => cmd.run(ctx, opts).await, + ConfigureAddonCommand::AivenKafka(cmd) => cmd.run(ctx, opts).await, + ConfigureAddonCommand::Redpanda(cmd) => cmd.run(ctx, opts).await, + ConfigureAddonCommand::Warpstream(cmd) => cmd.run(ctx, opts).await, + ConfigureAddonCommand::Kafka(cmd) => cmd.run(ctx, opts, "Apache Kafka").await, } } diff --git a/implementations/rust/ockam/ockam_command/src/project/create.rs b/implementations/rust/ockam/ockam_command/src/project/create.rs index 9c0a9f73834..62dd993d082 100644 --- a/implementations/rust/ockam/ockam_command/src/project/create.rs +++ b/implementations/rust/ockam/ockam_command/src/project/create.rs @@ -8,7 +8,6 @@ use ockam_api::orchestrator::project::ProjectsOrchestratorApi; use crate::operation::util::check_for_project_completion; use crate::project::util::check_project_readiness; use crate::shared_args::IdentityOpts; -use crate::util::async_cmd; use crate::util::parsers::project_name_parser; use crate::{docs, CommandGlobalOpts}; use ockam_api::output::Output; @@ -37,21 +36,11 @@ pub struct CreateCommand { } impl CreateCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "project create".into() } - pub(crate) async fn async_run( - &self, - ctx: &Context, - opts: CommandGlobalOpts, - ) -> miette::Result<()> { + pub(crate) async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = InMemoryNode::start(ctx, &opts.state).await?; let project = node .create_project(ctx, &self.space_name, &self.project_name, vec![]) diff --git a/implementations/rust/ockam/ockam_command/src/project/delete.rs b/implementations/rust/ockam/ockam_command/src/project/delete.rs index 10b7d0da5b6..66edae70963 100644 --- a/implementations/rust/ockam/ockam_command/src/project/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/project/delete.rs @@ -7,7 +7,6 @@ use ockam_api::nodes::InMemoryNode; use ockam_api::orchestrator::project::ProjectsOrchestratorApi; use crate::shared_args::IdentityOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/delete/long_about.txt"); @@ -37,17 +36,11 @@ pub struct DeleteCommand { } impl DeleteCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "project delete".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { if opts.terminal.confirmed_with_flag_or_prompt( self.yes, "Are you sure you want to delete this project?", diff --git a/implementations/rust/ockam/ockam_command/src/project/enroll.rs b/implementations/rust/ockam/ockam_command/src/project/enroll.rs index 4fe230cf08e..bc9a736a178 100644 --- a/implementations/rust/ockam/ockam_command/src/project/enroll.rs +++ b/implementations/rust/ockam/ockam_command/src/project/enroll.rs @@ -89,7 +89,7 @@ impl Command for EnrollCommand { Some(self.retry_opts.clone()) } - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { // Store project if an enrollment ticket is passed let (project, enrollment_ticket) = if let Some(enrollment_ticket) = &self.enrollment_ticket { diff --git a/implementations/rust/ockam/ockam_command/src/project/import.rs b/implementations/rust/ockam/ockam_command/src/project/import.rs index b5d27479855..fb180b6d090 100644 --- a/implementations/rust/ockam/ockam_command/src/project/import.rs +++ b/implementations/rust/ockam/ockam_command/src/project/import.rs @@ -6,7 +6,6 @@ use miette::IntoDiagnostic; use ockam_api::fmt_ok; use ockam_api::orchestrator::project::models::ProjectModel; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/import/long_about.txt"); @@ -26,17 +25,11 @@ pub struct ImportCommand { } impl ImportCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "project import".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { let file_content = std::fs::read_to_string(&self.project_file).into_diagnostic()?; let project: ProjectModel = serde_json::from_str(&file_content).into_diagnostic()?; opts.state diff --git a/implementations/rust/ockam/ockam_command/src/project/info.rs b/implementations/rust/ockam/ockam_command/src/project/info.rs index 2b194750ddc..4bb2f1fe074 100644 --- a/implementations/rust/ockam/ockam_command/src/project/info.rs +++ b/implementations/rust/ockam/ockam_command/src/project/info.rs @@ -7,7 +7,6 @@ use ockam_api::orchestrator::project::ProjectsOrchestratorApi; use ockam_api::output::Output; use crate::shared_args::IdentityOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; /// Show project details @@ -23,17 +22,11 @@ pub struct InfoCommand { } impl InfoCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "project information".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = InMemoryNode::start(ctx, &opts.state).await?; let project = node.get_project_by_name(ctx, &self.name).await?; opts.terminal diff --git a/implementations/rust/ockam/ockam_command/src/project/list.rs b/implementations/rust/ockam/ockam_command/src/project/list.rs index 2a69a1d6145..f99f05f7432 100644 --- a/implementations/rust/ockam/ockam_command/src/project/list.rs +++ b/implementations/rust/ockam/ockam_command/src/project/list.rs @@ -9,7 +9,6 @@ use ockam_api::nodes::InMemoryNode; use ockam_api::orchestrator::project::ProjectsOrchestratorApi; use crate::shared_args::IdentityOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/list/long_about.txt"); @@ -29,17 +28,11 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "project list".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = InMemoryNode::start(ctx, &opts.state).await?; let is_finished: Mutex = Mutex::new(false); let get_projects = async { diff --git a/implementations/rust/ockam/ockam_command/src/project/mod.rs b/implementations/rust/ockam/ockam_command/src/project/mod.rs index 739c476e73a..0dd06b651af 100644 --- a/implementations/rust/ockam/ockam_command/src/project/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/project/mod.rs @@ -21,11 +21,14 @@ mod ticket; #[allow(unused)] pub mod util; mod version; + pub use addon::AddonCommand; pub use create::CreateCommand; pub use delete::DeleteCommand; pub use ticket::TicketCommand; +use ockam_node::Context; + const LONG_ABOUT: &str = include_str!("./static/long_about.txt"); #[derive(Clone, Debug, Args)] @@ -55,18 +58,18 @@ pub enum ProjectSubcommand { } impl ProjectCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - ProjectSubcommand::Enroll(c) => c.run(opts), - ProjectSubcommand::Import(c) => c.run(opts), - ProjectSubcommand::List(c) => c.run(opts), - ProjectSubcommand::Show(c) => c.run(opts), - ProjectSubcommand::Version(c) => c.run(opts), - ProjectSubcommand::Information(c) => c.run(opts), - ProjectSubcommand::Ticket(c) => c.run(opts), - ProjectSubcommand::Create(c) => c.run(opts), - ProjectSubcommand::Delete(c) => c.run(opts), - ProjectSubcommand::Addon(c) => c.run(opts), + ProjectSubcommand::Enroll(c) => c.run(ctx, opts).await, + ProjectSubcommand::Import(c) => c.run(opts).await, + ProjectSubcommand::List(c) => c.run(ctx, opts).await, + ProjectSubcommand::Show(c) => c.run(ctx, opts).await, + ProjectSubcommand::Version(c) => c.run(ctx, opts).await, + ProjectSubcommand::Information(c) => c.run(ctx, opts).await, + ProjectSubcommand::Ticket(c) => c.run(ctx, opts).await, + ProjectSubcommand::Create(c) => c.run(ctx, opts).await, + ProjectSubcommand::Delete(c) => c.run(ctx, opts).await, + ProjectSubcommand::Addon(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/project/show.rs b/implementations/rust/ockam/ockam_command/src/project/show.rs index e240a716571..3c3dd1636be 100644 --- a/implementations/rust/ockam/ockam_command/src/project/show.rs +++ b/implementations/rust/ockam/ockam_command/src/project/show.rs @@ -42,11 +42,7 @@ pub struct ShowCommand { impl Command for ShowCommand { const NAME: &'static str = "project show"; - fn retry_opts(&self) -> Option { - Some(self.retry_opts.clone()) - } - - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(ShowTui::run(ctx.try_clone().into_diagnostic()?, opts, self.name.clone()).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/project/ticket.rs b/implementations/rust/ockam/ockam_command/src/project/ticket.rs index 3355f196c37..051e6ffff33 100644 --- a/implementations/rust/ockam/ockam_command/src/project/ticket.rs +++ b/implementations/rust/ockam/ockam_command/src/project/ticket.rs @@ -87,11 +87,7 @@ pub struct TicketCommand { impl Command for TicketCommand { const NAME: &'static str = "project ticket"; - fn retry_opts(&self) -> Option { - Some(self.retry_opts.clone()) - } - - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { let cmd = self.parse_args(&opts).await?; let identity = opts .state diff --git a/implementations/rust/ockam/ockam_command/src/project/version.rs b/implementations/rust/ockam/ockam_command/src/project/version.rs index f49a13c20c4..be33586ea4a 100644 --- a/implementations/rust/ockam/ockam_command/src/project/version.rs +++ b/implementations/rust/ockam/ockam_command/src/project/version.rs @@ -8,7 +8,6 @@ use ockam_api::fmt_ok; use ockam_api::nodes::InMemoryNode; use crate::shared_args::IdentityOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/version/long_about.txt"); @@ -26,17 +25,11 @@ pub struct VersionCommand { } impl VersionCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "project version".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { // Send request let node = InMemoryNode::start(ctx, &opts.state).await?; let controller = node.create_controller().await?; diff --git a/implementations/rust/ockam/ockam_command/src/project_admin/add.rs b/implementations/rust/ockam/ockam_command/src/project_admin/add.rs index 9a486d67efd..d6589ff5749 100644 --- a/implementations/rust/ockam/ockam_command/src/project_admin/add.rs +++ b/implementations/rust/ockam/ockam_command/src/project_admin/add.rs @@ -29,7 +29,7 @@ pub struct AddCommand { impl Command for AddCommand { const NAME: &'static str = "project-admin add"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let project = opts .state .projects() diff --git a/implementations/rust/ockam/ockam_command/src/project_admin/delete.rs b/implementations/rust/ockam/ockam_command/src/project_admin/delete.rs index 82ec81dab58..b017e4679cb 100644 --- a/implementations/rust/ockam/ockam_command/src/project_admin/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/project_admin/delete.rs @@ -42,7 +42,7 @@ pub struct DeleteCommand { impl Command for DeleteCommand { const NAME: &'static str = "project-admin delete"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(DeleteTui::run(ctx, opts, self).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/project_admin/list.rs b/implementations/rust/ockam/ockam_command/src/project_admin/list.rs index 8718776c3e9..374c67c9149 100644 --- a/implementations/rust/ockam/ockam_command/src/project_admin/list.rs +++ b/implementations/rust/ockam/ockam_command/src/project_admin/list.rs @@ -21,7 +21,7 @@ pub struct ListCommand { impl Command for ListCommand { const NAME: &'static str = "project-admin list"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let project = opts .state .projects() diff --git a/implementations/rust/ockam/ockam_command/src/project_admin/mod.rs b/implementations/rust/ockam/ockam_command/src/project_admin/mod.rs index d9d7951fc2a..0ca4376b523 100644 --- a/implementations/rust/ockam/ockam_command/src/project_admin/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/project_admin/mod.rs @@ -9,6 +9,8 @@ use crate::project_admin::delete::DeleteCommand; use crate::project_admin::list::ListCommand; use crate::{docs, Command, CommandGlobalOpts}; +use ockam_node::Context; + #[derive(Clone, Debug, Args)] #[command(hide = docs::hide(), arg_required_else_help = true, subcommand_required = true, about = docs::about("Manage Project Admins in Ockam Orchestrator"))] @@ -30,11 +32,11 @@ enum ProjectAdminSubcommand { } impl ProjectAdminCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - ProjectAdminSubcommand::List(c) => c.run(opts), - ProjectAdminSubcommand::Add(c) => c.run(opts), - ProjectAdminSubcommand::Delete(c) => c.run(opts), + ProjectAdminSubcommand::List(c) => c.run(ctx, opts).await, + ProjectAdminSubcommand::Add(c) => c.run(ctx, opts).await, + ProjectAdminSubcommand::Delete(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/project_member/add.rs b/implementations/rust/ockam/ockam_command/src/project_member/add.rs index d0ad5362ebf..80501f25254 100644 --- a/implementations/rust/ockam/ockam_command/src/project_member/add.rs +++ b/implementations/rust/ockam/ockam_command/src/project_member/add.rs @@ -71,7 +71,7 @@ impl Command for AddCommand { Some(self.retry_opts.clone()) } - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let (authority_node_client, project_name) = authority_client(ctx, &opts, &self.identity_opts, &self.project_name).await?; diff --git a/implementations/rust/ockam/ockam_command/src/project_member/delete.rs b/implementations/rust/ockam/ockam_command/src/project_member/delete.rs index 4f730a7d512..5c171990498 100644 --- a/implementations/rust/ockam/ockam_command/src/project_member/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/project_member/delete.rs @@ -48,7 +48,7 @@ pub struct DeleteCommand { impl Command for DeleteCommand { const NAME: &'static str = "project-member delete"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { if self.member.is_none() && !self.all { return Err(miette!( "You need to specify either an identifier to delete or use the --all flag to delete all the members from a project." diff --git a/implementations/rust/ockam/ockam_command/src/project_member/list.rs b/implementations/rust/ockam/ockam_command/src/project_member/list.rs index 639c5077607..d7e7edb89b5 100644 --- a/implementations/rust/ockam/ockam_command/src/project_member/list.rs +++ b/implementations/rust/ockam/ockam_command/src/project_member/list.rs @@ -35,7 +35,7 @@ pub struct ListCommand { impl Command for ListCommand { const NAME: &'static str = "project-member list"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { let (authority_node_client, _) = authority_client(ctx, &opts, &self.identity_opts, &self.project_name).await?; diff --git a/implementations/rust/ockam/ockam_command/src/project_member/list_ids.rs b/implementations/rust/ockam/ockam_command/src/project_member/list_ids.rs index 7a880d33c78..96cb532c887 100644 --- a/implementations/rust/ockam/ockam_command/src/project_member/list_ids.rs +++ b/implementations/rust/ockam/ockam_command/src/project_member/list_ids.rs @@ -31,7 +31,7 @@ pub struct ListIdsCommand { impl Command for ListIdsCommand { const NAME: &'static str = "project-member list-ids"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { let (authority_node_client, _) = authority_client(ctx, &opts, &self.identity_opts, &self.project_name).await?; diff --git a/implementations/rust/ockam/ockam_command/src/project_member/mod.rs b/implementations/rust/ockam/ockam_command/src/project_member/mod.rs index 6e7069f007a..53813a46720 100644 --- a/implementations/rust/ockam/ockam_command/src/project_member/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/project_member/mod.rs @@ -49,13 +49,13 @@ pub struct ProjectMemberCommand { } impl ProjectMemberCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - ProjectMemberSubcommand::List(c) => c.run(opts), - ProjectMemberSubcommand::ListIds(c) => c.run(opts), - ProjectMemberSubcommand::Add(c) => c.run(opts), - ProjectMemberSubcommand::Show(c) => c.run(opts), - ProjectMemberSubcommand::Delete(c) => c.run(opts), + ProjectMemberSubcommand::List(c) => c.run(ctx, opts).await, + ProjectMemberSubcommand::ListIds(c) => c.run(ctx, opts).await, + ProjectMemberSubcommand::Add(c) => c.run(ctx, opts).await, + ProjectMemberSubcommand::Show(c) => c.run(ctx, opts).await, + ProjectMemberSubcommand::Delete(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/project_member/show.rs b/implementations/rust/ockam/ockam_command/src/project_member/show.rs index 0ce336a2c45..80e0cdbe101 100644 --- a/implementations/rust/ockam/ockam_command/src/project_member/show.rs +++ b/implementations/rust/ockam/ockam_command/src/project_member/show.rs @@ -44,7 +44,7 @@ pub struct ShowCommand { impl Command for ShowCommand { const NAME: &'static str = "project-member show"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(ShowTui::run(ctx.try_clone().into_diagnostic()?, opts, self).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/relay/create.rs b/implementations/rust/ockam/ockam_command/src/relay/create.rs index f27179fc602..766b5b43b9d 100644 --- a/implementations/rust/ockam/ockam_command/src/relay/create.rs +++ b/implementations/rust/ockam/ockam_command/src/relay/create.rs @@ -79,7 +79,7 @@ impl Command for CreateCommand { Some(self.retry_opts.clone()) } - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { if self.project_relay { print_warning_for_deprecated_flag_no_effect(&opts, "--project-relay")?; } diff --git a/implementations/rust/ockam/ockam_command/src/relay/delete.rs b/implementations/rust/ockam/ockam_command/src/relay/delete.rs index 9b2332601fb..49b9a28dcac 100644 --- a/implementations/rust/ockam/ockam_command/src/relay/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/relay/delete.rs @@ -16,7 +16,6 @@ use ockam_core::TryClone; use crate::terminal::tui::DeleteCommandTui; use crate::tui::PluralTerm; -use crate::util::async_cmd; const AFTER_LONG_HELP: &str = include_str!("./static/delete/after_long_help.txt"); @@ -38,17 +37,11 @@ pub struct DeleteCommand { } impl DeleteCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "relay delete".into() } - pub async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { DeleteTui::run(ctx.try_clone().into_diagnostic()?, opts, self.clone()).await } } diff --git a/implementations/rust/ockam/ockam_command/src/relay/list.rs b/implementations/rust/ockam/ockam_command/src/relay/list.rs index 79c539fcae6..d69eb23edd2 100644 --- a/implementations/rust/ockam/ockam_command/src/relay/list.rs +++ b/implementations/rust/ockam/ockam_command/src/relay/list.rs @@ -7,7 +7,6 @@ use ockam_api::nodes::models::relay::RelayInfo; use ockam_api::nodes::BackgroundNodeClient; use ockam_core::api::Request; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const PREVIEW_TAG: &str = include_str!("../static/preview_tag.txt"); @@ -29,17 +28,11 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "relay list".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.to).await?; let relays: Vec = { let pb = opts.terminal.spinner(); diff --git a/implementations/rust/ockam/ockam_command/src/relay/mod.rs b/implementations/rust/ockam/ockam_command/src/relay/mod.rs index d649e6812c5..fc47c43f634 100644 --- a/implementations/rust/ockam/ockam_command/src/relay/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/relay/mod.rs @@ -7,6 +7,8 @@ pub(crate) use show::ShowCommand; use crate::{docs, Command, CommandGlobalOpts}; +use ockam_node::Context; + mod create; mod delete; mod list; @@ -37,12 +39,12 @@ pub enum RelaySubCommand { } impl RelayCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - RelaySubCommand::Create(c) => c.run(opts), - RelaySubCommand::List(c) => c.run(opts), - RelaySubCommand::Show(c) => c.run(opts), - RelaySubCommand::Delete(c) => c.run(opts), + RelaySubCommand::Create(c) => c.run(ctx, opts).await, + RelaySubCommand::List(c) => c.run(ctx, opts).await, + RelaySubCommand::Show(c) => c.run(ctx, opts).await, + RelaySubCommand::Delete(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/relay/show.rs b/implementations/rust/ockam/ockam_command/src/relay/show.rs index 60addba1579..391d7fca66c 100644 --- a/implementations/rust/ockam/ockam_command/src/relay/show.rs +++ b/implementations/rust/ockam/ockam_command/src/relay/show.rs @@ -20,7 +20,6 @@ use serde::Serialize; use crate::terminal::tui::ShowCommandTui; use crate::tui::PluralTerm; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const PREVIEW_TAG: &str = include_str!("../static/preview_tag.txt"); @@ -42,16 +41,11 @@ pub struct ShowCommand { } impl ShowCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } pub fn name(&self) -> String { "relay show".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { ShowTui::run(ctx.try_clone().into_diagnostic()?, opts, self.clone()).await } } diff --git a/implementations/rust/ockam/ockam_command/src/rendezvous/create/create.rs b/implementations/rust/ockam/ockam_command/src/rendezvous/create/create.rs index 80b4f2744dc..f39e68d1f54 100644 --- a/implementations/rust/ockam/ockam_command/src/rendezvous/create/create.rs +++ b/implementations/rust/ockam/ockam_command/src/rendezvous/create/create.rs @@ -1,10 +1,8 @@ use crate::util::foreground_args::ForegroundArgs; -use crate::util::{embedded_node_that_is_not_stopped, local_cmd}; use crate::{Command, CommandGlobalOpts}; use async_trait::async_trait; use clap::Args; use ockam_node::Context; -use tracing::instrument; /// Start a Rendezvous server in foreground #[derive(Clone, Debug, Args)] @@ -35,15 +33,7 @@ pub struct CreateCommand { impl Command for CreateCommand { const NAME: &'static str = "rendezvous create"; - #[instrument(skip_all)] - fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - local_cmd(embedded_node_that_is_not_stopped( - opts.rt.clone(), - |ctx| async move { self.foreground_mode(&ctx, opts).await }, - )) - } - - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { self.foreground_mode(ctx, opts).await?; Ok(()) diff --git a/implementations/rust/ockam/ockam_command/src/rendezvous/get_my_address.rs b/implementations/rust/ockam/ockam_command/src/rendezvous/get_my_address.rs index edba3b28271..9a829d7802d 100644 --- a/implementations/rust/ockam/ockam_command/src/rendezvous/get_my_address.rs +++ b/implementations/rust/ockam/ockam_command/src/rendezvous/get_my_address.rs @@ -19,7 +19,7 @@ pub struct GetMyAddressCommand { impl Command for GetMyAddressCommand { const NAME: &'static str = "rendezvous get-my-address"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let udp = UdpTransport::create(ctx)?; let bind = udp .bind( diff --git a/implementations/rust/ockam/ockam_command/src/rendezvous/mod.rs b/implementations/rust/ockam/ockam_command/src/rendezvous/mod.rs index 25f28c090cc..a5e4cd7b5dc 100644 --- a/implementations/rust/ockam/ockam_command/src/rendezvous/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/rendezvous/mod.rs @@ -8,6 +8,8 @@ use create::CreateCommand; use crate::rendezvous::get_my_address::GetMyAddressCommand; use crate::{docs, Command, CommandGlobalOpts}; +use ockam_node::Context; + /// Manage Rendezvous server #[derive(Clone, Debug, Args)] #[command(hide = docs::hide(), arg_required_else_help = true, subcommand_required = true)] @@ -41,10 +43,10 @@ impl RendezvousSubcommand { } impl RendezvousCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - RendezvousSubcommand::Create(c) => c.run(opts), - RendezvousSubcommand::GetMyAddress(c) => c.run(opts), + RendezvousSubcommand::Create(c) => c.run(ctx, opts).await, + RendezvousSubcommand::GetMyAddress(c) => c.run(ctx, opts).await, } } } diff --git a/implementations/rust/ockam/ockam_command/src/reset/mod.rs b/implementations/rust/ockam/ockam_command/src/reset/mod.rs index 8731b63c10a..169d305f583 100644 --- a/implementations/rust/ockam/ockam_command/src/reset/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/reset/mod.rs @@ -14,7 +14,6 @@ use ockam_node::Context; use crate::branding::BrandingCompileEnvVars; use crate::docs; -use crate::util::async_cmd; const LONG_ABOUT: &str = include_str!("./static/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/after_long_help.txt"); @@ -37,14 +36,7 @@ pub struct ResetCommand { all: bool, } -// TODO: Detach all eBPFs impl ResetCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "reset".into() } @@ -55,7 +47,7 @@ impl ResetCommand { } } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let delete_orchestrator_resources = BrandingCompileEnvVars::is_ockam_developer() && self.all && opts.state.is_enrolled().await.unwrap_or_default(); diff --git a/implementations/rust/ockam/ockam_command/src/run/mod.rs b/implementations/rust/ockam/ockam_command/src/run/mod.rs index a21d74f5dba..1a800db2eb0 100644 --- a/implementations/rust/ockam/ockam_command/src/run/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/run/mod.rs @@ -8,7 +8,6 @@ use ockam_api::cli_state::journeys::APPLICATION_EVENT_COMMAND_CONFIGURATION_FILE use std::path::PathBuf; use tracing::{instrument, Span}; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; mod config; @@ -34,18 +33,12 @@ pub struct RunCommand { } impl RunCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "run".to_string() } #[instrument(skip_all, fields(app.event.command.configuration_file))] - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let contents = match &self.inline { Some(contents) => contents.to_string(), None => { diff --git a/implementations/rust/ockam/ockam_command/src/run/parser/resource/traits.rs b/implementations/rust/ockam/ockam_command/src/run/parser/resource/traits.rs index 56572024c5b..7f7027ae356 100644 --- a/implementations/rust/ockam/ockam_command/src/run/parser/resource/traits.rs +++ b/implementations/rust/ockam/ockam_command/src/run/parser/resource/traits.rs @@ -41,7 +41,7 @@ where async fn run(&self, ctx: &Context, opts: &CommandGlobalOpts) -> Result<()> { debug!("running command {} {:?}", self.name(), self); - Ok(self.clone().async_run_with_retry(ctx, opts.clone()).await?) + Ok(self.clone().run_with_retry(ctx, opts.clone()).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/secure_channel/create.rs b/implementations/rust/ockam/ockam_command/src/secure_channel/create.rs index 3e338618487..f9c2d838914 100644 --- a/implementations/rust/ockam/ockam_command/src/secure_channel/create.rs +++ b/implementations/rust/ockam/ockam_command/src/secure_channel/create.rs @@ -23,7 +23,7 @@ use crate::project::util::{ clean_projects_multiaddr, get_projects_secure_channels_from_config_lookup, }; use crate::shared_args::IdentityOpts; -use crate::util::{async_cmd, clean_nodes_multiaddr, exitcode}; +use crate::util::{clean_nodes_multiaddr, exitcode}; const LONG_ABOUT: &str = include_str!("./static/create/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/create/after_long_help.txt"); @@ -61,12 +61,6 @@ pub struct CreateCommand { } impl CreateCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "secure-channel create".into() } @@ -99,7 +93,7 @@ impl CreateCommand { clean_projects_multiaddr(to, projects_sc).wrap_err("Could not parse projects from route") } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { initialize_default_node(ctx, &opts).await?; let node = BackgroundNodeClient::create_to_node(ctx, &opts.state, &self.from)?; diff --git a/implementations/rust/ockam/ockam_command/src/secure_channel/delete.rs b/implementations/rust/ockam/ockam_command/src/secure_channel/delete.rs index ce7519a2c5b..b700ab8e8bf 100644 --- a/implementations/rust/ockam/ockam_command/src/secure_channel/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/secure_channel/delete.rs @@ -11,7 +11,6 @@ use ockam_api::nodes::BackgroundNodeClient; use ockam_api::ReverseLocalConverter; use ockam_core::{Address, AddressParseError}; -use crate::util::async_cmd; use crate::util::{api, exitcode}; use crate::{docs, CommandGlobalOpts}; @@ -40,19 +39,13 @@ pub struct DeleteCommand { } impl DeleteCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "secure-channel delete".into() } fn print_output( &self, - node_name: &String, + node_name: &str, address: &Address, options: &CommandGlobalOpts, response: DeleteSecureChannelResponse, @@ -134,7 +127,7 @@ impl DeleteCommand { Ok(()) } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { if opts.terminal.confirmed_with_flag_or_prompt( self.yes, "Are you sure you want to delete this secure channel?", @@ -143,7 +136,7 @@ impl DeleteCommand { let address = &self.address; let response: DeleteSecureChannelResponse = node.ask(ctx, api::delete_secure_channel(address)).await?; - self.print_output(&node.node_name(), address, &opts, response)?; + self.print_output(node.node_name(), address, &opts, response)?; } Ok(()) } diff --git a/implementations/rust/ockam/ockam_command/src/secure_channel/list.rs b/implementations/rust/ockam/ockam_command/src/secure_channel/list.rs index 36aaa7249b8..00a014d72b9 100644 --- a/implementations/rust/ockam/ockam_command/src/secure_channel/list.rs +++ b/implementations/rust/ockam/ockam_command/src/secure_channel/list.rs @@ -12,7 +12,6 @@ use ockam_api::nodes::models::secure_channel::ShowSecureChannelResponse; use ockam_api::nodes::BackgroundNodeClient; use ockam_core::{route, Address, Result}; -use crate::util::async_cmd; use crate::{docs, util::api, CommandGlobalOpts}; use ockam_api::output::Output; use ockam_api::ReverseLocalConverter; @@ -36,12 +35,6 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "secure-channel list".into() } @@ -81,7 +74,7 @@ impl ListCommand { Ok(SecureChannelListOutput { from, to, at }) } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.at).await?; let is_finished: Mutex = Mutex::new(false); @@ -104,7 +97,7 @@ impl ListCommand { let request = api::show_secure_channel(&Address::from(channel_addr)); let show_response: ShowSecureChannelResponse = node.ask(ctx, request).await?; let secure_channel_output = - self.build_output(&node.node_name(), channel_addr, show_response)?; + self.build_output(node.node_name(), channel_addr, show_response)?; *is_finished.lock().await = true; Ok(secure_channel_output) }; diff --git a/implementations/rust/ockam/ockam_command/src/secure_channel/listener/create.rs b/implementations/rust/ockam/ockam_command/src/secure_channel/listener/create.rs index ac7871351f7..a385c56f9b0 100644 --- a/implementations/rust/ockam/ockam_command/src/secure_channel/listener/create.rs +++ b/implementations/rust/ockam/ockam_command/src/secure_channel/listener/create.rs @@ -1,21 +1,19 @@ use clap::Args; use colorful::Colorful; -use miette::{miette, IntoDiagnostic, WrapErr}; -use minicbor::Decoder; +use miette::{miette, WrapErr}; use crate::{docs, CommandGlobalOpts}; use ockam::identity::Identifier; use ockam::Context; use ockam_api::colors::OckamColor; use ockam_api::nodes::models::secure_channel::CreateSecureChannelListenerRequest; -use ockam_api::nodes::{BackgroundNodeClient, NODEMANAGER_ADDR}; +use ockam_api::nodes::BackgroundNodeClient; use ockam_api::{fmt_log, fmt_ok}; -use ockam_core::api::{Request, ResponseHeader, Status}; -use ockam_core::{Address, Route}; +use ockam_core::api::Request; +use ockam_core::Address; use crate::node::util::initialize_default_node; use crate::node::NodeOpts; -use crate::util::{api, async_cmd, exitcode}; const LONG_ABOUT: &str = include_str!("./static/create/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/create/after_long_help.txt"); @@ -45,17 +43,11 @@ pub struct CreateCommand { } impl CreateCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "create secure channel listener".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { initialize_default_node(ctx, &opts).await?; let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let req = Request::post("/node/secure_channel_listener").body( @@ -95,33 +87,3 @@ impl CreateCommand { } } } - -pub async fn create_listener( - ctx: &Context, - addr: Address, - authorized_identifiers: Option>, - identity: Option, - base_route: Route, -) -> miette::Result<()> { - let resp: Vec = ctx - .send_and_receive( - base_route + NODEMANAGER_ADDR, - api::create_secure_channel_listener(&addr, authorized_identifiers, identity)?, - ) - .await - .into_diagnostic()?; - - let mut dec = Decoder::new(&resp); - let response = dec.decode::().into_diagnostic()?; - - match response.status() { - Some(Status::Ok) => { - println!("/service/{}", addr.address()); - Ok(()) - } - _ => { - eprintln!("An error occurred while creating the secure channel listener",); - std::process::exit(exitcode::CANTCREAT) - } - } -} diff --git a/implementations/rust/ockam/ockam_command/src/secure_channel/listener/delete.rs b/implementations/rust/ockam/ockam_command/src/secure_channel/listener/delete.rs index 93609c4922b..3531bf465bc 100644 --- a/implementations/rust/ockam/ockam_command/src/secure_channel/listener/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/secure_channel/listener/delete.rs @@ -8,7 +8,7 @@ use ockam_api::nodes::BackgroundNodeClient; use ockam_core::Address; use crate::node::NodeOpts; -use crate::util::{api, async_cmd}; +use crate::util::api; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/delete/long_about.txt"); @@ -30,17 +30,11 @@ pub struct DeleteCommand { } impl DeleteCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "delete secure channel listener".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let req = api::delete_secure_channel_listener(&self.address); let response: DeleteSecureChannelListenerResponse = node.ask(ctx, req).await?; diff --git a/implementations/rust/ockam/ockam_command/src/secure_channel/listener/list.rs b/implementations/rust/ockam/ockam_command/src/secure_channel/listener/list.rs index 1c93eae5c8f..0af4625e15a 100644 --- a/implementations/rust/ockam/ockam_command/src/secure_channel/listener/list.rs +++ b/implementations/rust/ockam/ockam_command/src/secure_channel/listener/list.rs @@ -10,7 +10,7 @@ use ockam_api::colors::OckamColor; use ockam_api::nodes::BackgroundNodeClient; use crate::node::NodeOpts; -use crate::util::{api, async_cmd}; +use crate::util::api; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/list/long_about.txt"); @@ -32,16 +32,11 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } pub fn name(&self) -> String { "secure-channel-listeners list".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let is_finished: Mutex = Mutex::new(false); diff --git a/implementations/rust/ockam/ockam_command/src/secure_channel/listener/mod.rs b/implementations/rust/ockam/ockam_command/src/secure_channel/listener/mod.rs index b857c35adac..e799aa7c938 100644 --- a/implementations/rust/ockam/ockam_command/src/secure_channel/listener/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/secure_channel/listener/mod.rs @@ -8,9 +8,12 @@ pub(crate) use delete::DeleteCommand; pub(crate) use list::ListCommand; pub(crate) use show::ShowCommand; -use crate::CommandGlobalOpts; use clap::{Args, Subcommand}; +use crate::CommandGlobalOpts; + +use ockam_node::Context; + /// Manage Secure Channel Listeners #[derive(Clone, Debug, Args)] #[command(arg_required_else_help = true, subcommand_required = true)] @@ -32,12 +35,12 @@ pub enum SecureChannelListenerSubcommand { } impl SecureChannelListenerCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - SecureChannelListenerSubcommand::Create(c) => c.run(opts), - SecureChannelListenerSubcommand::Delete(c) => c.run(opts), - SecureChannelListenerSubcommand::List(c) => c.run(opts), - SecureChannelListenerSubcommand::Show(c) => c.run(opts), + SecureChannelListenerSubcommand::Create(c) => c.run(ctx, opts).await, + SecureChannelListenerSubcommand::Delete(c) => c.run(ctx, opts).await, + SecureChannelListenerSubcommand::List(c) => c.run(ctx, opts).await, + SecureChannelListenerSubcommand::Show(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/secure_channel/listener/show.rs b/implementations/rust/ockam/ockam_command/src/secure_channel/listener/show.rs index 28dc1d254c8..9c111989b45 100644 --- a/implementations/rust/ockam/ockam_command/src/secure_channel/listener/show.rs +++ b/implementations/rust/ockam/ockam_command/src/secure_channel/listener/show.rs @@ -5,7 +5,7 @@ use ockam_api::nodes::BackgroundNodeClient; use ockam_core::Address; use crate::node::NodeOpts; -use crate::util::{api, async_cmd}; +use crate::util::api; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/show/long_about.txt"); @@ -29,16 +29,11 @@ pub struct ShowCommand { } impl ShowCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } pub fn name(&self) -> String { "show secure channel listener".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let address = &self.address; let req = api::show_secure_channel_listener(address); diff --git a/implementations/rust/ockam/ockam_command/src/secure_channel/mod.rs b/implementations/rust/ockam/ockam_command/src/secure_channel/mod.rs index 86d14903009..cb77082d77d 100644 --- a/implementations/rust/ockam/ockam_command/src/secure_channel/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/secure_channel/mod.rs @@ -12,6 +12,7 @@ pub use show::ShowCommand; use crate::{docs, CommandGlobalOpts}; use clap::{Args, Subcommand}; +use ockam_node::Context; const LONG_ABOUT: &str = include_str!("./static/long_about.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/after_long_help.txt"); @@ -42,12 +43,12 @@ enum SecureChannelSubcommand { } impl SecureChannelCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - SecureChannelSubcommand::Create(c) => c.run(opts), - SecureChannelSubcommand::Delete(c) => c.run(opts), - SecureChannelSubcommand::List(c) => c.run(opts), - SecureChannelSubcommand::Show(c) => c.run(opts), + SecureChannelSubcommand::Create(c) => c.run(ctx, opts).await, + SecureChannelSubcommand::Delete(c) => c.run(ctx, opts).await, + SecureChannelSubcommand::List(c) => c.run(ctx, opts).await, + SecureChannelSubcommand::Show(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/secure_channel/show.rs b/implementations/rust/ockam/ockam_command/src/secure_channel/show.rs index 83f33d930c9..1bad3c13563 100644 --- a/implementations/rust/ockam/ockam_command/src/secure_channel/show.rs +++ b/implementations/rust/ockam/ockam_command/src/secure_channel/show.rs @@ -6,7 +6,6 @@ use ockam_api::nodes::models::secure_channel::ShowSecureChannelResponse; use ockam_api::nodes::BackgroundNodeClient; use ockam_core::Address; -use crate::util::async_cmd; use crate::{docs, util::api, CommandGlobalOpts}; use ockam_api::output::Output; @@ -33,17 +32,11 @@ pub struct ShowCommand { } impl ShowCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "secure-channel show".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.at).await?; let address = &self.address; diff --git a/implementations/rust/ockam/ockam_command/src/service/list.rs b/implementations/rust/ockam/ockam_command/src/service/list.rs index 0ac272dc175..78ce7753c23 100644 --- a/implementations/rust/ockam/ockam_command/src/service/list.rs +++ b/implementations/rust/ockam/ockam_command/src/service/list.rs @@ -10,7 +10,7 @@ use ockam_api::nodes::models::services::ServiceStatus; use ockam_api::nodes::BackgroundNodeClient; use crate::node::NodeOpts; -use crate::util::{api, async_cmd}; +use crate::util::api; use crate::CommandGlobalOpts; /// List service(s) of a given node @@ -21,17 +21,11 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "service list".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let is_finished: Mutex = Mutex::new(false); diff --git a/implementations/rust/ockam/ockam_command/src/service/mod.rs b/implementations/rust/ockam/ockam_command/src/service/mod.rs index 4494a1fbdb0..e5d90db1894 100644 --- a/implementations/rust/ockam/ockam_command/src/service/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/service/mod.rs @@ -3,11 +3,14 @@ pub(crate) mod config; pub(crate) mod list; pub(crate) mod start; -use crate::{docs, CommandGlobalOpts}; use clap::{Args, Subcommand}; + +use crate::{docs, CommandGlobalOpts}; use list::ListCommand; pub(crate) use start::StartCommand; +use ockam_node::Context; + #[derive(Clone, Debug, Args)] #[command(hide = docs::hide())] pub struct ServiceCommand { @@ -24,10 +27,10 @@ pub enum ServiceSubcommand { } impl ServiceCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - ServiceSubcommand::Start(c) => c.run(opts), - ServiceSubcommand::List(c) => c.run(opts), + ServiceSubcommand::Start(c) => c.run(ctx, opts).await, + ServiceSubcommand::List(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/service/start.rs b/implementations/rust/ockam/ockam_command/src/service/start.rs index 99d32c2bb6e..10c0031bf70 100644 --- a/implementations/rust/ockam/ockam_command/src/service/start.rs +++ b/implementations/rust/ockam/ockam_command/src/service/start.rs @@ -12,7 +12,7 @@ use ockam_api::{fmt_ok, fmt_warn}; use ockam_core::api::Request; use crate::node::NodeOpts; -use crate::util::{api, async_cmd}; +use crate::util::api; /// Start a specified service #[derive(Clone, Debug, Args)] @@ -36,17 +36,11 @@ fn hop_default_addr() -> String { } impl StartCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "service start".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let addr = match &self.create_subcommand { StartSubCommand::Hop { addr, .. } => { diff --git a/implementations/rust/ockam/ockam_command/src/share/accept.rs b/implementations/rust/ockam/ockam_command/src/share/accept.rs index b91902bc87e..06bfb8a7fab 100644 --- a/implementations/rust/ockam/ockam_command/src/share/accept.rs +++ b/implementations/rust/ockam/ockam_command/src/share/accept.rs @@ -8,7 +8,6 @@ use ockam_api::nodes::InMemoryNode; use ockam_api::orchestrator::share::Invitations; use crate::shared_args::IdentityOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const PREVIEW_TAG: &str = include_str!("../static/preview_tag.txt"); @@ -24,17 +23,11 @@ pub struct AcceptCommand { } impl AcceptCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "accept invitation".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let is_finished: Mutex = Mutex::new(false); let node = InMemoryNode::start(ctx, &opts.state).await?; let controller = node.create_controller().await?; diff --git a/implementations/rust/ockam/ockam_command/src/share/create.rs b/implementations/rust/ockam/ockam_command/src/share/create.rs index 1dc957fa9d3..6229af0fbe0 100644 --- a/implementations/rust/ockam/ockam_command/src/share/create.rs +++ b/implementations/rust/ockam/ockam_command/src/share/create.rs @@ -12,7 +12,6 @@ use ockam_api::orchestrator::email_address::EmailAddress; use ockam_api::orchestrator::share::{Invitations, RoleInShare, ShareScope}; use crate::shared_args::IdentityOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const PREVIEW_TAG: &str = include_str!("../static/preview_tag.txt"); @@ -36,17 +35,11 @@ pub struct CreateCommand { } impl CreateCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "create invitation".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let is_finished: Mutex = Mutex::new(false); let node = InMemoryNode::start(ctx, &opts.state).await?; let controller = node.create_controller().await?; diff --git a/implementations/rust/ockam/ockam_command/src/share/list.rs b/implementations/rust/ockam/ockam_command/src/share/list.rs index 19543f2aff2..fefbfa458a7 100644 --- a/implementations/rust/ockam/ockam_command/src/share/list.rs +++ b/implementations/rust/ockam/ockam_command/src/share/list.rs @@ -8,7 +8,6 @@ use ockam_api::nodes::InMemoryNode; use ockam_api::orchestrator::share::{InvitationListKind, Invitations}; use crate::shared_args::IdentityOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const PREVIEW_TAG: &str = include_str!("../static/preview_tag.txt"); @@ -25,17 +24,11 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "list invitations".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let is_finished: Mutex = Mutex::new(false); let node = InMemoryNode::start(ctx, &opts.state).await?; let controller = node.create_controller().await?; diff --git a/implementations/rust/ockam/ockam_command/src/share/mod.rs b/implementations/rust/ockam/ockam_command/src/share/mod.rs index f75afd078d1..f3cb8a21aee 100644 --- a/implementations/rust/ockam/ockam_command/src/share/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/share/mod.rs @@ -8,6 +8,8 @@ pub use show::ShowCommand; use crate::{docs, CommandGlobalOpts}; +use ockam_node::Context; + mod accept; mod create; mod list; @@ -39,15 +41,15 @@ pub enum ShareSubcommand { } impl ShareCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { use ShareSubcommand::*; match self.subcommand { - Accept(c) => c.run(opts), - Create(c) => c.run(opts), - List(c) => c.run(opts), + Accept(c) => c.run(ctx, opts).await, + Create(c) => c.run(ctx, opts).await, + List(c) => c.run(ctx, opts).await, Revoke => todo!(), - Service(c) => c.run(opts), - Show(c) => c.run(opts), + Service(c) => c.run(ctx, opts).await, + Show(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/share/service.rs b/implementations/rust/ockam/ockam_command/src/share/service.rs index a8a7fa66abb..9834d104102 100644 --- a/implementations/rust/ockam/ockam_command/src/share/service.rs +++ b/implementations/rust/ockam/ockam_command/src/share/service.rs @@ -13,7 +13,6 @@ use ockam_api::orchestrator::email_address::EmailAddress; use ockam_api::orchestrator::share::{CreateServiceInvitation, Invitations}; use crate::shared_args::IdentityOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const PREVIEW_TAG: &str = include_str!("../static/preview_tag.txt"); @@ -43,17 +42,11 @@ pub struct ServiceCreateCommand { } impl ServiceCreateCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "create shared service".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let is_finished: Mutex = Mutex::new(false); let node = InMemoryNode::start(ctx, &opts.state).await?; let controller = node.create_controller().await?; diff --git a/implementations/rust/ockam/ockam_command/src/share/show.rs b/implementations/rust/ockam/ockam_command/src/share/show.rs index fb4009bad84..6cbfa8a71e0 100644 --- a/implementations/rust/ockam/ockam_command/src/share/show.rs +++ b/implementations/rust/ockam/ockam_command/src/share/show.rs @@ -10,7 +10,6 @@ use ockam_api::nodes::InMemoryNode; use ockam_api::orchestrator::share::Invitations; use crate::shared_args::IdentityOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const PREVIEW_TAG: &str = include_str!("../static/preview_tag.txt"); @@ -26,17 +25,11 @@ pub struct ShowCommand { } impl ShowCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "show invitation".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let is_finished: Mutex = Mutex::new(false); let node = InMemoryNode::start(ctx, &opts.state).await?; let controller = node.create_controller().await?; diff --git a/implementations/rust/ockam/ockam_command/src/sidecar/mod.rs b/implementations/rust/ockam/ockam_command/src/sidecar/mod.rs index 43952e014e7..0973fca9931 100644 --- a/implementations/rust/ockam/ockam_command/src/sidecar/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/sidecar/mod.rs @@ -4,6 +4,8 @@ use crate::sidecar::secure_relay_inlet::SecureRelayInlet; use crate::sidecar::secure_relay_outlet::SecureRelayOutlet; use crate::{docs, CommandGlobalOpts}; +use ockam_node::Context; + mod secure_relay_inlet; mod secure_relay_outlet; @@ -30,10 +32,10 @@ pub enum SidecarSubcommand { } impl SidecarCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - SidecarSubcommand::SecureRelayOutlet(c) => c.run(opts), - SidecarSubcommand::SecureRelayInlet(c) => c.run(opts), + SidecarSubcommand::SecureRelayOutlet(c) => c.run(ctx, opts).await, + SidecarSubcommand::SecureRelayInlet(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/sidecar/secure_relay_inlet.rs b/implementations/rust/ockam/ockam_command/src/sidecar/secure_relay_inlet.rs index 75ff53afac0..2afc3fdb476 100644 --- a/implementations/rust/ockam/ockam_command/src/sidecar/secure_relay_inlet.rs +++ b/implementations/rust/ockam/ockam_command/src/sidecar/secure_relay_inlet.rs @@ -1,6 +1,5 @@ use crate::run::Config; use crate::tcp::inlet::create::tcp_inlet_default_from_addr; -use crate::util::async_cmd; use crate::util::parsers::hostname_parser; use crate::{docs, CommandGlobalOpts}; use clap::Args; @@ -53,17 +52,11 @@ struct Enroll { } impl SecureRelayInlet { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "show relay inlet".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { self.create_config_and_start(ctx, opts).await } diff --git a/implementations/rust/ockam/ockam_command/src/sidecar/secure_relay_outlet.rs b/implementations/rust/ockam/ockam_command/src/sidecar/secure_relay_outlet.rs index aed8f703670..ac9617869b8 100644 --- a/implementations/rust/ockam/ockam_command/src/sidecar/secure_relay_outlet.rs +++ b/implementations/rust/ockam/ockam_command/src/sidecar/secure_relay_outlet.rs @@ -1,5 +1,4 @@ use crate::run::Config; -use crate::util::async_cmd; use crate::util::parsers::hostname_parser; use crate::{docs, CommandGlobalOpts}; use clap::Args; @@ -52,17 +51,11 @@ struct Enroll { } impl SecureRelayOutlet { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "show relay outlet".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { self.create_config_and_start(ctx, opts).await } diff --git a/implementations/rust/ockam/ockam_command/src/space/create.rs b/implementations/rust/ockam/ockam_command/src/space/create.rs index 4c4cf62cb16..c52a3d94df9 100644 --- a/implementations/rust/ockam/ockam_command/src/space/create.rs +++ b/implementations/rust/ockam/ockam_command/src/space/create.rs @@ -39,7 +39,7 @@ pub struct CreateCommand { impl Command for CreateCommand { const NAME: &'static str = "space create"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { if !opts .state .is_identity_enrolled(&self.identity_opts.identity_name) diff --git a/implementations/rust/ockam/ockam_command/src/space/delete.rs b/implementations/rust/ockam/ockam_command/src/space/delete.rs index 0b3c731cd10..fe4d6d7bb60 100644 --- a/implementations/rust/ockam/ockam_command/src/space/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/space/delete.rs @@ -43,7 +43,7 @@ pub struct DeleteCommand { impl Command for DeleteCommand { const NAME: &'static str = "space delete"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(DeleteTui::run(ctx, opts, self).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/space/list.rs b/implementations/rust/ockam/ockam_command/src/space/list.rs index 5af2b28862c..d436cf168b8 100644 --- a/implementations/rust/ockam/ockam_command/src/space/list.rs +++ b/implementations/rust/ockam/ockam_command/src/space/list.rs @@ -28,7 +28,7 @@ pub struct ListCommand { impl Command for ListCommand { const NAME: &'static str = "space list"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let node = InMemoryNode::start(ctx, &opts.state).await?; let spaces = { diff --git a/implementations/rust/ockam/ockam_command/src/space/mod.rs b/implementations/rust/ockam/ockam_command/src/space/mod.rs index e8ecab22321..8939896b5d8 100644 --- a/implementations/rust/ockam/ockam_command/src/space/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/space/mod.rs @@ -9,9 +9,12 @@ mod create; mod delete; mod list; mod show; + pub use create::CreateCommand; pub use delete::DeleteCommand; +use ockam_node::Context; + const LONG_ABOUT: &str = include_str!("./static/long_about.txt"); #[derive(Clone, Debug, Args)] @@ -35,12 +38,12 @@ pub enum SpaceSubcommand { } impl SpaceCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - SpaceSubcommand::List(c) => c.run(opts), - SpaceSubcommand::Show(c) => c.run(opts), - SpaceSubcommand::Create(c) => c.run(opts), - SpaceSubcommand::Delete(c) => c.run(opts), + SpaceSubcommand::List(c) => c.run(ctx, opts).await, + SpaceSubcommand::Show(c) => c.run(ctx, opts).await, + SpaceSubcommand::Create(c) => c.run(ctx, opts).await, + SpaceSubcommand::Delete(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/space/show.rs b/implementations/rust/ockam/ockam_command/src/space/show.rs index 7d3195c6b4c..9d9faf5d1f9 100644 --- a/implementations/rust/ockam/ockam_command/src/space/show.rs +++ b/implementations/rust/ockam/ockam_command/src/space/show.rs @@ -37,7 +37,7 @@ pub struct ShowCommand { impl Command for ShowCommand { const NAME: &'static str = "space show"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(ShowTui::run(ctx, opts, self).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/space_admin/add.rs b/implementations/rust/ockam/ockam_command/src/space_admin/add.rs index 64c175d6ef3..484aac4b70a 100644 --- a/implementations/rust/ockam/ockam_command/src/space_admin/add.rs +++ b/implementations/rust/ockam/ockam_command/src/space_admin/add.rs @@ -29,7 +29,7 @@ pub struct AddCommand { impl Command for AddCommand { const NAME: &'static str = "space-admin add"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let space = opts.state.get_space_by_name_or_default(&self.name).await?; let node = InMemoryNode::start_with_identity(ctx, &opts.state, self.identity_opts.identity_name) diff --git a/implementations/rust/ockam/ockam_command/src/space_admin/delete.rs b/implementations/rust/ockam/ockam_command/src/space_admin/delete.rs index 285d561fc03..7d4c9eb9f2f 100644 --- a/implementations/rust/ockam/ockam_command/src/space_admin/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/space_admin/delete.rs @@ -42,7 +42,7 @@ pub struct DeleteCommand { impl Command for DeleteCommand { const NAME: &'static str = "space-admin delete"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(DeleteTui::run(ctx, opts, self).await?) } } diff --git a/implementations/rust/ockam/ockam_command/src/space_admin/list.rs b/implementations/rust/ockam/ockam_command/src/space_admin/list.rs index c3678d8af0c..54c4a8731ed 100644 --- a/implementations/rust/ockam/ockam_command/src/space_admin/list.rs +++ b/implementations/rust/ockam/ockam_command/src/space_admin/list.rs @@ -21,7 +21,7 @@ pub struct ListCommand { impl Command for ListCommand { const NAME: &'static str = "space-admin list"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { let space = opts.state.get_space_by_name_or_default(&self.name).await?; let node = InMemoryNode::start_with_identity(ctx, &opts.state, self.identity_opts.identity_name) diff --git a/implementations/rust/ockam/ockam_command/src/space_admin/mod.rs b/implementations/rust/ockam/ockam_command/src/space_admin/mod.rs index f2fbbecb414..e95eba1a05b 100644 --- a/implementations/rust/ockam/ockam_command/src/space_admin/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/space_admin/mod.rs @@ -9,6 +9,8 @@ use crate::space_admin::delete::DeleteCommand; use crate::space_admin::list::ListCommand; use crate::{docs, Command, CommandGlobalOpts}; +use ockam_node::Context; + #[derive(Clone, Debug, Args)] #[command(arg_required_else_help = true, subcommand_required = true, about = docs::about("Manage Space Admins in Ockam Orchestrator"))] @@ -30,11 +32,11 @@ enum SpaceAdminSubcommand { } impl SpaceAdminCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - SpaceAdminSubcommand::List(c) => c.run(opts), - SpaceAdminSubcommand::Add(c) => c.run(opts), - SpaceAdminSubcommand::Delete(c) => c.run(opts), + SpaceAdminSubcommand::List(c) => c.run(ctx, opts).await, + SpaceAdminSubcommand::Add(c) => c.run(ctx, opts).await, + SpaceAdminSubcommand::Delete(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/status/mod.rs b/implementations/rust/ockam/ockam_command/src/status/mod.rs index fd4a97549f5..630c1afca8e 100644 --- a/implementations/rust/ockam/ockam_command/src/status/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/status/mod.rs @@ -42,7 +42,7 @@ pub struct StatusCommand { impl Command for StatusCommand { const NAME: &'static str = "status"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()> { let identities_details = self.get_identities_details(&opts).await?; let nodes = self.get_nodes_resources(ctx, &opts).await?; let node = InMemoryNode::start(ctx, &opts.state) @@ -91,7 +91,7 @@ impl StatusCommand { } let mut node = BackgroundNodeClient::create(ctx, &opts.state, &Some(node.name())).await?; - nodes_resources.push(get_node_resources(ctx, &opts.state, &mut node, false).await?); + nodes_resources.push(get_node_resources(ctx, &opts.state, &mut node).await?); } if let Some(ref pb) = pb { pb.finish_and_clear(); diff --git a/implementations/rust/ockam/ockam_command/src/subcommand.rs b/implementations/rust/ockam/ockam_command/src/subcommand.rs index 67c4fb17b56..6a6923bcc2a 100644 --- a/implementations/rust/ockam/ockam_command/src/subcommand.rs +++ b/implementations/rust/ockam/ockam_command/src/subcommand.rs @@ -7,7 +7,7 @@ use std::time::Duration; use async_trait::async_trait; use clap::Subcommand; use colorful::Colorful; -use miette::{miette, IntoDiagnostic}; +use miette::IntoDiagnostic; use tokio_retry::strategy::jitter; use tracing::warn; @@ -59,7 +59,6 @@ use crate::tcp::connection::TcpConnectionCommand; use crate::tcp::inlet::TcpInletCommand; use crate::tcp::listener::TcpListenerCommand; use crate::tcp::outlet::TcpOutletCommand; -use crate::util::async_cmd; use crate::vault::VaultCommand; use crate::worker::WorkerCommand; use crate::Error; @@ -162,54 +161,54 @@ pub enum OckamSubcommand { impl OckamSubcommand { /// Run the subcommand - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self { - OckamSubcommand::Enroll(c) => c.run(opts), + OckamSubcommand::Enroll(c) => c.run(ctx, opts).await, + OckamSubcommand::Node(c) => c.run(ctx, opts).await, + OckamSubcommand::Vault(c) => c.run(ctx, opts).await, + OckamSubcommand::Identity(c) => c.run(ctx, opts).await, + OckamSubcommand::Project(c) => c.run(ctx, opts).await, + OckamSubcommand::Policy(c) => c.run(ctx, opts).await, + OckamSubcommand::Credential(c) => c.run(ctx, opts).await, + OckamSubcommand::Relay(c) => c.run(ctx, opts).await, + OckamSubcommand::TcpOutlet(c) => c.run(ctx, opts).await, + OckamSubcommand::TcpInlet(c) => c.run(ctx, opts).await, + OckamSubcommand::KafkaInlet(c) => c.run(ctx, opts).await, + OckamSubcommand::KafkaOutlet(c) => c.run(ctx, opts).await, + OckamSubcommand::InfluxDBInlet(c) => c.run(ctx, opts).await, + OckamSubcommand::InfluxDBOutlet(c) => c.run(ctx, opts).await, + OckamSubcommand::Rendezvous(c) => c.run(ctx, opts).await, + OckamSubcommand::Status(c) => c.run(ctx, opts).await, + OckamSubcommand::Reset(c) => c.run(ctx, opts).await, + OckamSubcommand::Run(c) => c.run(ctx, opts).await, - OckamSubcommand::Node(c) => c.run(opts), - OckamSubcommand::Vault(c) => c.run(opts), - OckamSubcommand::Identity(c) => c.run(opts), - OckamSubcommand::Project(c) => c.run(opts), - OckamSubcommand::Policy(c) => c.run(opts), - OckamSubcommand::Credential(c) => c.run(opts), - OckamSubcommand::Relay(c) => c.run(opts), - OckamSubcommand::TcpOutlet(c) => c.run(opts), - OckamSubcommand::TcpInlet(c) => c.run(opts), - OckamSubcommand::KafkaInlet(c) => c.run(opts), - OckamSubcommand::KafkaOutlet(c) => c.run(opts), - OckamSubcommand::InfluxDBInlet(c) => c.run(opts), - OckamSubcommand::InfluxDBOutlet(c) => c.run(opts), - OckamSubcommand::Rendezvous(c) => c.run(opts), - OckamSubcommand::Status(c) => c.run(opts), - OckamSubcommand::Reset(c) => c.run(opts), - OckamSubcommand::Run(c) => c.run(opts), OckamSubcommand::Manpages(c) => c.run(), OckamSubcommand::Completion(c) => c.run(), OckamSubcommand::Environment(c) => c.run(), - OckamSubcommand::Admin(c) => c.run(opts), - OckamSubcommand::Space(c) => c.run(opts), - OckamSubcommand::SpaceAdmin(c) => c.run(opts), - OckamSubcommand::ProjectAdmin(c) => c.run(opts), - OckamSubcommand::ProjectMember(c) => c.run(opts), - OckamSubcommand::Sidecar(c) => c.run(opts), - OckamSubcommand::Subscription(c) => c.run(opts), - OckamSubcommand::Lease(c) => c.run(opts), - OckamSubcommand::Authority(c) => c.run(opts), - OckamSubcommand::Service(c) => c.run(opts), - OckamSubcommand::Message(c) => c.run(opts), + OckamSubcommand::Admin(c) => c.run(ctx, opts).await, + OckamSubcommand::Space(c) => c.run(ctx, opts).await, + OckamSubcommand::SpaceAdmin(c) => c.run(ctx, opts).await, + OckamSubcommand::ProjectAdmin(c) => c.run(ctx, opts).await, + OckamSubcommand::ProjectMember(c) => c.run(ctx, opts).await, + OckamSubcommand::Sidecar(c) => c.run(ctx, opts).await, + OckamSubcommand::Subscription(c) => c.run(ctx, opts).await, + OckamSubcommand::Lease(c) => c.run(ctx, opts).await, + OckamSubcommand::Authority(c) => c.run(ctx, opts).await, + OckamSubcommand::Service(c) => c.run(ctx, opts).await, + OckamSubcommand::Message(c) => c.run(ctx, opts).await, OckamSubcommand::Markdown(c) => c.run(), - OckamSubcommand::MigrateDatabase(c) => c.run(opts), - OckamSubcommand::Worker(c) => c.run(opts), - OckamSubcommand::SecureChannelListener(c) => c.run(opts), - OckamSubcommand::SecureChannel(c) => c.run(opts), - OckamSubcommand::TcpListener(c) => c.run(opts), - OckamSubcommand::TcpConnection(c) => c.run(opts), - OckamSubcommand::FlowControl(c) => c.run(opts), - OckamSubcommand::KafkaConsumer(c) => c.run(opts), - OckamSubcommand::KafkaProducer(c) => c.run(opts), - OckamSubcommand::Share(c) => c.run(opts), + OckamSubcommand::MigrateDatabase(c) => c.run(ctx, opts).await, + OckamSubcommand::Worker(c) => c.run(ctx, opts).await, + OckamSubcommand::SecureChannelListener(c) => c.run(ctx, opts).await, + OckamSubcommand::SecureChannel(c) => c.run(ctx, opts).await, + OckamSubcommand::TcpListener(c) => c.run(ctx, opts).await, + OckamSubcommand::TcpConnection(c) => c.run(ctx, opts).await, + OckamSubcommand::FlowControl(c) => c.run(ctx, opts).await, + OckamSubcommand::KafkaConsumer(c) => c.run(ctx, opts).await, + OckamSubcommand::KafkaProducer(c) => c.run(ctx, opts).await, + OckamSubcommand::Share(c) => c.run(ctx, opts).await, } } @@ -375,20 +374,7 @@ pub trait Command: Debug + Clone + Sized + Send + Sync + 'static { None } - fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - if Self::hide() { - return Err(miette!("This command is not available")); - } - async_cmd(Self::NAME, opts.clone(), |ctx| async move { - self.async_run_with_retry(&ctx, opts).await - }) - } - - async fn async_run_with_retry( - self, - ctx: &Context, - opts: CommandGlobalOpts, - ) -> miette::Result<()> { + async fn run_with_retry(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { if let Some(retry_opts) = self.retry_opts() { let (mut retry_count, retry_delay) = match (retry_opts.retry_count(), retry_opts.retry_delay()) { @@ -396,7 +382,7 @@ pub trait Command: Debug + Clone + Sized + Send + Sync + 'static { (Some(count), None) => (count, Duration::from_secs(5)), (None, Some(delay)) => (3, delay), (None, None) => { - self.async_run(ctx, opts).await?; + self.run(ctx, opts).await?; return Ok(()); } }; @@ -406,7 +392,7 @@ pub trait Command: Debug + Clone + Sized + Send + Sync + 'static { ); while retry_count > 0 { let cmd = self.clone(); - match cmd.async_run(ctx, opts.clone()).await { + match cmd.run(ctx, opts.clone()).await { Ok(_) => break, Err(report) => { match report.downcast::() { @@ -446,10 +432,10 @@ pub trait Command: Debug + Clone + Sized + Send + Sync + 'static { } Ok(()) } else { - self.async_run(ctx, opts).await?; + self.run(ctx, opts).await?; Ok(()) } } - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()>; + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> Result<()>; } diff --git a/implementations/rust/ockam/ockam_command/src/subscription.rs b/implementations/rust/ockam/ockam_command/src/subscription.rs index 39a8566a0ca..35ba57ed6b4 100644 --- a/implementations/rust/ockam/ockam_command/src/subscription.rs +++ b/implementations/rust/ockam/ockam_command/src/subscription.rs @@ -10,7 +10,6 @@ use ockam_api::nodes::InMemoryNode; use ockam_api::output::Output; use crate::shared_args::IdentityOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts, Result}; #[derive(Clone, Debug, Args)] @@ -46,12 +45,6 @@ pub enum SubscriptionSubcommand { } impl SubscriptionCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { match &self.subcommand { SubscriptionSubcommand::Show { .. } => "subscription show", @@ -59,7 +52,7 @@ impl SubscriptionCommand { .to_string() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = InMemoryNode::start(ctx, &opts.state).await?; let controller = node.create_controller().await?; diff --git a/implementations/rust/ockam/ockam_command/src/tcp/connection/create.rs b/implementations/rust/ockam/ockam_command/src/tcp/connection/create.rs index ee7f5f38fa9..492aec29d09 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/connection/create.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/connection/create.rs @@ -39,7 +39,7 @@ pub struct CreateCommand { impl Command for CreateCommand { const NAME: &'static str = "tcp-connection create"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { initialize_default_node(ctx, &opts).await?; let node = BackgroundNodeClient::create(ctx, &opts.state, &self.from).await?; let payload = models::transport::CreateTcpConnection::new(self.address.clone()); @@ -47,7 +47,7 @@ impl Command for CreateCommand { let transport_status: TransportStatus = node.ask(ctx, request).await?; let output = TcpConnection::new( - node.node_name(), + node.node_name().to_string(), transport_status.socket_addr().into_diagnostic()?, transport_status.multiaddr().into_diagnostic()?, ); diff --git a/implementations/rust/ockam/ockam_command/src/tcp/connection/delete.rs b/implementations/rust/ockam/ockam_command/src/tcp/connection/delete.rs index d47268ac39d..5d76a0ce56e 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/connection/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/connection/delete.rs @@ -6,7 +6,6 @@ use ockam_api::nodes::{models, BackgroundNodeClient}; use ockam_core::api::Request; use ockam_node::Context; -use crate::util::async_cmd; use crate::{docs, node::NodeOpts, CommandGlobalOpts}; const AFTER_LONG_HELP: &str = include_str!("./static/delete/after_long_help.txt"); @@ -27,17 +26,11 @@ pub struct DeleteCommand { } impl DeleteCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "tcp-connection delete".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { if opts.terminal.confirmed_with_flag_or_prompt( self.yes, "Are you sure you want to delete this TCP connection?", diff --git a/implementations/rust/ockam/ockam_command/src/tcp/connection/list.rs b/implementations/rust/ockam/ockam_command/src/tcp/connection/list.rs index 848cb43b6be..35614d338b1 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/connection/list.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/connection/list.rs @@ -12,8 +12,6 @@ use ockam_node::Context; use crate::node::NodeOpts; use crate::{docs, CommandGlobalOpts}; -use crate::util::async_cmd; - const PREVIEW_TAG: &str = include_str!("../../static/preview_tag.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/list/after_long_help.txt"); @@ -28,17 +26,11 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "tcp-connection list".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let is_finished: Mutex = Mutex::new(false); diff --git a/implementations/rust/ockam/ockam_command/src/tcp/connection/mod.rs b/implementations/rust/ockam/ockam_command/src/tcp/connection/mod.rs index 4b3a15c0690..7ae73f01b2f 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/connection/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/connection/mod.rs @@ -7,6 +7,8 @@ pub(crate) use list::ListCommand; use crate::tcp::connection::show::ShowCommand; use crate::{Command, CommandGlobalOpts}; +use ockam_node::Context; + mod create; mod delete; mod list; @@ -29,12 +31,12 @@ pub enum TcpConnectionSubCommand { } impl TcpConnectionCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - TcpConnectionSubCommand::Create(c) => c.run(opts), - TcpConnectionSubCommand::Delete(c) => c.run(opts), - TcpConnectionSubCommand::List(c) => c.run(opts), - TcpConnectionSubCommand::Show(c) => c.run(opts), + TcpConnectionSubCommand::Create(c) => c.run(ctx, opts).await, + TcpConnectionSubCommand::Delete(c) => c.run(ctx, opts).await, + TcpConnectionSubCommand::List(c) => c.run(ctx, opts).await, + TcpConnectionSubCommand::Show(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/tcp/connection/show.rs b/implementations/rust/ockam/ockam_command/src/tcp/connection/show.rs index b8914528bee..cc8199f7385 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/connection/show.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/connection/show.rs @@ -9,7 +9,6 @@ use ockam_api::{fmt_log, fmt_ok}; use ockam_core::api::Request; use crate::node::NodeOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const PREVIEW_TAG: &str = include_str!("../../static/preview_tag.txt"); @@ -29,17 +28,11 @@ pub struct ShowCommand { } impl ShowCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "tcp-connection show".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let transport_status: TransportStatus = node .ask( diff --git a/implementations/rust/ockam/ockam_command/src/tcp/inlet/create.rs b/implementations/rust/ockam/ockam_command/src/tcp/inlet/create.rs index 2a1603cdb25..a0dec99e7a2 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/inlet/create.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/inlet/create.rs @@ -167,7 +167,7 @@ pub(crate) fn tcp_inlet_default_to_addr() -> String { impl Command for CreateCommand { const NAME: &'static str = "tcp-inlet create"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { initialize_default_node(ctx, &opts).await?; let cmd = self.parse_args(&opts).await?; @@ -231,12 +231,12 @@ impl Command for CreateCommand { }; let node_name = node.node_name(); - cmd.add_inlet_created_event(&opts, &node_name, &inlet_status) + cmd.add_inlet_created_event(&opts, node_name, &inlet_status) .await?; let created_message = format!( "Created a new TCP Inlet in the Node {} bound to {}", - color_primary(&node_name), + color_primary(node_name), color_primary(cmd.from.to_string()), ); diff --git a/implementations/rust/ockam/ockam_command/src/tcp/inlet/delete.rs b/implementations/rust/ockam/ockam_command/src/tcp/inlet/delete.rs index 7e849053e87..9628007277a 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/inlet/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/inlet/delete.rs @@ -46,7 +46,7 @@ pub struct DeleteCommand { impl Command for DeleteCommand { const NAME: &'static str = "tcp-inlet delete"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(DeleteTui::run(ctx, opts, self).await?) } } @@ -113,7 +113,7 @@ impl DeleteCommandTui for DeleteTui { .plain(fmt_ok!( "TCP Inlet with alias {} on Node {} has been deleted", color_primary(item_name), - color_primary(&node_name) + color_primary(node_name) )) .json(serde_json::json!({ "alias": item_name, "node": node_name })) .write_line()?; diff --git a/implementations/rust/ockam/ockam_command/src/tcp/inlet/list.rs b/implementations/rust/ockam/ockam_command/src/tcp/inlet/list.rs index d46d0fc8e3e..725c07c2731 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/inlet/list.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/inlet/list.rs @@ -6,7 +6,6 @@ use ockam_core::api::Request; use ockam_node::Context; use crate::node::NodeOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const PREVIEW_TAG: &str = include_str!("../../static/preview_tag.txt"); @@ -23,17 +22,11 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "tcp-inlet list".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node.at_node).await?; let inlets: Vec = { let pb = opts.terminal.spinner(); diff --git a/implementations/rust/ockam/ockam_command/src/tcp/inlet/mod.rs b/implementations/rust/ockam/ockam_command/src/tcp/inlet/mod.rs index 9098fe82244..8024ac764a8 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/inlet/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/inlet/mod.rs @@ -7,6 +7,8 @@ pub(crate) use show::ShowCommand; use crate::{docs, Command, CommandGlobalOpts}; +use ockam_node::Context; + pub(crate) mod create; mod delete; mod list; @@ -37,12 +39,12 @@ pub enum TcpInletSubCommand { } impl TcpInletCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - TcpInletSubCommand::Create(c) => c.run(opts), - TcpInletSubCommand::Delete(c) => c.run(opts), - TcpInletSubCommand::List(c) => c.run(opts), - TcpInletSubCommand::Show(c) => c.run(opts), + TcpInletSubCommand::Create(c) => c.run(ctx, opts).await, + TcpInletSubCommand::Delete(c) => c.run(ctx, opts).await, + TcpInletSubCommand::List(c) => c.run(ctx, opts).await, + TcpInletSubCommand::Show(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/tcp/inlet/show.rs b/implementations/rust/ockam/ockam_command/src/tcp/inlet/show.rs index 26d4a8f41ad..61d863f728d 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/inlet/show.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/inlet/show.rs @@ -36,7 +36,7 @@ pub struct ShowCommand { impl Command for ShowCommand { const NAME: &'static str = "tcp-inlet show"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(ShowTui::run(ctx.try_clone().into_diagnostic()?, opts, self.clone()).await?) } } @@ -55,7 +55,7 @@ impl ShowTui { mut cmd: ShowCommand, ) -> miette::Result<()> { let node = BackgroundNodeClient::create(&ctx, &opts.state, &cmd.at).await?; - cmd.at = Some(node.node_name()); + cmd.at = Some(node.node_name().to_string()); let tui = Self { ctx, diff --git a/implementations/rust/ockam/ockam_command/src/tcp/listener/create.rs b/implementations/rust/ockam/ockam_command/src/tcp/listener/create.rs index 704b4506c50..6c0b761a4a5 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/listener/create.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/listener/create.rs @@ -12,7 +12,6 @@ use ockam_multiaddr::MultiAddr; use ockam_node::Context; use crate::node::util::initialize_default_node; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const AFTER_LONG_HELP: &str = include_str!("./static/create/after_long_help.txt"); @@ -30,17 +29,11 @@ pub struct CreateCommand { } impl CreateCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "tcp-listener create".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { initialize_default_node(ctx, &opts).await?; let node = BackgroundNodeClient::create(ctx, &opts.state, &self.at).await?; let transport_status: TransportStatus = node diff --git a/implementations/rust/ockam/ockam_command/src/tcp/listener/delete.rs b/implementations/rust/ockam/ockam_command/src/tcp/listener/delete.rs index c2cc2a740dc..5c712197bad 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/listener/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/listener/delete.rs @@ -8,7 +8,6 @@ use ockam_api::nodes::models::transport::TransportStatus; use ockam_api::nodes::{models, BackgroundNodeClient}; use ockam_core::api::Request; -use crate::util::async_cmd; use crate::{docs, node::NodeOpts, CommandGlobalOpts}; const AFTER_LONG_HELP: &str = include_str!("./static/delete/after_long_help.txt"); @@ -29,17 +28,11 @@ pub struct DeleteCommand { } impl DeleteCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "tcp-listener delete".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; // Check if there an TCP listener with the provided address exists diff --git a/implementations/rust/ockam/ockam_command/src/tcp/listener/list.rs b/implementations/rust/ockam/ockam_command/src/tcp/listener/list.rs index ce66c38291f..83ef646cd08 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/listener/list.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/listener/list.rs @@ -11,7 +11,7 @@ use ockam_api::nodes::BackgroundNodeClient; use crate::node::NodeOpts; use crate::{docs, CommandGlobalOpts}; -use crate::util::{api, async_cmd}; +use crate::util::api; const PREVIEW_TAG: &str = include_str!("../../static/preview_tag.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/list/after_long_help.txt"); @@ -27,17 +27,11 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "tcp-listener list".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let is_finished: Mutex = Mutex::new(false); diff --git a/implementations/rust/ockam/ockam_command/src/tcp/listener/mod.rs b/implementations/rust/ockam/ockam_command/src/tcp/listener/mod.rs index ee97dd34e99..cc640013131 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/listener/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/listener/mod.rs @@ -7,6 +7,8 @@ pub(crate) use show::ShowCommand; use crate::CommandGlobalOpts; +use ockam_node::Context; + mod create; mod delete; mod list; @@ -35,12 +37,12 @@ pub enum TcpListenerSubCommand { } impl TcpListenerCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - TcpListenerSubCommand::Create(c) => c.run(opts), - TcpListenerSubCommand::Delete(c) => c.run(opts), - TcpListenerSubCommand::List(c) => c.run(opts), - TcpListenerSubCommand::Show(c) => c.run(opts), + TcpListenerSubCommand::Create(c) => c.run(ctx, opts).await, + TcpListenerSubCommand::Delete(c) => c.run(ctx, opts).await, + TcpListenerSubCommand::List(c) => c.run(ctx, opts).await, + TcpListenerSubCommand::Show(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/tcp/listener/show.rs b/implementations/rust/ockam/ockam_command/src/tcp/listener/show.rs index 32bcaa8b4a3..5f597f878ba 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/listener/show.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/listener/show.rs @@ -7,7 +7,6 @@ use ockam_api::nodes::BackgroundNodeClient; use ockam_core::api::Request; use crate::node::NodeOpts; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const PREVIEW_TAG: &str = include_str!("../../static/preview_tag.txt"); @@ -27,17 +26,11 @@ pub struct ShowCommand { } impl ShowCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "tcp-listener show".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let transport_status: TransportStatus = node .ask( diff --git a/implementations/rust/ockam/ockam_command/src/tcp/outlet/create.rs b/implementations/rust/ockam/ockam_command/src/tcp/outlet/create.rs index 80f9e1a4065..7f278e4388e 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/outlet/create.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/outlet/create.rs @@ -79,7 +79,7 @@ pub struct CreateCommand { impl Command for CreateCommand { const NAME: &'static str = "tcp-outlet create"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { initialize_default_node(ctx, &opts).await?; let cmd = self.parse_args(&opts).await?; @@ -103,14 +103,14 @@ impl Command for CreateCommand { ) .await? }; - cmd.add_outlet_created_journey_event(&opts, &node_name, &outlet_status) + cmd.add_outlet_created_journey_event(&opts, node_name, &outlet_status) .await?; let worker_route = outlet_status.worker_route().into_diagnostic()?; let mut msg = fmt_ok!( "Created a new TCP Outlet in the Node {} at {} bound to {}\n", - color_primary(&node_name), + color_primary(node_name), color_primary(worker_route.to_string()), color_primary(cmd.to.to_string()) ); diff --git a/implementations/rust/ockam/ockam_command/src/tcp/outlet/delete.rs b/implementations/rust/ockam/ockam_command/src/tcp/outlet/delete.rs index b4da0908eb9..50c28b83301 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/outlet/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/outlet/delete.rs @@ -51,7 +51,7 @@ pub struct DeleteCommand { impl Command for DeleteCommand { const NAME: &'static str = "tcp-outlet delete"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(DeleteTui::run(ctx, opts, self).await?) } } @@ -126,7 +126,7 @@ impl DeleteCommandTui for DeleteTui { .plain(fmt_ok!( "TCP Outlet with alias {} on node {} has been deleted", color_primary(item_name), - color_primary(&node_name) + color_primary(node_name) )) .machine(item_name) .json(serde_json::json!({ "alias": item_name, "node": node_name })) diff --git a/implementations/rust/ockam/ockam_command/src/tcp/outlet/list.rs b/implementations/rust/ockam/ockam_command/src/tcp/outlet/list.rs index a5e83d7de07..cef9147ad29 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/outlet/list.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/outlet/list.rs @@ -12,8 +12,6 @@ use ockam_api::nodes::BackgroundNodeClient; use ockam_core::api::Request; use ockam_node::Context; -use crate::util::async_cmd; - const PREVIEW_TAG: &str = include_str!("../../static/preview_tag.txt"); const AFTER_LONG_HELP: &str = include_str!("./static/list/after_long_help.txt"); const LONG_ABOUT: &str = include_str!("./static/list/long_about.txt"); @@ -31,17 +29,11 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "tcp-outlet list".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.node_opts.at_node).await?; let is_finished: Mutex = Mutex::new(false); diff --git a/implementations/rust/ockam/ockam_command/src/tcp/outlet/mod.rs b/implementations/rust/ockam/ockam_command/src/tcp/outlet/mod.rs index ac5be4c42a2..973d293ec27 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/outlet/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/outlet/mod.rs @@ -3,6 +3,7 @@ use clap::{Args, Subcommand}; use create::CreateCommand; use delete::DeleteCommand; use list::ListCommand; +use ockam_node::Context; use show::ShowCommand; use crate::{docs, Command, CommandGlobalOpts}; @@ -37,12 +38,12 @@ pub enum TcpOutletSubCommand { } impl TcpOutletCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - TcpOutletSubCommand::Create(c) => c.run(opts), - TcpOutletSubCommand::Delete(c) => c.run(opts), - TcpOutletSubCommand::List(c) => c.run(opts), - TcpOutletSubCommand::Show(c) => c.run(opts), + TcpOutletSubCommand::Create(c) => c.run(ctx, opts).await, + TcpOutletSubCommand::Delete(c) => c.run(ctx, opts).await, + TcpOutletSubCommand::List(c) => c.run(ctx, opts).await, + TcpOutletSubCommand::Show(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/tcp/outlet/show.rs b/implementations/rust/ockam/ockam_command/src/tcp/outlet/show.rs index eee4cb8e8cb..3f18e5ace88 100644 --- a/implementations/rust/ockam/ockam_command/src/tcp/outlet/show.rs +++ b/implementations/rust/ockam/ockam_command/src/tcp/outlet/show.rs @@ -45,7 +45,7 @@ pub struct ShowCommand { impl Command for ShowCommand { const NAME: &'static str = "tcp-outlet show"; - async fn async_run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { Ok(ShowTui::run(ctx.try_clone().into_diagnostic()?, opts, self.clone()).await?) } } @@ -82,7 +82,7 @@ impl ShowTui { mut cmd: ShowCommand, ) -> miette::Result<()> { let node = BackgroundNodeClient::create(&ctx, &opts.state, &cmd.at).await?; - cmd.at = Some(node.node_name()); + cmd.at = Some(node.node_name().to_string()); let tui = Self { ctx, @@ -136,7 +136,7 @@ impl ShowCommandTui for ShowTui { .ask(&self.ctx, Request::get(format!("/node/outlet/{item_name}"))) .await?; let info = OutletInformation { - node_name: self.node.node_name(), + node_name: self.node.node_name().to_string(), worker_address: outlet_status.worker_route().into_diagnostic()?, to: outlet_status.to.to_string(), }; diff --git a/implementations/rust/ockam/ockam_command/src/upgrade.rs b/implementations/rust/ockam/ockam_command/src/upgrade.rs index 2bdf32be38a..36f680cdd5f 100644 --- a/implementations/rust/ockam/ockam_command/src/upgrade.rs +++ b/implementations/rust/ockam/ockam_command/src/upgrade.rs @@ -8,7 +8,6 @@ use ockam_core::env::get_env_with_default; use serde::Deserialize; use std::env; use std::fmt::Display; -use std::thread::sleep; use std::time::Duration; use tracing::{debug, info, warn}; use url::Url; @@ -68,13 +67,13 @@ impl TryFrom for Release { } } -pub fn check_if_an_upgrade_is_available(options: &CommandGlobalOpts) -> Result<()> { +pub async fn check_if_an_upgrade_is_available(options: &CommandGlobalOpts) -> Result<()> { if upgrade_check_is_disabled() || options.global_args.test_argument_parser { debug!("Upgrade check is disabled"); return Ok(()); } - let latest_release = get_release_data()?; + let latest_release = get_release_data().await?; let current_version = semver::Version::parse(crate_version!()).map_err(|_| miette!("Invalid version"))?; let latest_version = @@ -103,10 +102,10 @@ pub fn check_if_an_upgrade_is_available(options: &CommandGlobalOpts) -> Result<( Ok(()) } -fn get_release_data() -> Result { +async fn get_release_data() -> Result { // All GitHub API requests must include a valid `User-Agent` header. // See https://docs.github.com/en/rest/using-the-rest-api/getting-started-with-the-rest-api?apiVersion=2022-11-28#user-agent - let client = reqwest::blocking::Client::builder() + let client = reqwest::Client::builder() .user_agent("ockam") .default_headers({ let mut headers = reqwest::header::HeaderMap::new(); @@ -125,9 +124,11 @@ fn get_release_data() -> Result { if let Ok(res) = client .get("https://github.com/build-trust/ockam/releases/latest") .send() + .await { let json = res .json::() + .await .into_diagnostic() .wrap_err("Failed to parse JSON response")?; let parsed = Release::try_from(json)?; @@ -136,14 +137,13 @@ fn get_release_data() -> Result { } warn!("Failed to retrieve the latest release data from GitHub, retrying..."); retries_left -= 1; - sleep(Duration::from_millis(250)); + tokio::time::sleep(Duration::from_millis(250)).await; } Err(miette!("Couldn't retrieve the release data from GitHub")) } #[cfg(test)] mod tests { - use std::thread::sleep; use std::time::Duration; use super::*; @@ -202,16 +202,16 @@ mod tests { assert!(Release::try_from(json).is_err()); } - #[test] - fn get_and_parse_release_data_from_github() { + #[tokio::test] + async fn get_and_parse_release_data_from_github() { // Make sure that the data received from GitHub can be parsed correctly let mut is_ok = false; for _ in 0..5 { - if get_release_data().is_ok() { + if get_release_data().await.is_ok() { is_ok = true; break; } - sleep(Duration::from_secs(2)); + tokio::time::sleep(Duration::from_secs(2)).await; } assert!(is_ok); } diff --git a/implementations/rust/ockam/ockam_command/src/util/api.rs b/implementations/rust/ockam/ockam_command/src/util/api.rs index 52f47ec9bc6..5ebca6402e9 100644 --- a/implementations/rust/ockam/ockam_command/src/util/api.rs +++ b/implementations/rust/ockam/ockam_command/src/util/api.rs @@ -1,5 +1,3 @@ -use miette::IntoDiagnostic; -use ockam::identity::Identifier; use ockam_api::nodes::models::flow_controls::AddConsumer; use ockam_api::nodes::models::services::StartHopServiceRequest; use ockam_api::nodes::service::default_address::DefaultAddress; @@ -9,13 +7,6 @@ use ockam_core::flow_control::FlowControlId; use ockam_core::Address; use ockam_multiaddr::MultiAddr; -use crate::Result; - -/// Construct a request to query node status -pub(crate) fn query_status() -> Request<()> { - Request::get("/node") -} - pub(crate) fn get_node_resources() -> Request<()> { Request::get("/node/resources") } @@ -54,26 +45,6 @@ pub(crate) fn show_secure_channel( Request::get("/node/show_secure_channel").body(payload) } -/// Construct a request to create Secure Channel Listeners -pub(crate) fn create_secure_channel_listener( - addr: &Address, - authorized_identifiers: Option>, - identity_name: Option, -) -> Result> { - let payload = models::secure_channel::CreateSecureChannelListenerRequest::new( - addr, - authorized_identifiers, - identity_name, - ); - - let mut buf = vec![]; - Request::post("/node/secure_channel_listener") - .body(payload) - .encode(&mut buf) - .into_diagnostic()?; - Ok(buf) -} - /// Construct a request to list Secure Channel Listeners pub(crate) fn list_secure_channel_listener() -> Request<()> { Request::get("/node/secure_channel_listener") diff --git a/implementations/rust/ockam/ockam_command/src/util/mod.rs b/implementations/rust/ockam/ockam_command/src/util/mod.rs index c825eba9d26..d018e680845 100644 --- a/implementations/rust/ockam/ockam_command/src/util/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/util/mod.rs @@ -1,23 +1,16 @@ -use std::sync::Arc; use std::{ net::{SocketAddr, TcpListener}, path::Path, }; use colorful::Colorful; -use miette::{miette, IntoDiagnostic}; -use ockam::{Address, Context, NodeBuilder}; +use miette::miette; use ockam_api::cli_state::CliState; -use ockam_api::cli_state::CliStateError; use ockam_api::colors::color_primary; use ockam_api::config::lookup::{InternetAddress, LookupMeta}; use ockam_api::fmt_warn; -use ockam_core::{DenyAll, OpenTelemetryContext}; use ockam_multiaddr::proto::{DnsAddr, Ip4, Ip6, Project, Space, Tcp}; use ockam_multiaddr::{proto::Node, MultiAddr, Protocol}; -use opentelemetry::trace::FutureExt; -use tokio::runtime::Runtime; -use tracing::{debug, error}; use crate::{CommandGlobalOpts, Result}; @@ -30,89 +23,6 @@ pub mod parsers; #[allow(unused)] pub mod validators; -pub fn local_cmd(res: miette::Result<()>) -> miette::Result<()> { - if let Err(error) = &res { - // Note: error! is also called in command_event.rs::add_command_error_event() - error!(%error, "Failed to run command"); - } - res -} - -pub fn async_cmd(command_name: &str, opts: CommandGlobalOpts, f: F) -> miette::Result<()> -where - F: FnOnce(Context) -> Fut + Send + Sync + 'static, - Fut: core::future::Future> + Send + 'static, -{ - debug!("running '{}' asynchronously", command_name); - let res = embedded_node(opts, |ctx| { - async move { f(ctx).await }.with_context(OpenTelemetryContext::current_context()) - }); - local_cmd(res) -} - -pub fn embedded_node(opts: CommandGlobalOpts, f: F) -> core::result::Result -where - F: FnOnce(Context) -> Fut + Send + Sync + 'static, - Fut: core::future::Future> + Send + 'static, - T: Send + 'static, - E: Send + Sync + From + 'static, -{ - let (ctx, mut executor) = NodeBuilder::new() - .no_logging() - .with_runtime(opts.rt.clone()) - .build(); - let res = executor.execute( - async move { - let child_ctx = ctx - .new_detached( - Address::random_tagged("Detached.embedded_node"), - DenyAll, - DenyAll, - ) - .expect("Embedded node child ctx can't be created"); - let r = f(child_ctx).await; - let _ = ctx.shutdown_node().await; - r - } - .with_context(OpenTelemetryContext::current_context()), - ); - match res { - Ok(Err(e)) => Err(e), - Ok(Ok(t)) => Ok(t), - Err(e) => Err(CliStateError::Ockam(e).into()), - } -} - -pub fn embedded_node_that_is_not_stopped(rt: Arc, f: F) -> miette::Result -where - F: FnOnce(Context) -> Fut + Send + Sync + 'static, - Fut: core::future::Future> + Send + 'static, - T: Send + 'static, -{ - let (ctx, mut executor) = NodeBuilder::new().no_logging().with_runtime(rt).build(); - let res = executor.execute(async move { - let child_ctx = ctx - .new_detached( - Address::random_tagged("Detached.embedded_node.not_stopped"), - DenyAll, - DenyAll, - ) - .expect("Embedded node child ctx can't be created"); - let result = f(child_ctx).await; - let _ = ctx.shutdown_node().await; - result.map_err(|e| { - ockam_core::Error::new( - ockam_core::errcode::Origin::Executor, - ockam_core::errcode::Kind::Unknown, - e, - ) - }) - }); - - let res = res.map_err(|e| miette::miette!(e)); - res?.into_diagnostic() -} - #[allow(unused)] pub fn print_path(p: &Path) -> String { p.to_str().unwrap_or("").to_string() @@ -226,9 +136,9 @@ pub fn print_warning_for_deprecated_flag_no_effect( #[cfg(test)] mod tests { - use std::str::FromStr; - use super::*; + use ockam_node::Context; + use std::str::FromStr; #[ockam_macros::test(crate = "ockam")] async fn test_process_multi_addr(_ctx: &mut Context) -> ockam::Result<()> { @@ -269,34 +179,4 @@ mod tests { } Ok(()) } - - #[test] - fn test_execute_error() { - let result = embedded_node_that_is_not_stopped( - Arc::new(Runtime::new().unwrap()), - |ctx| async move { function_returning_an_error(ctx, 1).await }, - ); - assert!(result.is_err()); - - async fn function_returning_an_error(_ctx: Context, _parameter: u8) -> miette::Result<()> { - Err(miette!("boom")) - } - } - - #[test] - fn test_execute_error_() { - let result = embedded_node_that_is_not_stopped( - Arc::new(Runtime::new().unwrap()), - |ctx| async move { function_returning_an_error_and_stopping_the_context(ctx, 1).await }, - ); - assert!(result.is_err()); - - async fn function_returning_an_error_and_stopping_the_context( - ctx: Context, - _parameter: u8, - ) -> miette::Result<()> { - ctx.shutdown_node().await.into_diagnostic()?; - Err(miette!("boom")) - } - } } diff --git a/implementations/rust/ockam/ockam_command/src/vault/create.rs b/implementations/rust/ockam/ockam_command/src/vault/create.rs index 241c242592c..f71a83b7d5a 100644 --- a/implementations/rust/ockam/ockam_command/src/vault/create.rs +++ b/implementations/rust/ockam/ockam_command/src/vault/create.rs @@ -34,7 +34,7 @@ pub struct CreateCommand { impl Command for CreateCommand { const NAME: &'static str = "vault create"; - async fn async_run(self, _ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { + async fn run(self, _ctx: &Context, opts: CommandGlobalOpts) -> crate::Result<()> { if opts.state.get_named_vaults().await?.is_empty() { opts.terminal.write_line(fmt_info!( "This is the first vault to be created in this environment. It will be set as the default vault" diff --git a/implementations/rust/ockam/ockam_command/src/vault/delete.rs b/implementations/rust/ockam/ockam_command/src/vault/delete.rs index ec20e7f4a4f..55a69f77607 100644 --- a/implementations/rust/ockam/ockam_command/src/vault/delete.rs +++ b/implementations/rust/ockam/ockam_command/src/vault/delete.rs @@ -1,6 +1,5 @@ use crate::terminal::tui::DeleteCommandTui; use crate::tui::PluralTerm; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; use clap::Args; use colorful::Colorful; @@ -31,17 +30,11 @@ pub struct DeleteCommand { } impl DeleteCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "vault delete".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { DeleteTui::run(opts, self.clone()).await } } diff --git a/implementations/rust/ockam/ockam_command/src/vault/list.rs b/implementations/rust/ockam/ockam_command/src/vault/list.rs index 06d3e066f04..352205f8c6d 100644 --- a/implementations/rust/ockam/ockam_command/src/vault/list.rs +++ b/implementations/rust/ockam/ockam_command/src/vault/list.rs @@ -1,7 +1,6 @@ use clap::Args; use miette::IntoDiagnostic; -use crate::util::async_cmd; use crate::vault::util::VaultOutput; use crate::{docs, CommandGlobalOpts}; @@ -19,17 +18,11 @@ const AFTER_LONG_HELP: &str = include_str!("./static/list/after_long_help.txt"); pub struct ListCommand; impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "vaults list".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { let vaults = opts .state .get_named_vaults() diff --git a/implementations/rust/ockam/ockam_command/src/vault/mod.rs b/implementations/rust/ockam/ockam_command/src/vault/mod.rs index 5bb64aa6803..fa29981977d 100644 --- a/implementations/rust/ockam/ockam_command/src/vault/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/vault/mod.rs @@ -7,6 +7,8 @@ use crate::vault::move_vault::MoveCommand; use crate::vault::show::ShowCommand; use crate::{docs, Command, CommandGlobalOpts}; +use ockam_node::Context; + mod create; mod delete; mod list; @@ -38,13 +40,13 @@ pub enum VaultSubcommand { } impl VaultCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - VaultSubcommand::Create(cmd) => cmd.run(opts), - VaultSubcommand::Move(cmd) => cmd.run(opts), - VaultSubcommand::Show(cmd) => cmd.run(opts), - VaultSubcommand::List(cmd) => cmd.run(opts), - VaultSubcommand::Delete(cmd) => cmd.run(opts), + VaultSubcommand::Create(cmd) => cmd.run(ctx, opts).await, + VaultSubcommand::Move(cmd) => cmd.run(opts).await, + VaultSubcommand::Show(cmd) => cmd.run(opts).await, + VaultSubcommand::List(cmd) => cmd.run(opts).await, + VaultSubcommand::Delete(cmd) => cmd.run(opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/src/vault/move_vault.rs b/implementations/rust/ockam/ockam_command/src/vault/move_vault.rs index 5089cfc3b73..a52bd8a031f 100644 --- a/implementations/rust/ockam/ockam_command/src/vault/move_vault.rs +++ b/implementations/rust/ockam/ockam_command/src/vault/move_vault.rs @@ -4,7 +4,6 @@ use clap::Args; use colorful::Colorful; use ockam_api::{fmt_err, fmt_info}; -use crate::util::async_cmd; use crate::{docs, CommandGlobalOpts}; const LONG_ABOUT: &str = include_str!("./static/move/long_about.txt"); @@ -25,17 +24,11 @@ pub struct MoveCommand { } impl MoveCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "move vault".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { let vault_name = self.name.clone(); let vault_path = self.path.clone(); match opts diff --git a/implementations/rust/ockam/ockam_command/src/vault/show.rs b/implementations/rust/ockam/ockam_command/src/vault/show.rs index 94ee771bac1..3582eedc7d1 100644 --- a/implementations/rust/ockam/ockam_command/src/vault/show.rs +++ b/implementations/rust/ockam/ockam_command/src/vault/show.rs @@ -8,7 +8,6 @@ use ockam_api::output::Output; use crate::terminal::tui::ShowCommandTui; use crate::tui::PluralTerm; -use crate::util::async_cmd; use crate::vault::util::VaultOutput; const LONG_ABOUT: &str = include_str!("./static/show/long_about.txt"); @@ -28,17 +27,11 @@ pub struct ShowCommand { } impl ShowCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |_ctx| async move { - self.async_run(opts).await - }) - } - pub fn name(&self) -> String { "vault show".into() } - async fn async_run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, opts: CommandGlobalOpts) -> miette::Result<()> { ShowTui::run(opts, self.clone()).await } } diff --git a/implementations/rust/ockam/ockam_command/src/worker/list.rs b/implementations/rust/ockam/ockam_command/src/worker/list.rs index 7f6088770b4..f94df14fb1e 100644 --- a/implementations/rust/ockam/ockam_command/src/worker/list.rs +++ b/implementations/rust/ockam/ockam_command/src/worker/list.rs @@ -11,7 +11,7 @@ use ockam_api::nodes::BackgroundNodeClient; use crate::{docs, CommandGlobalOpts}; -use crate::util::{api, async_cmd}; +use crate::util::api; const LONG_ABOUT: &str = include_str!("./static/list/long_about.txt"); const PREVIEW_TAG: &str = include_str!("../static/preview_tag.txt"); @@ -31,17 +31,11 @@ pub struct ListCommand { } impl ListCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { - async_cmd(&self.name(), opts.clone(), |ctx| async move { - self.async_run(&ctx, opts).await - }) - } - pub fn name(&self) -> String { "workers list".into() } - async fn async_run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(&self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { let node = BackgroundNodeClient::create(ctx, &opts.state, &self.at).await?; let is_finished: Mutex = Mutex::new(false); diff --git a/implementations/rust/ockam/ockam_command/src/worker/mod.rs b/implementations/rust/ockam/ockam_command/src/worker/mod.rs index e6d28735f94..58d9bc99893 100644 --- a/implementations/rust/ockam/ockam_command/src/worker/mod.rs +++ b/implementations/rust/ockam/ockam_command/src/worker/mod.rs @@ -4,6 +4,8 @@ use list::ListCommand; use crate::{docs, CommandGlobalOpts}; +use ockam_node::Context; + mod list; const LONG_ABOUT: &str = include_str!("./static/long_about.txt"); @@ -27,9 +29,9 @@ pub enum WorkerSubcommand { } impl WorkerCommand { - pub fn run(self, opts: CommandGlobalOpts) -> miette::Result<()> { + pub async fn run(self, ctx: &Context, opts: CommandGlobalOpts) -> miette::Result<()> { match self.subcommand { - WorkerSubcommand::List(c) => c.run(opts), + WorkerSubcommand::List(c) => c.run(ctx, opts).await, } } diff --git a/implementations/rust/ockam/ockam_command/tests/bats/local/authority.bats b/implementations/rust/ockam/ockam_command/tests/bats/local/authority.bats index 793855f158b..3c9680df0e9 100644 --- a/implementations/rust/ockam/ockam_command/tests/bats/local/authority.bats +++ b/implementations/rust/ockam/ockam_command/tests/bats/local/authority.bats @@ -15,11 +15,8 @@ teardown() { # ===== TESTS @test "authority - an authority node must be shown as UP even if its tcp listener cannot be accessed" { - run_success "$OCKAM" identity create authority - authority_identity_full=$($OCKAM identity show --full --encoding hex authority) - trusted="{}" port="$(random_port)" - run_success "$OCKAM" authority create --tcp-listener-address="127.0.0.1:$port" --project-identifier 1 --trusted-identities "$trusted" + run_success "$OCKAM" authority create --tcp-listener-address="127.0.0.1:$port" --project-identifier 1 --trusted-identities "{}" sleep 1 # the name of the node is authority-{project-identifier} diff --git a/implementations/rust/ockam/ockam_node/Cargo.toml b/implementations/rust/ockam/ockam_node/Cargo.toml index 7508afe2acb..96c160749b4 100644 --- a/implementations/rust/ockam/ockam_node/Cargo.toml +++ b/implementations/rust/ockam/ockam_node/Cargo.toml @@ -38,7 +38,6 @@ default = ["std"] std = [ "ockam_core/std", "ockam_transport_core/std", - "once_cell/std", "opentelemetry", "tokio", "tracing-opentelemetry", @@ -93,7 +92,6 @@ ockam_core = { path = "../ockam_core", version = "^0.124.0", default-features = ockam_executor = { path = "../ockam_executor", version = "^0.93.0", default-features = false, optional = true } ockam_macros = { path = "../ockam_macros", version = "^0.37.0" } ockam_transport_core = { path = "../ockam_transport_core", version = "^0.101.0", default-features = false, optional = true } -once_cell = { version = "1.19.0", optional = true, default-features = false } opentelemetry = { version = "0.26.0", features = ["logs", "metrics", "trace"], optional = true } percent-encoding = { version = "2.3", default-features = false } regex = { version = "1.10.6", default-features = false, optional = true } diff --git a/implementations/rust/ockam/ockam_node/src/executor.rs b/implementations/rust/ockam/ockam_node/src/executor.rs index b6adfcb9e2a..51b354f5070 100644 --- a/implementations/rust/ockam/ockam_node/src/executor.rs +++ b/implementations/rust/ockam/ockam_node/src/executor.rs @@ -23,13 +23,6 @@ use ockam_core::{ Error, }; -// TODO: Either make this the only one place we create runtime, or vice verse: remove it from here -#[cfg(feature = "std")] -pub(crate) static RUNTIME: once_cell::sync::Lazy>> = - once_cell::sync::Lazy::new(|| { - ockam_core::compat::sync::Mutex::new(Some(Runtime::new().unwrap())) - }); - /// Underlying Ockam node executor /// /// This type is a small wrapper around an inner async runtime (`tokio` by @@ -128,22 +121,6 @@ impl Executor { } } - /// Execute a future and block until a result is returned - /// This function can only be called to run futures before the Executor has been initialized. - /// Otherwise the Executor rt attribute needs to be accessed to execute or spawn futures - #[cfg(feature = "std")] - pub fn execute_future(future: F) -> Result - where - F: Future + Send + 'static, - F::Output: Send + 'static, - { - let lock = RUNTIME.lock().unwrap(); - let rt = lock.as_ref().expect("Runtime was consumed"); - let join_body = rt.spawn(future.with_current_context()); - rt.block_on(join_body.with_current_context()) - .map_err(|e| Error::new(Origin::Executor, Kind::Unknown, e)) - } - #[cfg(not(feature = "std"))] /// Initialise and run the Ockam node executor context /// diff --git a/implementations/rust/ockam/ockam_node/src/node.rs b/implementations/rust/ockam/ockam_node/src/node.rs index f1b33534d70..45308fba7e0 100644 --- a/implementations/rust/ockam/ockam_node/src/node.rs +++ b/implementations/rust/ockam/ockam_node/src/node.rs @@ -111,11 +111,6 @@ impl NodeBuilder { { Arc::new( tokio::runtime::Builder::new_multi_thread() - // Using a lower stack size than the default (1MB), - // this helps improve the cache hit ratio and reduces - // the memory footprint. - // Can be increased if needed. - .thread_stack_size(1024 * 1024) .enable_all() .build() .expect("cannot initialize the tokio runtime"), diff --git a/implementations/rust/ockam/ockam_node/src/storage/database/sqlx_database.rs b/implementations/rust/ockam/ockam_node/src/storage/database/sqlx_database.rs index 4547c70e71b..a59303a352f 100644 --- a/implementations/rust/ockam/ockam_node/src/storage/database/sqlx_database.rs +++ b/implementations/rust/ockam/ockam_node/src/storage/database/sqlx_database.rs @@ -147,6 +147,8 @@ impl SqlxDatabase { configuration: &DatabaseConfiguration, migration_set: Option, ) -> Result { + debug!("Creating SQLx database using configuration"); + configuration.create_directory_if_necessary()?; // creating a new database might be failing a few times diff --git a/implementations/rust/ockam/ockam_transport_core/src/error.rs b/implementations/rust/ockam/ockam_transport_core/src/error.rs index 079363160ce..1313098ba96 100644 --- a/implementations/rust/ockam/ockam_transport_core/src/error.rs +++ b/implementations/rust/ockam/ockam_transport_core/src/error.rs @@ -80,6 +80,8 @@ pub enum TransportError { IdentifierChanged, /// Invalid OckamPortalPacket InvalidOckamPortalPacket(String), + /// Connection timeout + ConnectionTimeout, } impl ockam_core::compat::error::Error for TransportError {} @@ -130,6 +132,7 @@ impl core::fmt::Display for TransportError { "identifier of the other side of the portal has changed when updating the route" ), Self::InvalidOckamPortalPacket(e) => write!(f, "invalid OckamPortalPacket: {}", e), + Self::ConnectionTimeout => write!(f, "connection timed out"), } } } @@ -171,6 +174,7 @@ impl From for Error { PrivilegedPortalsPrerequisitesCheckFailed(_) => Kind::Misuse, IdentifierChanged => Kind::Conflict, InvalidOckamPortalPacket(_) => Kind::Invalid, + ConnectionTimeout => Kind::Io, }; Error::new(Origin::Transport, kind, err) diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/options.rs b/implementations/rust/ockam/ockam_transport_tcp/src/options.rs index a500f816401..b5cb49816ed 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/options.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/options.rs @@ -1,11 +1,13 @@ use crate::workers::Addresses; use ockam_core::compat::sync::Arc; +use ockam_core::compat::time::Duration; use ockam_core::flow_control::{FlowControlId, FlowControlOutgoingAccessControl, FlowControls}; use ockam_core::{Address, OutgoingAccessControl}; /// Trust Options for a TCP connection #[derive(Debug)] pub struct TcpConnectionOptions { + pub(super) timeout: Option, pub(super) consumer: Vec, pub(crate) flow_control_id: FlowControlId, } @@ -15,6 +17,7 @@ impl TcpConnectionOptions { /// Mark this Tcp Receiver as a Producer with a random [`FlowControlId`] pub fn new() -> Self { Self { + timeout: None, consumer: vec![], flow_control_id: FlowControls::generate_flow_control_id(), } @@ -31,6 +34,23 @@ impl TcpConnectionOptions { pub fn flow_control_id(&self) -> FlowControlId { self.flow_control_id.clone() } + + /// Set connect timeout + pub fn set_timeout(mut self, timeout: Option) -> Self { + self.timeout = timeout; + self + } + + /// Set connect timeout + pub fn with_timeout(mut self, timeout: Duration) -> Self { + self.timeout = Some(timeout); + self + } + + /// Connect timeout + pub fn timeout(&self) -> Option { + self.timeout + } } impl TcpConnectionOptions { diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/portal/portal_worker.rs b/implementations/rust/ockam/ockam_transport_tcp/src/portal/portal_worker.rs index 9621300d622..d4db4a2d237 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/portal/portal_worker.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/portal/portal_worker.rs @@ -375,7 +375,7 @@ impl TcpPortalWorker { self.read_half = Some(ReadHalfWithTls(rx)); } else { debug!(portal_type = %self.portal_type, sender_internal = %self.addresses.sender_internal, "connect to {}", self.hostname_port); - let (rx, tx) = connect(&self.hostname_port).await?; + let (rx, tx) = connect(&self.hostname_port, None).await?; self.write_half = Some(WriteHalfNoTls(tx)); self.read_half = Some(ReadHalfNoTls(rx)); } diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/transport/common.rs b/implementations/rust/ockam/ockam_transport_tcp/src/transport/common.rs index 461cd87936f..28423195df2 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/transport/common.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/transport/common.rs @@ -15,14 +15,33 @@ use tracing::{debug, instrument}; /// Connect to a socket address via a regular TcpStream #[instrument(skip_all)] -pub(crate) async fn connect(to: &HostnamePort) -> Result<(OwnedReadHalf, OwnedWriteHalf)> { - Ok(create_tcp_stream(to).await?.into_split()) +pub(crate) async fn connect( + to: &HostnamePort, + timeout: Option, +) -> Result<(OwnedReadHalf, OwnedWriteHalf)> { + Ok(create_tcp_stream(to, timeout).await?.into_split()) } /// Create a TCP stream to a given socket address -pub(crate) async fn create_tcp_stream(to: &HostnamePort) -> Result { +pub(crate) async fn create_tcp_stream( + to: &HostnamePort, + timeout: Option, +) -> Result { debug!(addr = %to, "Connecting"); - let connection = match TcpStream::connect(to.to_string()).await { + + let result = if let Some(timeout) = timeout { + match tokio::time::timeout(timeout, TcpStream::connect(to.to_string())).await { + Ok(result) => result, + Err(_) => { + debug!(addr = %to, timeout = %timeout.as_secs(), "Timeout"); + return Err(TransportError::ConnectionTimeout)?; + } + } + } else { + TcpStream::connect(to.to_string()).await + }; + + let connection = match result { Ok(c) => { debug!(addr = %to, "Connected"); c @@ -64,7 +83,7 @@ pub(crate) async fn connect_tls( debug!(to = %to, "Trying to connect using TLS"); // create a tcp stream - let connection = create_tcp_stream(to).await?; + let connection = create_tcp_stream(to, None).await?; // create a TLS connector let tls_connector = create_tls_connector().await?; diff --git a/implementations/rust/ockam/ockam_transport_tcp/src/transport/connection.rs b/implementations/rust/ockam/ockam_transport_tcp/src/transport/connection.rs index 8081814fe8d..3c2f11bf9e2 100644 --- a/implementations/rust/ockam/ockam_transport_tcp/src/transport/connection.rs +++ b/implementations/rust/ockam/ockam_transport_tcp/src/transport/connection.rs @@ -111,7 +111,7 @@ impl TcpTransport { let peer = HostnamePort::from_str(&peer.into())?; debug!("Connecting to {}", peer.clone()); - let (read_half, write_half) = connect(&peer).await?; + let (read_half, write_half) = connect(&peer, options.timeout).await?; let socket = read_half .peer_addr() .map_err(|e| ockam_core::Error::new(Origin::Transport, Kind::Internal, e))?; diff --git a/tools/stress-test/src/main.rs b/tools/stress-test/src/main.rs index 96fefde840c..1e67edc01fc 100644 --- a/tools/stress-test/src/main.rs +++ b/tools/stress-test/src/main.rs @@ -132,9 +132,12 @@ struct State { impl State { fn new(config: Config, log: bool) -> Self { - let cli_state = CliState::new(CliStateMode::with_default_dir().unwrap()) - .expect("cannot create cli state"); let rt = Arc::new(Runtime::new().expect("cannot create a tokio runtime")); + let cli_state = rt.block_on(async move { + CliState::create(CliStateMode::with_default_dir().unwrap()) + .await + .expect("cannot create cli state") + }); let builder = if log { NodeBuilder::new() } else {