diff options
Diffstat (limited to 'src/garage/cli_v2/mod.rs')
-rw-r--r-- | src/garage/cli_v2/mod.rs | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/garage/cli_v2/mod.rs b/src/garage/cli_v2/mod.rs new file mode 100644 index 00000000..6cc13b2d --- /dev/null +++ b/src/garage/cli_v2/mod.rs @@ -0,0 +1,106 @@ +pub mod bucket; +pub mod cluster; +pub mod key; +pub mod layout; + +use std::convert::TryFrom; +use std::sync::Arc; +use std::time::Duration; + +use garage_util::error::*; + +use garage_rpc::system::*; +use garage_rpc::*; + +use garage_api_admin::api::*; +use garage_api_admin::EndpointHandler as AdminApiEndpoint; + +use crate::admin::*; +use crate::cli as cli_v1; +use crate::cli::structs::*; +use crate::cli::Command; + +pub struct Cli { + pub system_rpc_endpoint: Arc<Endpoint<SystemRpc, ()>>, + pub admin_rpc_endpoint: Arc<Endpoint<AdminRpc, ()>>, + pub rpc_host: NodeID, +} + +impl Cli { + pub async fn handle(&self, cmd: Command) -> Result<(), Error> { + match cmd { + Command::Status => self.cmd_status().await, + Command::Node(NodeOperation::Connect(connect_opt)) => { + self.cmd_connect(connect_opt).await + } + Command::Layout(layout_opt) => self.layout_command_dispatch(layout_opt).await, + Command::Bucket(bo) => self.cmd_bucket(bo).await, + Command::Key(ko) => self.cmd_key(ko).await, + + // TODO + Command::Repair(ro) => cli_v1::cmd_admin( + &self.admin_rpc_endpoint, + self.rpc_host, + AdminRpc::LaunchRepair(ro), + ) + .await + .ok_or_message("cli_v1"), + Command::Stats(so) => { + cli_v1::cmd_admin(&self.admin_rpc_endpoint, self.rpc_host, AdminRpc::Stats(so)) + .await + .ok_or_message("cli_v1") + } + Command::Worker(wo) => cli_v1::cmd_admin( + &self.admin_rpc_endpoint, + self.rpc_host, + AdminRpc::Worker(wo), + ) + .await + .ok_or_message("cli_v1"), + Command::Block(bo) => cli_v1::cmd_admin( + &self.admin_rpc_endpoint, + self.rpc_host, + AdminRpc::BlockOperation(bo), + ) + .await + .ok_or_message("cli_v1"), + Command::Meta(mo) => cli_v1::cmd_admin( + &self.admin_rpc_endpoint, + self.rpc_host, + AdminRpc::MetaOperation(mo), + ) + .await + .ok_or_message("cli_v1"), + + _ => unreachable!(), + } + } + + pub async fn api_request<T>(&self, req: T) -> Result<<T as AdminApiEndpoint>::Response, Error> + where + T: AdminApiEndpoint, + AdminApiRequest: From<T>, + <T as AdminApiEndpoint>::Response: TryFrom<TaggedAdminApiResponse>, + { + let req = AdminApiRequest::from(req); + let req_name = req.name(); + match self + .admin_rpc_endpoint + .call(&self.rpc_host, AdminRpc::ApiRequest(req), PRIO_NORMAL) + .await? + .ok_or_message("rpc")? + { + AdminRpc::ApiOkResponse(resp) => <T as AdminApiEndpoint>::Response::try_from(resp) + .map_err(|_| Error::Message(format!("{} returned unexpected response", req_name))), + AdminRpc::ApiErrorResponse { + http_code, + error_code, + message, + } => Err(Error::Message(format!( + "{} returned {} ({}): {}", + req_name, error_code, http_code, message + ))), + m => Err(Error::unexpected_rpc_message(m)), + } + } +} |