Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Unified Diff: tools/telemetry/third_party/gsutil/third_party/boto/boto/glacier/vault.py

Issue 1260493004: Revert "Add gsutil 4.13 to telemetry/third_party" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/third_party/gsutil/third_party/boto/boto/glacier/vault.py
diff --git a/tools/telemetry/third_party/gsutil/third_party/boto/boto/glacier/vault.py b/tools/telemetry/third_party/gsutil/third_party/boto/boto/glacier/vault.py
deleted file mode 100644
index 45d276cadb56347130133e509f98c00359e6ce3a..0000000000000000000000000000000000000000
--- a/tools/telemetry/third_party/gsutil/third_party/boto/boto/glacier/vault.py
+++ /dev/null
@@ -1,450 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2012 Thomas Parslow http://almostobsolete.net/
-# Copyright (c) 2012 Robie Basak <robie@justgohome.co.uk>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish, dis-
-# tribute, sublicense, and/or sell copies of the Software, and to permit
-# persons to whom the Software is furnished to do so, subject to the fol-
-# lowing conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
-# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-#
-import codecs
-from boto.glacier.exceptions import UploadArchiveError
-from boto.glacier.job import Job
-from boto.glacier.writer import compute_hashes_from_fileobj, \
- resume_file_upload, Writer
-from boto.glacier.concurrent import ConcurrentUploader
-from boto.glacier.utils import minimum_part_size, DEFAULT_PART_SIZE
-import os.path
-
-
-_MEGABYTE = 1024 * 1024
-_GIGABYTE = 1024 * _MEGABYTE
-
-MAXIMUM_ARCHIVE_SIZE = 10000 * 4 * _GIGABYTE
-MAXIMUM_NUMBER_OF_PARTS = 10000
-
-
-class Vault(object):
-
- DefaultPartSize = DEFAULT_PART_SIZE
- SingleOperationThreshold = 100 * _MEGABYTE
-
- ResponseDataElements = (('VaultName', 'name', None),
- ('VaultARN', 'arn', None),
- ('CreationDate', 'creation_date', None),
- ('LastInventoryDate', 'last_inventory_date', None),
- ('SizeInBytes', 'size', 0),
- ('NumberOfArchives', 'number_of_archives', 0))
-
- def __init__(self, layer1, response_data=None):
- self.layer1 = layer1
- if response_data:
- for response_name, attr_name, default in self.ResponseDataElements:
- value = response_data[response_name]
- setattr(self, attr_name, value)
- else:
- for response_name, attr_name, default in self.ResponseDataElements:
- setattr(self, attr_name, default)
-
- def __repr__(self):
- return 'Vault("%s")' % self.arn
-
- def delete(self):
- """
- Delete's this vault. WARNING!
- """
- self.layer1.delete_vault(self.name)
-
- def upload_archive(self, filename, description=None):
- """
- Adds an archive to a vault. For archives greater than 100MB the
- multipart upload will be used.
-
- :type file: str
- :param file: A filename to upload
-
- :type description: str
- :param description: An optional description for the archive.
-
- :rtype: str
- :return: The archive id of the newly created archive
- """
- if os.path.getsize(filename) > self.SingleOperationThreshold:
- return self.create_archive_from_file(filename, description=description)
- return self._upload_archive_single_operation(filename, description)
-
- def _upload_archive_single_operation(self, filename, description):
- """
- Adds an archive to a vault in a single operation. It's recommended for
- archives less than 100MB
-
- :type file: str
- :param file: A filename to upload
-
- :type description: str
- :param description: A description for the archive.
-
- :rtype: str
- :return: The archive id of the newly created archive
- """
- with open(filename, 'rb') as fileobj:
- linear_hash, tree_hash = compute_hashes_from_fileobj(fileobj)
- fileobj.seek(0)
- response = self.layer1.upload_archive(self.name, fileobj,
- linear_hash, tree_hash,
- description)
- return response['ArchiveId']
-
- def create_archive_writer(self, part_size=DefaultPartSize,
- description=None):
- """
- Create a new archive and begin a multi-part upload to it.
- Returns a file-like object to which the data for the archive
- can be written. Once all the data is written the file-like
- object should be closed, you can then call the get_archive_id
- method on it to get the ID of the created archive.
-
- :type part_size: int
- :param part_size: The part size for the multipart upload.
-
- :type description: str
- :param description: An optional description for the archive.
-
- :rtype: :class:`boto.glacier.writer.Writer`
- :return: A Writer object that to which the archive data
- should be written.
- """
- response = self.layer1.initiate_multipart_upload(self.name,
- part_size,
- description)
- return Writer(self, response['UploadId'], part_size=part_size)
-
- def create_archive_from_file(self, filename=None, file_obj=None,
- description=None, upload_id_callback=None):
- """
- Create a new archive and upload the data from the given file
- or file-like object.
-
- :type filename: str
- :param filename: A filename to upload
-
- :type file_obj: file
- :param file_obj: A file-like object to upload
-
- :type description: str
- :param description: An optional description for the archive.
-
- :type upload_id_callback: function
- :param upload_id_callback: if set, call with the upload_id as the
- only parameter when it becomes known, to enable future calls
- to resume_archive_from_file in case resume is needed.
-
- :rtype: str
- :return: The archive id of the newly created archive
- """
- part_size = self.DefaultPartSize
- if not file_obj:
- file_size = os.path.getsize(filename)
- try:
- part_size = minimum_part_size(file_size, part_size)
- except ValueError:
- raise UploadArchiveError("File size of %s bytes exceeds "
- "40,000 GB archive limit of Glacier.")
- file_obj = open(filename, "rb")
- writer = self.create_archive_writer(
- description=description,
- part_size=part_size)
- if upload_id_callback:
- upload_id_callback(writer.upload_id)
- while True:
- data = file_obj.read(part_size)
- if not data:
- break
- writer.write(data)
- writer.close()
- return writer.get_archive_id()
-
- @staticmethod
- def _range_string_to_part_index(range_string, part_size):
- start, inside_end = [int(value) for value in range_string.split('-')]
- end = inside_end + 1
- length = end - start
- if length == part_size + 1:
- # Off-by-one bug in Amazon's Glacier implementation,
- # see: https://forums.aws.amazon.com/thread.jspa?threadID=106866
- # Workaround: since part_size is too big by one byte, adjust it
- end -= 1
- inside_end -= 1
- length -= 1
- assert not (start % part_size), (
- "upload part start byte is not on a part boundary")
- assert (length <= part_size), "upload part is bigger than part size"
- return start // part_size
-
- def resume_archive_from_file(self, upload_id, filename=None,
- file_obj=None):
- """Resume upload of a file already part-uploaded to Glacier.
-
- The resumption of an upload where the part-uploaded section is empty
- is a valid degenerate case that this function can handle.
-
- One and only one of filename or file_obj must be specified.
-
- :type upload_id: str
- :param upload_id: existing Glacier upload id of upload being resumed.
-
- :type filename: str
- :param filename: file to open for resume
-
- :type fobj: file
- :param fobj: file-like object containing local data to resume. This
- must read from the start of the entire upload, not just from the
- point being resumed. Use fobj.seek(0) to achieve this if necessary.
-
- :rtype: str
- :return: The archive id of the newly created archive
-
- """
- part_list_response = self.list_all_parts(upload_id)
- part_size = part_list_response['PartSizeInBytes']
-
- part_hash_map = {}
- for part_desc in part_list_response['Parts']:
- part_index = self._range_string_to_part_index(
- part_desc['RangeInBytes'], part_size)
- part_tree_hash = codecs.decode(part_desc['SHA256TreeHash'], 'hex_codec')
- part_hash_map[part_index] = part_tree_hash
-
- if not file_obj:
- file_obj = open(filename, "rb")
-
- return resume_file_upload(
- self, upload_id, part_size, file_obj, part_hash_map)
-
- def concurrent_create_archive_from_file(self, filename, description,
- **kwargs):
- """
- Create a new archive from a file and upload the given
- file.
-
- This is a convenience method around the
- :class:`boto.glacier.concurrent.ConcurrentUploader`
- class. This method will perform a multipart upload
- and upload the parts of the file concurrently.
-
- :type filename: str
- :param filename: A filename to upload
-
- :param kwargs: Additional kwargs to pass through to
- :py:class:`boto.glacier.concurrent.ConcurrentUploader`.
- You can pass any argument besides the ``api`` and
- ``vault_name`` param (these arguments are already
- passed to the ``ConcurrentUploader`` for you).
-
- :raises: `boto.glacier.exception.UploadArchiveError` is an error
- occurs during the upload process.
-
- :rtype: str
- :return: The archive id of the newly created archive
-
- """
- uploader = ConcurrentUploader(self.layer1, self.name, **kwargs)
- archive_id = uploader.upload(filename, description)
- return archive_id
-
- def retrieve_archive(self, archive_id, sns_topic=None,
- description=None):
- """
- Initiate a archive retrieval job to download the data from an
- archive. You will need to wait for the notification from
- Amazon (via SNS) before you can actually download the data,
- this takes around 4 hours.
-
- :type archive_id: str
- :param archive_id: The id of the archive
-
- :type description: str
- :param description: An optional description for the job.
-
- :type sns_topic: str
- :param sns_topic: The Amazon SNS topic ARN where Amazon Glacier
- sends notification when the job is completed and the output
- is ready for you to download.
-
- :rtype: :class:`boto.glacier.job.Job`
- :return: A Job object representing the retrieval job.
- """
- job_data = {'Type': 'archive-retrieval',
- 'ArchiveId': archive_id}
- if sns_topic is not None:
- job_data['SNSTopic'] = sns_topic
- if description is not None:
- job_data['Description'] = description
-
- response = self.layer1.initiate_job(self.name, job_data)
- return self.get_job(response['JobId'])
-
- def retrieve_inventory(self, sns_topic=None,
- description=None, byte_range=None,
- start_date=None, end_date=None,
- limit=None):
- """
- Initiate a inventory retrieval job to list the items in the
- vault. You will need to wait for the notification from
- Amazon (via SNS) before you can actually download the data,
- this takes around 4 hours.
-
- :type description: str
- :param description: An optional description for the job.
-
- :type sns_topic: str
- :param sns_topic: The Amazon SNS topic ARN where Amazon Glacier
- sends notification when the job is completed and the output
- is ready for you to download.
-
- :type byte_range: str
- :param byte_range: Range of bytes to retrieve.
-
- :type start_date: DateTime
- :param start_date: Beginning of the date range to query.
-
- :type end_date: DateTime
- :param end_date: End of the date range to query.
-
- :type limit: int
- :param limit: Limits the number of results returned.
-
- :rtype: str
- :return: The ID of the job
- """
- job_data = {'Type': 'inventory-retrieval'}
- if sns_topic is not None:
- job_data['SNSTopic'] = sns_topic
- if description is not None:
- job_data['Description'] = description
- if byte_range is not None:
- job_data['RetrievalByteRange'] = byte_range
- if start_date is not None or end_date is not None or limit is not None:
- rparams = {}
-
- if start_date is not None:
- rparams['StartDate'] = start_date.strftime('%Y-%m-%dT%H:%M:%S%Z')
- if end_date is not None:
- rparams['EndDate'] = end_date.strftime('%Y-%m-%dT%H:%M:%S%Z')
- if limit is not None:
- rparams['Limit'] = limit
-
- job_data['InventoryRetrievalParameters'] = rparams
-
- response = self.layer1.initiate_job(self.name, job_data)
- return response['JobId']
-
- def retrieve_inventory_job(self, **kwargs):
- """
- Identical to ``retrieve_inventory``, but returns a ``Job`` instance
- instead of just the job ID.
-
- :type description: str
- :param description: An optional description for the job.
-
- :type sns_topic: str
- :param sns_topic: The Amazon SNS topic ARN where Amazon Glacier
- sends notification when the job is completed and the output
- is ready for you to download.
-
- :type byte_range: str
- :param byte_range: Range of bytes to retrieve.
-
- :type start_date: DateTime
- :param start_date: Beginning of the date range to query.
-
- :type end_date: DateTime
- :param end_date: End of the date range to query.
-
- :type limit: int
- :param limit: Limits the number of results returned.
-
- :rtype: :class:`boto.glacier.job.Job`
- :return: A Job object representing the retrieval job.
- """
- job_id = self.retrieve_inventory(**kwargs)
- return self.get_job(job_id)
-
- def delete_archive(self, archive_id):
- """
- This operation deletes an archive from the vault.
-
- :type archive_id: str
- :param archive_id: The ID for the archive to be deleted.
- """
- return self.layer1.delete_archive(self.name, archive_id)
-
- def get_job(self, job_id):
- """
- Get an object representing a job in progress.
-
- :type job_id: str
- :param job_id: The ID of the job
-
- :rtype: :class:`boto.glacier.job.Job`
- :return: A Job object representing the job.
- """
- response_data = self.layer1.describe_job(self.name, job_id)
- return Job(self, response_data)
-
- def list_jobs(self, completed=None, status_code=None):
- """
- Return a list of Job objects related to this vault.
-
- :type completed: boolean
- :param completed: Specifies the state of the jobs to return.
- If a value of True is passed, only completed jobs will
- be returned. If a value of False is passed, only
- uncompleted jobs will be returned. If no value is
- passed, all jobs will be returned.
-
- :type status_code: string
- :param status_code: Specifies the type of job status to return.
- Valid values are: InProgress|Succeeded|Failed. If not
- specified, jobs with all status codes are returned.
-
- :rtype: list of :class:`boto.glacier.job.Job`
- :return: A list of Job objects related to this vault.
- """
- response_data = self.layer1.list_jobs(self.name, completed,
- status_code)
- return [Job(self, jd) for jd in response_data['JobList']]
-
- def list_all_parts(self, upload_id):
- """Automatically make and combine multiple calls to list_parts.
-
- Call list_parts as necessary, combining the results in case multiple
- calls were required to get data on all available parts.
-
- """
- result = self.layer1.list_parts(self.name, upload_id)
- marker = result['Marker']
- while marker:
- additional_result = self.layer1.list_parts(
- self.name, upload_id, marker=marker)
- result['Parts'].extend(additional_result['Parts'])
- marker = additional_result['Marker']
- # The marker makes no sense in an unpaginated result, and clearing it
- # makes testing easier. This also has the nice property that the result
- # is a normal (but expanded) response.
- result['Marker'] = None
- return result

Powered by Google App Engine
This is Rietveld 408576698