From 9c6d23ca157af9b7b90b2a0756acc8ac0a4d726e Mon Sep 17 00:00:00 2001 From: Elizabeth Engelman <4752801+elizabethengelman@users.noreply.github.com> Date: Fri, 7 Jun 2024 12:02:32 -0400 Subject: [PATCH] Feat/add container log tailing cmd (#1361) * Add a command to tail logs from quickstart container * Move logs under a container subcommand: network container logs * Move start command under container: network container start network start will still work, it is marked as deprecated and should be removed at the next major release * Move stop command under container: network container stop `network stop` will still work, it is marked as deprecated and should be removed at the next major release --------- Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> --- FULL_HELP_DOCS.md | 98 ++++++++++++++++++- .../src/commands/network/container.rs | 49 ++++++++++ .../src/commands/network/container/logs.rs | 45 +++++++++ .../network/{ => container}/shared.rs | 0 .../commands/network/{ => container}/start.rs | 3 +- .../commands/network/{ => container}/stop.rs | 2 +- cmd/soroban-cli/src/commands/network/mod.rs | 39 ++++++-- 7 files changed, 222 insertions(+), 14 deletions(-) create mode 100644 cmd/soroban-cli/src/commands/network/container.rs create mode 100644 cmd/soroban-cli/src/commands/network/container/logs.rs rename cmd/soroban-cli/src/commands/network/{ => container}/shared.rs (100%) rename cmd/soroban-cli/src/commands/network/{ => container}/start.rs (99%) rename cmd/soroban-cli/src/commands/network/{ => container}/stop.rs (94%) diff --git a/FULL_HELP_DOCS.md b/FULL_HELP_DOCS.md index 4e3219e90..f78a1ae66 100644 --- a/FULL_HELP_DOCS.md +++ b/FULL_HELP_DOCS.md @@ -50,6 +50,10 @@ This document contains the help content for the `stellar` command-line program. * [`stellar network ls`↴](#stellar-network-ls) * [`stellar network start`↴](#stellar-network-start) * [`stellar network stop`↴](#stellar-network-stop) +* [`stellar network container`↴](#stellar-network-container) +* [`stellar network container logs`↴](#stellar-network-container-logs) +* [`stellar network container start`↴](#stellar-network-container-start) +* [`stellar network container stop`↴](#stellar-network-container-stop) * [`stellar version`↴](#stellar-version) * [`stellar cache`↴](#stellar-cache) * [`stellar cache clean`↴](#stellar-cache-clean) @@ -1188,8 +1192,9 @@ Start and configure networks * `add` — Add a new network * `rm` — Remove a network * `ls` — List networks -* `start` — Start network -* `stop` — Stop a network started with `network start`. For example, if you ran `soroban network start local`, you can use `soroban network stop local` to stop it +* `start` — ⚠️ Deprecated: use `soroban container start` instead +* `stop` — ⚠️ Deprecated: use `soroban container stop` instead +* `container` — Commands to start, stop and get logs for a quickstart container @@ -1257,6 +1262,8 @@ List networks ## `stellar network start` +⚠️ Deprecated: use `soroban container start` instead + Start network Start a container running a Stellar node, RPC, API, and friendbot (faucet). @@ -1288,7 +1295,9 @@ By default, when starting a testnet container, without any optional arguments, i ## `stellar network stop` -Stop a network started with `network start`. For example, if you ran `soroban network start local`, you can use `soroban network stop local` to stop it +⚠️ Deprecated: use `soroban container stop` instead + +Stop a network started with `network start`. For example, if you ran `soroban network start local`, you can use `soroban network stop local` to stop it. **Usage:** `stellar network stop [OPTIONS] ` @@ -1305,6 +1314,89 @@ Stop a network started with `network start`. For example, if you ran `soroban ne +## `stellar network container` + +Commands to start, stop and get logs for a quickstart container + +**Usage:** `stellar network container ` + +###### **Subcommands:** + +* `logs` — Tail logs of a running network container +* `start` — Start network +* `stop` — Stop a network started with `network container start`. For example, if you ran `network container start local`, you can use `network container stop local` to stop it + + + +## `stellar network container logs` + +Tail logs of a running network container + +**Usage:** `stellar network container logs [OPTIONS] ` + +###### **Arguments:** + +* `` — Network to tail + + Possible values: `local`, `testnet`, `futurenet`, `pubnet` + + +###### **Options:** + +* `-d`, `--docker-host ` — Optional argument to override the default docker host. This is useful when you are using a non-standard docker host path for your Docker-compatible container runtime, e.g. Docker Desktop defaults to $HOME/.docker/run/docker.sock instead of /var/run/docker.sock + + + +## `stellar network container start` + +Start network + +Start a container running a Stellar node, RPC, API, and friendbot (faucet). + +soroban network start [OPTIONS] + +By default, when starting a testnet container, without any optional arguments, it will run the equivalent of the following docker command: docker run --rm -p 8000:8000 --name stellar stellar/quickstart:testing --testnet --enable-soroban-rpc + +**Usage:** `stellar network container start [OPTIONS] ` + +###### **Arguments:** + +* `` — Network to start + + Possible values: `local`, `testnet`, `futurenet`, `pubnet` + + +###### **Options:** + +* `-d`, `--docker-host ` — Optional argument to override the default docker host. This is useful when you are using a non-standard docker host path for your Docker-compatible container runtime, e.g. Docker Desktop defaults to $HOME/.docker/run/docker.sock instead of /var/run/docker.sock +* `-l`, `--limits ` — Optional argument to specify the limits for the local network only +* `-p`, `--ports-mapping ` — Argument to specify the HOST_PORT:CONTAINER_PORT mapping + + Default value: `8000:8000` +* `-t`, `--image-tag-override ` — Optional argument to override the default docker image tag for the given network +* `-v`, `--protocol-version ` — Optional argument to specify the protocol version for the local network only + + + +## `stellar network container stop` + +Stop a network started with `network container start`. For example, if you ran `network container start local`, you can use `network container stop local` to stop it + +**Usage:** `stellar network container stop [OPTIONS] ` + +###### **Arguments:** + +* `` — Network to stop + + Possible values: `local`, `testnet`, `futurenet`, `pubnet` + + +###### **Options:** + +* `-d`, `--docker-host ` — Optional argument to override the default docker host. This is useful when you are using a non-standard docker host path for your Docker-compatible container runtime, e.g. Docker Desktop defaults to $HOME/.docker/run/docker.sock instead of /var/run/docker.sock + + + ## `stellar version` Print version information diff --git a/cmd/soroban-cli/src/commands/network/container.rs b/cmd/soroban-cli/src/commands/network/container.rs new file mode 100644 index 000000000..5ce74d07c --- /dev/null +++ b/cmd/soroban-cli/src/commands/network/container.rs @@ -0,0 +1,49 @@ +pub(crate) mod logs; +mod shared; +pub(crate) mod start; +pub(crate) mod stop; + +// TODO: remove once `network start` is removed +pub type StartCmd = start::Cmd; +// TODO: remove once `network top` is removed +pub type StopCmd = stop::Cmd; + +#[derive(Debug, clap::Subcommand)] +pub enum Cmd { + /// Tail logs of a running network container + Logs(logs::Cmd), + /// Start network + /// + /// Start a container running a Stellar node, RPC, API, and friendbot (faucet). + /// + /// soroban network start [OPTIONS] + /// + /// By default, when starting a testnet container, without any optional arguments, it will run the equivalent of the following docker command: + /// docker run --rm -p 8000:8000 --name stellar stellar/quickstart:testing --testnet --enable-soroban-rpc + Start(start::Cmd), + /// Stop a network started with `network container start`. For example, if you ran `network container start local`, you can use `network container stop local` to stop it. + Stop(stop::Cmd), +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + Logs(#[from] logs::Error), + + #[error(transparent)] + Start(#[from] start::Error), + + #[error(transparent)] + Stop(#[from] stop::Error), +} + +impl Cmd { + pub async fn run(&self) -> Result<(), Error> { + match &self { + Cmd::Logs(cmd) => cmd.run().await?, + Cmd::Start(cmd) => cmd.run().await?, + Cmd::Stop(cmd) => cmd.run().await?, + } + Ok(()) + } +} diff --git a/cmd/soroban-cli/src/commands/network/container/logs.rs b/cmd/soroban-cli/src/commands/network/container/logs.rs new file mode 100644 index 000000000..e37ceb098 --- /dev/null +++ b/cmd/soroban-cli/src/commands/network/container/logs.rs @@ -0,0 +1,45 @@ +use futures_util::TryStreamExt; + +use crate::commands::network::container::shared::{ + connect_to_docker, Error as ConnectionError, Network, DOCKER_HOST_HELP, +}; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + ConnectionError(#[from] ConnectionError), + + #[error("⛔ ️Failed to tail container: {0}")] + TailContainerError(#[from] bollard::errors::Error), +} + +#[derive(Debug, clap::Parser, Clone)] +pub struct Cmd { + /// Network to tail + pub network: Network, + + #[arg(short = 'd', long, help = DOCKER_HOST_HELP, env = "DOCKER_HOST")] + pub docker_host: Option, +} + +impl Cmd { + pub async fn run(&self) -> Result<(), Error> { + let container_name = format!("stellar-{}", self.network); + let docker = connect_to_docker(&self.docker_host).await?; + let logs_stream = &mut docker.logs( + &container_name, + Some(bollard::container::LogsOptions { + follow: true, + stdout: true, + stderr: true, + tail: "all", + ..Default::default() + }), + ); + + while let Some(log) = logs_stream.try_next().await? { + print!("{log}"); + } + Ok(()) + } +} diff --git a/cmd/soroban-cli/src/commands/network/shared.rs b/cmd/soroban-cli/src/commands/network/container/shared.rs similarity index 100% rename from cmd/soroban-cli/src/commands/network/shared.rs rename to cmd/soroban-cli/src/commands/network/container/shared.rs diff --git a/cmd/soroban-cli/src/commands/network/start.rs b/cmd/soroban-cli/src/commands/network/container/start.rs similarity index 99% rename from cmd/soroban-cli/src/commands/network/start.rs rename to cmd/soroban-cli/src/commands/network/container/start.rs index 1d2c0645e..bb67ac408 100644 --- a/cmd/soroban-cli/src/commands/network/start.rs +++ b/cmd/soroban-cli/src/commands/network/container/start.rs @@ -7,7 +7,7 @@ use bollard::{ }; use futures_util::TryStreamExt; -use crate::commands::network::shared::{ +use crate::commands::network::container::shared::{ connect_to_docker, Error as ConnectionError, Network, DOCKER_HOST_HELP, }; @@ -114,6 +114,7 @@ async fn run_docker_command(cmd: &Cmd) -> Result<(), Error> { String::new() } ); + println!("{stop_message}"); Ok(()) } diff --git a/cmd/soroban-cli/src/commands/network/stop.rs b/cmd/soroban-cli/src/commands/network/container/stop.rs similarity index 94% rename from cmd/soroban-cli/src/commands/network/stop.rs rename to cmd/soroban-cli/src/commands/network/container/stop.rs index 3a7443aed..c511b5e4d 100644 --- a/cmd/soroban-cli/src/commands/network/stop.rs +++ b/cmd/soroban-cli/src/commands/network/container/stop.rs @@ -1,4 +1,4 @@ -use crate::commands::network::shared::{ +use crate::commands::network::container::shared::{ connect_to_docker, Error as ConnectionError, Network, DOCKER_HOST_HELP, }; diff --git a/cmd/soroban-cli/src/commands/network/mod.rs b/cmd/soroban-cli/src/commands/network/mod.rs index 18fdb0029..581b965a0 100644 --- a/cmd/soroban-cli/src/commands/network/mod.rs +++ b/cmd/soroban-cli/src/commands/network/mod.rs @@ -15,11 +15,9 @@ use super::config::locator; pub const LOCAL_NETWORK_PASSPHRASE: &str = "Standalone Network ; February 2017"; pub mod add; +pub mod container; pub mod ls; pub mod rm; -pub mod shared; -pub mod start; -pub mod stop; #[derive(Debug, Parser)] pub enum Cmd { @@ -29,6 +27,8 @@ pub enum Cmd { Rm(rm::Cmd), /// List networks Ls(ls::Cmd), + /// ⚠️ Deprecated: use `soroban container start` instead + /// /// Start network /// /// Start a container running a Stellar node, RPC, API, and friendbot (faucet). @@ -37,9 +37,15 @@ pub enum Cmd { /// /// By default, when starting a testnet container, without any optional arguments, it will run the equivalent of the following docker command: /// docker run --rm -p 8000:8000 --name stellar stellar/quickstart:testing --testnet --enable-soroban-rpc - Start(start::Cmd), + Start(container::StartCmd), + /// ⚠️ Deprecated: use `soroban container stop` instead + /// /// Stop a network started with `network start`. For example, if you ran `soroban network start local`, you can use `soroban network stop local` to stop it. - Stop(stop::Cmd), + Stop(container::StopCmd), + + /// Commands to start, stop and get logs for a quickstart container + #[command(subcommand)] + Container(container::Cmd), } #[derive(thiserror::Error, Debug)] @@ -53,11 +59,16 @@ pub enum Error { #[error(transparent)] Ls(#[from] ls::Error), + // TODO: remove once `network start` is removed + #[error(transparent)] + Start(#[from] container::start::Error), + + // TODO: remove once `network stop` is removed #[error(transparent)] - Start(#[from] start::Error), + Stop(#[from] container::stop::Error), #[error(transparent)] - Stop(#[from] stop::Error), + Container(#[from] container::Error), #[error(transparent)] Config(#[from] locator::Error), @@ -86,8 +97,18 @@ impl Cmd { Cmd::Add(cmd) => cmd.run()?, Cmd::Rm(new) => new.run()?, Cmd::Ls(cmd) => cmd.run()?, - Cmd::Start(cmd) => cmd.run().await?, - Cmd::Stop(cmd) => cmd.run().await?, + Cmd::Container(cmd) => cmd.run().await?, + + // TODO Remove this once `network start` is removed + Cmd::Start(cmd) => { + eprintln!("⚠️ Warning: `network start` has been deprecated. Use `network container start` instead"); + cmd.run().await?; + } + // TODO Remove this once `network stop` is removed + Cmd::Stop(cmd) => { + println!("⚠️ Warning: `network stop` has been deprecated. Use `network container stop` instead"); + cmd.run().await?; + } }; Ok(()) }