From: caleb miles Date: Thu, 9 Aug 2012 16:55:27 +0000 (-0700) Subject: rgw_admin.cc: Allow for deletion of objects through radosgw-admin. X-Git-Tag: v0.51~24^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=cc8eac2427c745e154ad40eeb84ef28dbed99d36;p=ceph.git rgw_admin.cc: Allow for deletion of objects through radosgw-admin. 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 --- diff --git a/doc/man/8/radosgw-admin.rst b/doc/man/8/radosgw-admin.rst index 545239087d3b..a3f9b309c047 100644 --- a/doc/man/8/radosgw-admin.rst +++ b/doc/man/8/radosgw-admin.rst @@ -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 ======== diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 1b0cf6d0e09b..30845e7e2873 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -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= enable/disable dump of log entries on log show\n"; cerr << " --show-log-sum= 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 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; } diff --git a/src/rgw/rgw_log.cc b/src/rgw/rgw_log.cc index be16f3c8ec47..851427aeafe7 100644 --- a/src/rgw/rgw_log.cc +++ b/src/rgw/rgw_log.cc @@ -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); +} diff --git a/src/rgw/rgw_log.h b/src/rgw/rgw_log.h index 6152708f77a8..0738809bce09 100644 --- a/src/rgw/rgw_log.h +++ b/src/rgw/rgw_log.h @@ -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(); diff --git a/src/test/cli/radosgw-admin/help.t b/src/test/cli/radosgw-admin/help.t index 75a18aaa455e..1cfa11f7720e 100644 --- a/src/test/cli/radosgw-admin/help.t +++ b/src/test/cli/radosgw-admin/help.t @@ -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= enable/disable dump of log entries on log show --show-log-sum= enable/disable dump of log summation on log show --skip-zero-entries log show only dumps entries that don't have zero value