From: Jiffin Tony Thottan Date: Fri, 17 Oct 2025 09:00:24 +0000 (+0530) Subject: src/rgw_bucket.cc: include restore stats in the same json dict for bucket stats X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f32b4acfef00b666f05254350ba58ef1ef0a67cb;p=ceph-ci.git src/rgw_bucket.cc: include restore stats in the same json dict for bucket stats Resolves: rhbz#2403699 Signed-off-by: Jiffin Tony Thottan (cherry picked from commit 1085dfca361fc880c14542ea49094753e303ffc8) --- diff --git a/src/rgw/driver/rados/rgw_bucket.cc b/src/rgw/driver/rados/rgw_bucket.cc index 1f45b37f2c6..7f187c70faa 100644 --- a/src/rgw/driver/rados/rgw_bucket.cc +++ b/src/rgw/driver/rados/rgw_bucket.cc @@ -1510,11 +1510,72 @@ int RGWBucketAdminOp::sync_bucket(rgw::sal::Driver* driver, RGWBucketAdminOpStat return bucket.sync(op_state, dpp, y, err_msg); } -static int bucket_stats(rgw::sal::Driver* driver, +static int bucket_restore_stats(rgw::sal::Driver* driver, const std::string& tenant_name, const std::string& bucket_name, Formatter* formatter, const DoutPrefixProvider* dpp, optional_yield y) { std::unique_ptr bucket; + int restore_completed_count = 0; + int restore_in_progress_count = 0; + int restore_failed_count = 0; + int ret = driver->load_bucket(dpp, rgw_bucket(tenant_name, bucket_name), + &bucket, y); + if (ret < 0) { + return ret; + } + rgw::sal::Bucket::ListParams params; + rgw::sal::Bucket::ListResults results; + params.list_versions = bucket->versioned(); + params.allow_unordered = true; + do { + ret = bucket->list(dpp, params, listing_max_entries, results, null_yield); + if (ret < 0) { + cerr << "ERROR: driver->list_objects(): " << cpp_strerror(-ret) << std::endl; + return ret; + } + for (vector::iterator iter = results.objs.begin(); iter != results.objs.end(); ++iter) { + std::unique_ptr obj = bucket->get_object(iter->key.name); + if (obj) { + ret = obj->get_obj_attrs(null_yield, dpp); + if (ret < 0) { + cerr << "ERROR: failed to stat object, returned error: " << cpp_strerror(-ret) << std::endl; + return ret; + } + for (map::iterator getattriter = obj->get_attrs().begin(); getattriter != obj->get_attrs().end(); ++getattriter) { + bufferlist& bl = getattriter->second; + if (getattriter->first == RGW_ATTR_RESTORE_STATUS) { + rgw::sal::RGWRestoreStatus rs; + try { + decode(rs, bl); + } catch (const JSONDecoder::err& e) { + cerr << "failed to decode JSON input: " << e.what() << std::endl; + return -EINVAL; + } + if (rs == rgw::sal::RGWRestoreStatus::RestoreAlreadyInProgress) { + restore_in_progress_count ++; + } else if (rs == rgw::sal::RGWRestoreStatus::CloudRestored) { + restore_completed_count ++; + } else if (rs == rgw::sal::RGWRestoreStatus::RestoreFailed) { + restore_failed_count ++; + } + } + } + } + } + } while (results.is_truncated); + formatter->open_object_section("restore_stats"); + formatter->dump_int("restore_completed_count", restore_completed_count); + formatter->dump_int("restore_in_progress_count", restore_in_progress_count); + formatter->dump_int("restore_failed_count", restore_failed_count); + formatter->close_section(); + return 0; +} + +static int bucket_stats(rgw::sal::Driver* driver, + const std::string& tenant_name, const std::string& bucket_name, + bool dump_restore_stats, Formatter* formatter, + const DoutPrefixProvider* dpp, optional_yield y) { + std::unique_ptr bucket; map stats; int ret = driver->load_bucket(dpp, rgw_bucket(tenant_name, bucket_name), @@ -1589,71 +1650,14 @@ static int bucket_stats(rgw::sal::Driver* driver, formatter->dump_int("read_tracker", bucket_info.objv_tracker.read_version.ver); // TODO: bucket CORS // TODO: bucket LC - formatter->close_section(); - - return 0; -} - -static int bucket_restore_stats(rgw::sal::Driver* driver, - const std::string& tenant_name, - const std::string& bucket_name, Formatter* formatter, - const DoutPrefixProvider* dpp, optional_yield y) { - std::unique_ptr bucket; - int restore_completed_count = 0; - int restore_in_progress_count = 0; - int restore_failed_count = 0; - int ret = driver->load_bucket(dpp, rgw_bucket(tenant_name, bucket_name), - &bucket, y); - if (ret < 0) { - return ret; - } - rgw::sal::Bucket::ListParams params; - rgw::sal::Bucket::ListResults results; - params.list_versions = bucket->versioned(); - params.allow_unordered = true; - do { - ret = bucket->list(dpp, params, listing_max_entries, results, null_yield); - if (ret < 0) { - cerr << "ERROR: driver->list_objects(): " << cpp_strerror(-ret) << std::endl; - return ret; - } - for (vector::iterator iter = results.objs.begin(); iter != results.objs.end(); ++iter) { - std::unique_ptr obj = bucket->get_object(iter->key.name); - if (obj) { - ret = obj->get_obj_attrs(null_yield, dpp); - if (ret < 0) { - cerr << "ERROR: failed to stat object, returned error: " << cpp_strerror(-ret) << std::endl; - return ret; - } - for (map::iterator getattriter = obj->get_attrs().begin(); getattriter != obj->get_attrs().end(); ++getattriter) { - bufferlist& bl = getattriter->second; - if (getattriter->first == RGW_ATTR_RESTORE_STATUS) { - rgw::sal::RGWRestoreStatus rs; - try { - decode(rs, bl); - } catch (const JSONDecoder::err& e) { - cerr << "failed to decode JSON input: " << e.what() << std::endl; - return -EINVAL; - } - if (rs == rgw::sal::RGWRestoreStatus::RestoreAlreadyInProgress) { - restore_in_progress_count ++; - } else if (rs == rgw::sal::RGWRestoreStatus::CloudRestored) { - restore_completed_count ++; - } else if (rs == rgw::sal::RGWRestoreStatus::RestoreFailed) { - restore_failed_count ++; - } - } - } + if (dump_restore_stats) { + ret = bucket_restore_stats(driver, tenant_name, bucket_name, formatter, dpp, y); + if (ret < 0) { + return ret; } - } - } while (results.is_truncated); - formatter->open_object_section(""); - formatter->open_object_section("restore_stats"); - formatter->dump_int("restore_completed_count", restore_completed_count); - formatter->dump_int("restore_in_progress_count", restore_in_progress_count); - formatter->dump_int("restore_failed_count", restore_failed_count); - formatter->close_section(); + } formatter->close_section(); + return 0; } @@ -1793,7 +1797,7 @@ static int list_owner_bucket_info(const DoutPrefixProvider* dpp, for (const auto& ent : listing.buckets) { if (show_stats) { - bucket_stats(driver, tenant, ent.bucket.name, formatter, dpp, y); + bucket_stats(driver, tenant, ent.bucket.name, false, formatter, dpp, y); } else { formatter->dump_string("bucket", ent.bucket.name); } @@ -1829,16 +1833,10 @@ int RGWBucketAdminOp::info(rgw::sal::Driver* driver, const bool show_stats = op_state.will_fetch_stats(); const rgw_user& user_id = op_state.get_user_id(); if (!bucket_name.empty()) { - ret = bucket_stats(driver, user_id.tenant, bucket_name, formatter, dpp, y); + ret = bucket_stats(driver, user_id.tenant, bucket_name, op_state.restore_stats, formatter, dpp, y); if (ret < 0) { return ret; } - if (op_state.restore_stats) { - ret = bucket_restore_stats(driver, user_id.tenant, bucket_name, formatter, dpp, y); - if (ret < 0) { - return ret; - } - } } else if (op_state.is_user_op()) { const rgw_user& uid = op_state.get_user_id(); auto user = driver->get_user(uid); @@ -1890,7 +1888,7 @@ int RGWBucketAdminOp::info(rgw::sal::Driver* driver, &truncated); for (auto& bucket_name : buckets) { if (show_stats) { - bucket_stats(driver, user_id.tenant, bucket_name, formatter, dpp, y); + bucket_stats(driver, user_id.tenant, bucket_name, op_state.restore_stats, formatter, dpp, y); } else { formatter->dump_string("bucket", bucket_name); } diff --git a/src/rgw/driver/rados/rgw_rest_bucket.cc b/src/rgw/driver/rados/rgw_rest_bucket.cc index 1d144b2885b..e22523f5a6c 100644 --- a/src/rgw/driver/rados/rgw_rest_bucket.cc +++ b/src/rgw/driver/rados/rgw_rest_bucket.cc @@ -35,6 +35,7 @@ void RGWOp_Bucket_Info::execute(optional_yield y) RGWBucketAdminOpState op_state; bool fetch_stats; + bool fetch_restore_stats; std::string bucket; @@ -45,10 +46,12 @@ void RGWOp_Bucket_Info::execute(optional_yield y) RESTArgs::get_string(s, "bucket", bucket, &bucket); RESTArgs::get_bool(s, "stats", false, &fetch_stats); + RESTArgs::get_bool(s, "restore-stats", false, &fetch_restore_stats); op_state.set_user_id(uid); op_state.set_bucket_name(bucket); op_state.set_fetch_stats(fetch_stats); + op_state.set_restore_stats(fetch_restore_stats); op_ret = RGWBucketAdminOp::info(driver, op_state, flusher, y, this); } diff --git a/src/rgw/radosgw-admin/radosgw-admin.cc b/src/rgw/radosgw-admin/radosgw-admin.cc index 2f9951985b7..d874e661561 100644 --- a/src/rgw/radosgw-admin/radosgw-admin.cc +++ b/src/rgw/radosgw-admin/radosgw-admin.cc @@ -360,7 +360,7 @@ void usage() cout << " notification rm remove a bucket notifications configuration\n"; cout << " restore status shows restoration status of object in a bucket\n"; cout << " restore list list restore status of each object in the bucket\n"; - cout <<" can be filtered with help of --restore-status which shows objects with specified status\n"; + cout << " can be filtered with help of --restore-status which shows objects with specified status\n"; cout << "options:\n"; cout << " --tenant= tenant name\n"; cout << " --user_ns= namespace of user (oidc in case of users authenticated with oidc provider)\n"; diff --git a/src/test/cli/radosgw-admin/help.t b/src/test/cli/radosgw-admin/help.t index b3604528381..998b99860ff 100644 --- a/src/test/cli/radosgw-admin/help.t +++ b/src/test/cli/radosgw-admin/help.t @@ -220,6 +220,9 @@ notification list list bucket notifications configuration notification get get a bucket notifications configuration notification rm remove a bucket notifications configuration + restore status shows restoration status of object in a bucket + restore list list restore status of each object in the bucket + can be filtered with help of --restore-status which shows objects with specified status options: --tenant= tenant name --user_ns= namespace of user (oidc in case of users authenticated with oidc provider) @@ -420,6 +423,7 @@ Bucket list objects options: --max-entries max number of entries listed (default 1000) --marker the marker used to specify on which entry the listing begins, default none (i.e., very first entry) + --show-restore-stats if the flag is in present it will show restores stats in the bucket stats command --conf/-c FILE read configuration from the given configuration file --id ID set ID portion of my name