| OLD | NEW |
| 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 |
| 11 import re | 11 import re |
| 12 import optparse | 12 import optparse |
| 13 import os | 13 import os |
| 14 import shutil | 14 import shutil |
| 15 import sys | 15 import sys |
| 16 | 16 |
| 17 import cbuildbot_comm | 17 import cbuildbot_comm |
| 18 from cbuildbot_config import config | 18 from cbuildbot_config import config |
| 19 | 19 |
| 20 sys.path.append(os.path.join(os.path.dirname(__file__), '../lib')) | 20 sys.path.append(os.path.join(os.path.dirname(__file__), '../lib')) |
| 21 from cros_build_lib import (Die, Info, ReinterpretPathForChroot, RunCommand, | 21 from cros_build_lib import (Die, Info, ReinterpretPathForChroot, RunCommand, |
| 22 Warning) | 22 Warning) |
| 23 | 23 |
| 24 _DEFAULT_RETRIES = 3 | 24 _DEFAULT_RETRIES = 3 |
| 25 _PACKAGE_FILE = '%(buildroot)s/src/scripts/cbuildbot_package.list' | 25 _PACKAGE_FILE = '%(buildroot)s/src/scripts/cbuildbot_package.list' |
| 26 ARCHIVE_BASE = '/var/www/archive' | 26 ARCHIVE_BASE = '/var/www/archive' |
| 27 ARCHIVE_COUNT = 10 | 27 ARCHIVE_COUNT = 10 |
| 28 PUBLIC_OVERLAY = '%(buildroot)s/src/third_party/chromiumos-overlay' |
| 29 PRIVATE_OVERLAY = '%(buildroot)s/src/private-overlays/chromeos-overlay' |
| 28 | 30 |
| 29 # Currently, both the full buildbot and the preflight buildbot store their | 31 # Currently, both the full buildbot and the preflight buildbot store their |
| 30 # data in a variable named PORTAGE_BINHOST, but they're in different files. | 32 # data in a variable named PORTAGE_BINHOST, but they're in different files. |
| 31 # We're planning on joining the two files soon and renaming the full binhost | 33 # We're planning on joining the two files soon and renaming the full binhost |
| 32 # to FULL_BINHOST. | 34 # to FULL_BINHOST. |
| 33 _FULL_BINHOST = 'PORTAGE_BINHOST' | 35 _FULL_BINHOST = 'PORTAGE_BINHOST' |
| 34 _PREFLIGHT_BINHOST = 'PORTAGE_BINHOST' | 36 _PREFLIGHT_BINHOST = 'PORTAGE_BINHOST' |
| 35 | 37 |
| 36 # ======================== Utility functions ================================ | 38 # ======================== Utility functions ================================ |
| 37 | 39 |
| 40 def _PrintFile(path): |
| 41 """Prints out the contents of a file to stderr.""" |
| 42 file_handle = open(path) |
| 43 print >> sys.stderr, file_handle.read() |
| 44 file_handle.close() |
| 45 sys.stderr.flush() |
| 46 |
| 47 |
| 38 def MakeDir(path, parents=False): | 48 def MakeDir(path, parents=False): |
| 39 """Basic wrapper around os.mkdirs. | 49 """Basic wrapper around os.mkdirs. |
| 40 | 50 |
| 41 Keyword arguments: | 51 Keyword arguments: |
| 42 path -- Path to create. | 52 path -- Path to create. |
| 43 parents -- Follow mkdir -p logic. | 53 parents -- Follow mkdir -p logic. |
| 44 | 54 |
| 45 """ | 55 """ |
| 46 try: | 56 try: |
| 47 os.makedirs(path) | 57 os.makedirs(path) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 69 RunCommand(['repo', '--trace', 'sync'], cwd=buildroot) | 79 RunCommand(['repo', '--trace', 'sync'], cwd=buildroot) |
| 70 retries = 0 | 80 retries = 0 |
| 71 except: | 81 except: |
| 72 retries -= 1 | 82 retries -= 1 |
| 73 if retries > 0: | 83 if retries > 0: |
| 74 Warning('CBUILDBOT -- Repo Sync Failed, retrying') | 84 Warning('CBUILDBOT -- Repo Sync Failed, retrying') |
| 75 else: | 85 else: |
| 76 Warning('CBUILDBOT -- Retries exhausted') | 86 Warning('CBUILDBOT -- Retries exhausted') |
| 77 raise | 87 raise |
| 78 | 88 |
| 79 # Output manifest | |
| 80 RunCommand(['repo', 'manifest', '-r', '-o', '-'], cwd=buildroot) | |
| 81 | |
| 82 # =========================== Command Helpers ================================= | 89 # =========================== Command Helpers ================================= |
| 83 | 90 |
| 84 def _GetAllGitRepos(buildroot, debug=False): | 91 def _GetAllGitRepos(buildroot, debug=False): |
| 85 """Returns a list of tuples containing [git_repo, src_path].""" | 92 """Returns a list of tuples containing [git_repo, src_path].""" |
| 86 manifest_tuples = [] | 93 manifest_tuples = [] |
| 87 # Gets all the git repos from a full repo manifest. | 94 # Gets all the git repos from a full repo manifest. |
| 88 repo_cmd = "repo manifest -o -".split() | 95 repo_cmd = "repo manifest -o -".split() |
| 89 output = RunCommand(repo_cmd, cwd=buildroot, redirect_stdout=True, | 96 output = RunCommand(repo_cmd, cwd=buildroot, redirect_stdout=True, |
| 90 redirect_stderr=True, print_cmd=debug) | 97 redirect_stderr=True, print_cmd=debug) |
| 91 | 98 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 for mount_pt_str in mount_pts_in_buildroot.splitlines(): | 278 for mount_pt_str in mount_pts_in_buildroot.splitlines(): |
| 272 mount_pt = mount_pt_str.rpartition(' type ')[0].partition(' on ')[2] | 279 mount_pt = mount_pt_str.rpartition(' type ')[0].partition(' on ')[2] |
| 273 RunCommand(['sudo', 'umount', '-l', mount_pt], error_ok=True) | 280 RunCommand(['sudo', 'umount', '-l', mount_pt], error_ok=True) |
| 274 | 281 |
| 275 | 282 |
| 276 def _WipeOldOutput(buildroot): | 283 def _WipeOldOutput(buildroot): |
| 277 """Wipes out build output directories.""" | 284 """Wipes out build output directories.""" |
| 278 RunCommand(['rm', '-rf', 'src/build/images'], cwd=buildroot) | 285 RunCommand(['rm', '-rf', 'src/build/images'], cwd=buildroot) |
| 279 | 286 |
| 280 | 287 |
| 288 def _GetChromeOSVersion(buildroot): |
| 289 """Returns the tuple version of the Chrome OS version of the buildroot.""" |
| 290 cwd = os.path.join(buildroot, 'src', 'scripts') |
| 291 version_cmd = './chromeos_version.sh' |
| 292 output = RunCommand(version_cmd, cwd=cwd, redirect_stdout=True, |
| 293 redirect_stderr=True) |
| 294 version_re = re.compile('\s+CHROMEOS_VERSION_STRING=' |
| 295 '(\d+)\.(\d+)\.(\d+)\.(\w+)') |
| 296 for line in output.splitlines(): |
| 297 match = version_re.match(line) |
| 298 if match: |
| 299 return match.group(1), match.group(2), match.group(3), match.group(4) |
| 300 |
| 301 raise Exception('Chrome OS version not found.') |
| 302 |
| 303 |
| 304 def _GetManifestPath(buildroot): |
| 305 """Returns the relative path that a manifest should be saved into.""" |
| 306 version_tuple = _GetChromeOSVersion(buildroot) |
| 307 (major, minor, branch, patch) = version_tuple |
| 308 relative_path = os.path.join('.'.join([major, minor]), |
| 309 '%s.xml' % '.'.join(version_tuple)) |
| 310 return relative_path |
| 311 |
| 312 |
| 281 # =========================== Main Commands =================================== | 313 # =========================== Main Commands =================================== |
| 282 | 314 |
| 283 | 315 |
| 284 def _PreFlightRinse(buildroot, board, tracking_branch, overlays): | 316 def _PreFlightRinse(buildroot, board, tracking_branch, overlays): |
| 285 """Cleans up any leftover state from previous runs.""" | 317 """Cleans up any leftover state from previous runs.""" |
| 286 _GitCleanup(buildroot, board, tracking_branch, overlays) | 318 _GitCleanup(buildroot, board, tracking_branch, overlays) |
| 287 _CleanUpMountPoints(buildroot) | 319 _CleanUpMountPoints(buildroot) |
| 288 RunCommand(['sudo', 'killall', 'kvm'], error_ok=True) | 320 RunCommand(['sudo', 'killall', 'kvm'], error_ok=True) |
| 289 | 321 |
| 290 | 322 |
| 291 def _FullCheckout(buildroot, tracking_branch, | 323 def _FullCheckout(buildroot, tracking_branch, |
| 292 retries=_DEFAULT_RETRIES, | 324 retries=_DEFAULT_RETRIES, |
| 293 url='http://git.chromium.org/git/manifest'): | 325 url='http://git.chromium.org/git/manifest'): |
| 294 """Performs a full checkout and clobbers any previous checkouts.""" | 326 """Performs a full checkout and clobbers any previous checkouts.""" |
| 295 RunCommand(['sudo', 'rm', '-rf', buildroot]) | 327 RunCommand(['sudo', 'rm', '-rf', buildroot]) |
| 296 MakeDir(buildroot, parents=True) | 328 MakeDir(buildroot, parents=True) |
| 297 branch = tracking_branch.split('/'); | 329 branch = tracking_branch.split('/'); |
| 298 RunCommand(['repo', 'init', '-u', | 330 RunCommand(['repo', 'init', '-u', |
| 299 url, '-b', | 331 url, '-b', |
| 300 '%s' % branch[-1]], cwd=buildroot, input='\n\ny\n') | 332 '%s' % branch[-1]], cwd=buildroot, input='\n\ny\n') |
| 301 RepoSync(buildroot, retries) | 333 RepoSync(buildroot, retries) |
| 302 | 334 |
| 303 | 335 |
| 304 def _IncrementalCheckout(buildroot, retries=_DEFAULT_RETRIES): | 336 def _IncrementalCheckout(buildroot, retries=_DEFAULT_RETRIES): |
| 305 """Performs a checkout without clobbering previous checkout.""" | 337 """Performs a checkout without clobbering previous checkout.""" |
| 306 RepoSync(buildroot, retries) | 338 RepoSync(buildroot, retries) |
| 307 | 339 |
| 308 | 340 |
| 341 def _DumpManifest(buildroot, url): |
| 342 """Stores the manifest in the public | private overlay depending on url.""" |
| 343 public_overlay = PUBLIC_OVERLAY % {'buildroot': buildroot} |
| 344 private_overlay = PRIVATE_OVERLAY % {'buildroot': buildroot} |
| 345 if url.endswith('manifest-internal'): |
| 346 overlay = PRIVATE_OVERLAY % {'buildroot': buildroot} |
| 347 else: |
| 348 overlay = PUBLIC_OVERLAY % {'buildroot': buildroot} |
| 349 |
| 350 # Generate paths for manifests. |
| 351 relative_path = _GetManifestPath(buildroot) |
| 352 manifest_path = os.path.join(overlay, 'manifests', relative_path) |
| 353 symlink_path = os.path.join(overlay, 'manifests', 'LATEST') |
| 354 if not os.path.isdir(os.path.dirname(manifest_path)): |
| 355 os.makedirs(os.path.dirname(manifest_path)) |
| 356 |
| 357 # Dump the manifest and create a symlink to it. |
| 358 RunCommand(['repo', 'manifest', '-r', '-o', manifest_path], cwd=buildroot) |
| 359 if os.path.exists(symlink_path): |
| 360 os.unlink(symlink_path) |
| 361 |
| 362 os.symlink(relative_path, symlink_path) |
| 363 |
| 364 # Add it to git and print it to stderr. |
| 365 RunCommand(['git', 'add', os.path.join('manifests', relative_path)], |
| 366 cwd=overlay) |
| 367 RunCommand(['git', 'add', os.path.join('manifests', 'LATEST')], cwd=overlay) |
| 368 _PrintFile(manifest_path) |
| 369 |
| 370 |
| 309 def _MakeChroot(buildroot): | 371 def _MakeChroot(buildroot): |
| 310 """Wrapper around make_chroot.""" | 372 """Wrapper around make_chroot.""" |
| 311 cwd = os.path.join(buildroot, 'src', 'scripts') | 373 cwd = os.path.join(buildroot, 'src', 'scripts') |
| 312 RunCommand(['./make_chroot', '--fast'], cwd=cwd) | 374 RunCommand(['./make_chroot', '--fast'], cwd=cwd) |
| 313 | 375 |
| 314 | 376 |
| 315 def _GetPortageEnvVar(buildroot, board, envvar): | 377 def _GetPortageEnvVar(buildroot, board, envvar): |
| 316 """Get a portage environment variable for the specified board, if any. | 378 """Get a portage environment variable for the specified board, if any. |
| 317 | 379 |
| 318 buildroot: The root directory where the build occurs. Must be an absolute | 380 buildroot: The root directory where the build occurs. Must be an absolute |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 """Return the list of overlays to use for a given buildbot. | 582 """Return the list of overlays to use for a given buildbot. |
| 521 | 583 |
| 522 Args: | 584 Args: |
| 523 buildroot: The root directory where the build occurs. Must be an absolute | 585 buildroot: The root directory where the build occurs. Must be an absolute |
| 524 path. | 586 path. |
| 525 overlays: A string describing which overlays you want. | 587 overlays: A string describing which overlays you want. |
| 526 'private': Just the private overlay. | 588 'private': Just the private overlay. |
| 527 'public': Just the public overlay. | 589 'public': Just the public overlay. |
| 528 'both': Both the public and private overlays. | 590 'both': Both the public and private overlays. |
| 529 """ | 591 """ |
| 530 public_overlay = '%s/src/third_party/chromiumos-overlay' % buildroot | 592 public_overlay = PUBLIC_OVERLAY % {'buildroot': buildroot} |
| 531 private_overlay = '%s/src/private-overlays/chromeos-overlay' % buildroot | 593 private_overlay = PRIVATE_OVERLAY % {'buildroot': buildroot} |
| 532 if overlays == 'private': | 594 if overlays == 'private': |
| 533 paths = [private_overlay] | 595 paths = [private_overlay] |
| 534 elif overlays == 'public': | 596 elif overlays == 'public': |
| 535 paths = [public_overlay] | 597 paths = [public_overlay] |
| 536 elif overlays == 'both': | 598 elif overlays == 'both': |
| 537 paths = [public_overlay, private_overlay] | 599 paths = [public_overlay, private_overlay] |
| 538 else: | 600 else: |
| 539 Info('No overlays found.') | 601 Info('No overlays found.') |
| 540 paths = [] | 602 paths = [] |
| 541 return paths | 603 return paths |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 _IncrementalCheckout(buildroot) | 712 _IncrementalCheckout(buildroot) |
| 651 | 713 |
| 652 new_binhost = _GetPortageEnvVar(buildroot, board, _FULL_BINHOST) | 714 new_binhost = _GetPortageEnvVar(buildroot, board, _FULL_BINHOST) |
| 653 emptytree = (old_binhost and old_binhost != new_binhost) | 715 emptytree = (old_binhost and old_binhost != new_binhost) |
| 654 | 716 |
| 655 # Check that all overlays can be found. | 717 # Check that all overlays can be found. |
| 656 for path in rev_overlays: | 718 for path in rev_overlays: |
| 657 if not os.path.isdir(path): | 719 if not os.path.isdir(path): |
| 658 Die('Missing overlay: %s' % path) | 720 Die('Missing overlay: %s' % path) |
| 659 | 721 |
| 722 _DumpManifest(buildroot, options.url) |
| 723 |
| 660 if not os.path.isdir(chroot_path): | 724 if not os.path.isdir(chroot_path): |
| 661 _MakeChroot(buildroot) | 725 _MakeChroot(buildroot) |
| 662 | 726 |
| 663 if not os.path.isdir(boardpath): | 727 if not os.path.isdir(boardpath): |
| 664 _SetupBoard(buildroot, board=buildconfig['board']) | 728 _SetupBoard(buildroot, board=buildconfig['board']) |
| 665 | 729 |
| 666 # Perform uprev. If chrome_uprev is set, rev Chrome ebuilds. | 730 # Perform uprev. If chrome_uprev is set, rev Chrome ebuilds. |
| 667 if options.chrome_rev: | 731 if options.chrome_rev: |
| 668 chrome_atom_to_build = _MarkChromeAsStable(buildroot, tracking_branch, | 732 chrome_atom_to_build = _MarkChromeAsStable(buildroot, tracking_branch, |
| 669 options.chrome_rev) | 733 options.chrome_rev) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 except: | 784 except: |
| 721 # Send failure to master bot. | 785 # Send failure to master bot. |
| 722 if not buildconfig['master'] and buildconfig['important']: | 786 if not buildconfig['master'] and buildconfig['important']: |
| 723 cbuildbot_comm.PublishStatus(cbuildbot_comm.STATUS_BUILD_FAILED) | 787 cbuildbot_comm.PublishStatus(cbuildbot_comm.STATUS_BUILD_FAILED) |
| 724 | 788 |
| 725 raise | 789 raise |
| 726 | 790 |
| 727 | 791 |
| 728 if __name__ == '__main__': | 792 if __name__ == '__main__': |
| 729 main() | 793 main() |
| OLD | NEW |