]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_admin.cc: Allow for deletion of objects through radosgw-admin.
authorcaleb miles <caleb.miles@inktank.com>
Thu, 9 Aug 2012 16:55:27 +0000 (09:55 -0700)
committercaleb miles <caleb.miles@inktank.com>
Thu, 9 Aug 2012 16:55:27 +0000 (09:55 -0700)
Allow objects to be deleted through radosgw-admin with an optional flag
to delete the tail of that object during the processing of the intent log.

Signed-off-by: caleb miles <caleb.miles@inktank.com>
doc/man/8/radosgw-admin.rst
src/rgw/rgw_admin.cc
src/rgw/rgw_log.cc
src/rgw/rgw_log.h
src/test/cli/radosgw-admin/help.t

index 545239087d3b9e33e5980675e8ff0f7951c8a416..a3f9b309c047309ab0b877adea14700b9904698d 100644 (file)
@@ -50,6 +50,9 @@ Commands
 :command:`bucket unlink`
   Remove a bucket
 
+:command:'object rm'
+  Remove an object
+
 :command:`key create`
   Create an access key
 
@@ -122,6 +125,10 @@ Options
 
    The librados auid
 
+.. option:: --lazy-remove
+
+   Defer removal of object tail
+   
 
 Examples
 ========
index 1b0cf6d0e09b55e65ee15760b21b028ab7eb85c8..30845e7e28730663ec5007c5b9864b2020456498 100644 (file)
@@ -11,6 +11,7 @@ using namespace std;
 #include "common/Formatter.h"
 #include "global/global_init.h"
 #include "common/errno.h"
+#include "include/utime.h"
 
 #include "common/armor.h"
 #include "rgw_user.h"
@@ -46,6 +47,7 @@ void _usage()
   cerr << "  bucket unlink              unlink bucket from specified user\n";
   cerr << "  bucket stats               returns bucket statistics\n";
   cerr << "  bucket info                show bucket information\n";
+  cerr << "  object rm                  remove object\n";
   cerr << "  pool add                   add an existing pool for data placement\n";
   cerr << "  pool rm                    remove an existing pool from data placement set\n";
   cerr << "  pools list                 list placement active set\n";
@@ -84,6 +86,8 @@ void _usage()
   cerr << "                             user data\n";
   cerr << "   --purge-keys              when specified, subuser removal will also purge all the\n";
   cerr << "                             subuser keys\n";
+  cerr << "   --lazy-remove             defer the removal of the tail of an object until the intent\n";
+  cerr << "                             log is processed.\n";
   cerr << "   --show-log-entries=<flag> enable/disable dump of log entries on log show\n";
   cerr << "   --show-log-sum=<flag>     enable/disable dump of log summation on log show\n";
   cerr << "   --skip-zero-entries       log show only dumps entries that don't have zero value\n";
@@ -134,6 +138,7 @@ enum {
   OPT_USAGE_SHOW,
   OPT_USAGE_TRIM,
   OPT_TEMP_REMOVE,
+  OPT_OBJECT_RM,
 };
 
 static uint32_t str_to_perm(const char *str)
@@ -205,6 +210,7 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
       strcmp(cmd, "pools") == 0 ||
       strcmp(cmd, "log") == 0 ||
       strcmp(cmd, "usage") == 0 ||
+      strcmp(cmd, "object") == 0 ||
       strcmp(cmd, "temp") == 0) {
     *need_more = true;
     return 0;
@@ -276,6 +282,9 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
   } else if (strcmp(prev_cmd, "pools") == 0) {
     if (strcmp(cmd, "list") == 0)
       return OPT_POOLS_LIST;
+  } else if (strcmp(prev_cmd, "object") == 0) {
+    if (strcmp(cmd, "rm") == 0)
+      return OPT_OBJECT_RM;
   }
 
   return -EINVAL;
@@ -547,6 +556,36 @@ static void parse_date(string& date, uint64_t *epoch, string *out_date = NULL, s
   }
 }
 
+static int remove_shadow_file_now(void *user_ctx, rgw_obj& obj, RGWIntentEvent intent)
+{
+  int r = rgwstore->delete_obj(NULL,obj);
+  return r;
+}
+
+static int remove_shadow_file_eventually(void *user_ctx, rgw_obj& obj, RGWIntentEvent intent)
+{
+  int r = rgw_log_intent(obj, DEL_OBJ, ceph_clock_now(g_ceph_context),
+                         g_conf->rgw_intent_log_object_name_utc);
+
+  return r;
+}
+
+static int remove_object(rgw_bucket& bucket, std::string& object, bool delete_object_tail_later)
+{
+  int ret = -EINVAL;
+  RGWRadosCtx *rctx = new RGWRadosCtx();
+  rgw_obj obj(bucket,object);
+
+  if (delete_object_tail_later)
+    rgwstore->set_intent_cb(rctx, remove_shadow_file_eventually);
+  else
+    rgwstore->set_intent_cb(rctx, remove_shadow_file_now);
+
+  ret = rgwstore->delete_obj(rctx, obj);
+
+  return ret;
+}
+
 int main(int argc, char **argv) 
 {
   vector<const char*> args;
@@ -587,6 +626,7 @@ int main(int argc, char **argv)
   int skip_zero_entries = false;  // log show
   int purge_keys = false;
   int yes_i_really_mean_it = false;
+  int delete_object_tail_later = false;
   int max_buckets = -1;
 
   std::string val;
@@ -664,6 +704,8 @@ int main(int argc, char **argv)
       }
     } else if (ceph_argparse_witharg(args, i, &val, "--format", (char*)NULL)) {
       format = val;
+    }  else if (ceph_argparse_binary_flag(args, i, &delete_object_tail_later, NULL, "--lazy-remove", (char*)NULL)) {
+      delete_object_tail_later = true;
     } else if (ceph_argparse_binary_flag(args, i, &pretty_format, NULL, "--pretty-format", (char*)NULL)) {
       // do nothing
     } else if (ceph_argparse_binary_flag(args, i, &purge_data, NULL, "--purge-data", (char*)NULL)) {
@@ -1500,5 +1542,14 @@ next:
     }   
   }
 
