]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: can list regions, show default region info
authorYehuda Sadeh <yehuda@inktank.com>
Thu, 21 Feb 2013 00:22:40 +0000 (16:22 -0800)
committerYehuda Sadeh <yehuda@inktank.com>
Wed, 8 May 2013 17:54:53 +0000 (10:54 -0700)
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/rgw/rgw_admin.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 4070c19fb10aaa0b8be69beba8341a5c22b0eccb..f33956dc6042ee91d8412f3d28836e9693a8706e 100644 (file)
@@ -62,6 +62,7 @@ void _usage()
   cerr << "  object rm                  remove object\n";
   cerr << "  object unlink              unlink object from bucket index\n";
   cerr << "  region info                show region info\n";
+  cerr << "  region list                list all regions\n";
   cerr << "  zone info                  show zone params info\n";
   cerr << "  pool add                   add an existing pool for data placement\n";
   cerr << "  pool rm                    remove an existing pool from data placement set\n";
@@ -167,6 +168,7 @@ enum {
   OPT_GC_LIST,
   OPT_GC_PROCESS,
   OPT_REGION_INFO,
+  OPT_REGION_LIST,
   OPT_ZONE_INFO,
   OPT_ZONE_SET,
   OPT_CAPS_ADD,
@@ -280,6 +282,8 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
   } else if (strcmp(prev_cmd, "region") == 0) {
     if (strcmp(cmd, "info") == 0)
       return OPT_REGION_INFO;
+    if (strcmp(cmd, "list") == 0)
+      return OPT_REGION_LIST;
   } else if (strcmp(prev_cmd, "zone") == 0) {
     if (strcmp(cmd, "info") == 0)
       return OPT_ZONE_INFO;
@@ -633,7 +637,7 @@ int main(int argc, char **argv)
 
   RGWStreamFlusher f(formatter, cout);
 
-  bool raw_storage_op = (opt_cmd == OPT_REGION_INFO);
+  bool raw_storage_op = (opt_cmd == OPT_REGION_INFO || opt_cmd == OPT_REGION_LIST);
 
 
   if (raw_storage_op) {
@@ -654,12 +658,35 @@ int main(int argc, char **argv)
       int ret = region.init(g_ceph_context, store);
       if (ret < 0) {
         cerr << "failed to init region: " << cpp_strerror(-ret) << std::endl;
+       return -ret;
       }
 
       encode_json("region", region, formatter);
       formatter->flush(cout);
       cout << std::endl;
     }
+    if (opt_cmd == OPT_REGION_LIST) {
+      RGWRegion region;
+      int ret = region.init(g_ceph_context, store, false);
+
+      list<string> regions;
+      ret = store->list_regions(regions);
+      if (ret < 0) {
+        cerr << "failed to list regions: " << cpp_strerror(-ret) << std::endl;
+       return -ret;
+      }
+      RGWDefaultRegionInfo default_region;
+      ret = region.read_default(default_region);
+      if (ret < 0 && ret != -ENOENT) {
+       cerr << "could not determine default region: " << cpp_strerror(-ret) << std::endl;
+      }
+      formatter->open_object_section("regions_list");
+      encode_json("default_info", default_region, formatter);
+      encode_json("regions", regions, formatter);
+      formatter->close_section();
+      formatter->flush(cout);
+      cout << std::endl;
+    }
 
     return 0;
   }
index c0a23d4dd8bb8424a55ff16ede0e67e7fd273d76..97db750ebe89ebdb7a9591ce34ef942bde92327d 100644 (file)
@@ -65,28 +65,13 @@ static RGWObjCategory main_category = RGW_OBJ_CATEGORY_MAIN;
 
 #define dout_subsys ceph_subsys_rgw
 
