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

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: Add in back off timeout 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 print 'Error pushing changes trying again (%s/%s)' % (retry, retries)
140 time.sleep(5*retry)
sosa 2010/11/16 17:29:50 nit: You sleep after the last try You may wanna c
scottz 2010/11/16 17:49:02 Done.
141 else:
142 raise GitPushFailed('Failed to push change after %s retries' % retries)
143
144
145 def RevGitFile(filename, value, retries=5):
121 """Update and push the git file. 146 """Update and push the git file.
122 147
123 Args: 148 Args:
124 filename: file to modify that is in a git repo already 149 filename: file to modify that is in a git repo already
125 key: board or host package type e.g. x86-dogfood 150 value: string representing the version of the prebuilt that has been
126 value: string representing the version of the prebuilt that has been 151 uploaded.
127 uploaded. 152 retries: The number of times to retry before giving up, default: 5
128 """ 153 """
129 prebuilt_branch = 'prebuilt_branch' 154 prebuilt_branch = 'prebuilt_branch'
130 old_cwd = os.getcwd() 155 old_cwd = os.getcwd()
131 os.chdir(os.path.dirname(filename)) 156 os.chdir(os.path.dirname(filename))
132 157
133 cros_build_lib.RunCommand('repo sync', shell=True) 158 cros_build_lib.RunCommand('repo sync .', shell=True)
134 cros_build_lib.RunCommand('repo start %s .' % prebuilt_branch, shell=True) 159 cros_build_lib.RunCommand('repo start %s .' % prebuilt_branch, shell=True)
135 git_ssh_config_cmd = ( 160 git_ssh_config_cmd = (
136 'git config url.ssh://git@gitrw.chromium.org:9222.pushinsteadof ' 161 'git config url.ssh://git@gitrw.chromium.org:9222.pushinsteadof '
137 'http://git.chromium.org/git') 162 'http://git.chromium.org/git')
138 cros_build_lib.RunCommand(git_ssh_config_cmd, shell=True) 163 cros_build_lib.RunCommand(git_ssh_config_cmd, shell=True)
139 description = 'Update PORTAGE_BINHOST="%s" in %s' % (value, filename) 164 description = 'Update PORTAGE_BINHOST="%s" in %s' % (value, filename)
140 print description 165 print description
141 try: 166 try:
142 UpdateLocalFile(filename, value) 167 UpdateLocalFile(filename, value)
143 cros_build_lib.RunCommand('git config push.default tracking', shell=True) 168 cros_build_lib.RunCommand('git config push.default tracking', shell=True)
144 cros_build_lib.RunCommand('git commit -am "%s"' % description, shell=True) 169 cros_build_lib.RunCommand('git commit -am "%s"' % description, shell=True)
145 cros_build_lib.RunCommand('repo sync', shell=True) 170 RevGitPushWithRetry(retries)
146 cros_build_lib.RunCommand('git push', shell=True)
147 finally: 171 finally:
148 cros_build_lib.RunCommand('repo abandon %s .' % prebuilt_branch, shell=True) 172 cros_build_lib.RunCommand('repo abandon %s .' % prebuilt_branch, shell=True)
149 os.chdir(old_cwd) 173 os.chdir(old_cwd)
150 174
151 175
152 def GetVersion(): 176 def GetVersion():
153 """Get the version to put in LATEST and update the git version with.""" 177 """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') 178 return datetime.datetime.now().strftime('%d.%m.%y.%H%M%S')
155 179
156 180
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 elif re.match('.*?-\w+', target): 398 elif re.match('.*?-\w+', target):
375 overlay_str = 'overlay-%s' % target 399 overlay_str = 'overlay-%s' % target
376 make_path = os.path.join(_BINHOST_BASE_DIR, overlay_str, 'make.conf') 400 make_path = os.path.join(_BINHOST_BASE_DIR, overlay_str, 'make.conf')
377 else: 401 else:
378 raise UnknownBoardFormat('Unknown format: %s' % target) 402 raise UnknownBoardFormat('Unknown format: %s' % target)
379 403
380 return os.path.join(make_path) 404 return os.path.join(make_path)
381 405
382 406
383 def UploadPrebuilt(build_path, upload_location, version, binhost_base_url, 407 def UploadPrebuilt(build_path, upload_location, version, binhost_base_url,
384 board=None, git_sync=False): 408 board=None, git_sync=False, git_sync_retries=5):
385 """Upload Host prebuilt files to Google Storage space. 409 """Upload Host prebuilt files to Google Storage space.
386 410
387 Args: 411 Args:
388 build_path: The path to the root of the chroot. 412 build_path: The path to the root of the chroot.
389 upload_location: The upload location. 413 upload_location: The upload location.
390 board: The board to upload to Google Storage, if this is None upload 414 board: The board to upload to Google Storage, if this is None upload
391 host packages. 415 host packages.
392 git_sync: If set, update make.conf of target to reference the latest 416 git_sync: If set, update make.conf of target to reference the latest
393 prebuilt packages genereated here. 417 prebuilt packages genereated here.
418 git_sync_retries: How many times to retry pushing when updating git files.
419 This helps avoid failures when multiple bots are modifying the same Repo.
420 default: 5
394 """ 421 """
395 422
396 if not board: 423 if not board:
397 # We are uploading host packages 424 # We are uploading host packages
398 # TODO(scottz): eventually add support for different host_targets 425 # TODO(scottz): eventually add support for different host_targets
399 package_path = os.path.join(build_path, _HOST_PACKAGES_PATH) 426 package_path = os.path.join(build_path, _HOST_PACKAGES_PATH)
400 url_suffix = _REL_HOST_PATH % {'version': version, 'target': _HOST_TARGET} 427 url_suffix = _REL_HOST_PATH % {'version': version, 'target': _HOST_TARGET}
401 package_string = _HOST_TARGET 428 package_string = _HOST_TARGET
402 git_file = os.path.join(build_path, _PREBUILT_MAKE_CONF[_HOST_TARGET]) 429 git_file = os.path.join(build_path, _PREBUILT_MAKE_CONF[_HOST_TARGET])
403 else: 430 else:
(...skipping 15 matching lines...) Expand all
419 else: 446 else:
420 ssh_server, remote_path = remote_location.split(':', 1) 447 ssh_server, remote_path = remote_location.split(':', 1)
421 cmds = ['ssh %s mkdir -p %s' % (ssh_server, remote_path), 448 cmds = ['ssh %s mkdir -p %s' % (ssh_server, remote_path),
422 'rsync -av %s/ %s/' % (package_path, remote_location)] 449 'rsync -av %s/ %s/' % (package_path, remote_location)]
423 for cmd in cmds: 450 for cmd in cmds:
424 if not _RetryRun(cmd, shell=True): 451 if not _RetryRun(cmd, shell=True):
425 raise UploadFailed('Could not run %s' % cmd) 452 raise UploadFailed('Could not run %s' % cmd)
426 453
427 if git_sync: 454 if git_sync:
428 url_value = '%s/%s/' % (binhost_base_url, url_suffix) 455 url_value = '%s/%s/' % (binhost_base_url, url_suffix)
429 RevGitFile(git_file, url_value) 456 RevGitFile(git_file, url_value, retries=git_sync_retries)
430 457
431 458
432 def usage(parser, msg): 459 def usage(parser, msg):
433 """Display usage message and parser help then exit with 1.""" 460 """Display usage message and parser help then exit with 1."""
434 print >> sys.stderr, msg 461 print >> sys.stderr, msg
435 parser.print_help() 462 parser.print_help()
436 sys.exit(1) 463 sys.exit(1)
437 464
438 465
439 def main(): 466 def main():
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 options.binhost_base_url, git_sync=options.git_sync) 513 options.binhost_base_url, git_sync=options.git_sync)
487 514
488 if options.board: 515 if options.board:
489 UploadPrebuilt(options.build_path, options.upload, version, 516 UploadPrebuilt(options.build_path, options.upload, version,
490 options.binhost_base_url, board=options.board, 517 options.binhost_base_url, board=options.board,
491 git_sync=options.git_sync) 518 git_sync=options.git_sync)
492 519
493 520
494 if __name__ == '__main__': 521 if __name__ == '__main__':
495 main() 522 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