Devserver update rpc: translate xBuddy paths. If an update request starts with 'xbuddy' the rest of the path will be translated to a directory within the devserver's static_dir before being passed onto the normal update call. BUG=chromium:261671 TEST=Effectively None, as there aren't any scripts that use the update rpc with xBuddy yet. :( Can call http://host:port/update/xbuddy/board/version/ to see that the translation happens, but without the xml, this isn't meaningful yet. Change-Id: I072ba04045a30b3c7d03d67556f9f9d0c7af41ec Reviewed-on: https://gerrit.chromium.org/gerrit/63282 Reviewed-by: Chris Sosa <sosa@chromium.org> Commit-Queue: Joy Chen <joychen@chromium.org> Reviewed-by: Joy Chen <joychen@chromium.org> Tested-by: Joy Chen <joychen@chromium.org>
diff --git a/devserver.py b/devserver.py index faec8a1..5b82608 100755 --- a/devserver.py +++ b/devserver.py
@@ -792,7 +792,15 @@ Example: http://myhost/update/optional/path/to/payload """ - label = '/'.join(args) + if len(args) > 0 and args[0] == 'xbuddy': + # Interpret the rest of the path as an xbuddy path + label, found = self._xbuddy.Translate(args[1:] + ('full_payload',)) + if not found: + _Log("Update payload not found for %s, xBuddy looking it up.", label) + else: + label = '/'.join(args) + + _Log('Update label: %s', label) body_length = int(cherrypy.request.headers.get('Content-Length', 0)) data = cherrypy.request.rfile.read(body_length) return updater.HandleUpdatePing(data, label)
diff --git a/xbuddy.py b/xbuddy.py index d04d96e..1bd4b6d 100644 --- a/xbuddy.py +++ b/xbuddy.py
@@ -33,13 +33,14 @@ 'test', 'base', 'dev', + 'full_payload', ] LOCAL_FILE_NAMES = [ devserver_constants.TEST_IMAGE_FILE, - devserver_constants.BASE_IMAGE_FILE, devserver_constants.IMAGE_FILE, + devserver_constants.ROOT_UPDATE_FILE, ] LOCAL_ALIAS_TO_FILENAME = dict(zip(LOCAL_ALIASES, LOCAL_FILE_NAMES)) @@ -277,6 +278,7 @@ Returns: version - the discovered version of the image. + found - True if file was found """ latest_local_dir = self.GetLatestImageDir(board) if not latest_local_dir and os.path.exists(latest_local_dir): @@ -287,10 +289,10 @@ version = os.path.basename(latest_local_dir) path_to_image = os.path.join(latest_local_dir, file_name) - if not os.path.exists(path_to_image): - raise XBuddyException('%s not found in %s. Did you run build_image?' % - (file_name, latest_local_dir)) - return version + if os.path.exists(path_to_image): + return version, True + else: + return version, False def _InterpretPath(self, path_list): """ @@ -343,7 +345,7 @@ # This path doesn't have an alias or a version. That's fine. _Log("Some parts of the path not specified. Using defaults.") - _Log("Get artifact '%s' in {%s/%s}. Locally? %s", + _Log("Get artifact '%s' in '%s/%s'. Locally? %s", image_type, board, version, is_local) return image_type, board, version, is_local @@ -437,26 +439,45 @@ except Exception: raise XBuddyException('Failed to clear build in %s.' % clear_dir) - def _GetFromGS(self, build_id, image_type): - """Check if the artifact is available locally. Download from GS if not.""" + def _GetFromGS(self, build_id, image_type, lookup_only): + """Check if the artifact is available locally. Download from GS if not. + + Return: + boolean - True if cached. + """ gs_url = os.path.join(devserver_constants.GS_IMAGE_DIR, build_id) # stage image if not found in cache file_name = GS_ALIAS_TO_FILENAME[image_type] - cached = os.path.exists(os.path.join(self.static_dir, - build_id, - file_name)) + file_loc = os.path.join(self.static_dir, build_id, file_name) + cached = os.path.exists(file_loc) + if not cached: - artifact = GS_ALIAS_TO_ARTIFACT[image_type] - self._Download(gs_url, artifact) + if lookup_only: + return False + else: + artifact = GS_ALIAS_TO_ARTIFACT[image_type] + self._Download(gs_url, artifact) + return True else: _Log('Image already cached.') + return True - def _GetArtifact(self, path): - """Interpret an xBuddy path and return directory/file_name to resource.""" + def _GetArtifact(self, path, lookup_only=False): + """Interpret an xBuddy path and return directory/file_name to resource. + + Returns: + image_url to the directory + file_name of the artifact + found = True if the artifact is cached + + Raises: + XBuddyException if the path could not be translated + """ image_type, board, version, is_local = self._InterpretPath(path) + found = False if is_local: # Get a local image if image_type not in LOCAL_ALIASES: @@ -466,12 +487,12 @@ if version == LATEST: # Get the latest local image for the given board - version = self._GetLatestLocalVersion(board, file_name) + version, found = self._GetLatestLocalVersion(board, file_name) else: # An exact version path in build/images was specified for this board local_file = os.path.join(self.images_dir, board, version, file_name) - if not os.path.exists(local_file): - raise XBuddyException('File not found in local dir: %s', local_file) + if os.path.exists(local_file): + found = True image_url = os.path.join(board, version) else: @@ -483,9 +504,9 @@ # Interpret the version (alias), and get gs address image_url = self._ResolveVersionToUrl(board, version) - self._GetFromGS(image_url, image_type) + found = self._GetFromGS(image_url, image_type, lookup_only) - return image_url, file_name + return image_url, file_name, found ############################ BEGIN PUBLIC METHODS @@ -503,6 +524,22 @@ """Returns the number of images cached by xBuddy.""" return str(_XBUDDY_CAPACITY) + def Translate(self, path_list): + """Translates an xBuddy path to a real path to artifact if it exists. + + Equivalent to the Get call, minus downloading and updating timestamps. + The returned path is always the path to the directory. + + Throws: + XBuddyException - if the path couldn't be translated + """ + self._SyncRegistryWithBuildImages() + + build_id, _file_name, found = self._GetArtifact(path_list, lookup_only=True) + + _Log('Returning path to payload: %s', build_id) + return build_id, found + def Get(self, path_list, return_dir=False): """The full xBuddy call, returns resource specified by path_list. @@ -519,10 +556,10 @@ http://host/static/x86-generic/R26-4000.0.0/ Raises: - XBuddyException if path is invalid or XBuddy's cache fails + XBuddyException if path is invalid """ self._SyncRegistryWithBuildImages() - build_id, file_name = self._GetArtifact(path_list) + build_id, file_name, _found = self._GetArtifact(path_list) Timestamp.UpdateTimestamp(self._timestamp_folder, build_id)