aboutsummaryrefslogtreecommitdiff
path: root/src/garage/main.rs
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2021-10-21 17:29:27 +0200
committerAlex Auvolat <alex@adnab.me>2021-10-21 17:29:27 +0200
commitbff5333c622ce5c8c3a151b4bd2d7ad2d04004c2 (patch)
tree526f8a96612c6bc8b69344db6e60aa861e006932 /src/garage/main.rs
parentb7eccf52640b91c7243748e46506b88d0f1ceaef (diff)
downloadgarage-bff5333c622ce5c8c3a151b4bd2d7ad2d04004c2.tar.gz
garage-bff5333c622ce5c8c3a151b4bd2d7ad2d04004c2.zip
Move things around, improvements to CLI
Diffstat (limited to 'src/garage/main.rs')
-rw-r--r--src/garage/main.rs85
1 files changed, 15 insertions, 70 deletions
diff --git a/src/garage/main.rs b/src/garage/main.rs
index 57767df1..7f7196d9 100644
--- a/src/garage/main.rs
+++ b/src/garage/main.rs
@@ -4,7 +4,7 @@
#[macro_use]
extern crate log;
-mod admin_rpc;
+mod admin;
mod cli;
mod repair;
mod server;
@@ -16,12 +16,12 @@ use structopt::StructOpt;
use netapp::util::parse_and_resolve_peer_addr;
use netapp::NetworkKey;
-use garage_util::error::Error;
+use garage_util::error::*;
use garage_rpc::system::*;
use garage_rpc::*;
-use admin_rpc::*;
+use admin::*;
use cli::*;
#[derive(StructOpt, Debug)]
@@ -66,7 +66,7 @@ async fn main() {
};
if let Err(e) = res {
- error!("{}", e);
+ eprintln!("Error: {}", e);
std::process::exit(1);
}
}
@@ -74,7 +74,7 @@ async fn main() {
async fn cli_command(opt: Opt) -> Result<(), Error> {
let config = if opt.rpc_secret.is_none() || opt.rpc_host.is_none() {
Some(garage_util::config::read_config(opt.config_file.clone())
- .map_err(|e| Error::Message(format!("Unable to read configuration file {}: {}. Configuration file is needed because -h or -s is not provided on the command line.", opt.config_file.to_string_lossy(), e)))?)
+ .err_context(format!("Unable to read configuration file {}. Configuration file is needed because -h or -s is not provided on the command line.", opt.config_file.to_string_lossy()))?)
} else {
None
};
@@ -84,11 +84,11 @@ async fn cli_command(opt: Opt) -> Result<(), Error> {
.rpc_secret
.as_ref()
.or_else(|| config.as_ref().map(|c| &c.rpc_secret))
- .expect("No RPC secret provided");
+ .ok_or("No RPC secret provided")?;
let network_key = NetworkKey::from_slice(
- &hex::decode(net_key_hex_str).expect("Invalid RPC secret key (bad hex)")[..],
+ &hex::decode(net_key_hex_str).err_context("Invalid RPC secret key (bad hex)")?[..],
)
- .expect("Invalid RPC secret provided (wrong length)");
+ .ok_or("Invalid RPC secret provided (wrong length)")?;
// Generate a temporary keypair for our RPC client
let (_pk, sk) = sodiumoxide::crypto::sign::ed25519::gen_keypair();
@@ -97,77 +97,22 @@ async fn cli_command(opt: Opt) -> Result<(), Error> {
// Find and parse the address of the target host
let (id, addr) = if let Some(h) = opt.rpc_host {
- let (id, addrs) = parse_and_resolve_peer_addr(&h).expect("Invalid RPC host");
+ let (id, addrs) = parse_and_resolve_peer_addr(&h).ok_or_else(|| format!("Invalid RPC remote node identifier: {}. Expected format is <pubkey>@<IP or hostname>:<port>.", h))?;
(id, addrs[0])
} else if let Some(a) = config.as_ref().map(|c| c.rpc_public_addr).flatten() {
- let node_key = garage_rpc::system::gen_node_key(&config.unwrap().metadata_dir)
- .map_err(|e| Error::Message(format!("Unable to read or generate node key: {}", e)))?;
- (node_key.public_key(), a)
+ let node_id = garage_rpc::system::read_node_id(&config.unwrap().metadata_dir)
+ .err_context(READ_KEY_ERROR)?;
+ (node_id, a)
} else {
return Err(Error::Message("No RPC host provided".into()));
};
// Connect to target host
- netapp.clone().try_connect(addr, id).await?;
+ netapp.clone().try_connect(addr, id).await
+ .err_context("Unable to connect to destination RPC host. Check that you are using the same value of rpc_secret as them, and that you have their correct public key.")?;
let system_rpc_endpoint = netapp.endpoint::<SystemRpc, ()>(SYSTEM_RPC_PATH.into());
let admin_rpc_endpoint = netapp.endpoint::<AdminRpc, ()>(ADMIN_RPC_PATH.into());
- cli_cmd(opt.cmd, &system_rpc_endpoint, &admin_rpc_endpoint, id).await
-}
-
-fn node_id_command(config_file: PathBuf, quiet: bool) -> Result<(), Error> {
- let config = garage_util::config::read_config(config_file.clone()).map_err(|e| {
- Error::Message(format!(
- "Unable to read configuration file {}: {}",
- config_file.to_string_lossy(),
- e
- ))
- })?;
-
- let node_key = garage_rpc::system::gen_node_key(&config.metadata_dir)
- .map_err(|e| Error::Message(format!("Unable to read or generate node key: {}", e)))?;
-
- let idstr = if let Some(addr) = config.rpc_public_addr {
- let idstr = format!("{}@{}", hex::encode(&node_key.public_key()), addr);
- println!("{}", idstr);
- idstr
- } else {
- let idstr = hex::encode(&node_key.public_key());
- println!("{}", idstr);
-
- if !quiet {
- eprintln!("WARNING: I don't know the public address to reach this node.");
- eprintln!("In all of the instructions below, replace 127.0.0.1:3901 by the appropriate address and port.");
- }
-
- format!("{}@127.0.0.1:3901", idstr)
- };
-
- if !quiet {
- eprintln!();
- eprintln!(
- "To instruct a node to connect to this node, run the following command on that node:"
- );
- eprintln!(" garage [-c <config file path>] node connect {}", idstr);
- eprintln!();
- eprintln!("Or instruct them to connect from here by running:");
- eprintln!(
- " garage -c {} -h <remote node> node connect {}",
- config_file.to_string_lossy(),
- idstr
- );
- eprintln!(
- "where <remote_node> is their own node identifier in the format: <pubkey>@<ip>:<port>"
- );
- eprintln!();
- eprintln!("This node identifier can also be added as a bootstrap node in other node's garage.toml files:");
- eprintln!(" bootstrap_peers = [");
- eprintln!(" \"{}\",", idstr);
- eprintln!(" ...");
- eprintln!(" ]");
- eprintln!();
- }
-
- Ok(())
+ cli_command_dispatch(opt.cmd, &system_rpc_endpoint, &admin_rpc_endpoint, id).await
}