| OLD | NEW |
| (Empty) |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import logging | |
| 6 import os | |
| 7 | |
| 8 from catapult_base import cloud_storage | |
| 9 | |
| 10 from catapult_base.dependency_manager import exceptions | |
| 11 | |
| 12 | |
| 13 BACKUP_PATH_EXTENSION = 'old' | |
| 14 | |
| 15 | |
| 16 class CloudStorageUploader(object): | |
| 17 def __init__(self, bucket, remote_path, local_path, cs_backup_path=None): | |
| 18 if not bucket or not remote_path or not local_path: | |
| 19 raise ValueError( | |
| 20 'Attempted to partially initialize upload data with bucket %s, ' | |
| 21 'remote_path %s, and local_path %s', bucket, remote_path, local_path) | |
| 22 if not os.path.exists(local_path): | |
| 23 raise ValueError('Attempting to initilize UploadInfo with missing ' | |
| 24 'local path %s', local_path) | |
| 25 | |
| 26 self._cs_bucket = bucket | |
| 27 self._cs_remote_path = remote_path | |
| 28 self._local_path = local_path | |
| 29 self._cs_backup_path = (cs_backup_path or | |
| 30 '%s.%s' % (self._cs_remote_path, | |
| 31 BACKUP_PATH_EXTENSION)) | |
| 32 self._updated = False | |
| 33 self._backed_up = False | |
| 34 | |
| 35 def Upload(self, force=False): | |
| 36 """Upload all pending files and then write the updated config to disk. | |
| 37 | |
| 38 Will attempt to copy files existing in the upload location to a backup | |
| 39 location in the same bucket in cloud storage if |force| is True. | |
| 40 | |
| 41 Args: | |
| 42 force: True if files should be uploaded to cloud storage even if a | |
| 43 file already exists in the upload location. | |
| 44 | |
| 45 Raises: | |
| 46 CloudStorageUploadConflictError: If |force| is False and the potential | |
| 47 upload location of a file already exists. | |
| 48 CloudStorageError: If copying an existing file to the backup location | |
| 49 or uploading the new file fails. | |
| 50 """ | |
| 51 if cloud_storage.Exists(self._cs_bucket, self._cs_remote_path): | |
| 52 if not force: | |
| 53 raise exceptions.CloudStorageUploadConflictError(self._cs_bucket, | |
| 54 self._cs_remote_path) | |
| 55 logging.debug('A file already exists at upload path %s in self.cs_bucket' | |
| 56 ' %s', self._cs_remote_path, self._cs_bucket) | |
| 57 try: | |
| 58 cloud_storage.Copy(self._cs_bucket, self._cs_bucket, | |
| 59 self._cs_remote_path, self._cs_backup_path) | |
| 60 self._backed_up = True | |
| 61 except cloud_storage.CloudStorageError: | |
| 62 logging.error('Failed to copy existing file %s in cloud storage bucket ' | |
| 63 '%s to backup location %s', self._cs_remote_path, self._cs_bucket, | |
| 64 self._cs_backup_path) | |
| 65 raise | |
| 66 | |
| 67 try: | |
| 68 cloud_storage.Insert( | |
| 69 self._cs_bucket, self._cs_remote_path, self._local_path) | |
| 70 except cloud_storage.CloudStorageError: | |
| 71 logging.error('Failed to upload %s to %s in cloud_storage bucket %s', | |
| 72 self._local_path, self._cs_remote_path, self._cs_bucket) | |
| 73 raise | |
| 74 self._updated = True | |
| 75 | |
| 76 def Rollback(self): | |
| 77 """Attempt to undo the previous call to Upload. | |
| 78 | |
| 79 Does nothing if no previous call to Upload was made, or if nothing was | |
| 80 successfully changed. | |
| 81 | |
| 82 Returns: | |
| 83 True iff changes were successfully rolled back. | |
| 84 Raises: | |
| 85 CloudStorageError: If copying the backed up file to its original | |
| 86 location or removing the uploaded file fails. | |
| 87 """ | |
| 88 cloud_storage_changed = False | |
| 89 if self._backed_up: | |
| 90 cloud_storage.Copy(self._cs_bucket, self._cs_bucket, self._cs_backup_path, | |
| 91 self._cs_remote_path) | |
| 92 cloud_storage_changed = True | |
| 93 self._cs_backup_path = None | |
| 94 elif self._updated: | |
| 95 cloud_storage.Delete(self._cs_bucket, self._cs_remote_path) | |
| 96 cloud_storage_changed = True | |
| 97 self._updated = False | |
| 98 return cloud_storage_changed | |
| 99 | |
| 100 def __eq__(self, other, msg=None): | |
| 101 if type(self) != type(other): | |
| 102 return False | |
| 103 return (self._local_path == other._local_path and | |
| 104 self._cs_remote_path == other._cs_remote_path and | |
| 105 self._cs_bucket == other._cs_bucket) | |
| 106 | |
| OLD | NEW |