blob: c7e6872c65900713bbea1c12444ef8de3f3cb1e9 [file] [log] [blame]
David James8c846492011-01-25 17:07:29 -08001#!/usr/bin/python
David Jamesb619a782012-07-25 19:37:57 -07002# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
David James8c846492011-01-25 17:07:29 -08003# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
Brian Harringaf019fb2012-05-10 15:06:13 -07006"""This script is used to upload host prebuilts as well as board BINHOSTS.
David James8c846492011-01-25 17:07:29 -08007
David James015af872012-06-19 15:24:36 -07008Prebuilts are uploaded using gsutil to Google Storage. After these prebuilts
9are successfully uploaded, a file is updated with the proper BINHOST version.
David James8c846492011-01-25 17:07:29 -080010
11To read more about prebuilts/binhost binary packages please refer to:
David James015af872012-06-19 15:24:36 -070012http://goto/chromeos-prebuilts
David James8c846492011-01-25 17:07:29 -080013
14Example of uploading prebuilt amd64 host files to Google Storage:
David Jamesc5cbd472012-06-19 16:25:45 -070015upload_prebuilts -p /b/cbuild/build -s -u gs://chromeos-prebuilt
David James8c846492011-01-25 17:07:29 -080016
17Example of uploading x86-dogfood binhosts to Google Storage:
David Jamesc5cbd472012-06-19 16:25:45 -070018upload_prebuilts -b x86-dogfood -p /b/cbuild/build/ -u gs://chromeos-prebuilt -g
David James8c846492011-01-25 17:07:29 -080019"""
20
Chris Sosa1dc96132012-05-11 15:40:50 -070021import datetime
22import multiprocessing
23import optparse
24import os
25import sys
Chris Sosa1dc96132012-05-11 15:40:50 -070026
Zdenek Behan33a34112012-09-10 21:07:51 +020027from chromite.buildbot import constants
David Jamese5867812012-10-19 12:02:20 -070028from chromite.buildbot import portage_utilities
David James6450a0a2012-12-04 07:59:53 -080029from chromite.lib import binpkg
Chris Sosa1dc96132012-05-11 15:40:50 -070030from chromite.lib import cros_build_lib
David James97d95872012-11-16 15:09:56 -080031from chromite.lib import git
Brian Harring7904b482012-08-08 02:54:12 -070032from chromite.lib import gs
Brian Harringaf019fb2012-05-10 15:06:13 -070033from chromite.lib import osutils
David James6450a0a2012-12-04 07:59:53 -080034from chromite.lib import parallel
Mike Frysinger8e727a32013-01-16 16:57:53 -050035from chromite.lib import toolchain
Chris Sosa1dc96132012-05-11 15:40:50 -070036
David James015af872012-06-19 15:24:36 -070037# How many times to retry uploads.
38_RETRIES = 10
39
40# Multiplier for how long to sleep (in seconds) between retries; will delay
41# (1*sleep) the first time, then (2*sleep), continuing via attempt * sleep.
42_SLEEP_TIME = 60
43
David James8c846492011-01-25 17:07:29 -080044_HOST_PACKAGES_PATH = 'chroot/var/lib/portage/pkgs'
David James05bcb2b2011-02-09 09:25:47 -080045_CATEGORIES_PATH = 'chroot/etc/portage/categories'
David James615e5b52011-06-03 11:10:15 -070046_PYM_PATH = 'chroot/usr/lib/portage/pym'
David James4058b0d2011-12-08 21:24:50 -080047_HOST_ARCH = 'amd64'
David James8c846492011-01-25 17:07:29 -080048_BOARD_PATH = 'chroot/build/%(board)s'
David James4058b0d2011-12-08 21:24:50 -080049_REL_BOARD_PATH = 'board/%(target)s/%(version)s'
50_REL_HOST_PATH = 'host/%(host_arch)s/%(target)s/%(version)s'
David James8c846492011-01-25 17:07:29 -080051# Private overlays to look at for builds to filter
52# relative to build path
53_PRIVATE_OVERLAY_DIR = 'src/private-overlays'
Scott Zawalskiab1bed32011-03-16 15:24:24 -070054_GOOGLESTORAGE_ACL_FILE = 'googlestorage_acl.xml'
David James3753d942014-04-23 10:55:48 -070055_BINHOST_BASE_URL = 'gs://chromeos-prebuilt'
David James8c846492011-01-25 17:07:29 -080056_PREBUILT_BASE_DIR = 'src/third_party/chromiumos-overlay/chromeos/config/'
57# Created in the event of new host targets becoming available
58_PREBUILT_MAKE_CONF = {'amd64': os.path.join(_PREBUILT_BASE_DIR,
59 'make.conf.amd64-host')}
60_BINHOST_CONF_DIR = 'src/third_party/chromiumos-overlay/chromeos/binhost'
61
62
David James4058b0d2011-12-08 21:24:50 -080063class BuildTarget(object):
64 """A board/variant/profile tuple."""
65
66 def __init__(self, board_variant, profile=None):
67 self.board_variant = board_variant
68 self.board, _, self.variant = board_variant.partition('_')
69 self.profile = profile
70
71 def __str__(self):
72 if self.profile:
73 return '%s_%s' % (self.board_variant, self.profile)
74 else:
75 return self.board_variant
76
77 def __eq__(self, other):
78 return str(other) == str(self)
79
80 def __hash__(self):
81 return hash(str(self))
82
83
David James8c846492011-01-25 17:07:29 -080084def UpdateLocalFile(filename, value, key='PORTAGE_BINHOST'):
85 """Update the key in file with the value passed.
Mike Frysinger1a736a82013-12-12 01:50:59 -050086
David James8c846492011-01-25 17:07:29 -080087 File format:
88 key="value"
89 Note quotes are added automatically
90
91 Args:
92 filename: Name of file to modify.
93 value: Value to write with the key.
94 key: The variable key to update. (Default: PORTAGE_BINHOST)
95 """
96 if os.path.exists(filename):
97 file_fh = open(filename)
98 else:
99 file_fh = open(filename, 'w+')
100 file_lines = []
101 found = False
102 keyval_str = '%(key)s=%(value)s'
103 for line in file_fh:
104 # Strip newlines from end of line. We already add newlines below.
105 line = line.rstrip("\n")
106
107 if len(line.split('=')) != 2:
108 # Skip any line that doesn't fit key=val.
109 file_lines.append(line)
110 continue
111
112 file_var, file_val = line.split('=')
113 if file_var == key:
114 found = True
David James20b2b6f2011-11-18 15:11:58 -0800115 print 'Updating %s=%s to %s="%s"' % (file_var, file_val, key, value)
David James8c846492011-01-25 17:07:29 -0800116 value = '"%s"' % value
117 file_lines.append(keyval_str % {'key': key, 'value': value})
118 else:
119 file_lines.append(keyval_str % {'key': file_var, 'value': file_val})
120
121 if not found:
Brian Harring2a014302012-05-12 00:53:33 -0700122 value = '"%s"' % value
David James8c846492011-01-25 17:07:29 -0800123 file_lines.append(keyval_str % {'key': key, 'value': value})
124
125 file_fh.close()
126 # write out new file
Brian Harringaf019fb2012-05-10 15:06:13 -0700127 osutils.WriteFile(filename, '\n'.join(file_lines) + '\n')
David James8c846492011-01-25 17:07:29 -0800128
129
Mike Frysinger5b34d732013-01-17 15:11:58 -0500130def RevGitFile(filename, data, retries=5, dryrun=False):
David James8c846492011-01-25 17:07:29 -0800131 """Update and push the git file.
132
Mike Frysinger5b34d732013-01-17 15:11:58 -0500133 Args:
134 filename: file to modify that is in a git repo already
135 data: A dict of key/values to update in |filename|
136 retries: The number of times to retry before giving up, default: 5
Matt Tennante8179042013-10-01 15:47:32 -0700137 dryrun: If True, do not actually commit the change.
David James8c846492011-01-25 17:07:29 -0800138 """
139 prebuilt_branch = 'prebuilt_branch'
David James1b6e67a2011-05-19 21:32:38 -0700140 cwd = os.path.abspath(os.path.dirname(filename))
David James97d95872012-11-16 15:09:56 -0800141 commit = git.RunGit(cwd, ['rev-parse', 'HEAD']).output.rstrip()
Mike Frysinger5b34d732013-01-17 15:11:58 -0500142 description = '%s: updating %s' % (os.path.basename(filename),
143 ', '.join(data.keys()))
144 # UpdateLocalFile will print out the keys/values for us.
145 print 'Revving git file %s' % filename
David James66009462012-03-25 10:08:38 -0700146
David James8c846492011-01-25 17:07:29 -0800147 try:
David James97d95872012-11-16 15:09:56 -0800148 git.CreatePushBranch(prebuilt_branch, cwd)
Mike Frysinger5b34d732013-01-17 15:11:58 -0500149 for key, value in data.iteritems():
150 UpdateLocalFile(filename, value, key)
David James97d95872012-11-16 15:09:56 -0800151 git.RunGit(cwd, ['add', filename])
152 git.RunGit(cwd, ['commit', '-m', description])
153 git.PushWithRetry(prebuilt_branch, cwd, dryrun=dryrun, retries=retries)
David James8c846492011-01-25 17:07:29 -0800154 finally:
David James67d73252013-09-19 17:33:12 -0700155 git.RunGit(cwd, ['checkout', commit])
David James8c846492011-01-25 17:07:29 -0800156
157
158def GetVersion():
159 """Get the version to put in LATEST and update the git version with."""
Mike Frysinger0b92cfe2012-12-13 02:13:45 -0500160 return datetime.datetime.now().strftime('%Y.%m.%d.%H%M%S')
David James8c846492011-01-25 17:07:29 -0800161
162
David James015af872012-06-19 15:24:36 -0700163def _GsUpload(local_file, remote_file, acl):
David James8c846492011-01-25 17:07:29 -0800164 """Upload to GS bucket.
165
166 Args:
Matt Tennante8179042013-10-01 15:47:32 -0700167 local_file: The local file to be uploaded.
168 remote_file: The remote location to upload to.
169 acl: The ACL to use for uploading the file.
David James8c846492011-01-25 17:07:29 -0800170
171 Returns:
172 Return the arg tuple of two if the upload failed
173 """
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700174 CANNED_ACLS = ['public-read', 'private', 'bucket-owner-read',
175 'authenticated-read', 'bucket-owner-full-control',
176 'public-read-write']
David James9374aac2013-10-08 16:00:17 -0700177 gs_context = gs.GSContext(retries=_RETRIES, sleep=_SLEEP_TIME)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700178 if acl in CANNED_ACLS:
David James9374aac2013-10-08 16:00:17 -0700179 gs_context.Copy(local_file, remote_file, acl=acl)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700180 else:
181 # For private uploads we assume that the overlay board is set up properly
David James015af872012-06-19 15:24:36 -0700182 # and a googlestore_acl.xml is present. Otherwise, this script errors.
David James9374aac2013-10-08 16:00:17 -0700183 gs_context.Copy(local_file, remote_file, acl='private')
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700184 # Apply the passed in ACL xml file to the uploaded object.
David James9374aac2013-10-08 16:00:17 -0700185 gs_context.SetACL(remote_file, acl=acl)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700186
David Jamesfd0b0852011-02-23 11:15:36 -0800187def RemoteUpload(acl, files, pool=10):
David James8c846492011-01-25 17:07:29 -0800188 """Upload to google storage.
189
190 Create a pool of process and call _GsUpload with the proper arguments.
191
192 Args:
David Jamesfd0b0852011-02-23 11:15:36 -0800193 acl: The canned acl used for uploading. acl can be one of: "public-read",
194 "public-read-write", "authenticated-read", "bucket-owner-read",
195 "bucket-owner-full-control", or "private".
David James8c846492011-01-25 17:07:29 -0800196 files: dictionary with keys to local files and values to remote path.
197 pool: integer of maximum proesses to have at the same time.
198
199 Returns:
200 Return a set of tuple arguments of the failed uploads
201 """
David James015af872012-06-19 15:24:36 -0700202 tasks = [[key, value, acl] for key, value in files.iteritems()]
David James6450a0a2012-12-04 07:59:53 -0800203 parallel.RunTasksInProcessPool(_GsUpload, tasks, pool)
David James8c846492011-01-25 17:07:29 -0800204
205
206def GenerateUploadDict(base_local_path, base_remote_path, pkgs):
207 """Build a dictionary of local remote file key pairs to upload.
208
209 Args:
210 base_local_path: The base path to the files on the local hard drive.
Matt Tennante8179042013-10-01 15:47:32 -0700211 base_remote_path: The base path to the remote paths.
David James8c846492011-01-25 17:07:29 -0800212 pkgs: The packages to upload.
213
214 Returns:
215 Returns a dictionary of local_path/remote_path pairs
216 """
217 upload_files = {}
218 for pkg in pkgs:
219 suffix = pkg['CPV'] + '.tbz2'
220 local_path = os.path.join(base_local_path, suffix)
221 assert os.path.exists(local_path)
222 remote_path = '%s/%s' % (base_remote_path.rstrip('/'), suffix)
223 upload_files[local_path] = remote_path
224
225 return upload_files
226
Peter Mayo950e41a2014-02-06 21:07:33 +0000227def GetBoardOverlay(build_path, target):
David Jamese5867812012-10-19 12:02:20 -0700228 """Get the path to the board variant.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500229
David James8c846492011-01-25 17:07:29 -0800230 Args:
231 build_path: The path to the root of the build directory
David Jamese5867812012-10-19 12:02:20 -0700232 target: The target board as a BuildTarget object.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500233
David James8c846492011-01-25 17:07:29 -0800234 Returns:
David Jamese5867812012-10-19 12:02:20 -0700235 The last overlay configured for the given board as a string.
David James8c846492011-01-25 17:07:29 -0800236 """
David Jamese5867812012-10-19 12:02:20 -0700237 board = target.board_variant
238 overlays = portage_utilities.FindOverlays(constants.BOTH_OVERLAYS, board,
239 buildroot=build_path)
240 # We only care about the last entry.
241 return overlays[-1]
David James8c846492011-01-25 17:07:29 -0800242
243
244def DeterminePrebuiltConfFile(build_path, target):
245 """Determine the prebuilt.conf file that needs to be updated for prebuilts.
246
Mike Frysinger1a736a82013-12-12 01:50:59 -0500247 Args:
248 build_path: The path to the root of the build directory
249 target: String representation of the board. This includes host and board
250 targets
David James8c846492011-01-25 17:07:29 -0800251
Mike Frysinger1a736a82013-12-12 01:50:59 -0500252 Returns:
253 A string path to a prebuilt.conf file to be updated.
David James8c846492011-01-25 17:07:29 -0800254 """
David James4058b0d2011-12-08 21:24:50 -0800255 if _HOST_ARCH == target:
David James8c846492011-01-25 17:07:29 -0800256 # We are host.
257 # Without more examples of hosts this is a kludge for now.
258 # TODO(Scottz): as new host targets come online expand this to
259 # work more like boards.
Chris Sosa471532a2011-02-01 15:10:06 -0800260 make_path = _PREBUILT_MAKE_CONF[target]
David James8c846492011-01-25 17:07:29 -0800261 else:
262 # We are a board
Peter Mayo950e41a2014-02-06 21:07:33 +0000263 board = GetBoardOverlay(build_path, target)
David James8c846492011-01-25 17:07:29 -0800264 make_path = os.path.join(board, 'prebuilt.conf')
265
266 return make_path
267
268
269def UpdateBinhostConfFile(path, key, value):
270 """Update binhost config file file with key=value.
271
272 Args:
273 path: Filename to update.
274 key: Key to update.
275 value: New value for key.
276 """
277 cwd = os.path.dirname(os.path.abspath(path))
278 filename = os.path.basename(path)
Brian Harringaf019fb2012-05-10 15:06:13 -0700279 osutils.SafeMakedirs(cwd)
David Jamesf6e8fb72013-05-10 08:58:43 -0700280 if not git.GetCurrentBranch(cwd):
281 git.CreatePushBranch(constants.STABLE_EBUILD_BRANCH, cwd, sync=False)
Brian Harring22edb442012-05-11 23:55:18 -0700282 osutils.WriteFile(path, '', mode='a')
David James8c846492011-01-25 17:07:29 -0800283 UpdateLocalFile(path, value, key)
David James67d73252013-09-19 17:33:12 -0700284 git.RunGit(cwd, ['add', filename])
Mike Frysinger109cada2013-01-17 15:50:44 -0500285 description = '%s: updating %s' % (os.path.basename(filename), key)
David James67d73252013-09-19 17:33:12 -0700286 git.RunGit(cwd, ['commit', '-m', description])
David James8c846492011-01-25 17:07:29 -0800287
288
David Jamesce093af2011-02-23 15:21:58 -0800289def _GrabAllRemotePackageIndexes(binhost_urls):
David James05bcb2b2011-02-09 09:25:47 -0800290 """Grab all of the packages files associated with a list of binhost_urls.
291
David James05bcb2b2011-02-09 09:25:47 -0800292 Args:
293 binhost_urls: The URLs for the directories containing the Packages files we
294 want to grab.
David James05bcb2b2011-02-09 09:25:47 -0800295
296 Returns:
297 A list of PackageIndex objects.
298 """
299 pkg_indexes = []
300 for url in binhost_urls:
David James32faafe2012-06-08 14:25:03 -0700301 pkg_index = binpkg.GrabRemotePackageIndex(url)
David James05bcb2b2011-02-09 09:25:47 -0800302 if pkg_index:
303 pkg_indexes.append(pkg_index)
David James05bcb2b2011-02-09 09:25:47 -0800304 return pkg_indexes
305
306
David Jamesc0f158a2011-02-22 16:07:29 -0800307class PrebuiltUploader(object):
308 """Synchronize host and board prebuilts."""
David James8c846492011-01-25 17:07:29 -0800309
David James615e5b52011-06-03 11:10:15 -0700310 def __init__(self, upload_location, acl, binhost_base_url,
David James32b0b2f2011-07-13 20:56:50 -0700311 pkg_indexes, build_path, packages, skip_upload,
David James4058b0d2011-12-08 21:24:50 -0800312 binhost_conf_dir, debug, target, slave_targets):
David Jamesc0f158a2011-02-22 16:07:29 -0800313 """Constructor for prebuilt uploader object.
David James8c846492011-01-25 17:07:29 -0800314
David Jamesc0f158a2011-02-22 16:07:29 -0800315 This object can upload host or prebuilt files to Google Storage.
David James8c846492011-01-25 17:07:29 -0800316
David Jamesc0f158a2011-02-22 16:07:29 -0800317 Args:
318 upload_location: The upload location.
David Jamesfd0b0852011-02-23 11:15:36 -0800319 acl: The canned acl used for uploading to Google Storage. acl can be one
320 of: "public-read", "public-read-write", "authenticated-read",
Matt Tennante8179042013-10-01 15:47:32 -0700321 "bucket-owner-read", "bucket-owner-full-control", "project-private",
322 or "private" (see "gsutil help acls"). If we are not uploading to
323 Google Storage, this parameter is unused.
David Jamesfd0b0852011-02-23 11:15:36 -0800324 binhost_base_url: The URL used for downloading the prebuilts.
David Jamesc0f158a2011-02-22 16:07:29 -0800325 pkg_indexes: Old uploaded prebuilts to compare against. Instead of
326 uploading duplicate files, we just link to the old files.
David James615e5b52011-06-03 11:10:15 -0700327 build_path: The path to the directory containing the chroot.
328 packages: Packages to upload.
David James32b0b2f2011-07-13 20:56:50 -0700329 skip_upload: Don't actually upload the tarballs.
330 binhost_conf_dir: Directory where to store binhost.conf files.
331 debug: Don't push or upload prebuilts.
David James4058b0d2011-12-08 21:24:50 -0800332 target: BuildTarget managed by this builder.
333 slave_targets: List of BuildTargets managed by slave builders.
David Jamesc0f158a2011-02-22 16:07:29 -0800334 """
335 self._upload_location = upload_location
David Jamesfd0b0852011-02-23 11:15:36 -0800336 self._acl = acl
David Jamesc0f158a2011-02-22 16:07:29 -0800337 self._binhost_base_url = binhost_base_url
338 self._pkg_indexes = pkg_indexes
David James615e5b52011-06-03 11:10:15 -0700339 self._build_path = build_path
340 self._packages = set(packages)
Mike Frysingerf5f809a2013-02-12 13:47:37 -0500341 self._found_packages = set()
David James8ece7ee2011-06-29 16:02:30 -0700342 self._skip_upload = skip_upload
David James32b0b2f2011-07-13 20:56:50 -0700343 self._binhost_conf_dir = binhost_conf_dir
David James27fa7d12011-06-29 17:24:14 -0700344 self._debug = debug
David James4058b0d2011-12-08 21:24:50 -0800345 self._target = target
346 self._slave_targets = slave_targets
David James615e5b52011-06-03 11:10:15 -0700347
348 def _ShouldFilterPackage(self, pkg):
349 if not self._packages:
350 return False
351 pym_path = os.path.abspath(os.path.join(self._build_path, _PYM_PATH))
David James710b7dc2012-02-07 16:49:59 -0800352 sys.path.insert(0, pym_path)
Don Garrett25f309a2014-03-19 14:02:12 -0700353 # pylint: disable=F0401
David James615e5b52011-06-03 11:10:15 -0700354 import portage.versions
355 cat, pkgname = portage.versions.catpkgsplit(pkg['CPV'])[0:2]
356 cp = '%s/%s' % (cat, pkgname)
Mike Frysingerf5f809a2013-02-12 13:47:37 -0500357 self._found_packages.add(cp)
David James615e5b52011-06-03 11:10:15 -0700358 return pkgname not in self._packages and cp not in self._packages
David James8c846492011-01-25 17:07:29 -0800359
David Jamesc0f158a2011-02-22 16:07:29 -0800360 def _UploadPrebuilt(self, package_path, url_suffix):
361 """Upload host or board prebuilt files to Google Storage space.
David James8c846492011-01-25 17:07:29 -0800362
David Jamesc0f158a2011-02-22 16:07:29 -0800363 Args:
364 package_path: The path to the packages dir.
David Jamesce093af2011-02-23 15:21:58 -0800365 url_suffix: The remote subdirectory where we should upload the packages.
David Jamesc0f158a2011-02-22 16:07:29 -0800366 """
David Jamesc0f158a2011-02-22 16:07:29 -0800367 # Process Packages file, removing duplicates and filtered packages.
David James32faafe2012-06-08 14:25:03 -0700368 pkg_index = binpkg.GrabLocalPackageIndex(package_path)
David Jamesc0f158a2011-02-22 16:07:29 -0800369 pkg_index.SetUploadLocation(self._binhost_base_url, url_suffix)
David James615e5b52011-06-03 11:10:15 -0700370 pkg_index.RemoveFilteredPackages(self._ShouldFilterPackage)
David Jamesc0f158a2011-02-22 16:07:29 -0800371 uploads = pkg_index.ResolveDuplicateUploads(self._pkg_indexes)
Mike Frysingerf5f809a2013-02-12 13:47:37 -0500372 unmatched_pkgs = self._packages - self._found_packages
373 if unmatched_pkgs:
374 cros_build_lib.Warning('unable to match packages: %r' % unmatched_pkgs)
David James05bcb2b2011-02-09 09:25:47 -0800375
David Jamesc0f158a2011-02-22 16:07:29 -0800376 # Write Packages file.
377 tmp_packages_file = pkg_index.WriteToNamedTemporaryFile()
David James05bcb2b2011-02-09 09:25:47 -0800378
David Jamesc0f158a2011-02-22 16:07:29 -0800379 remote_location = '%s/%s' % (self._upload_location.rstrip('/'), url_suffix)
David James015af872012-06-19 15:24:36 -0700380 assert remote_location.startswith('gs://')
David James05bcb2b2011-02-09 09:25:47 -0800381
David James015af872012-06-19 15:24:36 -0700382 # Build list of files to upload.
383 upload_files = GenerateUploadDict(package_path, remote_location, uploads)
384 remote_file = '%s/Packages' % remote_location.rstrip('/')
385 upload_files[tmp_packages_file.name] = remote_file
386
387 RemoteUpload(self._acl, upload_files)
David James8c846492011-01-25 17:07:29 -0800388
Mike Frysinger9e979b92012-11-29 02:55:09 -0500389 def _UploadSdkTarball(self, board_path, url_suffix, version, prepackaged,
390 toolchain_tarballs, toolchain_upload_path):
391 """Upload a tarball of the sdk at the specified path to Google Storage.
David James8fa34ea2011-04-15 13:00:20 -0700392
393 Args:
394 board_path: The path to the board dir.
395 url_suffix: The remote subdirectory where we should upload the packages.
Zdenek Behan5ad96c02011-06-23 01:04:06 +0200396 version: The version of the board.
Zdenek Behan62a57792012-08-31 15:09:08 +0200397 prepackaged: If given, a tarball that has been packaged outside of this
398 script and should be used.
Mike Frysinger9e979b92012-11-29 02:55:09 -0500399 toolchain_tarballs: List of toolchain tarballs to upload.
400 toolchain_upload_path: Path under the bucket to place toolchain tarballs.
David James8fa34ea2011-04-15 13:00:20 -0700401 """
402 remote_location = '%s/%s' % (self._upload_location.rstrip('/'), url_suffix)
403 assert remote_location.startswith('gs://')
Zdenek Behan86c15e92012-10-13 00:55:47 +0200404 boardname = os.path.basename(board_path.rstrip('/'))
405 # We do not upload non SDK board tarballs,
406 assert boardname == constants.CHROOT_BUILDER_BOARD
407 assert prepackaged is not None
Zdenek Behan62a57792012-08-31 15:09:08 +0200408
Zdenek Behan86c15e92012-10-13 00:55:47 +0200409 version_str = version[len('chroot-'):]
Mike Frysinger8e727a32013-01-16 16:57:53 -0500410 remote_tarfile = toolchain.GetSdkURL(
411 for_gsutil=True, suburl='cros-sdk-%s.tar.xz' % (version_str,))
Zdenek Behan86c15e92012-10-13 00:55:47 +0200412 # For SDK, also upload the manifest which is guaranteed to exist
413 # by the builderstage.
414 _GsUpload(prepackaged + '.Manifest', remote_tarfile + '.Manifest',
415 self._acl)
416 _GsUpload(prepackaged, remote_tarfile, self._acl)
417
Mike Frysinger9e979b92012-11-29 02:55:09 -0500418 # Post the toolchain tarballs too.
419 for tarball in toolchain_tarballs:
420 target, local_path = tarball.split(':')
421 suburl = toolchain_upload_path % {'target': target}
422 remote_path = toolchain.GetSdkURL(for_gsutil=True, suburl=suburl)
423 _GsUpload(local_path, remote_path, self._acl)
424
Zdenek Behan86c15e92012-10-13 00:55:47 +0200425 # Finally, also update the pointer to the latest SDK on which polling
426 # scripts rely.
David James4bc13702013-03-26 08:08:04 -0700427 with osutils.TempDir() as tmpdir:
Zdenek Behan86c15e92012-10-13 00:55:47 +0200428 pointerfile = os.path.join(tmpdir, 'cros-sdk-latest.conf')
Mike Frysinger8e727a32013-01-16 16:57:53 -0500429 remote_pointerfile = toolchain.GetSdkURL(for_gsutil=True,
430 suburl='cros-sdk-latest.conf')
Zdenek Behan86c15e92012-10-13 00:55:47 +0200431 osutils.WriteFile(pointerfile, 'LATEST_SDK="%s"' % version_str)
432 _GsUpload(pointerfile, remote_pointerfile, self._acl)
Zdenek Behan33a34112012-09-10 21:07:51 +0200433
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700434 def _GetTargets(self):
435 """Retuns the list of targets to use."""
436 targets = self._slave_targets[:]
437 if self._target:
438 targets.append(self._target)
439
440 return targets
441
442 def SyncHostPrebuilts(self, version, key, git_sync, sync_binhost_conf):
David Jamesc0f158a2011-02-22 16:07:29 -0800443 """Synchronize host prebuilt files.
David James05bcb2b2011-02-09 09:25:47 -0800444
David Jamesc0f158a2011-02-22 16:07:29 -0800445 This function will sync both the standard host packages, plus the host
446 packages associated with all targets that have been "setup" with the
447 current host's chroot. For instance, if this host has been used to build
448 x86-generic, it will sync the host packages associated with
449 'i686-pc-linux-gnu'. If this host has also been used to build arm-generic,
450 it will also sync the host packages associated with
451 'armv7a-cros-linux-gnueabi'.
David James05bcb2b2011-02-09 09:25:47 -0800452
David Jamesc0f158a2011-02-22 16:07:29 -0800453 Args:
David Jamesc0f158a2011-02-22 16:07:29 -0800454 version: A unique string, intended to be included in the upload path,
455 which identifies the version number of the uploaded prebuilts.
456 key: The variable key to update in the git file.
457 git_sync: If set, update make.conf of target to reference the latest
458 prebuilt packages generated here.
459 sync_binhost_conf: If set, update binhost config file in
460 chromiumos-overlay for the host.
461 """
David Jamese2488642011-11-14 16:15:20 -0800462 # Slave boards are listed before the master board so that the master board
463 # takes priority (i.e. x86-generic preflight host prebuilts takes priority
464 # over preflight host prebuilts from other builders.)
465 binhost_urls = []
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700466 for target in self._GetTargets():
David James4058b0d2011-12-08 21:24:50 -0800467 url_suffix = _REL_HOST_PATH % {'version': version,
468 'host_arch': _HOST_ARCH,
469 'target': target}
David Jamese2488642011-11-14 16:15:20 -0800470 packages_url_suffix = '%s/packages' % url_suffix.rstrip('/')
David James05bcb2b2011-02-09 09:25:47 -0800471
David James4058b0d2011-12-08 21:24:50 -0800472 if self._target == target and not self._skip_upload and not self._debug:
David Jamese2488642011-11-14 16:15:20 -0800473 # Upload prebuilts.
474 package_path = os.path.join(self._build_path, _HOST_PACKAGES_PATH)
475 self._UploadPrebuilt(package_path, packages_url_suffix)
David James8ece7ee2011-06-29 16:02:30 -0700476
David Jamese2488642011-11-14 16:15:20 -0800477 # Record URL where prebuilts were uploaded.
478 binhost_urls.append('%s/%s/' % (self._binhost_base_url.rstrip('/'),
479 packages_url_suffix.rstrip('/')))
480
David James20b2b6f2011-11-18 15:11:58 -0800481 binhost = ' '.join(binhost_urls)
David James8ece7ee2011-06-29 16:02:30 -0700482 if git_sync:
483 git_file = os.path.join(self._build_path,
David James4058b0d2011-12-08 21:24:50 -0800484 _PREBUILT_MAKE_CONF[_HOST_ARCH])
Mike Frysinger5b34d732013-01-17 15:11:58 -0500485 RevGitFile(git_file, {key: binhost}, dryrun=self._debug)
David James8ece7ee2011-06-29 16:02:30 -0700486 if sync_binhost_conf:
David James32b0b2f2011-07-13 20:56:50 -0700487 binhost_conf = os.path.join(self._build_path, self._binhost_conf_dir,
David James4058b0d2011-12-08 21:24:50 -0800488 'host', '%s-%s.conf' % (_HOST_ARCH, key))
David Jamese2488642011-11-14 16:15:20 -0800489 UpdateBinhostConfFile(binhost_conf, key, binhost)
David Jamesc0f158a2011-02-22 16:07:29 -0800490
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700491 def SyncBoardPrebuilts(self, version, key, git_sync, sync_binhost_conf,
Mike Frysinger9e979b92012-11-29 02:55:09 -0500492 upload_board_tarball, prepackaged_board,
493 toolchain_tarballs, toolchain_upload_path):
David Jamesc0f158a2011-02-22 16:07:29 -0800494 """Synchronize board prebuilt files.
495
496 Args:
David Jamesc0f158a2011-02-22 16:07:29 -0800497 version: A unique string, intended to be included in the upload path,
498 which identifies the version number of the uploaded prebuilts.
499 key: The variable key to update in the git file.
500 git_sync: If set, update make.conf of target to reference the latest
501 prebuilt packages generated here.
502 sync_binhost_conf: If set, update binhost config file in
503 chromiumos-overlay for the current board.
David James8fa34ea2011-04-15 13:00:20 -0700504 upload_board_tarball: Include a tarball of the board in our upload.
Zdenek Behan62a57792012-08-31 15:09:08 +0200505 prepackaged_board: A tarball of the board built outside of this script.
Mike Frysinger9e979b92012-11-29 02:55:09 -0500506 toolchain_tarballs: A list of toolchain tarballs to upload.
507 toolchain_upload_path: Path under the bucket to place toolchain tarballs.
David Jamesc0f158a2011-02-22 16:07:29 -0800508 """
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700509 for target in self._GetTargets():
David Jamese2488642011-11-14 16:15:20 -0800510 board_path = os.path.join(self._build_path,
David James4058b0d2011-12-08 21:24:50 -0800511 _BOARD_PATH % {'board': target.board_variant})
David Jamese2488642011-11-14 16:15:20 -0800512 package_path = os.path.join(board_path, 'packages')
David James4058b0d2011-12-08 21:24:50 -0800513 url_suffix = _REL_BOARD_PATH % {'target': target, 'version': version}
David Jamese2488642011-11-14 16:15:20 -0800514 packages_url_suffix = '%s/packages' % url_suffix.rstrip('/')
David James8fa34ea2011-04-15 13:00:20 -0700515
Matt Tennante8179042013-10-01 15:47:32 -0700516 # Process the target board differently if it is the main --board.
David James4058b0d2011-12-08 21:24:50 -0800517 if self._target == target and not self._skip_upload and not self._debug:
Matt Tennante8179042013-10-01 15:47:32 -0700518 # This strips "chroot" prefix because that is sometimes added as the
519 # --prepend-version argument (e.g. by chromiumos-sdk bot).
520 # TODO(build): Clean it up to be less hard-coded.
Mike Frysinger9e979b92012-11-29 02:55:09 -0500521 version_str = version[len('chroot-'):]
522
David Jamese2488642011-11-14 16:15:20 -0800523 # Upload board tarballs in the background.
524 if upload_board_tarball:
Mike Frysinger9e979b92012-11-29 02:55:09 -0500525 if toolchain_upload_path:
526 toolchain_upload_path %= {'version': version_str}
527 tar_process = multiprocessing.Process(
528 target=self._UploadSdkTarball,
529 args=(board_path, url_suffix, version, prepackaged_board,
530 toolchain_tarballs, toolchain_upload_path))
David Jamese2488642011-11-14 16:15:20 -0800531 tar_process.start()
David James8fa34ea2011-04-15 13:00:20 -0700532
David Jamese2488642011-11-14 16:15:20 -0800533 # Upload prebuilts.
534 self._UploadPrebuilt(package_path, packages_url_suffix)
David James8fa34ea2011-04-15 13:00:20 -0700535
David Jamese2488642011-11-14 16:15:20 -0800536 # Make sure we finished uploading the board tarballs.
537 if upload_board_tarball:
538 tar_process.join()
539 assert tar_process.exitcode == 0
540 # TODO(zbehan): This should be done cleaner.
Zdenek Behan33a34112012-09-10 21:07:51 +0200541 if target.board == constants.CHROOT_BUILDER_BOARD:
David Jamese2488642011-11-14 16:15:20 -0800542 sdk_conf = os.path.join(self._build_path, self._binhost_conf_dir,
Mike Frysinger5b34d732013-01-17 15:11:58 -0500543 'host/sdk_version.conf')
544 sdk_settings = {
Mike Frysinger9e979b92012-11-29 02:55:09 -0500545 'SDK_LATEST_VERSION': version_str,
546 'TC_PATH': toolchain_upload_path,
Mike Frysinger5b34d732013-01-17 15:11:58 -0500547 }
548 RevGitFile(sdk_conf, sdk_settings, dryrun=self._debug)
David Jamesc0f158a2011-02-22 16:07:29 -0800549
David Jamese2488642011-11-14 16:15:20 -0800550 # Record URL where prebuilts were uploaded.
551 url_value = '%s/%s/' % (self._binhost_base_url.rstrip('/'),
552 packages_url_suffix.rstrip('/'))
553
554 if git_sync:
David James4058b0d2011-12-08 21:24:50 -0800555 git_file = DeterminePrebuiltConfFile(self._build_path, target)
Mike Frysinger5b34d732013-01-17 15:11:58 -0500556 RevGitFile(git_file, {key: url_value}, dryrun=self._debug)
Matt Tennante8179042013-10-01 15:47:32 -0700557
David Jamese2488642011-11-14 16:15:20 -0800558 if sync_binhost_conf:
Matt Tennante8179042013-10-01 15:47:32 -0700559 # Update the binhost configuration file in git.
David Jamese2488642011-11-14 16:15:20 -0800560 binhost_conf = os.path.join(self._build_path, self._binhost_conf_dir,
David James4058b0d2011-12-08 21:24:50 -0800561 'target', '%s-%s.conf' % (target, key))
David Jamese2488642011-11-14 16:15:20 -0800562 UpdateBinhostConfFile(binhost_conf, key, url_value)
David James05bcb2b2011-02-09 09:25:47 -0800563
564
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700565def Usage(parser, msg):
David James8c846492011-01-25 17:07:29 -0800566 """Display usage message and parser help then exit with 1."""
567 print >> sys.stderr, msg
568 parser.print_help()
569 sys.exit(1)
570
David James4058b0d2011-12-08 21:24:50 -0800571
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700572def _AddSlaveBoard(_option, _opt_str, value, parser):
573 """Callback that adds a slave board to the list of slave targets."""
David James4058b0d2011-12-08 21:24:50 -0800574 parser.values.slave_targets.append(BuildTarget(value))
575
576
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700577def _AddSlaveProfile(_option, _opt_str, value, parser):
578 """Callback that adds a slave profile to the list of slave targets."""
David James4058b0d2011-12-08 21:24:50 -0800579 if not parser.values.slave_targets:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700580 Usage(parser, 'Must specify --slave-board before --slave-profile')
David James4058b0d2011-12-08 21:24:50 -0800581 if parser.values.slave_targets[-1].profile is not None:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700582 Usage(parser, 'Cannot specify --slave-profile twice for same board')
David James4058b0d2011-12-08 21:24:50 -0800583 parser.values.slave_targets[-1].profile = value
584
585
David Jamesc0f158a2011-02-22 16:07:29 -0800586def ParseOptions():
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700587 """Returns options given by the user and the target specified.
588
Mike Frysinger1a736a82013-12-12 01:50:59 -0500589 Returns:
590 A tuple containing a parsed options object and BuildTarget.
591 The target instance is None if no board is specified.
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700592 """
David James8c846492011-01-25 17:07:29 -0800593 parser = optparse.OptionParser()
594 parser.add_option('-H', '--binhost-base-url', dest='binhost_base_url',
595 default=_BINHOST_BASE_URL,
596 help='Base URL to use for binhost in make.conf updates')
597 parser.add_option('', '--previous-binhost-url', action='append',
598 default=[], dest='previous_binhost_url',
599 help='Previous binhost URL')
600 parser.add_option('-b', '--board', dest='board', default=None,
601 help='Board type that was built on this machine')
Zdenek Behan62a57792012-08-31 15:09:08 +0200602 parser.add_option('-B', '--prepackaged-tarball', dest='prepackaged_tarball',
603 default=None,
604 help='Board tarball prebuilt outside of this script.')
Mike Frysinger9e979b92012-11-29 02:55:09 -0500605 parser.add_option('--toolchain-tarball', dest='toolchain_tarballs',
606 action='append', default=[],
607 help='Redistributable toolchain tarball.')
608 parser.add_option('--toolchain-upload-path', default='',
609 help='Path to place toolchain tarballs in the sdk tree.')
David James4058b0d2011-12-08 21:24:50 -0800610 parser.add_option('', '--profile', dest='profile', default=None,
611 help='Profile that was built on this machine')
612 parser.add_option('', '--slave-board', default=[], action='callback',
613 dest='slave_targets', type='string',
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700614 callback=_AddSlaveBoard,
David James4058b0d2011-12-08 21:24:50 -0800615 help='Board type that was built on a slave machine. To '
616 'add a profile to this board, use --slave-profile.')
617 parser.add_option('', '--slave-profile', action='callback', type='string',
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700618 callback=_AddSlaveProfile,
David James4058b0d2011-12-08 21:24:50 -0800619 help='Board profile that was built on a slave machine. '
620 'Applies to previous slave board.')
David James8c846492011-01-25 17:07:29 -0800621 parser.add_option('-p', '--build-path', dest='build_path',
David James05bcb2b2011-02-09 09:25:47 -0800622 help='Path to the directory containing the chroot')
David James615e5b52011-06-03 11:10:15 -0700623 parser.add_option('', '--packages', action='append',
624 default=[], dest='packages',
625 help='Only include the specified packages. '
626 '(Default is to include all packages.)')
David James8c846492011-01-25 17:07:29 -0800627 parser.add_option('-s', '--sync-host', dest='sync_host',
628 default=False, action='store_true',
629 help='Sync host prebuilts')
630 parser.add_option('-g', '--git-sync', dest='git_sync',
631 default=False, action='store_true',
David Jamese2488642011-11-14 16:15:20 -0800632 help='Enable git version sync (This commits to a repo.) '
633 'This is used by full builders to commit directly '
634 'to board overlays.')
David James8c846492011-01-25 17:07:29 -0800635 parser.add_option('-u', '--upload', dest='upload',
636 default=None,
637 help='Upload location')
638 parser.add_option('-V', '--prepend-version', dest='prepend_version',
639 default=None,
640 help='Add an identifier to the front of the version')
641 parser.add_option('-f', '--filters', dest='filters', action='store_true',
642 default=False,
643 help='Turn on filtering of private ebuild packages')
644 parser.add_option('-k', '--key', dest='key',
645 default='PORTAGE_BINHOST',
646 help='Key to update in make.conf / binhost.conf')
David James8ece7ee2011-06-29 16:02:30 -0700647 parser.add_option('', '--set-version', dest='set_version',
648 default=None,
649 help='Specify the version string')
David James8c846492011-01-25 17:07:29 -0800650 parser.add_option('', '--sync-binhost-conf', dest='sync_binhost_conf',
651 default=False, action='store_true',
David Jamese2488642011-11-14 16:15:20 -0800652 help='Update binhost.conf in chromiumos-overlay or '
653 'chromeos-overlay. Commit the changes, but don\'t '
654 'push them. This is used for preflight binhosts.')
David James32b0b2f2011-07-13 20:56:50 -0700655 parser.add_option('', '--binhost-conf-dir', dest='binhost_conf_dir',
656 default=_BINHOST_CONF_DIR,
657 help='Directory to commit binhost config with '
658 '--sync-binhost-conf.')
David Jamesfd0b0852011-02-23 11:15:36 -0800659 parser.add_option('-P', '--private', dest='private', action='store_true',
660 default=False, help='Mark gs:// uploads as private.')
David James8ece7ee2011-06-29 16:02:30 -0700661 parser.add_option('', '--skip-upload', dest='skip_upload',
662 action='store_true', default=False,
663 help='Skip upload step.')
David James8fa34ea2011-04-15 13:00:20 -0700664 parser.add_option('', '--upload-board-tarball', dest='upload_board_tarball',
665 action='store_true', default=False,
666 help='Upload board tarball to Google Storage.')
David James27fa7d12011-06-29 17:24:14 -0700667 parser.add_option('', '--debug', dest='debug',
668 action='store_true', default=False,
669 help='Don\'t push or upload prebuilts.')
David James8c846492011-01-25 17:07:29 -0800670
671 options, args = parser.parse_args()
David James8c846492011-01-25 17:07:29 -0800672 if not options.build_path:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700673 Usage(parser, 'Error: you need provide a chroot path')
David James8ece7ee2011-06-29 16:02:30 -0700674 if not options.upload and not options.skip_upload:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700675 Usage(parser, 'Error: you need to provide an upload location using -u')
David James8ece7ee2011-06-29 16:02:30 -0700676 if not options.set_version and options.skip_upload:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700677 Usage(parser, 'Error: If you are using --skip-upload, you must specify a '
David James8ece7ee2011-06-29 16:02:30 -0700678 'version number using --set-version.')
David James9417f272011-05-26 13:24:47 -0700679 if args:
David Jamesc5cbd472012-06-19 16:25:45 -0700680 Usage(parser, 'Error: invalid arguments passed to upload_prebuilts: '
681 '%r' % args)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700682
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700683 target = None
684 if options.board:
685 target = BuildTarget(options.board, options.profile)
686
687 if target in options.slave_targets:
688 Usage(parser, 'Error: --board/--profile must not also be a slave target.')
David Jamese2488642011-11-14 16:15:20 -0800689
David James4058b0d2011-12-08 21:24:50 -0800690 if len(set(options.slave_targets)) != len(options.slave_targets):
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700691 Usage(parser, 'Error: --slave-boards must not have duplicates.')
David Jamese2488642011-11-14 16:15:20 -0800692
David James4058b0d2011-12-08 21:24:50 -0800693 if options.slave_targets and options.git_sync:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700694 Usage(parser, 'Error: --slave-boards is not compatible with --git-sync')
David Jamese2488642011-11-14 16:15:20 -0800695
David James8ece7ee2011-06-29 16:02:30 -0700696 if (options.upload_board_tarball and options.skip_upload and
697 options.board == 'amd64-host'):
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700698 Usage(parser, 'Error: --skip-upload is not compatible with '
David James8ece7ee2011-06-29 16:02:30 -0700699 '--upload-board-tarball and --board=amd64-host')
David James8fa34ea2011-04-15 13:00:20 -0700700
David James8ece7ee2011-06-29 16:02:30 -0700701 if (options.upload_board_tarball and not options.skip_upload and
702 not options.upload.startswith('gs://')):
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700703 Usage(parser, 'Error: --upload-board-tarball only works with gs:// URLs.\n'
David James8fa34ea2011-04-15 13:00:20 -0700704 '--upload must be a gs:// URL.')
705
Zdenek Behan86c15e92012-10-13 00:55:47 +0200706 if options.upload_board_tarball and options.prepackaged_tarball is None:
707 Usage(parser, 'Error: --upload-board-tarball requires '
708 '--prepackaged-tarball.')
709
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700710 if options.private:
711 if options.sync_host:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700712 Usage(parser, 'Error: --private and --sync-host/-s cannot be specified '
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700713 'together, we do not support private host prebuilts')
714
David James8ece7ee2011-06-29 16:02:30 -0700715 if not options.upload or not options.upload.startswith('gs://'):
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700716 Usage(parser, 'Error: --private is only valid for gs:// URLs.\n'
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700717 '--upload must be a gs:// URL.')
718
719 if options.binhost_base_url != _BINHOST_BASE_URL:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700720 Usage(parser, 'Error: when using --private the --binhost-base-url '
David Jamese2488642011-11-14 16:15:20 -0800721 'is automatically derived.')
David James27fa7d12011-06-29 17:24:14 -0700722
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700723 return options, target
David Jamesc0f158a2011-02-22 16:07:29 -0800724
David Jamesc5cbd472012-06-19 16:25:45 -0700725def main(_argv):
David Jamesdb401072011-06-10 12:17:16 -0700726 # Set umask to a sane value so that files created as root are readable.
Mike Frysinger60ec1012013-10-21 00:11:10 -0400727 os.umask(0o22)
David Jamesdb401072011-06-10 12:17:16 -0700728
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700729 options, target = ParseOptions()
David Jamesc0f158a2011-02-22 16:07:29 -0800730
David James05bcb2b2011-02-09 09:25:47 -0800731 # Calculate a list of Packages index files to compare against. Whenever we
732 # upload a package, we check to make sure it's not already stored in one of
733 # the packages files we uploaded. This list of packages files might contain
734 # both board and host packages.
David Jamesce093af2011-02-23 15:21:58 -0800735 pkg_indexes = _GrabAllRemotePackageIndexes(options.previous_binhost_url)
David James8c846492011-01-25 17:07:29 -0800736
David James8ece7ee2011-06-29 16:02:30 -0700737 if options.set_version:
738 version = options.set_version
739 else:
740 version = GetVersion()
Matt Tennante8179042013-10-01 15:47:32 -0700741
David Jamesc0f158a2011-02-22 16:07:29 -0800742 if options.prepend_version:
743 version = '%s-%s' % (options.prepend_version, version)
744
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700745 acl = 'public-read'
746 binhost_base_url = options.binhost_base_url
747
David Jamesadd21432013-05-21 10:04:07 -0700748 if options.private:
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700749 binhost_base_url = options.upload
David Jamesadd21432013-05-21 10:04:07 -0700750 if target:
Peter Mayo950e41a2014-02-06 21:07:33 +0000751 board_path = GetBoardOverlay(options.build_path, target)
David Jamesadd21432013-05-21 10:04:07 -0700752 acl = os.path.join(board_path, _GOOGLESTORAGE_ACL_FILE)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700753
754 uploader = PrebuiltUploader(options.upload, acl, binhost_base_url,
David James615e5b52011-06-03 11:10:15 -0700755 pkg_indexes, options.build_path,
David James27fa7d12011-06-29 17:24:14 -0700756 options.packages, options.skip_upload,
David Jamese2488642011-11-14 16:15:20 -0800757 options.binhost_conf_dir, options.debug,
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700758 target, options.slave_targets)
David Jamesc0f158a2011-02-22 16:07:29 -0800759
David James8c846492011-01-25 17:07:29 -0800760 if options.sync_host:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700761 uploader.SyncHostPrebuilts(version, options.key, options.git_sync,
762 options.sync_binhost_conf)
David James8c846492011-01-25 17:07:29 -0800763
Chris Sosa62c8ff52012-06-04 15:03:12 -0700764 if options.board or options.slave_targets:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700765 uploader.SyncBoardPrebuilts(version, options.key, options.git_sync,
766 options.sync_binhost_conf,
Zdenek Behan62a57792012-08-31 15:09:08 +0200767 options.upload_board_tarball,
Mike Frysinger9e979b92012-11-29 02:55:09 -0500768 options.prepackaged_tarball,
769 options.toolchain_tarballs,
770 options.toolchain_upload_path)