|
| 1 | +#!/usr/bin/env bash |
| 2 | +set -euo pipefail |
| 3 | + |
| 4 | +DEFAULT_INSTALL_DIR="/usr/local/bin" |
| 5 | +INSTALL_DIR="${INSTALL_DIR:-$DEFAULT_INSTALL_DIR}" |
| 6 | +BASE_URL="https://github.com/anchore/${TOOL}/releases/download/v${VERSION}" |
| 7 | +ARCHIVE="${TOOL}_${VERSION}_linux_${ARCH}.tar.gz" |
| 8 | +CHECKSUMS="${TOOL}_${VERSION}_checksums.txt" |
| 9 | +CHECKSUMS_PEM="${TOOL}_${VERSION}_checksums.txt.pem" |
| 10 | +CHECKSUMS_SIG="${TOOL}_${VERSION}_checksums.txt.sig" |
| 11 | + |
| 12 | +if [ -z "$TOOL" ] |
| 13 | +then |
| 14 | + echo "\$TOOL is NULL" |
| 15 | +fi |
| 16 | +if [ -z "$ARCH" ] |
| 17 | +then |
| 18 | + echo "\$ARCH is NULL" |
| 19 | +fi |
| 20 | +if [ -z "$VERSION" ] |
| 21 | +then |
| 22 | + echo "\$VERSION is NULL" |
| 23 | +fi |
| 24 | + |
| 25 | +usage() { |
| 26 | + cat <<'EOF' |
| 27 | +Usage: install_anchore_tool.sh |
| 28 | +
|
| 29 | +Downloads an Anchore tool (syft or grype) archive and its sigstore bundle to a temporary directory, |
| 30 | +verifies the sigstore bundle following |
| 31 | +https://oss.anchore.com/docs/installation/verification/, |
| 32 | +and installs the Anchore tool binary into INSTALL_DIR (default: /usr/local/bin). |
| 33 | +
|
| 34 | +Environment variables: |
| 35 | + INSTALL_DIR Directory to install the Anchore tool binary into (default: /usr/local/bin) |
| 36 | + VERSION Anchore tool version tag to install |
| 37 | + ARCH Architecture suffix used in the download |
| 38 | + TOOL Anchore tool name, either "syft" or "grype" |
| 39 | +EOF |
| 40 | +} |
| 41 | + |
| 42 | +if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then |
| 43 | + usage |
| 44 | + exit 0 |
| 45 | +fi |
| 46 | + |
| 47 | +for cmd in curl cosign; do |
| 48 | + if ! command -v "$cmd" >/dev/null 2>&1; then |
| 49 | + echo "Error: $cmd is required but not found in PATH" >&2 |
| 50 | + exit 1 |
| 51 | + fi |
| 52 | +done |
| 53 | + |
| 54 | +TMP_DIR="$(mktemp -d)" |
| 55 | +trap 'rm -rf "$TMP_DIR"' EXIT |
| 56 | + |
| 57 | +download() { |
| 58 | + local url="${1}" dest="${2}" |
| 59 | + echo "Downloading ${dest} from ${url} ..." |
| 60 | + curl -fsSL "${url}" -o "${dest}" |
| 61 | +} |
| 62 | +ARCHIVE_PATH="${TMP_DIR}/${ARCHIVE}" |
| 63 | +ALL_CHECKSUMS_PATH="${TMP_DIR}/${CHECKSUMS}" |
| 64 | +CHECKSUM_PATH="${TMP_DIR}/${ARCHIVE}.sha256sum" |
| 65 | +CHECKSUMS_PEM_PATH="${TMP_DIR}/${CHECKSUMS_PEM}" |
| 66 | +CHECKSUMS_SIG_PATH="${TMP_DIR}/${CHECKSUMS_SIG}" |
| 67 | +download "${BASE_URL}/${ARCHIVE}" "${ARCHIVE_PATH}" |
| 68 | +download "${BASE_URL}/${CHECKSUMS}" "${ALL_CHECKSUMS_PATH}" |
| 69 | +download "${BASE_URL}/${CHECKSUMS_PEM}" "${CHECKSUMS_PEM_PATH}" |
| 70 | +download "${BASE_URL}/${CHECKSUMS_SIG}" "${CHECKSUMS_SIG_PATH}" |
| 71 | + |
| 72 | +cosign verify-blob "${ALL_CHECKSUMS_PATH}" \ |
| 73 | + --certificate "${CHECKSUMS_PEM_PATH}" \ |
| 74 | + --signature "${CHECKSUMS_SIG_PATH}" \ |
| 75 | + --certificate-identity-regexp "https://github\.com/anchore/${TOOL}/\.github/workflows/.+" \ |
| 76 | + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" |
| 77 | + |
| 78 | +echo "Sigstore verification passed" |
| 79 | + |
| 80 | +grep "${ARCHIVE}" "${ALL_CHECKSUMS_PATH}" > "${CHECKSUM_PATH}" |
| 81 | + |
| 82 | +cd "${TMP_DIR}" |
| 83 | +sha256sum -c "${CHECKSUM_PATH}" |
| 84 | +echo "Checksum verification passed" |
| 85 | +tar -xzf "${ARCHIVE_PATH}" -C "${TMP_DIR}" |
| 86 | + |
| 87 | +mkdir -p "$INSTALL_DIR" |
| 88 | +install -m 0755 "$TMP_DIR/${TOOL}" "${INSTALL_DIR}/${TOOL}" |
| 89 | + |
| 90 | +echo "${TOOL} ${VERSION} installed to ${INSTALL_DIR}" |
0 commit comments