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 |