pub mod util; pub mod bucket; pub mod cluster; pub mod key; pub mod layout; use std::collections::{HashMap, HashSet}; 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>, pub admin_rpc_endpoint: Arc>, 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("xoxo"), Command::Stats(so) => { cli_v1::cmd_admin(&self.admin_rpc_endpoint, self.rpc_host, AdminRpc::Stats(so)) .await .ok_or_message("xoxo") } Command::Worker(wo) => cli_v1::cmd_admin( &self.admin_rpc_endpoint, self.rpc_host, AdminRpc::Worker(wo), ) .await .ok_or_message("xoxo"), Command::Block(bo) => cli_v1::cmd_admin( &self.admin_rpc_endpoint, self.rpc_host, AdminRpc::BlockOperation(bo), ) .await .ok_or_message("xoxo"), Command::Meta(mo) => cli_v1::cmd_admin( &self.admin_rpc_endpoint, self.rpc_host, AdminRpc::MetaOperation(mo), ) .await .ok_or_message("xoxo"), _ => unreachable!(), } } pub async fn api_request(&self, req: T) -> Result<::Response, Error> where T: AdminApiEndpoint, AdminApiRequest: From, ::Response: TryFrom, { 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("xoxo")? { AdminRpc::ApiOkResponse(resp) => ::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)), } } }