-struct RGWDefaultRegionInfo {
-  string default_region;
-
-  void encode(bufferlist& bl) const {
-    ENCODE_START(1, 1, bl);
-    ::encode(default_region, bl);
-    ENCODE_FINISH(bl);
-  }
+void RGWDefaultRegionInfo::dump(Formatter *f) const {
+  encode_json("default_region", default_region, f);
+}
 
-  void decode(bufferlist::iterator& bl) {
-    DECODE_START(1, bl);
-    ::decode(default_region, bl);
-    DECODE_FINISH(bl);
-  }
-  void dump(Formatter *f) const {
-    encode_json("default_region", default_region, f);
-  }
-  void decode_json(JSONObj *obj) {
-    JSONDecoder::decode_json("default_region", default_region, obj);
-  }
-};
-WRITE_CLASS_ENCODER(RGWDefaultRegionInfo);
+void RGWDefaultRegionInfo::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("default_region", default_region, obj);
+}
 
 string RGWRegion::get_pool_name(CephContext *cct)
 {
@@ -97,7 +82,7 @@ string RGWRegion::get_pool_name(CephContext *cct)
   return pool_name;
 }
 
-int RGWRegion::read_default()
+int RGWRegion::read_default(RGWDefaultRegionInfo& default_info)
 {
   string pool_name = get_pool_name(cct);
 
@@ -112,7 +97,6 @@ int RGWRegion::read_default()
   if (ret < 0)
     return ret;
 
-  RGWDefaultRegionInfo default_info;
   try {
     bufferlist::iterator iter = bl.begin();
     ::decode(default_info, iter);
@@ -150,17 +134,21 @@ int RGWRegion::set_as_default()
   return 0;
 }
 
-int RGWRegion::init(CephContext *_cct, RGWRados *_store)
+int RGWRegion::init(CephContext *_cct, RGWRados *_store, bool setup_region)
 {
   cct = _cct;
   store = _store;
 
+  if (!setup_region)
+    return 0;
+
   string pool_name = get_pool_name(cct);
 
   name = cct->_conf->rgw_region;
 
   if (name.empty()) {
-    int r = read_default();
+    RGWDefaultRegionInfo default_info;
+    int r = read_default(default_info);
     if (r == -ENOENT) {
       r = create_default();
       if (r < 0)
@@ -172,6 +160,7 @@ int RGWRegion::init(CephContext *_cct, RGWRados *_store)
       lderr(cct) << "failed reading default region info: " << cpp_strerror(-r) << dendl;
       return r;
     }
+    name = default_info.default_region;
   }
 
   rgw_bucket pool(pool_name.c_str());
@@ -237,6 +226,8 @@ int RGWRegion::store_info(bool exclusive)
   return ret;
 }
 
+
+
 void RGWZoneParams::init_default()
 {
   domain_root = ".rgw";
@@ -453,6 +444,29 @@ void RGWRados::finalize_watch()
   delete[] watchers;
 }
 
+int RGWRados::list_regions(list<string>& regions)
+{
+  string pool_name = RGWRegion::get_pool_name(cct);
+
+  rgw_bucket pool(pool_name.c_str());
+  bool is_truncated;
+  RGWListRawObjsCtx ctx;
+  do {
+    vector<string> oids;
+    int r = list_raw_objects(pool, region_info_oid_prefix, 1000,
+                            ctx, oids, &is_truncated);
+    if (r < 0) {
+      return r;
+    }
+    vector<string>::iterator iter;
+    for (iter = oids.begin(); iter != oids.end(); ++iter) {
+      regions.push_back(iter->substr(region_info_oid_prefix.size() + 1));
+    }
+  } while (is_truncated);
+
+  return 0;
+}
+
 /**
  * Open the pool used as root for this gateway
  * Returns: 0 on success, -ERR# otherwise.
@@ -3664,6 +3678,44 @@ int RGWRados::pool_iterate(RGWPoolIterCtx& ctx, uint32_t num, vector<RGWObjEnt>&
 
   return objs.size();
 }
+struct RGWAccessListFilterPrefix : public RGWAccessListFilter {
+  string prefix;
+
+  RGWAccessListFilterPrefix(const string& _prefix) : prefix(_prefix) {}
+  virtual bool filter(string& name, string& key) {
+    return (prefix.compare(key.substr(0, prefix.size())) == 0);
+  }
+};
+
+int RGWRados::list_raw_objects(rgw_bucket& pool, const string& prefix_filter,
+                              int max, RGWListRawObjsCtx& ctx, vector<string>& oids,
+                              bool *is_truncated)
+{
+  RGWAccessListFilterPrefix filter(prefix_filter);
+
+  if (!ctx.initialized) {
+    int r = pool_iterate_begin(pool, ctx.iter_ctx);
+    if (r < 0) {
+      lderr(cct) << "failed to list objects pool_iterate_begin() returned r=" << r << dendl;
+      return r;
+    }
+    ctx.initialized = true;
+  }
+
+  vector<RGWObjEnt> objs;
+  int r = pool_iterate(ctx.iter_ctx, max, objs, is_truncated, &filter);
+  if (r < 0) {
+    lderr(cct) << "failed to list objects pool_iterate returned r=" << r << dendl;
+    return r;
+  }
+
+  vector<RGWObjEnt>::iterator iter;
+  for (iter = objs.begin(); iter != objs.end(); ++iter) {
+    oids.push_back(iter->name);
+  }
+
+  return oids.size();
+}
 
 int RGWRados::gc_operate(string& oid, librados::ObjectWriteOperation *op)
 {
index f0568013df5ca5db81b3e1cdf916a2913f71e201..f31d8c73174e1fd274f1b930a86df91a031c4956 100644 (file)
@@ -239,6 +239,13 @@ struct RGWPoolIterCtx {
   librados::ObjectIterator iter;
 };
 
+struct RGWListRawObjsCtx {
+  bool initialized;
+  RGWPoolIterCtx iter_ctx;
+
+  RGWListRawObjsCtx() : initialized(false) {}
+};
+
 struct RGWZoneParams {
   rgw_bucket domain_root;
   rgw_bucket control_pool;
@@ -318,6 +325,25 @@ struct RGWZone {
 };
 WRITE_CLASS_ENCODER(RGWZone);
 
+struct RGWDefaultRegionInfo {
+  string default_region;
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(default_region, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(default_region, bl);
+    DECODE_FINISH(bl);
+  }
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
+};
+WRITE_CLASS_ENCODER(RGWDefaultRegionInfo);
+
 struct RGWRegion {
   string name;
   list<string> endpoints;
@@ -344,13 +370,14 @@ struct RGWRegion {
     DECODE_FINISH(bl);
   }
 
-  string get_pool_name(CephContext *cct);
-  int init(CephContext *_cct, RGWRados *_store);
+  int init(CephContext *_cct, RGWRados *_store, bool setup_region = true);
   int create_default();
   int store_info(bool exclusive);
-  int read_default();
+  int read_default(RGWDefaultRegionInfo& default_region);
   int set_as_default();
 
+  static string get_pool_name(CephContext *cct);
+
   void dump(Formatter *f) const;
   void decode_json(JSONObj *obj);
 };
@@ -512,6 +539,8 @@ public:
     }
   }
 
+  int list_regions(list<string>& regions);
+
   void tick();
 
   CephContext *ctx() { return cct; }
@@ -915,6 +944,10 @@ public:
   int pool_iterate(RGWPoolIterCtx& ctx, uint32_t num, vector<RGWObjEnt>& objs,
                    bool *is_truncated, RGWAccessListFilter *filter);
 
+  int list_raw_objects(rgw_bucket& pool, const string& prefix_filter, int max,
+                       RGWListRawObjsCtx& ctx, vector<string>& oids,
+                       bool *is_truncated);
+
   uint64_t instance_id();
   uint64_t next_bucket_id();