--- /dev/null
+tasks:
+- install:
+- ceph:
+- rgw:
+ client.0:
+ port: 8000
+ client.1:
+ port: 8001
+- rgw-cloudtier:
+ client.1:
+ client.0:
+ cloud_storage_class: CLOUDTIER-CLIENT0
+ cloud_client: client.1
+ cloud_regular_storage_class: LUKEWARM
+ cloud_target_storage_class: FROZEN
+ cloud_retain_head_object: "true"
+ cloud_target_by_bucket: "true"
+ cloud_target_by_bucket_prefix: "rgwx-${storage_class}-${bucket}"
+ cloud_allow_read_through: "true"
+ cloud_read_through_restore_days: "5"
+ cloudtier_user:
+ cloud_secret: "abcefgh"
+ cloud_access_key: "12345678"
+- tox: [client.0]
+- s3tests:
+ client.0:
+ rgw_server: client.0
+ extra_attrs: ["target_by_bucket"]
+ lc_debug_interval: 10
+ rgw_restore_debug_interval: 20
+ rgw_restore_processor_period: 10
+ lifecycle_tests: True
+ cloudtier_tests: True
cloud_target_path:
cloud_allow_read_through:
cloud_read_through_restore_days:
+ cloud_target_by_bucket:
+ cloud_target_by_bucket_prefix:
cloudtier_user:
cloud_secret:
cloud_access_key:
def __init__(self, ctx, config):
super(RGWCloudTier, self).__init__(ctx, config)
+ @staticmethod
+ def _normalize_bool_option(value, option_name):
+ """
+ Normalize a boolean option to 'true' or 'false' string.
+ RGW parses these as case-sensitive s == "true".
+ """
+ if value is None:
+ return None
+ if isinstance(value, bool):
+ return "true" if value else "false"
+ if isinstance(value, str):
+ normalized = value.strip().lower()
+ if normalized not in ("true", "false"):
+ raise ConfigError(
+ f"rgw-cloudtier: {option_name} must be 'true' or 'false', got '{value}'")
+ return normalized
+ raise ConfigError(f"rgw-cloudtier: {option_name} must be a boolean or string, got {type(value)}")
+
def setup(self):
super(RGWCloudTier, self).setup()
cloud_retain_head_object = client_config.get('cloud_retain_head_object')
cloud_allow_read_through = client_config.get('cloud_allow_read_through')
cloud_read_through_restore_days = client_config.get('cloud_read_through_restore_days')
+ cloud_target_by_bucket = self._normalize_bool_option(
+ client_config.get('cloud_target_by_bucket'), 'cloud_target_by_bucket')
+ cloud_target_by_bucket_prefix = client_config.get('cloud_target_by_bucket_prefix')
cloudtier_user = client_config.get('cloudtier_user')
cloud_access_key = cloudtier_user.get('cloud_access_key')
tier_config_params += ",allow_read_through=" + cloud_allow_read_through
if (cloud_read_through_restore_days != None):
tier_config_params += ",read_through_restore_days=" + cloud_read_through_restore_days
+ if (cloud_target_by_bucket != None):
+ tier_config_params += ",target_by_bucket=" + cloud_target_by_bucket
+ if (cloud_target_by_bucket_prefix != None):
+ tier_config_params += ",target_by_bucket_prefix=" + cloud_target_by_bucket_prefix
log.info('Configuring cloud-s3 tier storage class type = %s', cloud_storage_class)
cloud_read_through_restore_days = client_rgw_config.get('cloud_read_through_restore_days')
if (cloud_read_through_restore_days != None):
s3tests_conf['s3 cloud']['read_through_restore_days'] = cloud_read_through_restore_days
+ cloud_target_by_bucket = client_rgw_config.get('cloud_target_by_bucket')
+ if (cloud_target_by_bucket != None):
+ s3tests_conf['s3 cloud']['target_by_bucket'] = cloud_target_by_bucket
+ cloud_target_by_bucket_prefix = client_rgw_config.get('cloud_target_by_bucket_prefix')
+ if (cloud_target_by_bucket_prefix != None):
+ s3tests_conf['s3 cloud']['target_by_bucket_prefix'] = cloud_target_by_bucket_prefix
(remote,) = ctx.cluster.only(client).remotes.keys()
conf_fp = BytesIO()