+  if (opt_cmd == OPT_OBJECT_RM) {
+    int ret = remove_object(bucket, object, delete_object_tail_later);
+
+    if (ret < 0) {
+      cerr << "ERROR: object remove returned ret=" << ret << std::endl;
+      return 1;
+    }
+  }
+
   return 0;
 }
index be16f3c8ec47eb4ee3977d6693583c9247ca96a9..851427aeafe76c5f3b214d9709774fc2a169206a 100644 (file)
@@ -283,25 +283,27 @@ done:
   return ret;
 }
 
-int rgw_log_intent(struct req_state *s, rgw_obj& obj, RGWIntentEvent intent)
+int rgw_log_intent(rgw_obj& obj, RGWIntentEvent intent, const utime_t& timestamp, bool utc)
 {
   rgw_bucket intent_log_bucket(RGW_INTENT_LOG_POOL_NAME);
 
   rgw_intent_log_entry entry;
   entry.obj = obj;
   entry.intent = (uint32_t)intent;
-  entry.op_time = s->time;
+  entry.op_time = timestamp;
 
   struct tm bdt;
-  time_t t = entry.op_time.sec();
-  if (s->cct->_conf->rgw_intent_log_object_name_utc)
+  time_t t = timestamp.sec();
+  if (utc)
     gmtime_r(&t, &bdt);
   else
     localtime_r(&t, &bdt);
 
-  char buf[obj.bucket.name.size() + s->bucket.bucket_id.size() + 16];
+  struct rgw_bucket& bucket = obj.bucket;
+
+  char buf[bucket.name.size() + bucket.bucket_id.size() + 16];
   sprintf(buf, "%.4d-%.2d-%.2d-%s-%s", (bdt.tm_year+1900), (bdt.tm_mon+1), bdt.tm_mday,
-         s->bucket.bucket_id.c_str(), obj.bucket.name.c_str());
+          bucket.bucket_id.c_str(), obj.bucket.name.c_str());
   string oid(buf);
   rgw_obj log_obj(intent_log_bucket, oid);
 
@@ -321,3 +323,8 @@ int rgw_log_intent(struct req_state *s, rgw_obj& obj, RGWIntentEvent intent)
 done:
   return ret;
 }
+
+int rgw_log_intent(struct req_state *s, rgw_obj& obj, RGWIntentEvent intent)
+{
+  return rgw_log_intent(obj, intent, s->time, s->cct->_conf->rgw_intent_log_object_name_utc);
+}
index 6152708f77a8dd325e5d74c4ec63a87d7b6f7713..0738809bce0994890810c560470a72d4370ff15e 100644 (file)
@@ -118,6 +118,7 @@ struct rgw_intent_log_entry {
 WRITE_CLASS_ENCODER(rgw_intent_log_entry)
 
 int rgw_log_op(struct req_state *s);
+int rgw_log_intent(rgw_obj& obj, RGWIntentEvent intent, const utime_t& timestamp, bool utc);
 int rgw_log_intent(struct req_state *s, rgw_obj& obj, RGWIntentEvent intent);
 void rgw_log_usage_init(CephContext *cct);
 void rgw_log_usage_finalize();
index 75a18aaa455ea4e760fb34cfc74358bc9c7fb6bd..1cfa11f7720e58d6130989c5142a9f4c59777954 100644 (file)
@@ -17,6 +17,7 @@
     bucket unlink              unlink bucket from specified user
     bucket stats               returns bucket statistics
     bucket info                show bucket information
+    object rm                  remove object
     pool add                   add an existing pool for data placement
     pool rm                    remove an existing pool from data placement set
     pools list                 list placement active set
@@ -55,6 +56,8 @@
                                user data
      --purge-keys              when specified, subuser removal will also purge all the
                                subuser keys
+     --lazy-remove             defer the removal of the tail of an object until the intent
+                               log is processed.
      --show-log-entries=<flag> enable/disable dump of log entries on log show
      --show-log-sum=<flag>     enable/disable dump of log summation on log show
      --skip-zero-entries       log show only dumps entries that don't have zero value