From: Yehuda Sadeh Date: Mon, 9 Jan 2017 21:04:43 +0000 (-0800) Subject: rgw: new rest api to retrieve object layout X-Git-Tag: v10.2.8~47^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F14851%2Fhead;p=ceph.git rgw: new rest api to retrieve object layout Signed-off-by: Yehuda Sadeh (cherry picked from commit 2768583dc486109e49d209243675b99fdd39e92c) --- diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 645f236f3f389..e164850e0370d 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -428,7 +428,8 @@ enum RGWOpType { RGW_OP_GET_INFO, /* rgw specific */ - RGW_OP_ADMIN_SET_METADATA + RGW_OP_ADMIN_SET_METADATA, + RGW_OP_GET_OBJ_LAYOUT, }; class RGWAccessControlPolicy; diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index fca78572c4d1e..3af17ddcdecac 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -4832,6 +4832,29 @@ void RGWSetAttrs::execute() } } +void RGWGetObjLayout::pre_exec() +{ + rgw_bucket_object_pre_exec(s); +} + +void RGWGetObjLayout::execute() +{ + rgw_obj obj(s->bucket, s->object.name); + obj.set_instance(s->object.instance); + target = new RGWRados::Object(store, s->bucket_info, *static_cast(s->obj_ctx), obj); + RGWRados::Object::Read stat_op(target); + + op_ret = stat_op.prepare(NULL, NULL); + if (op_ret < 0) { + return; + } + + head_obj = stat_op.state.obj; + + op_ret = target->get_manifest(&manifest); +} + + RGWHandler::~RGWHandler() { } diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index f8875202a8e22..2ec2353534ea1 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -1615,4 +1615,32 @@ public: virtual uint32_t op_mask() { return RGW_OP_TYPE_WRITE; } }; +class RGWGetObjLayout : public RGWOp { +protected: + RGWRados::Object *target{nullptr}; + RGWObjManifest *manifest{nullptr}; + rgw_obj head_obj; + +public: + RGWGetObjLayout() { + delete target; + } + + int check_caps(RGWUserCaps& caps) { + return caps.check_cap("admin", RGW_CAP_READ); + } + int verify_permission() { + return check_caps(s->user->caps); + } + void pre_exec(); + void execute(); + + virtual void send_response() = 0; + virtual const string name() { return "get_obj_layout"; } + virtual RGWOpType get_type() { return RGW_OP_GET_OBJ_LAYOUT; } + virtual uint32_t op_mask() { return RGW_OP_TYPE_READ; } +}; + + + #endif /* CEPH_RGW_OP_H */ diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 1127906207e8c..1030bb52cf307 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -8293,6 +8293,19 @@ int RGWRados::get_obj_state(RGWObjectCtx *rctx, rgw_obj& obj, RGWObjState **stat return ret; } +int RGWRados::Object::get_manifest(RGWObjManifest **pmanifest) +{ + RGWObjState *astate; + int r = get_state(&astate, true); + if (r < 0) { + return r; + } + + *pmanifest = &astate->manifest; + + return 0; +} + int RGWRados::Object::Read::get_attr(const char *name, bufferlist& dest) { RGWObjState *state; diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 7a9ea5277cb01..6a63a03a63663 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -2223,6 +2223,7 @@ public: rgw_obj& get_obj() { return obj; } RGWObjectCtx& get_ctx() { return ctx; } RGWBucketInfo& get_bucket_info() { return bucket_info; } + int get_manifest(RGWObjManifest **pmanifest); int get_bucket_shard(BucketShard **pbs) { if (!bs_initialized) { diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 9d83fcdec8fcb..bb4decc3e35e3 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -2860,6 +2860,38 @@ void RGWDeleteMultiObj_ObjStore_S3::end_response() rgw_flush_formatter_and_reset(s, s->formatter); } +void RGWGetObjLayout_ObjStore_S3::send_response() +{ + if (op_ret) + set_req_state_err(s, op_ret); + dump_errno(s); + end_header(s, this, "application/json"); + + JSONFormatter f; + + if (op_ret < 0) { + return; + } + + f.open_object_section("result"); + ::encode_json("head", head_obj, &f); + ::encode_json("manifest", *manifest, &f); + f.open_array_section("data_location"); + for (auto miter = manifest->obj_begin(); miter != manifest->obj_end(); ++miter) { + f.open_object_section("obj"); + rgw_obj loc = miter.get_location(); + ::encode_json("ofs", miter.get_ofs(), &f); + ::encode_json("loc", loc, &f); + ::encode_json("loc_ofs", miter.location_ofs(), &f); + ::encode_json("loc_size", miter.get_stripe_size(), &f); + f.close_section(); + rgw_flush_formatter(s, &f); + } + f.close_section(); + f.close_section(); + rgw_flush_formatter(s, &f); +} + RGWOp *RGWHandler_REST_Service_S3::op_get() { if (is_usage_op()) { @@ -2991,6 +3023,8 @@ RGWOp *RGWHandler_REST_Obj_S3::op_get() return new RGWGetACLs_ObjStore_S3; } else if (s->info.args.exists("uploadId")) { return new RGWListMultipart_ObjStore_S3; + } else if (s->info.args.exists("layout")) { + return new RGWGetObjLayout_ObjStore_S3; } return get_obj_op(true); } diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index 0f424667cc2a3..6414f667d1334 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -364,6 +364,14 @@ public: void end_response(); }; +class RGWGetObjLayout_ObjStore_S3 : public RGWGetObjLayout { +public: + RGWGetObjLayout_ObjStore_S3() {} + ~RGWGetObjLayout_ObjStore_S3() {} + + void send_response(); +}; + class RGW_Auth_S3_Keystone_ValidateToken : public RGWHTTPClient { private: bufferlist rx_buffer;