Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 import datetime | 6 import datetime |
| 7 import multiprocessing | 7 import multiprocessing |
| 8 import optparse | 8 import optparse |
| 9 import os | 9 import os |
| 10 import re | 10 import re |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 | 66 |
| 67 | 67 |
| 68 class UploadFailed(Exception): | 68 class UploadFailed(Exception): |
| 69 """Raised when one of the files uploaded failed.""" | 69 """Raised when one of the files uploaded failed.""" |
| 70 pass | 70 pass |
| 71 | 71 |
| 72 class UnknownBoardFormat(Exception): | 72 class UnknownBoardFormat(Exception): |
| 73 """Raised when a function finds an unknown board format.""" | 73 """Raised when a function finds an unknown board format.""" |
| 74 pass | 74 pass |
| 75 | 75 |
| 76 class GitPushFailed(Exception): | |
| 77 """Raised when a git push failed after retry.""" | |
| 78 | |
| 76 | 79 |
| 77 def UpdateLocalFile(filename, value, key='PORTAGE_BINHOST'): | 80 def UpdateLocalFile(filename, value, key='PORTAGE_BINHOST'): |
| 78 """Update the key in file with the value passed. | 81 """Update the key in file with the value passed. |
| 79 File format: | 82 File format: |
| 80 key="value" | 83 key="value" |
| 81 Note quotes are added automatically | 84 Note quotes are added automatically |
| 82 | 85 |
| 83 Args: | 86 Args: |
| 84 filename: Name of file to modify. | 87 filename: Name of file to modify. |
| 85 value: Value to write with the key. | 88 value: Value to write with the key. |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 110 if not found: | 113 if not found: |
| 111 file_lines.append(keyval_str % {'key': key, 'value': value}) | 114 file_lines.append(keyval_str % {'key': key, 'value': value}) |
| 112 | 115 |
| 113 file_fh.close() | 116 file_fh.close() |
| 114 # write out new file | 117 # write out new file |
| 115 new_file_fh = open(filename, 'w') | 118 new_file_fh = open(filename, 'w') |
| 116 new_file_fh.write('\n'.join(file_lines)) | 119 new_file_fh.write('\n'.join(file_lines)) |
| 117 new_file_fh.close() | 120 new_file_fh.close() |
| 118 | 121 |
| 119 | 122 |
| 120 def RevGitFile(filename, value): | 123 def RevGitPushWithRetry(retries=5): |
| 124 """Repo sync and then push git changes in flight. | |
| 125 | |
| 126 Args: | |
| 127 retries: The number of times to retry before giving up, default: 5 | |
| 128 | |
| 129 Raises: | |
| 130 GitPushFailed if push was unsuccessful after retries | |
| 131 """ | |
| 132 for retry in range(retries+1): | |
| 133 try: | |
| 134 cros_build_lib.RunCommand('repo sync .', shell=True) | |
| 135 cros_build_lib.RunCommand('git push', shell=True) | |
| 136 break | |
| 137 except cros_build_lib.RunCommandError: | |
| 138 print 'Error pushing changes trying again (%s/%s)' % (retry, retries) | |
|
sosa
2010/11/16 17:28:43
Nit: The last error will say trying again even tho
| |
| 139 else: | |
| 140 raise GitPushFailed('Failed to push change after %s retries' % retries) | |
| 141 | |
| 142 | |
| 143 def RevGitFile(filename, value, retries=5): | |
| 121 """Update and push the git file. | 144 """Update and push the git file. |
| 122 | 145 |
| 123 Args: | 146 Args: |
| 124 filename: file to modify that is in a git repo already | 147 filename: file to modify that is in a git repo already |
| 125 key: board or host package type e.g. x86-dogfood | 148 value: string representing the version of the prebuilt that has been |
| 126 value: string representing the version of the prebuilt that has been | 149 uploaded. |
| 127 uploaded. | 150 retries: The number of times to retry before giving up, default: 5 |
| 128 """ | 151 """ |
| 129 prebuilt_branch = 'prebuilt_branch' | 152 prebuilt_branch = 'prebuilt_branch' |
| 130 old_cwd = os.getcwd() | 153 old_cwd = os.getcwd() |
| 131 os.chdir(os.path.dirname(filename)) | 154 os.chdir(os.path.dirname(filename)) |
| 132 | 155 |
| 133 cros_build_lib.RunCommand('repo sync', shell=True) | 156 cros_build_lib.RunCommand('repo sync .', shell=True) |
| 134 cros_build_lib.RunCommand('repo start %s .' % prebuilt_branch, shell=True) | 157 cros_build_lib.RunCommand('repo start %s .' % prebuilt_branch, shell=True) |
| 135 git_ssh_config_cmd = ( | 158 git_ssh_config_cmd = ( |
| 136 'git config url.ssh://git@gitrw.chromium.org:9222.pushinsteadof ' | 159 'git config url.ssh://git@gitrw.chromium.org:9222.pushinsteadof ' |
| 137 'http://git.chromium.org/git') | 160 'http://git.chromium.org/git') |
| 138 cros_build_lib.RunCommand(git_ssh_config_cmd, shell=True) | 161 cros_build_lib.RunCommand(git_ssh_config_cmd, shell=True) |
| 139 description = 'Update PORTAGE_BINHOST="%s" in %s' % (value, filename) | 162 description = 'Update PORTAGE_BINHOST="%s" in %s' % (value, filename) |
| 140 print description | 163 print description |
| 141 try: | 164 try: |
| 142 UpdateLocalFile(filename, value) | 165 UpdateLocalFile(filename, value) |
| 143 cros_build_lib.RunCommand('git config push.default tracking', shell=True) | 166 cros_build_lib.RunCommand('git config push.default tracking', shell=True) |
| 144 cros_build_lib.RunCommand('git commit -am "%s"' % description, shell=True) | 167 cros_build_lib.RunCommand('git commit -am "%s"' % description, shell=True) |
| 145 cros_build_lib.RunCommand('repo sync', shell=True) | 168 RevGitPushWithRetry(retries) |
| 146 cros_build_lib.RunCommand('git push', shell=True) | |
| 147 finally: | 169 finally: |
| 148 cros_build_lib.RunCommand('repo abandon %s .' % prebuilt_branch, shell=True) | 170 cros_build_lib.RunCommand('repo abandon %s .' % prebuilt_branch, shell=True) |
| 149 os.chdir(old_cwd) | 171 os.chdir(old_cwd) |
| 150 | 172 |
| 151 | 173 |
| 152 def GetVersion(): | 174 def GetVersion(): |
| 153 """Get the version to put in LATEST and update the git version with.""" | 175 """Get the version to put in LATEST and update the git version with.""" |
| 154 return datetime.datetime.now().strftime('%d.%m.%y.%H%M%S') | 176 return datetime.datetime.now().strftime('%d.%m.%y.%H%M%S') |
| 155 | 177 |
| 156 | 178 |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 374 elif re.match('.*?-\w+', target): | 396 elif re.match('.*?-\w+', target): |
| 375 overlay_str = 'overlay-%s' % target | 397 overlay_str = 'overlay-%s' % target |
| 376 make_path = os.path.join(_BINHOST_BASE_DIR, overlay_str, 'make.conf') | 398 make_path = os.path.join(_BINHOST_BASE_DIR, overlay_str, 'make.conf') |
| 377 else: | 399 else: |
| 378 raise UnknownBoardFormat('Unknown format: %s' % target) | 400 raise UnknownBoardFormat('Unknown format: %s' % target) |
| 379 | 401 |
| 380 return os.path.join(make_path) | 402 return os.path.join(make_path) |
| 381 | 403 |
| 382 | 404 |
| 383 def UploadPrebuilt(build_path, upload_location, version, binhost_base_url, | 405 def UploadPrebuilt(build_path, upload_location, version, binhost_base_url, |
| 384 board=None, git_sync=False): | 406 board=None, git_sync=False, git_sync_retries=5): |
| 385 """Upload Host prebuilt files to Google Storage space. | 407 """Upload Host prebuilt files to Google Storage space. |
| 386 | 408 |
| 387 Args: | 409 Args: |
| 388 build_path: The path to the root of the chroot. | 410 build_path: The path to the root of the chroot. |
| 389 upload_location: The upload location. | 411 upload_location: The upload location. |
| 390 board: The board to upload to Google Storage, if this is None upload | 412 board: The board to upload to Google Storage, if this is None upload |
| 391 host packages. | 413 host packages. |
| 392 git_sync: If set, update make.conf of target to reference the latest | 414 git_sync: If set, update make.conf of target to reference the latest |
| 393 prebuilt packages genereated here. | 415 prebuilt packages genereated here. |
| 416 git_sync_retries: How many times to retry pushing when updating git files. | |
| 417 This helps avoid failures when multiple bots are modifying the same Repo. | |
| 418 default: 5 | |
| 394 """ | 419 """ |
| 395 | 420 |
| 396 if not board: | 421 if not board: |
| 397 # We are uploading host packages | 422 # We are uploading host packages |
| 398 # TODO(scottz): eventually add support for different host_targets | 423 # TODO(scottz): eventually add support for different host_targets |
| 399 package_path = os.path.join(build_path, _HOST_PACKAGES_PATH) | 424 package_path = os.path.join(build_path, _HOST_PACKAGES_PATH) |
| 400 url_suffix = _REL_HOST_PATH % {'version': version, 'target': _HOST_TARGET} | 425 url_suffix = _REL_HOST_PATH % {'version': version, 'target': _HOST_TARGET} |
| 401 package_string = _HOST_TARGET | 426 package_string = _HOST_TARGET |
| 402 git_file = os.path.join(build_path, _PREBUILT_MAKE_CONF[_HOST_TARGET]) | 427 git_file = os.path.join(build_path, _PREBUILT_MAKE_CONF[_HOST_TARGET]) |
| 403 else: | 428 else: |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 419 else: | 444 else: |
| 420 ssh_server, remote_path = remote_location.split(':', 1) | 445 ssh_server, remote_path = remote_location.split(':', 1) |
| 421 cmds = ['ssh %s mkdir -p %s' % (ssh_server, remote_path), | 446 cmds = ['ssh %s mkdir -p %s' % (ssh_server, remote_path), |
| 422 'rsync -av %s/ %s/' % (package_path, remote_location)] | 447 'rsync -av %s/ %s/' % (package_path, remote_location)] |
| 423 for cmd in cmds: | 448 for cmd in cmds: |
| 424 if not _RetryRun(cmd, shell=True): | 449 if not _RetryRun(cmd, shell=True): |
| 425 raise UploadFailed('Could not run %s' % cmd) | 450 raise UploadFailed('Could not run %s' % cmd) |
| 426 | 451 |
| 427 if git_sync: | 452 if git_sync: |
| 428 url_value = '%s/%s/' % (binhost_base_url, url_suffix) | 453 url_value = '%s/%s/' % (binhost_base_url, url_suffix) |
| 429 RevGitFile(git_file, url_value) | 454 RevGitFile(git_file, url_value, retries=git_sync_retries) |
| 430 | 455 |
| 431 | 456 |
| 432 def usage(parser, msg): | 457 def usage(parser, msg): |
| 433 """Display usage message and parser help then exit with 1.""" | 458 """Display usage message and parser help then exit with 1.""" |
| 434 print >> sys.stderr, msg | 459 print >> sys.stderr, msg |
| 435 parser.print_help() | 460 parser.print_help() |
| 436 sys.exit(1) | 461 sys.exit(1) |
| 437 | 462 |
| 438 | 463 |
| 439 def main(): | 464 def main(): |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 486 options.binhost_base_url, git_sync=options.git_sync) | 511 options.binhost_base_url, git_sync=options.git_sync) |
| 487 | 512 |
| 488 if options.board: | 513 if options.board: |
| 489 UploadPrebuilt(options.build_path, options.upload, version, | 514 UploadPrebuilt(options.build_path, options.upload, version, |
| 490 options.binhost_base_url, board=options.board, | 515 options.binhost_base_url, board=options.board, |
| 491 git_sync=options.git_sync) | 516 git_sync=options.git_sync) |
| 492 | 517 |
| 493 | 518 |
| 494 if __name__ == '__main__': | 519 if __name__ == '__main__': |
| 495 main() | 520 main() |
| OLD | NEW |