forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Google Cloud Storage support to the documentation AppEngine serve…
…r using Cloud Storage official Python client library. With this CL, URL paths can be directly mapped to Cloud Storage buckets (http://developer.chrome.com/path/... -> gs://bucket/...) using content_storage.json configuration file. open-source-thrid-party-reviews@ team: this CL adds a third-party library to Chromium repo. The library will be used only in the documentation server and it is the official Google library to access Google Cloud Storage from a Google AppEngine application (docs server). BUG=338007 Review URL: https://codereview.chromium.org/139303023 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250663 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
mangini@chromium.org
committed
Feb 12, 2014
1 parent
2723b3c
commit 2507e44
Showing
29 changed files
with
2,853 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
third_party/ | ||
local_debug/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
application: chrome-apps-doc | ||
version: 3-6-0 | ||
version: 3-7-0 | ||
runtime: python27 | ||
api_version: 1 | ||
threadsafe: false | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
chrome/common/extensions/docs/server2/gcs_file_system.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
# Copyright 2014 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. | ||
|
||
from third_party.cloudstorage import cloudstorage_api | ||
from third_party.cloudstorage import common | ||
from third_party.cloudstorage import errors | ||
|
||
from docs_server_utils import StringIdentity | ||
from file_system import FileSystem, FileNotFoundError, StatInfo | ||
from future import Gettable, Future | ||
|
||
import logging | ||
import traceback | ||
|
||
'''See gcs_file_system_provider.py for documentation on using Google Cloud | ||
Storage as a filesystem. | ||
''' | ||
def _ReadFile(filename): | ||
try: | ||
with cloudstorage_api.open(filename, 'r') as f: | ||
return f.read() | ||
except errors.Error: | ||
raise FileNotFoundError('Read failed for %s: %s' % (filename, | ||
traceback.format_exc())) | ||
|
||
def _ListDir(dir_name): | ||
try: | ||
files = cloudstorage_api.listbucket(dir_name) | ||
return [os_path.filename for os_path in files] | ||
except errors.Error: | ||
raise FileNotFoundError('cloudstorage.listbucket failed for %s: %s' % | ||
(dir_name, traceback.format_exc())) | ||
|
||
def _CreateStatInfo(bucket, path): | ||
bucket = '/%s' % bucket | ||
full_path = '/'.join( (bucket, path.lstrip('/')) ) | ||
try: | ||
if full_path.endswith('/'): | ||
child_versions = dict() | ||
version = 0 | ||
# Fetching stats for all files under full_path, recursively. The | ||
# listbucket method uses a prefix approach to simulate hierarchy, | ||
# but calling it without the "delimiter" argument searches for prefix, | ||
# which means, for directories, everything beneath it. | ||
for _file in cloudstorage_api.listbucket(full_path): | ||
if not _file.is_dir: | ||
# GCS doesn't have metadata for dirs | ||
child_stat = cloudstorage_api.stat('%s' % _file.filename).st_ctime | ||
filename = _file.filename[len(bucket)+1:] | ||
child_versions[filename] = child_stat | ||
version = max(version, child_stat) | ||
else: | ||
child_versions = None | ||
version = cloudstorage_api.stat(full_path).st_ctime | ||
return StatInfo(version, child_versions) | ||
except (TypeError, errors.Error): | ||
raise FileNotFoundError('cloudstorage.stat failed for %s: %s' % (path, | ||
traceback.format_exc())) | ||
|
||
|
||
class CloudStorageFileSystem(FileSystem): | ||
'''FileSystem implementation which fetches resources from Google Cloud | ||
Storage. | ||
''' | ||
def __init__(self, bucket, debug_access_token=None, debug_bucket_prefix=None): | ||
self._bucket = bucket | ||
if debug_access_token: | ||
logging.debug('gcs: using debug access token: %s' % debug_access_token) | ||
common.set_access_token(debug_access_token) | ||
if debug_bucket_prefix: | ||
logging.debug('gcs: prefixing all bucket names with %s' % | ||
debug_bucket_prefix) | ||
self._bucket = debug_bucket_prefix + self._bucket | ||
|
||
def Read(self, paths): | ||
def resolve(): | ||
try: | ||
result = {} | ||
for path in paths: | ||
full_path = '/%s/%s' % (self._bucket, path.lstrip('/')) | ||
logging.debug('gcs: requested path %s, reading %s' % | ||
(path, full_path)) | ||
if path == '' or path.endswith('/'): | ||
result[path] = _ListDir(full_path) | ||
else: | ||
result[path] = _ReadFile(full_path) | ||
return result | ||
except errors.AuthorizationError: | ||
self._warnAboutAuthError() | ||
raise | ||
|
||
return Future(delegate=Gettable(resolve)) | ||
|
||
def Refresh(self): | ||
return Future(value=()) | ||
|
||
def Stat(self, path): | ||
try: | ||
return _CreateStatInfo(self._bucket, path) | ||
except errors.AuthorizationError: | ||
self._warnAboutAuthError() | ||
raise | ||
|
||
def GetIdentity(self): | ||
return '@'.join((self.__class__.__name__, StringIdentity(self._bucket))) | ||
|
||
def __repr__(self): | ||
return 'LocalFileSystem(%s)' % self._bucket | ||
|
||
def _warnAboutAuthError(self): | ||
logging.warn(('Authentication error on Cloud Storage. Check if your' | ||
' appengine project has permissions to Read the GCS' | ||
' buckets. If you are running a local appengine server,' | ||
' you need to set an access_token in' | ||
' local_debug/gcs_debug.conf.' | ||
' Remember that this token expires in less than 10' | ||
' minutes, so keep it updated. See' | ||
' gcs_file_system_provider.py for instructions.')); | ||
logging.debug(traceback.format_exc()) |
Oops, something went wrong.