Paste Deploy最终使用swift.obj.server模块的app_factory()函数加载Object Server的WSGI Application,即swift.obj.server.ObjectController
以Object DELETE操作为例:
Object DELETE的API参见官网:
https://developer.openstack.org/api-ref/object-store/
Object DELETE操作代码分析
# swift/obj/server.py
class ObjectController(object):
def DELETE(self, request):
"""Handle HTTP DELETE requests for the Swift Object Server."""
#从请求参数req中获取device, partition, account, container, object以及storage policy的相关信息
device, partition, account, container, obj, policy_idx = \
get_name_and_placement(request, 5, 5, True)
req_timestamp = valid_timestamp(request)
try:
#Swift将Object在磁盘上的二进制数据抽象为一个DiskFile类,该类封装了
#创建、删除以及读写object等方法。
#而且可以通过使用不同的DiskFile类来达到实现不同Object Server的目的。
#此处通过调用get_diskfile()方法获取一个DiskFile类的实例。
disk_file = self.get_diskfile(
device, partition, account, container, obj,
policy_idx=policy_idx)
except DiskFileDeviceUnavailable:
return HTTPInsufficientStorage(drive=device, request=request)
try:
#读取object元数据
orig_metadata = disk_file.read_metadata()
except DiskFileExpired as e:
#过期处理
orig_timestamp = e.timestamp
orig_metadata = e.metadata
response_class = HTTPNotFound
except DiskFileDeleted as e:
#已经被删除
orig_timestamp = e.timestamp
orig_metadata = {}
response_class = HTTPNotFound
except (DiskFileNotExist, DiskFileQuarantined):
#不存在或者被auditor隔离(数据损坏)
orig_timestamp = 0
orig_metadata = {}
response_class = HTTPNotFound
else:
orig_timestamp = Timestamp(orig_metadata.get('X-Timestamp', 0))
if orig_timestamp < req_timestamp:
response_class = HTTPNoContent
else:
response_class = HTTPConflict
response_timestamp = max(orig_timestamp, req_timestamp)
#Swift为object提供了名为X-Delete-At的metadata
#X-Delete-At的意思是如果到了X-Delete-At所表示的时间戳,则将这个object删除。
#这个功能主要是给object-expirer准备的。
#object-expirer是一个后台进程,会定期检查并删掉那些已经过期的object
orig_delete_at = int(orig_metadata.get('X-Delete-At') or 0)
try:
req_if_delete_at_val = request.headers['x-if-delete-at']
req_if_delete_at = int(req_if_delete_at_val)
except KeyError:
pass
except ValueError:
return HTTPBadRequest(
request=request,
body='Bad X-If-Delete-At header value')
else:
# request includes x-if-delete-at; we must not place a tombstone
# if we can not verify the x-if-delete-at time
if not orig_timestamp:
# no object found at all
return HTTPNotFound()
#如果orig_delete_at和req_if_delete_at相等,则删除object
if orig_delete_at != req_if_delete_at:
return HTTPPreconditionFailed(
request=request,
body='X-If-Delete-At and X-Delete-At do not match')
else:
# differentiate success from no object at all
response_class = HTTPNoContent
if orig_delete_at:
#更新container的delete_at信息
self.delete_at_update('DELETE', orig_delete_at, account,
container, obj, request, device,
policy_idx)
if orig_timestamp < req_timestamp:
#删除object二进制文件,这里并没有真正地将文件删除,
#而是创建一个后缀为.ts(tombstone)的文件作为这个object的最新版本,
#后续由replicator来做真正的删除操作。
#Replicator是后台程序,不需要占用DELETE操作时间。
disk_file.delete(req_timestamp)
#更新container
self.container_update(
'DELETE', account, container, obj, request,
HeaderKeyDict({'x-timestamp': req_timestamp.internal}),
device, policy_idx)
return response_class(
request=request,
headers={'X-Backend-Timestamp': response_timestamp.internal})