Add does_storage_object_exist to gs_utils Needed for recreate_skps script BUG=skia:3008 Review URL: https://codereview.chromium.org/661563002
diff --git a/.gitignore b/.gitignore index 2f78cf5..f4bf1d0 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,2 +1,2 @@ *.pyc - +third_party/externals
diff --git a/py/utils/gs_utils.py b/py/utils/gs_utils.py index d5c5b95..fd9999c 100644 --- a/py/utils/gs_utils.py +++ b/py/utils/gs_utils.py
@@ -52,7 +52,7 @@ # each core sits idle waiting for network I/O to complete. DEFAULT_UPLOAD_THREADS = 10 -_GS_PREFIX = 'gs://' +GS_PREFIX = 'gs://' class AnonymousGSConnection(GSConnection): @@ -132,19 +132,34 @@ Params: boto_file_path: full path (local-OS-style) on local disk where .boto - credentials file can be found. If None, then the GSUtils object - created will be able to access only public files in Google Storage. + credentials file can be found. If None, fall back on the + AWS_CREDENTIAL_FILE environment variable, then look in a set of + common paths for the .boto file. If no .boto file is found, then the + GSUtils object created will be able to access only public files in + Google Storage. Raises an exception if no file is found at boto_file_path, or if the file found there is malformed. """ self._gs_access_key_id = None self._gs_secret_access_key = None + if not boto_file_path: + if os.environ.get('AWS_CREDENTIAL_FILE'): + boto_file_path = os.path.expanduser(os.environ['AWS_CREDENTIAL_FILE']) + if not boto_file_path: + for path in (os.path.join(os.path.expanduser('~'), '.boto'),): + if os.path.isfile(path): + boto_file_path = path + break + if boto_file_path: print ('Reading boto file from %s' % boto_file_path) boto_dict = _config_file_as_dict(filepath=boto_file_path) self._gs_access_key_id = boto_dict['gs_access_key_id'] self._gs_secret_access_key = boto_dict['gs_secret_access_key'] + else: + print >> sys.stderr, 'Warning: no .boto file found.' + # Which field we get/set in ACL entries, depending on IdType. self._field_by_id_type = { self.IdType.GROUP_BY_DOMAIN: 'domain', @@ -582,13 +597,24 @@ dirs.append(item.name[prefix_length:-1]) return (dirs, files) + def does_storage_object_exist(self, bucket, object_name): + """Determines whether an object exists in Google Storage. + + Returns True if it exists else returns False. + """ + b = self._connect_to_bucket(bucket=bucket) + if object_name in b: + return True + dirs, files = self.list_bucket_contents(bucket, object_name) + return bool(dirs or files) + @staticmethod def is_gs_url(url): """Returns True if url is a legal Google Storage URL ("gs://bucket/file"). """ try: - if url.lower().startswith(_GS_PREFIX) and len(url) > len(_GS_PREFIX): - return url[len(_GS_PREFIX)].isalnum() + if url.lower().startswith(GS_PREFIX) and len(url) > len(GS_PREFIX): + return url[len(GS_PREFIX)].isalnum() else: return False except AttributeError: @@ -602,7 +628,7 @@ """ if not GSUtils.is_gs_url(url): raise AttributeError('"%s" is not a legal Google Storage URL' % url) - prefix_removed = url[len(_GS_PREFIX):] + prefix_removed = url[len(GS_PREFIX):] pathsep_index = prefix_removed.find('/') if pathsep_index < 0: return (prefix_removed, '')
diff --git a/py/utils/gs_utils_manualtest.py b/py/utils/gs_utils_manualtest.py index 3365055..2ba63e4 100755 --- a/py/utils/gs_utils_manualtest.py +++ b/py/utils/gs_utils_manualtest.py
@@ -388,6 +388,17 @@ path=posixpath.join(remote_dir, subdir, filename)) +def _test_does_storage_object_exist(): + gs = gs_utils.GSUtils() + cases = (('gs_utils_manualtest/4843645167453050644/subdir/file1', True), + ('gs_utils_manualtest', True), + ('bogus', False)) + for obj, expect in cases: + msg = 'expected exists(%s) to be %s' % ( + '/'.join(('gs:/', TEST_BUCKET, obj)), expect) + assert gs.does_storage_object_exist(TEST_BUCKET, obj) == expect, msg + + if __name__ == '__main__': _test_static_methods() _test_upload_if_multiple_files() @@ -395,5 +406,6 @@ _test_public_read() _test_authenticated_round_trip() _test_dir_upload_and_download() + _test_does_storage_object_exist() # TODO(epoger): Add _test_unauthenticated_access() to make sure we raise # an exception when we try to access without needed credentials.