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