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

Side by Side Diff: prebuilt.py

Issue 3858003: Update prebuilt to modify make.conf files for the board/host targets. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/crosutils
Patch Set: Address sosa comments Created 10 years, 2 months 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 | prebuilt_unittest.py » ('j') | 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
(...skipping 12 matching lines...) Expand all
23 http://sites/chromeos/for-team-members/engineering/releng/prebuilt-binaries-for- streamlining-the-build-process 23 http://sites/chromeos/for-team-members/engineering/releng/prebuilt-binaries-for- streamlining-the-build-process
24 24
25 25
26 Example of uploading prebuilt amd64 host files 26 Example of uploading prebuilt amd64 host files
27 ./prebuilt.py -p /b/cbuild/build -s -u gs://chromeos-prebuilt 27 ./prebuilt.py -p /b/cbuild/build -s -u gs://chromeos-prebuilt
28 28
29 Example of uploading x86-dogfood binhosts 29 Example of uploading x86-dogfood binhosts
30 ./prebuilt.py -b x86-dogfood -p /b/cbuild/build/ -u gs://chromeos-prebuilt -g 30 ./prebuilt.py -b x86-dogfood -p /b/cbuild/build/ -u gs://chromeos-prebuilt -g
31 """ 31 """
32 32
33 VER_FILE = 'src/third_party/chromiumos-overlay/chromeos/config/stable_versions'
34
35 # as per http://crosbug.com/5855 always filter the below packages 33 # as per http://crosbug.com/5855 always filter the below packages
36 _FILTER_PACKAGES = set() 34 _FILTER_PACKAGES = set()
37 _RETRIES = 3 35 _RETRIES = 3
38 _GSUTIL_BIN = '/b/third_party/gsutil/gsutil' 36 _GSUTIL_BIN = '/b/third_party/gsutil/gsutil'
39 _HOST_PACKAGES_PATH = 'chroot/var/lib/portage/pkgs' 37 _HOST_PACKAGES_PATH = 'chroot/var/lib/portage/pkgs'
40 _HOST_TARGET = 'amd64' 38 _HOST_TARGET = 'amd64'
41 _BOARD_PATH = 'chroot/build/%(board)s' 39 _BOARD_PATH = 'chroot/build/%(board)s'
42 _BOTO_CONFIG = '/home/chrome-bot/external-boto' 40 _BOTO_CONFIG = '/home/chrome-bot/external-boto'
43 # board/board-target/version' 41 # board/board-target/version'
44 _GS_BOARD_PATH = 'board/%(board)s/%(version)s/' 42 _GS_BOARD_PATH = 'board/%(board)s/%(version)s/'
45 # We only support amd64 right now 43 # We only support amd64 right now
46 _GS_HOST_PATH = 'host/%s' % _HOST_TARGET 44 _GS_HOST_PATH = 'host/%s' % _HOST_TARGET
47 # Private overlays to look at for builds to filter 45 # Private overlays to look at for builds to filter
48 # relative to build path 46 # relative to build path
49 _PRIVATE_OVERLAY_DIR = 'src/private-overlays' 47 _PRIVATE_OVERLAY_DIR = 'src/private-overlays'
48 _BINHOST_BASE_DIR = 'src/overlays'
49 _BINHOST_BASE_URL = 'http://commondatastorage.googleapis.com/chromeos-prebuilt'
50 _PREBUILT_BASE_DIR = 'src/third_party/chromiumos-overlay/chromeos/config/'
51 # Created in the event of new host targets becoming available
52 _PREBUILT_MAKE_CONF = {'amd64': os.path.join(_PREBUILT_BASE_DIR,
53 'make.conf.amd64-host')}
50 54
51 55
52 class FiltersEmpty(Exception): 56 class FiltersEmpty(Exception):
53 """Raised when filters are used but none are found.""" 57 """Raised when filters are used but none are found."""
54 pass 58 pass
55 59
56 60
57 class UploadFailed(Exception): 61 class UploadFailed(Exception):
58 """Raised when one of the files uploaded failed.""" 62 """Raised when one of the files uploaded failed."""
59 pass 63 pass
60 64
65 class UnknownBoardFormat(Exception):
66 """Raised when a function finds an unknown board format."""
67 pass
61 68
62 def UpdateLocalFile(filename, key, value): 69
70 def UpdateLocalFile(filename, value, key='PORTAGE_BINHOST'):
63 """Update the key in file with the value passed. 71 """Update the key in file with the value passed.
64 File format: 72 File format:
65 key value 73 key="value"
74 Note quotes are added automatically
66 75
67 Args: 76 Args:
68 filename: Name of file to modify. 77 filename: Name of file to modify.
69 key: The variable key to update.
70 value: Value to write with the key. 78 value: Value to write with the key.
79 key: The variable key to update. (Default: PORTAGE_BINHOST)
71 """ 80 """
72 file_fh = open(filename) 81 file_fh = open(filename)
73 file_lines = [] 82 file_lines = []
74 found = False 83 found = False
75 for line in file_fh: 84 for line in file_fh:
76 file_var, file_val = line.split() 85 if '=' not in line:
86 # Skip any line without an equal in it and just write it out
87 file_lines.append(line)
88 continue
89
90 file_var, file_val = line.split('=')
91 keyval_str = '%(key)s=%(value)s'
77 if file_var == key: 92 if file_var == key:
78 found = True 93 found = True
79 print 'Updating %s %s to %s %s' % (file_var, file_val, key, value) 94 print 'Updating %s=%s to %s="%s"' % (file_var, file_val, key, value)
80 file_lines.append('%s %s' % (key, value)) 95 value = '"%s"' % value
96 file_lines.append(keyval_str % {'key': key, 'value': value})
81 else: 97 else:
82 file_lines.append('%s %s' % (file_var, file_val)) 98 file_lines.append(keyval_str % {'key': file_var, 'value': file_val})
83 99
84 if not found: 100 if not found:
85 file_lines.append('%s %s' % (key, value)) 101 file_lines.append(keyval_str % {'key': key, 'value': value})
86 102
87 file_fh.close() 103 file_fh.close()
88 # write out new file 104 # write out new file
89 new_file_fh = open(filename, 'w') 105 new_file_fh = open(filename, 'w')
90 new_file_fh.write('\n'.join(file_lines)) 106 new_file_fh.write('\n'.join(file_lines))
91 new_file_fh.close() 107 new_file_fh.close()
92 108
93 109
94 def RevGitFile(filename, key, value): 110 def RevGitFile(filename, value):
95 """Update and push the git file. 111 """Update and push the git file.
96 112
97 Args: 113 Args:
98 filename: file to modify that is in a git repo already 114 filename: file to modify that is in a git repo already
99 key: board or host package type e.g. x86-dogfood 115 key: board or host package type e.g. x86-dogfood
100 value: string representing the version of the prebuilt that has been 116 value: string representing the version of the prebuilt that has been
101 uploaded. 117 uploaded.
102 """ 118 """
103 prebuilt_branch = 'prebuilt_branch' 119 prebuilt_branch = 'prebuilt_branch'
104 old_cwd = os.getcwd() 120 old_cwd = os.getcwd()
105 os.chdir(os.path.dirname(filename)) 121 os.chdir(os.path.dirname(filename))
122
123 cros_build_lib.RunCommand('repo sync', shell=True)
106 cros_build_lib.RunCommand('repo start %s .' % prebuilt_branch, shell=True) 124 cros_build_lib.RunCommand('repo start %s .' % prebuilt_branch, shell=True)
107 UpdateLocalFile(filename, key, value)
108 description = 'Update BINHOST key/value %s %s' % (key, value)
109 print description
110 git_ssh_config_cmd = ( 125 git_ssh_config_cmd = (
111 'git config url.ssh://git@gitrw.chromium.org:9222.pushinsteadof ' 126 'git config url.ssh://git@gitrw.chromium.org:9222.pushinsteadof '
112 'http://git.chromium.org/git') 127 'http://git.chromium.org/git')
128 cros_build_lib.RunCommand(git_ssh_config_cmd, shell=True)
129 description = 'Update PORTAGE_BINHOST="%s" in %s' % (value, file)
130 print description
113 try: 131 try:
114 cros_build_lib.RunCommand(git_ssh_config_cmd, shell=True) 132 UpdateLocalFile(filename, value)
115 cros_build_lib.RunCommand('git pull', shell=True)
116 cros_build_lib.RunCommand('git config push.default tracking', shell=True) 133 cros_build_lib.RunCommand('git config push.default tracking', shell=True)
117 cros_build_lib.RunCommand('git commit -am "%s"' % description, shell=True) 134 cros_build_lib.RunCommand('git commit -am "%s"' % description, shell=True)
135 cros_build_lib.RunCommand('repo sync', shell=True)
118 cros_build_lib.RunCommand('git push', shell=True) 136 cros_build_lib.RunCommand('git push', shell=True)
119 finally: 137 finally:
120 cros_build_lib.RunCommand('repo abandon %s .' % prebuilt_branch, shell=True) 138 cros_build_lib.RunCommand('repo abandon %s .' % prebuilt_branch, shell=True)
121 os.chdir(old_cwd) 139 os.chdir(old_cwd)
122 140
123 141
124 def GetVersion(): 142 def GetVersion():
125 """Get the version to put in LATEST and update the git version with.""" 143 """Get the version to put in LATEST and update the git version with."""
126 return datetime.datetime.now().strftime('%d.%m.%y.%H%M%S') 144 return datetime.datetime.now().strftime('%d.%m.%y.%H%M%S')
127 145
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 files_to_sync = cros_build_lib.ListFiles(local_path) 262 files_to_sync = cros_build_lib.ListFiles(local_path)
245 upload_files = {} 263 upload_files = {}
246 for file_path in files_to_sync: 264 for file_path in files_to_sync:
247 filename = file_path.replace(strip_str, '').lstrip('/') 265 filename = file_path.replace(strip_str, '').lstrip('/')
248 gs_file_path = os.path.join(gs_path, filename) 266 gs_file_path = os.path.join(gs_path, filename)
249 upload_files[file_path] = gs_file_path 267 upload_files[file_path] = gs_file_path
250 268
251 return upload_files 269 return upload_files
252 270
253 271
254 def UploadPrebuilt(build_path, bucket, board=None, git_file=None): 272 def DetermineMakeConfFile(target):
273 """Determine the make.conf file that needs to be updated for prebuilts.
274
275 Args:
276 target: String representation of the board. This includes host and board
277 targets
278
279 Returns
280 A string path to a make.conf file to be updated.
281 """
282 if _HOST_TARGET == target:
283 # We are host.
284 # Without more examples of hosts this is a kludge for now.
285 # TODO(Scottz): as new host targets come online expand this to
286 # work more like boards.
287 make_path = _PREBUILT_MAKE_CONF[target]
288 elif re.match('.*?-.*?_.*', target):
289 # We are a board variant
290 overlay_str = 'overlay-variant-%s' % target.replace('_', '-')
291 make_path = os.path.join(_BINHOST_BASE_DIR, overlay_str, 'make.conf')
292 elif re.match('.*?-\w+', target):
293 overlay_str = 'overlay-%s' % target
294 make_path = os.path.join(_BINHOST_BASE_DIR, overlay_str, 'make.conf')
295 else:
296 raise UnknownBoardFormat('Unknown format: %s' % target)
297
298 return os.path.join(make_path)
299
300
301 def UploadPrebuilt(build_path, bucket, version, board=None, git_sync=False):
255 """Upload Host prebuilt files to Google Storage space. 302 """Upload Host prebuilt files to Google Storage space.
256 303
257 Args: 304 Args:
258 build_path: The path to the root of the chroot. 305 build_path: The path to the root of the chroot.
259 bucket: The Google Storage bucket to upload to. 306 bucket: The Google Storage bucket to upload to.
260 board: The board to upload to Google Storage, if this is None upload 307 board: The board to upload to Google Storage, if this is None upload
261 host packages. 308 host packages.
262 git_file: If set, update this file with a host/version combo, commit and 309 git_sync: If set, update make.conf of target to reference the latest
263 push it. 310 prebuilt packages genereated here.
264 """ 311 """
265 version = GetVersion()
266 312
267 if not board: 313 if not board:
268 # We are uploading host packages 314 # We are uploading host packages
269 # TODO(scottz): eventually add support for different host_targets 315 # TODO(scottz): eventually add support for different host_targets
270 package_path = os.path.join(build_path, _HOST_PACKAGES_PATH) 316 package_path = os.path.join(build_path, _HOST_PACKAGES_PATH)
271 gs_path = os.path.join(bucket, _GS_HOST_PATH, version) 317 gs_path = os.path.join(bucket, _GS_HOST_PATH, version)
272 strip_pattern = package_path 318 strip_pattern = package_path
273 package_string = _HOST_TARGET 319 package_string = _HOST_TARGET
320 git_file = os.path.join(build_path, _PREBUILT_MAKE_CONF[_HOST_TARGET])
321 url_suffix = '%s/%s' % (_GS_HOST_PATH, version)
274 else: 322 else:
275 board_path = os.path.join(build_path, _BOARD_PATH % {'board': board}) 323 board_path = os.path.join(build_path, _BOARD_PATH % {'board': board})
276 package_path = os.path.join(board_path, 'packages') 324 package_path = os.path.join(board_path, 'packages')
277 package_string = board 325 package_string = board
278 strip_pattern = board_path 326 strip_pattern = board_path
279 gs_path = os.path.join(bucket, _GS_BOARD_PATH % {'board': board, 327 remote_board_path = _GS_BOARD_PATH % {'board': board, 'version': version}
280 'version': version}) 328 gs_path = os.path.join(bucket, remote_board_path)
329 git_file = os.path.join(build_path, DetermineMakeConfFile(board))
330 url_suffix = remote_board_path
281 331
282 upload_files = GenerateUploadDict(package_path, gs_path, strip_pattern) 332 upload_files = GenerateUploadDict(package_path, gs_path, strip_pattern)
283 333
284 print 'Uploading %s' % package_string 334 print 'Uploading %s' % package_string
285 failed_uploads = RemoteUpload(upload_files) 335 failed_uploads = RemoteUpload(upload_files)
286 if len(failed_uploads) > 1 or (None not in failed_uploads): 336 if len(failed_uploads) > 1 or (None not in failed_uploads):
287 error_msg = ['%s -> %s\n' % args for args in failed_uploads] 337 error_msg = ['%s -> %s\n' % args for args in failed_uploads]
288 raise UploadFailed('Error uploading:\n%s' % error_msg) 338 raise UploadFailed('Error uploading:\n%s' % error_msg)
289 339
290 if git_file: 340 if git_sync:
291 RevGitFile(git_file, package_string, version) 341 url_value = '%s/%s' % (_BINHOST_BASE_URL, url_suffix)
342 RevGitFile(git_file, url_value)
292 343
293 344
294 def usage(parser, msg): 345 def usage(parser, msg):
295 """Display usage message and parser help then exit with 1.""" 346 """Display usage message and parser help then exit with 1."""
296 print >> sys.stderr, msg 347 print >> sys.stderr, msg
297 parser.print_help() 348 parser.print_help()
298 sys.exit(1) 349 sys.exit(1)
299 350
300 351
301 def main(): 352 def main():
302 parser = optparse.OptionParser() 353 parser = optparse.OptionParser()
303 parser.add_option('-b', '--board', dest='board', default=None, 354 parser.add_option('-b', '--board', dest='board', default=None,
304 help='Board type that was built on this machine') 355 help='Board type that was built on this machine')
305 parser.add_option('-p', '--build-path', dest='build_path', 356 parser.add_option('-p', '--build-path', dest='build_path',
306 help='Path to the chroot') 357 help='Path to the chroot')
307 parser.add_option('-s', '--sync-host', dest='sync_host', 358 parser.add_option('-s', '--sync-host', dest='sync_host',
308 default=False, action='store_true', 359 default=False, action='store_true',
309 help='Sync host prebuilts') 360 help='Sync host prebuilts')
310 parser.add_option('-g', '--git-sync', dest='git_sync', 361 parser.add_option('-g', '--git-sync', dest='git_sync',
311 default=False, action='store_true', 362 default=False, action='store_true',
312 help='Enable git version sync (This commits to a repo)') 363 help='Enable git version sync (This commits to a repo)')
313 parser.add_option('-u', '--upload', dest='upload', 364 parser.add_option('-u', '--upload', dest='upload',
314 default=None, 365 default=None,
315 help='Upload to GS bucket') 366 help='Upload to GS bucket')
367 parser.add_option('-V', '--prepend-version', dest='prepend_version',
368 default=None,
369 help='Add an identifier to the front of the version')
316 parser.add_option('-f', '--filters', dest='filters', action='store_true', 370 parser.add_option('-f', '--filters', dest='filters', action='store_true',
317 default=False, 371 default=False,
318 help='Turn on filtering of private ebuild packages') 372 help='Turn on filtering of private ebuild packages')
319 373
320 options, args = parser.parse_args() 374 options, args = parser.parse_args()
321 # Setup boto environment for gsutil to use 375 # Setup boto environment for gsutil to use
322 os.environ['BOTO_CONFIG'] = _BOTO_CONFIG 376 os.environ['BOTO_CONFIG'] = _BOTO_CONFIG
323 if not options.build_path: 377 if not options.build_path:
324 usage(parser, 'Error: you need provide a chroot path') 378 usage(parser, 'Error: you need provide a chroot path')
325 379
326 if not options.upload: 380 if not options.upload:
327 usage(parser, 'Error: you need to provide a gsutil upload bucket -u') 381 usage(parser, 'Error: you need to provide a gsutil upload bucket -u')
328 382
329 if options.filters: 383 if options.filters:
330 LoadPrivateFilters(options.build_path) 384 LoadPrivateFilters(options.build_path)
331 385
332 git_file = None 386 version = GetVersion()
333 if options.git_sync: 387 if options.prepend_version:
334 git_file = os.path.join(options.build_path, VER_FILE) 388 version = '%s-%s' % (options.prepend_version, version)
335 389
336 if options.sync_host: 390 if options.sync_host:
337 UploadPrebuilt(options.build_path, options.upload, git_file=git_file) 391 UploadPrebuilt(options.build_path, options.upload, version,
392 git_sync=options.git_sync)
338 393
339 if options.board: 394 if options.board:
340 UploadPrebuilt(options.build_path, options.upload, board=options.board, 395 UploadPrebuilt(options.build_path, options.upload, version,
341 git_file=git_file) 396 board=options.board, git_sync=options.git_sync)
342 397
343 398
344 if __name__ == '__main__': 399 if __name__ == '__main__':
345 main() 400 main()
OLDNEW
« no previous file with comments | « no previous file | prebuilt_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698