]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab ft=cpp | |
3 | ||
4 | /* | |
5 | * Ceph - scalable distributed file system | |
6 | * | |
7 | * Copyright (C) 2019 Red Hat, Inc. | |
8 | * | |
9 | * This is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU Lesser General Public | |
11 | * License version 2.1, as published by the Free Software | |
12 | * Foundation. See file COPYING. | |
13 | * | |
14 | */ | |
15 | ||
16 | #pragma once | |
17 | ||
1e59de90 TL |
18 | #include "rgw_sal_fwd.h" |
19 | #include "rgw_lua.h" | |
9f95a23c | 20 | #include "rgw_user.h" |
20effc67 TL |
21 | #include "rgw_notify_event_type.h" |
22 | #include "common/tracer.h" | |
1e59de90 TL |
23 | #include "rgw_datalog_notify.h" |
24 | #include "include/random.h" | |
9f95a23c | 25 | |
1e59de90 | 26 | class RGWRESTMgr; |
f67539c2 TL |
27 | class RGWAccessListFilter; |
28 | class RGWLC; | |
20effc67 TL |
29 | struct rgw_user_bucket; |
30 | class RGWUsageBatch; | |
31 | class RGWCoroutinesManagerRegistry; | |
20effc67 TL |
32 | class RGWBucketSyncPolicyHandler; |
33 | using RGWBucketSyncPolicyHandlerRef = std::shared_ptr<RGWBucketSyncPolicyHandler>; | |
34 | class RGWDataSyncStatusManager; | |
35 | class RGWSyncModuleInstance; | |
36 | typedef std::shared_ptr<RGWSyncModuleInstance> RGWSyncModuleInstanceRef; | |
37 | class RGWCompressionInfo; | |
1e59de90 TL |
38 | struct rgw_pubsub_topics; |
39 | struct rgw_pubsub_bucket_topics; | |
20effc67 TL |
40 | |
41 | ||
42 | using RGWBucketListNameFilter = std::function<bool (const std::string&)>; | |
43 | ||
44 | ||
45 | namespace rgw { | |
46 | class Aio; | |
47 | namespace IAM { struct Policy; } | |
48 | } | |
49 | ||
50 | class RGWGetDataCB { | |
51 | public: | |
52 | virtual int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) = 0; | |
53 | RGWGetDataCB() {} | |
54 | virtual ~RGWGetDataCB() {} | |
55 | }; | |
f67539c2 TL |
56 | |
57 | struct RGWUsageIter { | |
20effc67 | 58 | std::string read_iter; |
f67539c2 TL |
59 | uint32_t index; |
60 | ||
61 | RGWUsageIter() : index(0) {} | |
62 | }; | |
63 | ||
64 | /** | |
65 | * @struct RGWClusterStat | |
66 | * Cluster-wide usage information | |
67 | */ | |
68 | struct RGWClusterStat { | |
69 | /// total device size | |
70 | uint64_t kb; | |
71 | /// total used | |
72 | uint64_t kb_used; | |
73 | /// total available/free | |
74 | uint64_t kb_avail; | |
75 | /// number of objects | |
76 | uint64_t num_objects; | |
77 | }; | |
78 | ||
20effc67 TL |
79 | class RGWGetBucketStats_CB : public RefCountedObject { |
80 | protected: | |
81 | rgw_bucket bucket; | |
82 | std::map<RGWObjCategory, RGWStorageStats>* stats; | |
83 | public: | |
84 | explicit RGWGetBucketStats_CB(const rgw_bucket& _bucket) : bucket(_bucket), stats(NULL) {} | |
85 | ~RGWGetBucketStats_CB() override {} | |
86 | virtual void handle_response(int r) = 0; | |
87 | virtual void set_response(std::map<RGWObjCategory, RGWStorageStats>* _stats) { | |
88 | stats = _stats; | |
89 | } | |
90 | }; | |
91 | ||
92 | class RGWGetUserStats_CB : public RefCountedObject { | |
93 | protected: | |
94 | rgw_user user; | |
95 | RGWStorageStats stats; | |
96 | public: | |
97 | explicit RGWGetUserStats_CB(const rgw_user& _user) : user(_user) {} | |
98 | ~RGWGetUserStats_CB() override {} | |
99 | virtual void handle_response(int r) = 0; | |
100 | virtual void set_response(RGWStorageStats& _stats) { | |
101 | stats = _stats; | |
102 | } | |
103 | }; | |
104 | ||
1e59de90 TL |
105 | struct RGWObjState { |
106 | rgw_obj obj; | |
107 | bool is_atomic{false}; | |
108 | bool has_attrs{false}; | |
109 | bool exists{false}; | |
110 | uint64_t size{0}; //< size of raw object | |
111 | uint64_t accounted_size{0}; //< size before compression, encryption | |
112 | ceph::real_time mtime; | |
113 | uint64_t epoch{0}; | |
114 | bufferlist obj_tag; | |
115 | bufferlist tail_tag; | |
116 | std::string write_tag; | |
117 | bool fake_tag{false}; | |
118 | std::string shadow_obj; | |
119 | bool has_data{false}; | |
120 | bufferlist data; | |
121 | bool prefetch_data{false}; | |
122 | bool keep_tail{false}; | |
123 | bool is_olh{false}; | |
124 | bufferlist olh_tag; | |
125 | uint64_t pg_ver{false}; | |
126 | uint32_t zone_short_id{0}; | |
127 | bool compressed{false}; | |
128 | ||
129 | /* important! don't forget to update copy constructor */ | |
130 | ||
131 | RGWObjVersionTracker objv_tracker; | |
132 | ||
133 | std::map<std::string, ceph::buffer::list> attrset; | |
134 | ||
135 | RGWObjState(); | |
136 | RGWObjState(const RGWObjState& rhs); | |
137 | ~RGWObjState(); | |
138 | ||
139 | bool get_attr(std::string name, bufferlist& dest) { | |
140 | auto iter = attrset.find(name); | |
141 | if (iter != attrset.end()) { | |
142 | dest = iter->second; | |
143 | return true; | |
144 | } | |
145 | return false; | |
146 | } | |
147 | }; | |
148 | ||
20effc67 TL |
149 | /** |
150 | * @defgroup RGWSAL RGW Store Abstraction Layer | |
151 | * | |
152 | * The Store Abstraction Layer is an API that separates the top layer of RGW that | |
153 | * handles client protocols (such as S3 or Swift) from the bottom layer of RGW that | |
154 | * interacts with a backing store. It allows the creation of multiple backing stores | |
155 | * that can co-exist with a single RGW instance, and allows the creation of stacking | |
156 | * layers of translators that can modify operations as they pass down the stack. | |
157 | * Examples of translators might be a cache layer, a duplication layer that copies | |
158 | * operations to multiple stores, or a policy layer that sends some operations to one | |
159 | * store and some to another. | |
160 | * | |
161 | * The basic unit of a SAL implementation is the Store. Whether an actual backing store | |
162 | * or a translator, there will be a Store implementation that represents it. Examples | |
163 | * are the RadosStore that communicates via RADOS with a Ceph cluster, and the DBStore | |
164 | * that uses a SQL db (such as SQLite3) as a backing store. There is a singleton | |
165 | * instance of each Store. | |
166 | * | |
167 | * Data within RGW is owned by a User. The User is the unit of authentication and | |
168 | * access control. | |
169 | * | |
170 | * Data within RGW is stored as an Object. Each Object is a single chunk of data, owned | |
171 | * by a single User, contained within a single Bucket. It has metadata associated with | |
1e59de90 | 172 | * it, such as size, owner, and so on, and a set of key-value attributes that can |
20effc67 TL |
173 | * contain anything needed by the top half. |
174 | * | |
175 | * Data with RGW is organized into Buckets. Each Bucket is owned by a User, and | |
176 | * contains Objects. There is a single, flat layer of Buckets, there is no hierarchy, | |
177 | * and each Object is contained in a single Bucket. | |
178 | * | |
179 | * Instantiations of SAL classes are done as unique pointers, using std::unique_ptr. | |
180 | * Instances of these classes are acquired via getters, and it's up to the caller to | |
181 | * manage the lifetime. | |
182 | * | |
183 | * @note Anything using RGWObjContext is subject to change, as that type will not be | |
184 | * used in the final API. | |
185 | * @{ | |
186 | */ | |
187 | ||
188 | /** | |
189 | * @file rgw_sal.h | |
190 | * @brief Base abstractions and API for SAL | |
191 | */ | |
f67539c2 | 192 | |
9f95a23c TL |
193 | namespace rgw { namespace sal { |
194 | ||
20effc67 TL |
195 | /** |
196 | * @addtogroup RGWSAL | |
197 | * @{ | |
198 | */ | |
199 | ||
9f95a23c TL |
200 | #define RGW_SAL_VERSION 1 |
201 | ||
f67539c2 | 202 | struct MPSerializer; |
20effc67 | 203 | class GCChain; |
20effc67 TL |
204 | class RGWOIDCProvider; |
205 | class RGWRole; | |
9f95a23c | 206 | |
f67539c2 TL |
207 | enum AttrsMod { |
208 | ATTRSMOD_NONE = 0, | |
209 | ATTRSMOD_REPLACE = 1, | |
210 | ATTRSMOD_MERGE = 2 | |
211 | }; | |
9f95a23c | 212 | |
f38dd50b TL |
213 | static constexpr uint32_t FLAG_LOG_OP = 0x0001; |
214 | static constexpr uint32_t FLAG_PREVENT_VERSIONING = 0x0002; | |
215 | ||
20effc67 TL |
216 | // a simple streaming data processing abstraction |
217 | /** | |
218 | * @brief A simple streaming data processing abstraction | |
219 | */ | |
220 | class DataProcessor { | |
221 | public: | |
222 | virtual ~DataProcessor() {} | |
223 | ||
224 | /** | |
225 | * @brief Consume a bufferlist in its entirety at the given object offset. | |
226 | * | |
227 | * An empty bufferlist is given to request that any buffered data be flushed, though this doesn't | |
228 | * wait for completions | |
229 | */ | |
230 | virtual int process(bufferlist&& data, uint64_t offset) = 0; | |
231 | }; | |
232 | ||
233 | /** | |
234 | * @brief a data consumer that writes an object in a bucket | |
235 | */ | |
236 | class ObjectProcessor : public DataProcessor { | |
237 | public: | |
238 | /** prepare to start processing object data */ | |
239 | virtual int prepare(optional_yield y) = 0; | |
240 | ||
241 | /** complete the operation and make its result visible to clients */ | |
242 | virtual int complete(size_t accounted_size, const std::string& etag, | |
243 | ceph::real_time *mtime, ceph::real_time set_mtime, | |
244 | std::map<std::string, bufferlist>& attrs, | |
245 | ceph::real_time delete_at, | |
246 | const char *if_match, const char *if_nomatch, | |
247 | const std::string *user_data, | |
248 | rgw_zone_set *zones_trace, bool *canceled, | |
f38dd50b TL |
249 | optional_yield y, |
250 | uint32_t flags) = 0; | |
20effc67 | 251 | }; |
f67539c2 | 252 | |
20effc67 TL |
253 | /** Base class for AIO completions */ |
254 | class Completions { | |
9f95a23c | 255 | public: |
20effc67 TL |
256 | Completions() {} |
257 | virtual ~Completions() = default; | |
258 | virtual int drain() = 0; | |
259 | }; | |
260 | ||
261 | /** A list of key-value attributes */ | |
1e59de90 | 262 | using Attrs = std::map<std::string, ceph::buffer::list>; |
20effc67 TL |
263 | |
264 | /** | |
1e59de90 | 265 | * @brief Base singleton representing a Store or Filter |
20effc67 | 266 | * |
1e59de90 | 267 | * The Driver is the base abstraction of the SAL layer. It represents a base storage |
20effc67 | 268 | * mechanism, or a intermediate stacking layer. There is a single instance of a given |
1e59de90 | 269 | * Driver per RGW, and this Driver mediates all access to it's backing. |
20effc67 | 270 | * |
1e59de90 | 271 | * A Driver contains, loosely, @a User, @a Bucket, and @a Object entities. The @a Object |
20effc67 TL |
272 | * contains data, and it's associated metadata. The @a Bucket contains Objects, and |
273 | * metadata about the bucket. Both Buckets and Objects are owned by a @a User, which is | |
274 | * the basic unit of access control. | |
275 | * | |
1e59de90 | 276 | * A Driver also has metadata and some global responsibilities. For example, a driver is |
20effc67 TL |
277 | * responsible for managing the LifeCycle activities for it's data. |
278 | */ | |
1e59de90 | 279 | class Driver { |
20effc67 | 280 | public: |
1e59de90 TL |
281 | Driver() {} |
282 | virtual ~Driver() = default; | |
20effc67 | 283 | |
1e59de90 TL |
284 | /** Post-creation initialization of driver */ |
285 | virtual int initialize(CephContext *cct, const DoutPrefixProvider *dpp) = 0; | |
286 | /** Name of this driver provider (e.g., "rados") */ | |
287 | virtual const std::string get_name() const = 0; | |
20effc67 TL |
288 | /** Get cluster unique identifier */ |
289 | virtual std::string get_cluster_id(const DoutPrefixProvider* dpp, optional_yield y) = 0; | |
1e59de90 | 290 | /** Get a User from a rgw_user. Does not query driver for user info, so quick */ |
20effc67 | 291 | virtual std::unique_ptr<User> get_user(const rgw_user& u) = 0; |
1e59de90 | 292 | /** Lookup a User by access key. Queries driver for user info. */ |
20effc67 | 293 | virtual int get_user_by_access_key(const DoutPrefixProvider* dpp, const std::string& key, optional_yield y, std::unique_ptr<User>* user) = 0; |
1e59de90 | 294 | /** Lookup a User by email address. Queries driver for user info. */ |
20effc67 | 295 | virtual int get_user_by_email(const DoutPrefixProvider* dpp, const std::string& email, optional_yield y, std::unique_ptr<User>* user) = 0; |
1e59de90 | 296 | /** Lookup a User by swift username. Queries driver for user info. */ |
20effc67 TL |
297 | virtual int get_user_by_swift(const DoutPrefixProvider* dpp, const std::string& user_str, optional_yield y, std::unique_ptr<User>* user) = 0; |
298 | /** Get a basic Object. This Object is not looked up, and is incomplete, since is | |
299 | * does not have a bucket. This should only be used when an Object is needed before | |
300 | * there is a Bucket, otherwise use the get_object() in the Bucket class. */ | |
301 | virtual std::unique_ptr<Object> get_object(const rgw_obj_key& k) = 0; | |
1e59de90 | 302 | /** Get a Bucket by info. Does not query the driver, just uses the give bucket info. */ |
20effc67 | 303 | virtual int get_bucket(User* u, const RGWBucketInfo& i, std::unique_ptr<Bucket>* bucket) = 0; |
1e59de90 | 304 | /** Lookup a Bucket by key. Queries driver for bucket info. */ |
20effc67 | 305 | virtual int get_bucket(const DoutPrefixProvider* dpp, User* u, const rgw_bucket& b, std::unique_ptr<Bucket>* bucket, optional_yield y) = 0; |
1e59de90 | 306 | /** Lookup a Bucket by name. Queries driver for bucket info. */ |
20effc67 | 307 | virtual int get_bucket(const DoutPrefixProvider* dpp, User* u, const std::string& tenant, const std::string& name, std::unique_ptr<Bucket>* bucket, optional_yield y) = 0; |
1e59de90 | 308 | /** For multisite, this driver is the zone's master */ |
f67539c2 | 309 | virtual bool is_meta_master() = 0; |
20effc67 TL |
310 | /** For multisite, forward an OP to the zone's master */ |
311 | virtual int forward_request_to_master(const DoutPrefixProvider *dpp, User* user, obj_version* objv, | |
312 | bufferlist& in_data, JSONParser* jp, req_info& info, | |
f67539c2 | 313 | optional_yield y) = 0; |
39ae355f TL |
314 | virtual int forward_iam_request_to_master(const DoutPrefixProvider *dpp, const RGWAccessKey& key, obj_version* objv, |
315 | bufferlist& in_data, | |
316 | RGWXMLDecoder::XMLParser* parser, req_info& info, | |
317 | optional_yield y) = 0; | |
1e59de90 | 318 | /** Get zone info for this driver */ |
20effc67 TL |
319 | virtual Zone* get_zone() = 0; |
320 | /** Get a unique ID specific to this zone. */ | |
321 | virtual std::string zone_unique_id(uint64_t unique_num) = 0; | |
322 | /** Get a unique Swift transaction ID specific to this zone */ | |
323 | virtual std::string zone_unique_trans_id(const uint64_t unique_num) = 0; | |
1e59de90 TL |
324 | /** Lookup a zonegroup by ID */ |
325 | virtual int get_zonegroup(const std::string& id, std::unique_ptr<ZoneGroup>* zonegroup) = 0; | |
326 | /** List all zones in all zone groups by ID */ | |
327 | virtual int list_all_zones(const DoutPrefixProvider* dpp, std::list<std::string>& zone_ids) = 0; | |
328 | /** Get statistics about the cluster represented by this driver */ | |
f67539c2 | 329 | virtual int cluster_stat(RGWClusterStat& stats) = 0; |
20effc67 | 330 | /** Get a @a Lifecycle object. Used to manage/run lifecycle transitions */ |
f67539c2 | 331 | virtual std::unique_ptr<Lifecycle> get_lifecycle(void) = 0; |
20effc67 TL |
332 | /** Get a @a Completions object. Used for Async I/O tracking */ |
333 | virtual std::unique_ptr<Completions> get_completions(void) = 0; | |
334 | ||
335 | /** Get a @a Notification object. Used to communicate with non-RGW daemons, such as | |
336 | * management/tracking software */ | |
337 | /** RGWOp variant */ | |
1e59de90 TL |
338 | virtual std::unique_ptr<Notification> get_notification(rgw::sal::Object* obj, rgw::sal::Object* src_obj, req_state* s, |
339 | rgw::notify::EventType event_type, optional_yield y, const std::string* object_name=nullptr) = 0; | |
20effc67 TL |
340 | /** No-req_state variant (e.g., rgwlc) */ |
341 | virtual std::unique_ptr<Notification> get_notification( | |
1e59de90 | 342 | const DoutPrefixProvider* dpp, rgw::sal::Object* obj, rgw::sal::Object* src_obj, |
20effc67 TL |
343 | rgw::notify::EventType event_type, rgw::sal::Bucket* _bucket, std::string& _user_id, std::string& _user_tenant, |
344 | std::string& _req_id, optional_yield y) = 0; | |
1e59de90 TL |
345 | /** Read the topic config entry into @a data and (optionally) @a objv_tracker */ |
346 | virtual int read_topics(const std::string& tenant, rgw_pubsub_topics& topics, RGWObjVersionTracker* objv_tracker, | |
347 | optional_yield y, const DoutPrefixProvider *dpp) = 0; | |
348 | /** Write @a info and (optionally) @a objv_tracker into the config */ | |
349 | virtual int write_topics(const std::string& tenant, const rgw_pubsub_topics& topics, RGWObjVersionTracker* objv_tracker, | |
350 | optional_yield y, const DoutPrefixProvider *dpp) = 0; | |
351 | /** Remove the topic config, optionally a specific version */ | |
352 | virtual int remove_topics(const std::string& tenant, RGWObjVersionTracker* objv_tracker, | |
353 | optional_yield y,const DoutPrefixProvider *dpp) = 0; | |
20effc67 | 354 | /** Get access to the lifecycle management thread */ |
f67539c2 | 355 | virtual RGWLC* get_rgwlc(void) = 0; |
20effc67 TL |
356 | /** Get access to the coroutine registry. Used to create new coroutine managers */ |
357 | virtual RGWCoroutinesManagerRegistry* get_cr_registry() = 0; | |
358 | ||
1e59de90 | 359 | /** Log usage data to the driver. Usage data is things like bytes sent/received and |
20effc67 TL |
360 | * op count */ |
361 | virtual int log_usage(const DoutPrefixProvider *dpp, std::map<rgw_user_bucket, RGWUsageBatch>& usage_info) = 0; | |
1e59de90 | 362 | /** Log OP data to the driver. Data is opaque to SAL */ |
20effc67 | 363 | virtual int log_op(const DoutPrefixProvider *dpp, std::string& oid, bufferlist& bl) = 0; |
1e59de90 | 364 | /** Register this driver to the service map. Somewhat Rados specific; may be removed*/ |
20effc67 TL |
365 | virtual int register_to_service_map(const DoutPrefixProvider *dpp, const std::string& daemon_type, |
366 | const std::map<std::string, std::string>& meta) = 0; | |
367 | /** Get default quota info. Used as fallback if a user or bucket has no quota set*/ | |
1e59de90 | 368 | virtual void get_quota(RGWQuota& quota) = 0; |
20effc67 TL |
369 | /** Get global rate limit configuration*/ |
370 | virtual void get_ratelimit(RGWRateLimitInfo& bucket_ratelimit, RGWRateLimitInfo& user_ratelimit, RGWRateLimitInfo& anon_ratelimit) = 0; | |
371 | /** Enable or disable a set of bucket. e.g. if a User is suspended */ | |
372 | virtual int set_buckets_enabled(const DoutPrefixProvider* dpp, std::vector<rgw_bucket>& buckets, bool enabled) = 0; | |
373 | /** Get a new request ID */ | |
374 | virtual uint64_t get_new_req_id() = 0; | |
375 | /** Get a handler for bucket sync policy. */ | |
376 | virtual int get_sync_policy_handler(const DoutPrefixProvider* dpp, | |
377 | std::optional<rgw_zone_id> zone, | |
378 | std::optional<rgw_bucket> bucket, | |
379 | RGWBucketSyncPolicyHandlerRef* phandler, | |
380 | optional_yield y) = 0; | |
381 | /** Get a status manager for bucket sync */ | |
382 | virtual RGWDataSyncStatusManager* get_data_sync_manager(const rgw_zone_id& source_zone) = 0; | |
383 | /** Wake up sync threads for bucket metadata sync */ | |
384 | virtual void wakeup_meta_sync_shards(std::set<int>& shard_ids) = 0; | |
385 | /** Wake up sync threads for bucket data sync */ | |
1e59de90 | 386 | virtual void wakeup_data_sync_shards(const DoutPrefixProvider *dpp, const rgw_zone_id& source_zone, boost::container::flat_map<int, boost::container::flat_set<rgw_data_notify_entry>>& shard_ids) = 0; |
20effc67 TL |
387 | /** Clear all usage statistics globally */ |
388 | virtual int clear_usage(const DoutPrefixProvider *dpp) = 0; | |
389 | /** Get usage statistics for all users and buckets */ | |
390 | virtual int read_all_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch, | |
391 | uint32_t max_entries, bool* is_truncated, | |
392 | RGWUsageIter& usage_iter, | |
393 | std::map<rgw_user_bucket, rgw_usage_log_entry>& usage) = 0; | |
394 | /** Trim usage log for all users and buckets */ | |
395 | virtual int trim_all_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) = 0; | |
396 | /** Get a configuration value for the given name */ | |
397 | virtual int get_config_key_val(std::string name, bufferlist* bl) = 0; | |
398 | /** Start a metadata listing of the given section */ | |
399 | virtual int meta_list_keys_init(const DoutPrefixProvider *dpp, const std::string& section, const std::string& marker, void** phandle) = 0; | |
400 | /** Get the next key from a metadata list */ | |
401 | virtual int meta_list_keys_next(const DoutPrefixProvider *dpp, void* handle, int max, std::list<std::string>& keys, bool* truncated) = 0; | |
402 | /** Complete a metadata listing */ | |
403 | virtual void meta_list_keys_complete(void* handle) = 0; | |
404 | /** Get the marker associated with the current metadata listing */ | |
405 | virtual std::string meta_get_marker(void* handle) = 0; | |
406 | /** Remove a specific metadata key */ | |
407 | virtual int meta_remove(const DoutPrefixProvider* dpp, std::string& metadata_key, optional_yield y) = 0; | |
408 | /** Get an instance of the Sync module for bucket sync */ | |
409 | virtual const RGWSyncModuleInstanceRef& get_sync_module() = 0; | |
410 | /** Get the ID of the current host */ | |
411 | virtual std::string get_host_id() = 0; | |
412 | /** Get a Lua script manager for running lua scripts */ | |
1e59de90 | 413 | virtual std::unique_ptr<LuaManager> get_lua_manager() = 0; |
20effc67 TL |
414 | /** Get an IAM Role by name etc. */ |
415 | virtual std::unique_ptr<RGWRole> get_role(std::string name, | |
416 | std::string tenant, | |
417 | std::string path="", | |
418 | std::string trust_policy="", | |
419 | std::string max_session_duration_str="", | |
420 | std::multimap<std::string,std::string> tags={}) = 0; | |
421 | /** Get an IAM Role by ID */ | |
422 | virtual std::unique_ptr<RGWRole> get_role(std::string id) = 0; | |
39ae355f | 423 | virtual std::unique_ptr<RGWRole> get_role(const RGWRoleInfo& info) = 0; |
20effc67 TL |
424 | /** Get all IAM Roles optionally filtered by path */ |
425 | virtual int get_roles(const DoutPrefixProvider *dpp, | |
426 | optional_yield y, | |
427 | const std::string& path_prefix, | |
428 | const std::string& tenant, | |
429 | std::vector<std::unique_ptr<RGWRole>>& roles) = 0; | |
430 | /** Get an empty Open ID Connector provider */ | |
431 | virtual std::unique_ptr<RGWOIDCProvider> get_oidc_provider() = 0; | |
432 | /** Get all Open ID Connector providers, optionally filtered by tenant */ | |
433 | virtual int get_oidc_providers(const DoutPrefixProvider *dpp, | |
434 | const std::string& tenant, | |
435 | std::vector<std::unique_ptr<RGWOIDCProvider>>& providers) = 0; | |
436 | /** Get a Writer that appends to an object */ | |
437 | virtual std::unique_ptr<Writer> get_append_writer(const DoutPrefixProvider *dpp, | |
438 | optional_yield y, | |
1e59de90 TL |
439 | rgw::sal::Object* obj, |
440 | const rgw_user& owner, | |
20effc67 TL |
441 | const rgw_placement_rule *ptail_placement_rule, |
442 | const std::string& unique_tag, | |
443 | uint64_t position, | |
444 | uint64_t *cur_accounted_size) = 0; | |
445 | /** Get a Writer that atomically writes an entire object */ | |
446 | virtual std::unique_ptr<Writer> get_atomic_writer(const DoutPrefixProvider *dpp, | |
447 | optional_yield y, | |
1e59de90 TL |
448 | rgw::sal::Object* obj, |
449 | const rgw_user& owner, | |
20effc67 TL |
450 | const rgw_placement_rule *ptail_placement_rule, |
451 | uint64_t olh_epoch, | |
452 | const std::string& unique_tag) = 0; | |
453 | ||
1e59de90 TL |
454 | /** Get the compression type of a placement rule */ |
455 | virtual const std::string& get_compression_type(const rgw_placement_rule& rule) = 0; | |
456 | /** Check to see if this placement rule is valid */ | |
457 | virtual bool valid_placement(const rgw_placement_rule& rule) = 0; | |
458 | ||
459 | /** Clean up a driver for termination */ | |
20effc67 TL |
460 | virtual void finalize(void) = 0; |
461 | ||
1e59de90 | 462 | /** Get the Ceph context associated with this driver. May be removed. */ |
20effc67 | 463 | virtual CephContext* ctx(void) = 0; |
1e59de90 TL |
464 | |
465 | /** Register admin APIs unique to this driver */ | |
466 | virtual void register_admin_apis(RGWRESTMgr* mgr) = 0; | |
9f95a23c TL |
467 | }; |
468 | ||
20effc67 TL |
469 | /** |
470 | * @brief User abstraction | |
471 | * | |
472 | * This represents a user. In general, there will be a @a User associated with an OP | |
473 | * (the user performing the OP), and potentially several others acting as owners. | |
474 | * Lifetime of a User is a bit tricky , since it must last as long as any Buckets | |
475 | * associated with it. A User has associated metadata, including a set of key/value | |
476 | * attributes, and statistics (including usage) about the User. | |
477 | */ | |
478 | class User { | |
9f95a23c | 479 | public: |
1e59de90 | 480 | User() {} |
20effc67 TL |
481 | virtual ~User() = default; |
482 | ||
483 | /** Clone a copy of this user. Used when modification is necessary of the copy */ | |
484 | virtual std::unique_ptr<User> clone() = 0; | |
485 | /** List the buckets owned by a user */ | |
486 | virtual int list_buckets(const DoutPrefixProvider* dpp, | |
487 | const std::string& marker, const std::string& end_marker, | |
488 | uint64_t max, bool need_stats, BucketList& buckets, | |
f67539c2 | 489 | optional_yield y) = 0; |
20effc67 TL |
490 | /** Create a new bucket owned by this user. Creates in the backing store, not just the instantiation. */ |
491 | virtual int create_bucket(const DoutPrefixProvider* dpp, | |
492 | const rgw_bucket& b, | |
493 | const std::string& zonegroup_id, | |
494 | rgw_placement_rule& placement_rule, | |
495 | std::string& swift_ver_location, | |
496 | const RGWQuotaInfo* pquota_info, | |
497 | const RGWAccessControlPolicy& policy, | |
498 | Attrs& attrs, | |
499 | RGWBucketInfo& info, | |
500 | obj_version& ep_objv, | |
501 | bool exclusive, | |
502 | bool obj_lock_enabled, | |
503 | bool* existed, | |
504 | req_info& req_info, | |
505 | std::unique_ptr<Bucket>* bucket, | |
506 | optional_yield y) = 0; | |
9f95a23c | 507 | |
20effc67 | 508 | /** Get the display name for this User */ |
1e59de90 | 509 | virtual std::string& get_display_name() = 0; |
20effc67 | 510 | /** Get the tenant name for this User */ |
1e59de90 | 511 | virtual const std::string& get_tenant() = 0; |
20effc67 | 512 | /** Set the tenant name for this User */ |
1e59de90 | 513 | virtual void set_tenant(std::string& _t) = 0; |
20effc67 | 514 | /** Get the namespace for this User */ |
1e59de90 | 515 | virtual const std::string& get_ns() = 0; |
20effc67 | 516 | /** Set the namespace for this User */ |
1e59de90 | 517 | virtual void set_ns(std::string& _ns) = 0; |
20effc67 | 518 | /** Clear the namespace for this User */ |
1e59de90 | 519 | virtual void clear_ns() = 0; |
20effc67 | 520 | /** Get the full ID for this User */ |
1e59de90 | 521 | virtual const rgw_user& get_id() const = 0; |
20effc67 | 522 | /** Get the type of this User */ |
1e59de90 | 523 | virtual uint32_t get_type() const = 0; |
20effc67 | 524 | /** Get the maximum number of buckets allowed for this User */ |
1e59de90 | 525 | virtual int32_t get_max_buckets() const = 0; |
20effc67 | 526 | /** Get the capabilities for this User */ |
1e59de90 | 527 | virtual const RGWUserCaps& get_caps() const = 0; |
20effc67 | 528 | /** Get the version tracker for this User */ |
1e59de90 | 529 | virtual RGWObjVersionTracker& get_version_tracker() = 0; |
20effc67 | 530 | /** Get the cached attributes for this User */ |
1e59de90 | 531 | virtual Attrs& get_attrs() = 0; |
20effc67 | 532 | /** Set the cached attributes fro this User */ |
1e59de90 TL |
533 | virtual void set_attrs(Attrs& _attrs) = 0; |
534 | /** Check if a User is empty */ | |
535 | virtual bool empty() const = 0; | |
20effc67 | 536 | /** Check if a User pointer is empty */ |
1e59de90 | 537 | static bool empty(const User* u) { return (!u || u->empty()); } |
20effc67 | 538 | /** Check if a User unique_pointer is empty */ |
1e59de90 | 539 | static bool empty(const std::unique_ptr<User>& u) { return (!u || u->empty()); } |
20effc67 TL |
540 | /** Read the User attributes from the backing Store */ |
541 | virtual int read_attrs(const DoutPrefixProvider* dpp, optional_yield y) = 0; | |
542 | /** Set the attributes in attrs, leaving any other existing attrs set, and | |
543 | * write them to the backing store; a merge operation */ | |
544 | virtual int merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs& new_attrs, optional_yield y) = 0; | |
1e59de90 | 545 | /** Read the User stats from the backing Store, synchronous */ |
20effc67 TL |
546 | virtual int read_stats(const DoutPrefixProvider *dpp, |
547 | optional_yield y, RGWStorageStats* stats, | |
548 | ceph::real_time* last_stats_sync = nullptr, | |
549 | ceph::real_time* last_stats_update = nullptr) = 0; | |
550 | /** Read the User stats from the backing Store, asynchronous */ | |
551 | virtual int read_stats_async(const DoutPrefixProvider *dpp, RGWGetUserStats_CB* cb) = 0; | |
552 | /** Flush accumulated stat changes for this User to the backing store */ | |
553 | virtual int complete_flush_stats(const DoutPrefixProvider *dpp, optional_yield y) = 0; | |
554 | /** Read detailed usage stats for this User from the backing store */ | |
555 | virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, | |
556 | uint64_t end_epoch, uint32_t max_entries, | |
557 | bool* is_truncated, RGWUsageIter& usage_iter, | |
558 | std::map<rgw_user_bucket, rgw_usage_log_entry>& usage) = 0; | |
559 | /** Trim User usage stats to the given epoch range */ | |
560 | virtual int trim_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) = 0; | |
561 | ||
562 | /** Load this User from the backing store. requires ID to be set, fills all other fields. */ | |
563 | virtual int load_user(const DoutPrefixProvider* dpp, optional_yield y) = 0; | |
564 | /** Store this User to the backing store */ | |
565 | virtual int store_user(const DoutPrefixProvider* dpp, optional_yield y, bool exclusive, RGWUserInfo* old_info = nullptr) = 0; | |
566 | /** Remove this User from the backing store */ | |
567 | virtual int remove_user(const DoutPrefixProvider* dpp, optional_yield y) = 0; | |
1e59de90 TL |
568 | /** Verify multi-factor authentication for this user */ |
569 | virtual int verify_mfa(const std::string& mfa_str, bool* verified, const DoutPrefixProvider* dpp, optional_yield y) = 0; | |
9f95a23c | 570 | |
f67539c2 | 571 | /* dang temporary; will be removed when User is complete */ |
1e59de90 TL |
572 | virtual RGWUserInfo& get_info() = 0; |
573 | ||
574 | /** Print the User to @a out */ | |
575 | virtual void print(std::ostream& out) const = 0; | |
f67539c2 | 576 | |
20effc67 | 577 | friend inline std::ostream& operator<<(std::ostream& out, const User& u) { |
1e59de90 | 578 | u.print(out); |
f67539c2 TL |
579 | return out; |
580 | } | |
581 | ||
20effc67 | 582 | friend inline std::ostream& operator<<(std::ostream& out, const User* u) { |
f67539c2 TL |
583 | if (!u) |
584 | out << "<NULL>"; | |
585 | else | |
1e59de90 | 586 | u->print(out); |
f67539c2 TL |
587 | return out; |
588 | } | |
589 | ||
20effc67 | 590 | friend inline std::ostream& operator<<(std::ostream& out, const std::unique_ptr<User>& p) { |
f67539c2 TL |
591 | out << p.get(); |
592 | return out; | |
593 | } | |
9f95a23c TL |
594 | }; |
595 | ||
20effc67 TL |
596 | /** |
597 | * @brief Bucket abstraction | |
598 | * | |
599 | * This represents a bucket. A bucket is a container for objects. It is owned by a user, and has | |
600 | * it's own set of metadata, including a set of key/value attributes. A bucket may not contain | |
601 | * other buckets, only objects. Buckets have Access Control Lists (ACLs) that control what users | |
602 | * can access the contents of the bucket, and in what ways. | |
603 | */ | |
604 | class Bucket { | |
9f95a23c | 605 | public: |
f67539c2 | 606 | |
20effc67 TL |
607 | /** |
608 | * @brief Parameters for a bucket list operation | |
609 | */ | |
f67539c2 TL |
610 | struct ListParams { |
611 | std::string prefix; | |
612 | std::string delim; | |
613 | rgw_obj_key marker; | |
614 | rgw_obj_key end_marker; | |
615 | std::string ns; | |
616 | bool enforce_ns{true}; | |
20effc67 TL |
617 | RGWAccessListFilter* access_list_filter{nullptr}; |
618 | RGWBucketListNameFilter force_check_filter; | |
f67539c2 TL |
619 | bool list_versions{false}; |
620 | bool allow_unordered{false}; | |
20effc67 TL |
621 | int shard_id{RGW_NO_SHARD}; |
622 | ||
623 | friend std::ostream& operator<<(std::ostream& out, const ListParams& p) { | |
624 | out << "rgw::sal::Bucket::ListParams{ prefix=\"" << p.prefix << | |
625 | "\", delim=\"" << p.delim << | |
626 | "\", marker=\"" << p.marker << | |
627 | "\", end_marker=\"" << p.end_marker << | |
628 | "\", ns=\"" << p.ns << | |
629 | "\", enforce_ns=" << p.enforce_ns << | |
630 | ", list_versions=" << p.list_versions << | |
631 | ", allow_unordered=" << p.allow_unordered << | |
632 | ", shard_id=" << p.shard_id << | |
633 | " }"; | |
634 | return out; | |
635 | } | |
f67539c2 | 636 | }; |
20effc67 TL |
637 | /** |
638 | * @brief Results from a bucket list operation | |
639 | */ | |
f67539c2 | 640 | struct ListResults { |
20effc67 TL |
641 | std::vector<rgw_bucket_dir_entry> objs; |
642 | std::map<std::string, bool> common_prefixes; | |
f67539c2 TL |
643 | bool is_truncated{false}; |
644 | rgw_obj_key next_marker; | |
645 | }; | |
646 | ||
20effc67 | 647 | Bucket() = default; |
20effc67 TL |
648 | virtual ~Bucket() = default; |
649 | ||
650 | /** Get an @a Object belonging to this bucket */ | |
651 | virtual std::unique_ptr<Object> get_object(const rgw_obj_key& key) = 0; | |
652 | /** List the contents of this bucket */ | |
653 | virtual int list(const DoutPrefixProvider* dpp, ListParams&, int, ListResults&, optional_yield y) = 0; | |
654 | /** Get the cached attributes associated with this bucket */ | |
1e59de90 | 655 | virtual Attrs& get_attrs(void) = 0; |
20effc67 | 656 | /** Set the cached attributes on this bucket */ |
1e59de90 | 657 | virtual int set_attrs(Attrs a) = 0; |
20effc67 TL |
658 | /** Remove this bucket from the backing store */ |
659 | virtual int remove_bucket(const DoutPrefixProvider* dpp, bool delete_children, bool forward_to_master, req_info* req_info, optional_yield y) = 0; | |
660 | /** Remove this bucket, bypassing garbage collection. May be removed */ | |
661 | virtual int remove_bucket_bypass_gc(int concurrent_max, bool | |
662 | keep_index_consistent, | |
663 | optional_yield y, const | |
664 | DoutPrefixProvider *dpp) = 0; | |
665 | /** Get then ACL for this bucket */ | |
9f95a23c | 666 | virtual RGWAccessControlPolicy& get_acl(void) = 0; |
20effc67 TL |
667 | /** Set the ACL for this bucket */ |
668 | virtual int set_acl(const DoutPrefixProvider* dpp, RGWAccessControlPolicy& acl, optional_yield y) = 0; | |
669 | ||
670 | // XXXX hack | |
1e59de90 | 671 | virtual void set_owner(rgw::sal::User* _owner) = 0; |
20effc67 TL |
672 | |
673 | /** Load this bucket from the backing store. Requires the key to be set, fills other fields. | |
674 | * If @a get_stats is true, then statistics on the bucket are also looked up. */ | |
675 | virtual int load_bucket(const DoutPrefixProvider* dpp, optional_yield y, bool get_stats = false) = 0; | |
676 | /** Read the bucket stats from the backing Store, synchronous */ | |
1e59de90 TL |
677 | virtual int read_stats(const DoutPrefixProvider *dpp, |
678 | const bucket_index_layout_generation& idx_layout, | |
679 | int shard_id, std::string* bucket_ver, std::string* master_ver, | |
680 | std::map<RGWObjCategory, RGWStorageStats>& stats, | |
681 | std::string* max_marker = nullptr, | |
682 | bool* syncstopped = nullptr) = 0; | |
20effc67 | 683 | /** Read the bucket stats from the backing Store, asynchronous */ |
1e59de90 TL |
684 | virtual int read_stats_async(const DoutPrefixProvider *dpp, |
685 | const bucket_index_layout_generation& idx_layout, | |
686 | int shard_id, RGWGetBucketStats_CB* ctx) = 0; | |
20effc67 | 687 | /** Sync this bucket's stats to the owning user's stats in the backing store */ |
b3b6e05e | 688 | virtual int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y) = 0; |
20effc67 TL |
689 | /** Refresh the metadata stats (size, count, and so on) from the backing store */ |
690 | virtual int update_container_stats(const DoutPrefixProvider* dpp) = 0; | |
691 | /** Check if this bucket needs resharding, and schedule it if it does */ | |
692 | virtual int check_bucket_shards(const DoutPrefixProvider* dpp) = 0; | |
39ae355f TL |
693 | /** Change the owner of this bucket in the backing store. Current owner must be set. Does not |
694 | * change ownership of the objects in the bucket. */ | |
695 | virtual int chown(const DoutPrefixProvider* dpp, User& new_user, optional_yield y) = 0; | |
20effc67 TL |
696 | /** Store the cached bucket info into the backing store */ |
697 | virtual int put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time mtime) = 0; | |
698 | /** Check to see if the given user is the owner of this bucket */ | |
699 | virtual bool is_owner(User* user) = 0; | |
700 | /** Get the owner of this bucket */ | |
1e59de90 | 701 | virtual User* get_owner(void) = 0; |
20effc67 | 702 | /** Get the owner of this bucket in the form of an ACLOwner object */ |
1e59de90 | 703 | virtual ACLOwner get_acl_owner(void) = 0; |
20effc67 TL |
704 | /** Check in the backing store if this bucket is empty */ |
705 | virtual int check_empty(const DoutPrefixProvider* dpp, optional_yield y) = 0; | |
706 | /** Chec k if the given size fits within the quota */ | |
1e59de90 | 707 | virtual int check_quota(const DoutPrefixProvider *dpp, RGWQuota& quota, uint64_t obj_size, optional_yield y, bool check_size_only = false) = 0; |
20effc67 TL |
708 | /** Set the attributes in attrs, leaving any other existing attrs set, and |
709 | * write them to the backing store; a merge operation */ | |
710 | virtual int merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs& new_attrs, optional_yield y) = 0; | |
711 | /** Try to refresh the cached bucket info from the backing store. Used in | |
712 | * read-modify-update loop. */ | |
713 | virtual int try_refresh_info(const DoutPrefixProvider* dpp, ceph::real_time* pmtime) = 0; | |
714 | /** Read usage information about this bucket from the backing store */ | |
b3b6e05e | 715 | virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch, uint32_t max_entries, |
20effc67 TL |
716 | bool* is_truncated, RGWUsageIter& usage_iter, |
717 | std::map<rgw_user_bucket, rgw_usage_log_entry>& usage) = 0; | |
718 | /** Trim the usage information to the given epoch range */ | |
719 | virtual int trim_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) = 0; | |
720 | /** Remove objects from the bucket index of this bucket. May be removed from API */ | |
721 | virtual int remove_objs_from_index(const DoutPrefixProvider *dpp, std::list<rgw_obj_index_key>& objs_to_unlink) = 0; | |
722 | /** Check the state of the bucket index, and get stats from it. May be removed from API */ | |
723 | virtual int check_index(const DoutPrefixProvider *dpp, std::map<RGWObjCategory, RGWStorageStats>& existing_stats, std::map<RGWObjCategory, RGWStorageStats>& calculated_stats) = 0; | |
724 | /** Rebuild the bucket index. May be removed from API */ | |
725 | virtual int rebuild_index(const DoutPrefixProvider *dpp) = 0; | |
726 | /** Set a timeout on the check_index() call. May be removed from API */ | |
727 | virtual int set_tag_timeout(const DoutPrefixProvider *dpp, uint64_t timeout) = 0; | |
728 | /** Remove this specific bucket instance from the backing store. May be removed from API */ | |
729 | virtual int purge_instance(const DoutPrefixProvider* dpp) = 0; | |
730 | ||
731 | /** Check if this instantiation is empty */ | |
1e59de90 | 732 | virtual bool empty() const = 0; |
20effc67 | 733 | /** Get the cached name of this bucket */ |
1e59de90 | 734 | virtual const std::string& get_name() const = 0; |
20effc67 | 735 | /** Get the cached tenant of this bucket */ |
1e59de90 | 736 | virtual const std::string& get_tenant() const = 0; |
20effc67 | 737 | /** Get the cached marker of this bucket */ |
1e59de90 | 738 | virtual const std::string& get_marker() const = 0; |
20effc67 | 739 | /** Get the cached ID of this bucket */ |
1e59de90 | 740 | virtual const std::string& get_bucket_id() const = 0; |
20effc67 | 741 | /** Get the cached size of this bucket */ |
1e59de90 | 742 | virtual size_t get_size() const = 0; |
20effc67 | 743 | /** Get the cached rounded size of this bucket */ |
1e59de90 | 744 | virtual size_t get_size_rounded() const = 0; |
20effc67 | 745 | /** Get the cached object count of this bucket */ |
1e59de90 | 746 | virtual uint64_t get_count() const = 0; |
20effc67 | 747 | /** Get the cached placement rule of this bucket */ |
1e59de90 | 748 | virtual rgw_placement_rule& get_placement_rule() = 0; |
20effc67 | 749 | /** Get the cached creation time of this bucket */ |
1e59de90 | 750 | virtual ceph::real_time& get_creation_time() = 0; |
20effc67 | 751 | /** Get the cached modification time of this bucket */ |
1e59de90 | 752 | virtual ceph::real_time& get_modification_time() = 0; |
20effc67 | 753 | /** Get the cached version of this bucket */ |
1e59de90 | 754 | virtual obj_version& get_version() = 0; |
20effc67 | 755 | /** Set the cached version of this bucket */ |
1e59de90 | 756 | virtual void set_version(obj_version &ver) = 0; |
20effc67 | 757 | /** Check if this bucket is versioned */ |
1e59de90 | 758 | virtual bool versioned() = 0; |
20effc67 | 759 | /** Check if this bucket has versioning enabled */ |
1e59de90 | 760 | virtual bool versioning_enabled() = 0; |
9f95a23c | 761 | |
20effc67 | 762 | /** Check if a Bucket pointer is empty */ |
2a845540 TL |
763 | static bool empty(const Bucket* b) { return (!b || b->empty()); } |
764 | /** Check if a Bucket unique pointer is empty */ | |
765 | static bool empty(const std::unique_ptr<Bucket>& b) { return (!b || b->empty()); } | |
20effc67 TL |
766 | /** Clone a copy of this bucket. Used when modification is necessary of the copy */ |
767 | virtual std::unique_ptr<Bucket> clone() = 0; | |
768 | ||
769 | /** Create a multipart upload in this bucket */ | |
770 | virtual std::unique_ptr<MultipartUpload> get_multipart_upload( | |
771 | const std::string& oid, | |
772 | std::optional<std::string> upload_id=std::nullopt, | |
773 | ACLOwner owner={}, ceph::real_time mtime=real_clock::now()) = 0; | |
774 | /** List multipart uploads currently in this bucket */ | |
775 | virtual int list_multiparts(const DoutPrefixProvider *dpp, | |
776 | const std::string& prefix, | |
777 | std::string& marker, | |
778 | const std::string& delim, | |
779 | const int& max_uploads, | |
780 | std::vector<std::unique_ptr<MultipartUpload>>& uploads, | |
781 | std::map<std::string, bool> *common_prefixes, | |
782 | bool *is_truncated) = 0; | |
783 | /** Abort multipart uploads in a bucket */ | |
784 | virtual int abort_multiparts(const DoutPrefixProvider* dpp, | |
785 | CephContext* cct) = 0; | |
f67539c2 | 786 | |
1e59de90 TL |
787 | /** Read the bucket notification config into @a notifications with and (optionally) @a objv_tracker */ |
788 | virtual int read_topics(rgw_pubsub_bucket_topics& notifications, | |
789 | RGWObjVersionTracker* objv_tracker, optional_yield y, const DoutPrefixProvider *dpp) = 0; | |
790 | /** Write @a notifications with (optionally) @a objv_tracker into the bucket notification config */ | |
791 | virtual int write_topics(const rgw_pubsub_bucket_topics& notifications, RGWObjVersionTracker* objv_tracker, | |
792 | optional_yield y, const DoutPrefixProvider *dpp) = 0; | |
793 | /** Remove the bucket notification config with (optionally) @a objv_tracker */ | |
794 | virtual int remove_topics(RGWObjVersionTracker* objv_tracker, | |
795 | optional_yield y, const DoutPrefixProvider *dpp) = 0; | |
796 | ||
9f95a23c | 797 | /* dang - This is temporary, until the API is completed */ |
1e59de90 TL |
798 | virtual rgw_bucket& get_key() = 0; |
799 | virtual RGWBucketInfo& get_info() = 0; | |
800 | ||
801 | /** Print the User to @a out */ | |
802 | virtual void print(std::ostream& out) const = 0; | |
9f95a23c | 803 | |
20effc67 | 804 | friend inline std::ostream& operator<<(std::ostream& out, const Bucket& b) { |
1e59de90 | 805 | b.print(out); |
f67539c2 TL |
806 | return out; |
807 | } | |
808 | ||
20effc67 | 809 | friend inline std::ostream& operator<<(std::ostream& out, const Bucket* b) { |
f67539c2 TL |
810 | if (!b) |
811 | out << "<NULL>"; | |
812 | else | |
1e59de90 | 813 | b->print(out); |
f67539c2 TL |
814 | return out; |
815 | } | |
816 | ||
20effc67 | 817 | friend inline std::ostream& operator<<(std::ostream& out, const std::unique_ptr<Bucket>& p) { |
f67539c2 | 818 | out << p.get(); |
9f95a23c TL |
819 | return out; |
820 | } | |
821 | ||
1e59de90 TL |
822 | virtual bool operator==(const Bucket& b) const = 0; |
823 | virtual bool operator!=(const Bucket& b) const = 0; | |
9f95a23c | 824 | |
20effc67 | 825 | friend class BucketList; |
9f95a23c TL |
826 | }; |
827 | ||
20effc67 TL |
828 | /** |
829 | * @brief A list of buckets | |
830 | * | |
831 | * This is the result from a bucket listing operation. | |
832 | */ | |
833 | class BucketList { | |
834 | std::map<std::string, std::unique_ptr<Bucket>> buckets; | |
9f95a23c TL |
835 | bool truncated; |
836 | ||
837 | public: | |
20effc67 TL |
838 | BucketList() : buckets(), truncated(false) {} |
839 | BucketList(BucketList&& _bl) : | |
f67539c2 TL |
840 | buckets(std::move(_bl.buckets)), |
841 | truncated(_bl.truncated) | |
842 | { } | |
20effc67 TL |
843 | BucketList& operator=(const BucketList&) = delete; |
844 | BucketList& operator=(BucketList&& _bl) { | |
f67539c2 TL |
845 | for (auto& ent : _bl.buckets) { |
846 | buckets.emplace(ent.first, std::move(ent.second)); | |
847 | } | |
848 | truncated = _bl.truncated; | |
849 | return *this; | |
850 | }; | |
9f95a23c | 851 | |
20effc67 TL |
852 | /** Get the list of buckets. The list is a map of <bucket-name, Bucket> pairs. */ |
853 | std::map<std::string, std::unique_ptr<Bucket>>& get_buckets() { return buckets; } | |
854 | /** True if the list is truncated (that is, there are more buckets to list) */ | |
9f95a23c | 855 | bool is_truncated(void) const { return truncated; } |
20effc67 | 856 | /** Set the truncated state of the list */ |
9f95a23c | 857 | void set_truncated(bool trunc) { truncated = trunc; } |
20effc67 TL |
858 | /** Add a bucket to the list. Takes ownership of the bucket */ |
859 | void add(std::unique_ptr<Bucket> bucket) { | |
1e59de90 | 860 | buckets.emplace(bucket->get_name(), std::move(bucket)); |
9f95a23c | 861 | } |
20effc67 | 862 | /** The number of buckets in this list */ |
9f95a23c | 863 | size_t count() const { return buckets.size(); } |
20effc67 | 864 | /** Clear the list */ |
f67539c2 TL |
865 | void clear(void) { |
866 | buckets.clear(); | |
867 | truncated = false; | |
868 | } | |
869 | }; | |
9f95a23c | 870 | |
20effc67 TL |
871 | /** |
872 | * @brief Object abstraction | |
873 | * | |
874 | * This represents an Object. An Object is the basic unit of data storage. It | |
875 | * represents a blob of data, a set of metadata (such as size, owner, ACLs, etc.) and | |
876 | * a set of key/value attributes. Objects may be versioned. If a versioned object | |
877 | * is written to, a new object with the same name but a different version is created, | |
878 | * and the old version of the object is still accessible. If an unversioned object | |
879 | * is written to, it is replaced, and the old data is not accessible. | |
880 | */ | |
881 | class Object { | |
9f95a23c | 882 | public: |
f67539c2 | 883 | |
20effc67 TL |
884 | /** |
885 | * @brief Read operation on an Object | |
886 | * | |
887 | * This represents a Read operation on an Object. Read operations are optionally | |
888 | * asynchronous, using the iterate() API. | |
889 | */ | |
f67539c2 TL |
890 | struct ReadOp { |
891 | struct Params { | |
20effc67 TL |
892 | const ceph::real_time* mod_ptr{nullptr}; |
893 | const ceph::real_time* unmod_ptr{nullptr}; | |
f67539c2 TL |
894 | bool high_precision_time{false}; |
895 | uint32_t mod_zone_id{0}; | |
896 | uint64_t mod_pg_ver{0}; | |
20effc67 TL |
897 | const char* if_match{nullptr}; |
898 | const char* if_nomatch{nullptr}; | |
899 | ceph::real_time* lastmod{nullptr}; | |
900 | rgw_obj* target_obj{nullptr}; // XXX dang remove? | |
f67539c2 TL |
901 | } params; |
902 | ||
f67539c2 TL |
903 | virtual ~ReadOp() = default; |
904 | ||
20effc67 TL |
905 | /** Prepare the Read op. Must be called first */ |
906 | virtual int prepare(optional_yield y, const DoutPrefixProvider* dpp) = 0; | |
1e59de90 TL |
907 | |
908 | /** Synchronous read. Read from @a ofs to @a end (inclusive) | |
909 | * into @a bl. Length is `end - ofs + 1`. */ | |
910 | virtual int read(int64_t ofs, int64_t end, bufferlist& bl, | |
911 | optional_yield y, const DoutPrefixProvider* dpp) = 0; | |
912 | ||
913 | /** Asynchronous read. Read from @a ofs to @a end (inclusive) | |
914 | * calling @a cb on each read chunk. Length is `end - ofs + | |
915 | * 1`. */ | |
916 | virtual int iterate(const DoutPrefixProvider* dpp, int64_t ofs, | |
917 | int64_t end, RGWGetDataCB* cb, optional_yield y) = 0; | |
918 | ||
20effc67 TL |
919 | /** Get an attribute by name */ |
920 | virtual int get_attr(const DoutPrefixProvider* dpp, const char* name, bufferlist& dest, optional_yield y) = 0; | |
f67539c2 TL |
921 | }; |
922 | ||
20effc67 TL |
923 | /** |
924 | * @brief Delete operation on an Object | |
925 | * | |
926 | * This deletes an Object from the backing store. | |
927 | */ | |
928 | struct DeleteOp { | |
f67539c2 | 929 | struct Params { |
20effc67 TL |
930 | ACLOwner bucket_owner; |
931 | ACLOwner obj_owner; | |
932 | int versioning_status{0}; | |
933 | uint64_t olh_epoch{0}; | |
934 | std::string marker_version_id; | |
935 | uint32_t bilog_flags{0}; | |
936 | std::list<rgw_obj_index_key>* remove_objs{nullptr}; | |
937 | ceph::real_time expiration_time; | |
938 | ceph::real_time unmod_since; | |
939 | ceph::real_time mtime; | |
940 | bool high_precision_time{false}; | |
941 | rgw_zone_set* zones_trace{nullptr}; | |
942 | bool abortmp{false}; | |
943 | uint64_t parts_accounted_size{0}; | |
f67539c2 TL |
944 | } params; |
945 | ||
20effc67 TL |
946 | struct Result { |
947 | bool delete_marker{false}; | |
948 | std::string version_id; | |
949 | } result; | |
950 | ||
951 | virtual ~DeleteOp() = default; | |
f67539c2 | 952 | |
20effc67 | 953 | /** Delete the object */ |
f38dd50b | 954 | virtual int delete_obj(const DoutPrefixProvider* dpp, optional_yield y, uint32_t flags) = 0; |
f67539c2 TL |
955 | }; |
956 | ||
1e59de90 | 957 | Object() {} |
20effc67 | 958 | virtual ~Object() = default; |
9f95a23c | 959 | |
20effc67 TL |
960 | /** Shortcut synchronous delete call for common deletes */ |
961 | virtual int delete_object(const DoutPrefixProvider* dpp, | |
b3b6e05e | 962 | optional_yield y, |
f38dd50b | 963 | uint32_t flags) = 0; |
20effc67 TL |
964 | /** Asynchronous delete call */ |
965 | virtual int delete_obj_aio(const DoutPrefixProvider* dpp, RGWObjState* astate, Completions* aio, | |
966 | bool keep_index_consistent, optional_yield y) = 0; | |
967 | /** Copy an this object to another object. */ | |
1e59de90 | 968 | virtual int copy_object(User* user, |
20effc67 TL |
969 | req_info* info, const rgw_zone_id& source_zone, |
970 | rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket, | |
971 | rgw::sal::Bucket* src_bucket, | |
f67539c2 | 972 | const rgw_placement_rule& dest_placement, |
20effc67 TL |
973 | ceph::real_time* src_mtime, ceph::real_time* mtime, |
974 | const ceph::real_time* mod_ptr, const ceph::real_time* unmod_ptr, | |
f67539c2 | 975 | bool high_precision_time, |
20effc67 TL |
976 | const char* if_match, const char* if_nomatch, |
977 | AttrsMod attrs_mod, bool copy_if_newer, Attrs& attrs, | |
f67539c2 TL |
978 | RGWObjCategory category, uint64_t olh_epoch, |
979 | boost::optional<ceph::real_time> delete_at, | |
20effc67 TL |
980 | std::string* version_id, std::string* tag, std::string* etag, |
981 | void (*progress_cb)(off_t, void *), void* progress_data, | |
982 | const DoutPrefixProvider* dpp, optional_yield y) = 0; | |
983 | /** Get the ACL for this object */ | |
9f95a23c | 984 | virtual RGWAccessControlPolicy& get_acl(void) = 0; |
20effc67 | 985 | /** Set the ACL for this object */ |
9f95a23c | 986 | virtual int set_acl(const RGWAccessControlPolicy& acl) = 0; |
20effc67 | 987 | /** Mark further operations on this object as being atomic */ |
1e59de90 TL |
988 | virtual void set_atomic() = 0; |
989 | /** Check if this object is atomic */ | |
990 | virtual bool is_atomic() = 0; | |
20effc67 | 991 | /** Pre-fetch data when reading */ |
1e59de90 TL |
992 | virtual void set_prefetch_data() = 0; |
993 | /** Check if this object should prefetch */ | |
994 | virtual bool is_prefetch_data() = 0; | |
20effc67 | 995 | /** Mark data as compressed */ |
1e59de90 TL |
996 | virtual void set_compressed() = 0; |
997 | /** Check if this object is compressed */ | |
998 | virtual bool is_compressed() = 0; | |
999 | /** Invalidate cached info about this object, except atomic, prefetch, and | |
1000 | * compressed */ | |
1001 | virtual void invalidate() = 0; | |
20effc67 TL |
1002 | |
1003 | /** Check to see if this object has an empty key. This means it's uninitialized */ | |
1e59de90 | 1004 | virtual bool empty() const = 0; |
20effc67 | 1005 | /** Get the name of this object */ |
1e59de90 | 1006 | virtual const std::string &get_name() const = 0; |
f67539c2 | 1007 | |
20effc67 | 1008 | /** Get the object state for this object. Will be removed in the future */ |
1e59de90 | 1009 | virtual int get_obj_state(const DoutPrefixProvider* dpp, RGWObjState **state, optional_yield y, bool follow_olh = true) = 0; |
20effc67 TL |
1010 | /** Set attributes for this object from the backing store. Attrs can be set or |
1011 | * deleted. @note the attribute APIs may be revisited in the future. */ | |
1e59de90 | 1012 | virtual int set_obj_attrs(const DoutPrefixProvider* dpp, Attrs* setattrs, Attrs* delattrs, optional_yield y) = 0; |
20effc67 | 1013 | /** Get attributes for this object */ |
1e59de90 | 1014 | virtual int get_obj_attrs(optional_yield y, const DoutPrefixProvider* dpp, rgw_obj* target_obj = NULL) = 0; |
20effc67 | 1015 | /** Modify attributes for this object. */ |
1e59de90 | 1016 | virtual int modify_obj_attrs(const char* attr_name, bufferlist& attr_val, optional_yield y, const DoutPrefixProvider* dpp) = 0; |
20effc67 | 1017 | /** Delete attributes for this object */ |
1e59de90 | 1018 | virtual int delete_obj_attrs(const DoutPrefixProvider* dpp, const char* attr_name, optional_yield y) = 0; |
20effc67 | 1019 | /** Check to see if this object has expired */ |
f67539c2 | 1020 | virtual bool is_expired() = 0; |
20effc67 | 1021 | /** Create a randomized instance ID for this object */ |
f67539c2 | 1022 | virtual void gen_rand_obj_instance_name() = 0; |
20effc67 | 1023 | /** Get a multipart serializer for this object */ |
1e59de90 TL |
1024 | virtual std::unique_ptr<MPSerializer> get_serializer(const DoutPrefixProvider *dpp, |
1025 | const std::string& lock_name) = 0; | |
20effc67 | 1026 | /** Move the data of an object to new placement storage */ |
1e59de90 | 1027 | virtual int transition(Bucket* bucket, |
f67539c2 TL |
1028 | const rgw_placement_rule& placement_rule, |
1029 | const real_time& mtime, | |
1030 | uint64_t olh_epoch, | |
20effc67 | 1031 | const DoutPrefixProvider* dpp, |
f38dd50b TL |
1032 | optional_yield y, |
1033 | uint32_t flags) = 0; | |
1e59de90 TL |
1034 | /** Move an object to the cloud */ |
1035 | virtual int transition_to_cloud(Bucket* bucket, | |
1036 | rgw::sal::PlacementTier* tier, | |
1037 | rgw_bucket_dir_entry& o, | |
1038 | std::set<std::string>& cloud_targets, | |
1039 | CephContext* cct, | |
1040 | bool update_object, | |
1041 | const DoutPrefixProvider* dpp, | |
1042 | optional_yield y) = 0; | |
20effc67 | 1043 | /** Check to see if two placement rules match */ |
f67539c2 | 1044 | virtual bool placement_rules_match(rgw_placement_rule& r1, rgw_placement_rule& r2) = 0; |
1e59de90 TL |
1045 | /** Dump driver-specific object layout info in JSON */ |
1046 | virtual int dump_obj_layout(const DoutPrefixProvider *dpp, optional_yield y, Formatter* f) = 0; | |
20effc67 TL |
1047 | |
1048 | /** Get the cached attributes for this object */ | |
1e59de90 | 1049 | virtual Attrs& get_attrs(void) = 0; |
20effc67 | 1050 | /** Get the (const) cached attributes for this object */ |
1e59de90 | 1051 | virtual const Attrs& get_attrs(void) const = 0; |
20effc67 | 1052 | /** Set the cached attributes for this object */ |
1e59de90 TL |
1053 | virtual int set_attrs(Attrs a) = 0; |
1054 | /** Check to see if attributes are cached on this object */ | |
1055 | virtual bool has_attrs(void) = 0; | |
20effc67 | 1056 | /** Get the cached modification time for this object */ |
1e59de90 | 1057 | virtual ceph::real_time get_mtime(void) const = 0; |
20effc67 | 1058 | /** Get the cached size for this object */ |
1e59de90 | 1059 | virtual uint64_t get_obj_size(void) const = 0; |
20effc67 | 1060 | /** Get the bucket containing this object */ |
1e59de90 | 1061 | virtual Bucket* get_bucket(void) const = 0; |
20effc67 | 1062 | /** Set the bucket containing this object */ |
1e59de90 | 1063 | virtual void set_bucket(Bucket* b) = 0; |
20effc67 | 1064 | /** Get the sharding hash representation of this object */ |
1e59de90 | 1065 | virtual std::string get_hash_source(void) = 0; |
20effc67 | 1066 | /** Set the sharding hash representation of this object */ |
1e59de90 | 1067 | virtual void set_hash_source(std::string s) = 0; |
20effc67 | 1068 | /** Build an Object Identifier string for this object */ |
1e59de90 | 1069 | virtual std::string get_oid(void) const = 0; |
20effc67 | 1070 | /** True if this object is a delete marker (newest version is deleted) */ |
1e59de90 | 1071 | virtual bool get_delete_marker(void) = 0; |
20effc67 | 1072 | /** True if this object is stored in the extra data pool */ |
1e59de90 | 1073 | virtual bool get_in_extra_data(void) = 0; |
20effc67 | 1074 | /** Set the in_extra_data field */ |
1e59de90 | 1075 | virtual void set_in_extra_data(bool i) = 0; |
20effc67 | 1076 | /** Helper to sanitize object size, offset, and end values */ |
f67539c2 | 1077 | int range_to_ofs(uint64_t obj_size, int64_t &ofs, int64_t &end); |
20effc67 | 1078 | /** Set the cached size of this object */ |
1e59de90 | 1079 | virtual void set_obj_size(uint64_t s) = 0; |
20effc67 | 1080 | /** Set the cached name of this object */ |
1e59de90 | 1081 | virtual void set_name(const std::string& n) = 0; |
20effc67 | 1082 | /** Set the cached key of this object */ |
1e59de90 | 1083 | virtual void set_key(const rgw_obj_key& k) = 0; |
20effc67 | 1084 | /** Get an rgw_obj representing this object */ |
1e59de90 | 1085 | virtual rgw_obj get_obj(void) const = 0; |
9f95a23c | 1086 | |
20effc67 | 1087 | /** Restore the previous swift version of this object */ |
1e59de90 | 1088 | virtual int swift_versioning_restore(bool& restored, /* out */ |
20effc67 TL |
1089 | const DoutPrefixProvider* dpp) = 0; |
1090 | /** Copy the current version of a swift object to the configured destination bucket*/ | |
1e59de90 | 1091 | virtual int swift_versioning_copy(const DoutPrefixProvider* dpp, |
f67539c2 | 1092 | optional_yield y) = 0; |
9f95a23c | 1093 | |
20effc67 | 1094 | /** Get a new ReadOp for this object */ |
1e59de90 | 1095 | virtual std::unique_ptr<ReadOp> get_read_op() = 0; |
20effc67 | 1096 | /** Get a new DeleteOp for this object */ |
1e59de90 | 1097 | virtual std::unique_ptr<DeleteOp> get_delete_op() = 0; |
20effc67 TL |
1098 | |
1099 | /** Get @a count OMAP values via listing, starting at @a marker for this object */ | |
1100 | virtual int omap_get_vals(const DoutPrefixProvider *dpp, const std::string& marker, uint64_t count, | |
1101 | std::map<std::string, bufferlist>* m, | |
1102 | bool* pmore, optional_yield y) = 0; | |
1103 | /** Get all OMAP key/value pairs for this object */ | |
1104 | virtual int omap_get_all(const DoutPrefixProvider *dpp, std::map<std::string, bufferlist>* m, | |
1105 | optional_yield y) = 0; | |
1106 | /** Get the OMAP values matching the given set of keys */ | |
b3b6e05e | 1107 | virtual int omap_get_vals_by_keys(const DoutPrefixProvider *dpp, const std::string& oid, |
f67539c2 | 1108 | const std::set<std::string>& keys, |
20effc67 TL |
1109 | Attrs* vals) = 0; |
1110 | /** Get a single OMAP value matching the given key */ | |
b3b6e05e | 1111 | virtual int omap_set_val_by_key(const DoutPrefixProvider *dpp, const std::string& key, bufferlist& val, |
f67539c2 | 1112 | bool must_exist, optional_yield y) = 0; |
39ae355f TL |
1113 | /** Change the ownership of this object */ |
1114 | virtual int chown(User& new_user, const DoutPrefixProvider* dpp, optional_yield y) = 0; | |
9f95a23c | 1115 | |
1e59de90 TL |
1116 | /** Check to see if the given object pointer is uninitialized */ |
1117 | static bool empty(const Object* o) { return (!o || o->empty()); } | |
1118 | /** Check to see if the given object unique pointer is uninitialized */ | |
1119 | static bool empty(const std::unique_ptr<Object>& o) { return (!o || o->empty()); } | |
20effc67 TL |
1120 | /** Get a unique copy of this object */ |
1121 | virtual std::unique_ptr<Object> clone() = 0; | |
9f95a23c | 1122 | |
f67539c2 | 1123 | /* dang - This is temporary, until the API is completed */ |
20effc67 | 1124 | /** Get the key for this object */ |
1e59de90 | 1125 | virtual rgw_obj_key& get_key() = 0; |
20effc67 | 1126 | /** Set the instance for this object */ |
1e59de90 | 1127 | virtual void set_instance(const std::string &i) = 0; |
20effc67 | 1128 | /** Get the instance for this object */ |
1e59de90 | 1129 | virtual const std::string &get_instance() const = 0; |
20effc67 | 1130 | /** Check to see if this object has an instance set */ |
1e59de90 TL |
1131 | virtual bool have_instance(void) = 0; |
1132 | /** Clear the instance on this object */ | |
1133 | virtual void clear_instance() = 0; | |
1134 | ||
1135 | /** Print the User to @a out */ | |
1136 | virtual void print(std::ostream& out) const = 0; | |
f67539c2 | 1137 | |
20effc67 | 1138 | friend inline std::ostream& operator<<(std::ostream& out, const Object& o) { |
1e59de90 | 1139 | o.print(out); |
f67539c2 | 1140 | return out; |
9f95a23c | 1141 | } |
20effc67 | 1142 | friend inline std::ostream& operator<<(std::ostream& out, const Object* o) { |
f67539c2 TL |
1143 | if (!o) |
1144 | out << "<NULL>"; | |
1145 | else | |
1e59de90 | 1146 | o->print(out); |
f67539c2 | 1147 | return out; |
9f95a23c | 1148 | } |
20effc67 | 1149 | friend inline std::ostream& operator<<(std::ostream& out, const std::unique_ptr<Object>& p) { |
f67539c2 TL |
1150 | out << p.get(); |
1151 | return out; | |
9f95a23c | 1152 | } |
9f95a23c TL |
1153 | }; |
1154 | ||
20effc67 TL |
1155 | /** |
1156 | * @brief Abstraction of a single part of a multipart upload | |
1157 | */ | |
1158 | class MultipartPart { | |
20effc67 TL |
1159 | public: |
1160 | MultipartPart() = default; | |
1161 | virtual ~MultipartPart() = default; | |
1162 | ||
1163 | /** Get the part number of this part */ | |
1164 | virtual uint32_t get_num() = 0; | |
1165 | /** Get the size of this part */ | |
1166 | virtual uint64_t get_size() = 0; | |
1167 | /** Get the etag of this part */ | |
1168 | virtual const std::string& get_etag() = 0; | |
1169 | /** Get the modification time of this part */ | |
1170 | virtual ceph::real_time& get_mtime() = 0; | |
1171 | }; | |
1172 | ||
1173 | /** | |
1174 | * @brief Abstraction of a multipart upload | |
1175 | * | |
1176 | * This represents a multipart upload. For large objects, it's inefficient to do a | |
1177 | * single, long-lived upload of the object. Instead, protocols such as S3 allow the | |
1178 | * client to start a multipart upload, and then upload object in smaller parts in | |
1179 | * parallel. A MultipartUpload consists of a target bucket, a unique identifier, and a | |
1180 | * set of upload parts. | |
1181 | */ | |
1182 | class MultipartUpload { | |
20effc67 | 1183 | public: |
1e59de90 | 1184 | MultipartUpload() = default; |
20effc67 TL |
1185 | virtual ~MultipartUpload() = default; |
1186 | ||
1187 | /** Get the name of the object representing this upload in the backing store */ | |
1188 | virtual const std::string& get_meta() const = 0; | |
1189 | /** Get the name of the target object for this upload */ | |
1190 | virtual const std::string& get_key() const = 0; | |
1191 | /** Get the unique ID of this upload */ | |
1192 | virtual const std::string& get_upload_id() const = 0; | |
1193 | /** Get the owner of this upload */ | |
1194 | virtual const ACLOwner& get_owner() const = 0; | |
1195 | /** Get the modification time of this upload */ | |
1196 | virtual ceph::real_time& get_mtime() = 0; | |
1197 | ||
1198 | /** Get all the cached parts that make up this upload */ | |
1e59de90 | 1199 | virtual std::map<uint32_t, std::unique_ptr<MultipartPart>>& get_parts() = 0; |
20effc67 TL |
1200 | |
1201 | /** Get the trace context of this upload */ | |
1e59de90 | 1202 | virtual const jspan_context& get_trace() = 0; |
20effc67 TL |
1203 | |
1204 | /** Get the Object that represents this upload */ | |
1205 | virtual std::unique_ptr<rgw::sal::Object> get_meta_obj() = 0; | |
1206 | ||
1207 | /** Initialize this upload */ | |
1e59de90 | 1208 | virtual int init(const DoutPrefixProvider* dpp, optional_yield y, ACLOwner& owner, rgw_placement_rule& dest_placement, rgw::sal::Attrs& attrs) = 0; |
20effc67 TL |
1209 | /** List all the parts of this upload, filling the parts cache */ |
1210 | virtual int list_parts(const DoutPrefixProvider* dpp, CephContext* cct, | |
1211 | int num_parts, int marker, | |
1212 | int* next_marker, bool* truncated, | |
1213 | bool assume_unsorted = false) = 0; | |
1214 | /** Abort this upload */ | |
1e59de90 | 1215 | virtual int abort(const DoutPrefixProvider* dpp, CephContext* cct) = 0; |
20effc67 TL |
1216 | /** Complete this upload, making it available as a normal object */ |
1217 | virtual int complete(const DoutPrefixProvider* dpp, | |
1218 | optional_yield y, CephContext* cct, | |
1219 | std::map<int, std::string>& part_etags, | |
1220 | std::list<rgw_obj_index_key>& remove_objs, | |
1221 | uint64_t& accounted_size, bool& compressed, | |
1222 | RGWCompressionInfo& cs_info, off_t& ofs, | |
1223 | std::string& tag, ACLOwner& owner, | |
1224 | uint64_t olh_epoch, | |
1e59de90 | 1225 | rgw::sal::Object* target_obj) = 0; |
20effc67 TL |
1226 | |
1227 | /** Get placement and/or attribute info for this upload */ | |
1e59de90 | 1228 | virtual int get_info(const DoutPrefixProvider *dpp, optional_yield y, rgw_placement_rule** rule, rgw::sal::Attrs* attrs = nullptr) = 0; |
20effc67 TL |
1229 | |
1230 | /** Get a Writer to write to a part of this upload */ | |
1231 | virtual std::unique_ptr<Writer> get_writer(const DoutPrefixProvider *dpp, | |
1232 | optional_yield y, | |
1e59de90 TL |
1233 | rgw::sal::Object* obj, |
1234 | const rgw_user& owner, | |
20effc67 TL |
1235 | const rgw_placement_rule *ptail_placement_rule, |
1236 | uint64_t part_num, | |
1237 | const std::string& part_num_str) = 0; | |
1238 | ||
1e59de90 TL |
1239 | /** Print the Upload to @a out */ |
1240 | virtual void print(std::ostream& out) const = 0; | |
1241 | ||
20effc67 | 1242 | friend inline std::ostream& operator<<(std::ostream& out, const MultipartUpload& u) { |
1e59de90 | 1243 | u.print(out); |
20effc67 TL |
1244 | return out; |
1245 | } | |
1246 | friend inline std::ostream& operator<<(std::ostream& out, const MultipartUpload* u) { | |
1247 | if (!u) | |
1248 | out << "<NULL>"; | |
1249 | else | |
1e59de90 | 1250 | u->print(out); |
20effc67 TL |
1251 | return out; |
1252 | } | |
1253 | friend inline std::ostream& operator<<(std::ostream& out, const | |
1254 | std::unique_ptr<MultipartUpload>& p) { | |
1255 | out << p.get(); | |
1256 | return out; | |
1257 | } | |
1258 | }; | |
1259 | ||
1260 | /** | |
1261 | * @brief Interface of a lock/serialization | |
1262 | */ | |
1e59de90 TL |
1263 | class Serializer { |
1264 | public: | |
f67539c2 TL |
1265 | Serializer() = default; |
1266 | virtual ~Serializer() = default; | |
9f95a23c | 1267 | |
20effc67 | 1268 | /** Try to take the lock for the given amount of time. */ |
b3b6e05e | 1269 | virtual int try_lock(const DoutPrefixProvider *dpp, utime_t dur, optional_yield y) = 0; |
20effc67 | 1270 | /** Unlock the lock */ |
f67539c2 | 1271 | virtual int unlock() = 0; |
1e59de90 TL |
1272 | |
1273 | /** Print the Serializer to @a out */ | |
1274 | virtual void print(std::ostream& out) const = 0; | |
1275 | ||
1276 | friend inline std::ostream& operator<<(std::ostream& out, const Serializer& s) { | |
1277 | s.print(out); | |
1278 | return out; | |
1279 | } | |
1280 | friend inline std::ostream& operator<<(std::ostream& out, const Serializer* s) { | |
1281 | if (!s) | |
1282 | out << "<NULL>"; | |
1283 | else | |
1284 | s->print(out); | |
1285 | return out; | |
1286 | } | |
f67539c2 | 1287 | }; |
9f95a23c | 1288 | |
20effc67 TL |
1289 | /** @brief Abstraction of a serializer for multipart uploads |
1290 | */ | |
1e59de90 TL |
1291 | class MPSerializer : public Serializer { |
1292 | public: | |
1293 | MPSerializer() = default; | |
f67539c2 | 1294 | virtual ~MPSerializer() = default; |
9f95a23c | 1295 | |
1e59de90 TL |
1296 | virtual void clear_locked() = 0; |
1297 | /** Check to see if locked */ | |
1298 | virtual bool is_locked() = 0; | |
f67539c2 | 1299 | }; |
9f95a23c | 1300 | |
20effc67 TL |
1301 | /** @brief Abstraction of a serializer for Lifecycle |
1302 | */ | |
1e59de90 TL |
1303 | class LCSerializer : public Serializer { |
1304 | public: | |
f67539c2 TL |
1305 | LCSerializer() {} |
1306 | virtual ~LCSerializer() = default; | |
1307 | }; | |
9f95a23c | 1308 | |
20effc67 TL |
1309 | /** |
1310 | * @brief Abstraction for lifecycle processing | |
1311 | * | |
1312 | * Lifecycle processing loops over the objects in a bucket, applying per-bucket policy | |
1313 | * to each object. Examples of policy can be deleting after a certain amount of time, | |
1314 | * deleting extra versions, changing the storage class, and so on. | |
1315 | */ | |
f67539c2 TL |
1316 | class Lifecycle { |
1317 | public: | |
20effc67 | 1318 | /** Head of a lifecycle run. Used for tracking parallel lifecycle runs. */ |
f67539c2 | 1319 | struct LCHead { |
f67539c2 | 1320 | LCHead() = default; |
1e59de90 TL |
1321 | virtual ~LCHead() = default; |
1322 | ||
1323 | virtual time_t& get_start_date() = 0; | |
1324 | virtual void set_start_date(time_t) = 0; | |
1325 | virtual std::string& get_marker() = 0; | |
1326 | virtual void set_marker(const std::string&) = 0; | |
1327 | virtual time_t& get_shard_rollover_date() = 0; | |
1328 | virtual void set_shard_rollover_date(time_t) = 0; | |
f67539c2 TL |
1329 | }; |
1330 | ||
20effc67 TL |
1331 | /** Single entry in a lifecycle run. Multiple entries can exist processing different |
1332 | * buckets. */ | |
f67539c2 | 1333 | struct LCEntry { |
f67539c2 | 1334 | LCEntry() = default; |
1e59de90 TL |
1335 | virtual ~LCEntry() = default; |
1336 | ||
1337 | virtual std::string& get_bucket() = 0; | |
1338 | virtual void set_bucket(const std::string&) = 0; | |
1339 | virtual std::string& get_oid() = 0; | |
1340 | virtual void set_oid(const std::string&) = 0; | |
1341 | virtual uint64_t get_start_time() = 0; | |
1342 | virtual void set_start_time(uint64_t) = 0; | |
1343 | virtual uint32_t get_status() = 0; | |
1344 | virtual void set_status(uint32_t) = 0; | |
1345 | ||
1346 | /** Print the entry to @a out */ | |
1347 | virtual void print(std::ostream& out) const = 0; | |
1348 | ||
1349 | friend inline std::ostream& operator<<(std::ostream& out, const LCEntry& e) { | |
1350 | e.print(out); | |
1351 | return out; | |
1352 | } | |
1353 | friend inline std::ostream& operator<<(std::ostream& out, const LCEntry* e) { | |
1354 | if (!e) | |
1355 | out << "<NULL>"; | |
1356 | else | |
1357 | e->print(out); | |
1358 | return out; | |
1359 | } | |
1360 | friend inline std::ostream& operator<<(std::ostream& out, const std::unique_ptr<LCEntry>& p) { | |
1361 | out << p.get(); | |
1362 | return out; | |
1363 | } | |
f67539c2 TL |
1364 | }; |
1365 | ||
1366 | Lifecycle() = default; | |
1367 | virtual ~Lifecycle() = default; | |
1368 | ||
1e59de90 TL |
1369 | /** Get an empty entry */ |
1370 | virtual std::unique_ptr<LCEntry> get_entry() = 0; | |
20effc67 | 1371 | /** Get an entry matching the given marker */ |
1e59de90 | 1372 | virtual int get_entry(const std::string& oid, const std::string& marker, std::unique_ptr<LCEntry>* entry) = 0; |
20effc67 | 1373 | /** Get the entry following the given marker */ |
1e59de90 | 1374 | virtual int get_next_entry(const std::string& oid, const std::string& marker, std::unique_ptr<LCEntry>* entry) = 0; |
20effc67 | 1375 | /** Store a modified entry in then backing store */ |
1e59de90 | 1376 | virtual int set_entry(const std::string& oid, LCEntry& entry) = 0; |
20effc67 TL |
1377 | /** List all known entries */ |
1378 | virtual int list_entries(const std::string& oid, const std::string& marker, | |
1e59de90 TL |
1379 | uint32_t max_entries, |
1380 | std::vector<std::unique_ptr<LCEntry>>& entries) = 0; | |
20effc67 | 1381 | /** Remove an entry from the backing store */ |
1e59de90 | 1382 | virtual int rm_entry(const std::string& oid, LCEntry& entry) = 0; |
20effc67 | 1383 | /** Get a head */ |
1e59de90 | 1384 | virtual int get_head(const std::string& oid, std::unique_ptr<LCHead>* head) = 0; |
20effc67 | 1385 | /** Store a modified head to the backing store */ |
1e59de90 | 1386 | virtual int put_head(const std::string& oid, LCHead& head) = 0; |
20effc67 TL |
1387 | |
1388 | /** Get a serializer for lifecycle */ | |
1e59de90 TL |
1389 | virtual std::unique_ptr<LCSerializer> get_serializer(const std::string& lock_name, |
1390 | const std::string& oid, | |
1391 | const std::string& cookie) = 0; | |
9f95a23c TL |
1392 | }; |
1393 | ||
20effc67 TL |
1394 | /** |
1395 | * @brief Abstraction for a Notification event | |
1396 | * | |
1397 | * RGW can generate notifications for various events, such as object creation or | |
1398 | * deletion. | |
1399 | */ | |
1400 | class Notification { | |
1401 | protected: | |
20effc67 | 1402 | public: |
1e59de90 | 1403 | Notification() {} |
20effc67 TL |
1404 | |
1405 | virtual ~Notification() = default; | |
1406 | ||
1407 | /** Indicate the start of the event associated with this notification */ | |
1408 | virtual int publish_reserve(const DoutPrefixProvider *dpp, RGWObjTags* obj_tags = nullptr) = 0; | |
1409 | /** Indicate the successful completion of the event associated with this notification */ | |
1410 | virtual int publish_commit(const DoutPrefixProvider* dpp, uint64_t size, | |
1411 | const ceph::real_time& mtime, const std::string& etag, const std::string& version) = 0; | |
1412 | }; | |
1413 | ||
1414 | /** | |
1415 | * @brief Abstraction for an asynchronous writer | |
1416 | * | |
1417 | * Writing is done through a set of filters. This allows chaining filters to do things | |
1418 | * like compression and encryption on async writes. This is the base abstraction for | |
1419 | * those filters. | |
1420 | */ | |
1421 | class Writer : public ObjectProcessor { | |
20effc67 | 1422 | public: |
1e59de90 | 1423 | Writer() {} |
20effc67 TL |
1424 | virtual ~Writer() = default; |
1425 | ||
1426 | /** prepare to start processing object data */ | |
1427 | virtual int prepare(optional_yield y) = 0; | |
1428 | ||
1e59de90 TL |
1429 | /** |
1430 | * Process a buffer. Called multiple times to write different buffers. | |
1431 | * data.length() == 0 indicates the last call and may be used to flush | |
1432 | * the data buffers. | |
1433 | */ | |
20effc67 TL |
1434 | virtual int process(bufferlist&& data, uint64_t offset) = 0; |
1435 | ||
1436 | /** complete the operation and make its result visible to clients */ | |
1437 | virtual int complete(size_t accounted_size, const std::string& etag, | |
1438 | ceph::real_time *mtime, ceph::real_time set_mtime, | |
1439 | std::map<std::string, bufferlist>& attrs, | |
1440 | ceph::real_time delete_at, | |
1441 | const char *if_match, const char *if_nomatch, | |
1442 | const std::string *user_data, | |
1443 | rgw_zone_set *zones_trace, bool *canceled, | |
f38dd50b TL |
1444 | optional_yield y, |
1445 | uint32_t flags) = 0; | |
20effc67 TL |
1446 | }; |
1447 | ||
1e59de90 TL |
1448 | |
1449 | /** | |
1450 | * @brief Abstraction of a placement tier | |
1451 | * | |
1452 | * This abstraction allows access to information about placement tiers, | |
1453 | * including storage class. | |
1454 | */ | |
1455 | class PlacementTier { | |
1456 | public: | |
1457 | virtual ~PlacementTier() = default; | |
1458 | ||
1459 | /** Get the type of this tier */ | |
1460 | virtual const std::string& get_tier_type() = 0; | |
1461 | /** Get the storage class of this tier */ | |
1462 | virtual const std::string& get_storage_class() = 0; | |
1463 | /** Should we retain the head object when transitioning */ | |
1464 | virtual bool retain_head_object() = 0; | |
1465 | /** Get the placement rule associated with this tier */ | |
1466 | }; | |
1467 | ||
1468 | /** | |
1469 | * @brief Abstraction of a zone group | |
1470 | * | |
1471 | * This class allows access to information about a zonegroup. It may be the | |
1472 | * group containing the current zone, or another group. | |
1473 | */ | |
1474 | class ZoneGroup { | |
1475 | public: | |
1476 | virtual ~ZoneGroup() = default; | |
1477 | /** Get the ID of this zonegroup */ | |
1478 | virtual const std::string& get_id() const = 0; | |
1479 | /** Get the name of this zonegroup */ | |
1480 | virtual const std::string& get_name() const = 0; | |
1481 | /** Determine if two zonegroups are the same */ | |
1482 | virtual int equals(const std::string& other_zonegroup) const = 0; | |
1483 | /** Get the endpoint from zonegroup, or from master zone if not set */ | |
1484 | virtual const std::string& get_endpoint() const = 0; | |
1485 | /** Check if a placement target (by name) exists in this zonegroup */ | |
1486 | virtual bool placement_target_exists(std::string& target) const = 0; | |
1487 | /** Check if this is the master zonegroup */ | |
1488 | virtual bool is_master_zonegroup() const = 0; | |
1489 | /** Get the API name of this zonegroup */ | |
1490 | virtual const std::string& get_api_name() const = 0; | |
1491 | /** Get the list of placement target names for this zone */ | |
aee94f69 | 1492 | virtual void get_placement_target_names(std::set<std::string>& names) const = 0; |
1e59de90 TL |
1493 | /** Get the name of the default placement target for this zone */ |
1494 | virtual const std::string& get_default_placement_name() const = 0; | |
1495 | /** Get the list of hostnames from this zone */ | |
1496 | virtual int get_hostnames(std::list<std::string>& names) const = 0; | |
1497 | /** Get the list of hostnames that host s3 websites from this zone */ | |
1498 | virtual int get_s3website_hostnames(std::list<std::string>& names) const = 0; | |
1499 | /** Get the number of zones in this zonegroup */ | |
1500 | virtual int get_zone_count() const = 0; | |
1501 | /** Get the placement tier associated with the rule */ | |
1502 | virtual int get_placement_tier(const rgw_placement_rule& rule, std::unique_ptr<PlacementTier>* tier) = 0; | |
1503 | /** Get a zone by ID */ | |
1504 | virtual int get_zone_by_id(const std::string& id, std::unique_ptr<Zone>* zone) = 0; | |
1505 | /** Get a zone by Name */ | |
1506 | virtual int get_zone_by_name(const std::string& name, std::unique_ptr<Zone>* zone) = 0; | |
1507 | /** List zones in zone group by ID */ | |
1508 | virtual int list_zones(std::list<std::string>& zone_ids) = 0; | |
05a536ef TL |
1509 | /// Return true if the given feature is enabled in the zonegroup. |
1510 | virtual bool supports(std::string_view feature) const = 0; | |
1e59de90 TL |
1511 | /** Clone a copy of this zonegroup. */ |
1512 | virtual std::unique_ptr<ZoneGroup> clone() = 0; | |
1513 | }; | |
1514 | ||
20effc67 TL |
1515 | /** |
1516 | * @brief Abstraction of a Zone | |
1517 | * | |
1518 | * This abstraction allows access to information about zones. This can be the zone | |
1519 | * containing the RGW, or another zone. | |
1520 | */ | |
1521 | class Zone { | |
1522 | public: | |
1523 | virtual ~Zone() = default; | |
1524 | ||
1e59de90 TL |
1525 | /** Clone a copy of this zone. */ |
1526 | virtual std::unique_ptr<Zone> clone() = 0; | |
20effc67 | 1527 | /** Get info about the zonegroup containing this zone */ |
1e59de90 | 1528 | virtual ZoneGroup& get_zonegroup() = 0; |
20effc67 | 1529 | /** Get the ID of this zone */ |
1e59de90 | 1530 | virtual const std::string& get_id() = 0; |
20effc67 TL |
1531 | /** Get the name of this zone */ |
1532 | virtual const std::string& get_name() const = 0; | |
1533 | /** True if this zone is writable */ | |
1534 | virtual bool is_writeable() = 0; | |
1535 | /** Get the URL for the endpoint for redirecting to this zone */ | |
1536 | virtual bool get_redirect_endpoint(std::string* endpoint) = 0; | |
1537 | /** Check to see if the given API is supported in this zone */ | |
1538 | virtual bool has_zonegroup_api(const std::string& api) const = 0; | |
1539 | /** Get the current period ID for this zone */ | |
1540 | virtual const std::string& get_current_period_id() = 0; | |
1e59de90 TL |
1541 | /** Get thes system access key for this zone */ |
1542 | virtual const RGWAccessKey& get_system_key() = 0; | |
1543 | /** Get the name of the realm containing this zone */ | |
1544 | virtual const std::string& get_realm_name() = 0; | |
1545 | /** Get the ID of the realm containing this zone */ | |
1546 | virtual const std::string& get_realm_id() = 0; | |
1547 | /** Get the tier type for the zone */ | |
1548 | virtual const std::string_view get_tier_type() = 0; | |
1549 | /** Get a handler for zone sync policy. */ | |
1550 | virtual RGWBucketSyncPolicyHandlerRef get_sync_policy_handler() = 0; | |
20effc67 TL |
1551 | }; |
1552 | ||
1553 | /** | |
1e59de90 | 1554 | * @brief Abstraction of a manager for Lua scripts and packages |
20effc67 | 1555 | * |
1e59de90 | 1556 | * RGW can load and process Lua scripts. This will handle loading/storing scripts; adding, deleting, and listing packages |
20effc67 | 1557 | */ |
1e59de90 | 1558 | class LuaManager { |
20effc67 | 1559 | public: |
1e59de90 | 1560 | virtual ~LuaManager() = default; |
20effc67 TL |
1561 | |
1562 | /** Get a script named with the given key from the backing store */ | |
1e59de90 | 1563 | virtual int get_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, std::string& script) = 0; |
20effc67 | 1564 | /** Put a script named with the given key to the backing store */ |
1e59de90 | 1565 | virtual int put_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, const std::string& script) = 0; |
20effc67 | 1566 | /** Delete a script named with the given key from the backing store */ |
1e59de90 TL |
1567 | virtual int del_script(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key) = 0; |
1568 | /** Add a lua package */ | |
1569 | virtual int add_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name) = 0; | |
1570 | /** Remove a lua package */ | |
1571 | virtual int remove_package(const DoutPrefixProvider* dpp, optional_yield y, const std::string& package_name) = 0; | |
1572 | /** List lua packages */ | |
1573 | virtual int list_packages(const DoutPrefixProvider* dpp, optional_yield y, rgw::lua::packages_t& packages) = 0; | |
20effc67 TL |
1574 | }; |
1575 | ||
1576 | /** @} namespace rgw::sal in group RGWSAL */ | |
9f95a23c TL |
1577 | } } // namespace rgw::sal |
1578 | ||
20effc67 | 1579 | /** |
1e59de90 | 1580 | * @brief A manager for Drivers |
20effc67 | 1581 | * |
1e59de90 TL |
1582 | * This will manage the singleton instances of the various drivers. Drivers come in two |
1583 | * varieties: Full and Raw. A full driver is suitable for use in a radosgw daemon. It | |
1584 | * has full access to the cluster, if any. A raw driver is a stripped down driver, used | |
20effc67 TL |
1585 | * for admin commands. |
1586 | */ | |
1e59de90 | 1587 | class DriverManager { |
20effc67 | 1588 | public: |
1e59de90 TL |
1589 | struct Config { |
1590 | /** Name of store to create */ | |
1591 | std::string store_name; | |
1592 | /** Name of filter to create or "none" */ | |
1593 | std::string filter_name; | |
1594 | }; | |
1595 | ||
1596 | DriverManager() {} | |
1597 | /** Get a full driver by service name */ | |
1598 | static rgw::sal::Driver* get_storage(const DoutPrefixProvider* dpp, | |
1599 | CephContext* cct, | |
1600 | const Config& cfg, | |
1601 | bool use_gc_thread, | |
1602 | bool use_lc_thread, | |
1603 | bool quota_threads, | |
1604 | bool run_sync_thread, | |
1605 | bool run_reshard_thread, | |
1606 | bool use_cache = true, | |
1607 | bool use_gc = true) { | |
1608 | rgw::sal::Driver* driver = init_storage_provider(dpp, cct, cfg, use_gc_thread, | |
1609 | use_lc_thread, | |
1610 | quota_threads, | |
1611 | run_sync_thread, | |
1612 | run_reshard_thread, | |
1613 | use_cache, use_gc); | |
1614 | return driver; | |
20effc67 | 1615 | } |
1e59de90 TL |
1616 | /** Get a stripped down driver by service name */ |
1617 | static rgw::sal::Driver* get_raw_storage(const DoutPrefixProvider* dpp, | |
1618 | CephContext* cct, const Config& cfg) { | |
1619 | rgw::sal::Driver* driver = init_raw_storage_provider(dpp, cct, cfg); | |
1620 | return driver; | |
20effc67 | 1621 | } |
1e59de90 TL |
1622 | /** Initialize a new full Driver */ |
1623 | static rgw::sal::Driver* init_storage_provider(const DoutPrefixProvider* dpp, | |
1624 | CephContext* cct, | |
1625 | const Config& cfg, | |
1626 | bool use_gc_thread, | |
1627 | bool use_lc_thread, | |
1628 | bool quota_threads, | |
1629 | bool run_sync_thread, | |
1630 | bool run_reshard_thread, | |
1631 | bool use_metadata_cache, | |
1632 | bool use_gc); | |
1633 | /** Initialize a new raw Driver */ | |
1634 | static rgw::sal::Driver* init_raw_storage_provider(const DoutPrefixProvider* dpp, | |
1635 | CephContext* cct, | |
1636 | const Config& cfg); | |
1637 | /** Close a Driver when it's no longer needed */ | |
1638 | static void close_storage(rgw::sal::Driver* driver); | |
1639 | ||
1640 | /** Get the config for Drivers */ | |
1641 | static Config get_config(bool admin, CephContext* cct); | |
1642 | ||
1643 | /** Create a ConfigStore */ | |
1644 | static auto create_config_store(const DoutPrefixProvider* dpp, | |
1645 | std::string_view type) | |
1646 | -> std::unique_ptr<rgw::sal::ConfigStore>; | |
20effc67 TL |
1647 | |
1648 | }; | |
1649 | ||
1650 | /** @} */ |