Skip to content

Commit

Permalink
Improve messaging for start and stop
Browse files Browse the repository at this point in the history
  • Loading branch information
elizabethengelman committed Feb 13, 2024
1 parent 7a86f06 commit 84cedae
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 16 deletions.
42 changes: 38 additions & 4 deletions cmd/soroban-cli/src/commands/network/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,47 @@ impl fmt::Display for Network {
}
}

pub fn connect_to_docker(
pub async fn connect_to_docker(
docker_socket_path: &Option<String>,
) -> Result<Docker, bollard::errors::Error> {
if docker_socket_path.is_some() {
let docker = if docker_socket_path.is_some() {
let socket = docker_socket_path.as_ref().unwrap();
Docker::connect_with_socket(socket, DEFAULT_TIMEOUT, API_DEFAULT_VERSION)
let connection = Docker::connect_with_socket(socket, DEFAULT_TIMEOUT, API_DEFAULT_VERSION)?;
check_docker_connection(&connection).await?;
connection
} else {
Docker::connect_with_socket_defaults()
let connection = Docker::connect_with_socket_defaults()?;
check_docker_connection(&connection).await?;
connection
};
Ok(docker)
}

// When bollard is not able to connect to the docker daemon, it returns a generic ConnectionRefused error
// This method attempts to connect to the docker daemon and returns a more specific error message
pub async fn check_docker_connection(docker: &Docker) -> Result<(), bollard::errors::Error> {
// This is a bit hacky, but the `client_addr` field is not directly accessible from the `Docker` struct, but we can access it from the debug string representation of the `Docker` struct
let docker_debug_string = format!("{:#?}", docker);
let start_of_client_addr = docker_debug_string.find("client_addr: ").unwrap();
let end_of_client_addr = docker_debug_string[start_of_client_addr..]
.find(',')
.unwrap();
// Extract the substring containing the value of client_addr
let client_addr = &docker_debug_string
[start_of_client_addr + "client_addr: ".len()..start_of_client_addr + end_of_client_addr]
.trim()
.trim_matches('"');

match docker.version().await {
Ok(_version) => Ok(()),
Err(err) => {
println!(
"⛔️ Failed to connect to the Docker daemon at {:?}. Is the docker daemon running?\n
Running a local Stellar network requires a Docker-compatible container runtime.\n
Also, please note that if you are using Docker Desktop, you may need to utilize the `--docker-socket-path` flag to pass in the location of the docker socket on your machine.",
client_addr
);
Err(err)
}
}
}
33 changes: 24 additions & 9 deletions cmd/soroban-cli/src/commands/network/start.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::collections::HashMap;

use bollard::{
container::{Config, CreateContainerOptions, StartContainerOptions},
image::CreateImageOptions,
service::{HostConfig, PortBinding},
};
use futures_util::TryStreamExt;
use std::collections::HashMap;

use crate::commands::network::shared::connect_to_docker;
use crate::commands::network::shared::Network;
Expand All @@ -14,7 +15,7 @@ const DOCKER_IMAGE: &str = "docker.io/stellar/quickstart";

#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Failed to start container: {0}")]
#[error("⛔ ️Failed to start container: {0}")]
StartContainerError(#[from] bollard::errors::Error),
}

Expand Down Expand Up @@ -50,13 +51,13 @@ pub struct Cmd {

impl Cmd {
pub async fn run(&self) -> Result<(), Error> {
println!("Starting {} network", &self.network);
println!("ℹ️ Starting {} network", &self.network);
run_docker_command(self).await
}
}

async fn run_docker_command(cmd: &Cmd) -> Result<(), Error> {
let docker = connect_to_docker(&cmd.docker_socket_path)?;
let docker = connect_to_docker(&cmd.docker_socket_path).await?;

let image = get_image_name(cmd);
docker
Expand Down Expand Up @@ -91,20 +92,34 @@ async fn run_docker_command(cmd: &Cmd) -> Result<(), Error> {
let create_container_response = docker
.create_container(
Some(CreateContainerOptions {
name: container_name,
name: container_name.clone(),
..Default::default()
}),
config,
)
.await
.unwrap();
.await?;

docker
.start_container(
&create_container_response.id,
None::<StartContainerOptions<String>>,
)
.await
.map_err(Error::StartContainerError)
.await?;
println!("✅ Container started: {container_name}");
let stop_message = format!(
"ℹ️ To stop this container run: soroban network stop {network} {additional_flags}",
network = &cmd.network,
additional_flags = if cmd.docker_socket_path.is_some() {
format!(
"--docker-socket-path {}",
cmd.docker_socket_path.as_ref().unwrap()
)
} else {
String::new()
}
);
println!("{stop_message}");
Ok(())
}

fn get_container_args(cmd: &Cmd) -> Vec<String> {
Expand Down
6 changes: 3 additions & 3 deletions cmd/soroban-cli/src/commands/network/stop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ pub struct Cmd {
impl Cmd {
pub async fn run(&self) -> Result<(), Error> {
let container_name = format!("stellar-{}", self.network);
let docker = connect_to_docker(&self.docker_socket_path)?;
println!("Stopping container: {container_name}");
let docker = connect_to_docker(&self.docker_socket_path).await?;
println!("ℹ️ Stopping container: {container_name}");
docker.stop_container(&container_name, None).await.unwrap();

println!("✅ Container stopped: {container_name}");
Ok(())
}
}

0 comments on commit 84cedae

Please sign in to comment.