blob: c252e736e8ef9475a4def80dd7a526653a4cb532 [file] [log] [blame]
Mike Frysingere58c0e22017-10-04 15:43:30 -04001# -*- coding: utf-8 -*-
David Rileyc0da9d92016-02-01 12:11:01 -08002# Copyright 2016 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""This module uprevs Android for cbuildbot.
7
8After calling, it prints outs ANDROID_VERSION_ATOM=(version atom string). A
9caller could then use this atom with emerge to build the newly uprevved version
10of Android e.g.
11
Shuhei Takahashi6d02c192017-04-05 14:01:24 +090012./cros_mark_android_as_stable \
Shao-Chuan Lee9c39e0c2020-04-24 11:40:34 +090013 --android_build_branch=git_pi-arc \
14 --android_package=android-container-pi
Shuhei Takahashi6d02c192017-04-05 14:01:24 +090015
Shao-Chuan Lee9c39e0c2020-04-24 11:40:34 +090016Returns chromeos-base/android-container-pi-6417892-r1
David Rileyc0da9d92016-02-01 12:11:01 -080017
Shao-Chuan Lee9c39e0c2020-04-24 11:40:34 +090018emerge-eve =chromeos-base/android-container-pi-6417892-r1
David Rileyc0da9d92016-02-01 12:11:01 -080019"""
20
21from __future__ import print_function
22
23import filecmp
24import glob
25import os
Hidehiko Abe12727dd2016-05-27 23:23:45 +090026import re
khmel@google.com96c193e2018-05-10 14:00:38 -070027import time
Mike Frysinger00a02292020-04-19 06:28:03 -040028import sys
David Rileyc0da9d92016-02-01 12:11:01 -080029
Aviv Keshetb7519e12016-10-04 00:50:00 -070030from chromite.lib import constants
David Rileyc0da9d92016-02-01 12:11:01 -080031from chromite.lib import commandline
32from chromite.lib import cros_build_lib
33from chromite.lib import cros_logging as logging
34from chromite.lib import git
35from chromite.lib import gs
36from chromite.lib import portage_util
37from chromite.scripts import cros_mark_as_stable
38
39
Mike Frysinger00a02292020-04-19 06:28:03 -040040assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'
41
42
David Rileyc0da9d92016-02-01 12:11:01 -080043# Dir where all the action happens.
44_OVERLAY_DIR = '%(srcroot)s/private-overlays/project-cheets-private/'
45
Junichi Uekawa6d61ab02020-04-15 14:52:28 +090046_GIT_COMMIT_MESSAGE = """Marking latest for %(android_package)s ebuild with \
47version %(android_version)s as stable.
48
49BUG=None
50TEST=CQ
51"""
David Rileyc0da9d92016-02-01 12:11:01 -080052
khmel@chromium.orgd3ec3d72020-04-29 15:57:35 -070053_RUNTIME_ARTIFACTS_BUCKET_URL = 'gs://chromeos-arc-images/runtime_artifacts'
David Rileyc0da9d92016-02-01 12:11:01 -080054
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +090055def IsBuildIdValid(bucket_url, build_branch, build_id, targets):
David Rileyc0da9d92016-02-01 12:11:01 -080056 """Checks that a specific build_id is valid.
57
58 Looks for that build_id for all builds. Confirms that the subpath can
59 be found and that the zip file is present in that subdirectory.
60
61 Args:
62 bucket_url: URL of Android build gs bucket
63 build_branch: branch of Android builds
64 build_id: A string. The Android build id number to check.
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +090065 targets: Dict from build key to (targe build suffix, artifact file pattern)
66 pair.
David Rileyc0da9d92016-02-01 12:11:01 -080067
68 Returns:
69 Returns subpaths dictionary if build_id is valid.
70 None if the build_id is not valid.
71 """
72 gs_context = gs.GSContext()
73 subpaths_dict = {}
Mike Frysinger0bdbc102019-06-13 15:27:29 -040074 for build, (target, _) in targets.items():
David Rileyc0da9d92016-02-01 12:11:01 -080075 build_dir = '%s-%s' % (build_branch, target)
76 build_id_path = os.path.join(bucket_url, build_dir, build_id)
77
78 # Find name of subpath.
79 try:
80 subpaths = gs_context.List(build_id_path)
81 except gs.GSNoSuchKey:
Mike Frysinger968c1142020-05-09 00:37:56 -040082 logging.warning(
David Rileyc0da9d92016-02-01 12:11:01 -080083 'Directory [%s] does not contain any subpath, ignoring it.',
84 build_id_path)
85 return None
86 if len(subpaths) > 1:
Mike Frysinger968c1142020-05-09 00:37:56 -040087 logging.warning(
David Rileyc0da9d92016-02-01 12:11:01 -080088 'Directory [%s] contains more than one subpath, ignoring it.',
89 build_id_path)
90 return None
91
92 subpath_dir = subpaths[0].url.rstrip('/')
93 subpath_name = os.path.basename(subpath_dir)
94
95 # Look for a zipfile ending in the build_id number.
96 try:
Hidehiko Abe12727dd2016-05-27 23:23:45 +090097 gs_context.List(subpath_dir)
David Rileyc0da9d92016-02-01 12:11:01 -080098 except gs.GSNoSuchKey:
Mike Frysinger968c1142020-05-09 00:37:56 -040099 logging.warning(
Hidehiko Abe12727dd2016-05-27 23:23:45 +0900100 'Did not find a file for build id [%s] in directory [%s].',
David Rileyc0da9d92016-02-01 12:11:01 -0800101 build_id, subpath_dir)
102 return None
103
104 # Record subpath for the build.
105 subpaths_dict[build] = subpath_name
106
107 # If we got here, it means we found an appropriate build for all platforms.
108 return subpaths_dict
109
110
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900111def GetLatestBuild(bucket_url, build_branch, targets):
David Rileyc0da9d92016-02-01 12:11:01 -0800112 """Searches the gs bucket for the latest green build.
113
114 Args:
115 bucket_url: URL of Android build gs bucket
116 build_branch: branch of Android builds
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900117 targets: Dict from build key to (targe build suffix, artifact file pattern)
118 pair.
David Rileyc0da9d92016-02-01 12:11:01 -0800119
120 Returns:
121 Tuple of (latest version string, subpaths dictionary)
122 If no latest build can be found, returns None, None
123 """
124 gs_context = gs.GSContext()
125 common_build_ids = None
126 # Find builds for each target.
Mike Frysinger0bdbc102019-06-13 15:27:29 -0400127 for target, _ in targets.values():
David Rileyc0da9d92016-02-01 12:11:01 -0800128 build_dir = '-'.join((build_branch, target))
129 base_path = os.path.join(bucket_url, build_dir)
130 build_ids = []
131 for gs_result in gs_context.List(base_path):
132 # Remove trailing slashes and get the base name, which is the build_id.
133 build_id = os.path.basename(gs_result.url.rstrip('/'))
134 if not build_id.isdigit():
Mike Frysinger968c1142020-05-09 00:37:56 -0400135 logging.warning('Directory [%s] does not look like a valid build_id.',
136 gs_result.url)
David Rileyc0da9d92016-02-01 12:11:01 -0800137 continue
138 build_ids.append(build_id)
139
140 # Update current list of builds.
141 if common_build_ids is None:
142 # First run, populate it with the first platform.
143 common_build_ids = set(build_ids)
144 else:
145 # Already populated, find the ones that are common.
146 common_build_ids.intersection_update(build_ids)
147
148 if common_build_ids is None:
Mike Frysinger968c1142020-05-09 00:37:56 -0400149 logging.warning('Did not find a build_id common to all platforms.')
David Rileyc0da9d92016-02-01 12:11:01 -0800150 return None, None
151
152 # Otherwise, find the most recent one that is valid.
153 for build_id in sorted(common_build_ids, key=int, reverse=True):
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900154 subpaths = IsBuildIdValid(bucket_url, build_branch, build_id, targets)
David Rileyc0da9d92016-02-01 12:11:01 -0800155 if subpaths:
156 return build_id, subpaths
157
158 # If not found, no build_id is valid.
Mike Frysinger968c1142020-05-09 00:37:56 -0400159 logging.warning('Did not find a build_id valid on all platforms.')
David Rileyc0da9d92016-02-01 12:11:01 -0800160 return None, None
161
162
163def FindAndroidCandidates(package_dir):
164 """Return a tuple of Android's unstable ebuild and stable ebuilds.
165
166 Args:
167 package_dir: The path to where the package ebuild is stored.
168
169 Returns:
170 Tuple [unstable_ebuild, stable_ebuilds].
171
172 Raises:
173 Exception: if no unstable ebuild exists for Android.
174 """
175 stable_ebuilds = []
176 unstable_ebuilds = []
177 for path in glob.glob(os.path.join(package_dir, '*.ebuild')):
178 ebuild = portage_util.EBuild(path)
179 if ebuild.version == '9999':
180 unstable_ebuilds.append(ebuild)
181 else:
182 stable_ebuilds.append(ebuild)
183
184 # Apply some sanity checks.
185 if not unstable_ebuilds:
186 raise Exception('Missing 9999 ebuild for %s' % package_dir)
187 if not stable_ebuilds:
Lann Martinffb95162018-08-28 12:02:54 -0600188 logging.warning('Missing stable ebuild for %s', package_dir)
David Rileyc0da9d92016-02-01 12:11:01 -0800189
190 return portage_util.BestEBuild(unstable_ebuilds), stable_ebuilds
191
192
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800193def _GetArcBasename(build, basename):
194 """Tweaks filenames between Android bucket and ARC++ bucket.
195
196 Android builders create build artifacts with the same name for -user and
197 -userdebug builds, which breaks the android-container ebuild (b/33072485).
198 When copying the artifacts from the Android bucket to the ARC++ bucket some
199 artifacts will be renamed from the usual pattern
200 *cheets_${ARCH}-target_files-S{VERSION}.zip to
201 cheets_${BUILD_NAME}-target_files-S{VERSION}.zip which will typically look
202 like cheets_(${LABEL})*${ARCH}_userdebug-target_files-S{VERSION}.zip.
203
204 Args:
205 build: the build being mirrored, e.g. 'X86', 'ARM', 'X86_USERDEBUG'.
206 basename: the basename of the artifact to copy.
207
208 Returns:
209 The basename of the destination.
210 """
211 if build not in constants.ARC_BUILDS_NEED_ARTIFACTS_RENAMED:
212 return basename
Yūki Ishiief1ada92018-03-27 15:46:15 +0900213 if basename in constants.ARC_ARTIFACTS_RENAME_NOT_NEEDED:
214 return basename
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800215 to_discard, sep, to_keep = basename.partition('-')
216 if not sep:
217 logging.error(('Build %s: Could not find separator "-" in artifact'
218 ' basename %s'), build, basename)
219 return basename
Bernie Thompson63ed5612017-08-16 12:27:34 -0700220 if 'cheets_' in to_discard:
221 return 'cheets_%s-%s' % (build.lower(), to_keep)
222 elif 'bertha_' in to_discard:
223 return 'bertha_%s-%s' % (build.lower(), to_keep)
224 logging.error('Build %s: Unexpected artifact basename %s',
225 build, basename)
226 return basename
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800227
228
David Riley73f00d92016-02-16 18:54:20 -0800229def CopyToArcBucket(android_bucket_url, build_branch, build_id, subpaths,
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900230 targets, arc_bucket_url, acls):
David Riley73f00d92016-02-16 18:54:20 -0800231 """Copies from source Android bucket to ARC++ specific bucket.
232
233 Copies each build to the ARC bucket eliminating the subpath.
234 Applies build specific ACLs for each file.
235
236 Args:
237 android_bucket_url: URL of Android build gs bucket
238 build_branch: branch of Android builds
239 build_id: A string. The Android build id number to check.
240 subpaths: Subpath dictionary for each build to copy.
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900241 targets: Dict from build key to (targe build suffix, artifact file pattern)
242 pair.
David Riley73f00d92016-02-16 18:54:20 -0800243 arc_bucket_url: URL of the target ARC build gs bucket
244 acls: ACLs dictionary for each build to copy.
245 """
246 gs_context = gs.GSContext()
Mike Frysinger0bdbc102019-06-13 15:27:29 -0400247 for build, subpath in subpaths.items():
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900248 target, pattern = targets[build]
David Riley73f00d92016-02-16 18:54:20 -0800249 build_dir = '%s-%s' % (build_branch, target)
250 android_dir = os.path.join(android_bucket_url, build_dir, build_id, subpath)
251 arc_dir = os.path.join(arc_bucket_url, build_dir, build_id)
252
Hidehiko Abe12727dd2016-05-27 23:23:45 +0900253 # Copy all target files from android_dir to arc_dir, setting ACLs.
254 for targetfile in gs_context.List(android_dir):
255 if re.search(pattern, targetfile.url):
256 basename = os.path.basename(targetfile.url)
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800257 arc_path = os.path.join(arc_dir, _GetArcBasename(build, basename))
David Riley73f00d92016-02-16 18:54:20 -0800258 acl = acls[build]
259 needs_copy = True
khmel@google.com96c193e2018-05-10 14:00:38 -0700260 retry_count = 2
David Riley73f00d92016-02-16 18:54:20 -0800261
khmel@google.com96c193e2018-05-10 14:00:38 -0700262 # Retry in case race condition when several boards trying to copy the
263 # same resource
264 while True:
265 # Check a pre-existing file with the original source.
266 if gs_context.Exists(arc_path):
267 if (gs_context.Stat(targetfile.url).hash_crc32c !=
268 gs_context.Stat(arc_path).hash_crc32c):
Mike Frysinger968c1142020-05-09 00:37:56 -0400269 logging.warning('Removing incorrect file %s', arc_path)
khmel@google.com96c193e2018-05-10 14:00:38 -0700270 gs_context.Remove(arc_path)
271 else:
272 logging.info('Skipping already copied file %s', arc_path)
273 needs_copy = False
David Riley73f00d92016-02-16 18:54:20 -0800274
khmel@google.com96c193e2018-05-10 14:00:38 -0700275 # Copy if necessary, and set the ACL unconditionally.
276 # The Stat() call above doesn't verify the ACL is correct and
277 # the ChangeACL should be relatively cheap compared to the copy.
278 # This covers the following caes:
279 # - handling an interrupted copy from a previous run.
280 # - rerunning the copy in case one of the googlestorage_acl_X.txt
281 # files changes (e.g. we add a new variant which reuses a build).
282 if needs_copy:
283 logging.info('Copying %s -> %s (acl %s)',
284 targetfile.url, arc_path, acl)
285 try:
286 gs_context.Copy(targetfile.url, arc_path, version=0)
287 except gs.GSContextPreconditionFailed as error:
288 if not retry_count:
289 raise error
290 # Retry one more time after a short delay
291 logging.warning('Will retry copying %s -> %s',
292 targetfile.url, arc_path)
293 time.sleep(5)
294 retry_count = retry_count - 1
295 continue
296 gs_context.ChangeACL(arc_path, acl_args_file=acl)
297 break
David Riley73f00d92016-02-16 18:54:20 -0800298
299
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900300def MirrorArtifacts(android_bucket_url, android_build_branch, arc_bucket_url,
301 acls, targets, version=None):
302 """Mirrors artifacts from Android bucket to ARC bucket.
303
304 First, this function identifies which build version should be copied,
305 if not given. Please see GetLatestBuild() and IsBuildIdValid() for details.
306
307 On build version identified, then copies target artifacts to the ARC bucket,
308 with setting ACLs.
309
310 Args:
311 android_bucket_url: URL of Android build gs bucket
312 android_build_branch: branch of Android builds
313 arc_bucket_url: URL of the target ARC build gs bucket
314 acls: ACLs dictionary for each build to copy.
315 targets: Dict from build key to (targe build suffix, artifact file pattern)
316 pair.
317 version: (optional) A string. The Android build id number to check.
318 If not passed, detect latest good build version.
319
320 Returns:
321 Mirrored version.
322 """
323 if version:
324 subpaths = IsBuildIdValid(
325 android_bucket_url, android_build_branch, version, targets)
326 if not subpaths:
Lann Martinffb95162018-08-28 12:02:54 -0600327 logging.error('Requested build %s is not valid', version)
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900328 else:
329 version, subpaths = GetLatestBuild(
330 android_bucket_url, android_build_branch, targets)
331
332 CopyToArcBucket(android_bucket_url, android_build_branch, version, subpaths,
333 targets, arc_bucket_url, acls)
khmel@google.com778a1cd2018-04-13 11:11:58 -0700334
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900335 return version
336
337
David Riley73f00d92016-02-16 18:54:20 -0800338def MakeAclDict(package_dir):
339 """Creates a dictionary of acl files for each build type.
340
341 Args:
342 package_dir: The path to where the package acl files are stored.
343
344 Returns:
345 Returns acls dictionary.
346 """
347 return dict(
348 (k, os.path.join(package_dir, v))
349 for k, v in constants.ARC_BUCKET_ACLS.items()
350 )
351
352
Qijiang Fan6588cc92019-11-20 13:26:04 +0900353def MakeBuildTargetDict(package_name, build_branch):
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700354 """Creates a dictionary of build targets.
355
Bernie Thompson63ed5612017-08-16 12:27:34 -0700356 Not all targets are common between branches, for example
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700357 sdk_google_cheets_x86 only exists on N.
358 This generates a dictionary listing the available build targets for a
359 specific branch.
360
361 Args:
Qijiang Fan6588cc92019-11-20 13:26:04 +0900362 package_name: package name of chromeos arc package.
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700363 build_branch: branch of Android builds.
364
365 Returns:
366 Returns build target dictionary.
367
368 Raises:
369 ValueError: if the Android build branch is invalid.
370 """
Qijiang Fan6588cc92019-11-20 13:26:04 +0900371 if constants.ANDROID_CONTAINER_PACKAGE_KEYWORD in package_name:
Federico 'Morg' Pareschi041ee652020-03-10 15:09:42 +0900372 target_list = {
Federico 'Morg' Pareschi041ee652020-03-10 15:09:42 +0900373 constants.ANDROID_PI_BUILD_BRANCH:
374 constants.ANDROID_PI_BUILD_TARGETS,
Federico 'Morg' Pareschi041ee652020-03-10 15:09:42 +0900375 }
Qijiang Fan6588cc92019-11-20 13:26:04 +0900376 elif constants.ANDROID_VM_PACKAGE_KEYWORD in package_name:
Federico 'Morg' Pareschi041ee652020-03-10 15:09:42 +0900377 target_list = {
Federico 'Morg' Pareschi041ee652020-03-10 15:09:42 +0900378 constants.ANDROID_VMMST_BUILD_BRANCH:
379 constants.ANDROID_VMMST_BUILD_TARGETS,
380 constants.ANDROID_VMRVC_BUILD_BRANCH:
381 constants.ANDROID_VMRVC_BUILD_TARGETS,
382 }
383 else:
384 raise ValueError('Unknown package: %s' % package_name)
385 target = target_list.get(build_branch)
386 if not target:
Qijiang Fan6588cc92019-11-20 13:26:04 +0900387 raise ValueError('Unknown branch: %s' % build_branch)
Federico 'Morg' Pareschi041ee652020-03-10 15:09:42 +0900388 return target
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700389
390
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +0900391def PrintUprevMetadata(build_branch, stable_candidate, new_ebuild):
392 """Shows metadata on buildbot page at UprevAndroid step.
David Rileyc0da9d92016-02-01 12:11:01 -0800393
394 Args:
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +0900395 build_branch: The branch of Android builds.
396 stable_candidate: The existing stable ebuild.
397 new_ebuild: The newly written ebuild.
David Rileyc0da9d92016-02-01 12:11:01 -0800398 """
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +0900399 # Examples:
400 # "android-container-pi revved 6461825-r1 -> 6468247-r1"
401 # "android-container-pi revved 6461825-r1 -> 6461825-r2 (ebuild update only)"
402 msg = '%s revved %s -> %s' % (stable_candidate.pkgname,
403 stable_candidate.version,
404 new_ebuild.version)
405
406 old_android = stable_candidate.version_no_rev
407 new_android = new_ebuild.version_no_rev
408
409 if old_android == new_android:
410 msg += ' (ebuild update only)'
411 else:
412 ab_link = ('https://android-build.googleplex.com'
413 '/builds/%s/branches/%s/cls?end=%s'
414 % (new_android, build_branch, old_android))
415 logging.PrintBuildbotLink('Android changelog', ab_link)
416
417 logging.PrintBuildbotStepText(msg)
David Rileyc0da9d92016-02-01 12:11:01 -0800418
419
khmel@chromium.orgd3ec3d72020-04-29 15:57:35 -0700420def UpdateDataCollectorArtifacts(android_version,
421 runtime_artifacts_bucket_url):
422 r"""Finds and includes into variables artifacts from arc.DataCollector.
423
424 Args:
425 android_version: The \d+ build id of Android.
426 runtime_artifacts_bucket_url: root of runtime artifacts
427
428 Returns:
429 dictionary with filled ebuild variables.
430 """
431
432 variables = {}
433 buckets = ['ureadahead_pack', 'gms_core_cache']
434 archs = ['arm', 'arm64', 'x86', 'x86_64']
435 build_types = ['user', 'userdebug']
436
437 version_reference = '${PV}'
438 gs_context = gs.GSContext()
439 for bucket in buckets:
440 for arch in archs:
441 for build_type in build_types:
442 path = (f'{runtime_artifacts_bucket_url}/{bucket}_{arch}_{build_type}_'
Yury Khmele1b74402020-05-18 08:41:35 -0700443 f'{android_version}.tar')
khmel@chromium.orgd3ec3d72020-04-29 15:57:35 -0700444 if gs_context.Exists(path):
445 variables[(f'{arch}_{build_type}_{bucket}').upper()] = (
446 f'{runtime_artifacts_bucket_url}/{bucket}_{arch}_{build_type}_'
447 f'{version_reference}.tar')
448
449 return variables
450
451
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900452def MarkAndroidEBuildAsStable(stable_candidate, unstable_ebuild,
453 android_package, android_version, package_dir,
khmel@chromium.orgd3ec3d72020-04-29 15:57:35 -0700454 build_branch, arc_bucket_url,
455 runtime_artifacts_bucket_url,
456 build_targets):
David Rileyc0da9d92016-02-01 12:11:01 -0800457 r"""Uprevs the Android ebuild.
458
459 This is the main function that uprevs from a stable candidate
460 to its new version.
461
462 Args:
463 stable_candidate: ebuild that corresponds to the stable ebuild we are
464 revving from. If None, builds the a new ebuild given the version
465 with revision set to 1.
466 unstable_ebuild: ebuild corresponding to the unstable ebuild for Android.
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900467 android_package: android package name.
David Rileyc0da9d92016-02-01 12:11:01 -0800468 android_version: The \d+ build id of Android.
David Rileyc0da9d92016-02-01 12:11:01 -0800469 package_dir: Path to the android-container package dir.
David Riley73f00d92016-02-16 18:54:20 -0800470 build_branch: branch of Android builds.
471 arc_bucket_url: URL of the target ARC build gs bucket.
khmel@chromium.orgd3ec3d72020-04-29 15:57:35 -0700472 runtime_artifacts_bucket_url: root of runtime artifacts
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700473 build_targets: build targets for this particular Android branch.
David Rileyc0da9d92016-02-01 12:11:01 -0800474
475 Returns:
476 Full portage version atom (including rc's, etc) that was revved.
477 """
478 def IsTheNewEBuildRedundant(new_ebuild, stable_ebuild):
479 """Returns True if the new ebuild is redundant.
480
481 This is True if there if the current stable ebuild is the exact same copy
482 of the new one.
483 """
484 if not stable_ebuild:
485 return False
486
David Riley676f5402016-02-12 17:24:23 -0800487 if stable_candidate.version_no_rev == new_ebuild.version_no_rev:
David Rileyc0da9d92016-02-01 12:11:01 -0800488 return filecmp.cmp(
489 new_ebuild.ebuild_path, stable_ebuild.ebuild_path, shallow=False)
khmel@chromium.orgd3ec3d72020-04-29 15:57:35 -0700490 return False
David Rileyc0da9d92016-02-01 12:11:01 -0800491
492 # Case where we have the last stable candidate with same version just rev.
David Riley676f5402016-02-12 17:24:23 -0800493 if stable_candidate and stable_candidate.version_no_rev == android_version:
David Rileyc0da9d92016-02-01 12:11:01 -0800494 new_ebuild_path = '%s-r%d.ebuild' % (
495 stable_candidate.ebuild_path_no_revision,
496 stable_candidate.current_revision + 1)
497 else:
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900498 pf = '%s-%s-r1' % (android_package, android_version)
David Rileyc0da9d92016-02-01 12:11:01 -0800499 new_ebuild_path = os.path.join(package_dir, '%s.ebuild' % pf)
500
David Riley73f00d92016-02-16 18:54:20 -0800501 variables = {'BASE_URL': arc_bucket_url}
Mike Frysinger0bdbc102019-06-13 15:27:29 -0400502 for build, (target, _) in build_targets.items():
David Riley73f00d92016-02-16 18:54:20 -0800503 variables[build + '_TARGET'] = '%s-%s' % (build_branch, target)
David Rileyc0da9d92016-02-01 12:11:01 -0800504
khmel@chromium.orgd3ec3d72020-04-29 15:57:35 -0700505 variables.update(UpdateDataCollectorArtifacts(
506 android_version, runtime_artifacts_bucket_url))
507
David Rileyc0da9d92016-02-01 12:11:01 -0800508 portage_util.EBuild.MarkAsStable(
509 unstable_ebuild.ebuild_path, new_ebuild_path,
510 variables, make_stable=True)
511 new_ebuild = portage_util.EBuild(new_ebuild_path)
512
513 # Determine whether this is ebuild is redundant.
514 if IsTheNewEBuildRedundant(new_ebuild, stable_candidate):
515 msg = 'Previous ebuild with same version found and ebuild is redundant.'
516 logging.info(msg)
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +0900517 logging.PrintBuildbotStepText('%s %s not revved'
518 % (stable_candidate.pkgname,
519 stable_candidate.version))
David Rileyc0da9d92016-02-01 12:11:01 -0800520 os.unlink(new_ebuild_path)
521 return None
522
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +0900523 # PFQ runs should always be able to find a stable candidate.
David Rileyc0da9d92016-02-01 12:11:01 -0800524 if stable_candidate:
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +0900525 PrintUprevMetadata(build_branch, stable_candidate, new_ebuild)
David Rileyc0da9d92016-02-01 12:11:01 -0800526
527 git.RunGit(package_dir, ['add', new_ebuild_path])
528 if stable_candidate and not stable_candidate.IsSticky():
529 git.RunGit(package_dir, ['rm', stable_candidate.ebuild_path])
530
531 # Update ebuild manifest and git add it.
532 gen_manifest_cmd = ['ebuild', new_ebuild_path, 'manifest', '--force']
Mike Frysinger45602c72019-09-22 02:15:11 -0400533 cros_build_lib.run(gen_manifest_cmd, extra_env=None, print_cmd=True)
David Rileyc0da9d92016-02-01 12:11:01 -0800534 git.RunGit(package_dir, ['add', 'Manifest'])
535
536 portage_util.EBuild.CommitChange(
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900537 _GIT_COMMIT_MESSAGE % {'android_package': android_package,
David Rileyc0da9d92016-02-01 12:11:01 -0800538 'android_version': android_version},
539 package_dir)
540
541 return '%s-%s' % (new_ebuild.package, new_ebuild.version)
542
543
544def GetParser():
545 """Creates the argument parser."""
546 parser = commandline.ArgumentParser()
547 parser.add_argument('-b', '--boards')
548 parser.add_argument('--android_bucket_url',
David Riley73f00d92016-02-16 18:54:20 -0800549 default=constants.ANDROID_BUCKET_URL,
550 type='gs_path')
David Rileyc0da9d92016-02-01 12:11:01 -0800551 parser.add_argument('--android_build_branch',
Shuhei Takahashi6d02c192017-04-05 14:01:24 +0900552 required=True,
553 help='Android branch to import from. '
554 'Ex: git_mnc-dr-arc-dev')
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900555 parser.add_argument('--android_package',
556 default=constants.ANDROID_PACKAGE_NAME)
David Riley73f00d92016-02-16 18:54:20 -0800557 parser.add_argument('--arc_bucket_url',
558 default=constants.ARC_BUCKET_URL,
559 type='gs_path')
David Rileyc0da9d92016-02-01 12:11:01 -0800560 parser.add_argument('-f', '--force_version',
561 help='Android build id to use')
562 parser.add_argument('-s', '--srcroot',
563 default=os.path.join(os.environ['HOME'], 'trunk', 'src'),
564 help='Path to the src directory')
565 parser.add_argument('-t', '--tracking_branch', default='cros/master',
566 help='Branch we are tracking changes against')
khmel@chromium.orgd3ec3d72020-04-29 15:57:35 -0700567 parser.add_argument('--runtime_artifacts_bucket_url',
568 default=_RUNTIME_ARTIFACTS_BUCKET_URL,
569 type='gs_path')
David Rileyc0da9d92016-02-01 12:11:01 -0800570 return parser
571
572
573def main(argv):
Hidehiko Abec9ecf262017-07-05 15:17:41 +0900574 logging.EnableBuildbotMarkers()
David Rileyc0da9d92016-02-01 12:11:01 -0800575 parser = GetParser()
576 options = parser.parse_args(argv)
577 options.Freeze()
578
579 overlay_dir = os.path.abspath(_OVERLAY_DIR % {'srcroot': options.srcroot})
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900580 android_package_dir = os.path.join(
581 overlay_dir,
582 portage_util.GetFullAndroidPortagePackageName(options.android_package))
David Rileyc0da9d92016-02-01 12:11:01 -0800583 version_to_uprev = None
David Rileyc0da9d92016-02-01 12:11:01 -0800584
585 (unstable_ebuild, stable_ebuilds) = FindAndroidCandidates(android_package_dir)
David Riley73f00d92016-02-16 18:54:20 -0800586 acls = MakeAclDict(android_package_dir)
Qijiang Fan6588cc92019-11-20 13:26:04 +0900587 build_targets = MakeBuildTargetDict(options.android_package,
588 options.android_build_branch)
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900589 # Mirror artifacts, i.e., images and some sdk tools (e.g., adb, aapt).
590 version_to_uprev = MirrorArtifacts(options.android_bucket_url,
591 options.android_build_branch,
592 options.arc_bucket_url, acls,
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700593 build_targets,
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900594 options.force_version)
595
David Rileyc0da9d92016-02-01 12:11:01 -0800596 stable_candidate = portage_util.BestEBuild(stable_ebuilds)
597
598 if stable_candidate:
Lann Martinffb95162018-08-28 12:02:54 -0600599 logging.info('Stable candidate found %s', stable_candidate.version)
David Rileyc0da9d92016-02-01 12:11:01 -0800600 else:
601 logging.info('No stable candidate found.')
602
603 tracking_branch = 'remotes/m/%s' % os.path.basename(options.tracking_branch)
604 existing_branch = git.GetCurrentBranch(android_package_dir)
605 work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
606 tracking_branch,
607 android_package_dir)
608 work_branch.CreateBranch()
609
610 # In the case of uprevving overlays that have patches applied to them,
611 # include the patched changes in the stabilizing branch.
612 if existing_branch:
613 git.RunGit(overlay_dir, ['rebase', existing_branch])
614
615 android_version_atom = MarkAndroidEBuildAsStable(
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900616 stable_candidate, unstable_ebuild, options.android_package,
David Riley73f00d92016-02-16 18:54:20 -0800617 version_to_uprev, android_package_dir,
khmel@chromium.orgd3ec3d72020-04-29 15:57:35 -0700618 options.android_build_branch, options.arc_bucket_url,
619 options.runtime_artifacts_bucket_url, build_targets)
David Rileyc0da9d92016-02-01 12:11:01 -0800620 if android_version_atom:
621 if options.boards:
622 cros_mark_as_stable.CleanStalePackages(options.srcroot,
623 options.boards.split(':'),
624 [android_version_atom])
625
626 # Explicit print to communicate to caller.
627 print('ANDROID_VERSION_ATOM=%s' % android_version_atom)