blob: 28a39dd49b4df7984fede259a6d754c6c1bc744c [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
Mike Frysingerff441bf2014-05-24 13:47:21 -040021from __future__ import print_function
22
Chris Sosa1dc96132012-05-11 15:40:50 -070023import datetime
24import multiprocessing
Chris Sosa1dc96132012-05-11 15:40:50 -070025import os
26import sys
Chris Sosa1dc96132012-05-11 15:40:50 -070027
Don Garrett88b8d782014-05-13 17:30:55 -070028from chromite.cbuildbot import constants
29from chromite.cbuildbot import portage_utilities
David James6450a0a2012-12-04 07:59:53 -080030from chromite.lib import binpkg
Mike Frysinger86509232014-05-24 13:18:37 -040031from chromite.lib import commandline
Chris Sosa1dc96132012-05-11 15:40:50 -070032from chromite.lib import cros_build_lib
David James97d95872012-11-16 15:09:56 -080033from chromite.lib import git
Brian Harring7904b482012-08-08 02:54:12 -070034from chromite.lib import gs
Brian Harringaf019fb2012-05-10 15:06:13 -070035from chromite.lib import osutils
David James6450a0a2012-12-04 07:59:53 -080036from chromite.lib import parallel
Mike Frysinger8e727a32013-01-16 16:57:53 -050037from chromite.lib import toolchain
Chris Sosa1dc96132012-05-11 15:40:50 -070038
David James015af872012-06-19 15:24:36 -070039# How many times to retry uploads.
40_RETRIES = 10
41
42# Multiplier for how long to sleep (in seconds) between retries; will delay
43# (1*sleep) the first time, then (2*sleep), continuing via attempt * sleep.
44_SLEEP_TIME = 60
45
David James8c846492011-01-25 17:07:29 -080046_HOST_PACKAGES_PATH = 'chroot/var/lib/portage/pkgs'
David James05bcb2b2011-02-09 09:25:47 -080047_CATEGORIES_PATH = 'chroot/etc/portage/categories'
David James615e5b52011-06-03 11:10:15 -070048_PYM_PATH = 'chroot/usr/lib/portage/pym'
David James4058b0d2011-12-08 21:24:50 -080049_HOST_ARCH = 'amd64'
David James8c846492011-01-25 17:07:29 -080050_BOARD_PATH = 'chroot/build/%(board)s'
David James4058b0d2011-12-08 21:24:50 -080051_REL_BOARD_PATH = 'board/%(target)s/%(version)s'
52_REL_HOST_PATH = 'host/%(host_arch)s/%(target)s/%(version)s'
David James8c846492011-01-25 17:07:29 -080053# Private overlays to look at for builds to filter
54# relative to build path
55_PRIVATE_OVERLAY_DIR = 'src/private-overlays'
Scott Zawalskiab1bed32011-03-16 15:24:24 -070056_GOOGLESTORAGE_ACL_FILE = 'googlestorage_acl.xml'
David James3753d942014-04-23 10:55:48 -070057_BINHOST_BASE_URL = 'gs://chromeos-prebuilt'
David James8c846492011-01-25 17:07:29 -080058_PREBUILT_BASE_DIR = 'src/third_party/chromiumos-overlay/chromeos/config/'
59# Created in the event of new host targets becoming available
60_PREBUILT_MAKE_CONF = {'amd64': os.path.join(_PREBUILT_BASE_DIR,
61 'make.conf.amd64-host')}
62_BINHOST_CONF_DIR = 'src/third_party/chromiumos-overlay/chromeos/binhost'
63
64
David James4058b0d2011-12-08 21:24:50 -080065class BuildTarget(object):
66 """A board/variant/profile tuple."""
67
68 def __init__(self, board_variant, profile=None):
69 self.board_variant = board_variant
70 self.board, _, self.variant = board_variant.partition('_')
71 self.profile = profile
72
73 def __str__(self):
74 if self.profile:
75 return '%s_%s' % (self.board_variant, self.profile)
76 else:
77 return self.board_variant
78
79 def __eq__(self, other):
80 return str(other) == str(self)
81
82 def __hash__(self):
83 return hash(str(self))
84
85
David James8c846492011-01-25 17:07:29 -080086def UpdateLocalFile(filename, value, key='PORTAGE_BINHOST'):
87 """Update the key in file with the value passed.
Mike Frysinger1a736a82013-12-12 01:50:59 -050088
David James8c846492011-01-25 17:07:29 -080089 File format:
90 key="value"
91 Note quotes are added automatically
92
93 Args:
94 filename: Name of file to modify.
95 value: Value to write with the key.
96 key: The variable key to update. (Default: PORTAGE_BINHOST)
97 """
98 if os.path.exists(filename):
99 file_fh = open(filename)
100 else:
101 file_fh = open(filename, 'w+')
102 file_lines = []
103 found = False
104 keyval_str = '%(key)s=%(value)s'
105 for line in file_fh:
106 # Strip newlines from end of line. We already add newlines below.
107 line = line.rstrip("\n")
108
109 if len(line.split('=')) != 2:
110 # Skip any line that doesn't fit key=val.
111 file_lines.append(line)
112 continue
113
114 file_var, file_val = line.split('=')
115 if file_var == key:
116 found = True
Mike Frysingerff441bf2014-05-24 13:47:21 -0400117 print('Updating %s=%s to %s="%s"' % (file_var, file_val, key, value))
David James8c846492011-01-25 17:07:29 -0800118 value = '"%s"' % value
119 file_lines.append(keyval_str % {'key': key, 'value': value})
120 else:
121 file_lines.append(keyval_str % {'key': file_var, 'value': file_val})
122
123 if not found:
Brian Harring2a014302012-05-12 00:53:33 -0700124 value = '"%s"' % value
David James8c846492011-01-25 17:07:29 -0800125 file_lines.append(keyval_str % {'key': key, 'value': value})
126
127 file_fh.close()
128 # write out new file
Brian Harringaf019fb2012-05-10 15:06:13 -0700129 osutils.WriteFile(filename, '\n'.join(file_lines) + '\n')
David James8c846492011-01-25 17:07:29 -0800130
131
Mike Frysinger5b34d732013-01-17 15:11:58 -0500132def RevGitFile(filename, data, retries=5, dryrun=False):
David James8c846492011-01-25 17:07:29 -0800133 """Update and push the git file.
134
Mike Frysinger5b34d732013-01-17 15:11:58 -0500135 Args:
136 filename: file to modify that is in a git repo already
137 data: A dict of key/values to update in |filename|
138 retries: The number of times to retry before giving up, default: 5
Matt Tennante8179042013-10-01 15:47:32 -0700139 dryrun: If True, do not actually commit the change.
David James8c846492011-01-25 17:07:29 -0800140 """
141 prebuilt_branch = 'prebuilt_branch'
David James1b6e67a2011-05-19 21:32:38 -0700142 cwd = os.path.abspath(os.path.dirname(filename))
David James97d95872012-11-16 15:09:56 -0800143 commit = git.RunGit(cwd, ['rev-parse', 'HEAD']).output.rstrip()
Mike Frysinger5b34d732013-01-17 15:11:58 -0500144 description = '%s: updating %s' % (os.path.basename(filename),
145 ', '.join(data.keys()))
146 # UpdateLocalFile will print out the keys/values for us.
Mike Frysingerff441bf2014-05-24 13:47:21 -0400147 print('Revving git file %s' % filename)
David James66009462012-03-25 10:08:38 -0700148
David James8c846492011-01-25 17:07:29 -0800149 try:
David James97d95872012-11-16 15:09:56 -0800150 git.CreatePushBranch(prebuilt_branch, cwd)
Mike Frysinger5b34d732013-01-17 15:11:58 -0500151 for key, value in data.iteritems():
152 UpdateLocalFile(filename, value, key)
David James97d95872012-11-16 15:09:56 -0800153 git.RunGit(cwd, ['add', filename])
154 git.RunGit(cwd, ['commit', '-m', description])
155 git.PushWithRetry(prebuilt_branch, cwd, dryrun=dryrun, retries=retries)
David James8c846492011-01-25 17:07:29 -0800156 finally:
David James67d73252013-09-19 17:33:12 -0700157 git.RunGit(cwd, ['checkout', commit])
David James8c846492011-01-25 17:07:29 -0800158
159
160def GetVersion():
161 """Get the version to put in LATEST and update the git version with."""
Mike Frysinger0b92cfe2012-12-13 02:13:45 -0500162 return datetime.datetime.now().strftime('%Y.%m.%d.%H%M%S')
David James8c846492011-01-25 17:07:29 -0800163
164
David James015af872012-06-19 15:24:36 -0700165def _GsUpload(local_file, remote_file, acl):
David James8c846492011-01-25 17:07:29 -0800166 """Upload to GS bucket.
167
168 Args:
Matt Tennante8179042013-10-01 15:47:32 -0700169 local_file: The local file to be uploaded.
170 remote_file: The remote location to upload to.
171 acl: The ACL to use for uploading the file.
David James8c846492011-01-25 17:07:29 -0800172
173 Returns:
174 Return the arg tuple of two if the upload failed
175 """
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700176 CANNED_ACLS = ['public-read', 'private', 'bucket-owner-read',
177 'authenticated-read', 'bucket-owner-full-control',
178 'public-read-write']
David James9374aac2013-10-08 16:00:17 -0700179 gs_context = gs.GSContext(retries=_RETRIES, sleep=_SLEEP_TIME)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700180 if acl in CANNED_ACLS:
David James9374aac2013-10-08 16:00:17 -0700181 gs_context.Copy(local_file, remote_file, acl=acl)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700182 else:
183 # For private uploads we assume that the overlay board is set up properly
David James015af872012-06-19 15:24:36 -0700184 # and a googlestore_acl.xml is present. Otherwise, this script errors.
David James9374aac2013-10-08 16:00:17 -0700185 gs_context.Copy(local_file, remote_file, acl='private')
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700186 # Apply the passed in ACL xml file to the uploaded object.
David James9374aac2013-10-08 16:00:17 -0700187 gs_context.SetACL(remote_file, acl=acl)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700188
Mike Frysingercc838832014-05-24 13:10:30 -0400189
David Jamesfd0b0852011-02-23 11:15:36 -0800190def RemoteUpload(acl, files, pool=10):
David James8c846492011-01-25 17:07:29 -0800191 """Upload to google storage.
192
193 Create a pool of process and call _GsUpload with the proper arguments.
194
195 Args:
David Jamesfd0b0852011-02-23 11:15:36 -0800196 acl: The canned acl used for uploading. acl can be one of: "public-read",
197 "public-read-write", "authenticated-read", "bucket-owner-read",
198 "bucket-owner-full-control", or "private".
David James8c846492011-01-25 17:07:29 -0800199 files: dictionary with keys to local files and values to remote path.
200 pool: integer of maximum proesses to have at the same time.
201
202 Returns:
203 Return a set of tuple arguments of the failed uploads
204 """
David James015af872012-06-19 15:24:36 -0700205 tasks = [[key, value, acl] for key, value in files.iteritems()]
David James6450a0a2012-12-04 07:59:53 -0800206 parallel.RunTasksInProcessPool(_GsUpload, tasks, pool)
David James8c846492011-01-25 17:07:29 -0800207
208
209def GenerateUploadDict(base_local_path, base_remote_path, pkgs):
210 """Build a dictionary of local remote file key pairs to upload.
211
212 Args:
213 base_local_path: The base path to the files on the local hard drive.
Matt Tennante8179042013-10-01 15:47:32 -0700214 base_remote_path: The base path to the remote paths.
David James8c846492011-01-25 17:07:29 -0800215 pkgs: The packages to upload.
216
217 Returns:
218 Returns a dictionary of local_path/remote_path pairs
219 """
220 upload_files = {}
221 for pkg in pkgs:
222 suffix = pkg['CPV'] + '.tbz2'
223 local_path = os.path.join(base_local_path, suffix)
224 assert os.path.exists(local_path)
225 remote_path = '%s/%s' % (base_remote_path.rstrip('/'), suffix)
226 upload_files[local_path] = remote_path
227
228 return upload_files
229
Mike Frysingercc838832014-05-24 13:10:30 -0400230
Peter Mayo950e41a2014-02-06 21:07:33 +0000231def GetBoardOverlay(build_path, target):
David Jamese5867812012-10-19 12:02:20 -0700232 """Get the path to the board variant.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500233
David James8c846492011-01-25 17:07:29 -0800234 Args:
235 build_path: The path to the root of the build directory
David Jamese5867812012-10-19 12:02:20 -0700236 target: The target board as a BuildTarget object.
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.
245 return overlays[-1]
David James8c846492011-01-25 17:07:29 -0800246
247
248def DeterminePrebuiltConfFile(build_path, target):
249 """Determine the prebuilt.conf file that needs to be updated for prebuilts.
250
Mike Frysinger1a736a82013-12-12 01:50:59 -0500251 Args:
252 build_path: The path to the root of the build directory
253 target: String representation of the board. This includes host and board
254 targets
David James8c846492011-01-25 17:07:29 -0800255
Mike Frysinger1a736a82013-12-12 01:50:59 -0500256 Returns:
257 A string path to a prebuilt.conf file to be updated.
David James8c846492011-01-25 17:07:29 -0800258 """
David James4058b0d2011-12-08 21:24:50 -0800259 if _HOST_ARCH == target:
David James8c846492011-01-25 17:07:29 -0800260 # We are host.
261 # Without more examples of hosts this is a kludge for now.
262 # TODO(Scottz): as new host targets come online expand this to
263 # work more like boards.
Chris Sosa471532a2011-02-01 15:10:06 -0800264 make_path = _PREBUILT_MAKE_CONF[target]
David James8c846492011-01-25 17:07:29 -0800265 else:
266 # We are a board
Peter Mayo950e41a2014-02-06 21:07:33 +0000267 board = GetBoardOverlay(build_path, target)
David James8c846492011-01-25 17:07:29 -0800268 make_path = os.path.join(board, 'prebuilt.conf')
269
270 return make_path
271
272
273def UpdateBinhostConfFile(path, key, value):
274 """Update binhost config file file with key=value.
275
276 Args:
277 path: Filename to update.
278 key: Key to update.
279 value: New value for key.
280 """
281 cwd = os.path.dirname(os.path.abspath(path))
282 filename = os.path.basename(path)
Brian Harringaf019fb2012-05-10 15:06:13 -0700283 osutils.SafeMakedirs(cwd)
David Jamesf6e8fb72013-05-10 08:58:43 -0700284 if not git.GetCurrentBranch(cwd):
285 git.CreatePushBranch(constants.STABLE_EBUILD_BRANCH, cwd, sync=False)
Brian Harring22edb442012-05-11 23:55:18 -0700286 osutils.WriteFile(path, '', mode='a')
David James8c846492011-01-25 17:07:29 -0800287 UpdateLocalFile(path, value, key)
David James67d73252013-09-19 17:33:12 -0700288 git.RunGit(cwd, ['add', filename])
Mike Frysinger109cada2013-01-17 15:50:44 -0500289 description = '%s: updating %s' % (os.path.basename(filename), key)
David James67d73252013-09-19 17:33:12 -0700290 git.RunGit(cwd, ['commit', '-m', description])
David James8c846492011-01-25 17:07:29 -0800291
292
David Jamesce093af2011-02-23 15:21:58 -0800293def _GrabAllRemotePackageIndexes(binhost_urls):
David James05bcb2b2011-02-09 09:25:47 -0800294 """Grab all of the packages files associated with a list of binhost_urls.
295
David James05bcb2b2011-02-09 09:25:47 -0800296 Args:
297 binhost_urls: The URLs for the directories containing the Packages files we
298 want to grab.
David James05bcb2b2011-02-09 09:25:47 -0800299
300 Returns:
301 A list of PackageIndex objects.
302 """
303 pkg_indexes = []
304 for url in binhost_urls:
David James32faafe2012-06-08 14:25:03 -0700305 pkg_index = binpkg.GrabRemotePackageIndex(url)
David James05bcb2b2011-02-09 09:25:47 -0800306 if pkg_index:
307 pkg_indexes.append(pkg_index)
David James05bcb2b2011-02-09 09:25:47 -0800308 return pkg_indexes
309
310
David Jamesc0f158a2011-02-22 16:07:29 -0800311class PrebuiltUploader(object):
312 """Synchronize host and board prebuilts."""
David James8c846492011-01-25 17:07:29 -0800313
Mike Frysinger86509232014-05-24 13:18:37 -0400314 def __init__(self, upload_location, acl, binhost_base_url, pkg_indexes,
315 build_path, packages, skip_upload, binhost_conf_dir, dryrun,
316 target, slave_targets):
David Jamesc0f158a2011-02-22 16:07:29 -0800317 """Constructor for prebuilt uploader object.
David James8c846492011-01-25 17:07:29 -0800318
David Jamesc0f158a2011-02-22 16:07:29 -0800319 This object can upload host or prebuilt files to Google Storage.
David James8c846492011-01-25 17:07:29 -0800320
David Jamesc0f158a2011-02-22 16:07:29 -0800321 Args:
322 upload_location: The upload location.
David Jamesfd0b0852011-02-23 11:15:36 -0800323 acl: The canned acl used for uploading to Google Storage. acl can be one
324 of: "public-read", "public-read-write", "authenticated-read",
Matt Tennante8179042013-10-01 15:47:32 -0700325 "bucket-owner-read", "bucket-owner-full-control", "project-private",
326 or "private" (see "gsutil help acls"). If we are not uploading to
327 Google Storage, this parameter is unused.
David Jamesfd0b0852011-02-23 11:15:36 -0800328 binhost_base_url: The URL used for downloading the prebuilts.
David Jamesc0f158a2011-02-22 16:07:29 -0800329 pkg_indexes: Old uploaded prebuilts to compare against. Instead of
330 uploading duplicate files, we just link to the old files.
David James615e5b52011-06-03 11:10:15 -0700331 build_path: The path to the directory containing the chroot.
332 packages: Packages to upload.
David James32b0b2f2011-07-13 20:56:50 -0700333 skip_upload: Don't actually upload the tarballs.
334 binhost_conf_dir: Directory where to store binhost.conf files.
Mike Frysinger86509232014-05-24 13:18:37 -0400335 dryrun: Don't push or upload prebuilts.
David James4058b0d2011-12-08 21:24:50 -0800336 target: BuildTarget managed by this builder.
337 slave_targets: List of BuildTargets managed by slave builders.
David Jamesc0f158a2011-02-22 16:07:29 -0800338 """
339 self._upload_location = upload_location
David Jamesfd0b0852011-02-23 11:15:36 -0800340 self._acl = acl
David Jamesc0f158a2011-02-22 16:07:29 -0800341 self._binhost_base_url = binhost_base_url
342 self._pkg_indexes = pkg_indexes
David James615e5b52011-06-03 11:10:15 -0700343 self._build_path = build_path
344 self._packages = set(packages)
Mike Frysingerf5f809a2013-02-12 13:47:37 -0500345 self._found_packages = set()
David James8ece7ee2011-06-29 16:02:30 -0700346 self._skip_upload = skip_upload
David James32b0b2f2011-07-13 20:56:50 -0700347 self._binhost_conf_dir = binhost_conf_dir
Mike Frysinger86509232014-05-24 13:18:37 -0400348 self._dryrun = dryrun
David James4058b0d2011-12-08 21:24:50 -0800349 self._target = target
350 self._slave_targets = slave_targets
David James615e5b52011-06-03 11:10:15 -0700351
352 def _ShouldFilterPackage(self, pkg):
353 if not self._packages:
354 return False
355 pym_path = os.path.abspath(os.path.join(self._build_path, _PYM_PATH))
David James710b7dc2012-02-07 16:49:59 -0800356 sys.path.insert(0, pym_path)
Don Garrett25f309a2014-03-19 14:02:12 -0700357 # pylint: disable=F0401
David James615e5b52011-06-03 11:10:15 -0700358 import portage.versions
359 cat, pkgname = portage.versions.catpkgsplit(pkg['CPV'])[0:2]
360 cp = '%s/%s' % (cat, pkgname)
Mike Frysingerf5f809a2013-02-12 13:47:37 -0500361 self._found_packages.add(cp)
David James615e5b52011-06-03 11:10:15 -0700362 return pkgname not in self._packages and cp not in self._packages
David James8c846492011-01-25 17:07:29 -0800363
David Jamesc0f158a2011-02-22 16:07:29 -0800364 def _UploadPrebuilt(self, package_path, url_suffix):
365 """Upload host or board prebuilt files to Google Storage space.
David James8c846492011-01-25 17:07:29 -0800366
David Jamesc0f158a2011-02-22 16:07:29 -0800367 Args:
368 package_path: The path to the packages dir.
David Jamesce093af2011-02-23 15:21:58 -0800369 url_suffix: The remote subdirectory where we should upload the packages.
David Jamesc0f158a2011-02-22 16:07:29 -0800370 """
David Jamesc0f158a2011-02-22 16:07:29 -0800371 # Process Packages file, removing duplicates and filtered packages.
David James32faafe2012-06-08 14:25:03 -0700372 pkg_index = binpkg.GrabLocalPackageIndex(package_path)
David Jamesc0f158a2011-02-22 16:07:29 -0800373 pkg_index.SetUploadLocation(self._binhost_base_url, url_suffix)
David James615e5b52011-06-03 11:10:15 -0700374 pkg_index.RemoveFilteredPackages(self._ShouldFilterPackage)
David Jamesc0f158a2011-02-22 16:07:29 -0800375 uploads = pkg_index.ResolveDuplicateUploads(self._pkg_indexes)
Mike Frysingerf5f809a2013-02-12 13:47:37 -0500376 unmatched_pkgs = self._packages - self._found_packages
377 if unmatched_pkgs:
378 cros_build_lib.Warning('unable to match packages: %r' % unmatched_pkgs)
David James05bcb2b2011-02-09 09:25:47 -0800379
David Jamesc0f158a2011-02-22 16:07:29 -0800380 # Write Packages file.
381 tmp_packages_file = pkg_index.WriteToNamedTemporaryFile()
David James05bcb2b2011-02-09 09:25:47 -0800382
David Jamesc0f158a2011-02-22 16:07:29 -0800383 remote_location = '%s/%s' % (self._upload_location.rstrip('/'), url_suffix)
David James015af872012-06-19 15:24:36 -0700384 assert remote_location.startswith('gs://')
David James05bcb2b2011-02-09 09:25:47 -0800385
David James015af872012-06-19 15:24:36 -0700386 # Build list of files to upload.
387 upload_files = GenerateUploadDict(package_path, remote_location, uploads)
388 remote_file = '%s/Packages' % remote_location.rstrip('/')
389 upload_files[tmp_packages_file.name] = remote_file
390
391 RemoteUpload(self._acl, upload_files)
David James8c846492011-01-25 17:07:29 -0800392
Mike Frysinger9e979b92012-11-29 02:55:09 -0500393 def _UploadSdkTarball(self, board_path, url_suffix, version, prepackaged,
394 toolchain_tarballs, toolchain_upload_path):
395 """Upload a tarball of the sdk at the specified path to Google Storage.
David James8fa34ea2011-04-15 13:00:20 -0700396
397 Args:
398 board_path: The path to the board dir.
399 url_suffix: The remote subdirectory where we should upload the packages.
Zdenek Behan5ad96c02011-06-23 01:04:06 +0200400 version: The version of the board.
Zdenek Behan62a57792012-08-31 15:09:08 +0200401 prepackaged: If given, a tarball that has been packaged outside of this
402 script and should be used.
Mike Frysinger9e979b92012-11-29 02:55:09 -0500403 toolchain_tarballs: List of toolchain tarballs to upload.
404 toolchain_upload_path: Path under the bucket to place toolchain tarballs.
David James8fa34ea2011-04-15 13:00:20 -0700405 """
406 remote_location = '%s/%s' % (self._upload_location.rstrip('/'), url_suffix)
407 assert remote_location.startswith('gs://')
Zdenek Behan86c15e92012-10-13 00:55:47 +0200408 boardname = os.path.basename(board_path.rstrip('/'))
409 # We do not upload non SDK board tarballs,
410 assert boardname == constants.CHROOT_BUILDER_BOARD
411 assert prepackaged is not None
Zdenek Behan62a57792012-08-31 15:09:08 +0200412
Zdenek Behan86c15e92012-10-13 00:55:47 +0200413 version_str = version[len('chroot-'):]
Mike Frysinger8e727a32013-01-16 16:57:53 -0500414 remote_tarfile = toolchain.GetSdkURL(
415 for_gsutil=True, suburl='cros-sdk-%s.tar.xz' % (version_str,))
Zdenek Behan86c15e92012-10-13 00:55:47 +0200416 # For SDK, also upload the manifest which is guaranteed to exist
417 # by the builderstage.
418 _GsUpload(prepackaged + '.Manifest', remote_tarfile + '.Manifest',
419 self._acl)
420 _GsUpload(prepackaged, remote_tarfile, self._acl)
421
Mike Frysinger9e979b92012-11-29 02:55:09 -0500422 # Post the toolchain tarballs too.
423 for tarball in toolchain_tarballs:
424 target, local_path = tarball.split(':')
425 suburl = toolchain_upload_path % {'target': target}
426 remote_path = toolchain.GetSdkURL(for_gsutil=True, suburl=suburl)
427 _GsUpload(local_path, remote_path, self._acl)
428
Zdenek Behan86c15e92012-10-13 00:55:47 +0200429 # Finally, also update the pointer to the latest SDK on which polling
430 # scripts rely.
David James4bc13702013-03-26 08:08:04 -0700431 with osutils.TempDir() as tmpdir:
Zdenek Behan86c15e92012-10-13 00:55:47 +0200432 pointerfile = os.path.join(tmpdir, 'cros-sdk-latest.conf')
Mike Frysinger8e727a32013-01-16 16:57:53 -0500433 remote_pointerfile = toolchain.GetSdkURL(for_gsutil=True,
434 suburl='cros-sdk-latest.conf')
Zdenek Behan86c15e92012-10-13 00:55:47 +0200435 osutils.WriteFile(pointerfile, 'LATEST_SDK="%s"' % version_str)
436 _GsUpload(pointerfile, remote_pointerfile, self._acl)
Zdenek Behan33a34112012-09-10 21:07:51 +0200437
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700438 def _GetTargets(self):
439 """Retuns the list of targets to use."""
440 targets = self._slave_targets[:]
441 if self._target:
442 targets.append(self._target)
443
444 return targets
445
446 def SyncHostPrebuilts(self, version, key, git_sync, sync_binhost_conf):
David Jamesc0f158a2011-02-22 16:07:29 -0800447 """Synchronize host prebuilt files.
David James05bcb2b2011-02-09 09:25:47 -0800448
David Jamesc0f158a2011-02-22 16:07:29 -0800449 This function will sync both the standard host packages, plus the host
450 packages associated with all targets that have been "setup" with the
451 current host's chroot. For instance, if this host has been used to build
452 x86-generic, it will sync the host packages associated with
453 'i686-pc-linux-gnu'. If this host has also been used to build arm-generic,
454 it will also sync the host packages associated with
455 'armv7a-cros-linux-gnueabi'.
David James05bcb2b2011-02-09 09:25:47 -0800456
David Jamesc0f158a2011-02-22 16:07:29 -0800457 Args:
David Jamesc0f158a2011-02-22 16:07:29 -0800458 version: A unique string, intended to be included in the upload path,
459 which identifies the version number of the uploaded prebuilts.
460 key: The variable key to update in the git file.
461 git_sync: If set, update make.conf of target to reference the latest
462 prebuilt packages generated here.
463 sync_binhost_conf: If set, update binhost config file in
464 chromiumos-overlay for the host.
465 """
David Jamese2488642011-11-14 16:15:20 -0800466 # Slave boards are listed before the master board so that the master board
467 # takes priority (i.e. x86-generic preflight host prebuilts takes priority
468 # over preflight host prebuilts from other builders.)
469 binhost_urls = []
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700470 for target in self._GetTargets():
David James4058b0d2011-12-08 21:24:50 -0800471 url_suffix = _REL_HOST_PATH % {'version': version,
472 'host_arch': _HOST_ARCH,
473 'target': target}
David Jamese2488642011-11-14 16:15:20 -0800474 packages_url_suffix = '%s/packages' % url_suffix.rstrip('/')
David James05bcb2b2011-02-09 09:25:47 -0800475
Mike Frysinger86509232014-05-24 13:18:37 -0400476 if self._target == target and not self._skip_upload and not self._dryrun:
David Jamese2488642011-11-14 16:15:20 -0800477 # Upload prebuilts.
478 package_path = os.path.join(self._build_path, _HOST_PACKAGES_PATH)
479 self._UploadPrebuilt(package_path, packages_url_suffix)
David James8ece7ee2011-06-29 16:02:30 -0700480
David Jamese2488642011-11-14 16:15:20 -0800481 # Record URL where prebuilts were uploaded.
482 binhost_urls.append('%s/%s/' % (self._binhost_base_url.rstrip('/'),
483 packages_url_suffix.rstrip('/')))
484
David James20b2b6f2011-11-18 15:11:58 -0800485 binhost = ' '.join(binhost_urls)
David James8ece7ee2011-06-29 16:02:30 -0700486 if git_sync:
487 git_file = os.path.join(self._build_path,
David James4058b0d2011-12-08 21:24:50 -0800488 _PREBUILT_MAKE_CONF[_HOST_ARCH])
Mike Frysinger86509232014-05-24 13:18:37 -0400489 RevGitFile(git_file, {key: binhost}, dryrun=self._dryrun)
David James8ece7ee2011-06-29 16:02:30 -0700490 if sync_binhost_conf:
David James32b0b2f2011-07-13 20:56:50 -0700491 binhost_conf = os.path.join(self._build_path, self._binhost_conf_dir,
David James4058b0d2011-12-08 21:24:50 -0800492 'host', '%s-%s.conf' % (_HOST_ARCH, key))
David Jamese2488642011-11-14 16:15:20 -0800493 UpdateBinhostConfFile(binhost_conf, key, binhost)
David Jamesc0f158a2011-02-22 16:07:29 -0800494
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700495 def SyncBoardPrebuilts(self, version, key, git_sync, sync_binhost_conf,
Mike Frysinger9e979b92012-11-29 02:55:09 -0500496 upload_board_tarball, prepackaged_board,
497 toolchain_tarballs, toolchain_upload_path):
David Jamesc0f158a2011-02-22 16:07:29 -0800498 """Synchronize board prebuilt files.
499
500 Args:
David Jamesc0f158a2011-02-22 16:07:29 -0800501 version: A unique string, intended to be included in the upload path,
502 which identifies the version number of the uploaded prebuilts.
503 key: The variable key to update in the git file.
504 git_sync: If set, update make.conf of target to reference the latest
505 prebuilt packages generated here.
506 sync_binhost_conf: If set, update binhost config file in
507 chromiumos-overlay for the current board.
David James8fa34ea2011-04-15 13:00:20 -0700508 upload_board_tarball: Include a tarball of the board in our upload.
Zdenek Behan62a57792012-08-31 15:09:08 +0200509 prepackaged_board: A tarball of the board built outside of this script.
Mike Frysinger9e979b92012-11-29 02:55:09 -0500510 toolchain_tarballs: A list of toolchain tarballs to upload.
511 toolchain_upload_path: Path under the bucket to place toolchain tarballs.
David Jamesc0f158a2011-02-22 16:07:29 -0800512 """
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700513 for target in self._GetTargets():
David Jamese2488642011-11-14 16:15:20 -0800514 board_path = os.path.join(self._build_path,
David James4058b0d2011-12-08 21:24:50 -0800515 _BOARD_PATH % {'board': target.board_variant})
David Jamese2488642011-11-14 16:15:20 -0800516 package_path = os.path.join(board_path, 'packages')
David James4058b0d2011-12-08 21:24:50 -0800517 url_suffix = _REL_BOARD_PATH % {'target': target, 'version': version}
David Jamese2488642011-11-14 16:15:20 -0800518 packages_url_suffix = '%s/packages' % url_suffix.rstrip('/')
David James8fa34ea2011-04-15 13:00:20 -0700519
Matt Tennante8179042013-10-01 15:47:32 -0700520 # Process the target board differently if it is the main --board.
Mike Frysinger86509232014-05-24 13:18:37 -0400521 if self._target == target and not self._skip_upload and not self._dryrun:
Matt Tennante8179042013-10-01 15:47:32 -0700522 # This strips "chroot" prefix because that is sometimes added as the
523 # --prepend-version argument (e.g. by chromiumos-sdk bot).
524 # TODO(build): Clean it up to be less hard-coded.
Mike Frysinger9e979b92012-11-29 02:55:09 -0500525 version_str = version[len('chroot-'):]
526
David Jamese2488642011-11-14 16:15:20 -0800527 # Upload board tarballs in the background.
528 if upload_board_tarball:
Mike Frysinger9e979b92012-11-29 02:55:09 -0500529 if toolchain_upload_path:
530 toolchain_upload_path %= {'version': version_str}
531 tar_process = multiprocessing.Process(
532 target=self._UploadSdkTarball,
533 args=(board_path, url_suffix, version, prepackaged_board,
534 toolchain_tarballs, toolchain_upload_path))
David Jamese2488642011-11-14 16:15:20 -0800535 tar_process.start()
David James8fa34ea2011-04-15 13:00:20 -0700536
David Jamese2488642011-11-14 16:15:20 -0800537 # Upload prebuilts.
538 self._UploadPrebuilt(package_path, packages_url_suffix)
David James8fa34ea2011-04-15 13:00:20 -0700539
David Jamese2488642011-11-14 16:15:20 -0800540 # Make sure we finished uploading the board tarballs.
541 if upload_board_tarball:
542 tar_process.join()
543 assert tar_process.exitcode == 0
544 # TODO(zbehan): This should be done cleaner.
Zdenek Behan33a34112012-09-10 21:07:51 +0200545 if target.board == constants.CHROOT_BUILDER_BOARD:
David Jamese2488642011-11-14 16:15:20 -0800546 sdk_conf = os.path.join(self._build_path, self._binhost_conf_dir,
Mike Frysinger5b34d732013-01-17 15:11:58 -0500547 'host/sdk_version.conf')
548 sdk_settings = {
Mike Frysinger9e979b92012-11-29 02:55:09 -0500549 'SDK_LATEST_VERSION': version_str,
550 'TC_PATH': toolchain_upload_path,
Mike Frysinger5b34d732013-01-17 15:11:58 -0500551 }
Mike Frysinger86509232014-05-24 13:18:37 -0400552 RevGitFile(sdk_conf, sdk_settings, dryrun=self._dryrun)
David Jamesc0f158a2011-02-22 16:07:29 -0800553
David Jamese2488642011-11-14 16:15:20 -0800554 # Record URL where prebuilts were uploaded.
555 url_value = '%s/%s/' % (self._binhost_base_url.rstrip('/'),
556 packages_url_suffix.rstrip('/'))
557
558 if git_sync:
David James4058b0d2011-12-08 21:24:50 -0800559 git_file = DeterminePrebuiltConfFile(self._build_path, target)
Mike Frysinger86509232014-05-24 13:18:37 -0400560 RevGitFile(git_file, {key: url_value}, dryrun=self._dryrun)
Matt Tennante8179042013-10-01 15:47:32 -0700561
David Jamese2488642011-11-14 16:15:20 -0800562 if sync_binhost_conf:
Matt Tennante8179042013-10-01 15:47:32 -0700563 # Update the binhost configuration file in git.
David Jamese2488642011-11-14 16:15:20 -0800564 binhost_conf = os.path.join(self._build_path, self._binhost_conf_dir,
David James4058b0d2011-12-08 21:24:50 -0800565 'target', '%s-%s.conf' % (target, key))
David Jamese2488642011-11-14 16:15:20 -0800566 UpdateBinhostConfFile(binhost_conf, key, url_value)
David James05bcb2b2011-02-09 09:25:47 -0800567
568
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700569def _AddSlaveBoard(_option, _opt_str, value, parser):
570 """Callback that adds a slave board to the list of slave targets."""
David James4058b0d2011-12-08 21:24:50 -0800571 parser.values.slave_targets.append(BuildTarget(value))
572
573
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700574def _AddSlaveProfile(_option, _opt_str, value, parser):
575 """Callback that adds a slave profile to the list of slave targets."""
David James4058b0d2011-12-08 21:24:50 -0800576 if not parser.values.slave_targets:
Mike Frysinger86509232014-05-24 13:18:37 -0400577 parser.error('Must specify --slave-board before --slave-profile')
David James4058b0d2011-12-08 21:24:50 -0800578 if parser.values.slave_targets[-1].profile is not None:
Mike Frysinger86509232014-05-24 13:18:37 -0400579 parser.error('Cannot specify --slave-profile twice for same board')
David James4058b0d2011-12-08 21:24:50 -0800580 parser.values.slave_targets[-1].profile = value
581
582
Mike Frysinger86509232014-05-24 13:18:37 -0400583def ParseOptions(argv):
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700584 """Returns options given by the user and the target specified.
585
Mike Frysinger86509232014-05-24 13:18:37 -0400586 Args:
587 argv: The args to parse.
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 """
Mike Frysinger86509232014-05-24 13:18:37 -0400593 parser = commandline.OptionParser()
David James8c846492011-01-25 17:07:29 -0800594 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.')
Mike Frysinger86509232014-05-24 13:18:37 -0400667 parser.add_option('-n', '--dry-run', dest='dryrun',
David James27fa7d12011-06-29 17:24:14 -0700668 action='store_true', default=False,
669 help='Don\'t push or upload prebuilts.')
David James8c846492011-01-25 17:07:29 -0800670
Mike Frysinger86509232014-05-24 13:18:37 -0400671 options, args = parser.parse_args(argv)
David James8c846492011-01-25 17:07:29 -0800672 if not options.build_path:
Mike Frysinger86509232014-05-24 13:18:37 -0400673 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:
Mike Frysinger86509232014-05-24 13:18:37 -0400675 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:
Mike Frysinger86509232014-05-24 13:18:37 -0400677 parser.error('If you are using --skip-upload, you must specify a '
678 'version number using --set-version.')
David James9417f272011-05-26 13:24:47 -0700679 if args:
Mike Frysinger86509232014-05-24 13:18:37 -0400680 parser.error('invalid arguments passed to upload_prebuilts: %r' % args)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700681
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700682 target = None
683 if options.board:
684 target = BuildTarget(options.board, options.profile)
685
686 if target in options.slave_targets:
Mike Frysinger86509232014-05-24 13:18:37 -0400687 parser.error('--board/--profile must not also be a slave target.')
David Jamese2488642011-11-14 16:15:20 -0800688
David James4058b0d2011-12-08 21:24:50 -0800689 if len(set(options.slave_targets)) != len(options.slave_targets):
Mike Frysinger86509232014-05-24 13:18:37 -0400690 parser.error('--slave-boards must not have duplicates.')
David Jamese2488642011-11-14 16:15:20 -0800691
David James4058b0d2011-12-08 21:24:50 -0800692 if options.slave_targets and options.git_sync:
Mike Frysinger86509232014-05-24 13:18:37 -0400693 parser.error('--slave-boards is not compatible with --git-sync')
David Jamese2488642011-11-14 16:15:20 -0800694
David James8ece7ee2011-06-29 16:02:30 -0700695 if (options.upload_board_tarball and options.skip_upload and
696 options.board == 'amd64-host'):
Mike Frysinger86509232014-05-24 13:18:37 -0400697 parser.error('--skip-upload is not compatible with '
698 '--upload-board-tarball and --board=amd64-host')
David James8fa34ea2011-04-15 13:00:20 -0700699
David James8ece7ee2011-06-29 16:02:30 -0700700 if (options.upload_board_tarball and not options.skip_upload and
701 not options.upload.startswith('gs://')):
Mike Frysinger86509232014-05-24 13:18:37 -0400702 parser.error('--upload-board-tarball only works with gs:// URLs.\n'
703 '--upload must be a gs:// URL.')
David James8fa34ea2011-04-15 13:00:20 -0700704
Zdenek Behan86c15e92012-10-13 00:55:47 +0200705 if options.upload_board_tarball and options.prepackaged_tarball is None:
Mike Frysinger86509232014-05-24 13:18:37 -0400706 parser.error('--upload-board-tarball requires --prepackaged-tarball')
Zdenek Behan86c15e92012-10-13 00:55:47 +0200707
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700708 if options.private:
709 if options.sync_host:
Mike Frysinger86509232014-05-24 13:18:37 -0400710 parser.error('--private and --sync-host/-s cannot be specified '
711 'together; we do not support private host prebuilts')
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700712
David James8ece7ee2011-06-29 16:02:30 -0700713 if not options.upload or not options.upload.startswith('gs://'):
Mike Frysinger86509232014-05-24 13:18:37 -0400714 parser.error('--private is only valid for gs:// URLs; '
715 '--upload must be a gs:// URL.')
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700716
717 if options.binhost_base_url != _BINHOST_BASE_URL:
Mike Frysinger86509232014-05-24 13:18:37 -0400718 parser.error('when using --private the --binhost-base-url '
719 'is automatically derived.')
David James27fa7d12011-06-29 17:24:14 -0700720
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700721 return options, target
David Jamesc0f158a2011-02-22 16:07:29 -0800722
Mike Frysingercc838832014-05-24 13:10:30 -0400723
Mike Frysinger86509232014-05-24 13:18:37 -0400724def main(argv):
David Jamesdb401072011-06-10 12:17:16 -0700725 # Set umask to a sane value so that files created as root are readable.
Mike Frysinger60ec1012013-10-21 00:11:10 -0400726 os.umask(0o22)
David Jamesdb401072011-06-10 12:17:16 -0700727
Mike Frysinger86509232014-05-24 13:18:37 -0400728 options, target = ParseOptions(argv)
David Jamesc0f158a2011-02-22 16:07:29 -0800729
David James05bcb2b2011-02-09 09:25:47 -0800730 # Calculate a list of Packages index files to compare against. Whenever we
731 # upload a package, we check to make sure it's not already stored in one of
732 # the packages files we uploaded. This list of packages files might contain
733 # both board and host packages.
David Jamesce093af2011-02-23 15:21:58 -0800734 pkg_indexes = _GrabAllRemotePackageIndexes(options.previous_binhost_url)
David James8c846492011-01-25 17:07:29 -0800735
David James8ece7ee2011-06-29 16:02:30 -0700736 if options.set_version:
737 version = options.set_version
738 else:
739 version = GetVersion()
Matt Tennante8179042013-10-01 15:47:32 -0700740
David Jamesc0f158a2011-02-22 16:07:29 -0800741 if options.prepend_version:
742 version = '%s-%s' % (options.prepend_version, version)
743
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700744 acl = 'public-read'
745 binhost_base_url = options.binhost_base_url
746
David Jamesadd21432013-05-21 10:04:07 -0700747 if options.private:
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700748 binhost_base_url = options.upload
David Jamesadd21432013-05-21 10:04:07 -0700749 if target:
Peter Mayo950e41a2014-02-06 21:07:33 +0000750 board_path = GetBoardOverlay(options.build_path, target)
David Jamesadd21432013-05-21 10:04:07 -0700751 acl = os.path.join(board_path, _GOOGLESTORAGE_ACL_FILE)
Scott Zawalskiab1bed32011-03-16 15:24:24 -0700752
753 uploader = PrebuiltUploader(options.upload, acl, binhost_base_url,
David James615e5b52011-06-03 11:10:15 -0700754 pkg_indexes, options.build_path,
David James27fa7d12011-06-29 17:24:14 -0700755 options.packages, options.skip_upload,
Mike Frysinger86509232014-05-24 13:18:37 -0400756 options.binhost_conf_dir, options.dryrun,
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700757 target, options.slave_targets)
David Jamesc0f158a2011-02-22 16:07:29 -0800758
David James8c846492011-01-25 17:07:29 -0800759 if options.sync_host:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700760 uploader.SyncHostPrebuilts(version, options.key, options.git_sync,
761 options.sync_binhost_conf)
David James8c846492011-01-25 17:07:29 -0800762
Chris Sosa62c8ff52012-06-04 15:03:12 -0700763 if options.board or options.slave_targets:
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700764 uploader.SyncBoardPrebuilts(version, options.key, options.git_sync,
765 options.sync_binhost_conf,
Zdenek Behan62a57792012-08-31 15:09:08 +0200766 options.upload_board_tarball,
Mike Frysinger9e979b92012-11-29 02:55:09 -0500767 options.prepackaged_tarball,
768 options.toolchain_tarballs,
769 options.toolchain_upload_path)