| #!/bin/bash | |
| # | |
| # Copyright 2022 Google LLC | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # https://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| # Fetches the rust toolchain from cloud storage | |
| PUBLIC_ARTIFACTS_PATH="gs://shodan-public-artifacts" | |
| PUBLIC_ARTIFACTS_URL="https://storage.googleapis.com/shodan-public-artifacts" | |
| function die { | |
| echo "$@" >/dev/stderr | |
| exit 1 | |
| } | |
| function try { | |
| echo "$@" | |
| "$@" || die "Failed to execute '$@': exited with return code $?" | |
| } | |
| function in-dir { | |
| local directory="$1"; shift | |
| local exitcode="" | |
| echo "Entering directory ${directory}" | |
| (cd "$directory" && "$@") | |
| exitcode="$?" | |
| echo "Leaving directory ${directory}" | |
| if [[ "${exitcode}" != "0" ]]; then | |
| die "Failed to execute '$@': exited with return code ${exitcode}" | |
| fi | |
| } | |
| function list-tarballs { | |
| if [[ "$EUID" == 0 ]]; then | |
| die "This script must NOT be run as root." | |
| fi | |
| if ! hash gsutil 2>/dev/null; then | |
| die "Google cloud SDK is not installed." | |
| fi | |
| echo "Available tarballs:" | |
| echo | |
| gsutil ls "${PUBLIC_ARTIFACTS_PATH}/rust_toolchain*.tar.xz" | |
| } | |
| function generate-tarball-name { | |
| local version="$1"; shift | |
| if [[ -z "${version}" ]]; then | |
| die "No version specified." | |
| fi | |
| echo "rust_toolchain_${version}.tar.xz" | |
| } | |
| function get-original-name { | |
| local tarball="$1"; shift | |
| cat "${tarball}.sha256sum" |awk '{ print $2 }' | |
| } | |
| function download-tarball { | |
| local version="$1"; shift | |
| local tarball="$(generate-tarball-name ${version})" | |
| local checksum="${tarball}.sha256sum" | |
| try mkdir -p "${OUT}" | |
| try wget --progress=dot:giga -O "${OUT}/${tarball}" "${PUBLIC_ARTIFACTS_URL}/${tarball}" | |
| try wget -O "${OUT}/${checksum}" "${PUBLIC_ARTIFACTS_URL}/${checksum}" | |
| # Workaround the fact that we use the datestamped version of the filename | |
| # at sha256sum creation time. IOW, "latest" is a symbolic name to make | |
| # fetching easier, so we have to rename the tarball to the original name. | |
| # Conveniently, this also allows us to determine which tarball is currently | |
| # set as the latest in storage. | |
| if [[ "${version}" == "latest" ]]; then | |
| local original_name=$(get-original-name "${OUT}/${tarball}") | |
| try mv "${OUT}/${tarball}" "${OUT}/${original_name}" | |
| try mv "${OUT}/${checksum}" "${OUT}/${original_name}.sha256sum" | |
| tarball="${original_name}" | |
| checksum="${original_name}.sha256sum" | |
| fi | |
| try in-dir "${OUT}" sha256sum -c "${checksum}" | |
| try mkdir -p "${CACHE}" | |
| try tar -C "${CACHE}" -xf "${OUT}/${tarball}" | |
| } | |
| function show-usage { | |
| cat >/dev/stderr <<EOF | |
| Usage: fetch-rust-toolchain.sh <-d|-l> [-v <date|latest>] | |
| Fetches, verifies, and untars Rust toolchain tarballs from upstram cloud storage | |
| into cache/. | |
| Options: | |
| -l | --list List available rust tarballs. Note: this requires the | |
| Google Cloud SDK to be installed and logged in. | |
| -d | --download Download a tarball. If -v is not provided, assumes | |
| "latest". | |
| -v <date|latest> | --version <date|latest> | |
| Download either the tarball of the specified version, or | |
| the latest one from upstream storage. If this option is | |
| not specified, defaults to "latest". | |
| EOF | |
| } | |
| function main { | |
| local usage="Usage: install-rust-toolchain.sh [-d|-l|-v <datestamp>]" | |
| local args=$(getopt -o hdlv: \ | |
| --long help,download,list:,version: \ | |
| -n fetch-rust-toolchain.sh -- "$@") | |
| eval set -- "$args" | |
| local version="latest" | |
| local mode="" | |
| while true; do | |
| case "$1" in | |
| -d|--download) | |
| mode="download" | |
| shift | |
| ;; | |
| -l|--list) | |
| mode="list" | |
| shift | |
| ;; | |
| -v|--version) | |
| version="$2" | |
| shift | |
| shift | |
| ;; | |
| --) | |
| shift | |
| break | |
| ;; | |
| *) | |
| die "${usage}" | |
| ;; | |
| esac | |
| done | |
| case "${mode}" in | |
| list) | |
| list-tarballs | |
| ;; | |
| download) | |
| download-tarball "${version}" | |
| ;; | |
| *) | |
| show-usage | |
| ;; | |
| esac | |
| } | |
| if [[ -z "${ROOTDIR}" || -z "${RUSTDIR}" ]]; then | |
| die "Source build/setup.sh first" | |
| fi | |
| main "$@" |