]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Swift API. Allows setting attributes with COPY object operation.
authorDmytro Iurchenko <diurchenko@mirantis.com>
Fri, 20 Feb 2015 16:31:03 +0000 (18:31 +0200)
committerLoic Dachary <ldachary@redhat.com>
Wed, 6 May 2015 10:05:40 +0000 (12:05 +0200)
http://developer.openstack.org/api-ref-objectstorage-v1.html says: "With COPY, you can add additional metadata to the object."

Fixes: #10662
Backport: hammer
Reported-by: Ahmad Faheem <ahmad.faheem@ril.com>
Signed-off-by: Dmytro Iurchenko <diurchenko@mirantis.com>
(cherry picked from commit 1b722bbcd691e0a4a39ea77cd28e309fd723ec88)

src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_swift.cc

index 3ec8dbae08260e10bf81cd5730223946ba3cd484..52fa69a2101223bd4592a5ee30294f7f3d342956 100644 (file)
@@ -2384,7 +2384,7 @@ void RGWCopyObj::execute()
                         unmod_ptr,
                         if_match,
                         if_nomatch,
-                        replace_attrs,
+                        attrs_mod,
                         attrs, RGW_OBJ_CATEGORY_MAIN,
                         olh_epoch,
                         (version_id.empty() ? NULL : &version_id),
index a009ec38e8077ba031d7135f9053a27617180cd8..5fdc12958a6b5113756711b799e15af56f85fd6f 100644 (file)
@@ -585,7 +585,7 @@ protected:
   rgw_bucket dest_bucket;
   string dest_object;
   time_t mtime;
-  bool replace_attrs;
+  RGWRados::AttrsMod attrs_mod;
   RGWBucketInfo src_bucket_info;
   RGWBucketInfo dest_bucket_info;
   string source_zone;
@@ -616,7 +616,7 @@ public:
     unmod_ptr = NULL;
     ret = 0;
     mtime = 0;
-    replace_attrs = false;
+    attrs_mod = RGWRados::ATTRSMOD_NONE;
     last_ofs = 0;
     olh_epoch = 0;
   }
index 56f5d8146a915968150bdaf618f78f0a45fb308b..bd9a984a5b0a627a72333fe3ab30e0477005cfe0 100644 (file)
@@ -3448,19 +3448,27 @@ public:
 };
 
 /*
- * prepare attrset, either replace it with new attrs, or keep it (other than acls).
+ * prepare attrset depending on attrs_mod.
  */
-static void set_copy_attrs(map<string, bufferlist>& src_attrs, map<string, bufferlist>& attrs, bool replace_attrs, bool intra_region)
+static void set_copy_attrs(map<string, bufferlist>& src_attrs,
+                           map<string, bufferlist>& attrs,
+                           RGWRados::AttrsMod attrs_mod)
 {
-  if (replace_attrs) {
-    if (!attrs[RGW_ATTR_ETAG].length())
+  switch (attrs_mod) {
+  case RGWRados::ATTRSMOD_NONE:
+    src_attrs[RGW_ATTR_ACL] = attrs[RGW_ATTR_ACL];
+    break;
+  case RGWRados::ATTRSMOD_REPLACE:
+    if (!attrs[RGW_ATTR_ETAG].length()) {
       attrs[RGW_ATTR_ETAG] = src_attrs[RGW_ATTR_ETAG];
-
+    }
     src_attrs = attrs;
-  } else {
-    /* copying attrs from source, however acls should only be copied if it's intra-region operation */
-    if (!intra_region)
-      src_attrs[RGW_ATTR_ACL] = attrs[RGW_ATTR_ACL];
+    break;
+  case RGWRados::ATTRSMOD_MERGE:
+    for (map<string, bufferlist>::iterator it = attrs.begin(); it != attrs.end(); ++it) {
+      src_attrs[it->first] = it->second;
+    }
+    break;
   }
 }
 
@@ -3515,7 +3523,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
                const time_t *unmod_ptr,
                const char *if_match,
                const char *if_nomatch,
-               bool replace_attrs,
+               AttrsMod attrs_mod,
                map<string, bufferlist>& attrs,
                RGWObjCategory category,
                uint64_t olh_epoch,
@@ -3607,7 +3615,9 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
     }
   }
 
-  set_copy_attrs(src_attrs, attrs, replace_attrs, !source_zone.empty());
+  if (source_zone.empty()) {
+    set_copy_attrs(src_attrs, attrs, attrs_mod);
+  }
 
   ret = cb.complete(etag, mtime, set_mtime, src_attrs);
   if (ret < 0)
@@ -3658,7 +3668,14 @@ int RGWRados::copy_obj_to_remote_dest(RGWObjState *astate,
  * Copy an object.
  * dest_obj: the object to copy into
  * src_obj: the object to copy from
- * attrs: if replace_attrs is set then these are placed on the new object
+ * attrs: usage depends on attrs_mod parameter
+ * attrs_mod: the modification mode of the attrs, may have the following values:
+ *            ATTRSMOD_NONE - the attributes of the source object will be
+ *                            copied without modifications, attrs parameter is ignored;
+ *            ATTRSMOD_REPLACE - new object will have the attributes provided by attrs
+ *                               parameter, source object attributes are not copied;
+ *            ATTRSMOD_MERGE - any conflicting meta keys on the source object's attributes
+ *                             are overwritten by values contained in attrs parameter.
  * err: stores any errors resulting from the get of the original object
  * Returns: 0 on success, -ERR# otherwise.
  */
@@ -3677,7 +3694,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
                const time_t *unmod_ptr,
                const char *if_match,
                const char *if_nomatch,
-               bool replace_attrs,
+               AttrsMod attrs_mod,
                map<string, bufferlist>& attrs,
                RGWObjCategory category,
                uint64_t olh_epoch,
@@ -3713,7 +3730,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
   if (remote_src || !source_zone.empty()) {
     return fetch_remote_obj(obj_ctx, user_id, client_id, op_id, info, source_zone,
                dest_obj, src_obj, dest_bucket_info, src_bucket_info, mtime, mod_ptr,
-               unmod_ptr, if_match, if_nomatch, replace_attrs, attrs, category,
+               unmod_ptr, if_match, if_nomatch, attrs_mod, attrs, category,
                olh_epoch, version_id, ptag, petag, err, progress_cb, progress_data);
   }
 
@@ -3738,7 +3755,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
     return ret;
   }
 
