From 08b89a5f6a0310552fb1f3a02534f4df82b0c221 Mon Sep 17 00:00:00 2001 From: Orit Wasserman Date: Tue, 12 May 2015 12:12:03 +0200 Subject: [PATCH] rgw: introduce libradosgw This change exposes the radosgw service as a dynamic library, and also introduces a file-oriented view of the RGW corpus as a namespace (e.g., for interop with NFS clients). The change concatenates the following commits: * rgw: add rgw_file.h * rgw: add RGWLibRequest, RGWLibFrontend and RGWLibProcess * rgw: Add user command interface for librgw * user_commands * Implement gen_request * Install librgw.a * add rgw_request.cc to Makefile.am * Add empty API to librgw.h * Add rgw_file.cc * Make RGWLib a global object * Implement lookup and readdir - wip * Add rgw_rest_lib.cc * Install rgw_file.h * wip implement mount * RGWLibIO Signed-off-by: Matt Benjamin --- src/CMakeLists.txt | 6 +- src/include/Makefile.am | 6 + src/include/rados/librgw.h | 27 +++ src/include/rados/rgw_file.h | 104 ++++++++ src/rgw/Makefile.am | 1 + src/rgw/librgw.cc | 454 +++++++++++++++++++++++++++++++++++ src/rgw/rgw_common.h | 2 + src/rgw/rgw_file.cc | 145 +++++++++++ src/rgw/rgw_lib.h | 111 +++++++++ src/rgw/rgw_rest_lib.cc | 16 ++ src/rgw/rgw_rest_lib.h | 21 ++ src/rgw/rgw_user.cc | 2 +- src/rgw/rgw_user.h | 2 +- 13 files changed, 894 insertions(+), 3 deletions(-) create mode 100644 src/include/rados/rgw_file.h create mode 100644 src/rgw/rgw_file.cc create mode 100644 src/rgw/rgw_lib.h create mode 100644 src/rgw/rgw_rest_lib.cc create mode 100644 src/rgw/rgw_rest_lib.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 39f77a3934f3..da67ad80e344 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1170,11 +1170,15 @@ if(${WITH_RADOSGW}) rgw/rgw_request.cc rgw/rgw_process.cc rgw/rgw_frontend.cc + rgw/rgw_rest_lib.cc rgw/rgw_object_expirer_core.cc rgw/rgw_website.cc - rgw/rgw_xml_enc.cc) + rgw/rgw_xml_enc.cc + ) add_library(rgw_a STATIC ${rgw_a_srcs}) + set_target_properties(rgw_a PROPERTIES OUTPUT_NAME rgw) + install(TARGETS rgw_a DESTINATION lib) include_directories("${CMAKE_SOURCE_DIR}/src/civetweb/include") diff --git a/src/include/Makefile.am b/src/include/Makefile.am index 900a4c113383..1224c1ea1138 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -14,6 +14,11 @@ rados_include_DATA = \ $(srcdir)/include/crc32c.h \ $(srcdir)/include/memory.h +if WITH_RADOSGW +rados_include_DATA += \ + $(srcdir)/include/rados/librgw.h \ + $(srcdir)/include/rados/rgw_file.h +endif # WITH_RADOSGW if WITH_RBD librbd_includedir = $(includedir)/rbd @@ -110,6 +115,7 @@ noinst_HEADERS += \ include/rados/crc32c.h \ include/rados/buffer.h \ include/rados/buffer_fwd.h \ + include/rados/rgw_file.h \ include/radosstriper/libradosstriper.h \ include/radosstriper/libradosstriper.hpp \ include/rbd/features.h \ diff --git a/src/include/rados/librgw.h b/src/include/rados/librgw.h index cc2d6bdfd32c..f48b5eb23dcf 100644 --- a/src/include/rados/librgw.h +++ b/src/include/rados/librgw.h @@ -28,6 +28,33 @@ int librgw_acl_xml2bin(librgw_t rgw, const char *xml, char **bin, int *bin_len); void librgw_free_bin(librgw_t rgw, char *bin); void librgw_shutdown(librgw_t rgw); +/* librgw external interface */ +int librgw_init(); +int librgw_stop(); + +/* User interface */ +int get_userinfo_by_uid(const string& uid); +int get_user_acl(); +int set_user_permissions(); +int set_user_quota(); +int get_user_quota(); + +/* buckets */ +int get_user_buckets_list(); +int get_bucket_objects_list(); +int create_bucket(); +int delete_bucket(); +int get_bucket_attributes(); +int set_bucket_attributes(); + +/* objects */ +int create_object (); +int delete_object(); +int rgw_write(); +int rgw_read(); +int get_object_attributes(); +int set_object_attributes(); + #ifdef __cplusplus } #endif diff --git a/src/include/rados/rgw_file.h b/src/include/rados/rgw_file.h new file mode 100644 index 000000000000..2c9350bcb38e --- /dev/null +++ b/src/include/rados/rgw_file.h @@ -0,0 +1,104 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * convert RGW commands to file commands + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ +#ifndef RGW_FILE_H +#define RGW_FILE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * dynamic allocated handle to support nfs handle + * Currently we support only one instance of librgw. + * In order to support several instance we will need to include an + * instance id (16bit) + */ +struct nfs_handle +{ + uint64_t handle; +}; + +/* + get entity handle +*/ +int rgw_get_handle(const char *uri, struct nfs_handle *handle); + +/* + check handle +*/ +int rgw_check_handle(const struct nfs_handle *handle); + + int rgw_mount(const char *uid, const char *key, const char *secret, + const struct nfs_handle *handle); + +/* + create a new dirctory +*/ +int rgw_create_directory(const struct nfs_handle *parent_handle, const char *name); + +/* + create a new file +*/ + int rgw_create_file(const struct nfs_handle *parent_handle, const char* name); + + int rgw_rename(const struct nfs_handle *parent_handle, const char* old_name, const char* new_name); + +/* + remove file or directory +*/ +int rgw_unlink(const struct nfs_handle *parent_handle, const char* path); + +/* + lookup a directory or file +*/ +int rgw_lookup(const struct nfs_handle *parent_handle, const char *path, uint64_t *handle); + +/* + read directory content +*/ +int rgw_readdir(const struct nfs_handle *parent_handle, const char *path); + +int rgw_set_attributes(const struct nfs_handle *handle); + +int rgw_get_attributes(const struct nfs_handle *handle); + +int rgw_open(const struct nfs_handle *handle); + +int rgw_close(const struct nfs_handle *handle); + +int read(const struct nfs_handle *handle); + +int write(const struct nfs_handle *handle); + +int set_user_permissions(cosnt char *uid); + +int get_user_permissions(const char *uid); + +int set_dir_permissions(const struct nfs_handle *handle); + +int get_dir_permissions(const struct nfs_handle *handle); + +int set_file_permissions(const struct nfs_handle *handle); + +int get_file_permissions(const struct nfs_handle *handle); + +int acl2perm(); + +int perm2acl(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/rgw/Makefile.am b/src/rgw/Makefile.am index d2bb9ac0e494..494483b29749 100644 --- a/src/rgw/Makefile.am +++ b/src/rgw/Makefile.am @@ -105,6 +105,7 @@ radosgw_SOURCES = \ rgw/rgw_swift.cc \ rgw/rgw_swift_auth.cc \ rgw/rgw_loadgen.cc \ + rgw/rgw_rest_lib.cc \ rgw/rgw_main.cc radosgw_CFLAGS = -I$(srcdir)/civetweb/include radosgw_LDADD = $(LIBRGW) $(LIBCIVETWEB) $(LIBRGW_DEPS) $(RESOLV_LIBS) $(CEPH_GLOBAL) diff --git a/src/rgw/librgw.cc b/src/rgw/librgw.cc index f9b39aeba59e..a8dc95ecdb52 100644 --- a/src/rgw/librgw.cc +++ b/src/rgw/librgw.cc @@ -11,16 +11,39 @@ * Foundation. See file COPYING. * */ +#include +#include #include "include/types.h" #include "include/rados/librgw.h" #include "rgw/rgw_acl_s3.h" #include "rgw_acl.h" + +#include "include/str_list.h" +#include "global/global_init.h" +#include "common/config.h" +#include "common/errno.h" +#include "common/Timer.h" +#include "common/Throttle.h" +#include "common/WorkQueue.h" #include "common/ceph_argparse.h" #include "common/ceph_context.h" #include "common/common_init.h" #include "common/dout.h" +#include "rgw_rados.h" +#include "rgw_resolve.h" +#include "rgw_op.h" +#include "rgw_rest.h" +#include "rgw_frontend.h" +#include "rgw_request.h" +#include "rgw_process.h" +#include "rgw_rest_user.h" +#include "rgw_rest_s3.h" +#include "rgw_rest_lib.h" +#include "rgw_auth_s3.h" +#include "rgw_lib.h" + #include #include #include @@ -133,3 +156,434 @@ void librgw_shutdown(librgw_t rgw) { rgw->put(); } + +class C_InitTimeout : public Context { +public: + C_InitTimeout() {} + void finish(int r) { + derr << "Initialization timeout, failed to initialize" << dendl; + exit(1); + } +}; + +struct RGWLibRequest : public RGWRequest { + string method; + string resource; + int content_length; + atomic_t *fail_flag; + + RGWLibRequest(uint64_t req_id, const string& _m, const string& _r, int _cl, bool user_command, + atomic_t *_ff) : RGWRequest(req_id), method(_m), resource(_r), content_length(_cl), fail_flag(_ff) + { + s->librgw_user_command = user_command; + } +}; + +void RGWLibRequestEnv::set_date(utime_t& tm) +{ + stringstream s; + tm.asctime(s); + date_str = s.str(); +} + +int RGWLibRequestEnv::sign(RGWAccessKey& access_key) +{ + map meta_map; + map sub_resources; + + string canonical_header; + string digest; + + rgw_create_s3_canonical_header(request_method.c_str(), + NULL, /* const char *content_md5 */ + content_type.c_str(), + date_str.c_str(), + meta_map, + uri.c_str(), + sub_resources, + canonical_header); + + int ret = rgw_get_s3_header_digest(canonical_header, access_key.key, digest); + if (ret < 0) { + return ret; + } + +}; + +class RGWLibFrontend : public RGWProcessFrontend { +public: + RGWLibFrontend(RGWProcessEnv& pe, RGWFrontendConfig *_conf) : RGWProcessFrontend(pe, _conf) {} + int init(); + void gen_request(const string& method, const string& resource, int content_length, bool user_command, + atomic_t *fail_flag); +}; + +class RGWLibProcess : public RGWProcess { + RGWAccessKey access_key; +public: + RGWLibProcess(CephContext *cct, RGWProcessEnv *pe, int num_threads, RGWFrontendConfig *_conf) : + RGWProcess(cct, pe, num_threads, _conf) {} + void run(); + void checkpoint(); + void handle_request(RGWRequest *req); + void gen_request(const string& method, const string& resource, int content_length, bool user_command, + atomic_t *fail_flag); + void set_access_key(RGWAccessKey& key) { access_key = key; } +}; + + +void RGWLibProcess::checkpoint() +{ + m_tp.drain(&req_wq); +} + +void RGWLibProcess::run() +{ +} + +void RGWLibProcess::gen_request(const string& method, const string& resource, int content_length, + bool user_command, atomic_t *fail_flag) +{ + RGWLibRequest *req = new RGWLibRequest(store->get_new_req_id(), method, resource, + content_length, user_command, fail_flag); + dout(10) << "allocated request req=" << hex << req << dec << dendl; + req_throttle.get(1); + req_wq.queue(req); +} + +void RGWLibProcess::handle_request(RGWRequest *r) +{ + RGWLibRequest *req = static_cast(r); + + RGWLibRequestEnv env; + + utime_t tm = ceph_clock_now(NULL); + + env.port = 80; + env.content_length = req->content_length; + env.content_type = "binary/octet-stream"; /* TBD */ + env.request_method = req->method; + env.uri = req->resource; + env.set_date(tm); + env.sign(access_key); + + RGWLibIO client_io(&env); + + int ret = process_request(store, rest, req, &client_io, olog); + if (ret < 0) { + /* we don't really care about return code */ + dout(20) << "process_request() returned " << ret << dendl; + + } + delete req; +} + +void RGWLibFrontend::gen_request(const string& method, const string& resource, int content_length, + bool user_command, atomic_t *fail_flag) +{ + RGWLibProcess *lib_process = static_cast(pprocess); + lib_process->gen_request(method, resource, content_length, user_command, fail_flag); +} + +int RGWLib::init() +{ + int r = 0; + /* alternative default for module */ + vector def_args; + def_args.push_back("--debug-rgw=1/5"); + def_args.push_back("--keyring=$rgw_data/keyring"); + def_args.push_back("--log-file=/var/log/radosgw/$cluster-$name.log"); + + vector args; + global_init(&def_args, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_DAEMON, + CINIT_FLAG_UNPRIVILEGED_DAEMON_DEFAULTS); + + Mutex mutex("main"); + SafeTimer init_timer(g_ceph_context, mutex); + init_timer.init(); + mutex.Lock(); + init_timer.add_event_after(g_conf->rgw_init_timeout, new C_InitTimeout); + mutex.Unlock(); + + common_init_finish(g_ceph_context); + + rgw_tools_init(g_ceph_context); + + rgw_init_resolver(); + + store = RGWStoreManager::get_storage(g_ceph_context, + g_conf->rgw_enable_gc_threads, g_conf->rgw_enable_quota_threads); + + if (!store) { + mutex.Lock(); + init_timer.cancel_all_events(); + init_timer.shutdown(); + mutex.Unlock(); + + derr << "Couldn't init storage provider (RADOS)" << dendl; + return EIO; + } + + r = rgw_perf_start(g_ceph_context); + + rgw_rest_init(g_ceph_context, store->region); + + mutex.Lock(); + init_timer.cancel_all_events(); + init_timer.shutdown(); + mutex.Unlock(); + + if (r) + return 1; + + rgw_user_init(store); + rgw_bucket_init(store->meta_mgr); + rgw_log_usage_init(g_ceph_context, store); + + + mgr = new RGWRESTMgr_Lib(); + mgr->set_logging(true); + rest.register_default_mgr(mgr); + + if (!g_conf->rgw_ops_log_socket_path.empty()) { + olog = new OpsLogSocket(g_ceph_context, g_conf->rgw_ops_log_data_backlog); + olog->init(g_conf->rgw_ops_log_socket_path); + } + + int port = 80; + RGWProcessEnv env = { store, &rest, olog, port }; + + fec = new RGWFrontendConfig("librgw"); + fe = new RGWLibFrontend(env, fec); + + fe->init(); + if (r < 0) { + derr << "ERROR: failed initializing frontend" << dendl; + return -r; + } + + fe->run(); + + return 0; + +} + +int RGWLib::stop() +{ + derr << "shutting down" << dendl; + + fe->stop(); + + fe->join(); + + delete fe; + + rgw_log_usage_finalize(); + + delete olog; + + RGWStoreManager::close_storage(store); + + rgw_tools_cleanup(); + rgw_shutdown_resolver(); + + rgw_perf_stop(g_ceph_context); + + dout(1) << "final shutdown" << dendl; + g_ceph_context->put(); + + ceph::crypto::shutdown(); + + return 0; +} + +int RGWLib::get_uri(const uint64_t handle, string &uri) +{ + ceph::unordered_map::iterator i = handles_map.find(handle); + if (i != handles_map.end()) { + uri = i->second; + return 0; + } + return -1; +} + +uint64_t RGWLib::get_new_handle(const string& uri) +{ + ceph::unordered_map::iterator i = allocated_objects_handles.find(uri); + if (i != allocated_objects_handles.end()) { + return i->second; + } + + allocated_objects_handles[uri] = last_allocated_handle.inc(); + handles_map[last_allocated_handle.read()] = uri; + + return last_allocated_handle.read(); +} + +int RGWLibIO::set_uid(RGWRados *store, const rgw_user& uid) +{ + int ret = rgw_get_user_info_by_uid(store, uid, user_info, NULL); + if (ret < 0) { + derr << "ERROR: failed reading user info: uid=" << uid << " ret=" + << ret << dendl; + } + return ret; +} + +int RGWLibIO::write_data(const char *buf, int len) +{ + return len; +} + +int RGWLibIO::read_data(char *buf, int len) +{ + int read_len = MIN(left_to_read, (uint64_t)len); + left_to_read -= read_len; + return read_len; +} + +void RGWLibIO::flush() +{ +} + +int RGWLibIO::complete_request() +{ + return 0; +} + +void RGWLibIO::init_env(CephContext *cct) +{ + env.init(cct); + + left_to_read = re->content_length; + + char buf[32]; + snprintf(buf, sizeof(buf), "%lld", (long long)re->content_length); + env.set("CONTENT_LENGTH", buf); + + env.set("CONTENT_TYPE", re->content_type.c_str()); + env.set("HTTP_DATE", re->date_str.c_str()); + + for (map::iterator iter = re->headers.begin(); iter != re->headers.end(); ++iter) { + env.set(iter->first.c_str(), iter->second.c_str()); + } + + env.set("REQUEST_METHOD", re->request_method.c_str()); + env.set("REQUEST_URI", re->uri.c_str()); + env.set("QUERY_STRING", re->query_string.c_str()); + env.set("SCRIPT_URI", re->uri.c_str()); + + char port_buf[16]; + snprintf(port_buf, sizeof(port_buf), "%d", re->port); + env.set("SERVER_PORT", port_buf); +} + +int RGWLibIO::send_status(int status, const char *status_name) +{ + return 0; +} + +int RGWLibIO::send_100_continue() +{ + return 0; +} + +int RGWLibIO::complete_header() +{ + return 0; +} + +int RGWLibIO::send_content_length(uint64_t len) +{ + return 0; +} + +int RGWLib::get_userinfo_by_uid(const string& uid, RGWUserInfo &info) +{ + atomic_t failed; + + fe->gen_request("GET", uid, 4096, true, &failed); + return failed.read(); +} + +int RGWLib::get_user_acl() +{ +} + +int RGWLib::set_user_permissions() +{ +} + +int RGWLib::set_user_quota() +{ +} + +int RGWLib::get_user_quota() +{ +} + +int RGWLib::get_user_buckets_list() +{ + /* need to authanitcate first */ + atomic_t failed; + fe->gen_request("GET", "", 4096, false, &failed); + return failed.read(); + +} + +int RGWLib::get_bucket_objects_list() +{ +} + +int RGWLib::create_bucket() +{ +} + +int RGWLib::delete_bucket() +{ +} + +int RGWLib::get_bucket_attributes() +{ +} + +int RGWLib::set_bucket_attributes() +{ +} + +int RGWLib::create_object () +{ +} + +int RGWLib::delete_object() +{ +} + +int RGWLib::write() +{ +} + +int RGWLib::read() +{ +} + +int RGWLib::get_object_attributes() +{ +} + +int RGWLib::set_object_attributes() +{ +} + +/* global RGW library object */ +static RGWLib rgwlib; + +int librgw_init() +{ + return rgwlib.init(); +} + +int librgw_stop() +{ + return rgwlib.stop(); +} diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index e444f735c442..f9823397a733 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1146,6 +1146,8 @@ struct req_state { req_info info; req_init_state init_state; + bool librgw_user_command; + req_state(CephContext *_cct, class RGWEnv *e); ~req_state(); }; diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc new file mode 100644 index 000000000000..0c8e787762dc --- /dev/null +++ b/src/rgw/rgw_file.cc @@ -0,0 +1,145 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +#include "rgw_file.h" + +extern RGWLib librgw; + + +bool is_root(const string& uri) +{ + return uri.equals(""); +} + +bool is_bucket(const string& uri) +{ + int pos = req.find('/'); + return (pos < 0); +} + +/* + get generate nfs_handle +*/ +int rgw_get_handle(const char *uri, struct nfs_handle *handle) +{ + handle->handle = librgw.get_handle(uri); + return 0; +} + +/* + check nfs_handle +*/ +int rgw_check_handle(const struct nfs_handle *handle) +{ + return librgw.check_handle(handle); +} + +int rgw_mount(const char *uid, const char *key, const char *secret, + const struct nfs_handle *handle) +{ + int rc; + string uri = uid + "\"; + string auth_hdr; + map meta_map; + map sub_resources; + + rgw_create_s3_canonical_header('GET', + NULL, /* const char *content_md5 */ + 'text/html', + "", + meta_map, + urti.c_str(), + sub_resources, + auth_hdr); + + /* check key */ + rc = rgw_get_s3_header_digest(auth_hdr, key, secret); + if (rc < 0 ) { + return rc; + } + + return rgw_get_handle(uri); +} + +/* + create a new dirctory +*/ +int rgw_create_directory(const struct nfs_handle *parent_handle, const char *name) +{ + return 0; +} + +/* + create a new file +*/ +int rgw_create_file(const struct nfs_handle *parent_handle, const char* name) +{ + return 0; +} + +int rgw_rename(const struct nfs_handle *parent_handle, const char* old_name, const char* new_name) +{ + return 0; +} +/* + remove file or directory +*/ +int rgw_unlink(const struct nfs_handle *parent_handle, const char* path) +{ + return 0; +} + +/* + lookup a directory or file +*/ +int rgw_lookup(const struct nfs_handle *parent_handle, const struct nfs_handle *parent_handle, + const char *path, uint64_t *handle) +{ + string uri; + int rc; + + rc = get_uri(parent_handle, uri); + if (rc < 0 ) { /* invalid parent */ + return rc; + } + + if (is_root(uri)) { + librgw.get_bucket(uri); + } else if (is_bucket(uri)) { + /* get the object */ + } else { /* parent cannot be an object */ + return -1; + } + + uri += "/" + path; + /* find or create an handle for the object or bucket */ + *handle = librgw.get_new_handle(uri); + return 0; +} + +/* + read directory content +*/ +int rgw_readdir(const struct nfs_handle *parent_handle, const char *path) +{ + string uri; + int rc; + + rc = get_uri(parent_handle, uri); + if (rc < 0 ) { /* invalid parent */ + return rc; + } + + if (librgw.is_root(uri)) { + /* get the bucket list */ + return librgw.get_user_buckets_list(); + } else if (librgw.is_bucket(uri)) { + /* get the object list */ + return librgw.get_buckets_object_list(); + } else { /* parent cannot be an object */ + return -1; + } + + return 0; +} + + diff --git a/src/rgw/rgw_lib.h b/src/rgw/rgw_lib.h new file mode 100644 index 000000000000..29b70159a4ab --- /dev/null +++ b/src/rgw/rgw_lib.h @@ -0,0 +1,111 @@ +#ifndef RGW_LIB_H +#define RGW_LIB_H + +#include "include/unordered_map.h" +#include "rgw_common.h" +#include "rgw_client_io.h" +#include "rgw_rest.h" +#include "rgw_request.h" +#include "rgw_process.h" + + +class RGWLibFrontendConfig; +class RGWLibFrontend; +class OpsLogSocket; +class RGWREST; +class RGWRESTMgr; + +class RGWLib { + RGWFrontendConfig *fec; + RGWLibFrontend *fe; + OpsLogSocket *olog; + RGWREST rest; + RGWProcessEnv env; + RGWRados *store; + RGWRESTMgr *mgr; + ceph::unordered_map allocated_objects_handles; + ceph::unordered_map handles_map; + atomic64_t last_allocated_handle; +public: + RGWLib() {} + ~RGWLib() {} + + int init(); + int stop(); + + /* generate dynamic handle currently unique per librgw object + */ + uint64_t get_new_handle(const string& url); + + int get_uri(const uint64_t handle, string &uri); + + /* User interface */ + int get_userinfo_by_uid(const string& uid, RGWUserInfo &info); + int get_user_acl(); + int set_user_permissions(); + int set_user_quota(); + int get_user_quota(); + + /* buckets */ + int get_user_buckets_list(); + int get_bucket_objects_list(); + int create_bucket(); + int delete_bucket(); + int get_bucket_attributes(); + int set_bucket_attributes(); + + /* objects */ + int create_object (); + int delete_object(); + int write(); + int read(); + int get_object_attributes(); + int set_object_attributes(); +}; + +/* request interface */ + +struct RGWLibRequestEnv { + int port; + uint64_t content_length; + string content_type; + string request_method; + string uri; + string query_string; + string date_str; + + map headers; + + RGWLibRequestEnv() : port(0), content_length(0) {} + + void set_date(utime_t& tm); + int sign(RGWAccessKey& access_key); +}; + +class RGWLibIO : public RGWClientIO +{ + uint64_t left_to_read; + RGWLibRequestEnv *re; + RGWUserInfo user_info; +public: + RGWLibIO(RGWLibRequestEnv *_re): re(_re) {} + RGWLibIO(RGWLibRequestEnv *_re, const RGWUserInfo &_user_info) + : re(_re), user_info(_user_info) {} + + void init_env(CephContext *cct); + + int set_uid(RGWRados* store, const rgw_user& uid); + const RGWUserInfo &get_user() { return user_info; } + int write_data(const char *buf, int len); + int read_data(char *buf, int len); + + int send_status(int status, const char *status_name); + int send_100_continue(); + int complete_header(); + int complete_request(); + int send_content_length(uint64_t len); + + void flush(); +}; + +#endif diff --git a/src/rgw/rgw_rest_lib.cc b/src/rgw/rgw_rest_lib.cc new file mode 100644 index 000000000000..8ce65430c36c --- /dev/null +++ b/src/rgw/rgw_rest_lib.cc @@ -0,0 +1,16 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +#include "rgw_rest.h" +#include "rgw_rest_s3.h" +#include "rgw_rest_user.h" +#include "rgw_rest_lib.h" + + +RGWHandler *RGWRESTMgr_Lib::get_handler(struct req_state *s) +{ + if (!s->librgw_user_command) { + return new RGWHandler_ObjStore_Lib; + } + + return RGWRESTMgr_S3::get_handler(s); +} diff --git a/src/rgw/rgw_rest_lib.h b/src/rgw/rgw_rest_lib.h new file mode 100644 index 000000000000..222a73fd004c --- /dev/null +++ b/src/rgw/rgw_rest_lib.h @@ -0,0 +1,21 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_RGW_REST_LIB_H +#define CEPH_RGW_REST_LIB_H + +class RGWRESTMgr_Lib : public RGWRESTMgr_S3 { +public: + RGWRESTMgr_Lib() {} + virtual ~RGWRESTMgr_Lib() {} + virtual RGWHandler *get_handler(struct req_state *s); +}; + +class RGWHandler_ObjStore_Lib : public RGWHandler_User { + friend class RGWRestMgr_Lib; +public: + RGWHandler_ObjStore_Lib() {} + virtual ~RGWHandler_ObjStore_Lib() {} +}; + +#endif diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc index fb313d0071b4..cd27721f03c5 100644 --- a/src/rgw/rgw_user.cc +++ b/src/rgw/rgw_user.cc @@ -279,7 +279,7 @@ int rgw_get_user_info_from_index(RGWRados *store, string& key, rgw_bucket& bucke * returns: 0 on success, -ERR# on failure (including nonexistence) */ int rgw_get_user_info_by_uid(RGWRados *store, - rgw_user& uid, + const rgw_user& uid, RGWUserInfo& info, RGWObjVersionTracker *objv_tracker, time_t *pmtime, diff --git a/src/rgw/rgw_user.h b/src/rgw/rgw_user.h index bff4a52912e8..2a41ac05a39e 100644 --- a/src/rgw/rgw_user.h +++ b/src/rgw/rgw_user.h @@ -82,7 +82,7 @@ extern int rgw_store_user_attrs(RGWRados *store, * returns: 0 on success, -ERR# on failure (including nonexistence) */ extern int rgw_get_user_info_by_uid(RGWRados *store, - rgw_user& user_id, + const rgw_user& user_id, RGWUserInfo& info, RGWObjVersionTracker *objv_tracker = NULL, time_t *pmtime = NULL, -- 2.47.3