blob: 720da0c19623112331a58340c89f668822a2386e [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
David James8c846492011-01-25 17:07:29 -080020"""
21
Chris Sosa1dc96132012-05-11 15:40:50 -070022import datetime
23import multiprocessing
24import optparse
25import os
26import sys
Chris Sosa1dc96132012-05-11 15:40:50 -070027
Zdenek Behan33a34112012-09-10 21:07:51 +020028from chromite.buildbot import constants
David Jamese5867812012-10-19 12:02:20 -070029from chromite.buildbot import portage_utilities
David James6450a0a2012-12-04 07:59:53 -080030from chromite.lib import binpkg
Chris Sosa1dc96132012-05-11 15:40:50 -070031from chromite.lib import cros_build_lib
David James97d95872012-11-16 15:09:56 -080032from chromite.lib import git
Brian Harring7904b482012-08-08 02:54:12 -070033from chromite.lib import gs
Brian Harringaf019fb2012-05-10 15:06:13 -070034from chromite.lib import osutils
David James6450a0a2012-12-04 07:59:53 -080035from chromite.lib import parallel
Mike Frysinger8e727a32013-01-16 16:57:53 -050036from chromite.lib import toolchain
Chris Sosa1dc96132012-05-11 15:40:50 -070037
David James015af872012-06-19 15:24:36 -070038# How many times to retry uploads.
39_RETRIES = 10
40
41# Multiplier for how long to sleep (in seconds) between retries; will delay
42# (1*sleep) the first time, then (2*sleep), continuing via attempt * sleep.
43_SLEEP_TIME = 60
44
David James8c846492011-01-25 17:07:29 -080045_HOST_PACKAGES_PATH = 'chroot/var/lib/portage/pkgs'
David James05bcb2b2011-02-09 09:25:47 -080046_CATEGORIES_PATH = 'chroot/etc/portage/categories'
David James615e5b52011-06-03 11:10:15 -070047_PYM_PATH = 'chroot/usr/lib/portage/pym'
David James4058b0d2011-12-08 21:24:50 -080048_HOST_ARCH = 'amd64'
David James8c846492011-01-25 17:07:29 -080049_BOARD_PATH = 'chroot/build/%(board)s'
David James4058b0d2011-12-08 21:24:50 -080050_REL_BOARD_PATH = 'board/%(target)s/%(version)s'
51_REL_HOST_PATH = 'host/%(host_arch)s/%(target)s/%(version)s'
David James8c846492011-01-25 17:07:29 -080052# Private overlays to look at for builds to filter
53# relative to build path
54_PRIVATE_OVERLAY_DIR = 'src/private-overlays'
Scott Zawalskiab1bed32011-03-16 15:24:24 -070055_GOOGLESTORAGE_ACL_FILE = 'googlestorage_acl.xml'
Mike Frysinger5aba4dd2013-01-16 16:42:36 -050056_BINHOST_BASE_URL = gs.PUBLIC_BASE_HTTPS_URL + 'chromeos-prebuilt'
David James8c846492011-01-25 17:07:29 -080057_PREBUILT_BASE_DIR = 'src/third_party/chromiumos-overlay/chromeos/config/'
58# Created in the event of new host targets becoming available
59_PREBUILT_MAKE_CONF = {'amd64': os.path.join(_PREBUILT_BASE_DIR,
60 'make.conf.amd64-host')}
61_BINHOST_CONF_DIR = 'src/third_party/chromiumos-overlay/chromeos/binhost'
62
63
David James4058b0d2011-12-08 21:24:50 -080064class BuildTarget(object):
65 """A board/variant/profile tuple."""
66
67 def __init__(self, board_variant, profile=None):
68 self.board_variant = board_variant
69 self.board, _, self.variant = board_variant.partition('_')
70 self.profile = profile
71
72 def __str__(self):
73 if self.profile:
74 return '%s_%s' % (self.board_variant, self.profile)
75 else:
76 return self.board_variant
77
78 def __eq__(self, other):
79 return str(other) == str(self)
80
81 def __hash__(self):
82 return hash(str(self))
83
84
David James8c846492011-01-25 17:07:29 -080085def UpdateLocalFile(filename, value, key='PORTAGE_BINHOST'):
86 """Update the key in file with the value passed.
Mike Frysinger1a736a82013-12-12 01:50:59 -050087
David James8c846492011-01-25 17:07:29 -080088 File format:
89 key="value"
90 Note quotes are added automatically
91
92 Args:
93 filename: Name of file to modify.
94 value: Value to write with the key.
95 key: The variable key to update. (Default: PORTAGE_BINHOST)
96 """
97 if os.path.exists(filename):
98 file_fh = open(filename)
99 else:
100 file_fh = open(filename, 'w+')
101 file_lines = []
102 found = False
103 keyval_str = '%(key)s=%(value)s'
104 for line in file_fh:
105 # Strip newlines from end of line. We already add newlines below.
106 line = line.rstrip("\n")
107
108 if len(line.split('=')) != 2:
109 # Skip any line that doesn't fit key=val.
110 file_lines.append(line)
111 continue
112
113 file_var, file_val = line.split('=')
114 if file_var == key:
115 found = True
David James20b2b6f2011-11-18 15:11:58 -0800116 print 'Updating %s=%s to %s="%s"' % (file_var, file_val, key, value)
David James8c846492011-01-25 17:07:29 -0800117 value = '"%s"' % value
118 file_lines.append(keyval_str % {'key': key, 'value': value})
119 else:
120 file_lines.append(keyval_str % {'key': file_var, 'value': file_val})
121
122 if not found:
Brian Harring2a014302012-05-12 00:53:33 -0700123 value = '"%s"' % value
David James8c846492011-01-25 17:07:29 -0800124 file_lines.append(keyval_str % {'key': key, 'value': value})
125
126 file_fh.close()
127 # write out new file
Brian Harringaf019fb2012-05-10 15:06:13 -0700128 osutils.WriteFile(filename, '\n'.join(file_lines) + '\n')
David James8c846492011-01-25 17:07:29 -0800129
130
Mike Frysinger5b34d732013-01-17 15:11:58 -0500131def RevGitFile(filename, data, retries=5, dryrun=False):
David James8c846492011-01-25 17:07:29 -0800132 """Update and push the git file.
133
Mike Frysinger5b34d732013-01-17 15:11:58 -0500134 Args:
135 filename: file to modify that is in a git repo already
136 data: A dict of key/values to update in |filename|
137 retries: The number of times to retry before giving up, default: 5
Matt Tennante8179042013-10-01 15:47:32 -0700138 dryrun: If True, do not actually commit the change.
David James8c846492011-01-25 17:07:29 -0800139 """
140 prebuilt_branch = 'prebuilt_branch'
David James1b6e67a2011-05-19 21:32:38 -0700141 cwd = os.path.abspath(os.path.dirname(filename))
David James97d95872012-11-16 15:09:56 -0800142 commit = git.RunGit(cwd, ['rev-parse', 'HEAD']).output.rstrip()
Mike Frysinger5b34d732013-01-17 15:11:58 -0500143 description = '%s: updating %s' % (os.path.basename(filename),
144 ', '.join(data.keys()))
145 # UpdateLocalFile will print out the keys/values for us.
146 print 'Revving git file %s' % filename
David James66009462012-03-25 10:08:38 -0700147
David James8c846492011-01-25 17:07:29 -0800148 try:
David James97d95872012-11-16 15:09:56 -0800149 git.CreatePushBranch(prebuilt_branch, cwd)
Mike Frysinger5b34d732013-01-17 15:11:58 -0500150 for key, value in data.iteritems():
151 UpdateLocalFile(filename, value, key)
David James97d95872012-11-16 15:09:56 -0800152 git.RunGit(cwd, ['add', filename])
153 git.RunGit(cwd, ['commit', '-m', description])
154 git.PushWithRetry(prebuilt_branch, cwd, dryrun=dryrun, retries=retries)
David James8c846492011-01-25 17:07:29 -0800155 finally:
David James67d73252013-09-19 17:33:12 -0700156 git.RunGit(cwd, ['checkout', commit])
David James8c846492011-01-25 17:07:29 -0800157
158
159def GetVersion():
160 """Get the version to put in LATEST and update the git version with."""
Mike Frysinger0b92cfe2012-12-13 02:13:45 -0500161 return datetime.datetime.now().strftime('%Y.%m.%d.%H%M%S')
David James8c846492011-01-25 17:07:29 -0800162
163
David James015af872012-06-19 15:24:36 -0700164def _GsUpload(local_file, remote_file, acl):
David James8c846492011-01-25 17:07:29 -0800165 """Upload to GS bucket.
166
167 Args:
Matt Tennante8179042013-10-01 15:47:32 -0700168 local_file: The local file to be uploaded.
169 remote_file: The remote location to upload to.
170 acl: The ACL to use for uploading the file.
David James8c846492011-01-25 17:07:29 -0800171
172 Returns:
173 Return the arg tuple of two if the upload failed
174 """
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700175 CANNED_ACLS = ['public-read', 'private', 'bucket-owner-read',
176 'authenticated-read', 'bucket-owner-full-control',
177 'public-read-write']
David James9374aac2013-10-08 16:00:17 -0700178 gs_context = gs.GSContext(retries=_RETRIES, sleep=_SLEEP_TIME)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700179 if acl in CANNED_ACLS:
David James9374aac2013-10-08 16:00:17 -0700180 gs_context.Copy(local_file, remote_file, acl=acl)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700181 else:
182 # For private uploads we assume that the overlay board is set up properly
David James015af872012-06-19 15:24:36 -0700183 # and a googlestore_acl.xml is present. Otherwise, this script errors.
David James9374aac2013-10-08 16:00:17 -0700184 gs_context.Copy(local_file, remote_file, acl='private')
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700185 # Apply the passed in ACL xml file to the uploaded object.
David James9374aac2013-10-08 16:00:17 -0700186 gs_context.SetACL(remote_file, acl=acl)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700187
David Jamesfd0b0852011-02-23 11:15:36 -0800188def RemoteUpload(acl, files, pool=10):
David James8c846492011-01-25 17:07:29 -0800189 """Upload to google storage.
190
191 Create a pool of process and call _GsUpload with the proper arguments.
192
193 Args:
David Jamesfd0b0852011-02-23 11:15:36 -0800194 acl: The canned acl used for uploading. acl can be one of: "public-read",
195 "public-read-write", "authenticated-read", "bucket-owner-read",
196 "bucket-owner-full-control", or "private".
David James8c846492011-01-25 17:07:29 -0800197 files: dictionary with keys to local files and values to remote path.
198 pool: integer of maximum proesses to have at the same time.
199
200 Returns:
201 Return a set of tuple arguments of the failed uploads
202 """
David James015af872012-06-19 15:24:36 -0700203 tasks = [[key, value, acl] for key, value in files.iteritems()]
David James6450a0a2012-12-04 07:59:53 -0800204 parallel.RunTasksInProcessPool(_GsUpload, tasks, pool)
David James8c846492011-01-25 17:07:29 -0800205
206
207def GenerateUploadDict(base_local_path, base_remote_path, pkgs):
208 """Build a dictionary of local remote file key pairs to upload.
209
210 Args:
211 base_local_path: The base path to the files on the local hard drive.
Matt Tennante8179042013-10-01 15:47:32 -0700212 base_remote_path: The base path to the remote paths.
David James8c846492011-01-25 17:07:29 -0800213 pkgs: The packages to upload.
214
215 Returns:
216 Returns a dictionary of local_path/remote_path pairs
217 """
218 upload_files = {}
219 for pkg in pkgs:
220 suffix = pkg['CPV'] + '.tbz2'
221 local_path = os.path.join(base_local_path, suffix)
222 assert os.path.exists(local_path)
223 remote_path = '%s/%s' % (base_remote_path.rstrip('/'), suffix)
224 upload_files[local_path] = remote_path
225
226 return upload_files
227
Peter Mayo7e4605f2014-01-31 15:21:17 -0500228def GetBoardOverlay(build_path, target, prefer):
David Jamese5867812012-10-19 12:02:20 -0700229 """Get the path to the board variant.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500230
David James8c846492011-01-25 17:07:29 -0800231 Args:
232 build_path: The path to the root of the build directory
David Jamese5867812012-10-19 12:02:20 -0700233 target: The target board as a BuildTarget object.
Peter Mayo7e4605f2014-01-31 15:21:17 -0500234 prefer: If we find an overlay that start with this, return
235 the last one of them. Useful for generic override
236 variants that occur after private board overlays.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500237
David James8c846492011-01-25 17:07:29 -0800238 Returns:
David Jamese5867812012-10-19 12:02:20 -0700239 The last overlay configured for the given board as a string.
David James8c846492011-01-25 17:07:29 -0800240 """
David Jamese5867812012-10-19 12:02:20 -0700241 board = target.board_variant
242 overlays = portage_utilities.FindOverlays(constants.BOTH_OVERLAYS, board,
243 buildroot=build_path)
244 # We only care about the last entry.
Peter Mayo7e4605f2014-01-31 15:21:17 -0500245 if prefer:
246 for path in reversed(overlays):
247 if path.startswith(prefer):
248 return path
249
David Jamese5867812012-10-19 12:02:20 -0700250 return overlays[-1]
David James8c846492011-01-25 17:07:29 -0800251
252
253def DeterminePrebuiltConfFile(build_path, target):
254 """Determine the prebuilt.conf file that needs to be updated for prebuilts.
255
Mike Frysinger1a736a82013-12-12 01:50:59 -0500256 Args:
257 build_path: The path to the root of the build directory
258 target: String representation of the board. This includes host and board
259 targets
David James8c846492011-01-25 17:07:29 -0800260
Mike Frysinger1a736a82013-12-12 01:50:59 -0500261 Returns:
262 A string path to a prebuilt.conf file to be updated.
David James8c846492011-01-25 17:07:29 -0800263 """
David James4058b0d2011-12-08 21:24:50 -0800264 if _HOST_ARCH == target:
David James8c846492011-01-25 17:07:29 -0800265 # We are host.
266 # Without more examples of hosts this is a kludge for now.
267 # TODO(Scottz): as new host targets come online expand this to
268 # work more like boards.
Chris Sosa471532a2011-02-01 15:10:06 -0800269 make_path = _PREBUILT_MAKE_CONF[target]
David James8c846492011-01-25 17:07:29 -0800270 else:
271 # We are a board
Peter Mayo7e4605f2014-01-31 15:21:17 -0500272 board = GetBoardOverlay(build_path, target, None)
David James8c846492011-01-25 17:07:29 -0800273 make_path = os.path.join(board, 'prebuilt.conf')
274
275 return make_path
276
277
278def UpdateBinhostConfFile(path, key, value):
279 """Update binhost config file file with key=value.
280
281 Args:
282 path: Filename to update.
283 key: Key to update.
284 value: New value for key.
285 """
286 cwd = os.path.dirname(os.path.abspath(path))
287 filename = os.path.basename(path)
Brian Harringaf019fb2012-05-10 15:06:13 -0700288 osutils.SafeMakedirs(cwd)
David Jamesf6e8fb72013-05-10 08:58:43 -0700289 if not git.GetCurrentBranch(cwd):
290 git.CreatePushBranch(constants.STABLE_EBUILD_BRANCH, cwd, sync=False)
Brian Harring22edb442012-05-11 23:55:18 -0700291 osutils.WriteFile(path, '', mode='a')
David James8c846492011-01-25 17:07:29 -0800292 UpdateLocalFile(path, value, key)
David James67d73252013-09-19 17:33:12 -0700293 git.RunGit(cwd, ['add', filename])
Mike Frysinger109cada2013-01-17 15:50:44 -0500294 description = '%s: updating %s' % (os.path.basename(filename), key)
David James67d73252013-09-19 17:33:12 -0700295 git.RunGit(cwd, ['commit', '-m', description])
David James8c846492011-01-25 17:07:29 -0800296
297
David Jamesce093af2011-02-23 15:21:58 -0800298def _GrabAllRemotePackageIndexes(binhost_urls):
David James05bcb2b2011-02-09 09:25:47 -0800299 """Grab all of the packages files associated with a list of binhost_urls.
300
David James05bcb2b2011-02-09 09:25:47 -0800301 Args:
302 binhost_urls: The URLs for the directories containing the Packages files we
303 want to grab.
David James05bcb2b2011-02-09 09:25:47 -0800304
305 Returns:
306 A list of PackageIndex objects.
307 """
308 pkg_indexes = []
309 for url in binhost_urls:
David James32faafe2012-06-08 14:25:03 -0700310 pkg_index = binpkg.GrabRemotePackageIndex(url)
David James05bcb2b2011-02-09 09:25:47 -0800311 if pkg_index:
312 pkg_indexes.append(pkg_index)
David James05bcb2b2011-02-09 09:25:47 -0800313 return pkg_indexes
314
315
David Jamesc0f158a2011-02-22 16:07:29 -0800316class PrebuiltUploader(object):
317 """Synchronize host and board prebuilts."""
David James8c846492011-01-25 17:07:29 -0800318
David James615e5b52011-06-03 11:10:15 -0700319 def __init__(self, upload_location, acl, binhost_base_url,
David James32b0b2f2011-07-13 20:56:50 -0700320 pkg_indexes, build_path, packages, skip_upload,
David James4058b0d2011-12-08 21:24:50 -0800321 binhost_conf_dir, debug, target, slave_targets):
David Jamesc0f158a2011-02-22 16:07:29 -0800322 """Constructor for prebuilt uploader object.
David James8c846492011-01-25 17:07:29 -0800323
David Jamesc0f158a2011-02-22 16:07:29 -0800324 This object can upload host or prebuilt files to Google Storage.
David James8c846492011-01-25 17:07:29 -0800325
David Jamesc0f158a2011-02-22 16:07:29 -0800326 Args:
327 upload_location: The upload location.
David Jamesfd0b0852011-02-23 11:15:36 -0800328 acl: The canned acl used for uploading to Google Storage. acl can be one
329 of: "public-read", "public-read-write", "authenticated-read",
Matt Tennante8179042013-10-01 15:47:32 -0700330 "bucket-owner-read", "bucket-owner-full-control", "project-private",
331 or "private" (see "gsutil help acls"). If we are not uploading to
332 Google Storage, this parameter is unused.
David Jamesfd0b0852011-02-23 11:15:36 -0800333 binhost_base_url: The URL used for downloading the prebuilts.
David Jamesc0f158a2011-02-22 16:07:29 -0800334 pkg_indexes: Old uploaded prebuilts to compare against. Instead of
335 uploading duplicate files, we just link to the old files.
David James615e5b52011-06-03 11:10:15 -0700336 build_path: The path to the directory containing the chroot.
337 packages: Packages to upload.
David James32b0b2f2011-07-13 20:56:50 -0700338 skip_upload: Don't actually upload the tarballs.
339 binhost_conf_dir: Directory where to store binhost.conf files.
340 debug: Don't push or upload prebuilts.
David James4058b0d2011-12-08 21:24:50 -0800341 target: BuildTarget managed by this builder.
342 slave_targets: List of BuildTargets managed by slave builders.
David Jamesc0f158a2011-02-22 16:07:29 -0800343 """
344 self._upload_location = upload_location
David Jamesfd0b0852011-02-23 11:15:36 -0800345 self._acl = acl
David Jamesc0f158a2011-02-22 16:07:29 -0800346 self._binhost_base_url = binhost_base_url
347 self._pkg_indexes = pkg_indexes
David James615e5b52011-06-03 11:10:15 -0700348 self._build_path = build_path
349 self._packages = set(packages)
Mike Frysingerf5f809a2013-02-12 13:47:37 -0500350 self._found_packages = set()
David James8ece7ee2011-06-29 16:02:30 -0700351 self._skip_upload = skip_upload
David James32b0b2f2011-07-13 20:56:50 -0700352 self._binhost_conf_dir = binhost_conf_dir
David James27fa7d12011-06-29 17:24:14 -0700353 self._debug = debug
David James4058b0d2011-12-08 21:24:50 -0800354 self._target = target
355 self._slave_targets = slave_targets
David James615e5b52011-06-03 11:10:15 -0700356
357 def _ShouldFilterPackage(self, pkg):
358 if not self._packages:
359 return False
360 pym_path = os.path.abspath(os.path.join(self._build_path, _PYM_PATH))
David James710b7dc2012-02-07 16:49:59 -0800361 sys.path.insert(0, pym_path)
David James615e5b52011-06-03 11:10:15 -0700362 import portage.versions
363 cat, pkgname = portage.versions.catpkgsplit(pkg['CPV'])[0:2]
364 cp = '%s/%s' % (cat, pkgname)
Mike Frysingerf5f809a2013-02-12 13:47:37 -0500365 self._found_packages.add(cp)
David James615e5b52011-06-03 11:10:15 -0700366 return pkgname not in self._packages and cp not in self._packages
David James8c846492011-01-25 17:07:29 -0800367
David Jamesc0f158a2011-02-22 16:07:29 -0800368 def _UploadPrebuilt(self, package_path, url_suffix):
369 """Upload host or board prebuilt files to Google Storage space.
David James8c846492011-01-25 17:07:29 -0800370
David Jamesc0f158a2011-02-22 16:07:29 -0800371 Args:
372 package_path: The path to the packages dir.
David Jamesce093af2011-02-23 15:21:58 -0800373 url_suffix: The remote subdirectory where we should upload the packages.
David Jamesc0f158a2011-02-22 16:07:29 -0800374 """
David Jamesc0f158a2011-02-22 16:07:29 -0800375 # Process Packages file, removing duplicates and filtered packages.
David James32faafe2012-06-08 14:25:03 -0700376 pkg_index = binpkg.GrabLocalPackageIndex(package_path)
David Jamesc0f158a2011-02-22 16:07:29 -0800377 pkg_index.SetUploadLocation(self._binhost_base_url, url_suffix)
David James615e5b52011-06-03 11:10:15 -0700378 pkg_index.RemoveFilteredPackages(self._ShouldFilterPackage)
David Jamesc0f158a2011-02-22 16:07:29 -0800379 uploads = pkg_index.ResolveDuplicateUploads(self._pkg_indexes)
Mike Frysingerf5f809a2013-02-12 13:47:37 -0500380 unmatched_pkgs = self._packages - self._found_packages
381 if unmatched_pkgs:
382 cros_build_lib.Warning('unable to match packages: %r' % unmatched_pkgs)
David James05bcb2b2011-02-09 09:25:47 -0800383
David Jamesc0f158a2011-02-22 16:07:29 -0800384 # Write Packages file.
385 tmp_packages_file = pkg_index.WriteToNamedTemporaryFile()
David James05bcb2b2011-02-09 09:25:47 -0800386
David Jamesc0f158a2011-02-22 16:07:29 -0800387 remote_location = '%s/%s' % (self._upload_location.rstrip('/'), url_suffix)
David James015af872012-06-19 15:24:36 -0700388 assert remote_location.startswith('gs://')
David James05bcb2b2011-02-09 09:25:47 -0800389
David James015af872012-06-19 15:24:36 -0700390 # Build list of files to upload.
391 upload_files = GenerateUploadDict(package_path, remote_location, uploads)
392 remote_file = '%s/Packages' % remote_location.rstrip('/')
393 upload_files[tmp_packages_file.name] = remote_file
394
395 RemoteUpload(self._acl, upload_files)
David James8c846492011-01-25 17:07:29 -0800396
Mike Frysinger9e979b92012-11-29 02:55:09 -0500397 def _UploadSdkTarball(self, board_path, url_suffix, version, prepackaged,
398 toolchain_tarballs, toolchain_upload_path):
399 """Upload a tarball of the sdk at the specified path to Google Storage.
David James8fa34ea2011-04-15 13:00:20 -0700400
401 Args:
402 board_path: The path to the board dir.
403 url_suffix: The remote subdirectory where we should upload the packages.
Zdenek Behan5ad96c02011-06-23 01:04:06 +0200404 version: The version of the board.
Zdenek Behan62a57792012-08-31 15:09:08 +0200405 prepackaged: If given, a tarball that has been packaged outside of this
406 script and should be used.
Mike Frysinger9e979b92012-11-29 02:55:09 -0500407 toolchain_tarballs: List of toolchain tarballs to upload.
408 toolchain_upload_path: Path under the bucket to place toolchain tarballs.
David James8fa34ea2011-04-15 13:00:20 -0700409 """
410 remote_location = '%s/%s' % (self._upload_location.rstrip('/'), url_suffix)
411 assert remote_location.startswith('gs://')
Zdenek Behan86c15e92012-10-13 00:55:47 +0200412 boardname = os.path.basename(board_path.rstrip('/'))
413 # We do not upload non SDK board tarballs,
414 assert boardname == constants.CHROOT_BUILDER_BOARD
415 assert prepackaged is not None
Zdenek Behan62a57792012-08-31 15:09:08 +0200416
Zdenek Behan86c15e92012-10-13 00:55:47 +0200417 version_str = version[len('chroot-'):]
Mike Frysinger8e727a32013-01-16 16:57:53 -0500418 remote_tarfile = toolchain.GetSdkURL(
419 for_gsutil=True, suburl='cros-sdk-%s.tar.xz' % (version_str,))
Zdenek Behan86c15e92012-10-13 00:55:47 +0200420 # For SDK, also upload the manifest which is guaranteed to exist
421 # by the builderstage.
422 _GsUpload(prepackaged + '.Manifest', remote_tarfile + '.Manifest',
423 self._acl)
424 _GsUpload(prepackaged, remote_tarfile, self._acl)
425
Mike Frysinger9e979b92012-11-29 02:55:09 -0500426 # Post the toolchain tarballs too.
427 for tarball in toolchain_tarballs:
428 target, local_path = tarball.split(':')
429 suburl = toolchain_upload_path % {'target': target}
430 remote_path = toolchain.GetSdkURL(for_gsutil=True, suburl=suburl)
431 _GsUpload(local_path, remote_path, self._acl)
432
Zdenek Behan86c15e92012-10-13 00:55:47 +0200433 # Finally, also update the pointer to the latest SDK on which polling
434 # scripts rely.
David James4bc13702013-03-26 08:08:04 -0700435 with osutils.TempDir() as tmpdir:
Zdenek Behan86c15e92012-10-13 00:55:47 +0200436 pointerfile = os.path.join(tmpdir, 'cros-sdk-latest.conf')
Mike Frysinger8e727a32013-01-16 16:57:53 -0500437 remote_pointerfile = toolchain.GetSdkURL(for_gsutil=True,
438 suburl='cros-sdk-latest.conf')
Zdenek Behan86c15e92012-10-13 00:55:47 +0200439 osutils.WriteFile(pointerfile, 'LATEST_SDK="%s"' % version_str)
440 _GsUpload(pointerfile, remote_pointerfile, self._acl)
Zdenek Behan33a34112012-09-10 21:07:51 +0200441
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700442 def _GetTargets(self):
443 """Retuns the list of targets to use."""
444 targets = self._slave_targets[:]
445 if self._target:
446 targets.append(self._target)
447
448 return targets
449
450 def SyncHostPrebuilts(self, version, key, git_sync, sync_binhost_conf):
David Jamesc0f158a2011-02-22 16:07:29 -0800451 """Synchronize host prebuilt files.
David James05bcb2b2011-02-09 09:25:47 -0800452
David Jamesc0f158a2011-02-22 16:07:29 -0800453 This function will sync both the standard host packages, plus the host
454 packages associated with all targets that have been "setup" with the
455 current host's chroot. For instance, if this host has been used to build
456 x86-generic, it will sync the host packages associated with
457 'i686-pc-linux-gnu'. If this host has also been used to build arm-generic,
458 it will also sync the host packages associated with
459 'armv7a-cros-linux-gnueabi'.
David James05bcb2b2011-02-09 09:25:47 -0800460
David Jamesc0f158a2011-02-22 16:07:29 -0800461 Args:
David Jamesc0f158a2011-02-22 16:07:29 -0800462 version: A unique string, intended to be included in the upload path,
463 which identifies the version number of the uploaded prebuilts.
464 key: The variable key to update in the git file.
465 git_sync: If set, update make.conf of target to reference the latest
466 prebuilt packages generated here.
467 sync_binhost_conf: If set, update binhost config file in
468 chromiumos-overlay for the host.
469 """
David Jamese2488642011-11-14 16:15:20 -0800470 # Slave boards are listed before the master board so that the master board
471 # takes priority (i.e. x86-generic preflight host prebuilts takes priority
472 # over preflight host prebuilts from other builders.)
473 binhost_urls = []
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700474 for target in self._GetTargets():
David James4058b0d2011-12-08 21:24:50 -0800475 url_suffix = _REL_HOST_PATH % {'version': version,
476 'host_arch': _HOST_ARCH,
477 'target': target}
David Jamese2488642011-11-14 16:15:20 -0800478 packages_url_suffix = '%s/packages' % url_suffix.rstrip('/')
David James05bcb2b2011-02-09 09:25:47 -0800479
David James4058b0d2011-12-08 21:24:50 -0800480 if self._target == target and not self._skip_upload and not self._debug:
David Jamese2488642011-11-14 16:15:20 -0800481 # Upload prebuilts.
482 package_path = os.path.join(self._build_path, _HOST_PACKAGES_PATH)
483 self._UploadPrebuilt(package_path, packages_url_suffix)
David James8ece7ee2011-06-29 16:02:30 -0700484
David Jamese2488642011-11-14 16:15:20 -0800485 # Record URL where prebuilts were uploaded.
486 binhost_urls.append('%s/%s/' % (self._binhost_base_url.rstrip('/'),
487 packages_url_suffix.rstrip('/')))
488
David James20b2b6f2011-11-18 15:11:58 -0800489 binhost = ' '.join(binhost_urls)
David James8ece7ee2011-06-29 16:02:30 -0700490 if git_sync:
491 git_file = os.path.join(self._build_path,
David James4058b0d2011-12-08 21:24:50 -0800492 _PREBUILT_MAKE_CONF[_HOST_ARCH])
Mike Frysinger5b34d732013-01-17 15:11:58 -0500493 RevGitFile(git_file, {key: binhost}, dryrun=self._debug)
David James8ece7ee2011-06-29 16:02:30 -0700494 if sync_binhost_conf:
David James32b0b2f2011-07-13 20:56:50 -0700495 binhost_conf = os.path.join(self._build_path, self._binhost_conf_dir,
David James4058b0d2011-12-08 21:24:50 -0800496 'host', '%s-%s.conf' % (_HOST_ARCH, key))
David Jamese2488642011-11-14 16:15:20 -0800497 UpdateBinhostConfFile(binhost_conf, key, binhost)
David Jamesc0f158a2011-02-22 16:07:29 -0800498
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700499 def SyncBoardPrebuilts(self, version, key, git_sync, sync_binhost_conf,
Mike Frysinger9e979b92012-11-29 02:55:09 -0500500 upload_board_tarball, prepackaged_board,
501 toolchain_tarballs, toolchain_upload_path):
David Jamesc0f158a2011-02-22 16:07:29 -0800502 """Synchronize board prebuilt files.
503
504 Args:
David Jamesc0f158a2011-02-22 16:07:29 -0800505 version: A unique string, intended to be included in the upload path,
506 which identifies the version number of the uploaded prebuilts.
507 key: The variable key to update in the git file.
508 git_sync: If set, update make.conf of target to reference the latest
509 prebuilt packages generated here.
510 sync_binhost_conf: If set, update binhost config file in
511 chromiumos-overlay for the current board.
David James8fa34ea2011-04-15 13:00:20 -0700512 upload_board_tarball: Include a tarball of the board in our upload.
Zdenek Behan62a57792012-08-31 15:09:08 +0200513 prepackaged_board: A tarball of the board built outside of this script.
Mike Frysinger9e979b92012-11-29 02:55:09 -0500514 toolchain_tarballs: A list of toolchain tarballs to upload.
515 toolchain_upload_path: Path under the bucket to place toolchain tarballs.
David Jamesc0f158a2011-02-22 16:07:29 -0800516 """
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700517 for target in self._GetTargets():
David Jamese2488642011-11-14 16:15:20 -0800518 board_path = os.path.join(self._build_path,
David James4058b0d2011-12-08 21:24:50 -0800519 _BOARD_PATH % {'board': target.board_variant})
David Jamese2488642011-11-14 16:15:20 -0800520 package_path = os.path.join(board_path, 'packages')
David James4058b0d2011-12-08 21:24:50 -0800521 url_suffix = _REL_BOARD_PATH % {'target': target, 'version': version}
David Jamese2488642011-11-14 16:15:20 -0800522 packages_url_suffix = '%s/packages' % url_suffix.rstrip('/')
David James8fa34ea2011-04-15 13:00:20 -0700523
Matt Tennante8179042013-10-01 15:47:32 -0700524 # Process the target board differently if it is the main --board.
David James4058b0d2011-12-08 21:24:50 -0800525 if self._target == target and not self._skip_upload and not self._debug:
Matt Tennante8179042013-10-01 15:47:32 -0700526 # This strips "chroot" prefix because that is sometimes added as the
527 # --prepend-version argument (e.g. by chromiumos-sdk bot).
528 # TODO(build): Clean it up to be less hard-coded.
Mike Frysinger9e979b92012-11-29 02:55:09 -0500529 version_str = version[len('chroot-'):]
530
David Jamese2488642011-11-14 16:15:20 -0800531 # Upload board tarballs in the background.
532 if upload_board_tarball:
Mike Frysinger9e979b92012-11-29 02:55:09 -0500533 if toolchain_upload_path:
534 toolchain_upload_path %= {'version': version_str}
535 tar_process = multiprocessing.Process(
536 target=self._UploadSdkTarball,
537 args=(board_path, url_suffix, version, prepackaged_board,
538 toolchain_tarballs, toolchain_upload_path))
David Jamese2488642011-11-14 16:15:20 -0800539 tar_process.start()
David James8fa34ea2011-04-15 13:00:20 -0700540
David Jamese2488642011-11-14 16:15:20 -0800541 # Upload prebuilts.
542 self._UploadPrebuilt(package_path, packages_url_suffix)
David James8fa34ea2011-04-15 13:00:20 -0700543
David Jamese2488642011-11-14 16:15:20 -0800544 # Make sure we finished uploading the board tarballs.
545 if upload_board_tarball:
546 tar_process.join()
547 assert tar_process.exitcode == 0
548 # TODO(zbehan): This should be done cleaner.
Zdenek Behan33a34112012-09-10 21:07:51 +0200549 if target.board == constants.CHROOT_BUILDER_BOARD:
David Jamese2488642011-11-14 16:15:20 -0800550 sdk_conf = os.path.join(self._build_path, self._binhost_conf_dir,
Mike Frysinger5b34d732013-01-17 15:11:58 -0500551 'host/sdk_version.conf')
552 sdk_settings = {
Mike Frysinger9e979b92012-11-29 02:55:09 -0500553 'SDK_LATEST_VERSION': version_str,
554 'TC_PATH': toolchain_upload_path,
Mike Frysinger5b34d732013-01-17 15:11:58 -0500555 }
556 RevGitFile(sdk_conf, sdk_settings, dryrun=self._debug)
David Jamesc0f158a2011-02-22 16:07:29 -0800557
David Jamese2488642011-11-14 16:15:20 -0800558 # Record URL where prebuilts were uploaded.
559 url_value = '%s/%s/' % (self._binhost_base_url.rstrip('/'),
560 packages_url_suffix.rstrip('/'))
561
562 if git_sync:
David James4058b0d2011-12-08 21:24:50 -0800563 git_file = DeterminePrebuiltConfFile(self._build_path, target)
Mike Frysinger5b34d732013-01-17 15:11:58 -0500564 RevGitFile(git_file, {key: url_value}, dryrun=self._debug)
Matt Tennante8179042013-10-01 15:47:32 -0700565
David Jamese2488642011-11-14 16:15:20 -0800566 if sync_binhost_conf:
Matt Tennante8179042013-10-01 15:47:32 -0700567 # Update the binhost configuration file in git.
David Jamese2488642011-11-14 16:15:20 -0800568 binhost_conf = os.path.join(self._build_path, self._binhost_conf_dir,
David James4058b0d2011-12-08 21:24:50 -0800569 'target', '%s-%s.conf' % (target, key))
David Jamese2488642011-11-14 16:15:20 -0800570 UpdateBinhostConfFile(binhost_conf, key, url_value)
David James05bcb2b2011-02-09 09:25:47 -0800571
572
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700573def Usage(parser, msg):
David James8c846492011-01-25 17:07:29 -0800574 """Display usage message and parser help then exit with 1."""
575 print >> sys.stderr, msg
576 parser.print_help()
577 sys.exit(1)
578
David James4058b0d2011-12-08 21:24:50 -0800579
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700580def _AddSlaveBoard(_option, _opt_str, value, parser):
581 """Callback that adds a slave board to the list of slave targets."""
David James4058b0d2011-12-08 21:24:50 -0800582 parser.values.slave_targets.append(BuildTarget(value))
583
584
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700585def _AddSlaveProfile(_option, _opt_str, value, parser):
586 """Callback that adds a slave profile to the list of slave targets."""
David James4058b0d2011-12-08 21:24:50 -0800587 if not parser.values.slave_targets:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700588 Usage(parser, 'Must specify --slave-board before --slave-profile')
David James4058b0d2011-12-08 21:24:50 -0800589 if parser.values.slave_targets[-1].profile is not None:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700590 Usage(parser, 'Cannot specify --slave-profile twice for same board')
David James4058b0d2011-12-08 21:24:50 -0800591 parser.values.slave_targets[-1].profile = value
592
593
David Jamesc0f158a2011-02-22 16:07:29 -0800594def ParseOptions():
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700595 """Returns options given by the user and the target specified.
596
Mike Frysinger1a736a82013-12-12 01:50:59 -0500597 Returns:
598 A tuple containing a parsed options object and BuildTarget.
599 The target instance is None if no board is specified.
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700600 """
David James8c846492011-01-25 17:07:29 -0800601 parser = optparse.OptionParser()
602 parser.add_option('-H', '--binhost-base-url', dest='binhost_base_url',
603 default=_BINHOST_BASE_URL,
604 help='Base URL to use for binhost in make.conf updates')
605 parser.add_option('', '--previous-binhost-url', action='append',
606 default=[], dest='previous_binhost_url',
607 help='Previous binhost URL')
608 parser.add_option('-b', '--board', dest='board', default=None,
609 help='Board type that was built on this machine')
Zdenek Behan62a57792012-08-31 15:09:08 +0200610 parser.add_option('-B', '--prepackaged-tarball', dest='prepackaged_tarball',
611 default=None,
612 help='Board tarball prebuilt outside of this script.')
Mike Frysinger9e979b92012-11-29 02:55:09 -0500613 parser.add_option('--toolchain-tarball', dest='toolchain_tarballs',
614 action='append', default=[],
615 help='Redistributable toolchain tarball.')
616 parser.add_option('--toolchain-upload-path', default='',
617 help='Path to place toolchain tarballs in the sdk tree.')
David James4058b0d2011-12-08 21:24:50 -0800618 parser.add_option('', '--profile', dest='profile', default=None,
619 help='Profile that was built on this machine')
620 parser.add_option('', '--slave-board', default=[], action='callback',
621 dest='slave_targets', type='string',
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700622 callback=_AddSlaveBoard,
David James4058b0d2011-12-08 21:24:50 -0800623 help='Board type that was built on a slave machine. To '
624 'add a profile to this board, use --slave-profile.')
625 parser.add_option('', '--slave-profile', action='callback', type='string',
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700626 callback=_AddSlaveProfile,
David James4058b0d2011-12-08 21:24:50 -0800627 help='Board profile that was built on a slave machine. '
628 'Applies to previous slave board.')
David James8c846492011-01-25 17:07:29 -0800629 parser.add_option('-p', '--build-path', dest='build_path',
David James05bcb2b2011-02-09 09:25:47 -0800630 help='Path to the directory containing the chroot')
David James615e5b52011-06-03 11:10:15 -0700631 parser.add_option('', '--packages', action='append',
632 default=[], dest='packages',
633 help='Only include the specified packages. '
634 '(Default is to include all packages.)')
David James8c846492011-01-25 17:07:29 -0800635 parser.add_option('-s', '--sync-host', dest='sync_host',
636 default=False, action='store_true',
637 help='Sync host prebuilts')
638 parser.add_option('-g', '--git-sync', dest='git_sync',
639 default=False, action='store_true',
David Jamese2488642011-11-14 16:15:20 -0800640 help='Enable git version sync (This commits to a repo.) '
641 'This is used by full builders to commit directly '
642 'to board overlays.')
David James8c846492011-01-25 17:07:29 -0800643 parser.add_option('-u', '--upload', dest='upload',
644 default=None,
645 help='Upload location')
646 parser.add_option('-V', '--prepend-version', dest='prepend_version',
647 default=None,
648 help='Add an identifier to the front of the version')
649 parser.add_option('-f', '--filters', dest='filters', action='store_true',
650 default=False,
651 help='Turn on filtering of private ebuild packages')
652 parser.add_option('-k', '--key', dest='key',
653 default='PORTAGE_BINHOST',
654 help='Key to update in make.conf / binhost.conf')
David James8ece7ee2011-06-29 16:02:30 -0700655 parser.add_option('', '--set-version', dest='set_version',
656 default=None,
657 help='Specify the version string')
David James8c846492011-01-25 17:07:29 -0800658 parser.add_option('', '--sync-binhost-conf', dest='sync_binhost_conf',
659 default=False, action='store_true',
David Jamese2488642011-11-14 16:15:20 -0800660 help='Update binhost.conf in chromiumos-overlay or '
661 'chromeos-overlay. Commit the changes, but don\'t '
662 'push them. This is used for preflight binhosts.')
David James32b0b2f2011-07-13 20:56:50 -0700663 parser.add_option('', '--binhost-conf-dir', dest='binhost_conf_dir',
664 default=_BINHOST_CONF_DIR,
665 help='Directory to commit binhost config with '
666 '--sync-binhost-conf.')
David Jamesfd0b0852011-02-23 11:15:36 -0800667 parser.add_option('-P', '--private', dest='private', action='store_true',
668 default=False, help='Mark gs:// uploads as private.')
David James8ece7ee2011-06-29 16:02:30 -0700669 parser.add_option('', '--skip-upload', dest='skip_upload',
670 action='store_true', default=False,
671 help='Skip upload step.')
David James8fa34ea2011-04-15 13:00:20 -0700672 parser.add_option('', '--upload-board-tarball', dest='upload_board_tarball',
673 action='store_true', default=False,
674 help='Upload board tarball to Google Storage.')
David James27fa7d12011-06-29 17:24:14 -0700675 parser.add_option('', '--debug', dest='debug',
676 action='store_true', default=False,
677 help='Don\'t push or upload prebuilts.')
David James8c846492011-01-25 17:07:29 -0800678
679 options, args = parser.parse_args()
David James8c846492011-01-25 17:07:29 -0800680 if not options.build_path:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700681 Usage(parser, 'Error: you need provide a chroot path')
David James8ece7ee2011-06-29 16:02:30 -0700682 if not options.upload and not options.skip_upload:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700683 Usage(parser, 'Error: you need to provide an upload location using -u')
David James8ece7ee2011-06-29 16:02:30 -0700684 if not options.set_version and options.skip_upload:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700685 Usage(parser, 'Error: If you are using --skip-upload, you must specify a '
David James8ece7ee2011-06-29 16:02:30 -0700686 'version number using --set-version.')
David James9417f272011-05-26 13:24:47 -0700687 if args:
David Jamesc5cbd472012-06-19 16:25:45 -0700688 Usage(parser, 'Error: invalid arguments passed to upload_prebuilts: '
689 '%r' % args)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700690
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700691 target = None
692 if options.board:
693 target = BuildTarget(options.board, options.profile)
694
695 if target in options.slave_targets:
696 Usage(parser, 'Error: --board/--profile must not also be a slave target.')
David Jamese2488642011-11-14 16:15:20 -0800697
David James4058b0d2011-12-08 21:24:50 -0800698 if len(set(options.slave_targets)) != len(options.slave_targets):
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700699 Usage(parser, 'Error: --slave-boards must not have duplicates.')
David Jamese2488642011-11-14 16:15:20 -0800700
David James4058b0d2011-12-08 21:24:50 -0800701 if options.slave_targets and options.git_sync:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700702 Usage(parser, 'Error: --slave-boards is not compatible with --git-sync')
David Jamese2488642011-11-14 16:15:20 -0800703
David James8ece7ee2011-06-29 16:02:30 -0700704 if (options.upload_board_tarball and options.skip_upload and
705 options.board == 'amd64-host'):
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700706 Usage(parser, 'Error: --skip-upload is not compatible with '
David James8ece7ee2011-06-29 16:02:30 -0700707 '--upload-board-tarball and --board=amd64-host')
David James8fa34ea2011-04-15 13:00:20 -0700708
David James8ece7ee2011-06-29 16:02:30 -0700709 if (options.upload_board_tarball and not options.skip_upload and
710 not options.upload.startswith('gs://')):
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700711 Usage(parser, 'Error: --upload-board-tarball only works with gs:// URLs.\n'
David James8fa34ea2011-04-15 13:00:20 -0700712 '--upload must be a gs:// URL.')
713
Zdenek Behan86c15e92012-10-13 00:55:47 +0200714 if options.upload_board_tarball and options.prepackaged_tarball is None:
715 Usage(parser, 'Error: --upload-board-tarball requires '
716 '--prepackaged-tarball.')
717
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700718 if options.private:
719 if options.sync_host:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700720 Usage(parser, 'Error: --private and --sync-host/-s cannot be specified '
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700721 'together, we do not support private host prebuilts')
722
David James8ece7ee2011-06-29 16:02:30 -0700723 if not options.upload or not options.upload.startswith('gs://'):
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700724 Usage(parser, 'Error: --private is only valid for gs:// URLs.\n'
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700725 '--upload must be a gs:// URL.')
726
727 if options.binhost_base_url != _BINHOST_BASE_URL:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700728 Usage(parser, 'Error: when using --private the --binhost-base-url '
David Jamese2488642011-11-14 16:15:20 -0800729 'is automatically derived.')
David James27fa7d12011-06-29 17:24:14 -0700730
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700731 return options, target
David Jamesc0f158a2011-02-22 16:07:29 -0800732
David Jamesc5cbd472012-06-19 16:25:45 -0700733def main(_argv):
David Jamesdb401072011-06-10 12:17:16 -0700734 # Set umask to a sane value so that files created as root are readable.
Mike Frysinger60ec1012013-10-21 00:11:10 -0400735 os.umask(0o22)
David Jamesdb401072011-06-10 12:17:16 -0700736
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700737 options, target = ParseOptions()
David Jamesc0f158a2011-02-22 16:07:29 -0800738
David James05bcb2b2011-02-09 09:25:47 -0800739 # Calculate a list of Packages index files to compare against. Whenever we
740 # upload a package, we check to make sure it's not already stored in one of
741 # the packages files we uploaded. This list of packages files might contain
742 # both board and host packages.
David Jamesce093af2011-02-23 15:21:58 -0800743 pkg_indexes = _GrabAllRemotePackageIndexes(options.previous_binhost_url)
David James8c846492011-01-25 17:07:29 -0800744
David James8ece7ee2011-06-29 16:02:30 -0700745 if options.set_version:
746 version = options.set_version
747 else:
748 version = GetVersion()
Matt Tennante8179042013-10-01 15:47:32 -0700749
David Jamesc0f158a2011-02-22 16:07:29 -0800750 if options.prepend_version:
751 version = '%s-%s' % (options.prepend_version, version)
752
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700753 acl = 'public-read'
754 binhost_base_url = options.binhost_base_url
755
David Jamesadd21432013-05-21 10:04:07 -0700756 if options.private:
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700757 binhost_base_url = options.upload
David Jamesadd21432013-05-21 10:04:07 -0700758 if target:
Peter Mayo7e4605f2014-01-31 15:21:17 -0500759 board_path = GetBoardOverlay(options.build_path, target,
760 _PRIVATE_OVERLAY_DIR)
David Jamesadd21432013-05-21 10:04:07 -0700761 acl = os.path.join(board_path, _GOOGLESTORAGE_ACL_FILE)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700762
763 uploader = PrebuiltUploader(options.upload, acl, binhost_base_url,
David James615e5b52011-06-03 11:10:15 -0700764 pkg_indexes, options.build_path,
David James27fa7d12011-06-29 17:24:14 -0700765 options.packages, options.skip_upload,
David Jamese2488642011-11-14 16:15:20 -0800766 options.binhost_conf_dir, options.debug,
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700767 target, options.slave_targets)
David Jamesc0f158a2011-02-22 16:07:29 -0800768
David James8c846492011-01-25 17:07:29 -0800769 if options.sync_host:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700770 uploader.SyncHostPrebuilts(version, options.key, options.git_sync,
771 options.sync_binhost_conf)
David James8c846492011-01-25 17:07:29 -0800772
Chris Sosa62c8ff52012-06-04 15:03:12 -0700773 if options.board or options.slave_targets:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700774 uploader.SyncBoardPrebuilts(version, options.key, options.git_sync,
775 options.sync_binhost_conf,
Zdenek Behan62a57792012-08-31 15:09:08 +0200776 options.upload_board_tarball,
Mike Frysinger9e979b92012-11-29 02:55:09 -0500777 options.prepackaged_tarball,
778 options.toolchain_tarballs,
779 options.toolchain_upload_path)