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,
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";
OPT_KEY_CREATE,
OPT_KEY_RM,
OPT_BUCKETS_LIST,
+ OPT_BUCKET_LINK,
OPT_BUCKET_UNLINK,
OPT_POLICY,
OPT_LOG_SHOW,
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) {
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);
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();
}
}
+ 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)
}
-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) {
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,
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. */
* 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);
* 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,