]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw-admin: add object stat command
authorYehuda Sadeh <yehuda@inktank.com>
Wed, 17 Apr 2013 02:20:59 +0000 (19:20 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Wed, 8 May 2013 18:01:17 +0000 (11:01 -0700)
for retrieving object metadata.

Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/rgw/rgw_admin.cc

index a90200ae970404bfaa126ff50979c6cdc484c5b2..25f39222d41e54d9c327ce53577022b946a2317a 100644 (file)
@@ -177,6 +177,7 @@ enum {
   OPT_TEMP_REMOVE,
   OPT_OBJECT_RM,
   OPT_OBJECT_UNLINK,
+  OPT_OBJECT_STAT,
   OPT_GC_LIST,
   OPT_GC_PROCESS,
   OPT_REGION_INFO,
@@ -313,6 +314,8 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
       return OPT_OBJECT_RM;
     if (strcmp(cmd, "unlink") == 0)
       return OPT_OBJECT_UNLINK;
+    if (strcmp(cmd, "stat") == 0)
+      return OPT_OBJECT_STAT;
   } else if (strcmp(prev_cmd, "region") == 0) {
     if (strcmp(cmd, "info") == 0)
       return OPT_REGION_INFO;
@@ -542,6 +545,36 @@ static int parse_date_str(const string& date_str, utime_t& ut)
   return 0;
 }
 
+template <class T>
+static bool decode_dump(const char *field_name, bufferlist& bl, Formatter *f)
+{
+  T t;
+
+  bufferlist::iterator iter = bl.begin();
+
+  try {
+    ::decode(t, iter);
+  } catch (buffer::error& err) {
+    return false;
+  }
+
+  encode_json(field_name, t, f);
+
+  return true;
+}
+
+static bool dump_string(const char *field_name, bufferlist& bl, Formatter *f)
+{
+  string val;
+  if (bl.length() > 0) {
+    val.assign(bl.c_str(), bl.length());
+  }
+  f->dump_string(field_name, val);
+
+  return true;
+}
+
+
 int main(int argc, char **argv) 
 {
   vector<const char*> args;
@@ -1509,6 +1542,56 @@ next:
     }
   }
 
+  if (opt_cmd == OPT_OBJECT_STAT) {
+    int ret = init_bucket(bucket_name, bucket);
+    if (ret < 0) {
+      cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
+      return -ret;
+    }
+    rgw_obj obj(bucket, object);
+
+    void *handle;
+    uint64_t obj_size;
+    map<string, bufferlist> attrs;
+    void *obj_ctx = store->create_context(NULL);
+    ret = store->prepare_get_obj(obj_ctx, obj, NULL, NULL, &attrs, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, &obj_size, NULL, &handle, NULL);
+    store->finish_get_obj(&handle);
+    store->destroy_context(obj_ctx);
+    if (ret < 0) {
+      cerr << "ERROR: failed to stat object, returned error: " << cpp_strerror(-ret) << std::endl;
+      return 1;
+    }
+    formatter->open_object_section("object_metadata");
+    formatter->dump_string("name", object);
+    formatter->dump_unsigned("size", obj_size);
+
+    map<string, bufferlist>::iterator iter;
+    map<string, bufferlist> other_attrs;
+    for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
+      bufferlist& bl = iter->second;
+      bool handled = false;
+      if (iter->first == RGW_ATTR_MANIFEST) {
+        handled = decode_dump<RGWObjManifest>("manifest", bl, formatter);
+      } else if (iter->first == RGW_ATTR_ID_TAG) {
+        handled = dump_string("tag", bl, formatter);
+      } else if (iter->first == RGW_ATTR_ETAG) {
+        handled = dump_string("etag", bl, formatter);
+      }
+
+      if (!handled)
+        other_attrs[iter->first] = bl;
+    }
+
+    formatter->open_object_section("attrs");
+    for (iter = other_attrs.begin(); iter != other_attrs.end(); ++iter) {
+      dump_string(iter->first.c_str(), iter->second, formatter);
+    }
+    formatter->close_section();
+    formatter->close_section();
+    formatter->flush(cout);
+  }
+
   if (opt_cmd == OPT_BUCKET_CHECK) {
     RGWBucketAdminOp::check_index(store, bucket_op, f);
   }