Skip to content

Commit 4a58605

Browse files
committed
Allow to use bucket storage policy
1 parent 5820e7b commit 4a58605

File tree

3 files changed

+60
-14
lines changed

3 files changed

+60
-14
lines changed

conf/default.cfg

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ sds_default_account = myaccount
4343
# backend.
4444
oio_storage_policies=SINGLE,EC123,EC64,THREECOPIES,FOURCOPIES
4545

46+
# Enable or disable the use of bucket storage policy.
47+
# When enabled, and if a storage policy is defined for a bucket (root container),
48+
# all objects in this bucket will be uploaded with this storage policy.
49+
# use_bucket_storage_policy = false
50+
4651
# The configuration to chose the policy when unspecified. All the storage
4752
# policies mentioned here must have been listed in the `oio_storage_policies`
4853
# configuration directive. The string must respect the subsequent format:

oioswift/proxy/controllers/obj.py

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -215,30 +215,66 @@ def enforce_versioning(self, req):
215215
# first and an update of versioning mode may not be detected.
216216
memcache = getattr(self.app, 'memcache', None) or \
217217
req.environ.get('swift.cache')
218-
if memcache is None:
219-
return None
220218

221219
key = "/".join(("versioning", self.account_name, root_container))
222-
val = memcache.get(key)
223-
if val is not None:
224-
if val != '':
225-
req.headers[FORCEVERSIONING_HEADER] = val
220+
value = memcache.get(key)
221+
if value is not None:
222+
if value:
223+
req.headers[FORCEVERSIONING_HEADER] = value
226224
return
227225

228226
oio_headers = {REQID_HEADER: self.trans_id}
229-
oio_cache = req.environ.get('oio.cache')
230227
perfdata = req.environ.get('oio.perfdata')
231228
try:
232229
meta = self.app.storage.container_get_properties(
233230
self.account_name, root_container, headers=oio_headers,
234-
cache=oio_cache, perfdata=perfdata)
231+
perfdata=perfdata)
232+
except exceptions.NoSuchContainer:
233+
raise HTTPNotFound(request=req)
234+
235+
value = meta['system'].get('sys.m2.policy.version')
236+
memcache.set(key, value or '')
237+
if value:
238+
req.headers[FORCEVERSIONING_HEADER] = value
239+
240+
def use_bucket_storage_policy(self, req):
241+
"""
242+
Enforce the storage policy mode of a container just before executing
243+
an object operation. This is useful when the current object is not
244+
stored in the "main" container but in a shard,
245+
where the storage policy mode may not have been set yet.
246+
"""
247+
if not self.app.use_bucket_storage_policy:
248+
return None
249+
250+
root_container = req.headers.get(BUCKET_NAME_HEADER)
251+
if root_container is None:
252+
return None
253+
if root_container.endswith(MULTIUPLOAD_SUFFIX):
254+
root_container = root_container[:-len(MULTIUPLOAD_SUFFIX)]
255+
256+
# We can't use _get_info_from_caches as it would use local worker cache
257+
# first and an update of storage policy mode may not be detected.
258+
memcache = getattr(self.app, 'memcache', None) or \
259+
req.environ.get('swift.cache')
260+
261+
key = "/".join(("policy", self.account_name, root_container))
262+
value = memcache.get(key)
263+
if value is not None:
264+
return value or None
265+
266+
oio_headers = {REQID_HEADER: self.trans_id}
267+
perfdata = req.environ.get('oio.perfdata')
268+
try:
269+
meta = self.app.storage.container_get_properties(
270+
self.account_name, root_container, headers=oio_headers,
271+
perfdata=perfdata)
235272
except exceptions.NoSuchContainer:
236273
raise HTTPNotFound(request=req)
274+
value = meta['system'].get('sys.m2.policy.storage')
237275

238-
val = meta['system'].get('sys.m2.policy.version', '')
239-
memcache.set(key, val)
240-
if val:
241-
req.headers[FORCEVERSIONING_HEADER] = val
276+
memcache.set(key, value or '')
277+
return value
242278

243279
def get_object_head_resp(self, req):
244280
storage = self.app.storage
@@ -647,15 +683,15 @@ def _object_create(self, account, container, **kwargs):
647683
def _store_object(self, req, data_source, headers):
648684
content_type = req.headers.get('content-type', 'octet/stream')
649685
policy = None
650-
container_info = self.container_info(self.account_name,
651-
self.container_name, req)
652686
if 'X-Oio-Storage-Policy' in req.headers:
653687
policy = req.headers.get('X-Oio-Storage-Policy')
654688
if not self.app.POLICIES.get_by_name(policy):
655689
raise HTTPBadRequest(
656690
"invalid policy '%s', must be in %s" %
657691
(policy, self.app.POLICIES.by_name.keys()))
658692
else:
693+
container_info = self.container_info(self.account_name,
694+
self.container_name, req)
659695
try:
660696
policy_index = int(
661697
req.headers.get('X-Backend-Storage-Policy-Index',
@@ -665,6 +701,8 @@ def _store_object(self, req, data_source, headers):
665701
if policy_index != 0:
666702
policy = self.app.POLICIES.get_by_index(policy_index).name
667703
else:
704+
policy = self.use_bucket_storage_policy(req)
705+
if policy is None:
668706
content_length = int(req.headers.get('content-length', 0))
669707
policy = self._get_auto_policy_from_size(content_length)
670708

oioswift/server.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ def __init__(self, conf, memcache=None, logger=None, account_ring=None,
5959
for k, v in conf.iteritems()
6060
if k.startswith("sds_")}
6161

62+
self.use_bucket_storage_policy = config_true_value(
63+
conf.get('use_bucket_storage_policy', 'false'))
64+
6265
self.oio_stgpol = []
6366
if 'auto_storage_policies' in conf:
6467
for elem in conf['auto_storage_policies'].split(','):

0 commit comments

Comments
 (0)