]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
radosgw_admin: link bucket to user
authorYehuda Sadeh <yehuda.sadeh@dreamhost.com>
Mon, 6 Jun 2011 21:22:49 +0000 (14:22 -0700)
committerYehuda Sadeh <yehuda.sadeh@dreamhost.com>
Mon, 6 Jun 2011 21:22:49 +0000 (14:22 -0700)
src/rgw/rgw_access.h
src/rgw/rgw_admin.cc
src/rgw/rgw_fs.cc
src/rgw/rgw_fs.h
src/rgw/rgw_op.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index f52dcb938c80798d41661ec2ece8e1b7a202f27d..9af4498895969bb2105356b2e2becc61153da77f 100644 (file)
@@ -43,7 +43,7 @@ public:
                            bool get_content_type) = 0;
 
   /** Create a new bucket*/
-  virtual int create_bucket(std::string& id, std::string& bucket, map<std::string, bufferlist>& attrs, uint64_t auid=0) = 0;
+  virtual int create_bucket(std::string& id, std::string& bucket, map<std::string, bufferlist>& attrs, bool exclusive = true, uint64_t auid = 0) = 0;
   /** write an object to the storage device in the appropriate pool
     with the given stats */
   virtual int put_obj_meta(std::string& id, std::string& bucket, std::string& obj, time_t *mtime,
index ba40d0421cdfe841df9185ec3d6c0a1f41b82355..447d9af0daeb662205207f1a141f8d0d3b088ed4 100644 (file)
@@ -35,6 +35,7 @@ void usage()
   cerr << "  key create                 create access key\n";
   cerr << "  key rm                     remove access key\n";
   cerr << "  buckets list               list buckets\n";
+  cerr << "  bucket link                link bucket to specified user\n";
   cerr << "  bucket unlink              unlink bucket from specified user\n";
   cerr << "  policy                     read bucket/object policy\n";
   cerr << "  log show                   dump a log from specific object or (bucket + date)\n";
@@ -71,6 +72,7 @@ enum {
   OPT_KEY_CREATE,
   OPT_KEY_RM,
   OPT_BUCKETS_LIST,
+  OPT_BUCKET_LINK,
   OPT_BUCKET_UNLINK,
   OPT_POLICY,
   OPT_LOG_SHOW,
@@ -177,6 +179,8 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
     if (strcmp(cmd, "list") == 0)
       return OPT_BUCKETS_LIST;
   } else if (strcmp(prev_cmd, "bucket") == 0) {
+    if (strcmp(cmd, "link") == 0)
+      return OPT_BUCKET_LINK;
     if (strcmp(cmd, "unlink") == 0)
       return OPT_BUCKET_UNLINK;
   } else if (strcmp(prev_cmd, "log") == 0) {
@@ -281,6 +285,41 @@ static void show_user_info( RGWUserInfo& info)
   cout << "OpenStack Key: " << (info.openstack_key.size() ? info.openstack_key : "<undefined>")<< std::endl;
 }
 
+static int create_bucket(string& bucket, string& user_id, string& display_name, uint64_t auid)
+{
+  RGWAccessControlPolicy policy, old_policy;
+  map<string, bufferlist> attrs;
+  bufferlist aclbl;
+  string empty_obj;
+  int ret;
+
+  // defaule policy (private)
+  policy.create_default(user_id, display_name);
+  policy.encode(aclbl);
+cout << __FILE__ << __LINE__ << std::endl;
+
+cout << __FILE__ << __LINE__ << std::endl;
+  ret = rgwstore->create_bucket(user_id, bucket, attrs, false, auid);
+  if (ret && ret != -EEXIST)   
+    goto done;
+
+  ret = rgwstore->set_attr(bucket, empty_obj, RGW_ATTR_ACL, aclbl);
+  if (ret < 0) {
+    cerr << "couldn't set acl on bucket" << std::endl;
+  }
+cout << __FILE__ << __LINE__ << std::endl;
+
+  ret = rgw_add_bucket(user_id, bucket);
+
+  RGW_LOG(0) << "ret=" << ret << dendl;
+
+  if (ret == -EEXIST)
+    ret = 0;
+cout << __FILE__ << __LINE__ << std::endl;
+done:
+  return ret;
+}
+
 int main(int argc, char **argv) 
 {
   DEFINE_CONF_VARS(usage);
@@ -434,7 +473,7 @@ int main(int argc, char **argv)
 
 
   if (user_modify_op || opt_cmd == OPT_USER_CREATE ||
-      opt_cmd == OPT_USER_INFO || opt_cmd == OPT_BUCKET_UNLINK) {
+      opt_cmd == OPT_USER_INFO || opt_cmd == OPT_BUCKET_UNLINK || opt_cmd == OPT_BUCKET_LINK) {
     if (!user_id) {
       cerr << "user_id was not specified, aborting" << std::endl;
       usage();
@@ -636,11 +675,49 @@ int main(int argc, char **argv)
     }
   }
 
+  if (opt_cmd == OPT_BUCKET_LINK) {
+    if (!bucket) {
+      cerr << "bucket name was not specified" << std::endl;
+      usage();
+    }
+    string bucket_str(bucket);
+    string uid_str(user_id);
+    
+    string empty_obj;
+    bufferlist aclbl;
+
+    int r = rgwstore->get_attr(bucket_str, empty_obj, RGW_ATTR_ACL, aclbl);
+    if (r >= 0) {
+      RGWAccessControlPolicy policy;
+      ACLOwner owner;
+      try {
+       bufferlist::iterator iter = aclbl.begin();
+       ::decode(policy, iter);
+       owner = policy.get_owner();
+      } catch (buffer::error& err) {
+       dout(10) << "couldn't decode policy" << dendl;
+       return -EINVAL;
+      }
+      cout << "bucket is linked to user '" << owner.get_id() << "'.. unlinking" << std::endl;
+      r = rgw_remove_bucket(owner.get_id(), bucket_str);
+      if (r < 0) {
+       cerr << "could not unlink policy from user '" << owner.get_id() << "'" << std::endl;
+       return r;
+      }
+    }
+
+    r = create_bucket(bucket_str, uid_str, info.display_name, info.auid);
+    if (r < 0)
+        cerr << "error linking bucket to user: r=" << r << std::endl;
+    return -r;
+  }
+
   if (opt_cmd == OPT_BUCKET_UNLINK) {
     if (!bucket) {
       cerr << "bucket name was not specified" << std::endl;
       usage();
     }
+
     string bucket_str(bucket);
     int r = rgw_remove_bucket(user_id, bucket_str);
     if (r < 0)
index 6ea2f99da72fcd9ce6f08a303b732a8e02c83a79..10ac46c4bec8a4f4cb2e80773eccd7ee162d17b1 100644 (file)
@@ -158,14 +158,19 @@ int RGWFS::list_objects(string& id, string& bucket, int max, string& prefix, str
 }
 
 
-int RGWFS::create_bucket(std::string& id, std::string& bucket, map<std::string, bufferlist>& attrs, uint64_t auid)
+int RGWFS::create_bucket(std::string& id, std::string& bucket, map<std::string, bufferlist>& attrs, bool exclusive, uint64_t auid)
 {
   int len = strlen(DIR_NAME) + 1 + bucket.size() + 1;
   char buf[len];
   snprintf(buf, len, "%s/%s", DIR_NAME, bucket.c_str());
 
-  if (mkdir(buf, 0755) < 0)
-    return -errno;
+  int ret = mkdir(buf, 0755);
+  if (ret < 0)
+    ret = -errno;
+  if (ret == -EEXIST && !exclusive)
+    ret = 0;
+  if (ret < 0)
+    return ret;
 
   map<std::string, bufferlist>::iterator iter;
   for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
index e4c5deb9d7a372497e0a447e0da739f8fbb1bc87..e57bc461c89f040d7ad1b8898c464aee8d05b4f4 100644 (file)
@@ -18,7 +18,7 @@ public:
                    std::string& marker, std::vector<RGWObjEnt>& result, map<string, bool>& common_prefixes,
                    bool get_content_type);
 
-  int create_bucket(std::string& id, std::string& bucket, map<std::string, bufferlist>& attrs, uint64_t auid=0);
+  int create_bucket(std::string& id, std::string& bucket, map<std::string, bufferlist>& attrs, bool exclusive, uint64_t auid=0);
   int put_obj_meta(std::string& id, std::string& bucket, std::string& obj, time_t *mtime,
              map<std::string, bufferlist>& attrs);
   int put_obj_data(std::string& id, std::string& bucket, std::string& obj, const char *data,
index e1dac1824c0ae32883307d8634b0d7556a92b07a..4dee2cadaaef48bccf96c4482834a0dc008adda0 100644 (file)
@@ -327,7 +327,7 @@ void RGWCreateBucket::execute()
 
   attrs[RGW_ATTR_ACL] = aclbl;
 
-  ret = rgwstore->create_bucket(s->user.user_id, s->bucket_str, attrs,
+  ret = rgwstore->create_bucket(s->user.user_id, s->bucket_str, attrs, true,
                                s->user.auid);
   /* continue if EEXIST and create_bucket will fail below.  this way we can recover
    * from a partial create by retrying it. */
index 525665984a3c09cb4f31172c29552118174f1c5f..56bdd6d31947297891389730a8f78d21f597f569 100644 (file)
@@ -224,10 +224,10 @@ int RGWRados::list_objects(string& id, string& bucket, int max, string& prefix,
  * if auid is set, it sets the auid of the underlying rados io_ctx
  * returns 0 on success, -ERR# otherwise.
  */
-int RGWRados::create_bucket(std::string& id, std::string& bucket, map<std::string, bufferlist>& attrs, uint64_t auid)
+int RGWRados::create_bucket(std::string& id, std::string& bucket, map<std::string, bufferlist>& attrs, bool exclusive, uint64_t auid)
 {
   librados::ObjectOperation op;
-  op.create(true);
+  op.create(exclusive);
 
   for (map<string, bufferlist>::iterator iter = attrs.begin(); iter != attrs.end(); ++iter)
     op.setxattr(iter->first.c_str(), iter->second);
index 790c7c3b7b98341a5fa851db6b03febfa3b6f30d..ebb439b9fd17ae33a8b7c48fd9af211e0ff7b57d 100644 (file)
@@ -39,7 +39,7 @@ public:
    * create a bucket with name bucket and the given list of attrs
    * returns 0 on success, -ERR# otherwise.
    */
-  virtual int create_bucket(std::string& id, std::string& bucket, map<std::string,bufferlist>& attrs, uint64_t auid=0);
+  virtual int create_bucket(std::string& id, std::string& bucket, map<std::string,bufferlist>& attrs, bool exclusive = true, uint64_t auid = 0);
 
   /** Write/overwrite an object to the bucket storage. */
   virtual int put_obj_meta(std::string& id, std::string& bucket, std::string& obj, time_t *mtime,