blob: 3676633763fb96920f31bef0f6d4272ebed2f8d4 [file] [log] [blame]
xixuanbea010f2017-03-27 10:10:19 -07001# Copyright 2017 The Chromium OS 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"""Module for ChromeOS & Android build related logic in suite scheduler."""
6
7import apiclient
8import collections
9import logging
10import re
11
12# Bare branches
13BARE_BRANCHES = ['factory', 'firmware']
14
15# Definition of os types.
16OS_TYPE_CROS = 'cros'
17OS_TYPE_BRILLO = 'brillo'
18OS_TYPE_ANDROID = 'android'
19OS_TYPES = [OS_TYPE_CROS, OS_TYPE_BRILLO, OS_TYPE_ANDROID]
20OS_TYPES_LAUNCH_CONTROL = [OS_TYPE_BRILLO, OS_TYPE_ANDROID]
21
22
23LaunchControlBuildTargetInfo = collections.namedtuple(
24 'LaunchControlBuildTargetInfo',
25 [
26 'target',
27 'type',
28 ])
29
30CrOSBuildConfigInfo = collections.namedtuple(
31 'CrOSBuildConfigInfo',
32 [
33 'board',
34 'type',
35 ])
36
37
38class NoBuildError(Exception):
39 """Raised when failing to get the required build from Google Storage."""
40
41
42class BuildType(object):
43 """Representing the type of test source build.
44
45 This is used to identify the test source build for testing.
46 """
47 FIRMWARE_RW = 'firmware_rw'
48 FIRMWARE_RO = 'firmware_ro'
49 CROS = 'cros'
50
51
52class BuildVersionKey(object):
53 """Keys referring to the builds to install in run_suites."""
54
55 CROS_VERSION = 'cros_version'
56 ANDROID_BUILD_VERSION = 'android_version'
57 TESTBED_BUILD_VERSION = 'testbed_version'
58 FW_RW_VERSION = 'fwrw_version'
59 FW_RO_VERSION = 'fwro_version'
60
61
62class AndroidBuild(collections.namedtuple(
63 '_AndroidBuildBase', ['branch', 'target', 'build_id']), object):
64
65 def __str__(self):
66 return _ANDROID_BUILD_PATTERN % {'branch': self.branch,
67 'target': self.target,
68 'build_id': self.build_id}
69
70
71class CrOSBuild(collections.namedtuple(
72 '_CrOSBuildBase',
73 ['board', 'build_type', 'milestone', 'manifest']), object):
74
75 def __str__(self):
76 return _CROS_BUILD_PATTERN % {'board': self.board,
77 'build_type': self.build_type,
78 'milestone': self.milestone,
79 'manifest': self.manifest}
80
81
82def get_latest_cros_build_from_gs(storage_client, board=None, suffix=None):
83 """Get latest build for given board from Google Storage.
84
85 Args:
86 storage_client: a rest_client.StorageRestClient object.
87 board: the board to fetch latest build. Default is 'master'.
88 suffix: suffix represents build channel, like '-release'.
89 Default is '-paladin'.
90
91 Returns:
92 a ChromeOS version string, e.g. '59.0.000.0'.
93
94 Raises:
95 HttpError if error happens in interacting with Google Storage.
96 """
97 board = board if board is not None else _DEFAULT_MASTER
98 suffix = suffix if suffix is not None else _DEFAULT_BUILD_SUFFIX
99 file_to_check = _GS_LATEST_MASTER_PATTERN % {
100 'board': board,
101 'suffix': suffix,
102 'name': _LATEST_MASTER}
103
104 try:
105 return storage_client.ReadObject(_GS_BUCKET, file_to_check)
106 except apiclient.errors.HttpError as e:
107 raise NoBuildError(
108 'Cannot find latest build for board %s, suffix %s: %s' %
109 (board, suffix, str(e)))
110
111
112def get_latest_launch_control_build(android_client, branch, target):
113 """Get the latest launch control build from Android Build API.
114
115 Args:
116 android_client: a rest_client.AndroidBuildRestClient object.
117 branch: the launch control branch.
118 target: the launch control target.
119
120 Returns:
121 a string latest launch control build id.
122
123 Raises:
124 NoBuildError if no latest launch control build is found.
125 """
126 try:
127 latest_build_id = android_client.get_latest_build_id(branch, target)
128 if latest_build_id is None:
129 raise NoBuildError('No latest builds is found.')
130
131 return latest_build_id
132 except apiclient.errors.HttpError as e:
133 raise NoBuildError('HttpError happened in getting the latest launch '
134 'control build for '
135 '%s,%s: %s' % (branch, target, str(e)))
136
137def parse_launch_control_target(target):
138 """Parse the build target and type from a Launch Control target.
139
140 The Launch Control target has the format of build_target-build_type, e.g.,
141 shamu-eng or dragonboard-userdebug. This method extracts the build target
142 and type from the target name.
143
144 Args:
145 target: Name of a Launch Control target, e.g., shamu-userdebug.
146
147 Returns:
148 a LaunchControlBuildTargetInfo object whose value is like
149 (target='shamu',
150 type='userdebug')
151
152 Raises:
153 Raise ValueError if target is not valid.
154 """
155 match = re.match(_LAUNCH_CONTROL_TARGET_PATTERN, target)
156 if not match:
157 raise ValueError('target format is not valid')
158
159 return LaunchControlBuildTargetInfo(match.group('build_target'),
160 match.group('build_type'))
161
162
163def parse_cros_build_config(board, build_config):
164 """Parse build_type from a given builder for a given board.
165
166 Args:
167 board: the prefix of a ChromeOS build_config, representing board.
168 build_config: a ChromeOS build_config name, like 'kevin-release'.
169
170 Returns:
171 a CrOSBuildConfigInfo object whose value is like
172 (board='kevin',
173 type='release')
174
175 Raises:
176 Raise ValueError if target is not valid.
177 """
178 if build_config[0:len(board)] != board:
179 raise ValueError('build_config cannot be parsed: %s' % build_config)
180
181 match = re.match(_CROS_BUILD_CONFIG_PATTERN, build_config[len(board):])
182 if not match:
183 raise ValueError('build_config %s is not matched %s' % (
184 build_config, _CROS_BUILD_CONFIG_PATTERN))
185
186 return CrOSBuildConfigInfo(board, match.groups()[0])
187
188
189def get_board_by_android_target(target):
190 """Map a android target to a android board.
191
192 # Mapping between an android board name and a build target. This is for
193 # special case handling for certain Android board that the board name and
194 # build target name does not match.
195 # This comes from server/site_utils.py in autotest module.
196
197 Args:
198 board: an android board.
199
200 Returns:
201 a string android board mapped by ANDROID_TARGET_TO_BOARD_MAP.
202 """
203 return _ANDROID_TARGET_TO_BOARD_MAP.get(target, target)
204
205
206# The default build type for fetching latest build.
207_DEFAULT_BUILD_SUFFIX = '-paladin'
208
209# The default setting of board for fetching latest build.
210_DEFAULT_MASTER = 'master'
211
212# The path for storing the latest build.
213_GS_LATEST_MASTER_PATTERN = '%(board)s%(suffix)s/%(name)s'
214
215# The gs bucket to fetch the latest build.
216_GS_BUCKET = 'chromeos-image-archive'
217
218# The file in Google Storage to fetch the latest build.
219_LATEST_MASTER = 'LATEST-master'
220
221# Special android target to board map.
222_ANDROID_TARGET_TO_BOARD_MAP = {
223 'seed_l8150': 'gm4g_sprout',
224 'bat_land': 'bat'
225}
226
227# CrOS build name patter
228_CROS_BUILD_PATTERN = '%(board)s-%(build_type)s/R%(milestone)s-%(manifest)s'
229
230# Android build name pattern
231_ANDROID_BUILD_PATTERN = '%(branch)s/%(target)s/%(build_id)s'
232
233# The pattern for Launch Control target
234_LAUNCH_CONTROL_TARGET_PATTERN = r'(?P<build_target>.+)-(?P<build_type>[^-]+)'
235
236# The pattern for CrOS build config
237_CROS_BUILD_CONFIG_PATTERN = r'-([^-]+)(?:-group)?'