| #!/bin/bash |
| # Copyright 2018 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # NOTE: This tool must be able to be downloaded and run independently of the |
| # rest of this repo: the manual release processes that use it do not have a |
| # fuchsia checkout. |
| |
| ## usage: fetch-build-artifacts \ |
| ## [-r] [-p <parent_dir>] [-o <out_dir>] [-h] \ |
| ## <buildbucket_id> |
| ## |
| ## Downloads artifacts created by the specified build. |
| ## |
| ## <buildbucket_id> is a large number like '8938070794014050064', which you can |
| ## find on the build results page. This tool accepts an optional leading 'b', |
| ## letting you copy-and-paste the ID component from a URL like |
| ## https://ci.chromium.org/p/fuchsia/builders/luci.fuchsia.ci/garnet-arm64-release-qemu_kvm/b8938011100592458048 |
| ## |
| ## Prerequisites: |
| ## - Install the 'gsutil' tool: |
| ## https://cloud.google.com/storage/docs/gsutil_install |
| ## - Run 'gcloud init'. The default project does not matter, but if you need to |
| ## provide one you can use 'fuchsia-infra'. |
| ## - If you don't have gcloud installed, you can run 'gsutil config' instead. |
| ## - The user must have permission to access the target artifacts in Google |
| ## Cloud Storage (GCS). |
| ## |
| ## Optional arguments: |
| ## -r Indicates that the build ID points to a release build, whose |
| ## artifacts are stored in a special GCS bucket. |
| ## -p The parent directory of the destination build artifact directory: |
| ## see -o. Defaults to "${HOME}/.cache/fuchsia/build-artifacts". |
| ## Mutually exclusive with -o. |
| ## -o The directory to write the artifacts to. Defaults to |
| ## <parent_dir>/<buildbucket_id>. Mutually exclusive with -p. |
| ## -h Prints this help message. |
| |
| set -o errexit |
| set -o nounset |
| set -o pipefail |
| |
| readonly DEFAULT_PARENT_DIR="${HOME}/.cache/fuchsia/build-artifacts" |
| |
| function usage { |
| # Prints lines from this file that begin with ##. |
| sed -n -e 's/^## //p' -e 's/^##$//p' < "${BASH_SOURCE[0]}" |
| } |
| |
| function main { |
| if [[ -z "$(which gsutil)" ]]; then |
| echo "ERROR: Please install gsutil and run 'gcloud init'." |
| echo "See https://cloud.google.com/storage/docs/gsutil_install" |
| return 1 |
| fi |
| |
| local parent_dir='' |
| local out_dir='' |
| local is_release=0 |
| while getopts "rp:o:h" arg; do |
| case ${arg} in |
| r) |
| is_release=1 |
| ;; |
| p) |
| parent_dir="${OPTARG}" |
| ;; |
| o) |
| out_dir="${OPTARG}" |
| ;; |
| *) |
| usage |
| return 1 |
| ;; |
| esac |
| done |
| shift $((${OPTIND} - 1)) |
| |
| if [[ "${parent_dir}" ]] && [[ "${out_dir}" ]]; then |
| echo "ERROR: Cannot specify both -p and -o." |
| usage |
| return 1 |
| fi |
| |
| # Expect exactly one build ID. |
| # TODO(dbort): We could support multiple build IDs if -o isn't specified. |
| if [[ $# -ne 1 ]]; then |
| echo "ERROR: Build ID missing." |
| usage |
| return 1 |
| fi |
| local build_id="$1" |
| |
| # Make sure it's a number, but allow a leading 'b' since some LUCI URLs |
| # tack it onto the build ID component. |
| if [[ ! "${build_id}" =~ ^b?[0-9]+$ ]]; then |
| echo "ERROR: Build ID '${build_id}' is not a number." |
| usage |
| return 1 |
| fi |
| build_id="${build_id#b}" # Remove leading 'b' if present. |
| |
| if [[ -z "${parent_dir}" ]]; then |
| parent_dir="${DEFAULT_PARENT_DIR}" |
| fi |
| |
| if [[ -z "${out_dir}" ]]; then |
| out_dir="${parent_dir}/${build_id}" |
| fi |
| |
| if (( is_release )); then |
| local archive_bucket='fuchsia-release-archive' |
| else |
| local archive_bucket='fuchsia-archive' |
| fi |
| |
| echo "Fetching build ${build_id} to ${out_dir} ..." |
| mkdir -p "${out_dir}" |
| |
| local failed=0 |
| ( |
| set -x # Prints the gsutil command |
| # -m: Download files in parallel |
| # -c: Continue downloading later files even if an earlier one fails |
| # -L: Log file to use for resuming; also avoids re-downloading files |
| gsutil -m cp \ |
| -c \ |
| -L "${out_dir}/.gsutil-cp.log" \ |
| -r \ |
| "gs://${archive_bucket}/builds/${build_id}/*" "${out_dir}" |
| ) || failed=1 |
| |
| if (( failed )); then |
| if (( ! is_release )); then |
| echo "NOTE: If you are trying to download a release build, remember" |
| echo " to specify the '-r' flag." |
| fi |
| return 1 |
| fi |
| |
| echo "Downloaded artifacts to ${out_dir}" |
| echo "DONE" |
| } |
| |
| main "$@" |