| Index: tools/telemetry/catapult_base/dependency_manager/uploader.py
|
| diff --git a/tools/telemetry/catapult_base/dependency_manager/uploader.py b/tools/telemetry/catapult_base/dependency_manager/uploader.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..08e9c8f6b35d5159a1af8a40cf240a8e92de1e84
|
| --- /dev/null
|
| +++ b/tools/telemetry/catapult_base/dependency_manager/uploader.py
|
| @@ -0,0 +1,106 @@
|
| +# Copyright 2015 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +import logging
|
| +import os
|
| +
|
| +from catapult_base import cloud_storage
|
| +
|
| +from catapult_base.dependency_manager import exceptions
|
| +
|
| +
|
| +BACKUP_PATH_EXTENSION = 'old'
|
| +
|
| +
|
| +class CloudStorageUploader(object):
|
| + def __init__(self, bucket, remote_path, local_path, cs_backup_path=None):
|
| + if not bucket or not remote_path or not local_path:
|
| + raise ValueError(
|
| + 'Attempted to partially initialize upload data with bucket %s, '
|
| + 'remote_path %s, and local_path %s', bucket, remote_path, local_path)
|
| + if not os.path.exists(local_path):
|
| + raise ValueError('Attempting to initilize UploadInfo with missing '
|
| + 'local path %s', local_path)
|
| +
|
| + self._cs_bucket = bucket
|
| + self._cs_remote_path = remote_path
|
| + self._local_path = local_path
|
| + self._cs_backup_path = (cs_backup_path or
|
| + '%s.%s' % (self._cs_remote_path,
|
| + BACKUP_PATH_EXTENSION))
|
| + self._updated = False
|
| + self._backed_up = False
|
| +
|
| + def Upload(self, force=False):
|
| + """Upload all pending files and then write the updated config to disk.
|
| +
|
| + Will attempt to copy files existing in the upload location to a backup
|
| + location in the same bucket in cloud storage if |force| is True.
|
| +
|
| + Args:
|
| + force: True if files should be uploaded to cloud storage even if a
|
| + file already exists in the upload location.
|
| +
|
| + Raises:
|
| + CloudStorageUploadConflictError: If |force| is False and the potential
|
| + upload location of a file already exists.
|
| + CloudStorageError: If copying an existing file to the backup location
|
| + or uploading the new file fails.
|
| + """
|
| + if cloud_storage.Exists(self._cs_bucket, self._cs_remote_path):
|
| + if not force:
|
| + raise exceptions.CloudStorageUploadConflictError(self._cs_bucket,
|
| + self._cs_remote_path)
|
| + logging.debug('A file already exists at upload path %s in self.cs_bucket'
|
| + ' %s', self._cs_remote_path, self._cs_bucket)
|
| + try:
|
| + cloud_storage.Copy(self._cs_bucket, self._cs_bucket,
|
| + self._cs_remote_path, self._cs_backup_path)
|
| + self._backed_up = True
|
| + except cloud_storage.CloudStorageError:
|
| + logging.error('Failed to copy existing file %s in cloud storage bucket '
|
| + '%s to backup location %s', self._cs_remote_path, self._cs_bucket,
|
| + self._cs_backup_path)
|
| + raise
|
| +
|
| + try:
|
| + cloud_storage.Insert(
|
| + self._cs_bucket, self._cs_remote_path, self._local_path)
|
| + except cloud_storage.CloudStorageError:
|
| + logging.error('Failed to upload %s to %s in cloud_storage bucket %s',
|
| + self._local_path, self._cs_remote_path, self._cs_bucket)
|
| + raise
|
| + self._updated = True
|
| +
|
| + def Rollback(self):
|
| + """Attempt to undo the previous call to Upload.
|
| +
|
| + Does nothing if no previous call to Upload was made, or if nothing was
|
| + successfully changed.
|
| +
|
| + Returns:
|
| + True iff changes were successfully rolled back.
|
| + Raises:
|
| + CloudStorageError: If copying the backed up file to its original
|
| + location or removing the uploaded file fails.
|
| + """
|
| + cloud_storage_changed = False
|
| + if self._backed_up:
|
| + cloud_storage.Copy(self._cs_bucket, self._cs_bucket, self._cs_backup_path,
|
| + self._cs_remote_path)
|
| + cloud_storage_changed = True
|
| + self._cs_backup_path = None
|
| + elif self._updated:
|
| + cloud_storage.Delete(self._cs_bucket, self._cs_remote_path)
|
| + cloud_storage_changed = True
|
| + self._updated = False
|
| + return cloud_storage_changed
|
| +
|
| + def __eq__(self, other, msg=None):
|
| + if type(self) != type(other):
|
| + return False
|
| + return (self._local_path == other._local_path and
|
| + self._cs_remote_path == other._cs_remote_path and
|
| + self._cs_bucket == other._cs_bucket)
|
| +
|
|
|