XBuddy: Add support for obtaining Project SDK images.
* Adds a new alias 'project_sdk' mapping to a canonical image path.
* Adds support for pinned versions, including a 'VERSION' keyword in
aliases and API extensions for passing in a specific version. The
default is still 'latest'.
* Clarifies argument use in XBuddy._GetArtifact() docstring.
BUG=brillo:114
TEST=Unit tests.
TEST=Manual tests via cros flash --project-sdk.
Change-Id: I3e70ae7043d72906022e1d5203b69503be19f034
Reviewed-on: https://chromium-review.googlesource.com/251222
Trybot-Ready: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Chris Sosa <sosa@chromium.org>
Reviewed-by: Don Garrett <dgarrett@chromium.org>
Commit-Queue: Gilad Arnold <garnold@chromium.org>
diff --git a/xbuddy.py b/xbuddy.py
index 7cbacd7..0bab714 100644
--- a/xbuddy.py
+++ b/xbuddy.py
@@ -179,8 +179,8 @@
# Lock used to lock increasing/decreasing count.
_staging_thread_count_lock = threading.Lock()
- def __init__(self, manage_builds=False, board=None, images_dir=None,
- log_screen=True, **kwargs):
+ def __init__(self, manage_builds=False, board=None, version=None,
+ images_dir=None, log_screen=True, **kwargs):
super(XBuddy, self).__init__(**kwargs)
if not log_screen:
@@ -189,6 +189,7 @@
self.config = self._ReadConfig()
self._manage_builds = manage_builds or self._ManageBuilds()
self._board = board
+ self._version = version
self._timestamp_folder = os.path.join(self.static_dir,
Timestamp.XBUDDY_TIMESTAMP_DIR)
if images_dir:
@@ -265,7 +266,7 @@
except ConfigParser.Error:
return 5
- def _LookupAlias(self, alias, board):
+ def _LookupAlias(self, alias, board, version):
"""Given the full xbuddy config, look up an alias for path rewrite.
Args:
@@ -273,6 +274,8 @@
rewrite table.
board: The board to fill in with when paths are rewritten. Can be from
the update request xml or the default board from devserver.
+ version: The version to fill in when rewriting paths. Could be a specific
+ version number or a version alias like LATEST.
Returns:
If a rewrite is found, a string with the current board substituted in.
@@ -288,9 +291,10 @@
# The found value was an empty string.
return alias
else:
- # Fill in the board.
- rewrite = val.replace("BOARD", "%(board)s") % {
- 'board': board}
+ # Fill in the board and version.
+ rewrite = val.replace("BOARD", "%(board)s")
+ rewrite = rewrite.replace("VERSION", "%(version)s")
+ rewrite = rewrite % {'board': board, 'version': version}
_Log("Path was rewritten to %s", rewrite)
return rewrite
@@ -487,12 +491,13 @@
raise XBuddyException('No images found in %s' % local_dir)
@staticmethod
- def _InterpretPath(path, default_board=None):
+ def _InterpretPath(path, default_board=None, default_version=None):
"""Split and return the pieces of an xBuddy path name
Args:
path: the path xBuddy Get was called with.
default_board: board to use in case board isn't in path.
+ default_version: Version to use in case version isn't in path.
Returns:
tuple of (image_type, board, version, whether the path is local)
@@ -522,12 +527,12 @@
# of the path is just a board | version (like R33-2341.0.0) or just a board
# or just a version. So we do our best to do the right thing.
board = default_board
- version = LATEST
+ version = default_version or LATEST
if len(path_list) == 1:
path = path_list.pop(0)
- # If it's a version we know (contains latest), go for that, otherwise only
- # treat it as a version if we were given an actual default board.
- if LATEST in path or default_board is not None:
+ # Treat this as a version if it's one we know (contains default or
+ # latest), or we were given an actual default board.
+ if default_version in path or LATEST in path or default_board is not None:
version = path
else:
board = path
@@ -669,8 +674,8 @@
else:
_Log('Image already cached.')
- def _GetArtifact(self, path_list, board=None, lookup_only=False,
- image_dir=None):
+ def _GetArtifact(self, path_list, board=None, version=None,
+ lookup_only=False, image_dir=None):
"""Interpret an xBuddy path and return directory/file_name to resource.
Note board can be passed that in but by default if self._board is set,
@@ -678,8 +683,10 @@
Args:
path_list: [board, version, alias] as split from the xbuddy call url.
- board: Board whos artifacts we are looking for. If None, use the board
- XBuddy was initialized to use.
+ board: Board whos artifacts we are looking for. Only used if no board was
+ given during XBuddy initialization.
+ version: Version whose artifacts we are looking for. Used if no version
+ was given during XBuddy initialization. If None, defers to LATEST.
lookup_only: If true just look up the artifact, if False stage it on
the devserver as well.
image_dir: Google Storage image archive to search in if requesting a
@@ -697,11 +704,12 @@
"""
path = '/'.join(path_list)
default_board = self._board if self._board else board
+ default_version = self._version or version or LATEST
# Rewrite the path if there is an appropriate default.
- path = self._LookupAlias(path, default_board)
+ path = self._LookupAlias(path, default_board, default_version)
# Parse the path.
image_type, board, version, is_local = self._InterpretPath(
- path, default_board)
+ path, default_board, default_version)
if is_local:
# Get a local image.
if version == LATEST:
@@ -749,7 +757,7 @@
"""Returns the number of images cached by xBuddy."""
return str(self._Capacity())
- def Translate(self, path_list, board=None, image_dir=None):
+ def Translate(self, path_list, board=None, version=None, image_dir=None):
"""Translates an xBuddy path to a real path to artifact if it exists.
Equivalent to the Get call, minus downloading and updating timestamps,
@@ -758,6 +766,8 @@
path_list: [board, version, alias] as split from the xbuddy call url.
board: Board whos artifacts we are looking for. If None, use the board
XBuddy was initialized to use.
+ version: Version whose artifacts we are looking for. If None, use the
+ version XBuddy was initialized with, or LATEST.
image_dir: image directory to check in Google Storage. If none,
the default bucket is used.
@@ -776,6 +786,7 @@
"""
self._SyncRegistryWithBuildImages()
build_id, file_name = self._GetArtifact(path_list, board=board,
+ version=version,
lookup_only=True,
image_dir=image_dir)