-  set_copy_attrs(src_attrs, attrs, replace_attrs, false);
+  set_copy_attrs(src_attrs, attrs, attrs_mod);
   src_attrs.erase(RGW_ATTR_ID_TAG);
 
   RGWObjManifest manifest;
index 25adc418de4635808995fd14c6fa4eb30d43fd7c..9b14fa9c2d17e3f6a1f8b8a81d05add00ce46122 100644 (file)
@@ -1690,6 +1690,12 @@ public:
   virtual int aio_wait(void *handle);
   virtual bool aio_completed(void *handle);
 
+  enum AttrsMod {
+    ATTRSMOD_NONE    = 0,
+    ATTRSMOD_REPLACE = 1,
+    ATTRSMOD_MERGE   = 2
+  };
+
   int rewrite_obj(RGWBucketInfo& dest_bucket_info, rgw_obj& obj);
   int fetch_remote_obj(RGWObjectCtx& obj_ctx,
                        const string& user_id,
@@ -1706,7 +1712,7 @@ public:
                        const time_t *unmod_ptr,
                        const char *if_match,
                        const char *if_nomatch,
-                       bool replace_attrs,
+                       AttrsMod attrs_mod,
                        map<string, bufferlist>& attrs,
                        RGWObjCategory category,
                        uint64_t olh_epoch,
@@ -1726,7 +1732,14 @@ public:
    * Copy an object.
    * dest_obj: the object to copy into
    * src_obj: the object to copy from
-   * attrs: if replace_attrs is set then these are placed on the new object
+   * attrs: usage depends on attrs_mod parameter
+   * attrs_mod: the modification mode of the attrs, may have the following values:
+   *            ATTRSMOD_NONE - the attributes of the source object will be
+   *                            copied without modifications, attrs parameter is ignored;
+   *            ATTRSMOD_REPLACE - new object will have the attributes provided by attrs
+   *                               parameter, source object attributes are not copied;
+   *            ATTRSMOD_MERGE - any conflicting meta keys on the source object's attributes
+   *                             are overwritten by values contained in attrs parameter.
    * err: stores any errors resulting from the get of the original object
    * Returns: 0 on success, -ERR# otherwise.
    */
@@ -1745,7 +1758,7 @@ public:
                const time_t *unmod_ptr,
                const char *if_match,
                const char *if_nomatch,
-               bool replace_attrs,
+               AttrsMod attrs_mod,
                map<std::string, bufferlist>& attrs,
                RGWObjCategory category,
                uint64_t olh_epoch,
index dc71aa9477e096413e064845cc1c6f6b4882ddfe..bca45331240b1bd09a14793f638ac0f96c3b6af3 100644 (file)
@@ -1448,11 +1448,11 @@ int RGWCopyObj_ObjStore_S3::get_params()
   const char *md_directive = s->info.env->get("HTTP_X_AMZ_METADATA_DIRECTIVE");
   if (md_directive) {
     if (strcasecmp(md_directive, "COPY") == 0) {
-      replace_attrs = false;
+      attrs_mod = RGWRados::ATTRSMOD_NONE;
     } else if (strcasecmp(md_directive, "REPLACE") == 0) {
-      replace_attrs = true;
+      attrs_mod = RGWRados::ATTRSMOD_REPLACE;
     } else if (!source_zone.empty()) {
-      replace_attrs = false; // default for intra-region copy
+      attrs_mod = RGWRados::ATTRSMOD_NONE; // default for intra-region copy
     } else {
       ldout(s->cct, 0) << "invalid metadata directive" << dendl;
       return -EINVAL;
@@ -1463,7 +1463,7 @@ int RGWCopyObj_ObjStore_S3::get_params()
       (dest_bucket_name.compare(src_bucket_name) == 0) &&
       (dest_object.compare(src_object.name) == 0) &&
       src_object.instance.empty() &&
-      !replace_attrs) {
+      (attrs_mod != RGWRados::ATTRSMOD_REPLACE)) {
     /* can only copy object into itself if replacing attrs */
     ldout(s->cct, 0) << "can't copy object into itself if not replacing attrs" << dendl;
     return -ERR_INVALID_REQUEST;
index c0aef74fe56d97ddbdce9e63fb0ca47d856132a8..5738bbc50c7ecdca25a1aafcfc3523af628179fd 100644 (file)
@@ -557,6 +557,10 @@ int RGWCopyObj_ObjStore_SWIFT::get_params()
   dest_bucket_name = s->bucket_name_str;
   dest_object = s->object.name;
 
+  if (!s->info.x_meta_map.empty()) {
+    attrs_mod = RGWRados::ATTRSMOD_MERGE;
+  }
+
   return 0;
 }