swift 2.32.1__py2.py3-none-any.whl → 2.33.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- swift/account/server.py +1 -11
- swift/cli/info.py +28 -1
- swift-2.32.1.data/scripts/swift-recon-cron → swift/cli/recon_cron.py +4 -13
- swift/cli/reload.py +141 -0
- swift/common/daemon.py +12 -2
- swift/common/db.py +12 -8
- swift/common/http_protocol.py +76 -3
- swift/common/manager.py +18 -5
- swift/common/memcached.py +18 -12
- swift/common/middleware/proxy_logging.py +35 -27
- swift/common/middleware/s3api/acl_handlers.py +1 -1
- swift/common/middleware/s3api/controllers/__init__.py +3 -0
- swift/common/middleware/s3api/controllers/acl.py +3 -2
- swift/common/middleware/s3api/controllers/logging.py +2 -2
- swift/common/middleware/s3api/controllers/multi_upload.py +30 -6
- swift/common/middleware/s3api/controllers/object_lock.py +44 -0
- swift/common/middleware/s3api/s3api.py +4 -0
- swift/common/middleware/s3api/s3request.py +19 -12
- swift/common/middleware/s3api/s3response.py +13 -2
- swift/common/middleware/s3api/utils.py +1 -1
- swift/common/middleware/slo.py +395 -298
- swift/common/middleware/staticweb.py +45 -14
- swift/common/middleware/tempurl.py +132 -91
- swift/common/request_helpers.py +32 -8
- swift/common/storage_policy.py +1 -1
- swift/common/swob.py +5 -2
- swift/common/utils/__init__.py +230 -135
- swift/common/utils/timestamp.py +23 -2
- swift/common/wsgi.py +8 -0
- swift/container/backend.py +126 -21
- swift/container/replicator.py +42 -6
- swift/container/server.py +264 -145
- swift/container/sharder.py +50 -30
- swift/container/updater.py +1 -0
- swift/obj/auditor.py +2 -1
- swift/obj/diskfile.py +55 -19
- swift/obj/expirer.py +1 -13
- swift/obj/mem_diskfile.py +2 -1
- swift/obj/mem_server.py +1 -0
- swift/obj/replicator.py +2 -2
- swift/obj/server.py +12 -23
- swift/obj/updater.py +1 -0
- swift/obj/watchers/dark_data.py +72 -34
- swift/proxy/controllers/account.py +3 -2
- swift/proxy/controllers/base.py +217 -127
- swift/proxy/controllers/container.py +274 -289
- swift/proxy/controllers/obj.py +98 -141
- swift/proxy/server.py +2 -12
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-info +3 -0
- swift-2.33.1.data/scripts/swift-recon-cron +24 -0
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/AUTHORS +3 -1
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/METADATA +4 -3
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/RECORD +94 -91
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/WHEEL +1 -1
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/entry_points.txt +1 -0
- swift-2.33.1.dist-info/pbr.json +1 -0
- swift-2.32.1.dist-info/pbr.json +0 -1
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-audit +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-auditor +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-info +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-reaper +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-replicator +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-server +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-config +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-auditor +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-reconciler +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-replicator +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-server +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-sharder +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-sync +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-updater +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-dispersion-populate +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-dispersion-report +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-drive-audit +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-form-signature +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-get-nodes +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-init +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-auditor +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-expirer +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-info +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-reconstructor +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-relinker +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-replicator +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-server +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-updater +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-oldies +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-orphans +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-proxy-server +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-recon +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-reconciler-enqueue +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-ring-builder +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-ring-builder-analyzer +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-ring-composer +0 -0
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/LICENSE +0 -0
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/top_level.txt +0 -0
swift/container/server.py
CHANGED
@@ -141,17 +141,7 @@ class ContainerController(BaseStorageServer):
|
|
141
141
|
self.replicator_rpc = ContainerReplicatorRpc(
|
142
142
|
self.root, DATADIR, ContainerBroker, self.mount_check,
|
143
143
|
logger=self.logger)
|
144
|
-
|
145
|
-
self.logger.warning('Option auto_create_account_prefix is '
|
146
|
-
'deprecated. Configure '
|
147
|
-
'auto_create_account_prefix under the '
|
148
|
-
'swift-constraints section of '
|
149
|
-
'swift.conf. This option will '
|
150
|
-
'be ignored in a future release.')
|
151
|
-
self.auto_create_account_prefix = \
|
152
|
-
conf['auto_create_account_prefix']
|
153
|
-
else:
|
154
|
-
self.auto_create_account_prefix = AUTO_CREATE_ACCOUNT_PREFIX
|
144
|
+
self.auto_create_account_prefix = AUTO_CREATE_ACCOUNT_PREFIX
|
155
145
|
self.shards_account_prefix = (
|
156
146
|
self.auto_create_account_prefix + 'shards_')
|
157
147
|
if config_true_value(conf.get('allow_versions', 'f')):
|
@@ -511,59 +501,42 @@ class ContainerController(BaseStorageServer):
|
|
511
501
|
return HTTPInsufficientStorage(drive=drive, request=req)
|
512
502
|
if not self.check_free_space(drive):
|
513
503
|
return HTTPInsufficientStorage(drive=drive, request=req)
|
514
|
-
requested_policy_index = self.get_and_validate_policy_index(req)
|
515
|
-
broker = self._get_container_broker(drive, part, account, container)
|
516
|
-
if obj: # put container object
|
517
|
-
# obj put expects the policy_index header, default is for
|
518
|
-
# legacy support during upgrade.
|
519
|
-
obj_policy_index = requested_policy_index or 0
|
520
|
-
self._maybe_autocreate(
|
521
|
-
broker, req_timestamp, account, obj_policy_index, req)
|
522
|
-
# redirect if a shard exists for this object name
|
523
|
-
response = self._redirect_to_shard(req, broker, obj)
|
524
|
-
if response:
|
525
|
-
return response
|
526
|
-
|
527
|
-
broker.put_object(obj, req_timestamp.internal,
|
528
|
-
int(req.headers['x-size']),
|
529
|
-
wsgi_to_str(req.headers['x-content-type']),
|
530
|
-
wsgi_to_str(req.headers['x-etag']), 0,
|
531
|
-
obj_policy_index,
|
532
|
-
wsgi_to_str(req.headers.get(
|
533
|
-
'x-content-type-timestamp')),
|
534
|
-
wsgi_to_str(req.headers.get('x-meta-timestamp')))
|
535
|
-
return HTTPCreated(request=req)
|
536
504
|
|
505
|
+
broker = self._get_container_broker(drive, part, account, container)
|
506
|
+
if obj:
|
507
|
+
return self.PUT_object(req, broker, account, obj, req_timestamp)
|
537
508
|
record_type = req.headers.get('x-backend-record-type', '').lower()
|
538
509
|
if record_type == RECORD_TYPE_SHARD:
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
510
|
+
return self.PUT_shard(req, broker, account, req_timestamp)
|
511
|
+
else:
|
512
|
+
return self.PUT_container(req, broker, account,
|
513
|
+
container, req_timestamp)
|
514
|
+
|
515
|
+
@timing_stats()
|
516
|
+
def PUT_object(self, req, broker, account, obj, req_timestamp):
|
517
|
+
"""Put object into container."""
|
518
|
+
# obj put expects the policy_index header, default is for
|
519
|
+
# legacy support during upgrade.
|
520
|
+
requested_policy_index = self.get_and_validate_policy_index(req)
|
521
|
+
obj_policy_index = requested_policy_index or 0
|
522
|
+
self._maybe_autocreate(
|
523
|
+
broker, req_timestamp, account, obj_policy_index, req)
|
524
|
+
# redirect if a shard exists for this object name
|
525
|
+
response = self._redirect_to_shard(req, broker, obj)
|
526
|
+
if response:
|
527
|
+
return response
|
528
|
+
|
529
|
+
broker.put_object(obj, req_timestamp.internal,
|
530
|
+
int(req.headers['x-size']),
|
531
|
+
wsgi_to_str(req.headers['x-content-type']),
|
532
|
+
wsgi_to_str(req.headers['x-etag']), 0,
|
533
|
+
obj_policy_index,
|
534
|
+
wsgi_to_str(req.headers.get(
|
535
|
+
'x-content-type-timestamp')),
|
536
|
+
wsgi_to_str(req.headers.get('x-meta-timestamp')))
|
537
|
+
return HTTPCreated(request=req)
|
538
|
+
|
539
|
+
def _create_ok_resp(self, req, broker, created):
|
567
540
|
if created:
|
568
541
|
return HTTPCreated(request=req,
|
569
542
|
headers={'x-backend-storage-policy-index':
|
@@ -573,6 +546,45 @@ class ContainerController(BaseStorageServer):
|
|
573
546
|
headers={'x-backend-storage-policy-index':
|
574
547
|
broker.storage_policy_index})
|
575
548
|
|
549
|
+
@timing_stats()
|
550
|
+
def PUT_shard(self, req, broker, account, req_timestamp):
|
551
|
+
"""Put shards into container."""
|
552
|
+
requested_policy_index = self.get_and_validate_policy_index(req)
|
553
|
+
try:
|
554
|
+
# validate incoming data...
|
555
|
+
shard_ranges = [ShardRange.from_dict(sr)
|
556
|
+
for sr in json.loads(req.body)]
|
557
|
+
except (ValueError, KeyError, TypeError) as err:
|
558
|
+
return HTTPBadRequest('Invalid body: %r' % err)
|
559
|
+
created = self._maybe_autocreate(
|
560
|
+
broker, req_timestamp, account, requested_policy_index, req)
|
561
|
+
self._update_metadata(req, broker, req_timestamp, 'PUT')
|
562
|
+
if shard_ranges:
|
563
|
+
# TODO: consider writing the shard ranges into the pending
|
564
|
+
# file, but if so ensure an all-or-none semantic for the write
|
565
|
+
broker.merge_shard_ranges(shard_ranges)
|
566
|
+
return self._create_ok_resp(req, broker, created)
|
567
|
+
|
568
|
+
@timing_stats()
|
569
|
+
def PUT_container(self, req, broker, account, container, req_timestamp):
|
570
|
+
"""Update or create container."""
|
571
|
+
requested_policy_index = self.get_and_validate_policy_index(req)
|
572
|
+
if requested_policy_index is None:
|
573
|
+
# use the default index sent by the proxy if available
|
574
|
+
new_container_policy = req.headers.get(
|
575
|
+
'X-Backend-Storage-Policy-Default', int(POLICIES.default))
|
576
|
+
else:
|
577
|
+
new_container_policy = requested_policy_index
|
578
|
+
created = self._update_or_create(req, broker,
|
579
|
+
req_timestamp.internal,
|
580
|
+
new_container_policy,
|
581
|
+
requested_policy_index)
|
582
|
+
self._update_metadata(req, broker, req_timestamp, 'PUT')
|
583
|
+
resp = self.account_update(req, account, container, broker)
|
584
|
+
if resp:
|
585
|
+
return resp
|
586
|
+
return self._create_ok_resp(req, broker, created)
|
587
|
+
|
576
588
|
@public
|
577
589
|
@timing_stats(sample_rate=0.1)
|
578
590
|
def HEAD(self, req):
|
@@ -600,29 +612,42 @@ class ContainerController(BaseStorageServer):
|
|
600
612
|
resp.last_modified = Timestamp(headers['X-PUT-Timestamp']).ceil()
|
601
613
|
return resp
|
602
614
|
|
603
|
-
def
|
615
|
+
def update_shard_record(self, record, shard_record_full=True):
|
616
|
+
"""
|
617
|
+
Return the shard_range database record as a dict, the keys will depend
|
618
|
+
on the database fields provided in the record.
|
619
|
+
|
620
|
+
:param record: shard entry record, either ShardRange or Namespace.
|
621
|
+
:param shard_record_full: boolean, when true the timestamp field is
|
622
|
+
added as "last_modified" in iso format.
|
623
|
+
:returns: dict suitable for listing responses
|
604
624
|
"""
|
605
|
-
|
606
|
-
|
625
|
+
response = dict(record)
|
626
|
+
if shard_record_full:
|
627
|
+
created = record.timestamp
|
628
|
+
response['last_modified'] = Timestamp(created).isoformat
|
629
|
+
return response
|
630
|
+
|
631
|
+
def update_object_record(self, record):
|
632
|
+
"""
|
633
|
+
Perform mutation to container listing records that are common to all
|
634
|
+
serialization formats, and returns it as a dict.
|
607
635
|
|
608
636
|
Converts created time to iso timestamp.
|
609
637
|
Replaces size with 'swift_bytes' content type parameter.
|
610
638
|
|
611
|
-
:
|
639
|
+
:param record: object entry record
|
612
640
|
:returns: modified record
|
613
641
|
"""
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
'bytes': size, 'hash': etag, 'name': name_,
|
624
|
-
'content_type': content_type}
|
625
|
-
override_bytes_from_content_type(response, logger=self.logger)
|
642
|
+
# record is object info
|
643
|
+
(name, created, size, content_type, etag) = record[:5]
|
644
|
+
name_ = name.decode('utf8') if six.PY2 else name
|
645
|
+
if content_type is None:
|
646
|
+
return {'subdir': name_}
|
647
|
+
response = {
|
648
|
+
'bytes': size, 'hash': etag, 'name': name_,
|
649
|
+
'content_type': content_type}
|
650
|
+
override_bytes_from_content_type(response, logger=self.logger)
|
626
651
|
response['last_modified'] = Timestamp(created).isoformat
|
627
652
|
return response
|
628
653
|
|
@@ -685,11 +710,11 @@ class ContainerController(BaseStorageServer):
|
|
685
710
|
either the string or integer representation of
|
686
711
|
:data:`~swift.common.utils.ShardRange.STATES`.
|
687
712
|
|
688
|
-
|
689
|
-
``listing`` will cause the listing to include all shard ranges
|
690
|
-
state suitable for contributing to an object listing
|
691
|
-
will cause the listing to include all shard ranges
|
692
|
-
suitable to accept an object update.
|
713
|
+
Alias values may be used in a ``states`` parameter value. The
|
714
|
+
``listing`` alias will cause the listing to include all shard ranges
|
715
|
+
in a state suitable for contributing to an object listing. The
|
716
|
+
``updating`` alias will cause the listing to include all shard ranges
|
717
|
+
in a state suitable to accept an object update.
|
693
718
|
|
694
719
|
If either of these aliases is used then the shard range listing will
|
695
720
|
if necessary be extended with a synthesised 'filler' range in order
|
@@ -698,6 +723,23 @@ class ContainerController(BaseStorageServer):
|
|
698
723
|
uncovered tail of the requested name range and will point back to the
|
699
724
|
same container.
|
700
725
|
|
726
|
+
The ``auditing`` alias will cause the listing to include all shard
|
727
|
+
ranges in a state useful to the sharder while auditing a shard
|
728
|
+
container. This alias will not cause a 'filler' range to be added,
|
729
|
+
but will cause the container's own shard range to be included in the
|
730
|
+
listing. For now, ``auditing`` is only supported when
|
731
|
+
'X-Backend-Record-Shard-Format' is 'full'.
|
732
|
+
|
733
|
+
* Shard range listings can be simplified to include only Namespace
|
734
|
+
only attributes (name, lower and upper) if the caller send the header
|
735
|
+
``X-Backend-Record-Shard-Format`` with value 'namespace' as a hint
|
736
|
+
that it would prefer namespaces. If this header doesn't exist or the
|
737
|
+
value is 'full', the listings will default to include all attributes
|
738
|
+
of shard ranges. But if params has includes/marker/end_marker then
|
739
|
+
the response will be full shard ranges, regardless the header of
|
740
|
+
``X-Backend-Record-Shard-Format``. The response header
|
741
|
+
``X-Backend-Record-Type`` will tell the user what type it gets back.
|
742
|
+
|
701
743
|
* Listings are not normally returned from a deleted container. However,
|
702
744
|
the ``X-Backend-Override-Deleted`` header may be used with a value in
|
703
745
|
:attr:`swift.common.utils.TRUE_VALUES` to force a shard range
|
@@ -709,13 +751,6 @@ class ContainerController(BaseStorageServer):
|
|
709
751
|
"""
|
710
752
|
drive, part, account, container, obj = get_obj_name_and_placement(req)
|
711
753
|
params = validate_container_params(req)
|
712
|
-
path = params.get('path')
|
713
|
-
prefix = params.get('prefix')
|
714
|
-
delimiter = params.get('delimiter')
|
715
|
-
marker = params.get('marker', '')
|
716
|
-
end_marker = params.get('end_marker')
|
717
|
-
limit = params['limit']
|
718
|
-
reverse = config_true_value(params.get('reverse'))
|
719
754
|
out_content_type = listing_formats.get_listing_content_type(req)
|
720
755
|
try:
|
721
756
|
check_drive(self.root, drive, self.mount_check)
|
@@ -730,70 +765,154 @@ class ContainerController(BaseStorageServer):
|
|
730
765
|
if record_type == 'auto' and db_state in (SHARDING, SHARDED):
|
731
766
|
record_type = 'shard'
|
732
767
|
if record_type == 'shard':
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
768
|
+
return self.GET_shard(req, broker, container, params, info,
|
769
|
+
is_deleted, out_content_type)
|
770
|
+
else:
|
771
|
+
return self.GET_object(req, broker, container, params, info,
|
772
|
+
is_deleted, out_content_type)
|
773
|
+
|
774
|
+
@timing_stats()
|
775
|
+
def GET_shard(self, req, broker, container, params, info,
|
776
|
+
is_deleted, out_content_type):
|
777
|
+
"""
|
778
|
+
Returns a list of persisted shard ranges or namespaces in response.
|
779
|
+
|
780
|
+
:param req: swob.Request object
|
781
|
+
:param broker: container DB broker object
|
782
|
+
:param container: container name
|
783
|
+
:param params: the request params.
|
784
|
+
:param info: the global info for the container
|
785
|
+
:param is_deleted: the is_deleted status for the container.
|
786
|
+
:param out_content_type: content type as a string.
|
787
|
+
:returns: an instance of :class:`swift.common.swob.Response`
|
788
|
+
"""
|
789
|
+
override_deleted = info and config_true_value(
|
790
|
+
req.headers.get('x-backend-override-deleted', False))
|
791
|
+
resp_headers = gen_resp_headers(
|
792
|
+
info, is_deleted=is_deleted and not override_deleted)
|
793
|
+
|
794
|
+
if is_deleted and not override_deleted:
|
795
|
+
return HTTPNotFound(request=req, headers=resp_headers)
|
796
|
+
|
797
|
+
marker = params.get('marker', '')
|
798
|
+
end_marker = params.get('end_marker')
|
799
|
+
reverse = config_true_value(params.get('reverse'))
|
800
|
+
states = params.get('states')
|
801
|
+
includes = params.get('includes')
|
802
|
+
include_deleted = config_true_value(
|
803
|
+
req.headers.get('x-backend-include-deleted', False))
|
804
|
+
|
805
|
+
resp_headers['X-Backend-Record-Type'] = 'shard'
|
806
|
+
override_filter_hdr = req.headers.get(
|
807
|
+
'x-backend-override-shard-name-filter', '').lower()
|
808
|
+
if override_filter_hdr == info.get('db_state') == 'sharded':
|
809
|
+
# respect the request to send back *all* ranges if the db is in
|
810
|
+
# sharded state
|
811
|
+
resp_headers['X-Backend-Override-Shard-Name-Filter'] = 'true'
|
812
|
+
marker = end_marker = includes = None
|
813
|
+
reverse = False
|
814
|
+
fill_gaps = include_own = False
|
815
|
+
if states:
|
816
|
+
states = list_from_csv(states)
|
817
|
+
fill_gaps = any(('listing' in states, 'updating' in states))
|
818
|
+
# The 'auditing' state alias is used by the sharder during
|
819
|
+
# shard audit; if the shard is shrinking then it needs to get
|
820
|
+
# acceptor shard ranges, which may be the root container
|
821
|
+
# itself, so use include_own.
|
822
|
+
include_own = 'auditing' in states
|
823
|
+
try:
|
824
|
+
states = broker.resolve_shard_range_states(states)
|
825
|
+
except ValueError:
|
826
|
+
return HTTPBadRequest(request=req, body='Bad state')
|
827
|
+
|
828
|
+
# For record type of 'shard', user can specify an additional header
|
829
|
+
# to ask for list of Namespaces instead of full ShardRanges.
|
830
|
+
# This will allow proxy server who is going to retrieve Namespace
|
831
|
+
# to talk to older version of container servers who don't support
|
832
|
+
# Namespace yet during upgrade.
|
833
|
+
shard_format = req.headers.get(
|
834
|
+
'x-backend-record-shard-format', 'full').lower()
|
835
|
+
if shard_format == 'namespace':
|
836
|
+
resp_headers['X-Backend-Record-Shard-Format'] = 'namespace'
|
837
|
+
# Namespace GET does not support all the options of Shard Range
|
838
|
+
# GET: 'x-backend-include-deleted' cannot be supported because
|
839
|
+
# there is no way for a Namespace to indicate the deleted state;
|
840
|
+
# the 'auditing' state query parameter is not supported because it
|
841
|
+
# is specific to the sharder which only requests full shard ranges.
|
842
|
+
if include_deleted:
|
843
|
+
return HTTPBadRequest(
|
844
|
+
request=req, body='No include_deleted for namespace GET')
|
845
|
+
if include_own:
|
846
|
+
return HTTPBadRequest(
|
847
|
+
request=req, body='No auditing state for namespace GET')
|
848
|
+
shard_format_full = False
|
849
|
+
container_list = broker.get_namespaces(
|
850
|
+
marker, end_marker, includes, reverse, states, fill_gaps)
|
851
|
+
else:
|
852
|
+
resp_headers['X-Backend-Record-Shard-Format'] = 'full'
|
853
|
+
shard_format_full = True
|
764
854
|
container_list = broker.get_shard_ranges(
|
765
855
|
marker, end_marker, includes, reverse, states=states,
|
766
856
|
include_deleted=include_deleted, fill_gaps=fill_gaps,
|
767
857
|
include_own=include_own)
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
858
|
+
listing = [self.update_shard_record(record, shard_format_full)
|
859
|
+
for record in container_list]
|
860
|
+
return self._create_GET_response(req, out_content_type, info,
|
861
|
+
resp_headers, broker.metadata,
|
862
|
+
container, listing)
|
863
|
+
|
864
|
+
@timing_stats()
|
865
|
+
def GET_object(self, req, broker, container, params, info,
|
866
|
+
is_deleted, out_content_type):
|
867
|
+
"""
|
868
|
+
Returns a list of objects in response.
|
869
|
+
|
870
|
+
:param req: swob.Request object
|
871
|
+
:param broker: container DB broker object
|
872
|
+
:param container: container name
|
873
|
+
:param params: the request params.
|
874
|
+
:param info: the global info for the container
|
875
|
+
:param is_deleted: the is_deleted status for the container.
|
876
|
+
:param out_content_type: content type as a string.
|
877
|
+
:returns: an instance of :class:`swift.common.swob.Response`
|
878
|
+
"""
|
879
|
+
marker = params.get('marker', '')
|
880
|
+
end_marker = params.get('end_marker')
|
881
|
+
reverse = config_true_value(params.get('reverse'))
|
882
|
+
path = params.get('path')
|
883
|
+
prefix = params.get('prefix')
|
884
|
+
delimiter = params.get('delimiter')
|
885
|
+
limit = params['limit']
|
886
|
+
requested_policy_index = self.get_and_validate_policy_index(req)
|
887
|
+
resp_headers = gen_resp_headers(info, is_deleted=is_deleted)
|
888
|
+
if is_deleted:
|
889
|
+
return HTTPNotFound(request=req, headers=resp_headers)
|
890
|
+
resp_headers['X-Backend-Record-Type'] = 'object'
|
891
|
+
storage_policy_index = (
|
892
|
+
requested_policy_index if requested_policy_index is not None
|
893
|
+
else info['storage_policy_index'])
|
894
|
+
resp_headers['X-Backend-Record-Storage-Policy-Index'] = \
|
895
|
+
storage_policy_index
|
896
|
+
# Use the retired db while container is in process of sharding,
|
897
|
+
# otherwise use current db
|
898
|
+
src_broker = broker.get_brokers()[0]
|
899
|
+
container_list = src_broker.list_objects_iter(
|
900
|
+
limit, marker, end_marker, prefix, delimiter, path,
|
901
|
+
storage_policy_index=storage_policy_index,
|
902
|
+
reverse=reverse, allow_reserved=req.allow_reserved_names)
|
903
|
+
listing = [self.update_object_record(record)
|
904
|
+
for record in container_list]
|
905
|
+
return self._create_GET_response(req, out_content_type, info,
|
906
|
+
resp_headers, broker.metadata,
|
907
|
+
container, listing)
|
908
|
+
|
909
|
+
def _create_GET_response(self, req, out_content_type, info, resp_headers,
|
910
|
+
metadata, container, listing):
|
791
911
|
for key, (value, _timestamp) in metadata.items():
|
792
912
|
if value and (key.lower() in self.save_headers or
|
793
913
|
is_sys_or_user_meta('container', key)):
|
794
914
|
resp_headers[str_to_wsgi(key)] = str_to_wsgi(value)
|
795
|
-
|
796
|
-
for record in container_list]
|
915
|
+
|
797
916
|
if out_content_type.endswith('/xml'):
|
798
917
|
body = listing_formats.container_to_xml(listing, container)
|
799
918
|
elif out_content_type.endswith('/json'):
|