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 errno |
| 6 import os |
| 7 import stat |
| 8 |
| 9 from catapult_base import cloud_storage |
| 10 |
| 11 from catapult_base.dependency_manager import exceptions |
| 12 |
| 13 class CloudStorageInfo(object): |
| 14 def __init__(self, cs_bucket, cs_hash, download_path, cs_remote_path, |
| 15 version_in_cs=None, archive_info=None): |
| 16 """ Container for the information needed to download a dependency from |
| 17 cloud storage. |
| 18 |
| 19 Args: |
| 20 cs_bucket: The cloud storage bucket the dependency is located in. |
| 21 cs_hash: The hash of the file stored in cloud storage. |
| 22 download_path: Where the file should be downloaded to. |
| 23 cs_remote_path: Where the file is stored in the cloud storage bucket. |
| 24 version_in_cs: The version of the file stored in cloud storage. |
| 25 archive_info: An instance of ArchiveInfo if this dependency is an |
| 26 archive. Else None. |
| 27 """ |
| 28 self._download_path = download_path |
| 29 self._cs_remote_path = cs_remote_path |
| 30 self._cs_bucket = cs_bucket |
| 31 self._cs_hash = cs_hash |
| 32 self._version_in_cs = version_in_cs |
| 33 self._archive_info = archive_info |
| 34 if not self._has_minimum_data: |
| 35 raise ValueError( |
| 36 'Not enough information specified to initialize a cloud storage info.' |
| 37 ' %s' % self) |
| 38 |
| 39 def DependencyExistsInCloudStorage(self): |
| 40 return cloud_storage.Exists(self._cs_bucket, self._cs_remote_path) |
| 41 |
| 42 def GetRemotePath(self): |
| 43 """Gets the path to a downloaded version of the dependency. |
| 44 |
| 45 May not download the file if it has already been downloaded. |
| 46 Will unzip the downloaded file if a non-empty archive_info was passed in at |
| 47 init. |
| 48 |
| 49 Returns: A path to an executable that was stored in cloud_storage, or None |
| 50 if not found. |
| 51 |
| 52 Raises: |
| 53 CredentialsError: If cloud_storage credentials aren't configured. |
| 54 PermissionError: If cloud_storage credentials are configured, but not |
| 55 with an account that has permission to download the needed file. |
| 56 NotFoundError: If the needed file does not exist where expected in |
| 57 cloud_storage or the downloaded zip file. |
| 58 ServerError: If an internal server error is hit while downloading the |
| 59 needed file. |
| 60 CloudStorageError: If another error occured while downloading the remote |
| 61 path. |
| 62 FileNotFoundError: If the download was otherwise unsuccessful. |
| 63 """ |
| 64 if not self._has_minimum_data: |
| 65 return None |
| 66 |
| 67 download_dir = os.path.dirname(self._download_path) |
| 68 if not os.path.exists(download_dir): |
| 69 try: |
| 70 os.makedirs(download_dir) |
| 71 except OSError as e: |
| 72 # The logic above is racy, and os.makedirs will raise an OSError if |
| 73 # the directory exists. |
| 74 if e.errno != errno.EEXIST: |
| 75 raise |
| 76 |
| 77 dependency_path = self._download_path |
| 78 cloud_storage.GetIfHashChanged( |
| 79 self._cs_remote_path, self._download_path, self._cs_bucket, |
| 80 self._cs_hash) |
| 81 if not os.path.exists(dependency_path): |
| 82 raise exceptions.FileNotFoundError(dependency_path) |
| 83 |
| 84 if self.has_archive_info: |
| 85 dependency_path = self._archive_info.GetUnzippedPath() |
| 86 else: |
| 87 mode = os.stat(dependency_path).st_mode |
| 88 os.chmod(dependency_path, mode | stat.S_IXUSR) |
| 89 return os.path.abspath(dependency_path) |
| 90 |
| 91 @property |
| 92 def version_in_cs(self): |
| 93 return self._version_in_cs |
| 94 |
| 95 @property |
| 96 def _has_minimum_data(self): |
| 97 return all([self._cs_bucket, self._cs_remote_path, self._download_path, |
| 98 self._cs_hash]) |
| 99 |
| 100 |
| 101 @property |
| 102 def has_archive_info(self): |
| 103 return bool(self._archive_info) |
| 104 |
| 105 def __repr__(self): |
| 106 return ( |
| 107 'CloudStorageInfo(download_path=%s, cs_remote_path=%s, cs_bucket=%s, ' |
| 108 'cs_hash=%s, version_in_cs=%s, archive_info=%s)' % ( |
| 109 self._download_path, self._cs_remote_path, self._cs_bucket, |
| 110 self._cs_hash, self._version_in_cs, self._archive_info)) |
OLD | NEW |