diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index b2e3d3d9..496b1f19 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -14,6 +14,16 @@ jobs: environment: release runs-on: ubuntu-20.04 steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 + + - name: Check if running on main + if: github.ref != 'refs/heads/main' + # we are using the following flag when running `cosign blob-verify` for checksum signature verification: + # --certificate-identity-regexp "https://github.com/anchore/.github/workflows/release.yaml@refs/heads/main" + # if we are not on the main branch, the signature will not be verifiable since the suffix requires the main branch + # at the time of when the OIDC token was issued on the Github Actions runner. + run: echo "This can only be run on the main branch otherwise releases produced will not be verifiable with cosign" && exit 1 + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 - name: Check if pinned syft is a release version diff --git a/.github/workflows/validations.yaml b/.github/workflows/validations.yaml index 97cb1680..5921ce82 100644 --- a/.github/workflows/validations.yaml +++ b/.github/workflows/validations.yaml @@ -177,6 +177,9 @@ jobs: needs: [Build-Snapshot-Artifacts] runs-on: macos-latest steps: + - name: Install Cosign + uses: sigstore/cosign-installer@v3.5.0 + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6 - name: Download snapshot build diff --git a/README.md b/README.md index ef93b2b5..86f50104 100644 --- a/README.md +++ b/README.md @@ -60,12 +60,10 @@ If you encounter an issue, please [let us know using the issue tracker](https:// ```bash curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin ``` - -You can also choose another destination directory and release version for the installation. The destination directory doesn't need to be `/usr/local/bin`, it just needs to be a location found in the user's PATH and writable by the user that's installing Grype. - -``` -curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b -``` +Install script options: +- `-b`: Specify a custom installation directory (defaults to `./bin`) +- `-d`: More verbose logging levels (`-d` for debug, `-dd` for trace) +- `-v`: Verify the signature of the downloaded artifact before installation (requires [`cosign`](https://github.com/sigstore/cosign) to be installed) ### Chocolatey diff --git a/install.sh b/install.sh index 623b0045..303bf473 100755 --- a/install.sh +++ b/install.sh @@ -2,34 +2,26 @@ # note: we require errors to propagate (don't set -e) set -u -PROJECT_NAME="grype" +PROJECT_NAME=grype OWNER=anchore REPO="${PROJECT_NAME}" GITHUB_DOWNLOAD_PREFIX=https://github.com/${OWNER}/${REPO}/releases/download INSTALL_SH_BASE_URL=https://raw.githubusercontent.com/${OWNER}/${PROJECT_NAME} PROGRAM_ARGS=$@ +# signature verification options + +# the location to the cosign binary (allowed to be overridden by the user) +COSIGN_BINARY=${COSIGN_BINARY:-cosign} +VERIFY_SIGN=false +# this is the earliest tag in the repo where cosign sign-blob was introduced in the release process (see the goreleaser config) +VERIFY_SIGN_SUPPORTED_VERSION=v0.72.0 +# this is the earliest tag in the repo where the -v flag was introduced to this install.sh script +VERIFY_SIGN_FLAG_VERSION=v0.79.0 + # do not change the name of this parameter (this must always be backwards compatible) DOWNLOAD_TAG_INSTALL_SCRIPT=${DOWNLOAD_TAG_INSTALL_SCRIPT:-true} -# -# usage [script-name] -# -usage() ( - this=$1 - cat </dev/null | tr '\t' ' ' | cut -d ' ' -f 1) + target_basename=${target##*/} + want=$(grep "${target_basename}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1) if [ -z "$want" ]; then - log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'" + log_err "hash_sha256_verify unable to find checksum for '${target}' in '${checksums}'" return 1 fi - got=$(hash_sha256 "$TARGET") + got=$(hash_sha256 "$target") if [ "$want" != "$got" ]; then - log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got" + log_err "hash_sha256_verify checksum for '$target' did not verify ${want} vs $got" return 1 fi ) @@ -358,28 +350,69 @@ github_release_tag() ( echo "$tag" ) +# github_release_asset_url [release-url-prefix] [name] [version] [output-dir] [filename] +# +# outputs the url to the release asset +# +github_release_asset_url() ( + download_url="$1" + name="$2" + version="$3" + filename="$4" + + complete_filename="${name}_${version}_${filename}" + complete_url="${download_url}/${complete_filename}" + + echo "${complete_url}" +) + +# download_github_release_checksums_files [release-url-prefix] [name] [version] [output-dir] [filename] +# +# outputs path to the downloaded checksums related file +# +download_github_release_checksums_files() ( + download_url="$1" + name="$2" + version="$3" + output_dir="$4" + filename="$5" + + log_trace "download_github_release_checksums_files(url=${download_url}, name=${name}, version=${version}, output_dir=${output_dir}, filename=${filename})" + + complete_filename="${name}_${version}_${filename}" + complete_url=$(github_release_asset_url "${download_url}" "${name}" "${version}" "${filename}") + output_path="${output_dir}/${complete_filename}" + + http_download "${output_path}" "${complete_url}" "" + asset_file_exists "${output_path}" + + log_trace "download_github_release_checksums_files() returned '${output_path}' for file '${complete_filename}'" + + echo "${output_path}" +) + # download_github_release_checksums [release-url-prefix] [name] [version] [output-dir] # # outputs path to the downloaded checksums file # download_github_release_checksums() ( - download_url="$1" - name="$2" - version="$3" - output_dir="$4" + download_github_release_checksums_files "$@" "checksums.txt" +) - log_trace "download_github_release_checksums(url=${download_url}, name=${name}, version=${version}, output_dir=${output_dir})" +# github_release_checksums_sig_url [release-url-prefix] [name] [version] +# +# outputs the url to the release checksums signature file +# +github_release_checksums_sig_url() ( + github_release_asset_url "$@" "checksums.txt.sig" +) - checksum_filename=${name}_${version}_checksums.txt - checksum_url=${download_url}/${checksum_filename} - output_path="${output_dir}/${checksum_filename}" - - http_download "${output_path}" "${checksum_url}" "" - asset_file_exists "${output_path}" - - log_trace "download_github_release_checksums() returned '${output_path}'" - - echo "${output_path}" +# github_release_checksums_cert_url [release-url-prefix] [name] [version] +# +# outputs the url to the release checksums certificate file +# +github_release_checksums_cert_url() ( + github_release_asset_url "$@" "checksums.txt.pem" ) # search_for_asset [checksums-file-path] [name] [os] [arch] [format] @@ -535,7 +568,10 @@ download_and_install_asset() ( format="$8" binary="$9" - asset_filepath=$(download_asset "${download_url}" "${download_path}" "${name}" "${os}" "${arch}" "${version}" "${format}") + if ! asset_filepath=$(download_asset "${download_url}" "${download_path}" "${name}" "${os}" "${arch}" "${version}" "${format}"); then + log_err "could not download asset for os='${os}' arch='${arch}' format='${format}'" + return 1 + fi # don't continue if we couldn't download an asset if [ -z "${asset_filepath}" ]; then @@ -546,6 +582,36 @@ download_and_install_asset() ( install_asset "${asset_filepath}" "${install_path}" "${binary}" ) +# verify_sign [checksums-file-path] [certificate-reference] [signature-reference] [version] +# +# attempts verify the signature of the checksums file from the release workflow in Github Actions run against the main branch. +# +verify_sign() { + checksums_file=$1 + cert_reference=$2 + sig_reference=$3 + + log_trace "verifying artifact $1" + + log_file=$(mktemp) + + ${COSIGN_BINARY} \ + verify-blob "$checksums_file" \ + --certificate "$cert_reference" \ + --signature "$sig_reference" \ + --certificate-identity "https://github.com/${OWNER}/${REPO}/.github/workflows/release.yaml@refs/heads/main" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" > "${log_file}" 2>&1 + + if [ $? -ne 0 ]; then + log_err "$(cat "${log_file}")" + rm -f "${log_file}" + return 1 + fi + + rm -f "${log_file}" +} + + # download_asset [release-url-prefix] [download-path] [name] [os] [arch] [version] [format] [binary] # # outputs the path to the downloaded asset asset_filepath @@ -572,6 +638,20 @@ download_asset() ( return 1 fi + if [ "$VERIFY_SIGN" = true ]; then + checksum_sig_file_url=$(github_release_checksums_sig_url "${download_url}" "${name}" "${version}") + log_trace "checksums signature url: ${checksum_sig_file_url}" + + checksums_cert_file_url=$(github_release_checksums_cert_url "${download_url}" "${name}" "${version}") + log_trace "checksums certificate url: ${checksums_cert_file_url}" + + if ! verify_sign "${checksums_filepath}" "${checksums_cert_file_url}" "${checksum_sig_file_url}"; then + log_err "signature verification failed" + return 1 + fi + log_info "signature verification succeeded" + fi + asset_url="${download_url}/${asset_filename}" asset_filepath="${destination}/${asset_filename}" http_download "${asset_filepath}" "${asset_url}" "" @@ -609,6 +689,79 @@ install_asset() ( install "${archive_dir}/${binary}" "${destination}/" ) +# compare two semver strings. Returns 0 if version1 >= version2, 1 otherwise. +# Note: pre-release (-) and metadata (+) are not supported. +compare_semver() { + # remove leading 'v' if present + version1=${1#v} + version2=${2#v} + + IFS=. read -r major1 minor1 patch1 <= '$VERIFY_SIGN_SUPPORTED_VERSION')" + log_err "aborting installation" + return 1 + else + log_trace "${PROJECT_NAME} release '$version' supports signature verification (>= '$VERIFY_SIGN_SUPPORTED_VERSION')" + fi + + # will invoking an earlier version of this script work (considering the -v flag)? + if ! compare_semver "$version" "$VERIFY_SIGN_FLAG_VERSION"; then + # the -v argument did not always exist, so we cannot be guaranteed that invoking an earlier version of this script + # will work (error with "illegal option -v"). However, the user requested signature verification, so we will + # attempt to install the application with this version of the script (keeping signature verification). + DOWNLOAD_TAG_INSTALL_SCRIPT=false + log_debug "provided version install script does not support -v flag (>= '$VERIFY_SIGN_FLAG_VERSION'), using current script for installation" + else + log_trace "provided version install script supports -v flag (>= '$VERIFY_SIGN_FLAG_VERSION')" + fi + + # check to see if the cosign binary is installed + if is_command "${COSIGN_BINARY}"; then + log_trace "${COSIGN_BINARY} binary is installed" + else + log_err "signature verification is requested but ${COSIGN_BINARY} binary is not installed (see https://docs.sigstore.dev/system_config/installation/ to install it)" + return 1 + fi +} + main() ( # parse arguments @@ -616,7 +769,7 @@ main() ( install_dir=${install_dir:-./bin} # note: never change the program flags or arguments (this must always be backwards compatible) - while getopts "b:dh?x" arg; do + while getopts "b:dvh?x" arg; do case "$arg" in b) install_dir="$OPTARG" ;; d) @@ -628,11 +781,25 @@ main() ( log_set_priority $log_trace_priority fi ;; - h | \?) usage "$0" ;; + v) VERIFY_SIGN=true;; + h | \?) + cat <= version2) + compare_semver "0.32.0" "0.32.0" + assertEquals "0" "$?" "+ versions should equal" + + compare_semver "0.32.1" "0.32.0" + assertEquals "0" "$?" "+ patch version should be greater" + + compare_semver "0.33.0" "0.32.0" + assertEquals "0" "$?" "+ minor version should be greater" + + compare_semver "0.333.0" "0.32.0" + assertEquals "0" "$?" "+ minor version should be greater (different length)" + + compare_semver "00.33.00" "0.032.0" + assertEquals "0" "$?" "+ minor version should be greater (different length reversed)" + + compare_semver "1.0.0" "0.9.9" + assertEquals "0" "$?" "+ major version should be greater" + + compare_semver "v1.0.0" "1.0.0" + assertEquals "0" "$?" "+ can remove leading 'v' from version" + + # negative cases (version1 < version2) + compare_semver "0.32.0" "0.32.1" + assertEquals "1" "$?" "- patch version should be less" + + compare_semver "0.32.7" "0.33.0" + assertEquals "1" "$?" "- minor version should be less" + + compare_semver "00.00032.070" "0.33.0" + assertEquals "1" "$?" "- minor version should be less (different length)" + + compare_semver "0.32.7" "00.0033.000" + assertEquals "1" "$?" "- minor version should be less (different length reversed)" + + compare_semver "1.9.9" "2.0.1" + assertEquals "1" "$?" "- major version should be less" + + compare_semver "1.0.0" "v2.0.0" + assertEquals "1" "$?" "- can remove leading 'v' from version" +} + +run_test_case test_compare_semver + +# ensure that various signature verification pre-requisites are correctly checked for +test_prep_signature_verification() { + # prep_sign_verification [version] + + # we are expecting error messages, which is confusing to look at in passing tests... disable logging for now + log_set_priority -1 + + # backup original values... + OG_COSIGN_BINARY=${COSIGN_BINARY} + + # check the verification path... + VERIFY_SIGN=true + + # release does not support signature verification + prep_signature_verification "0.71.0" + assertEquals "1" "$?" "release does not support signature verification" + + # check that the COSIGN binary exists + COSIGN_BINARY=fake-cosign-that-doesnt-exist + prep_signature_verification "0.80.0" + assertEquals "1" "$?" "cosign binary verification failed" + # restore original values... + COSIGN_BINARY=${OG_COSIGN_BINARY} + + # ignore any failing conditions since we are not verifying the signature + VERIFY_SIGN=false + prep_signature_verification "0.71.0" + assertEquals "0" "$?" "release support verification should not have been triggered" + + COSIGN_BINARY=fake-cosign-that-doesnt-exist + prep_signature_verification "0.80.0" + assertEquals "0" "$?" "cosign binary verification should not have been triggered" + # restore original values... + COSIGN_BINARY=${OG_COSIGN_BINARY} + + # restore logging... + log_set_priority 0 +} + +run_test_case test_prep_signature_verification diff --git a/test/install/Makefile b/test/install/Makefile index d1e8d2aa..e4c74139 100644 --- a/test/install/Makefile +++ b/test/install/Makefile @@ -1,18 +1,22 @@ NAME=grype +# for local testing (not testing within containers) use the binny-managed version of cosign. +# this also means that the user does not need to install cosign on their system to run tests. +COSIGN_BINARY=../../.tool/cosign + IMAGE_NAME=$(NAME)-install.sh-env UBUNTU_IMAGE=$(IMAGE_NAME):ubuntu-20.04 ALPINE_IMAGE=$(IMAGE_NAME):alpine-3.6 -BUSYBOX_IMAGE=busybox:1.36.1-musl +BUSYBOX_IMAGE=$(IMAGE_NAME):busybox-1.36 ENVS=./environments DOCKER_RUN=docker run --rm -t -w /project/test/install -v $(shell pwd)/../../:/project -UNIT=make unit-local +UNIT=make unit-run # acceptance testing is running the current install.sh against the latest release. Note: this could be a problem down # the line if there are breaking changes made that don't align with the latest release (but will be OK with the next -# release) -ACCEPTANCE_CMD=sh -c '../../install.sh -b /usr/local/bin && grype version' +# release). This tests both installing with signature verification and without. +ACCEPTANCE_CMD=sh -c '../../install.sh -v -b /usr/local/bin && grype version && rm /usr/local/bin/grype && ../../install.sh -b /usr/local/bin && grype version' # we also want to test against a previous release to ensure that install.sh defers execution to a former install.sh # this version should be at least as recent as when grype was publishing for darwin arm64 as that is what the github runner uses for osx validation PREVIOUS_RELEASE=v0.60.0 @@ -29,17 +33,22 @@ endef test: unit acceptance .PHONY: ci-test-mac -ci-test-mac: unit-local acceptance-local +ci-test-mac: unit-run acceptance-local # note: do not add acceptance-local to this list .PHONY: acceptance -acceptance: acceptance-ubuntu-20.04 acceptance-alpine-3.6 acceptance-busybox +acceptance: acceptance-ubuntu-20.04 acceptance-alpine-3.6 acceptance-busybox-1.36 .PHONY: unit unit: unit-ubuntu-20.04 .PHONY: unit-local unit-local: + $(call title,unit tests) + @for f in $(shell ls *_test.sh); do echo "Running unit test suite '$${f}'"; bash -c "COSIGN_BINARY=$(COSIGN_BINARY) ./$${f}" || exit 1; done + +.PHONY: unit-run +unit-run: $(call title,unit tests) @for f in $(shell ls *_test.sh); do echo "Running unit test suite '$${f}'"; bash $${f} || exit 1; done @@ -56,7 +65,7 @@ acceptance-previous-release-local: grype version | grep $(shell echo $(PREVIOUS_RELEASE)| tr -d "v") .PHONY: save -save: ubuntu-20.04 alpine-3.6 pull-busybox +save: ubuntu-20.04 alpine-3.6 busybox-1.36 @mkdir cache || true docker image save -o cache/ubuntu-env.tar $(UBUNTU_IMAGE) docker image save -o cache/alpine-env.tar $(ALPINE_IMAGE) @@ -108,17 +117,17 @@ alpine-3.6: # note: busybox by default will not have cacerts, so you will get TLS warnings (we want to test under these conditions) -.PHONY: acceptance-busybox -acceptance-busybox: pull-busybox - $(call title,busybox - acceptance) +.PHONY: acceptance-busybox-1.36 +acceptance-busybox-1.36: busybox-1.36 + $(call title,busybox-1.36 - acceptance) $(DOCKER_RUN) $(BUSYBOX_IMAGE) \ $(ACCEPTANCE_CMD) @echo "\n*** test note: you should see grype spit out a 'x509: certificate signed by unknown authority' error --this is expected ***" -.PHONY: pull-busybox -pull-busybox: - $(call title,busybox - build environment) - docker pull $(BUSYBOX_IMAGE) +.PHONY: busybox-1.36 +busybox-1.36: + $(call title,busybox-1.36 - build environment) + docker build -t $(BUSYBOX_IMAGE) -f $(ENVS)/Dockerfile-busybox-1.36 . ## For CI ######################################################## diff --git a/test/install/environments/Dockerfile-alpine-3.6 b/test/install/environments/Dockerfile-alpine-3.6 index f0a5fcf7..51dc3d0e 100644 --- a/test/install/environments/Dockerfile-alpine-3.6 +++ b/test/install/environments/Dockerfile-alpine-3.6 @@ -1,2 +1,5 @@ -FROM alpine:3.6@sha256:66790a2b79e1ea3e1dabac43990c54aca5d1ddf268d9a5a0285e4167c8b24475 -RUN apk update && apk add python3 wget unzip make ca-certificates +FROM alpine:3.6 +RUN apk update && apk add python3 wget curl unzip make ca-certificates +RUN curl -O -L "https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64" && \ + mv cosign-linux-amd64 /usr/local/bin/cosign && \ + chmod +x /usr/local/bin/cosign diff --git a/test/install/environments/Dockerfile-busybox-1.36 b/test/install/environments/Dockerfile-busybox-1.36 new file mode 100644 index 00000000..e2cf2d72 --- /dev/null +++ b/test/install/environments/Dockerfile-busybox-1.36 @@ -0,0 +1,21 @@ +FROM alpine as certs +RUN apk update && apk add ca-certificates + +# note: using qemu with a multi-arch image results in redirects not working with wget +# so let docker pull the image that matches the hosts architecture first and then pull the correct asset +FROM busybox:1.36.1-musl + +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" = "x86_64" ]; then \ + COSIGN_ARCH="amd64"; \ + elif [ "$ARCH" = "aarch64" ]; then \ + COSIGN_ARCH="arm64"; \ + else \ + echo "Unsupported architecture: $ARCH" && exit 1; \ + fi && \ + echo "Downloading cosign for $COSIGN_ARCH" && \ + wget https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-${COSIGN_ARCH} && \ + mv cosign-linux-${COSIGN_ARCH} /bin/cosign && \ + chmod +x /bin/cosign + +COPY --from=certs /etc/ssl/certs /etc/ssl/certs diff --git a/test/install/environments/Dockerfile-ubuntu-20.04 b/test/install/environments/Dockerfile-ubuntu-20.04 index 07341fc3..25ba0333 100644 --- a/test/install/environments/Dockerfile-ubuntu-20.04 +++ b/test/install/environments/Dockerfile-ubuntu-20.04 @@ -1,2 +1,5 @@ -FROM ubuntu:20.04@sha256:33a5cc25d22c45900796a1aca487ad7a7cb09f09ea00b779e3b2026b4fc2faba +FROM --platform=linux/amd64 ubuntu:20.04@sha256:33a5cc25d22c45900796a1aca487ad7a7cb09f09ea00b779e3b2026b4fc2faba RUN apt update -y && apt install make python3 curl unzip -y +RUN LATEST_VERSION=$(curl https://api.github.com/repos/sigstore/cosign/releases/latest | grep tag_name | cut -d : -f2 | tr -d "v\", ") && \ + curl -O -L "https://github.com/sigstore/cosign/releases/latest/download/cosign_${LATEST_VERSION}_amd64.deb" && \ + dpkg -i cosign_${LATEST_VERSION}_amd64.deb \ No newline at end of file diff --git a/test/install/test-fixtures/assets/invalid/.gitignore b/test/install/test-fixtures/assets/invalid/.gitignore new file mode 100644 index 00000000..96739946 --- /dev/null +++ b/test/install/test-fixtures/assets/invalid/.gitignore @@ -0,0 +1 @@ +!grype_0.78.0_linux_arm64.tar.gz \ No newline at end of file diff --git a/test/install/test-fixtures/assets/invalid/checksums.txt b/test/install/test-fixtures/assets/invalid/checksums.txt new file mode 100644 index 00000000..dbf20a0b --- /dev/null +++ b/test/install/test-fixtures/assets/invalid/checksums.txt @@ -0,0 +1,15 @@ +cb4f335e106532b927dac14d4857b7be2333ec1b8bd2aea82be3f9112bb2728f grype_0.78.0_darwin_amd64.tar.gz +51249ee801b41272218252af2c72a644a7ef037b0b27d7b0eae3b55361e82cf6 grype_0.78.0_darwin_arm64.tar.gz +cc3cf4fcc856898fcd05ba2b8590de06e380b958fea5957b0a3e4eff5e8aeeaf grype_0.78.0_linux_amd64.deb +3a9af0f08d1aaf15853f8292be0aa896639e09328416a50d5deaefef894bab61 grype_0.78.0_linux_amd64.rpm +6037fd3763b6112302b98db559bb5390fbb06f0011c0585a4be03ca851daa838 grype_0.78.0_linux_amd64.tar.gz +0f2e3e07be5b5eb08637ac9071f4b0f95f8b4c7c7ea66592852ca82fea4adb93 grype_0.78.0_linux_arm64.deb +89a7f68676a18eb9dc0b706036dacbfb8b78833ed0950b8c6fa63ac159b93781 grype_0.78.0_linux_arm64.rpm +0d560e860d6f68cf23c8f0df1f5124ef6d3d8d57abb57a0dae3f951b7772822e grype_0.78.0_linux_arm64.tar.gz +7b22795114e27c3d147998edc9e803988d7c987cad2623d7fb1d7bf730b4e176 grype_0.78.0_linux_ppc64le.deb +91813ac66ad2ef761ce9629eb4213988de594abd4cab9148a85d71bfa80f6699 grype_0.78.0_linux_ppc64le.rpm +cb923a08fb9f367410190675f187b6aa5a04c1d538f055700c89c8350b826dcb grype_0.78.0_linux_ppc64le.tar.gz +4beb9d31d61df6212c3f996fc8f33239520eeea083dbe70b0969f23739d44dd1 grype_0.78.0_linux_s390x.deb +28f723777b1a136d2fadbdca0ae5e7e9b26f9bd08114095dbd2898def7e8b0b6 grype_0.78.0_linux_s390x.rpm +6c3e7e54ce40aa33ca5fc774c3be664fb910a99aa77b1e5e3cee77156e8399f4 grype_0.78.0_linux_s390x.tar.gz +31ca5d02a75dbb8f3361ac9836a2384013a67a7d9e2e437cb80e4ddfbd4c7812 grype_0.78.0_windows_amd64.zip diff --git a/test/install/test-fixtures/assets/invalid/grype_0.78.0_linux_arm64.tar.gz b/test/install/test-fixtures/assets/invalid/grype_0.78.0_linux_arm64.tar.gz new file mode 100644 index 00000000..c90127d2 --- /dev/null +++ b/test/install/test-fixtures/assets/invalid/grype_0.78.0_linux_arm64.tar.gz @@ -0,0 +1 @@ +fake archive \ No newline at end of file diff --git a/test/install/test-fixtures/assets/valid/.gitignore b/test/install/test-fixtures/assets/valid/.gitignore new file mode 100644 index 00000000..96739946 --- /dev/null +++ b/test/install/test-fixtures/assets/valid/.gitignore @@ -0,0 +1 @@ +!grype_0.78.0_linux_arm64.tar.gz \ No newline at end of file diff --git a/test/install/test-fixtures/assets/valid/checksums.txt b/test/install/test-fixtures/assets/valid/checksums.txt new file mode 100644 index 00000000..68294b56 --- /dev/null +++ b/test/install/test-fixtures/assets/valid/checksums.txt @@ -0,0 +1,15 @@ +cb4f335e106532b927dac14d4857b7be2333ec1b8bd2aea82be3f9112bb2728f grype_0.78.0_darwin_amd64.tar.gz +51249ee801b41272218252af2c72a644a7ef037b0b27d7b0eae3b55361e82cf6 grype_0.78.0_darwin_arm64.tar.gz +cc3cf4fcc856898fcd05ba2b8590de06e380b958fea5957b0a3e4eff5e8aeeaf grype_0.78.0_linux_amd64.deb +3a9af0f08d1aaf15853f8292be0aa896639e09328416a50d5deaefef894bab61 grype_0.78.0_linux_amd64.rpm +6037fd3763b6112302b98db559bb5390fbb06f0011c0585a4be03ca851daa838 grype_0.78.0_linux_amd64.tar.gz +0f2e3e07be5b5eb08637ac9071f4b0f95f8b4c7c7ea66592852ca82fea4adb93 grype_0.78.0_linux_arm64.deb +89a7f68676a18eb9dc0b706036dacbfb8b78833ed0950b8c6fa63ac159b93781 grype_0.78.0_linux_arm64.rpm +8d57abb57a0dae3ff23c8f0df1f51951b7772822e0d560e860d6f68c24ef6d3d grype_0.78.0_linux_arm64.tar.gz +7b22795114e27c3d147998edc9e803988d7c987cad2623d7fb1d7bf730b4e176 grype_0.78.0_linux_ppc64le.deb +91813ac66ad2ef761ce9629eb4213988de594abd4cab9148a85d71bfa80f6699 grype_0.78.0_linux_ppc64le.rpm +cb923a08fb9f367410190675f187b6aa5a04c1d538f055700c89c8350b826dcb grype_0.78.0_linux_ppc64le.tar.gz +4beb9d31d61df6212c3f996fc8f33239520eeea083dbe70b0969f23739d44dd1 grype_0.78.0_linux_s390x.deb +28f723777b1a136d2fadbdca0ae5e7e9b26f9bd08114095dbd2898def7e8b0b6 grype_0.78.0_linux_s390x.rpm +6c3e7e54ce40aa33ca5fc774c3be664fb910a99aa77b1e5e3cee77156e8399f4 grype_0.78.0_linux_s390x.tar.gz +31ca5d02a75dbb8f3361ac9836a2384013a67a7d9e2e437cb80e4ddfbd4c7812 grype_0.78.0_windows_amd64.zip diff --git a/test/install/test-fixtures/assets/valid/grype_0.78.0_linux_arm64.tar.gz b/test/install/test-fixtures/assets/valid/grype_0.78.0_linux_arm64.tar.gz new file mode 100644 index 00000000..c90127d2 --- /dev/null +++ b/test/install/test-fixtures/assets/valid/grype_0.78.0_linux_arm64.tar.gz @@ -0,0 +1 @@ +fake archive \ No newline at end of file