objects and the other deletes them. Read the troubleshooting section
of the dynamic resharding docs for details.
+* RGW: Bucket naming restrictions have changed and likely to cause
+ InvalidBucketName errors. We recommend to set ``rgw_relaxed_s3_bucket_names``
+ option to true as a workaround.
+
* In the Zabbix Mgr Module there was a typo in the key being send
to Zabbix for PGs in backfill_wait state. The key that was sent
was 'wait_backfill' and the correct name is 'backfill_wait'.
In general, bucket names should follow domain name constraints.
- Bucket names must be unique.
-- Bucket names must begin and end with a lowercase letter.
-- Bucket names may contain a dash (-).
+- Bucket names cannot be formatted as IP address.
+- Bucket names can be between 3 and 63 characters long.
+- Bucket names must not contain uppercase characters or underscores.
+- Bucket names must start with a lowercase letter or number.
+- Bucket names must be a series of one or more labels. Adjacent labels are separated by a single period (.). Bucket names can contain lowercase letters, numbers, and hyphens. Each label must start and end with a lowercase letter or a number.
+
+.. note:: The above constraints are relaxed if the option 'rgw_relaxed_s3_bucket_names' is set to true except that the bucket names must still be unique, cannot be formatted as IP address and can contain letters, numbers, periods, dashes and underscores for up to 255 characters long.
Syntax
~~~~~~
clients:
client.0:
- rgw/s3_bucket_quota.pl
+overrides:
+ ceph:
+ conf:
+ client:
+ rgw relaxed s3 bucket names: true
clients:
client.0:
- rgw/s3_multipart_upload.pl
+overrides:
+ ceph:
+ conf:
+ client:
+ rgw relaxed s3 bucket names: true
clients:
client.0:
- rgw/s3_user_quota.pl
+overrides:
+ ceph:
+ conf:
+ client:
+ rgw relaxed s3 bucket names: true
clients:
client.0:
- rgw/s3_bucket_quota.pl
+overrides:
+ ceph:
+ conf:
+ client:
+ rgw relaxed s3 bucket names: true
clients:
client.0:
- rgw/s3_multipart_upload.pl
+overrides:
+ ceph:
+ conf:
+ client:
+ rgw relaxed s3 bucket names: true
clients:
client.0:
- rgw/s3_user_quota.pl
+overrides:
+ ceph:
+ conf:
+ client:
+ rgw relaxed s3 bucket names: true
assert out['usage']['rgw.main']['num_objects'] == 0
# create a bucket for deletion stats
- useless_bucket = connection.create_bucket('useless_bucket')
+ useless_bucket = connection.create_bucket('useless-bucket')
useless_key = useless_bucket.new_key('useless_key')
useless_key.set_contents_from_string('useless string')
int RGWCreateBucket_ObjStore_S3::get_params()
{
RGWAccessControlPolicy_S3 s3policy(s->cct);
+ bool relaxed_names = s->cct->_conf->rgw_relaxed_s3_bucket_names;
+
+ int r = valid_s3_bucket_name(s->bucket_name, relaxed_names);
+ if (r)
+ return r;
- int r = create_s3_policy(s, store, s3policy, s->owner);
+ r = create_s3_policy(s, store, s3policy, s->owner);
if (r < 0)
return r;
int RGWHandler_REST_S3::postauth_init()
{
struct req_init_state *t = &s->init_state;
- bool relaxed_names = s->cct->_conf->rgw_relaxed_s3_bucket_names;
rgw_parse_url_bucket(t->url_bucket, s->user->user_id.tenant,
s->bucket_tenant, s->bucket_name);
if (ret)
return ret;
if (!s->bucket_name.empty()) {
- ret = valid_s3_bucket_name(s->bucket_name, relaxed_names);
- if (ret)
- return ret;
ret = validate_object_name(s->object.name);
if (ret)
return ret;
ret = rgw_validate_tenant_name(s->src_tenant_name);
if (ret)
return ret;
- ret = valid_s3_bucket_name(s->src_bucket_name, relaxed_names);
- if (ret)
- return ret;
}
const char *mfa = s->info.env->get("HTTP_X_AMZ_MFA");
ret = rgw_validate_tenant_name(s->bucket_tenant);
if (ret)
return ret;
- bool relaxed_names = s->cct->_conf->rgw_relaxed_s3_bucket_names;
if (!s->bucket_name.empty()) {
- ret = valid_s3_bucket_name(s->bucket_name, relaxed_names);
- if (ret)
- return ret;
ret = validate_object_name(s->object.name);
if (ret)
return ret;
// This function enforces Amazon's spec for bucket names.
// (The requirements, not the recommendations.)
int len = name.size();
+ int max = (relaxed ? 255 : 63);
+
if (len < 3) {
// Name too short
return -ERR_INVALID_BUCKET_NAME;
- } else if (len > 255) {
+ } else if (len > max) {
// Name too long
return -ERR_INVALID_BUCKET_NAME;
}
- // bucket names must start with a number, letter, or underscore
+ // bucket names must start with a number or letter
if (!(isalpha(name[0]) || isdigit(name[0]))) {
if (!relaxed)
return -ERR_INVALID_BUCKET_NAME;
return -ERR_INVALID_BUCKET_NAME;
}
+ // bucket names must end with a number or letter
+ if (!(isalpha(name[len-1]) || isdigit(name[len-1])))
+ if (!relaxed)
+ return -ERR_INVALID_BUCKET_NAME;
+
for (const char *s = name.c_str(); *s; ++s) {
char c = *s;
- if (isdigit(c) || (c == '.'))
- continue;
- if (isalpha(c))
+ if (isdigit(c))
continue;
- if ((c == '-') || (c == '_'))
+
+ if (isalpha(c)) {
+ // name cannot contain uppercase letters
+ if (relaxed || islower(c))
+ continue;
+ }
+
+ if (c == '_')
+ // name cannot contain underscore
+ if (relaxed)
+ continue;
+
+ if (c == '-')
continue;
+
+ if (c == '.') {
+ if (!relaxed && s && *s) {
+ // name cannot have consecutive periods or dashes
+ // adjacent to periods
+ // ensure s is neither the first nor the last character
+ char p = *(s-1);
+ char n = *(s+1);
+ if ((p != '-') && (n != '.') && (n != '-'))
+ continue;
+ } else {
+ continue;
+ }
+ }
+
// Invalid character
return -ERR_INVALID_BUCKET_NAME;
}