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

Side by Side Diff: prebuilt.py

Issue 5082002: Add a RevGitWithRetry method to retry repo sync and git push (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/crosutils@master
Patch Set: Added check in except clause 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
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 # 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
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
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
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
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
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()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698