diff --git a/src/garage/admin.rs b/src/garage/admin.rs index 31305b51..c4c9587a 100644 --- a/src/garage/admin.rs +++ b/src/garage/admin.rs @@ -38,7 +38,10 @@ pub enum AdminRpc { // Replies Ok(String), - BucketList(Vec), + BucketList { + buckets: Vec, + counters: HashMap>, + }, BucketInfo { bucket: Bucket, relevant_keys: HashMap, @@ -91,7 +94,25 @@ impl AdminRpcHandler { EnumerationOrder::Forward, ) .await?; - Ok(AdminRpc::BucketList(buckets)) + + let ring = self.garage.system.ring.borrow().clone(); + let counters = self + .garage + .object_counter_table + .table + .get_range( + &EmptyKey, + None, + Some((DeletedFilter::NotDeleted, ring.layout.node_id_vec.clone())), + 15000, + EnumerationOrder::Forward, + ) + .await? + .iter() + .map(|x| (x.sk, x.filtered_values(&ring))) + .collect::>(); + + Ok(AdminRpc::BucketList { buckets, counters }) } async fn handle_bucket_info(&self, query: &BucketOpt) -> Result { diff --git a/src/garage/cli/cmd.rs b/src/garage/cli/cmd.rs index 3a0bd956..e8e834e8 100644 --- a/src/garage/cli/cmd.rs +++ b/src/garage/cli/cmd.rs @@ -166,8 +166,8 @@ pub async fn cmd_admin( AdminRpc::Ok(msg) => { println!("{}", msg); } - AdminRpc::BucketList(bl) => { - print_bucket_list(bl); + AdminRpc::BucketList { buckets, counters } => { + print_bucket_list(buckets, counters); } AdminRpc::BucketInfo { bucket, diff --git a/src/garage/cli/util.rs b/src/garage/cli/util.rs index 23c669b9..f859c9bc 100644 --- a/src/garage/cli/util.rs +++ b/src/garage/cli/util.rs @@ -9,11 +9,11 @@ use garage_model::bucket_table::*; use garage_model::key_table::*; use garage_model::s3::object_table::{BYTES, OBJECTS, UNFINISHED_UPLOADS}; -pub fn print_bucket_list(bl: Vec) { +pub fn print_bucket_list(buckets: Vec, counters: HashMap>) { println!("List of buckets:"); let mut table = vec![]; - for bucket in bl { + for bucket in buckets { let aliases = bucket .aliases() .iter() @@ -30,11 +30,24 @@ pub fn print_bucket_list(bl: Vec) { [((k, n), _, _)] => format!("{}:{}", k, n), s => format!("[{} local aliases]", s.len()), }; + + let counters_tb = match counters.get(&bucket.id) { + Some(c) => format!( + "\t{}\t{}\t{}", + bytesize::ByteSize::b(c.get(BYTES).cloned().unwrap_or_default() as u64) + .to_string_as(true), + c.get(OBJECTS).cloned().unwrap_or_default(), + c.get(UNFINISHED_UPLOADS).cloned().unwrap_or_default(), + ), + None => "".into(), + }; + table.push(format!( - "\t{}\t{}\t{}", + "\t{}\t{}\t{}{}", aliases.join(","), local_aliases_n, - hex::encode(bucket.id) + hex::encode(bucket.id), + counters_tb )); } format_table(table);