From: Casey Bodley Date: Wed, 7 Sep 2022 18:19:34 +0000 (-0400) Subject: radosgw-admin: use ConfigStore and related zone APIs X-Git-Tag: v18.1.0~1101^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F47679%2Fhead;p=ceph.git radosgw-admin: use ConfigStore and related zone APIs replaces all of rgw_admin.cc's use of the RGWSystemMetaObj subclasses with calls to the ConfigStore Signed-off-by: Casey Bodley --- diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 62e13ac7deb3..4cb8c1794f35 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -1887,8 +1887,9 @@ static int send_to_remote_or_url(RGWRESTConn *conn, const string& url, return send_to_url(url, opt_region, access, secret, info, in_data, parser); } -static int commit_period(RGWRealm& realm, RGWPeriod& period, - string remote, const string& url, +static int commit_period(rgw::sal::ConfigStore* cfgstore, + RGWRealm& realm, rgw::sal::RealmWriter& realm_writer, + RGWPeriod& period, string remote, const string& url, std::optional opt_region, const string& access, const string& secret, bool force) @@ -1902,16 +1903,16 @@ static int commit_period(RGWRealm& realm, RGWPeriod& period, if (store->get_zone()->get_id() == master_zone) { // read the current period RGWPeriod current_period; - int ret = current_period.init(dpp(), g_ceph_context, - static_cast(store)->svc()->sysobj, realm.get_id(), - null_yield); + int ret = cfgstore->read_period(dpp(), null_yield, realm.current_period, + std::nullopt, current_period); if (ret < 0) { - cerr << "Error initializing current period: " - << cpp_strerror(-ret) << std::endl; + cerr << "failed to load current period: " << cpp_strerror(ret) << std::endl; return ret; } // the master zone can commit locally - ret = period.commit(dpp(), store, realm, current_period, cerr, null_yield, force); + ret = rgw::commit_period(dpp(), null_yield, cfgstore, store, + realm, realm_writer, current_period, + period, cerr, force); if (ret < 0) { cerr << "failed to commit period: " << cpp_strerror(-ret) << std::endl; } @@ -1975,63 +1976,67 @@ static int commit_period(RGWRealm& realm, RGWPeriod& period, } // the master zone gave us back the period that it committed, so it's // safe to save it as our latest epoch - ret = period.store_info(dpp(), false, null_yield); + constexpr bool exclusive = false; + ret = cfgstore->create_period(dpp(), null_yield, exclusive, period); if (ret < 0) { cerr << "Error storing committed period " << period.get_id() << ": " << cpp_strerror(ret) << std::endl; return ret; } - ret = period.set_latest_epoch(dpp(), null_yield, period.get_epoch()); - if (ret < 0) { - cerr << "Error updating period epoch: " << cpp_strerror(ret) << std::endl; - return ret; - } - ret = period.reflect(dpp(), null_yield); + ret = rgw::reflect_period(dpp(), null_yield, cfgstore, period); if (ret < 0) { cerr << "Error updating local objects: " << cpp_strerror(ret) << std::endl; return ret; } - realm.notify_new_period(dpp(), period, null_yield); + (void) cfgstore->realm_notify_new_period(dpp(), null_yield, period); return ret; } -static int update_period(const string& realm_id, const string& realm_name, - const string& period_id, const string& period_epoch, - bool commit, const string& remote, const string& url, +static int update_period(rgw::sal::ConfigStore* cfgstore, + const string& realm_id, const string& realm_name, + const string& period_epoch, bool commit, + const string& remote, const string& url, std::optional opt_region, const string& access, const string& secret, Formatter *formatter, bool force) { - RGWRealm realm(realm_id, realm_name); - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); - if (ret < 0 ) { - cerr << "Error initializing realm " << cpp_strerror(-ret) << std::endl; + RGWRealm realm; + std::unique_ptr realm_writer; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore, + realm_id, realm_name, + realm, &realm_writer); + if (ret < 0) { + cerr << "failed to load realm " << cpp_strerror(-ret) << std::endl; return ret; } - epoch_t epoch = 0; + std::optional epoch; if (!period_epoch.empty()) { epoch = atoi(period_epoch.c_str()); } - RGWPeriod period(period_id, epoch); - ret = period.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, realm.get_id(), null_yield); + RGWPeriod period; + ret = cfgstore->read_period(dpp(), null_yield, realm.current_period, + epoch, period); if (ret < 0) { - cerr << "period init failed: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load current period: " << cpp_strerror(-ret) << std::endl; return ret; } - period.fork(); - ret = period.update(dpp(), null_yield); - if(ret < 0) { - // Dropping the error message here, as both the ret codes were handled in - // period.update() + // convert to the realm's staging period + rgw::fork_period(dpp(), period); + // update the staging period with all of the realm's zonegroups + ret = rgw::update_period(dpp(), null_yield, cfgstore, period); + if (ret < 0) { return ret; } - ret = period.store_info(dpp(), false, null_yield); + + constexpr bool exclusive = false; + ret = cfgstore->create_period(dpp(), null_yield, exclusive, period); if (ret < 0) { cerr << "failed to store period: " << cpp_strerror(-ret) << std::endl; return ret; } if (commit) { - ret = commit_period(realm, period, remote, url, opt_region, access, secret, force); + ret = commit_period(cfgstore, realm, *realm_writer, period, remote, url, + opt_region, access, secret, force); if (ret < 0) { cerr << "failed to commit period: " << cpp_strerror(-ret) << std::endl; return ret; @@ -2056,7 +2061,8 @@ static int init_bucket_for_sync(rgw::sal::User* user, return 0; } -static int do_period_pull(RGWRESTConn *remote_conn, const string& url, +static int do_period_pull(rgw::sal::ConfigStore* cfgstore, + RGWRESTConn *remote_conn, const string& url, std::optional opt_region, const string& access_key, const string& secret_key, const string& realm_id, const string& realm_name, @@ -2086,37 +2092,17 @@ static int do_period_pull(RGWRESTConn *remote_conn, const string& url, cerr << "request failed: " << cpp_strerror(-ret) << std::endl; return ret; } - ret = period->init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield, false); - if (ret < 0) { - cerr << "faile to init period " << cpp_strerror(-ret) << std::endl; - return ret; - } try { decode_json_obj(*period, &p); } catch (const JSONDecoder::err& e) { cout << "failed to decode JSON input: " << e.what() << std::endl; return -EINVAL; } - ret = period->store_info(dpp(), false, null_yield); + constexpr bool exclusive = false; + ret = cfgstore->create_period(dpp(), null_yield, exclusive, *period); if (ret < 0) { cerr << "Error storing period " << period->get_id() << ": " << cpp_strerror(ret) << std::endl; } - // store latest epoch (ignore errors) - period->update_latest_epoch(dpp(), period->get_epoch(), null_yield); - return 0; -} - -static int read_current_period_id(rgw::sal::Store* store, const std::string& realm_id, - const std::string& realm_name, - std::string* period_id) -{ - RGWRealm realm(realm_id, realm_name); - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); - if (ret < 0) { - std::cerr << "failed to read realm: " << cpp_strerror(-ret) << std::endl; - return ret; - } - *period_id = realm.get_current_period(); return 0; } @@ -3155,7 +3141,9 @@ void init_optional_bucket(std::optional& opt_bucket, class SyncPolicyContext { + rgw::sal::ConfigStore* cfgstore; RGWZoneGroup zonegroup; + std::unique_ptr zonegroup_writer; std::optional b; std::unique_ptr bucket; @@ -3165,13 +3153,14 @@ class SyncPolicyContext std::optional owner; public: - SyncPolicyContext(const string& zonegroup_id, - const string& zonegroup_name, - std::optional _bucket) : zonegroup(zonegroup_id, zonegroup_name), - b(_bucket) {} + SyncPolicyContext(rgw::sal::ConfigStore* cfgstore, + std::optional _bucket) + : cfgstore(cfgstore), b(std::move(_bucket)) {} - int init() { - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + int init(const string& zonegroup_id, const string& zonegroup_name) { + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore, + zonegroup_id, zonegroup_name, + zonegroup, &zonegroup_writer); if (ret < 0) { cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; return ret; @@ -3202,7 +3191,7 @@ public: int write_policy() { if (!b) { - int ret = zonegroup.update(dpp(), null_yield); + int ret = zonegroup_writer->write(dpp(), null_yield, zonegroup); if (ret < 0) { cerr << "failed to update zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -3305,50 +3294,61 @@ public: } }; -static int search_entities_by_zone(rgw_zone_id zone_id, +static int search_entities_by_zone(rgw::sal::ConfigStore* cfgstore, + rgw_zone_id zone_id, RGWRealm *prealm, - RGWPeriod *pperiod, - RGWZoneGroup *pzonegroup, - bool *pfound) + RGWZoneGroup *pzonegroup) { - *pfound = false; - - auto& found = *pfound; + std::array realm_names; + rgw::sal::ListResult listing; - list realms; - int r = static_cast(store)->svc()->zone->list_realms(dpp(), realms); - if (r < 0) { - cerr << "failed to list realms: " << cpp_strerror(-r) << std::endl; - return r; - } - - for (auto& realm_name : realms) { - string realm_id; - string period_id; - RGWRealm realm(realm_id, realm_name); - r = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + do { + int r = cfgstore->list_realm_names(dpp(), null_yield, listing.next, + realm_names, listing); if (r < 0) { - cerr << "WARNING: can't open realm " << realm_name << ": " << cpp_strerror(-r) << " ... skipping" << std::endl; - continue; + cerr << "failed to list realms: " << cpp_strerror(-r) << std::endl; + return r; } - RGWPeriod period; - r = realm.find_zone(dpp(), zone_id, pperiod, - pzonegroup, &found, null_yield); - if (found) { - *prealm = realm; - break; - } - } + for (const auto& realm_name : listing.entries) { + RGWRealm realm; + r = cfgstore->read_realm_by_name(dpp(), null_yield, realm_name, + realm, nullptr); + if (r < 0) { + cerr << "WARNING: failed to load realm " << realm_name + << ": " << cpp_strerror(r) << " ... skipping" << std::endl; + continue; + } - return 0; + RGWPeriod period; + r = cfgstore->read_period(dpp(), null_yield, realm.current_period, + std::nullopt, period); + if (r < 0) { + cerr << "WARNING: failed to load current period for realm " + << realm_name << ": " << cpp_strerror(r) << " ... skipping" << std::endl; + continue; + } + + for (auto& [zid, zonegroup] : period.period_map.zonegroups) { + if (zonegroup.zones.count(zone_id)) { + *prealm = std::move(realm); + *pzonegroup = std::move(zonegroup); + return 0; + } + } // foreach zonegroup in period + } // foreach realm_name in listing.entries + } while (!listing.next.empty()); + + return -ENOENT; } -static int try_to_resolve_local_zone(string& zone_id, string& zone_name) +static int try_to_resolve_local_zone(rgw::sal::ConfigStore* cfgstore, + string& zone_id, string& zone_name) { /* try to read zone info */ - RGWZoneParams zone(zone_id, zone_name); - int r = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneParams zone; + int r = rgw::read_zone(dpp(), null_yield, cfgstore, + zone_id, zone_name, zone); if (r == -ENOENT) { ldpp_dout(dpp(), 20) << __func__ << "(): local zone not found (id=" << zone_id << ", name= " << zone_name << ")" << dendl; return r; @@ -3380,7 +3380,8 @@ static void check_set_consistent(const string& resolved_param, } -static int try_to_resolve_local_entities(string& realm_id, string& realm_name, +static int try_to_resolve_local_entities(rgw::sal::ConfigStore* cfgstore, + string& realm_id, string& realm_name, string& zonegroup_id, string& zonegroup_name, string& zone_id, string& zone_name) { @@ -3393,7 +3394,7 @@ static int try_to_resolve_local_entities(string& realm_id, string& realm_name, */ ldpp_dout(dpp(), 20) << __func__ << "(): before: realm_id=" << realm_id << " realm_name=" << realm_name << " zonegroup_id=" << zonegroup_id << " zonegroup_name=" << zonegroup_name << " zone_id=" << zone_id << " zone_name=" << zone_name << dendl; - int r = try_to_resolve_local_zone(zone_id, zone_name); + int r = try_to_resolve_local_zone(cfgstore, zone_id, zone_name); if (r == -ENOENT) { /* this local zone doesn't exist, abort */ return 0; @@ -3407,20 +3408,17 @@ static int try_to_resolve_local_entities(string& realm_id, string& realm_name, return 0; } - bool found; RGWRealm realm; - RGWPeriod period; RGWZoneGroup zonegroup; - r = search_entities_by_zone(zone_id, &realm, &period, &zonegroup, &found); + r = search_entities_by_zone(cfgstore, zone_id, &realm, &zonegroup); + if (r == -ENOENT) { + return 0; // not found + } if (r < 0) { ldpp_dout(dpp(), 0) << "ERROR: error when searching for realm id (r=" << r << "), ignoring" << dendl; return r; } - if (!found) { - return 0; - } - check_set_consistent(realm.get_id(), realm_id, "realm id (--realm-id)"); check_set_consistent(realm.get_name(), realm_name, "realm name (--rgw-realm)"); check_set_consistent(zonegroup.get_id(), zonegroup_id, "zonegroup id (--zonegroup-id)"); @@ -3431,16 +3429,6 @@ static int try_to_resolve_local_entities(string& realm_id, string& realm_name, return 0; } -static bool empty_opt(std::optional& os) -{ - return (!os || os->empty()); -} - -static string safe_opt(std::optional& os) -{ - return os.value_or(string()); -} - void init_realm_param(CephContext *cct, string& var, std::optional& opt_var, const string& conf_name) { var = cct->_conf.get_val(conf_name); @@ -4520,7 +4508,7 @@ int main(int argc, const char **argv) StoreDestructor store_destructor(store); if (raw_storage_op) { - try_to_resolve_local_entities(realm_id, realm_name, + try_to_resolve_local_entities(cfgstore.get(), realm_id, realm_name, zonegroup_id, zonegroup_name, zone_id, zone_name); @@ -4532,13 +4520,7 @@ int main(int argc, const char **argv) cerr << "missing period id" << std::endl; return EINVAL; } - RGWPeriod period(period_id); - int ret = period.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); - if (ret < 0) { - cerr << "period.init failed: " << cpp_strerror(-ret) << std::endl; - return -ret; - } - ret = period.delete_obj(dpp(), null_yield); + int ret = cfgstore->delete_period(dpp(), null_yield, period_id); if (ret < 0) { cerr << "ERROR: couldn't delete period: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -4548,15 +4530,16 @@ int main(int argc, const char **argv) break; case OPT::PERIOD_GET: { - epoch_t epoch = 0; + std::optional epoch; if (!period_epoch.empty()) { epoch = atoi(period_epoch.c_str()); } if (staging) { - RGWRealm realm(realm_id, realm_name); - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWRealm realm; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); if (ret < 0 ) { - cerr << "Error initializing realm " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load realm: " << cpp_strerror(-ret) << std::endl; return -ret; } realm_id = realm.get_id(); @@ -4564,11 +4547,23 @@ int main(int argc, const char **argv) period_id = RGWPeriod::get_staging_id(realm_id); epoch = 1; } - RGWPeriod period(period_id, epoch); - int ret = period.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, realm_id, - null_yield, realm_name); + if (period_id.empty()) { + // use realm's current period + RGWRealm realm; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); + if (ret < 0 ) { + cerr << "failed to load realm: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + period_id = realm.current_period; + } + + RGWPeriod period; + int ret = cfgstore->read_period(dpp(), null_yield, period_id, + epoch, period); if (ret < 0) { - cerr << "period init failed: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load period: " << cpp_strerror(-ret) << std::endl; return -ret; } encode_json("period", period, formatter.get()); @@ -4577,35 +4572,45 @@ int main(int argc, const char **argv) break; case OPT::PERIOD_GET_CURRENT: { - int ret = read_current_period_id(store, realm_id, realm_name, &period_id); + RGWRealm realm; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); if (ret < 0) { + std::cerr << "failed to load realm: " << cpp_strerror(ret) << std::endl; return -ret; } + formatter->open_object_section("period_get_current"); - encode_json("current_period", period_id, formatter.get()); + encode_json("current_period", realm.current_period, formatter.get()); formatter->close_section(); formatter->flush(cout); } break; case OPT::PERIOD_LIST: { - list periods; - int ret = static_cast(store)->svc()->zone->list_periods(dpp(), periods); - if (ret < 0) { - cerr << "failed to list periods: " << cpp_strerror(-ret) << std::endl; - return -ret; - } - formatter->open_object_section("periods_list"); - encode_json("periods", periods, formatter.get()); - formatter->close_section(); - formatter->flush(cout); - } + Formatter::ObjectSection periods_list{*formatter, "periods_list"}; + Formatter::ArraySection periods{*formatter, "periods"}; + rgw::sal::ListResult listing; + std::array period_ids; // list in pages of 1000 + do { + int ret = cfgstore->list_period_ids(dpp(), null_yield, listing.next, + period_ids, listing); + if (ret < 0) { + std::cerr << "failed to list periods: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + for (const auto& id : listing.entries) { + encode_json("id", id, formatter.get()); + } + } while (!listing.next.empty()); + } // close sections periods and periods_list + formatter->flush(cout); break; case OPT::PERIOD_UPDATE: { - int ret = update_period(realm_id, realm_name, period_id, period_epoch, - commit, remote, url, opt_region, - access_key, secret_key, + int ret = update_period(cfgstore.get(), realm_id, realm_name, + period_epoch, commit, remote, url, + opt_region, access_key, secret_key, formatter.get(), yes_i_really_mean_it); if (ret < 0) { return -ret; @@ -4618,16 +4623,20 @@ int main(int argc, const char **argv) RGWRESTConn *remote_conn = nullptr; if (url.empty()) { // load current period for endpoints - RGWRealm realm(realm_id, realm_name); - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); - if (ret < 0) { - cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl; + RGWRealm realm; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); + if (ret < 0 ) { + cerr << "failed to load realm: " << cpp_strerror(-ret) << std::endl; return -ret; } - RGWPeriod current_period(realm.get_current_period()); - ret = current_period.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + period_id = realm.current_period; + + RGWPeriod current_period; + ret = cfgstore->read_period(dpp(), null_yield, period_id, + std::nullopt, current_period); if (ret < 0) { - cerr << "failed to init current period: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load current period: " << cpp_strerror(-ret) << std::endl; return -ret; } if (remote.empty()) { @@ -4644,8 +4653,8 @@ int main(int argc, const char **argv) } RGWPeriod period; - int ret = do_period_pull(remote_conn, url, opt_region, - access_key, secret_key, + int ret = do_period_pull(cfgstore.get(), remote_conn, url, + opt_region, access_key, secret_key, realm_id, realm_name, period_id, period_epoch, &period); if (ret < 0) { @@ -4663,10 +4672,10 @@ int main(int argc, const char **argv) case OPT::GLOBAL_RATELIMIT_DISABLE: { if (realm_id.empty()) { - RGWRealm realm(g_ceph_context, static_cast(store)->svc()->sysobj); if (!realm_name.empty()) { // look up realm_id for the given realm_name - int ret = realm.read_id(dpp(), realm_name, realm_id, null_yield); + int ret = cfgstore->read_realm_id(dpp(), null_yield, + realm_name, realm_id); if (ret < 0) { cerr << "ERROR: failed to read realm for " << realm_name << ": " << cpp_strerror(-ret) << std::endl; @@ -4674,7 +4683,8 @@ int main(int argc, const char **argv) } } else { // use default realm_id when none is given - int ret = realm.read_default_id(dpp(), realm_id, null_yield); + int ret = cfgstore->read_default_realm_id(dpp(), null_yield, + realm_id); if (ret < 0 && ret != -ENOENT) { // on ENOENT, use empty realm_id cerr << "ERROR: failed to read default realm: " << cpp_strerror(-ret) << std::endl; @@ -4684,7 +4694,8 @@ int main(int argc, const char **argv) } RGWPeriodConfig period_config; - int ret = period_config.read(dpp(), static_cast(store)->svc()->sysobj, realm_id, null_yield); + int ret = cfgstore->read_period_config(dpp(), null_yield, realm_id, + period_config); if (ret < 0 && ret != -ENOENT) { cerr << "ERROR: failed to read period config: " << cpp_strerror(-ret) << std::endl; @@ -4732,7 +4743,9 @@ int main(int argc, const char **argv) if (opt_cmd != OPT::GLOBAL_RATELIMIT_GET) { // write the modified period config - ret = period_config.write(dpp(), static_cast(store)->svc()->sysobj, realm_id, null_yield); + constexpr bool exclusive = false; + ret = cfgstore->write_period_config(dpp(), null_yield, exclusive, + realm_id, period_config); if (ret < 0) { cerr << "ERROR: failed to write period config: " << cpp_strerror(-ret) << std::endl; @@ -4757,10 +4770,10 @@ int main(int argc, const char **argv) case OPT::GLOBAL_QUOTA_DISABLE: { if (realm_id.empty()) { - RGWRealm realm(g_ceph_context, static_cast(store)->svc()->sysobj); if (!realm_name.empty()) { // look up realm_id for the given realm_name - int ret = realm.read_id(dpp(), realm_name, realm_id, null_yield); + int ret = cfgstore->read_realm_id(dpp(), null_yield, + realm_name, realm_id); if (ret < 0) { cerr << "ERROR: failed to read realm for " << realm_name << ": " << cpp_strerror(-ret) << std::endl; @@ -4768,7 +4781,8 @@ int main(int argc, const char **argv) } } else { // use default realm_id when none is given - int ret = realm.read_default_id(dpp(), realm_id, null_yield); + int ret = cfgstore->read_default_realm_id(dpp(), null_yield, + realm_id); if (ret < 0 && ret != -ENOENT) { // on ENOENT, use empty realm_id cerr << "ERROR: failed to read default realm: " << cpp_strerror(-ret) << std::endl; @@ -4778,7 +4792,8 @@ int main(int argc, const char **argv) } RGWPeriodConfig period_config; - int ret = period_config.read(dpp(), static_cast(store)->svc()->sysobj, realm_id, null_yield); + int ret = cfgstore->read_period_config(dpp(), null_yield, realm_id, + period_config); if (ret < 0 && ret != -ENOENT) { cerr << "ERROR: failed to read period config: " << cpp_strerror(-ret) << std::endl; @@ -4809,7 +4824,9 @@ int main(int argc, const char **argv) if (opt_cmd != OPT::GLOBAL_QUOTA_GET) { // write the modified period config - ret = period_config.write(dpp(), static_cast(store)->svc()->sysobj, realm_id, null_yield); + constexpr bool exclusive = false; + ret = cfgstore->write_period_config(dpp(), null_yield, exclusive, + realm_id, period_config); if (ret < 0) { cerr << "ERROR: failed to write period config: " << cpp_strerror(-ret) << std::endl; @@ -4835,15 +4852,19 @@ int main(int argc, const char **argv) return EINVAL; } - RGWRealm realm(realm_name, g_ceph_context, static_cast(store)->svc()->sysobj); - int ret = realm.create(dpp(), null_yield); + RGWRealm realm; + realm.name = realm_name; + + constexpr bool exclusive = true; + int ret = rgw::create_realm(dpp(), null_yield, cfgstore.get(), + exclusive, realm); if (ret < 0) { cerr << "ERROR: couldn't create realm " << realm_name << ": " << cpp_strerror(-ret) << std::endl; return -ret; } if (set_default) { - ret = realm.set_as_default(dpp(), null_yield); + ret = rgw::set_default_realm(dpp(), null_yield, cfgstore.get(), realm); if (ret < 0) { cerr << "failed to set realm " << realm_name << " as default: " << cpp_strerror(-ret) << std::endl; } @@ -4855,19 +4876,21 @@ int main(int argc, const char **argv) break; case OPT::REALM_DELETE: { - if (empty_opt(opt_realm_name) && empty_opt(opt_realm_id)) { + if (realm_id.empty() && realm_name.empty()) { cerr << "missing realm name or id" << std::endl; return EINVAL; } - RGWRealm realm(safe_opt(opt_realm_id), safe_opt(opt_realm_name)); - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWRealm realm; + std::unique_ptr writer; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm, &writer); if (ret < 0) { - cerr << "realm.init failed: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load realm: " << cpp_strerror(-ret) << std::endl; return -ret; } - ret = realm.delete_obj(dpp(), null_yield); + ret = writer->remove(dpp(), null_yield); if (ret < 0) { - cerr << "ERROR: couldn't : " << cpp_strerror(-ret) << std::endl; + cerr << "failed to remove realm: " << cpp_strerror(-ret) << std::endl; return -ret; } @@ -4875,13 +4898,14 @@ int main(int argc, const char **argv) break; case OPT::REALM_GET: { - RGWRealm realm(realm_id, realm_name); - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWRealm realm; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); if (ret < 0) { if (ret == -ENOENT && realm_name.empty() && realm_id.empty()) { cerr << "missing realm name or id, or default realm not found" << std::endl; } else { - cerr << "realm.init failed: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load realm: " << cpp_strerror(-ret) << std::endl; } return -ret; } @@ -4891,9 +4915,8 @@ int main(int argc, const char **argv) break; case OPT::REALM_GET_DEFAULT: { - RGWRealm realm(g_ceph_context, static_cast(store)->svc()->sysobj); string default_id; - int ret = realm.read_default_id(dpp(), default_id, null_yield); + int ret = cfgstore->read_default_realm_id(dpp(), null_yield, default_id); if (ret == -ENOENT) { cout << "No default realm is set" << std::endl; return -ret; @@ -4906,48 +4929,68 @@ int main(int argc, const char **argv) break; case OPT::REALM_LIST: { - RGWRealm realm(g_ceph_context, static_cast(store)->svc()->sysobj); - string default_id; - int ret = realm.read_default_id(dpp(), default_id, null_yield); + std::string default_id; + int ret = cfgstore->read_default_realm_id(dpp(), null_yield, + default_id); if (ret < 0 && ret != -ENOENT) { cerr << "could not determine default realm: " << cpp_strerror(-ret) << std::endl; } - list realms; - ret = static_cast(store)->svc()->zone->list_realms(dpp(), realms); - if (ret < 0) { - cerr << "failed to list realms: " << cpp_strerror(-ret) << std::endl; - return -ret; - } - formatter->open_object_section("realms_list"); - encode_json("default_info", default_id, formatter.get()); - encode_json("realms", realms, formatter.get()); - formatter->close_section(); - formatter->flush(cout); - } + + Formatter::ObjectSection realms_list{*formatter, "realms_list"}; + encode_json("default_info", default_id, formatter.get()); + + Formatter::ArraySection realms{*formatter, "realms"}; + rgw::sal::ListResult listing; + std::array names; // list in pages of 1000 + do { + ret = cfgstore->list_realm_names(dpp(), null_yield, listing.next, + names, listing); + if (ret < 0) { + std::cerr << "failed to list realms: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + for (const auto& name : listing.entries) { + encode_json("name", name, formatter.get()); + } + } while (!listing.next.empty()); + } // close sections realms and realms_list + formatter->flush(cout); break; case OPT::REALM_LIST_PERIODS: { - int ret = read_current_period_id(store, realm_id, realm_name, &period_id); - if (ret < 0) { - return -ret; - } - list periods; - ret = static_cast(store)->svc()->zone->list_periods(dpp(), period_id, periods, null_yield); - if (ret < 0) { - cerr << "list periods failed: " << cpp_strerror(-ret) << std::endl; - return -ret; - } - formatter->open_object_section("realm_periods_list"); + // use realm's current period + RGWRealm realm; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); + if (ret < 0) { + cerr << "failed to load realm: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + period_id = realm.current_period; + + Formatter::ObjectSection periods_list{*formatter, "realm_periods_list"}; encode_json("current_period", period_id, formatter.get()); - encode_json("periods", periods, formatter.get()); - formatter->close_section(); - formatter->flush(cout); - } + + Formatter::ArraySection periods{*formatter, "periods"}; + + while (!period_id.empty()) { + RGWPeriod period; + ret = cfgstore->read_period(dpp(), null_yield, period_id, + std::nullopt, period); + if (ret < 0) { + cerr << "failed to load period id " << period_id + << ": " << cpp_strerror(-ret) << std::endl; + return -ret; + } + encode_json("id", period_id, formatter.get()); + period_id = period.predecessor_uuid; + } + } // close sections periods and realm_periods_list + formatter->flush(cout); break; case OPT::REALM_RENAME: { - RGWRealm realm(realm_id, realm_name); if (realm_new_name.empty()) { cerr << "missing realm new name" << std::endl; return EINVAL; @@ -4956,14 +4999,18 @@ int main(int argc, const char **argv) cerr << "missing realm name or id" << std::endl; return EINVAL; } - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + + RGWRealm realm; + std::unique_ptr writer; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm, &writer); if (ret < 0) { - cerr << "realm.init failed: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load realm: " << cpp_strerror(-ret) << std::endl; return -ret; } - ret = realm.rename(dpp(), realm_new_name, null_yield); + ret = writer->rename(dpp(), null_yield, realm, realm_new_name); if (ret < 0) { - cerr << "realm.rename failed: " << cpp_strerror(-ret) << std::endl; + cerr << "rename failed: " << cpp_strerror(-ret) << std::endl; return -ret; } cout << "Realm name updated. Note that this change only applies to " @@ -4977,9 +5024,11 @@ int main(int argc, const char **argv) cerr << "no realm name or id provided" << std::endl; return EINVAL; } - RGWRealm realm(realm_id, realm_name); bool new_realm = false; - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWRealm realm; + std::unique_ptr writer; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm, &writer); if (ret < 0 && ret != -ENOENT) { cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -4999,13 +5048,15 @@ int main(int argc, const char **argv) if (new_realm) { cout << "clearing period and epoch for new realm" << std::endl; realm.clear_current_period_and_epoch(); - ret = realm.create(dpp(), null_yield); + constexpr bool exclusive = true; + ret = rgw::create_realm(dpp(), null_yield, cfgstore.get(), + exclusive, realm); if (ret < 0) { cerr << "ERROR: couldn't create new realm: " << cpp_strerror(-ret) << std::endl; return 1; } } else { - ret = realm.update(dpp(), null_yield); + ret = writer->write(dpp(), null_yield, realm); if (ret < 0) { cerr << "ERROR: couldn't store realm info: " << cpp_strerror(-ret) << std::endl; return 1; @@ -5013,7 +5064,7 @@ int main(int argc, const char **argv) } if (set_default) { - ret = realm.set_as_default(dpp(), null_yield); + ret = rgw::set_default_realm(dpp(), null_yield, cfgstore.get(), realm); if (ret < 0) { cerr << "failed to set realm " << realm_name << " as default: " << cpp_strerror(-ret) << std::endl; } @@ -5025,13 +5076,14 @@ int main(int argc, const char **argv) case OPT::REALM_DEFAULT: { - RGWRealm realm(realm_id, realm_name); - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWRealm realm; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); if (ret < 0) { - cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load realm: " << cpp_strerror(-ret) << std::endl; return -ret; } - ret = realm.set_as_default(dpp(), null_yield); + ret = rgw::set_default_realm(dpp(), null_yield, cfgstore.get(), realm); if (ret < 0) { cerr << "failed to set realm as default: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -5068,7 +5120,6 @@ int main(int argc, const char **argv) return -ret; } RGWRealm realm; - realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield, false); try { decode_json_obj(realm, &p); } catch (const JSONDecoder::err& e) { @@ -5079,7 +5130,7 @@ int main(int argc, const char **argv) auto& current_period = realm.get_current_period(); if (!current_period.empty()) { // pull the latest epoch of the realm's current period - ret = do_period_pull(nullptr, url, opt_region, + ret = do_period_pull(cfgstore.get(), nullptr, url, opt_region, access_key, secret_key, realm_id, realm_name, current_period, "", &period); @@ -5088,21 +5139,17 @@ int main(int argc, const char **argv) return -ret; } } - ret = realm.create(dpp(), null_yield, false); - if (ret < 0 && ret != -EEXIST) { + constexpr bool exclusive = false; + ret = rgw::create_realm(dpp(), null_yield, cfgstore.get(), + exclusive, realm); + if (ret < 0) { cerr << "Error storing realm " << realm.get_id() << ": " << cpp_strerror(ret) << std::endl; return -ret; - } else if (ret ==-EEXIST) { - ret = realm.update(dpp(), null_yield); - if (ret < 0) { - cerr << "Error storing realm " << realm.get_id() << ": " - << cpp_strerror(ret) << std::endl; - } - } + } if (set_default) { - ret = realm.set_as_default(dpp(), null_yield); + ret = rgw::set_default_realm(dpp(), null_yield, cfgstore.get(), realm); if (ret < 0) { cerr << "failed to set realm " << realm_name << " as default: " << cpp_strerror(-ret) << std::endl; } @@ -5120,29 +5167,41 @@ int main(int argc, const char **argv) return EINVAL; } - RGWZoneGroup zonegroup(zonegroup_id,zonegroup_name); - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + // load the zonegroup and zone params + RGWZoneGroup zonegroup; + std::unique_ptr zonegroup_writer; + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, + zonegroup, &zonegroup_writer); if (ret < 0) { - cerr << "failed to initialize zonegroup " << zonegroup_name << " id " << zonegroup_id << ": " - << cpp_strerror(-ret) << std::endl; + cerr << "failed to load zonegroup " << zonegroup_name << " id " + << zonegroup_id << ": " << cpp_strerror(-ret) << std::endl; return -ret; } - RGWZoneParams zone(zone_id, zone_name); - ret = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + + RGWZoneParams zone_params; + std::unique_ptr zone_writer; + ret = rgw::read_zone(dpp(), null_yield, cfgstore.get(), + zone_id, zone_name, zone_params, &zone_writer); if (ret < 0) { - cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl; + cerr << "unable to load zone: " << cpp_strerror(-ret) << std::endl; return -ret; } + // update zone_params if necessary bool need_zone_update = false; - if (zone.realm_id != zonegroup.realm_id) { - zone.realm_id = zonegroup.realm_id; + if (zone_params.realm_id != zonegroup.realm_id) { + if (!zone_params.realm_id.empty()) { + cerr << "WARNING: overwriting zone realm_id=" << zone_params.realm_id + << " to match zonegroup realm_id=" << zonegroup.realm_id << std::endl; + } + zone_params.realm_id = zonegroup.realm_id; need_zone_update = true; } for (auto a : tier_config_add) { - ret = zone.tier_config.set(a.first, a.second); + ret = zone_params.tier_config.set(a.first, a.second); if (ret < 0) { cerr << "ERROR: failed to set configurable: " << a << std::endl; return EINVAL; @@ -5151,33 +5210,51 @@ int main(int argc, const char **argv) } if (need_zone_update) { - ret = zone.update(dpp(), null_yield); + ret = zone_writer->write(dpp(), null_yield, zone_params); if (ret < 0) { cerr << "failed to save zone info: " << cpp_strerror(-ret) << std::endl; return -ret; } } - string *ptier_type = (tier_type_specified ? &tier_type : nullptr); + const bool *pis_master = (is_master_set ? &is_master : nullptr); + const bool *pread_only = (is_read_only_set ? &read_only : nullptr); + const bool *psync_from_all = (sync_from_all_specified ? &sync_from_all : nullptr); + const string *predirect_zone = (redirect_zone_set ? &redirect_zone : nullptr); + + // validate --tier-type if specified + const string *ptier_type = (tier_type_specified ? &tier_type : nullptr); + if (ptier_type) { + auto sync_mgr = static_cast(store)->svc()->sync_modules->get_manager(); + if (!sync_mgr->get_module(*ptier_type, nullptr)) { + ldpp_dout(dpp(), -1) << "ERROR: could not find sync module: " + << *ptier_type << ", valid sync modules: " + << sync_mgr->get_registered_module_names() << dendl; + return EINVAL; + } + } - bool *psync_from_all = (sync_from_all_specified ? &sync_from_all : nullptr); - string *predirect_zone = (redirect_zone_set ? &redirect_zone : nullptr); if (enable_features.empty()) { // enable all features by default enable_features.insert(rgw::zone_features::supported.begin(), rgw::zone_features::supported.end()); } - ret = zonegroup.add_zone(dpp(), zone, - (is_master_set ? &is_master : NULL), - (is_read_only_set ? &read_only : NULL), - endpoints, ptier_type, - psync_from_all, sync_from, sync_from_rm, - predirect_zone, bucket_index_max_shards, - static_cast(store)->svc()->sync_modules->get_manager(), - enable_features, disable_features, null_yield); + // add/update the public zone information stored in the zonegroup + ret = rgw::add_zone_to_group(dpp(), zonegroup, zone_params, + pis_master, pread_only, endpoints, + ptier_type, psync_from_all, + sync_from, sync_from_rm, + predirect_zone, bucket_index_max_shards, + enable_features, disable_features); + if (ret < 0) { + return -ret; + } + + // write the updated zonegroup + ret = zonegroup_writer->write(dpp(), null_yield, zonegroup); if (ret < 0) { - cerr << "failed to add zone " << zone_name << " to zonegroup " << zonegroup.get_name() << ": " - << cpp_strerror(-ret) << std::endl; + cerr << "failed to write updated zonegroup " << zonegroup.get_name() + << ": " << cpp_strerror(-ret) << std::endl; return -ret; } @@ -5191,14 +5268,19 @@ int main(int argc, const char **argv) cerr << "Missing zonegroup name" << std::endl; return EINVAL; } - RGWRealm realm(realm_id, realm_name); - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWRealm realm; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); if (ret < 0) { cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl; return -ret; } - RGWZoneGroup zonegroup(zonegroup_name, is_master, g_ceph_context, static_cast(store)->svc()->sysobj, realm.get_id(), endpoints); + RGWZoneGroup zonegroup; + zonegroup.name = zonegroup_name; + zonegroup.is_master = is_master; + zonegroup.realm_id = realm.get_id(); + zonegroup.endpoints = endpoints; zonegroup.api_name = (api_name.empty() ? zonegroup_name : api_name); zonegroup.enabled_features = enable_features; @@ -5216,14 +5298,17 @@ int main(int argc, const char **argv) zonegroup.enabled_features.erase(i); } - ret = zonegroup.create(dpp(), null_yield); + constexpr bool exclusive = true; + ret = rgw::create_zonegroup(dpp(), null_yield, cfgstore.get(), + exclusive, zonegroup); if (ret < 0) { cerr << "failed to create zonegroup " << zonegroup_name << ": " << cpp_strerror(-ret) << std::endl; return -ret; } if (set_default) { - ret = zonegroup.set_as_default(dpp(), null_yield); + ret = rgw::set_default_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup); if (ret < 0) { cerr << "failed to set zonegroup " << zonegroup_name << " as default: " << cpp_strerror(-ret) << std::endl; } @@ -5240,14 +5325,17 @@ int main(int argc, const char **argv) return EINVAL; } - RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneGroup zonegroup; + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, + zonegroup); if (ret < 0) { cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; } - ret = zonegroup.set_as_default(dpp(), null_yield); + ret = rgw::set_default_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup); if (ret < 0) { cerr << "failed to set zonegroup as default: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -5256,18 +5344,20 @@ int main(int argc, const char **argv) break; case OPT::ZONEGROUP_DELETE: { - if (empty_opt(opt_zonegroup_id) && empty_opt(opt_zonegroup_name)) { + if (zonegroup_id.empty() && zonegroup_name.empty()) { cerr << "no zonegroup name or id provided" << std::endl; return EINVAL; } - RGWZoneGroup zonegroup(safe_opt(opt_zonegroup_id), safe_opt(opt_zonegroup_name)); - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, - null_yield); + RGWZoneGroup zonegroup; + std::unique_ptr writer; + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, + zonegroup, &writer); if (ret < 0) { - cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; } - ret = zonegroup.delete_obj(dpp(), null_yield); + ret = writer->remove(dpp(), null_yield); if (ret < 0) { cerr << "ERROR: couldn't delete zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -5276,10 +5366,11 @@ int main(int argc, const char **argv) break; case OPT::ZONEGROUP_GET: { - RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneGroup zonegroup; + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, zonegroup); if (ret < 0) { - cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; } @@ -5289,36 +5380,40 @@ int main(int argc, const char **argv) break; case OPT::ZONEGROUP_LIST: { - RGWZoneGroup zonegroup; - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, - null_yield, false); - if (ret < 0) { - cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; - return -ret; - } - - list zonegroups; - ret = static_cast(store)->svc()->zone->list_zonegroups(dpp(), zonegroups); - if (ret < 0) { - cerr << "failed to list zonegroups: " << cpp_strerror(-ret) << std::endl; - return -ret; - } - string default_zonegroup; - ret = zonegroup.read_default_id(dpp(), default_zonegroup, null_yield); + RGWZoneGroup default_zonegroup; + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + {}, {}, default_zonegroup); if (ret < 0 && ret != -ENOENT) { cerr << "could not determine default zonegroup: " << cpp_strerror(-ret) << std::endl; } - formatter->open_object_section("zonegroups_list"); - encode_json("default_info", default_zonegroup, formatter.get()); - encode_json("zonegroups", zonegroups, formatter.get()); - formatter->close_section(); - formatter->flush(cout); - } + + Formatter::ObjectSection zonegroups_list{*formatter, "zonegroups_list"}; + encode_json("default_info", default_zonegroup.id, formatter.get()); + + Formatter::ArraySection zonegroups{*formatter, "zonegroups"}; + rgw::sal::ListResult listing; + std::array names; // list in pages of 1000 + do { + ret = cfgstore->list_zonegroup_names(dpp(), null_yield, listing.next, + names, listing); + if (ret < 0) { + std::cerr << "failed to list zonegroups: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + for (const auto& name : listing.entries) { + encode_json("name", name, formatter.get()); + } + } while (!listing.next.empty()); + } // close sections zonegroups and zonegroups_list + formatter->flush(cout); break; case OPT::ZONEGROUP_MODIFY: { - RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneGroup zonegroup; + std::unique_ptr writer; + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, + zonegroup, &writer); if (ret < 0) { cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -5332,7 +5427,7 @@ int main(int argc, const char **argv) } if (is_master_set) { - zonegroup.update_master(dpp(), is_master, null_yield); + zonegroup.is_master = is_master; need_update = true; } @@ -5351,8 +5446,8 @@ int main(int argc, const char **argv) need_update = true; } else if (!realm_name.empty()) { // get realm id from name - RGWRealm realm{g_ceph_context, static_cast(store)->svc()->sysobj}; - ret = realm.read_id(dpp(), realm_name, zonegroup.realm_id, null_yield); + ret = cfgstore->read_realm_id(dpp(), null_yield, realm_name, + zonegroup.realm_id); if (ret < 0) { cerr << "failed to find realm by name " << realm_name << std::endl; return -ret; @@ -5384,7 +5479,7 @@ int main(int argc, const char **argv) } if (need_update) { - ret = zonegroup.update(dpp(), null_yield); + ret = writer->write(dpp(), null_yield, zonegroup); if (ret < 0) { cerr << "failed to update zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -5392,7 +5487,8 @@ int main(int argc, const char **argv) } if (set_default) { - ret = zonegroup.set_as_default(dpp(), null_yield); + ret = rgw::set_default_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup); if (ret < 0) { cerr << "failed to set zonegroup " << zonegroup_name << " as default: " << cpp_strerror(-ret) << std::endl; } @@ -5404,22 +5500,17 @@ int main(int argc, const char **argv) break; case OPT::ZONEGROUP_SET: { - RGWRealm realm(realm_id, realm_name); - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWRealm realm; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); bool default_realm_not_exist = (ret == -ENOENT && realm_id.empty() && realm_name.empty()); - if (ret < 0 && !default_realm_not_exist ) { + if (ret < 0 && !default_realm_not_exist) { cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl; return -ret; } RGWZoneGroup zonegroup; - ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, - null_yield, false); - if (ret < 0) { - cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; - return -ret; - } ret = read_decode_json(infile, zonegroup); if (ret < 0) { return 1; @@ -5453,20 +5544,19 @@ int main(int argc, const char **argv) } } } - ret = zonegroup.create(dpp(), null_yield); - if (ret < 0 && ret != -EEXIST) { + + // create/overwrite the zonegroup info + constexpr bool exclusive = false; + ret = rgw::create_zonegroup(dpp(), null_yield, cfgstore.get(), + exclusive, zonegroup); + if (ret < 0) { cerr << "ERROR: couldn't create zonegroup info: " << cpp_strerror(-ret) << std::endl; return 1; - } else if (ret == -EEXIST) { - ret = zonegroup.update(dpp(), null_yield); - if (ret < 0) { - cerr << "ERROR: couldn't store zonegroup info: " << cpp_strerror(-ret) << std::endl; - return 1; - } } if (set_default) { - ret = zonegroup.set_as_default(dpp(), null_yield); + ret = rgw::set_default_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup); if (ret < 0) { cerr << "failed to set zonegroup " << zonegroup_name << " as default: " << cpp_strerror(-ret) << std::endl; } @@ -5478,8 +5568,11 @@ int main(int argc, const char **argv) break; case OPT::ZONEGROUP_REMOVE: { - RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneGroup zonegroup; + std::unique_ptr writer; + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, + zonegroup, &writer); if (ret < 0) { cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -5504,12 +5597,18 @@ int main(int argc, const char **argv) } } - ret = zonegroup.remove_zone(dpp(), zone_id, null_yield); + ret = rgw::remove_zone_from_group(dpp(), zonegroup, zone_id); if (ret < 0) { cerr << "failed to remove zone: " << cpp_strerror(-ret) << std::endl; return -ret; } + ret = writer->write(dpp(), null_yield, zonegroup); + if (ret < 0) { + cerr << "failed to write zonegroup: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + encode_json("zonegroup", zonegroup, formatter.get()); formatter->flush(cout); } @@ -5524,13 +5623,16 @@ int main(int argc, const char **argv) cerr << "no zonegroup name or id provided" << std::endl; return EINVAL; } - RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneGroup zonegroup; + std::unique_ptr writer; + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, + zonegroup, &writer); if (ret < 0) { - cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; } - ret = zonegroup.rename(dpp(), zonegroup_new_name, null_yield); + ret = writer->rename(dpp(), null_yield, zonegroup, zonegroup_new_name); if (ret < 0) { cerr << "failed to rename zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -5539,11 +5641,11 @@ int main(int argc, const char **argv) break; case OPT::ZONEGROUP_PLACEMENT_LIST: { - RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, - null_yield); + RGWZoneGroup zonegroup; + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, zonegroup); if (ret < 0) { - cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; } @@ -5558,10 +5660,11 @@ int main(int argc, const char **argv) return EINVAL; } - RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneGroup zonegroup; + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, zonegroup); if (ret < 0) { - cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; } @@ -5595,8 +5698,11 @@ int main(int argc, const char **argv) rule.storage_class = opt_storage_class.value_or(string()); } - RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneGroup zonegroup; + std::unique_ptr writer; + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, + zonegroup, &writer); if (ret < 0) { cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -5677,15 +5783,27 @@ int main(int argc, const char **argv) target.tier_targets.emplace(std::make_pair(storage_class, *pt)); } + if (zonegroup.default_placement.empty()) { + zonegroup.default_placement.init(rule.name, RGW_STORAGE_CLASS_STANDARD); + } } else if (opt_cmd == OPT::ZONEGROUP_PLACEMENT_RM) { if (!opt_storage_class || opt_storage_class->empty()) { zonegroup.placement_targets.erase(placement_id); + if (zonegroup.default_placement.name == placement_id) { + // clear default placement + zonegroup.default_placement.clear(); + } } else { auto iter = zonegroup.placement_targets.find(placement_id); if (iter != zonegroup.placement_targets.end()) { RGWZoneGroupPlacementTarget& info = zonegroup.placement_targets[placement_id]; info.storage_classes.erase(*opt_storage_class); + if (zonegroup.default_placement == rule) { + // clear default storage class + zonegroup.default_placement.storage_class.clear(); + } + auto ptiter = info.tier_targets.find(*opt_storage_class); if (ptiter != info.tier_targets.end()) { info.tier_targets.erase(ptiter); @@ -5701,8 +5819,7 @@ int main(int argc, const char **argv) zonegroup.default_placement = rule; } - zonegroup.post_process_params(dpp(), null_yield); - ret = zonegroup.update(dpp(), null_yield); + ret = writer->write(dpp(), null_yield, zonegroup); if (ret < 0) { cerr << "failed to update zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -5718,13 +5835,16 @@ int main(int argc, const char **argv) cerr << "zone name not provided" << std::endl; return EINVAL; } - int ret; - RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); + + RGWZoneGroup zonegroup; + std::unique_ptr zonegroup_writer; /* if the user didn't provide zonegroup info , create stand alone zone */ if (!zonegroup_id.empty() || !zonegroup_name.empty()) { - ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + int ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, + zonegroup, &zonegroup_writer); if (ret < 0) { - cerr << "unable to initialize zonegroup " << zonegroup_name << ": " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load zonegroup " << zonegroup_name << ": " << cpp_strerror(-ret) << std::endl; return -ret; } if (realm_id.empty() && realm_name.empty()) { @@ -5732,49 +5852,78 @@ int main(int argc, const char **argv) } } - RGWZoneParams zone(zone_id, zone_name); - ret = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield, false); - if (ret < 0) { - cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl; - return -ret; - } + // create the local zone params + RGWZoneParams zone_params; + zone_params.id = zone_id; + zone_params.name = zone_name; - zone.system_key.id = access_key; - zone.system_key.key = secret_key; - zone.realm_id = realm_id; - for (auto a : tier_config_add) { - int r = zone.tier_config.set(a.first, a.second); + zone_params.system_key.id = access_key; + zone_params.system_key.key = secret_key; + zone_params.realm_id = realm_id; + for (const auto& a : tier_config_add) { + int r = zone_params.tier_config.set(a.first, a.second); if (r < 0) { cerr << "ERROR: failed to set configurable: " << a << std::endl; return EINVAL; } } - ret = zone.create(dpp(), null_yield); + if (zone_params.realm_id.empty()) { + RGWRealm realm; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); + if (ret < 0 && ret != -ENOENT) { + cerr << "failed to load realm: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + zone_params.realm_id = realm.id; + cerr << "NOTICE: set zone's realm_id=" << realm.id << std::endl; + } + + constexpr bool exclusive = true; + int ret = rgw::create_zone(dpp(), null_yield, cfgstore.get(), + exclusive, zone_params); if (ret < 0) { cerr << "failed to create zone " << zone_name << ": " << cpp_strerror(-ret) << std::endl; return -ret; } - if (!zonegroup_id.empty() || !zonegroup_name.empty()) { - string *ptier_type = (tier_type_specified ? &tier_type : nullptr); - bool *psync_from_all = (sync_from_all_specified ? &sync_from_all : nullptr); - string *predirect_zone = (redirect_zone_set ? &redirect_zone : nullptr); + if (zonegroup_writer) { + const bool *pis_master = (is_master_set ? &is_master : nullptr); + const bool *pread_only = (is_read_only_set ? &read_only : nullptr); + const bool *psync_from_all = (sync_from_all_specified ? &sync_from_all : nullptr); + const string *predirect_zone = (redirect_zone_set ? &redirect_zone : nullptr); + + // validate --tier-type if specified + const string *ptier_type = (tier_type_specified ? &tier_type : nullptr); + if (ptier_type) { + auto sync_mgr = static_cast(store)->svc()->sync_modules->get_manager(); + if (!sync_mgr->get_module(*ptier_type, nullptr)) { + ldpp_dout(dpp(), -1) << "ERROR: could not find sync module: " + << *ptier_type << ", valid sync modules: " + << sync_mgr->get_registered_module_names() << dendl; + return EINVAL; + } + } + if (enable_features.empty()) { // enable all features by default enable_features.insert(rgw::zone_features::supported.begin(), rgw::zone_features::supported.end()); } - ret = zonegroup.add_zone(dpp(), zone, - (is_master_set ? &is_master : NULL), - (is_read_only_set ? &read_only : NULL), - endpoints, - ptier_type, - psync_from_all, - sync_from, sync_from_rm, - predirect_zone, bucket_index_max_shards, - static_cast(store)->svc()->sync_modules->get_manager(), - enable_features, disable_features, null_yield); + // add/update the public zone information stored in the zonegroup + ret = rgw::add_zone_to_group(dpp(), zonegroup, zone_params, + pis_master, pread_only, endpoints, + ptier_type, psync_from_all, + sync_from, sync_from_rm, + predirect_zone, bucket_index_max_shards, + enable_features, disable_features); + if (ret < 0) { + return -ret; + } + + // write the updated zonegroup + ret = zonegroup_writer->write(dpp(), null_yield, zonegroup); if (ret < 0) { cerr << "failed to add zone " << zone_name << " to zonegroup " << zonegroup.get_name() << ": " << cpp_strerror(-ret) << std::endl; @@ -5783,13 +5932,14 @@ int main(int argc, const char **argv) } if (set_default) { - ret = zone.set_as_default(dpp(), null_yield); + ret = rgw::set_default_zone(dpp(), null_yield, cfgstore.get(), + zone_params); if (ret < 0) { cerr << "failed to set zone " << zone_name << " as default: " << cpp_strerror(-ret) << std::endl; } } - encode_json("zone", zone, formatter.get()); + encode_json("zone", zone_params, formatter.get()); formatter->flush(cout); } break; @@ -5799,13 +5949,16 @@ int main(int argc, const char **argv) cerr << "no zone name or id provided" << std::endl; return EINVAL; } - RGWZoneParams zone(zone_id, zone_name); - int ret = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneParams zone_params; + int ret = rgw::read_zone(dpp(), null_yield, cfgstore.get(), + zone_id, zone_name, zone_params); if (ret < 0) { - cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl; + cerr << "unable to load zone: " << cpp_strerror(-ret) << std::endl; return -ret; } - ret = zone.set_as_default(dpp(), null_yield); + + ret = rgw::set_default_zone(dpp(), null_yield, cfgstore.get(), + zone_params); if (ret < 0) { cerr << "failed to set zone as default: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -5814,69 +5967,49 @@ int main(int argc, const char **argv) break; case OPT::ZONE_DELETE: { - if (empty_opt(opt_zone_id) && empty_opt(opt_zone_name)) { + if (zone_id.empty() && zone_name.empty()) { cerr << "no zone name or id provided" << std::endl; return EINVAL; } - RGWZoneParams zone(safe_opt(opt_zone_id), safe_opt(opt_zone_name)); - int ret = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneParams zone_params; + std::unique_ptr writer; + int ret = rgw::read_zone(dpp(), null_yield, cfgstore.get(), + zone_id, zone_name, zone_params, &writer); if (ret < 0) { - cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load zone: " << cpp_strerror(-ret) << std::endl; return -ret; } - list zonegroups; - ret = static_cast(store)->svc()->zone->list_zonegroups(dpp(), zonegroups); + ret = rgw::delete_zone(dpp(), null_yield, cfgstore.get(), + zone_params, *writer); if (ret < 0) { - cerr << "failed to list zonegroups: " << cpp_strerror(-ret) << std::endl; - return -ret; - } - - for (list::iterator iter = zonegroups.begin(); iter != zonegroups.end(); ++iter) { - RGWZoneGroup zonegroup(string(), *iter); - int ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); - if (ret < 0) { - cerr << "WARNING: failed to initialize zonegroup " << zonegroup_name << std::endl; - continue; - } - ret = zonegroup.remove_zone(dpp(), zone.get_id(), null_yield); - if (ret < 0 && ret != -ENOENT) { - cerr << "failed to remove zone " << zone.get_name() << " from zonegroup " << zonegroup.get_name() << ": " - << cpp_strerror(-ret) << std::endl; - } - } - - ret = zone.delete_obj(dpp(), null_yield); - if (ret < 0) { - cerr << "failed to delete zone " << zone.get_name() << ": " << cpp_strerror(-ret) << std::endl; + cerr << "failed to delete zone " << zone_params.get_name() + << ": " << cpp_strerror(-ret) << std::endl; return -ret; } } break; case OPT::ZONE_GET: { - RGWZoneParams zone(zone_id, zone_name); - int ret = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneParams zone_params; + int ret = rgw::read_zone(dpp(), null_yield, cfgstore.get(), + zone_id, zone_name, zone_params); if (ret < 0) { - cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load zone: " << cpp_strerror(-ret) << std::endl; return -ret; } - encode_json("zone", zone, formatter.get()); + encode_json("zone", zone_params, formatter.get()); formatter->flush(cout); } break; case OPT::ZONE_SET: { - RGWZoneParams zone(zone_name); - int ret = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield, - false); - if (ret < 0) { - return -ret; - } - - ret = zone.read(dpp(), null_yield); + RGWZoneParams zone; + std::unique_ptr writer; + int ret = rgw::read_zone(dpp(), null_yield, cfgstore.get(), + zone_id, zone_name, zone, &writer); if (ret < 0 && ret != -ENOENT) { - cerr << "zone.read() returned ret=" << ret << std::endl; + cerr << "failed to load zone: " << cpp_strerror(ret) << std::endl; return -ret; } @@ -5887,17 +6020,19 @@ int main(int argc, const char **argv) return 1; } - if(zone.realm_id.empty()) { - RGWRealm realm(realm_id, realm_name); - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + if (zone.realm_id.empty()) { + RGWRealm realm; + ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); if (ret < 0 && ret != -ENOENT) { - cerr << "failed to init realm: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load realm: " << cpp_strerror(-ret) << std::endl; return -ret; } zone.realm_id = realm.get_id(); + cerr << "NOTICE: set zone's realm_id=" << zone.realm_id << std::endl; } - if( !zone_name.empty() && !zone.get_name().empty() && zone.get_name() != zone_name) { + if (!zone_name.empty() && !zone.get_name().empty() && zone.get_name() != zone_name) { cerr << "Error: zone name " << zone_name << " is different than the zone name " << zone.get_name() << " in the provided json " << std::endl; return EINVAL; } @@ -5916,30 +6051,16 @@ int main(int argc, const char **argv) zone.set_id(orig_id); } - if (zone.get_id().empty()) { - cerr << "no zone name id the json provided, assuming old format" << std::endl; - if (zone_name.empty()) { - cerr << "missing zone name" << std::endl; - return EINVAL; - } - zone.set_name(zone_name); - zone.set_id(zone_name); - } - - cerr << "zone id " << zone.get_id(); - ret = zone.fix_pool_names(dpp(), null_yield); - if (ret < 0) { - cerr << "ERROR: couldn't fix zone: " << cpp_strerror(-ret) << std::endl; - return -ret; - } - ret = zone.write(dpp(), false, null_yield); + constexpr bool exclusive = false; + ret = rgw::create_zone(dpp(), null_yield, cfgstore.get(), + exclusive, zone); if (ret < 0) { cerr << "ERROR: couldn't create zone: " << cpp_strerror(-ret) << std::endl; - return 1; + return -ret; } if (set_default) { - ret = zone.set_as_default(dpp(), null_yield); + ret = rgw::set_default_zone(dpp(), null_yield, cfgstore.get(), zone); if (ret < 0) { cerr << "failed to set zone " << zone_name << " as default: " << cpp_strerror(-ret) << std::endl; } @@ -5951,58 +6072,62 @@ int main(int argc, const char **argv) break; case OPT::ZONE_LIST: { - list zones; - int ret = store->list_all_zones(dpp(), zones); - if (ret < 0) { - cerr << "failed to list zones: " << cpp_strerror(-ret) << std::endl; - return -ret; - } - - RGWZoneParams zone; - ret = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield, false); - if (ret < 0) { - cerr << "failed to init zone: " << cpp_strerror(-ret) << std::endl; - return -ret; - } - string default_zone; - ret = zone.read_default_id(dpp(), default_zone, null_yield); + RGWZoneParams default_zone_params; + int ret = rgw::read_zone(dpp(), null_yield, cfgstore.get(), + {}, {}, default_zone_params); if (ret < 0 && ret != -ENOENT) { cerr << "could not determine default zone: " << cpp_strerror(-ret) << std::endl; } - formatter->open_object_section("zones_list"); - encode_json("default_info", default_zone, formatter.get()); - encode_json("zones", zones, formatter.get()); - formatter->close_section(); - formatter->flush(cout); - } + + Formatter::ObjectSection zones_list{*formatter, "zones_list"}; + encode_json("default_info", default_zone_params.id, formatter.get()); + + Formatter::ArraySection zones{*formatter, "zones"}; + rgw::sal::ListResult listing; + std::array names; // list in pages of 1000 + do { + ret = cfgstore->list_zone_names(dpp(), null_yield, listing.next, + names, listing); + if (ret < 0) { + std::cerr << "failed to list zones: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + for (const auto& name : listing.entries) { + encode_json("name", name, formatter.get()); + } + } while (!listing.next.empty()); + } // close sections zones and zones_list + formatter->flush(cout); break; case OPT::ZONE_MODIFY: { - RGWZoneParams zone(zone_id, zone_name); - int ret = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneParams zone_params; + std::unique_ptr zone_writer; + int ret = rgw::read_zone(dpp(), null_yield, cfgstore.get(), + zone_id, zone_name, zone_params, &zone_writer); if (ret < 0) { - cerr << "failed to init zone: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load zone: " << cpp_strerror(-ret) << std::endl; return -ret; } bool need_zone_update = false; if (!access_key.empty()) { - zone.system_key.id = access_key; + zone_params.system_key.id = access_key; need_zone_update = true; } if (!secret_key.empty()) { - zone.system_key.key = secret_key; + zone_params.system_key.key = secret_key; need_zone_update = true; } if (!realm_id.empty()) { - zone.realm_id = realm_id; + zone_params.realm_id = realm_id; need_zone_update = true; } else if (!realm_name.empty()) { // get realm id from name - RGWRealm realm{g_ceph_context, static_cast(store)->svc()->sysobj}; - ret = realm.read_id(dpp(), realm_name, zone.realm_id, null_yield); + ret = cfgstore->read_realm_id(dpp(), null_yield, + realm_name, zone_params.realm_id); if (ret < 0) { cerr << "failed to find realm by name " << realm_name << std::endl; return -ret; @@ -6010,70 +6135,89 @@ int main(int argc, const char **argv) need_zone_update = true; } - if (tier_config_add.size() > 0) { - for (auto add : tier_config_add) { - int r = zone.tier_config.set(add.first, add.second); - if (r < 0) { - cerr << "ERROR: failed to set configurable: " << add << std::endl; - return EINVAL; - } + for (const auto& add : tier_config_add) { + ret = zone_params.tier_config.set(add.first, add.second); + if (ret < 0) { + cerr << "ERROR: failed to set configurable: " << add << std::endl; + return EINVAL; } need_zone_update = true; } - for (auto rm : tier_config_rm) { + for (const auto& rm : tier_config_rm) { if (!rm.first.empty()) { /* otherwise will remove the entire config */ - zone.tier_config.erase(rm.first); + zone_params.tier_config.erase(rm.first); need_zone_update = true; } } if (need_zone_update) { - ret = zone.update(dpp(), null_yield); + ret = zone_writer->write(dpp(), null_yield, zone_params); if (ret < 0) { cerr << "failed to save zone info: " << cpp_strerror(-ret) << std::endl; return -ret; } } - RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); - ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); - if (ret < 0) { - cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; - return -ret; - } - string *ptier_type = (tier_type_specified ? &tier_type : nullptr); - - bool *psync_from_all = (sync_from_all_specified ? &sync_from_all : nullptr); - string *predirect_zone = (redirect_zone_set ? &redirect_zone : nullptr); - - ret = zonegroup.add_zone(dpp(), zone, - (is_master_set ? &is_master : NULL), - (is_read_only_set ? &read_only : NULL), - endpoints, ptier_type, - psync_from_all, sync_from, sync_from_rm, - predirect_zone, bucket_index_max_shards, - static_cast(store)->svc()->sync_modules->get_manager(), - enable_features, disable_features, null_yield); + RGWZoneGroup zonegroup; + std::unique_ptr zonegroup_writer; + ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, + zonegroup, &zonegroup_writer); if (ret < 0) { - cerr << "failed to update zonegroup: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; } - ret = zonegroup.update(dpp(), null_yield); + const bool *pis_master = (is_master_set ? &is_master : nullptr); + const bool *pread_only = (is_read_only_set ? &read_only : nullptr); + const bool *psync_from_all = (sync_from_all_specified ? &sync_from_all : nullptr); + const string *predirect_zone = (redirect_zone_set ? &redirect_zone : nullptr); + + // validate --tier-type if specified + const string *ptier_type = (tier_type_specified ? &tier_type : nullptr); + if (ptier_type) { + auto sync_mgr = static_cast(store)->svc()->sync_modules->get_manager(); + if (!sync_mgr->get_module(*ptier_type, nullptr)) { + ldpp_dout(dpp(), -1) << "ERROR: could not find sync module: " + << *ptier_type << ", valid sync modules: " + << sync_mgr->get_registered_module_names() << dendl; + return EINVAL; + } + } + + if (enable_features.empty()) { // enable all features by default + enable_features.insert(rgw::zone_features::supported.begin(), + rgw::zone_features::supported.end()); + } + + // add/update the public zone information stored in the zonegroup + ret = rgw::add_zone_to_group(dpp(), zonegroup, zone_params, + pis_master, pread_only, endpoints, + ptier_type, psync_from_all, + sync_from, sync_from_rm, + predirect_zone, bucket_index_max_shards, + enable_features, disable_features); + if (ret < 0) { + return -ret; + } + + // write the updated zonegroup + ret = zonegroup_writer->write(dpp(), null_yield, zonegroup); if (ret < 0) { cerr << "failed to update zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; } if (set_default) { - ret = zone.set_as_default(dpp(), null_yield); + ret = rgw::set_default_zone(dpp(), null_yield, cfgstore.get(), + zone_params); if (ret < 0) { cerr << "failed to set zone " << zone_name << " as default: " << cpp_strerror(-ret) << std::endl; } } - encode_json("zone", zone, formatter.get()); + encode_json("zone", zone_params, formatter.get()); formatter->flush(cout); } break; @@ -6087,28 +6231,43 @@ int main(int argc, const char **argv) cerr << "no zone name or id provided" << std::endl; return EINVAL; } - RGWZoneParams zone(zone_id,zone_name); - int ret = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + + RGWZoneParams zone_params; + std::unique_ptr zone_writer; + int ret = rgw::read_zone(dpp(), null_yield, cfgstore.get(), + zone_id, zone_name, zone_params, &zone_writer); if (ret < 0) { - cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load zone: " << cpp_strerror(-ret) << std::endl; return -ret; } - ret = zone.rename(dpp(), zone_new_name, null_yield); + + ret = zone_writer->rename(dpp(), null_yield, zone_params, zone_new_name); if (ret < 0) { cerr << "failed to rename zone " << zone_name << " to " << zone_new_name << ": " << cpp_strerror(-ret) << std::endl; return -ret; } - RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); - ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + + RGWZoneGroup zonegroup; + std::unique_ptr zonegroup_writer; + ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, + zonegroup, &zonegroup_writer); if (ret < 0) { - cerr << "WARNING: failed to initialize zonegroup " << zonegroup_name << std::endl; - } else { - ret = zonegroup.rename_zone(dpp(), zone, null_yield); - if (ret < 0) { - cerr << "Error in zonegroup rename for " << zone_name << ": " << cpp_strerror(-ret) << std::endl; - return -ret; - } + cerr << "WARNING: failed to load zonegroup " << zonegroup_name << std::endl; + return EXIT_SUCCESS; + } + + auto z = zonegroup.zones.find(zone_params.id); + if (z == zonegroup.zones.end()) { + return EXIT_SUCCESS; + } + z->second.name = zone_params.name; + + ret = zonegroup_writer->write(dpp(), null_yield, zonegroup); + if (ret < 0) { + cerr << "Error in zonegroup rename for " << zone_name << ": " << cpp_strerror(-ret) << std::endl; + return -ret; } } break; @@ -6127,8 +6286,10 @@ int main(int argc, const char **argv) return EINVAL; } - RGWZoneParams zone(zone_id, zone_name); - int ret = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneParams zone; + std::unique_ptr writer; + int ret = rgw::read_zone(dpp(), null_yield, cfgstore.get(), + zone_id, zone_name, zone, &writer); if (ret < 0) { cerr << "failed to init zone: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -6136,8 +6297,9 @@ int main(int argc, const char **argv) if (opt_cmd == OPT::ZONE_PLACEMENT_ADD || opt_cmd == OPT::ZONE_PLACEMENT_MODIFY) { - RGWZoneGroup zonegroup(zonegroup_id, zonegroup_name); - ret = zonegroup.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneGroup zonegroup; + ret = rgw::read_zonegroup(dpp(), null_yield, cfgstore.get(), + zonegroup_id, zonegroup_name, zonegroup); if (ret < 0) { cerr << "failed to init zonegroup: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -6215,7 +6377,7 @@ int main(int argc, const char **argv) } } - ret = zone.update(dpp(), null_yield); + ret = writer->write(dpp(), null_yield, zone); if (ret < 0) { cerr << "failed to save zone info: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -6227,8 +6389,9 @@ int main(int argc, const char **argv) break; case OPT::ZONE_PLACEMENT_LIST: { - RGWZoneParams zone(zone_id, zone_name); - int ret = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneParams zone; + int ret = rgw::read_zone(dpp(), null_yield, cfgstore.get(), + zone_id, zone_name, zone); if (ret < 0) { cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -6244,8 +6407,9 @@ int main(int argc, const char **argv) return EINVAL; } - RGWZoneParams zone(zone_id, zone_name); - int ret = zone.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWZoneParams zone; + int ret = rgw::read_zone(dpp(), null_yield, cfgstore.get(), + zone_id, zone_name, zone); if (ret < 0) { cerr << "unable to initialize zone: " << cpp_strerror(-ret) << std::endl; return -ret; @@ -6253,7 +6417,7 @@ int main(int argc, const char **argv) auto p = zone.placement_pools.find(placement_id); if (p == zone.placement_pools.end()) { cerr << "ERROR: zone placement target '" << placement_id << "' not found" << std::endl; - return -ENOENT; + return ENOENT; } encode_json("placement_pools", p->second, formatter.get()); formatter->flush(cout); @@ -6543,10 +6707,11 @@ int main(int argc, const char **argv) params["epoch"] = period_epoch; // load the period - RGWPeriod period(period_id); - int ret = period.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWPeriod period; + int ret = cfgstore->read_period(dpp(), null_yield, period_id, + std::nullopt, period); if (ret < 0) { - cerr << "period init failed: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load period: " << cpp_strerror(-ret) << std::endl; return -ret; } // json format into a bufferlist @@ -6567,9 +6732,9 @@ int main(int argc, const char **argv) return 0; case OPT::PERIOD_UPDATE: { - int ret = update_period(realm_id, realm_name, period_id, period_epoch, - commit, remote, url, opt_region, - access_key, secret_key, + int ret = update_period(cfgstore.get(), realm_id, realm_name, + period_epoch, commit, remote, url, + opt_region, access_key, secret_key, formatter.get(), yes_i_really_mean_it); if (ret < 0) { return -ret; @@ -6579,19 +6744,26 @@ int main(int argc, const char **argv) case OPT::PERIOD_COMMIT: { // read realm and staging period - RGWRealm realm(realm_id, realm_name); - int ret = realm.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, null_yield); + RGWRealm realm; + std::unique_ptr realm_writer; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, + realm, &realm_writer); if (ret < 0) { cerr << "Error initializing realm: " << cpp_strerror(-ret) << std::endl; return -ret; } - RGWPeriod period(RGWPeriod::get_staging_id(realm.get_id()), 1); - ret = period.init(dpp(), g_ceph_context, static_cast(store)->svc()->sysobj, realm.get_id(), null_yield); + period_id = rgw::get_staging_period_id(realm.id); + epoch_t epoch = 1; + + RGWPeriod period; + ret = cfgstore->read_period(dpp(), null_yield, period_id, epoch, period); if (ret < 0) { - cerr << "period init failed: " << cpp_strerror(-ret) << std::endl; + cerr << "failed to load period: " << cpp_strerror(-ret) << std::endl; return -ret; } - ret = commit_period(realm, period, remote, url, opt_region, access_key, secret_key, + ret = commit_period(cfgstore.get(), realm, *realm_writer, period, + remote, url, opt_region, access_key, secret_key, yes_i_really_mean_it); if (ret < 0) { cerr << "failed to commit period: " << cpp_strerror(-ret) << std::endl; @@ -8614,10 +8786,15 @@ next: int i = (specified_shard_id ? shard_id : 0); if (period_id.empty()) { - int ret = read_current_period_id(store, realm_id, realm_name, &period_id); - if (ret < 0) { + // use realm's current period + RGWRealm realm; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); + if (ret < 0 ) { + cerr << "failed to load realm: " << cpp_strerror(-ret) << std::endl; return -ret; } + period_id = realm.current_period; std::cerr << "No --period given, using current period=" << period_id << std::endl; } @@ -8659,10 +8836,15 @@ next: int i = (specified_shard_id ? shard_id : 0); if (period_id.empty()) { - int ret = read_current_period_id(store, realm_id, realm_name, &period_id); - if (ret < 0) { + // use realm's current period + RGWRealm realm; + int ret = rgw::read_realm(dpp(), null_yield, cfgstore.get(), + realm_id, realm_name, realm); + if (ret < 0 ) { + cerr << "failed to load realm: " << cpp_strerror(-ret) << std::endl; return -ret; } + period_id = realm.current_period; std::cerr << "No --period given, using current period=" << period_id << std::endl; } @@ -9320,8 +9502,8 @@ next: CHECK_TRUE(require_opt(opt_group_id), "ERROR: --group-id not specified", EINVAL); CHECK_TRUE(require_opt(opt_status), "ERROR: --status is not specified (options: forbidden, allowed, enabled)", EINVAL); - SyncPolicyContext sync_policy_ctx(zonegroup_id, zonegroup_name, opt_bucket); - ret = sync_policy_ctx.init(); + SyncPolicyContext sync_policy_ctx(cfgstore.get(), opt_bucket); + ret = sync_policy_ctx.init(zonegroup_id, zonegroup_name); if (ret < 0) { return -ret; } @@ -9354,8 +9536,8 @@ next: } if (opt_cmd == OPT::SYNC_GROUP_GET) { - SyncPolicyContext sync_policy_ctx(zonegroup_id, zonegroup_name, opt_bucket); - ret = sync_policy_ctx.init(); + SyncPolicyContext sync_policy_ctx(cfgstore.get(), opt_bucket); + ret = sync_policy_ctx.init(zonegroup_id, zonegroup_name); if (ret < 0) { return -ret; } @@ -9379,8 +9561,8 @@ next: if (opt_cmd == OPT::SYNC_GROUP_REMOVE) { CHECK_TRUE(require_opt(opt_group_id), "ERROR: --group-id not specified", EINVAL); - SyncPolicyContext sync_policy_ctx(zonegroup_id, zonegroup_name, opt_bucket); - ret = sync_policy_ctx.init(); + SyncPolicyContext sync_policy_ctx(cfgstore.get(), opt_bucket); + ret = sync_policy_ctx.init(zonegroup_id, zonegroup_name); if (ret < 0) { return -ret; } @@ -9410,8 +9592,8 @@ next: directional_flow_opt(*opt_flow_type)), "ERROR: --flow-type invalid (options: symmetrical, directional)", EINVAL); - SyncPolicyContext sync_policy_ctx(zonegroup_id, zonegroup_name, opt_bucket); - ret = sync_policy_ctx.init(); + SyncPolicyContext sync_policy_ctx(cfgstore.get(), opt_bucket); + ret = sync_policy_ctx.init(zonegroup_id, zonegroup_name); if (ret < 0) { return -ret; } @@ -9461,8 +9643,8 @@ next: directional_flow_opt(*opt_flow_type)), "ERROR: --flow-type invalid (options: symmetrical, directional)", EINVAL); - SyncPolicyContext sync_policy_ctx(zonegroup_id, zonegroup_name, opt_bucket); - ret = sync_policy_ctx.init(); + SyncPolicyContext sync_policy_ctx(cfgstore.get(), opt_bucket); + ret = sync_policy_ctx.init(zonegroup_id, zonegroup_name); if (ret < 0) { return -ret; } @@ -9502,8 +9684,8 @@ next: CHECK_TRUE(require_non_empty_opt(opt_dest_zone_ids), "ERROR: --dest-zones not provided or is empty; should be list of zones or '*'", EINVAL); } - SyncPolicyContext sync_policy_ctx(zonegroup_id, zonegroup_name, opt_bucket); - ret = sync_policy_ctx.init(); + SyncPolicyContext sync_policy_ctx(cfgstore.get(), opt_bucket); + ret = sync_policy_ctx.init(zonegroup_id, zonegroup_name); if (ret < 0) { return -ret; } @@ -9584,8 +9766,8 @@ next: CHECK_TRUE(require_opt(opt_group_id), "ERROR: --group-id not specified", EINVAL); CHECK_TRUE(require_opt(opt_pipe_id), "ERROR: --pipe-id not specified", EINVAL); - SyncPolicyContext sync_policy_ctx(zonegroup_id, zonegroup_name, opt_bucket); - ret = sync_policy_ctx.init(); + SyncPolicyContext sync_policy_ctx(cfgstore.get(), opt_bucket); + ret = sync_policy_ctx.init(zonegroup_id, zonegroup_name); if (ret < 0) { return -ret; } @@ -9640,8 +9822,8 @@ next: } if (opt_cmd == OPT::SYNC_POLICY_GET) { - SyncPolicyContext sync_policy_ctx(zonegroup_id, zonegroup_name, opt_bucket); - ret = sync_policy_ctx.init(); + SyncPolicyContext sync_policy_ctx(cfgstore.get(), opt_bucket); + ret = sync_policy_ctx.init(zonegroup_id, zonegroup_name); if (ret < 0) { return -ret; }