Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(443)

Side by Side Diff: bin/cbuildbot.py

Issue 4442001: Add more error checking to preflight queue. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/crosutils.git
Patch Set: Update cros_mark_as_stable.py to run outside chroot Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | bin/cbuildbot_config.py » ('j') | cros_mark_as_stable.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 """CBuildbot is wrapper around the build process used by the pre-flight queue""" 7 """CBuildbot is wrapper around the build process used by the pre-flight queue"""
8 8
9 import errno 9 import errno
10 import heapq 10 import heapq
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 repo_name = revision_tuple[0].replace('.git', '') 174 repo_name = revision_tuple[0].replace('.git', '')
175 # Might not have entry if no matching ebuild. 175 # Might not have entry if no matching ebuild.
176 if repo_dictionary.has_key(repo_name): 176 if repo_dictionary.has_key(repo_name):
177 # May be many corresponding packages to a given git repo e.g. kernel). 177 # May be many corresponding packages to a given git repo e.g. kernel).
178 for package in repo_dictionary[repo_name]: 178 for package in repo_dictionary[repo_name]:
179 revisions[package] = revision_tuple[1] 179 revisions[package] = revision_tuple[1]
180 180
181 return revisions.items() 181 return revisions.items()
182 182
183 183
184 def _UprevFromRevisionList(buildroot, tracking_branch, revision_list, board): 184 def _UprevFromRevisionList(buildroot, tracking_branch, revision_list, board,
185 overlays):
185 """Uprevs based on revision list.""" 186 """Uprevs based on revision list."""
186 if not revision_list: 187 if not revision_list:
187 Info('No packages found to uprev') 188 Info('No packages found to uprev')
188 return 189 return
189 190
190 package_str = '' 191 packages = []
191 for package, revision in revision_list: 192 for package, revision in revision_list:
192 package_str += package + ' ' 193 assert ':' not in package, 'Invalid package name: %s' % package
193 194 packages.append(package)
194 package_str = package_str.strip()
195 195
196 cwd = os.path.join(buildroot, 'src', 'scripts') 196 cwd = os.path.join(buildroot, 'src', 'scripts')
197 # TODO(davidjames): --foo="bar baz" only works here because we're using 197 RunCommand(['./cros_mark_as_stable', '--srcroot=..',
sosa 2010/11/12 19:18:46 put on sep line and below
198 # enter_chroot.
199 RunCommand(['./cros_mark_as_stable',
200 '--board=%s' % board, 198 '--board=%s' % board,
201 '--tracking_branch="%s"' % tracking_branch, 199 '--tracking_branch=%s' % tracking_branch,
202 '--packages="%s"' % package_str, 200 '--overlays=%s' % ':'.join(overlays),
201 '--packages=%s' % ':'.join(packages),
203 'commit'], 202 'commit'],
204 cwd=cwd, enter_chroot=True) 203 cwd=cwd)
205 204
206 205
207 def _UprevAllPackages(buildroot, tracking_branch, board): 206 def _UprevAllPackages(buildroot, tracking_branch, board, overlays):
208 """Uprevs all packages that have been updated since last uprev.""" 207 """Uprevs all packages that have been updated since last uprev."""
209 cwd = os.path.join(buildroot, 'src', 'scripts') 208 cwd = os.path.join(buildroot, 'src', 'scripts')
210 # TODO(davidjames): --foo="bar baz" only works here because we're using 209 RunCommand(['./cros_mark_as_stable', '--all', '--srcroot=..',
211 # enter_chroot.
212 RunCommand(['./cros_mark_as_stable', '--all',
213 '--board=%s' % board, 210 '--board=%s' % board,
214 '--tracking_branch="%s"' % tracking_branch, 'commit'], 211 '--overlays=%s' % ':'.join(overlays),
215 cwd=cwd, enter_chroot=True) 212 '--tracking_branch=%s' % tracking_branch, 'commit'],
213 cwd=cwd)
216 214
217 215
218 def _GetVMConstants(buildroot): 216 def _GetVMConstants(buildroot):
219 """Returns minimum (vdisk_size, statefulfs_size) recommended for VM's.""" 217 """Returns minimum (vdisk_size, statefulfs_size) recommended for VM's."""
220 cwd = os.path.join(buildroot, 'src', 'scripts', 'lib') 218 cwd = os.path.join(buildroot, 'src', 'scripts', 'lib')
221 source_cmd = 'source %s/cros_vm_constants.sh' % cwd 219 source_cmd = 'source %s/cros_vm_constants.sh' % cwd
222 vdisk_size = RunCommand([ 220 vdisk_size = RunCommand([
223 '/bin/bash', '-c', '%s && echo $MIN_VDISK_SIZE_FULL' % source_cmd], 221 '/bin/bash', '-c', '%s && echo $MIN_VDISK_SIZE_FULL' % source_cmd],
224 redirect_stdout=True) 222 redirect_stdout=True)
225 statefulfs_size = RunCommand([ 223 statefulfs_size = RunCommand([
226 '/bin/bash', '-c', '%s && echo $MIN_STATEFUL_FS_SIZE_FULL' % source_cmd], 224 '/bin/bash', '-c', '%s && echo $MIN_STATEFUL_FS_SIZE_FULL' % source_cmd],
227 redirect_stdout=True) 225 redirect_stdout=True)
228 return (vdisk_size.strip(), statefulfs_size.strip()) 226 return (vdisk_size.strip(), statefulfs_size.strip())
229 227
230 228
231 def _GitCleanup(buildroot, board, tracking_branch): 229 def _GitCleanup(buildroot, board, tracking_branch, overlays):
232 """Clean up git branch after previous uprev attempt.""" 230 """Clean up git branch after previous uprev attempt."""
233 cwd = os.path.join(buildroot, 'src', 'scripts') 231 cwd = os.path.join(buildroot, 'src', 'scripts')
234 if os.path.exists(cwd): 232 if os.path.exists(cwd):
235 RunCommand(['./cros_mark_as_stable', '--srcroot=..', 233 RunCommand(['./cros_mark_as_stable', '--srcroot=..',
236 '--board=%s' % board, 234 '--board=%s' % board,
235 '--overlays=%s' % ':'.join(overlays),
237 '--tracking_branch=%s' % tracking_branch, 'clean'], 236 '--tracking_branch=%s' % tracking_branch, 'clean'],
238 cwd=cwd, error_ok=True) 237 cwd=cwd, error_ok=True)
239 238
240 239
241 def _CleanUpMountPoints(buildroot): 240 def _CleanUpMountPoints(buildroot):
242 """Cleans up any stale mount points from previous runs.""" 241 """Cleans up any stale mount points from previous runs."""
243 mount_output = RunCommand(['mount'], redirect_stdout=True) 242 mount_output = RunCommand(['mount'], redirect_stdout=True)
244 mount_pts_in_buildroot = RunCommand(['grep', buildroot], input=mount_output, 243 mount_pts_in_buildroot = RunCommand(['grep', buildroot], input=mount_output,
245 redirect_stdout=True, error_ok=True) 244 redirect_stdout=True, error_ok=True)
246 245
247 for mount_pt_str in mount_pts_in_buildroot.splitlines(): 246 for mount_pt_str in mount_pts_in_buildroot.splitlines():
248 mount_pt = mount_pt_str.rpartition(' type ')[0].partition(' on ')[2] 247 mount_pt = mount_pt_str.rpartition(' type ')[0].partition(' on ')[2]
249 RunCommand(['sudo', 'umount', '-l', mount_pt], error_ok=True) 248 RunCommand(['sudo', 'umount', '-l', mount_pt], error_ok=True)
250 249
251 250
252 def _WipeOldOutput(buildroot): 251 def _WipeOldOutput(buildroot):
253 """Wipes out build output directories.""" 252 """Wipes out build output directories."""
254 RunCommand(['rm', '-rf', 'src/build/images'], cwd=buildroot) 253 RunCommand(['rm', '-rf', 'src/build/images'], cwd=buildroot)
255 254
256 255
257 # =========================== Main Commands =================================== 256 # =========================== Main Commands ===================================
258 257
259 258
260 def _PreFlightRinse(buildroot, board, tracking_branch): 259 def _PreFlightRinse(buildroot, board, tracking_branch, overlays):
261 """Cleans up any leftover state from previous runs.""" 260 """Cleans up any leftover state from previous runs."""
262 _GitCleanup(buildroot, board, tracking_branch) 261 _GitCleanup(buildroot, board, tracking_branch, overlays)
263 _CleanUpMountPoints(buildroot) 262 _CleanUpMountPoints(buildroot)
264 RunCommand(['sudo', 'killall', 'kvm'], error_ok=True) 263 RunCommand(['sudo', 'killall', 'kvm'], error_ok=True)
265 264
266 265
267 def _FullCheckout(buildroot, tracking_branch, rw_checkout=True, 266 def _FullCheckout(buildroot, tracking_branch, rw_checkout=True,
268 retries=_DEFAULT_RETRIES, 267 retries=_DEFAULT_RETRIES,
269 url='http://git.chromium.org/git/manifest'): 268 url='http://git.chromium.org/git/manifest'):
270 """Performs a full checkout and clobbers any previous checkouts.""" 269 """Performs a full checkout and clobbers any previous checkouts."""
271 RunCommand(['sudo', 'rm', '-rf', buildroot]) 270 RunCommand(['sudo', 'rm', '-rf', buildroot])
272 MakeDir(buildroot, parents=True) 271 MakeDir(buildroot, parents=True)
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 shutil.rmtree(results_dir_in_chroot) 339 shutil.rmtree(results_dir_in_chroot)
341 340
342 cwd = os.path.join(buildroot, 'src', 'scripts') 341 cwd = os.path.join(buildroot, 'src', 'scripts')
343 RunCommand(['bin/cros_run_vm_test', 342 RunCommand(['bin/cros_run_vm_test',
344 '--no_graphics', 343 '--no_graphics',
345 '--test_case=suite_Smoke', 344 '--test_case=suite_Smoke',
346 '--results_dir_root=%s' % results_dir, 345 '--results_dir_root=%s' % results_dir,
347 ], cwd=cwd, error_ok=False) 346 ], cwd=cwd, error_ok=False)
348 347
349 348
350 def _UprevPackages(buildroot, tracking_branch, revisionfile, board): 349 def _UprevPackages(buildroot, tracking_branch, revisionfile, board, overlays):
351 """Uprevs a package based on given revisionfile. 350 """Uprevs a package based on given revisionfile.
352 351
353 If revisionfile is set to None or does not resolve to an actual file, this 352 If revisionfile is set to None or does not resolve to an actual file, this
354 function will uprev all packages. 353 function will uprev all packages.
355 354
356 Keyword arguments: 355 Keyword arguments:
357 revisionfile -- string specifying a file that contains a list of revisions to 356 revisionfile -- string specifying a file that contains a list of revisions to
358 uprev. 357 uprev.
359 """ 358 """
360 # Purposefully set to None as it means Force Build was pressed. 359 # Purposefully set to None as it means Force Build was pressed.
361 revisions = 'None' 360 revisions = 'None'
362 if (revisionfile): 361 if (revisionfile):
363 try: 362 try:
364 rev_file = open(revisionfile) 363 rev_file = open(revisionfile)
365 revisions = rev_file.read() 364 revisions = rev_file.read()
366 rev_file.close() 365 rev_file.close()
367 except Exception, e: 366 except Exception, e:
368 Warning('Error reading %s, revving all' % revisionfile) 367 Warning('Error reading %s, revving all' % revisionfile)
369 revisions = 'None' 368 revisions = 'None'
370 369
371 revisions = revisions.strip() 370 revisions = revisions.strip()
372 371
373 # TODO(sosa): Un-comment once we close individual trees. 372 # TODO(sosa): Un-comment once we close individual trees.
374 # revisions == "None" indicates a Force Build. 373 # revisions == "None" indicates a Force Build.
375 #if revisions != 'None': 374 #if revisions != 'None':
376 # print >> sys.stderr, 'CBUILDBOT Revision list found %s' % revisions 375 # print >> sys.stderr, 'CBUILDBOT Revision list found %s' % revisions
377 # revision_list = _ParseRevisionString(revisions, 376 # revision_list = _ParseRevisionString(revisions,
378 # _CreateRepoDictionary(buildroot, board)) 377 # _CreateRepoDictionary(buildroot, board))
379 # _UprevFromRevisionList(buildroot, tracking_branch, revision_list, board) 378 # _UprevFromRevisionList(buildroot, tracking_branch, revision_list, board,
379 # overlays)
380 #else: 380 #else:
381 Info('CBUILDBOT Revving all') 381 Info('CBUILDBOT Revving all')
382 _UprevAllPackages(buildroot, tracking_branch, board) 382 _UprevAllPackages(buildroot, tracking_branch, board, overlays)
383 383
384 384
385 def _UprevPush(buildroot, tracking_branch, board, overlays): 385 def _UprevPush(buildroot, tracking_branch, board, overlays):
386 """Pushes uprev changes to the main line.""" 386 """Pushes uprev changes to the main line."""
387 cwd = os.path.join(buildroot, 'src', 'scripts') 387 cwd = os.path.join(buildroot, 'src', 'scripts')
388 public_overlay = '%s/src/third_party/chromiumos-overlay' % buildroot
389 private_overlay = '%s/src/private-overlays/chromeos-overlay' % buildroot
390 if overlays == 'private':
391 overlays = [private_overlay]
392 elif overlays == 'public':
393 overlays = [public_overlay]
394 else:
395 overlays = [public_overlay, private_overlay]
396 RunCommand(['./cros_mark_as_stable', '--srcroot=..', 388 RunCommand(['./cros_mark_as_stable', '--srcroot=..',
397 '--board=%s' % board, 389 '--board=%s' % board,
398 '--overlays=%s' % " ".join(overlays), 390 '--overlays=%s' % ':'.join(overlays),
399 '--tracking_branch=%s' % tracking_branch, 391 '--tracking_branch=%s' % tracking_branch,
400 '--push_options=--bypass-hooks -f', 'push'], 392 '--push_options=--bypass-hooks -f', 'push'],
401 cwd=cwd) 393 cwd=cwd)
402 394
403 395
404 def _ArchiveTestResults(buildroot, board, archive_dir, test_results_dir): 396 def _ArchiveTestResults(buildroot, board, archive_dir, test_results_dir):
405 """Archives the test results into the www dir for later use. 397 """Archives the test results into the www dir for later use.
406 398
407 Takes the results from the test_results_dir and dumps them into the archive 399 Takes the results from the test_results_dir and dumps them into the archive
408 dir specified. This also archives the last qemu image. 400 dir specified. This also archives the last qemu image.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 452
461 buildconfig = config[config_name] 453 buildconfig = config[config_name]
462 454
463 for key in default.iterkeys(): 455 for key in default.iterkeys():
464 if not buildconfig.has_key(key): 456 if not buildconfig.has_key(key):
465 buildconfig[key] = default[key] 457 buildconfig[key] = default[key]
466 458
467 return buildconfig 459 return buildconfig
468 460
469 461
462 def ResolveOverlays(buildroot, overlays):
463 """Return the list of overlays to use for a given buildbot.
464
465 Args:
466 overlays: A string describing which overlays you want.
467 'private': Just the private overlay.
468 'public': Just the public overlay.
469 'both': Both the public and private overlays.
470 """
471 public_overlay = '%s/src/third_party/chromiumos-overlay' % buildroot
472 private_overlay = '%s/src/private-overlays/chromeos-overlay' % buildroot
473 if overlays == 'private':
474 dirs = [private_overlay]
475 elif overlays == 'public':
476 dirs = [public_overlay]
477 elif overlays == 'both':
478 dirs = [public_overlay, private_overlay]
479 else:
480 Die('Incorrect overlay configuration: %s' % overlays)
481 for dir in dirs:
482 assert ':' not in dir, 'Overlay must not contain colons: %s' % dir
483 if not os.path.exists(dir):
484 Die('Missing overlay: %s' % dir)
485 return dirs
486
487
470 def main(): 488 def main():
471 # Parse options 489 # Parse options
472 usage = "usage: %prog [options] cbuildbot_config" 490 usage = "usage: %prog [options] cbuildbot_config"
473 parser = optparse.OptionParser(usage=usage) 491 parser = optparse.OptionParser(usage=usage)
474 parser.add_option('-r', '--buildroot', 492 parser.add_option('-r', '--buildroot',
475 help='root directory where build occurs', default=".") 493 help='root directory where build occurs', default=".")
476 parser.add_option('-n', '--buildnumber', 494 parser.add_option('-n', '--buildnumber',
477 help='build number', type='int', default=0) 495 help='build number', type='int', default=0)
478 parser.add_option('-f', '--revisionfile', 496 parser.add_option('-f', '--revisionfile',
479 help='file where new revisions are stored') 497 help='file where new revisions are stored')
480 parser.add_option('--clobber', action='store_true', dest='clobber', 498 parser.add_option('--clobber', action='store_true', dest='clobber',
481 default=False, 499 default=False,
482 help='Clobbers an old checkout before syncing') 500 help='Clobbers an old checkout before syncing')
483 parser.add_option('--debug', action='store_true', dest='debug', 501 parser.add_option('--debug', action='store_true', dest='debug',
484 default=False, 502 default=False,
485 help='Override some options to run as a developer.') 503 help='Override some options to run as a developer.')
486 parser.add_option('-t', '--tracking-branch', dest='tracking_branch', 504 parser.add_option('-t', '--tracking-branch', dest='tracking_branch',
487 default='cros/master', help='Run the buildbot on a branch') 505 default='cros/master', help='Run the buildbot on a branch')
488 parser.add_option('-u', '--url', dest='url', 506 parser.add_option('-u', '--url', dest='url',
489 default='http://git.chromium.org/git/manifest', 507 default='http://git.chromium.org/git/manifest',
490 help='Run the buildbot on internal manifest') 508 help='Run the buildbot on internal manifest')
491 509
492 (options, args) = parser.parse_args() 510 (options, args) = parser.parse_args()
493 511
494 buildroot = options.buildroot 512 buildroot = os.path.abspath(options.buildroot)
495 revisionfile = options.revisionfile 513 revisionfile = options.revisionfile
496 tracking_branch = options.tracking_branch 514 tracking_branch = options.tracking_branch
497 515
498 if len(args) >= 1: 516 if len(args) >= 1:
499 buildconfig = _GetConfig(args[-1]) 517 buildconfig = _GetConfig(args[-1])
500 else: 518 else:
501 Warning('Missing configuration description') 519 Warning('Missing configuration description')
502 parser.print_usage() 520 parser.print_usage()
503 sys.exit(1) 521 sys.exit(1)
504 522
523 # Calculate list of overlay directories.
524 overlays = ResolveOverlays(buildroot, buildconfig['overlays'])
525
505 try: 526 try:
506 _PreFlightRinse(buildroot, buildconfig['board'], tracking_branch) 527 _PreFlightRinse(buildroot, buildconfig['board'], tracking_branch, overlays)
507 if options.clobber or not os.path.isdir(buildroot): 528 if options.clobber or not os.path.isdir(buildroot):
508 _FullCheckout(buildroot, tracking_branch, url=options.url) 529 _FullCheckout(buildroot, tracking_branch, url=options.url)
509 else: 530 else:
510 _IncrementalCheckout(buildroot) 531 _IncrementalCheckout(buildroot)
511 532
512 chroot_path = os.path.join(buildroot, 'chroot') 533 chroot_path = os.path.join(buildroot, 'chroot')
513 if not os.path.isdir(chroot_path): 534 if not os.path.isdir(chroot_path):
514 _MakeChroot(buildroot) 535 _MakeChroot(buildroot)
515 536
516 boardpath = os.path.join(chroot_path, 'build', buildconfig['board']) 537 boardpath = os.path.join(chroot_path, 'build', buildconfig['board'])
517 if not os.path.isdir(boardpath): 538 if not os.path.isdir(boardpath):
518 _SetupBoard(buildroot, board=buildconfig['board']) 539 _SetupBoard(buildroot, board=buildconfig['board'])
519 540
520 if buildconfig['uprev']: 541 if buildconfig['uprev']:
521 _UprevPackages(buildroot, tracking_branch, revisionfile, 542 _UprevPackages(buildroot, tracking_branch, revisionfile,
522 board=buildconfig['board']) 543 buildconfig['board'], overlays)
523 544
524 _EnableLocalAccount(buildroot) 545 _EnableLocalAccount(buildroot)
525 _Build(buildroot) 546 _Build(buildroot)
526 if buildconfig['unittests']: 547 if buildconfig['unittests']:
527 _RunUnitTests(buildroot) 548 _RunUnitTests(buildroot)
528 549
529 _BuildImage(buildroot) 550 _BuildImage(buildroot)
530 551
531 if buildconfig['smoke_bvt']: 552 if buildconfig['smoke_bvt']:
532 _BuildVMImageForTesting(buildroot) 553 _BuildVMImageForTesting(buildroot)
533 test_results_dir = '/tmp/run_remote_tests.%s' % options.buildnumber 554 test_results_dir = '/tmp/run_remote_tests.%s' % options.buildnumber
534 try: 555 try:
535 _RunSmokeSuite(buildroot, test_results_dir) 556 _RunSmokeSuite(buildroot, test_results_dir)
536 finally: 557 finally:
537 _ArchiveTestResults(buildroot, buildconfig['board'], 558 _ArchiveTestResults(buildroot, buildconfig['board'],
538 archive_dir=options.buildnumber, 559 archive_dir=options.buildnumber,
539 test_results_dir=test_results_dir) 560 test_results_dir=test_results_dir)
540 561
541 if buildconfig['uprev']: 562 if buildconfig['uprev']:
542 # Don't push changes for developers. 563 # Don't push changes for developers.
543 if not options.debug: 564 if not options.debug:
544 if buildconfig['master']: 565 if buildconfig['master']:
545 # Master bot needs to check if the other slaves completed. 566 # Master bot needs to check if the other slaves completed.
546 if cbuildbot_comm.HaveSlavesCompleted(config): 567 if cbuildbot_comm.HaveSlavesCompleted(config):
547 _UprevPush(buildroot, tracking_branch, buildconfig['board'], 568 _UprevPush(buildroot, tracking_branch, buildconfig['board'],
548 buildconfig['overlays']) 569 overlays)
549 else: 570 else:
550 Die('CBUILDBOT - One of the slaves has failed!!!') 571 Die('CBUILDBOT - One of the slaves has failed!!!')
551 572
552 else: 573 else:
553 # Publish my status to the master if its expecting it. 574 # Publish my status to the master if its expecting it.
554 if buildconfig['important']: 575 if buildconfig['important']:
555 cbuildbot_comm.PublishStatus(cbuildbot_comm.STATUS_BUILD_COMPLETE) 576 cbuildbot_comm.PublishStatus(cbuildbot_comm.STATUS_BUILD_COMPLETE)
556 577
557 except: 578 except:
558 # Send failure to master bot. 579 # Send failure to master bot.
559 if not buildconfig['master'] and buildconfig['important']: 580 if not buildconfig['master'] and buildconfig['important']:
560 cbuildbot_comm.PublishStatus(cbuildbot_comm.STATUS_BUILD_FAILED) 581 cbuildbot_comm.PublishStatus(cbuildbot_comm.STATUS_BUILD_FAILED)
561 582
562 raise 583 raise
563 584
564 585
565 if __name__ == '__main__': 586 if __name__ == '__main__':
566 main() 587 main()
OLDNEW
« no previous file with comments | « no previous file | bin/cbuildbot_config.py » ('j') | cros_mark_as_stable.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698