Last active
August 18, 2016 20:24
-
-
Save pauldardeau/0cb8acfa82d7f2f75089ab2c3c0fc3f9 to your computer and use it in GitHub Desktop.
swift object metadata
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Read from filesystem extended attributes (through diskfile.py) for a HEAD request | |
| Written to filesystem extended attributes (through diskfile.py) as part of a POST request | |
| To set custom object metadata - https://prosuncsedu.wordpress.com/2015/12/09/set-metadata-on-openstack-swift-objects/ | |
| swift/obj/server.py | |
| ===================== | |
| def HEAD(self, request): | |
| """Handle HTTP HEAD requests for the Swift Object Server.""" | |
| device, partition, account, container, obj, policy = \ | |
| get_name_and_placement(request, 5, 5, True) | |
| try: | |
| disk_file = self.get_diskfile( | |
| device, partition, account, container, obj, | |
| policy=policy) | |
| except DiskFileDeviceUnavailable: | |
| return HTTPInsufficientStorage(drive=device, request=request) | |
| try: | |
| metadata = disk_file.read_metadata() | |
| except DiskFileXattrNotSupported: | |
| return HTTPInsufficientStorage(drive=device, request=request) | |
| except (DiskFileNotExist, DiskFileQuarantined) as e: | |
| headers = {} | |
| if hasattr(e, 'timestamp'): | |
| headers['X-Backend-Timestamp'] = e.timestamp.internal | |
| return HTTPNotFound(request=request, headers=headers, | |
| conditional_response=True) | |
| def POST(self, request): | |
| """Handle HTTP POST requests for the Swift Object Server.""" | |
| device, partition, account, container, obj, policy = \ | |
| get_name_and_placement(request, 5, 5, True) | |
| req_timestamp = valid_timestamp(request) | |
| new_delete_at = int(request.headers.get('X-Delete-At') or 0) | |
| if new_delete_at and new_delete_at < time.time(): | |
| return HTTPBadRequest(body='X-Delete-At in past', request=request, | |
| content_type='text/plain') | |
| ... | |
| try: | |
| disk_file.write_metadata(metadata) | |
| except (DiskFileXattrNotSupported, DiskFileNoSpace): | |
| return HTTPInsufficientStorage(drive=device, request=request) | |
| swift/obj/diskfile.py | |
| ===================== | |
| METADATA_KEY = 'user.swift.metadata' | |
| read_metadata - Helper function to read the pickled metadata from an object file. | |
| def read_metadata(fd): | |
| """ | |
| Helper function to read the pickled metadata from an object file. | |
| :param fd: file descriptor or filename to load the metadata from | |
| :returns: dictionary of metadata | |
| """ | |
| metadata = b'' | |
| key = 0 | |
| try: | |
| while True: | |
| metadata += xattr.getxattr(fd, '%s%s' % (METADATA_KEY, | |
| (key or ''))) | |
| key += 1 | |
| except (IOError, OSError) as e: | |
| for err in 'ENOTSUP', 'EOPNOTSUPP': | |
| if hasattr(errno, err) and e.errno == getattr(errno, err): | |
| msg = "Filesystem at %s does not support xattr" % \ | |
| _get_filename(fd) | |
| logging.exception(msg) | |
| raise DiskFileXattrNotSupported(e) | |
| if e.errno == errno.ENOENT: | |
| raise DiskFileNotExist() | |
| # TODO: we might want to re-raise errors that don't denote a missing | |
| # xattr here. Seems to be ENODATA on linux and ENOATTR on BSD/OSX. | |
| return pickle.loads(metadata) | |
| def write_metadata(fd, metadata, xattr_size=65536): | |
| """ | |
| Helper function to write pickled metadata for an object file. | |
| :param fd: file descriptor or filename to write the metadata | |
| :param metadata: metadata to write | |
| """ | |
| metastr = pickle.dumps(metadata, PICKLE_PROTOCOL) | |
| key = 0 | |
| while metastr: | |
| try: | |
| xattr.setxattr(fd, '%s%s' % (METADATA_KEY, key or ''), | |
| metastr[:xattr_size]) | |
| metastr = metastr[xattr_size:] | |
| key += 1 | |
| except IOError as e: | |
| for err in 'ENOTSUP', 'EOPNOTSUPP': | |
| if hasattr(errno, err) and e.errno == getattr(errno, err): | |
| msg = "Filesystem at %s does not support xattr" % \ | |
| _get_filename(fd) | |
| logging.exception(msg) | |
| raise DiskFileXattrNotSupported(e) | |
| if e.errno in (errno.ENOSPC, errno.EDQUOT): | |
| msg = "No space left on device for %s" % _get_filename(fd) | |
| logging.exception(msg) | |
| raise DiskFileNoSpace() | |
| raise |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment