mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
Refactor install.sh (#765)
* [wip] get assets based on gh api Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * put install.sh download_asset fn under test Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * put install.sh install_asset fn under test Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * use zip for darwin installs Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * fix install.sh negative test cases Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * allow errors to propagate in install.sh Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * remove exit on error from install.sh tests Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * add more docs around install.sh helpers Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * add integration tests for install.sh Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * add install.sh testing to pipeline Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * add install test cache to CI Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * make colors globally available Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * test download against github release Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * always test release-based install against latest release Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * use better install.sh test names Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
ed1cbf50d9
commit
f38b0b7256
39
.github/workflows/validations.yaml
vendored
39
.github/workflows/validations.yaml
vendored
@ -276,8 +276,30 @@ jobs:
|
||||
name: artifacts
|
||||
path: snapshot
|
||||
|
||||
- name: Run Acceptance Tests (Linux)
|
||||
run: make acceptance-linux
|
||||
- name: Run comparison tests (Linux)
|
||||
run: make compare-linux
|
||||
|
||||
- name: Build key for image cache
|
||||
run: make install-fingerprint
|
||||
|
||||
- name: Restore install.sh test image cache
|
||||
id: install-test-image-cache
|
||||
uses: actions/cache@v2.1.3
|
||||
with:
|
||||
path: ${{ github.workspace }}/test/install/cache
|
||||
key: ${{ runner.os }}-install-test-image-cache-${{ hashFiles('test/install/cache.fingerprint') }}
|
||||
|
||||
- name: Load test image cache
|
||||
if: steps.install-test-image-cache.outputs.cache-hit == 'true'
|
||||
run: make install-test-cache-load
|
||||
|
||||
- name: Run install.sh tests (Linux)
|
||||
run: make install-test
|
||||
|
||||
- name: (cache-miss) Create test image cache
|
||||
if: steps.install-test-image-cache.outputs.cache-hit != 'true'
|
||||
run: make install-test-cache-save
|
||||
|
||||
|
||||
Acceptance-Mac:
|
||||
# Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
|
||||
@ -292,15 +314,18 @@ jobs:
|
||||
name: artifacts
|
||||
path: snapshot
|
||||
|
||||
- name: Restore docker image cache
|
||||
id: go-cache
|
||||
- name: Restore docker image cache for compare testing
|
||||
id: mac-compare-testing-cache
|
||||
uses: actions/cache@v2.1.3
|
||||
with:
|
||||
path: image.tar
|
||||
key: ${{ runner.os }}-${{ hashFiles('test/acceptance/mac.sh') }}
|
||||
key: ${{ runner.os }}-${{ hashFiles('test/compare/mac.sh') }}
|
||||
|
||||
- name: Run Acceptance Tests (Mac)
|
||||
run: make acceptance-mac
|
||||
- name: Run comparison tests (Mac)
|
||||
run: make compare-mac
|
||||
|
||||
- name: Run install.sh tests (Mac)
|
||||
run: make install-test-ci-mac
|
||||
|
||||
Cli-Linux:
|
||||
# Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,6 +18,7 @@ CHANGELOG.md
|
||||
.images
|
||||
.tmp/
|
||||
coverage.txt
|
||||
bin/
|
||||
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
|
||||
@ -32,10 +32,10 @@ The main make tasks for common static analysis and testing are `lint`, `lint-fix
|
||||
for in-depth testing of code in the `cmd/` package (such as testing the proper behavior of application configuration,
|
||||
CLI switches, and glue code before syft library calls).
|
||||
|
||||
- `acceptance`: located within `test/acceptance`, these are smoke-like tests that ensure that application packaging
|
||||
and installation works as expected. For example, during release we provide RPM packages as a download artifact. We
|
||||
also have an accompanying RPM acceptance test that installs the RPM from a snapshot build and ensures the output
|
||||
of a syft invocation matches canned expected output. New acceptance tests should be added for each release artifact
|
||||
- `acceptance`: located within `test/compare` and `test/install`, these are smoke-like tests that ensure that application
|
||||
packaging and installation works as expected. For example, during release we provide RPM packages as a download
|
||||
artifact. We also have an accompanying RPM acceptance test that installs the RPM from a snapshot build and ensures the
|
||||
output of a syft invocation matches canned expected output. New acceptance tests should be added for each release artifact
|
||||
and architecture supported (when possible).
|
||||
|
||||
### Data diversity and freshness assertions
|
||||
|
||||
83
Makefile
83
Makefile
@ -4,8 +4,8 @@ RESULTSDIR = test/results
|
||||
COVER_REPORT = $(RESULTSDIR)/unit-coverage-details.txt
|
||||
COVER_TOTAL = $(RESULTSDIR)/unit-coverage-summary.txt
|
||||
LINTCMD = $(TEMPDIR)/golangci-lint run --tests=false --timeout=2m --config .golangci.yaml
|
||||
ACC_TEST_IMAGE = centos:8.2.2004
|
||||
ACC_DIR = ./test/acceptance
|
||||
COMPARE_TEST_IMAGE = centos:8.2.2004
|
||||
COMPARE_DIR = ./test/compare
|
||||
BOLD := $(shell tput -T linux bold)
|
||||
PURPLE := $(shell tput -T linux setaf 5)
|
||||
GREEN := $(shell tput -T linux setaf 2)
|
||||
@ -47,8 +47,8 @@ ifndef RESULTSDIR
|
||||
$(error RESULTSDIR is not set)
|
||||
endif
|
||||
|
||||
ifndef ACC_DIR
|
||||
$(error ACC_DIR is not set)
|
||||
ifndef COMPARE_DIR
|
||||
$(error COMPARE_DIR is not set)
|
||||
endif
|
||||
|
||||
ifndef DISTDIR
|
||||
@ -70,11 +70,11 @@ endef
|
||||
## Tasks
|
||||
|
||||
.PHONY: all
|
||||
all: clean static-analysis test ## Run all linux-based checks (linting, license check, unit, integration, and linux acceptance tests)
|
||||
all: clean static-analysis test ## Run all linux-based checks (linting, license check, unit, integration, and linux compare tests)
|
||||
@printf '$(SUCCESS)All checks pass!$(RESET)\n'
|
||||
|
||||
.PHONY: test
|
||||
test: unit validate-cyclonedx-schema integration benchmark acceptance-linux cli ## Run all tests (currently unit, integration, linux acceptance, and cli tests)
|
||||
test: unit validate-cyclonedx-schema integration benchmark compare-linux cli ## Run all tests (currently unit, integration, linux compare, and cli tests)
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@ -167,20 +167,42 @@ benchmark: $(RESULTSDIR) ## Run benchmark tests and compare against the baseline
|
||||
show-benchstat:
|
||||
@cat $(RESULTSDIR)/benchstat.txt
|
||||
|
||||
# note: this is used by CI to determine if the install test fixture cache (docker image tars) should be busted
|
||||
install-fingerprint:
|
||||
cd test/install && \
|
||||
make cache.fingerprint
|
||||
|
||||
install-test: $(SNAPSHOTDIR)
|
||||
cd test/install && \
|
||||
make
|
||||
|
||||
install-test-cache-save: $(SNAPSHOTDIR)
|
||||
cd test/install && \
|
||||
make save
|
||||
|
||||
install-test-cache-load: $(SNAPSHOTDIR)
|
||||
cd test/install && \
|
||||
make load
|
||||
|
||||
install-test-ci-mac: $(SNAPSHOTDIR)
|
||||
cd test/install && \
|
||||
make ci-test-mac
|
||||
|
||||
.PHONY: integration
|
||||
integration: ## Run integration tests
|
||||
$(call title,Running integration tests)
|
||||
|
||||
go test -v ./test/integration
|
||||
|
||||
# note: this is used by CI to determine if the integration test fixture cache (docker image tars) should be busted
|
||||
integration-fingerprint:
|
||||
find test/integration/test-fixtures/image-* -type f -exec md5sum {} + | awk '{print $1}' | sort | md5sum | tee test/integration/test-fixtures/cache.fingerprint && echo "$(INTEGRATION_CACHE_BUSTER)" >> test/integration/test-fixtures/cache.fingerprint
|
||||
$(call title,Integration test fixture fingerprint)
|
||||
find test/integration/test-fixtures/image-* -type f -exec md5sum {} + | awk '{print $1}' | sort | tee /dev/stderr | md5sum | tee test/integration/test-fixtures/cache.fingerprint && echo "$(INTEGRATION_CACHE_BUSTER)" >> test/integration/test-fixtures/cache.fingerprint
|
||||
|
||||
.PHONY: java-packages-fingerprint
|
||||
java-packages-fingerprint:
|
||||
@cd syft/pkg/cataloger/java/test-fixtures/java-builds && \
|
||||
make packages.fingerprint
|
||||
$(call title,Java test fixture fingerprint)
|
||||
cd syft/pkg/cataloger/java/test-fixtures/java-builds && \
|
||||
make packages.fingerprint
|
||||
|
||||
.PHONY: fixtures
|
||||
fixtures:
|
||||
@ -212,39 +234,40 @@ $(SNAPSHOTDIR): ## Build snapshot release binaries and packages
|
||||
$(TEMPDIR)/goreleaser release --skip-publish --skip-sign --rm-dist --snapshot --config $(TEMPDIR)/goreleaser.yaml
|
||||
|
||||
# note: we cannot clean the snapshot directory since the pipeline builds the snapshot separately
|
||||
.PHONY: acceptance-mac
|
||||
acceptance-mac: $(RESULTSDIR) $(SNAPSHOTDIR) ## Run acceptance tests on build snapshot binaries and packages (Mac)
|
||||
$(call title,Running acceptance test: Run on Mac)
|
||||
$(ACC_DIR)/mac.sh \
|
||||
.PHONY: compare-mac
|
||||
compare-mac: $(RESULTSDIR) $(SNAPSHOTDIR) ## Run compare tests on build snapshot binaries and packages (Mac)
|
||||
$(call title,Running compare test: Run on Mac)
|
||||
$(COMPARE_DIR)/mac.sh \
|
||||
$(SNAPSHOTDIR) \
|
||||
$(ACC_DIR) \
|
||||
$(ACC_TEST_IMAGE) \
|
||||
$(COMPARE_DIR) \
|
||||
$(COMPARE_TEST_IMAGE) \
|
||||
$(RESULTSDIR)
|
||||
|
||||
# note: we cannot clean the snapshot directory since the pipeline builds the snapshot separately
|
||||
.PHONY: acceptance-linux
|
||||
acceptance-linux: acceptance-test-deb-package-install acceptance-test-rpm-package-install ## Run acceptance tests on build snapshot binaries and packages (Linux)
|
||||
.PHONY: compare-linux
|
||||
compare-linux: compare-test-deb-package-install compare-test-rpm-package-install ## Run compare tests on build snapshot binaries and packages (Linux)
|
||||
|
||||
.PHONY: acceptance-test-deb-package-install
|
||||
acceptance-test-deb-package-install: $(RESULTSDIR) $(SNAPSHOTDIR)
|
||||
$(call title,Running acceptance test: DEB install)
|
||||
$(ACC_DIR)/deb.sh \
|
||||
.PHONY: compare-test-deb-package-install
|
||||
compare-test-deb-package-install: $(RESULTSDIR) $(SNAPSHOTDIR)
|
||||
$(call title,Running compare test: DEB install)
|
||||
$(COMPARE_DIR)/deb.sh \
|
||||
$(SNAPSHOTDIR) \
|
||||
$(ACC_DIR) \
|
||||
$(ACC_TEST_IMAGE) \
|
||||
$(COMPARE_DIR) \
|
||||
$(COMPARE_TEST_IMAGE) \
|
||||
$(RESULTSDIR)
|
||||
|
||||
.PHONY: acceptance-test-rpm-package-install
|
||||
acceptance-test-rpm-package-install: $(RESULTSDIR) $(SNAPSHOTDIR)
|
||||
$(call title,Running acceptance test: RPM install)
|
||||
$(ACC_DIR)/rpm.sh \
|
||||
.PHONY: compare-test-rpm-package-install
|
||||
compare-test-rpm-package-install: $(RESULTSDIR) $(SNAPSHOTDIR)
|
||||
$(call title,Running compare test: RPM install)
|
||||
$(COMPARE_DIR)/rpm.sh \
|
||||
$(SNAPSHOTDIR) \
|
||||
$(ACC_DIR) \
|
||||
$(ACC_TEST_IMAGE) \
|
||||
$(COMPARE_DIR) \
|
||||
$(COMPARE_TEST_IMAGE) \
|
||||
$(RESULTSDIR)
|
||||
|
||||
# note: this is used by CI to determine if the integration test fixture cache (docker image tars) should be busted
|
||||
cli-fingerprint:
|
||||
$(call title,CLI test fixture fingerprint)
|
||||
find test/cli/test-fixtures/image-* -type f -exec md5sum {} + | awk '{print $1}' | sort | md5sum | tee test/cli/test-fixtures/cache.fingerprint && echo "$(CLI_CACHE_BUSTER)" >> test/cli/test-fixtures/cache.fingerprint
|
||||
|
||||
.PHONY: cli
|
||||
|
||||
825
install.sh
825
install.sh
@ -1,198 +1,129 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
# note: we require errors to propagate (don't set -e)
|
||||
set -u
|
||||
|
||||
usage() {
|
||||
PROJECT_NAME="syft"
|
||||
OWNER=anchore
|
||||
REPO="${PROJECT_NAME}"
|
||||
GITHUB_DOWNLOAD_PREFIX=https://github.com/${OWNER}/${REPO}/releases/download
|
||||
|
||||
#
|
||||
# usage [script-name]
|
||||
#
|
||||
usage() (
|
||||
this=$1
|
||||
cat <<EOF
|
||||
$this: download go binaries for anchore/syft
|
||||
|
||||
Usage: $this [-b] bindir [-d] [tag]
|
||||
-b sets bindir or installation directory, Defaults to ./bin
|
||||
-d turns on debug logging
|
||||
[tag] is a tag from
|
||||
https://github.com/anchore/syft/releases
|
||||
If tag is missing, then the latest will be used.
|
||||
|
||||
Generated by godownloader
|
||||
https://github.com/goreleaser/godownloader
|
||||
|
||||
Usage: $this [-b] dir [-d] [tag]
|
||||
-b the installation directory (dDefaults to ./bin)
|
||||
-d turns on debug logging
|
||||
-dd turns on trace logging
|
||||
[tag] the specific release to use (if missing, then the latest will be used)
|
||||
EOF
|
||||
exit 2
|
||||
}
|
||||
)
|
||||
|
||||
parse_args() {
|
||||
# BINDIR is ./bin unless set be ENV
|
||||
# over-ridden by flag below
|
||||
|
||||
BINDIR=${BINDIR:-./bin}
|
||||
while getopts "b:dh?x" arg; do
|
||||
case "$arg" in
|
||||
b) BINDIR="$OPTARG" ;;
|
||||
d) log_set_priority 10 ;;
|
||||
h | \?) usage "$0" ;;
|
||||
x) set -x ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
TAG=$1
|
||||
}
|
||||
# this function wraps all the destructive operations
|
||||
# if a curl|bash cuts off the end of the script due to
|
||||
# network, either nothing will happen or will syntax error
|
||||
# out preventing half-done work
|
||||
execute() {
|
||||
tmpdir=$(mktemp -d)
|
||||
log_debug "downloading files into ${tmpdir}"
|
||||
http_download "${tmpdir}/${ARCHIVE}" "${ARCHIVE_URL}"
|
||||
http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}"
|
||||
# ------------------------------------------------------------------------
|
||||
# https://github.com/client9/shlib - portable posix shell functions
|
||||
# Public domain - http://unlicense.org
|
||||
# https://github.com/client9/shlib/blob/master/LICENSE.md
|
||||
# but credit (and pull requests) appreciated.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# macOS has its own secure verification mechanism, and checksums.txt is not used.
|
||||
if [ "$OS" != "darwin" ]; then
|
||||
hash_sha256_verify "${tmpdir}/${ARCHIVE}" "${tmpdir}/${CHECKSUM}"
|
||||
fi
|
||||
|
||||
srcdir="${tmpdir}"
|
||||
(cd "${tmpdir}" && unpack "${ARCHIVE}")
|
||||
test ! -d "${BINDIR}" && install -d "${BINDIR}"
|
||||
for binexe in $BINARIES; do
|
||||
if [ "$OS" = "windows" ]; then
|
||||
binexe="${binexe}.exe"
|
||||
fi
|
||||
install "${srcdir}/${binexe}" "${BINDIR}/"
|
||||
log_info "installed ${BINDIR}/${binexe}"
|
||||
done
|
||||
rm -rf "${tmpdir}"
|
||||
}
|
||||
get_binaries() {
|
||||
case "$PLATFORM" in
|
||||
darwin/arm64) BINARIES="syft" ;;
|
||||
darwin/amd64) BINARIES="syft" ;;
|
||||
linux/amd64) BINARIES="syft" ;;
|
||||
linux/arm64) BINARIES="syft" ;;
|
||||
windows/amd64) BINARIES="syft" ;;
|
||||
*)
|
||||
log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
tag_to_version() {
|
||||
if [ -z "${TAG}" ]; then
|
||||
log_info "checking GitHub for latest tag"
|
||||
else
|
||||
log_info "checking GitHub for tag '${TAG}'"
|
||||
fi
|
||||
REALTAG=$(github_release "$OWNER/$REPO" "${TAG}") && true
|
||||
if test -z "$REALTAG"; then
|
||||
log_crit "unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details"
|
||||
exit 1
|
||||
fi
|
||||
# if version starts with 'v', remove it
|
||||
TAG="$REALTAG"
|
||||
VERSION=${TAG#v}
|
||||
}
|
||||
adjust_format() {
|
||||
# change format (tar.gz or zip) based on OS
|
||||
case ${OS} in
|
||||
darwin) FORMAT=dmg ;;
|
||||
windows) FORMAT=zip ;;
|
||||
esac
|
||||
case "${PLATFORM}" in
|
||||
darwin/arm64) FORMAT=zip ;;
|
||||
esac
|
||||
true
|
||||
}
|
||||
adjust_os() {
|
||||
# adjust archive name based on OS
|
||||
true
|
||||
}
|
||||
adjust_arch() {
|
||||
# adjust archive name based on ARCH
|
||||
true
|
||||
}
|
||||
|
||||
cat /dev/null <<EOF
|
||||
------------------------------------------------------------------------
|
||||
https://github.com/client9/shlib - portable posix shell functions
|
||||
Public domain - http://unlicense.org
|
||||
https://github.com/client9/shlib/blob/master/LICENSE.md
|
||||
but credit (and pull requests) appreciated.
|
||||
------------------------------------------------------------------------
|
||||
EOF
|
||||
is_command() {
|
||||
is_command() (
|
||||
command -v "$1" >/dev/null
|
||||
}
|
||||
echoerr() {
|
||||
)
|
||||
|
||||
echo_stderr() (
|
||||
echo "$@" 1>&2
|
||||
}
|
||||
log_prefix() {
|
||||
echo "$0"
|
||||
}
|
||||
_logp=6
|
||||
)
|
||||
|
||||
_logp=2
|
||||
log_set_priority() {
|
||||
_logp="$1"
|
||||
}
|
||||
log_priority() {
|
||||
|
||||
log_priority() (
|
||||
if test -z "$1"; then
|
||||
echo "$_logp"
|
||||
return
|
||||
fi
|
||||
[ "$1" -le "$_logp" ]
|
||||
)
|
||||
|
||||
init_colors() {
|
||||
RED=''
|
||||
BLUE=''
|
||||
PURPLE=''
|
||||
BOLD=''
|
||||
RESET=''
|
||||
# check if stdout is a terminal
|
||||
if test -t 1 && is_command tput; then
|
||||
# see if it supports colors
|
||||
ncolors=$(tput colors)
|
||||
if test -n "$ncolors" && test $ncolors -ge 8; then
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
PURPLE='\033[0;35m'
|
||||
BOLD='\033[1m'
|
||||
RESET='\033[0m'
|
||||
fi
|
||||
fi
|
||||
}
|
||||
log_tag() {
|
||||
|
||||
init_colors
|
||||
|
||||
log_tag() (
|
||||
case $1 in
|
||||
0) echo "emerg" ;;
|
||||
1) echo "alert" ;;
|
||||
2) echo "crit" ;;
|
||||
3) echo "err" ;;
|
||||
4) echo "warning" ;;
|
||||
5) echo "notice" ;;
|
||||
6) echo "info" ;;
|
||||
7) echo "debug" ;;
|
||||
*) echo "$1" ;;
|
||||
0) echo "${RED}${BOLD}[error]${RESET}" ;;
|
||||
1) echo "${RED}[warn]${RESET}" ;;
|
||||
2) echo "[info]${RESET}" ;;
|
||||
3) echo "${BLUE}[debug]${RESET}" ;;
|
||||
4) echo "${PURPLE}[trace]${RESET}" ;;
|
||||
*) echo "[$1]" ;;
|
||||
esac
|
||||
}
|
||||
log_debug() {
|
||||
log_priority 7 || return 0
|
||||
echoerr "$(log_prefix)" "$(log_tag 7)" "$@"
|
||||
}
|
||||
log_info() {
|
||||
log_priority 6 || return 0
|
||||
echoerr "$(log_prefix)" "$(log_tag 6)" "$@"
|
||||
}
|
||||
log_err() {
|
||||
log_priority 3 || return 0
|
||||
echoerr "$(log_prefix)" "$(log_tag 3)" "$@"
|
||||
}
|
||||
log_crit() {
|
||||
log_priority 2 || return 0
|
||||
echoerr "$(log_prefix)" "$(log_tag 2)" "$@"
|
||||
}
|
||||
uname_os() {
|
||||
os=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||
case "$os" in
|
||||
cygwin_nt*) os="windows" ;;
|
||||
mingw*) os="windows" ;;
|
||||
msys_nt*) os="windows" ;;
|
||||
esac
|
||||
echo "$os"
|
||||
}
|
||||
uname_arch() {
|
||||
arch=$(uname -m)
|
||||
case $arch in
|
||||
x86_64) arch="amd64" ;;
|
||||
x86) arch="386" ;;
|
||||
i686) arch="386" ;;
|
||||
i386) arch="386" ;;
|
||||
aarch64) arch="arm64" ;;
|
||||
armv5*) arch="armv5" ;;
|
||||
armv6*) arch="armv6" ;;
|
||||
armv7*) arch="armv7" ;;
|
||||
esac
|
||||
echo ${arch}
|
||||
}
|
||||
uname_os_check() {
|
||||
os=$(uname_os)
|
||||
)
|
||||
|
||||
|
||||
log_trace_priority=4
|
||||
log_trace() (
|
||||
priority=$log_trace_priority
|
||||
log_priority "$priority" || return 0
|
||||
echo_stderr "$(log_tag $priority)" "${@}" "${RESET}"
|
||||
)
|
||||
|
||||
log_debug_priority=3
|
||||
log_debug() (
|
||||
priority=$log_debug_priority
|
||||
log_priority "$priority" || return 0
|
||||
echo_stderr "$(log_tag $priority)" "${@}" "${RESET}"
|
||||
)
|
||||
|
||||
log_info_priority=2
|
||||
log_info() (
|
||||
priority=$log_info_priority
|
||||
log_priority "$priority" || return 0
|
||||
echo_stderr "$(log_tag $priority)" "${@}" "${RESET}"
|
||||
)
|
||||
|
||||
log_warn_priority=1
|
||||
log_warn() (
|
||||
priority=$log_warn_priority
|
||||
log_priority "$priority" || return 0
|
||||
echo_stderr "$(log_tag $priority)" "${@}" "${RESET}"
|
||||
)
|
||||
|
||||
log_err_priority=0
|
||||
log_err() (
|
||||
priority=$log_err_priority
|
||||
log_priority "$priority" || return 0
|
||||
echo_stderr "$(log_tag $priority)" "${@}" "${RESET}"
|
||||
)
|
||||
|
||||
uname_os_check() (
|
||||
os=$1
|
||||
case "$os" in
|
||||
darwin) return 0 ;;
|
||||
dragonfly) return 0 ;;
|
||||
@ -206,11 +137,12 @@ uname_os_check() {
|
||||
solaris) return 0 ;;
|
||||
windows) return 0 ;;
|
||||
esac
|
||||
log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib"
|
||||
log_err "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib"
|
||||
return 1
|
||||
}
|
||||
uname_arch_check() {
|
||||
arch=$(uname_arch)
|
||||
)
|
||||
|
||||
uname_arch_check() (
|
||||
arch=$1
|
||||
case "$arch" in
|
||||
386) return 0 ;;
|
||||
amd64) return 0 ;;
|
||||
@ -227,56 +159,72 @@ uname_arch_check() {
|
||||
s390x) return 0 ;;
|
||||
amd64p32) return 0 ;;
|
||||
esac
|
||||
log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib"
|
||||
log_err "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib"
|
||||
return 1
|
||||
}
|
||||
unpack() {
|
||||
)
|
||||
|
||||
unpack() (
|
||||
archive=$1
|
||||
|
||||
log_trace "unpack(archive=${archive})"
|
||||
|
||||
case "${archive}" in
|
||||
*.tar.gz | *.tgz) tar --no-same-owner -xzf "${archive}" ;;
|
||||
*.tar) tar --no-same-owner -xf "${archive}" ;;
|
||||
*.zip) unzip "${archive}" ;;
|
||||
*.zip) unzip -q "${archive}" ;;
|
||||
*.dmg) extract_from_dmg "${archive}" ;;
|
||||
*)
|
||||
log_err "unpack unknown archive format for ${archive}"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
extract_from_dmg() {
|
||||
)
|
||||
|
||||
extract_from_dmg() (
|
||||
dmg_file=$1
|
||||
|
||||
mount_point="/Volumes/tmp-dmg"
|
||||
hdiutil attach -quiet -nobrowse -mountpoint "${mount_point}" "${dmg_file}"
|
||||
cp -fR "${mount_point}/." ./
|
||||
hdiutil detach -quiet -force "${mount_point}"
|
||||
}
|
||||
http_download_curl() {
|
||||
)
|
||||
|
||||
http_download_curl() (
|
||||
local_file=$1
|
||||
source_url=$2
|
||||
header=$3
|
||||
|
||||
log_trace "http_download_curl(local_file=$local_file, source_url=$source_url, header=$header)"
|
||||
|
||||
if [ -z "$header" ]; then
|
||||
code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url")
|
||||
else
|
||||
code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url")
|
||||
fi
|
||||
|
||||
if [ "$code" != "200" ]; then
|
||||
log_debug "http_download_curl received HTTP status $code"
|
||||
log_err "received HTTP status=$code for url='$source_url'"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
http_download_wget() {
|
||||
)
|
||||
|
||||
http_download_wget() (
|
||||
local_file=$1
|
||||
source_url=$2
|
||||
header=$3
|
||||
|
||||
log_trace "http_download_wget(local_file=$local_file, source_url=$source_url, header=$header)"
|
||||
|
||||
if [ -z "$header" ]; then
|
||||
wget -q -O "$local_file" "$source_url"
|
||||
else
|
||||
wget -q --header "$header" -O "$local_file" "$source_url"
|
||||
fi
|
||||
}
|
||||
http_download() {
|
||||
log_debug "http_download $2"
|
||||
)
|
||||
|
||||
http_download() (
|
||||
log_debug "http_download(url=$2)"
|
||||
if is_command curl; then
|
||||
http_download_curl "$@"
|
||||
return
|
||||
@ -284,28 +232,19 @@ http_download() {
|
||||
http_download_wget "$@"
|
||||
return
|
||||
fi
|
||||
log_crit "http_download unable to find wget or curl"
|
||||
log_err "http_download unable to find wget or curl"
|
||||
return 1
|
||||
}
|
||||
http_copy() {
|
||||
)
|
||||
|
||||
http_copy() (
|
||||
tmp=$(mktemp)
|
||||
http_download "${tmp}" "$1" "$2" || return 1
|
||||
body=$(cat "$tmp")
|
||||
rm -f "${tmp}"
|
||||
echo "$body"
|
||||
}
|
||||
github_release() {
|
||||
owner_repo=$1
|
||||
version=$2
|
||||
test -z "$version" && version="latest"
|
||||
giturl="https://github.com/${owner_repo}/releases/${version}"
|
||||
json=$(http_copy "$giturl" "Accept:application/json")
|
||||
test -z "$json" && return 1
|
||||
version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//')
|
||||
test -z "$version" && return 1
|
||||
echo "$version"
|
||||
}
|
||||
hash_sha256() {
|
||||
)
|
||||
|
||||
hash_sha256() (
|
||||
TARGET=${1:-/dev/stdin}
|
||||
if is_command gsha256sum; then
|
||||
hash=$(gsha256sum "$TARGET") || return 1
|
||||
@ -320,11 +259,12 @@ hash_sha256() {
|
||||
hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1
|
||||
echo "$hash" | cut -d ' ' -f a
|
||||
else
|
||||
log_crit "hash_sha256 unable to find command to compute sha-256 hash"
|
||||
log_err "hash_sha256 unable to find command to compute sha-256 hash"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
hash_sha256_verify() {
|
||||
)
|
||||
|
||||
hash_sha256_verify() (
|
||||
TARGET=$1
|
||||
checksums=$2
|
||||
if [ -z "$checksums" ]; then
|
||||
@ -342,51 +282,452 @@ hash_sha256_verify() {
|
||||
log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
cat /dev/null <<EOF
|
||||
------------------------------------------------------------------------
|
||||
End of functions from https://github.com/client9/shlib
|
||||
------------------------------------------------------------------------
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# End of functions from https://github.com/client9/shlib
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# asset_file_exists [path]
|
||||
#
|
||||
# returns 1 if the given file does not exist
|
||||
#
|
||||
asset_file_exists() (
|
||||
path="$1"
|
||||
if [ ! -f "${path}" ]; then
|
||||
return 1
|
||||
fi
|
||||
)
|
||||
|
||||
|
||||
# github_release_json [owner] [repo] [version]
|
||||
#
|
||||
# outputs release json string
|
||||
#
|
||||
github_release_json() (
|
||||
owner=$1
|
||||
repo=$2
|
||||
version=$3
|
||||
test -z "$version" && version="latest"
|
||||
giturl="https://github.com/${owner}/${repo}/releases/${version}"
|
||||
json=$(http_copy "$giturl" "Accept:application/json")
|
||||
|
||||
log_trace "github_release_json(owner=${owner}, repo=${repo}, version=${version}) returned '${json}'"
|
||||
|
||||
test -z "$json" && return 1
|
||||
echo "${json}"
|
||||
)
|
||||
|
||||
# extract_value [key-value-pair]
|
||||
#
|
||||
# outputs value from a colon delimited key-value pair
|
||||
#
|
||||
extract_value() (
|
||||
key_value="$1"
|
||||
IFS=':' read -r _ value << EOF
|
||||
${key_value}
|
||||
EOF
|
||||
echo "$value"
|
||||
)
|
||||
|
||||
PROJECT_NAME="syft"
|
||||
OWNER=anchore
|
||||
REPO="syft"
|
||||
BINARY=syft
|
||||
FORMAT=tar.gz
|
||||
OS=$(uname_os)
|
||||
ARCH=$(uname_arch)
|
||||
PREFIX="$OWNER/$REPO"
|
||||
# extract_json_value [json] [key]
|
||||
#
|
||||
# outputs value of the key from the given json string
|
||||
#
|
||||
extract_json_value() (
|
||||
json="$1"
|
||||
key="$2"
|
||||
key_value=$(echo "${json}" | grep -o "\"$key\":[^,]*[,}]" | tr -d '",}')
|
||||
|
||||
# use in logging routines
|
||||
log_prefix() {
|
||||
echo "$PREFIX"
|
||||
}
|
||||
PLATFORM="${OS}/${ARCH}"
|
||||
GITHUB_DOWNLOAD=https://github.com/${OWNER}/${REPO}/releases/download
|
||||
extract_value "$key_value"
|
||||
)
|
||||
|
||||
uname_os_check "$OS"
|
||||
uname_arch_check "$ARCH"
|
||||
# github_release_tag [release-json]
|
||||
#
|
||||
# outputs release tag string
|
||||
#
|
||||
github_release_tag() (
|
||||
json="$1"
|
||||
tag=$(extract_json_value "${json}" "tag_name")
|
||||
test -z "$tag" && return 1
|
||||
echo "$tag"
|
||||
)
|
||||
|
||||
parse_args "$@"
|
||||
# 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"
|
||||
|
||||
get_binaries
|
||||
log_trace "download_github_release_checksums(url=${download_url}, name=${name}, version=${version}, output_dir=${output_dir})"
|
||||
|
||||
tag_to_version
|
||||
checksum_filename=${name}_${version}_checksums.txt
|
||||
checksum_url=${download_url}/${checksum_filename}
|
||||
output_path="${output_dir}/${checksum_filename}"
|
||||
|
||||
adjust_format
|
||||
http_download "${output_path}" "${checksum_url}" ""
|
||||
asset_file_exists "${output_path}"
|
||||
|
||||
adjust_os
|
||||
log_trace "download_github_release_checksums() returned '${output_path}'"
|
||||
|
||||
adjust_arch
|
||||
echo "${output_path}"
|
||||
)
|
||||
|
||||
log_info "found version: ${VERSION} for ${TAG}/${OS}/${ARCH}"
|
||||
# search_for_asset [checksums-file-path] [name] [os] [arch] [format]
|
||||
#
|
||||
# outputs name of the asset to download
|
||||
#
|
||||
search_for_asset() (
|
||||
checksum_path="$1"
|
||||
name="$2"
|
||||
os="$3"
|
||||
arch="$4"
|
||||
format="$5"
|
||||
|
||||
NAME=${PROJECT_NAME}_${VERSION}_${OS}_${ARCH}
|
||||
ARCHIVE=${NAME}.${FORMAT}
|
||||
ARCHIVE_URL=${GITHUB_DOWNLOAD}/${TAG}/${ARCHIVE}
|
||||
CHECKSUM=${PROJECT_NAME}_${VERSION}_checksums.txt
|
||||
CHECKSUM_URL=${GITHUB_DOWNLOAD}/${TAG}/${CHECKSUM}
|
||||
log_trace "search_for_asset(checksum-path=${checksum_path}, name=${name}, os=${os}, arch=${arch}, format=${format})"
|
||||
|
||||
asset_glob="${name}_.*_${os}_${arch}.${format}"
|
||||
output_path=$(grep -o "${asset_glob}" "${checksum_path}" || true)
|
||||
|
||||
log_trace "search_for_asset() returned '${output_path}'"
|
||||
|
||||
echo "${output_path}"
|
||||
)
|
||||
|
||||
# uname_os
|
||||
#
|
||||
# outputs an adjusted os value
|
||||
#
|
||||
uname_os() (
|
||||
os=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||
case "$os" in
|
||||
cygwin_nt*) os="windows" ;;
|
||||
mingw*) os="windows" ;;
|
||||
msys_nt*) os="windows" ;;
|
||||
esac
|
||||
|
||||
uname_os_check "$os"
|
||||
|
||||
log_trace "uname_os() returned '${os}'"
|
||||
|
||||
echo "$os"
|
||||
)
|
||||
|
||||
# uname_arch
|
||||
#
|
||||
# outputs an adjusted architecture value
|
||||
#
|
||||
uname_arch() (
|
||||
arch=$(uname -m)
|
||||
case $arch in
|
||||
x86_64) arch="amd64" ;;
|
||||
x86) arch="386" ;;
|
||||
i686) arch="386" ;;
|
||||
i386) arch="386" ;;
|
||||
aarch64) arch="arm64" ;;
|
||||
armv5*) arch="armv5" ;;
|
||||
armv6*) arch="armv6" ;;
|
||||
armv7*) arch="armv7" ;;
|
||||
esac
|
||||
|
||||
uname_arch_check "${arch}"
|
||||
|
||||
log_trace "uname_arch() returned '${arch}'"
|
||||
|
||||
echo "${arch}"
|
||||
)
|
||||
|
||||
# get_release_tag [owner] [repo] [tag]
|
||||
#
|
||||
# outputs tag string
|
||||
#
|
||||
get_release_tag() (
|
||||
owner="$1"
|
||||
repo="$2"
|
||||
tag="$3"
|
||||
|
||||
log_trace "get_release_tag(owner=${owner}, repo=${repo}, tag=${tag})"
|
||||
|
||||
json=$(github_release_json "${owner}" "${repo}" "${tag}")
|
||||
real_tag=$(github_release_tag "${json}")
|
||||
if test -z "${real_tag}"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_trace "get_release_tag() returned '${real_tag}'"
|
||||
|
||||
echo "${real_tag}"
|
||||
)
|
||||
|
||||
# tag_to_version [tag]
|
||||
#
|
||||
# outputs version string
|
||||
#
|
||||
tag_to_version() (
|
||||
tag="$1"
|
||||
value="${tag#v}"
|
||||
|
||||
log_trace "tag_to_version(tag=${tag}) returned '${value}'"
|
||||
|
||||
echo "$value"
|
||||
)
|
||||
|
||||
# get_binary_name [os] [arch] [default-name]
|
||||
#
|
||||
# outputs a the binary string name
|
||||
#
|
||||
get_binary_name() (
|
||||
os="$1"
|
||||
arch="$2"
|
||||
binary="$3"
|
||||
original_binary="${binary}"
|
||||
|
||||
case "${os}" in
|
||||
windows) binary="${binary}.exe" ;;
|
||||
esac
|
||||
|
||||
log_trace "get_binary_name(os=${os}, arch=${arch}, binary=${original_binary}) returned '${binary}'"
|
||||
|
||||
echo "${binary}"
|
||||
)
|
||||
|
||||
|
||||
execute
|
||||
# get_format_name [os] [arch] [default-format]
|
||||
#
|
||||
# outputs an adjusted file format
|
||||
#
|
||||
get_format_name() (
|
||||
os="$1"
|
||||
arch="$2"
|
||||
format="$3"
|
||||
original_format="${format}"
|
||||
|
||||
case ${os} in
|
||||
# why override darwin to DMG? two reasons:
|
||||
# 1. the tar.gz does not contain a signed binary
|
||||
# 2. the zip is removed from the checksums file (since the signing process changes the content)
|
||||
darwin) format=dmg ;;
|
||||
windows) format=zip ;;
|
||||
esac
|
||||
case "${os}/${arch}" in
|
||||
darwin/arm64) format=zip ;;
|
||||
esac
|
||||
|
||||
log_trace "get_format_name(os=${os}, arch=${arch}, format=${original_format}) returned '${format}'"
|
||||
|
||||
echo "${format}"
|
||||
)
|
||||
|
||||
# download_and_install_asset [release-url-prefix] [download-path] [install-path] [name] [os] [arch] [version] [format] [binary]
|
||||
#
|
||||
# attempts to download the archive and install it to the given path.
|
||||
#
|
||||
download_and_install_asset() (
|
||||
download_url="$1"
|
||||
download_path="$2"
|
||||
install_path=$3
|
||||
name="$4"
|
||||
os="$5"
|
||||
arch="$6"
|
||||
version="$7"
|
||||
format="$8"
|
||||
binary="$9"
|
||||
|
||||
asset_filepath=$(download_asset "${download_url}" "${download_path}" "${name}" "${os}" "${arch}" "${version}" "${format}")
|
||||
|
||||
# don't continue if we couldn't download an asset
|
||||
if [ -z "${asset_filepath}" ]; then
|
||||
log_err "could not find release asset for os='${os}' arch='${arch}' format='${format}' "
|
||||
return 1
|
||||
fi
|
||||
|
||||
install_asset "${asset_filepath}" "${install_path}" "${binary}"
|
||||
)
|
||||
|
||||
# download_asset [release-url-prefix] [download-path] [name] [os] [arch] [version] [format] [binary]
|
||||
#
|
||||
# outputs the path to the downloaded asset asset_filepath
|
||||
#
|
||||
download_asset() (
|
||||
download_url="$1"
|
||||
download_path="$2"
|
||||
name="$3"
|
||||
os="$4"
|
||||
arch="$5"
|
||||
version="$6"
|
||||
format="$7"
|
||||
|
||||
if [ "$format" = "dmg" ] || [ "$os/$arch/$format" = "darwin/arm64/zip" ]; then
|
||||
# the signing process outputs the zip/dmg and the checksum is not included in the checksums.txt file
|
||||
# TODO: remove this case in the future by upgrading the release process
|
||||
asset_filepath=$(download_asset_without_verification "${download_url}" "${download_path}" "${name}" "${os}" "${arch}" "${version}" "${format}")
|
||||
else
|
||||
asset_filepath=$(download_asset_by_checksums_file "${download_url}" "${download_path}" "${name}" "${os}" "${arch}" "${version}" "${format}")
|
||||
fi
|
||||
|
||||
echo "${asset_filepath}"
|
||||
)
|
||||
|
||||
# download_asset_without_verification [release-url-prefix] [destination] [name] [os] [arch] [version] [format]
|
||||
#
|
||||
# outputs the filepath to the raw asset (no verification against the checksums file is performed)
|
||||
#
|
||||
download_asset_without_verification() (
|
||||
download_url="$1"
|
||||
destination="$2"
|
||||
name="$3"
|
||||
os="$4"
|
||||
arch="$5"
|
||||
version="$6"
|
||||
format="$7"
|
||||
|
||||
asset_filename="${name}_${version}_${os}_${arch}.${format}"
|
||||
asset_url="${download_url}/${asset_filename}"
|
||||
asset_filepath="${destination}/${asset_filename}"
|
||||
http_download "${asset_filepath}" "${asset_url}" ""
|
||||
|
||||
echo "${asset_filepath}"
|
||||
)
|
||||
|
||||
# download_asset_by_checksums_file [release-url-prefix] [destination] [name] [os] [arch] [version] [format]
|
||||
#
|
||||
# outputs the filepath to the raw asset (verified against the checksums file)
|
||||
#
|
||||
download_asset_by_checksums_file() (
|
||||
download_url="$1"
|
||||
destination="$2"
|
||||
name="$3"
|
||||
os="$4"
|
||||
arch="$5"
|
||||
version="$6"
|
||||
format="$7"
|
||||
|
||||
log_trace "download_asset_by_checksums_file(url=${download_url}, destination=${destination}, name=${name}, os=${os}, arch=${arch}, version=${version}, format=${format})"
|
||||
|
||||
checksums_filepath=$(download_github_release_checksums "${download_url}" "${name}" "${version}" "${destination}")
|
||||
|
||||
log_trace "checksums content:\n$(cat ${checksums_filepath})"
|
||||
|
||||
asset_filename=$(search_for_asset "${checksums_filepath}" "${name}" "${os}" "${arch}" "${format}")
|
||||
|
||||
# don't continue if we couldn't find a matching asset from the checksums file
|
||||
if [ -z "${asset_filename}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
asset_url="${download_url}/${asset_filename}"
|
||||
asset_filepath="${destination}/${asset_filename}"
|
||||
http_download "${asset_filepath}" "${asset_url}" ""
|
||||
|
||||
hash_sha256_verify "${asset_filepath}" "${checksums_filepath}"
|
||||
|
||||
log_trace "download_asset_by_checksums_file() returned '${asset_filepath}'"
|
||||
|
||||
echo "${asset_filepath}"
|
||||
)
|
||||
|
||||
# install_asset [asset-path] [destination-path] [binary]
|
||||
#
|
||||
install_asset() (
|
||||
asset_filepath="$1"
|
||||
destination="$2"
|
||||
binary="$3"
|
||||
|
||||
log_trace "install_asset(asset=${asset_filepath}, destination=${destination}, binary=${binary})"
|
||||
|
||||
# don't continue if we don't have anything to install
|
||||
if [ -z "${asset_filepath}" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
archive_dir=$(dirname "${asset_filepath}")
|
||||
|
||||
# unarchive the downloaded archive to the temp dir
|
||||
(cd "${archive_dir}" && unpack "${asset_filepath}")
|
||||
|
||||
# create the destination dir
|
||||
test ! -d "${destination}" && install -d "${destination}"
|
||||
|
||||
# install the binary to the destination dir
|
||||
install "${archive_dir}/${binary}" "${destination}/"
|
||||
)
|
||||
|
||||
main() (
|
||||
# parse arguments
|
||||
|
||||
install_dir=${install_dir:-./bin}
|
||||
while getopts "b:dh?x" arg; do
|
||||
case "$arg" in
|
||||
b) install_dir="$OPTARG" ;;
|
||||
d)
|
||||
if [ "$_logp" = "$log_info_priority" ]; then
|
||||
# -d == debug
|
||||
log_set_priority $log_debug_priority
|
||||
else
|
||||
# -dd (or -ddd...) == trace
|
||||
log_set_priority $log_trace_priority
|
||||
fi
|
||||
;;
|
||||
h | \?) usage "$0" ;;
|
||||
x) set -x ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
set +u
|
||||
tag=$1
|
||||
|
||||
if [ -z "${tag}" ]; then
|
||||
log_info "checking github for the current release tag"
|
||||
tag=""
|
||||
else
|
||||
log_info "checking github for release tag='${tag}'"
|
||||
fi
|
||||
set -u
|
||||
|
||||
tag=$(get_release_tag "${OWNER}" "${REPO}" "${tag}")
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
log_err "unable to find tag='${tag}'"
|
||||
log_err "do not specify a version or select a valid version from https://github.com/${OWNER}/${REPO}/releases"
|
||||
return 1
|
||||
fi
|
||||
|
||||
version=$(tag_to_version "${tag}")
|
||||
|
||||
download_dir=$(mktemp -d)
|
||||
trap 'rm -rf -- "$download_dir"' EXIT
|
||||
|
||||
# run the application
|
||||
|
||||
os=$(uname_os)
|
||||
arch=$(uname_arch)
|
||||
format=$(get_format_name "${os}" "${arch}" "tar.gz")
|
||||
binary=$(get_binary_name "${os}" "${arch}" "${PROJECT_NAME}")
|
||||
download_url="${GITHUB_DOWNLOAD_PREFIX}/${tag}"
|
||||
|
||||
log_info "using release tag='${tag}' version='${version}' os='${os}' arch='${arch}'"
|
||||
log_debug "downloading files into ${download_dir}"
|
||||
|
||||
download_and_install_asset "${download_url}" "${download_dir}" "${install_dir}" "${PROJECT_NAME}" "${os}" "${arch}" "${version}" "${format}" "${binary}"
|
||||
|
||||
# don't continue if we couldn't install the asset
|
||||
if [ "$?" != "0" ]; then
|
||||
log_err "failed to install ${PROJECT_NAME}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "installed ${install_dir}/${binary}"
|
||||
)
|
||||
|
||||
# entrypoint
|
||||
|
||||
set +u
|
||||
if [ -z "${TEST_INSTALL_SH}" ]; then
|
||||
set -u
|
||||
main "$@"
|
||||
fi
|
||||
set -u
|
||||
@ -65,5 +65,5 @@ clean-jenkins:
|
||||
# we need a way to determine if CI should bust the test cache based on the source material
|
||||
$(PKGSDIR).fingerprint: clean-examples
|
||||
mkdir -p $(PKGSDIR)
|
||||
find example-* -type f -exec sha256sum {} \; | sort | tee $(PKGSDIR).fingerprint
|
||||
find example-* -type f -exec sha256sum {} \; | sort | tee /dev/stderr | tee $(PKGSDIR).fingerprint
|
||||
sha256sum $(PKGSDIR).fingerprint
|
||||
|
||||
1
test/install/.dockerignore
Normal file
1
test/install/.dockerignore
Normal file
@ -0,0 +1 @@
|
||||
**
|
||||
1
test/install/.gitignore
vendored
Normal file
1
test/install/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
cache/
|
||||
40
test/install/0_search_for_asset_test.sh
Executable file
40
test/install/0_search_for_asset_test.sh
Executable file
@ -0,0 +1,40 @@
|
||||
. test_harness.sh
|
||||
|
||||
# search for an asset in a release checksums file
|
||||
test_search_for_asset_release() {
|
||||
fixture=./test-fixtures/syft_0.36.0_checksums.txt
|
||||
|
||||
# search_for_asset [checksums-file-path] [name] [os] [arch] [format]
|
||||
|
||||
# positive case
|
||||
actual=$(search_for_asset "${fixture}" "syft" "linux" "amd64" "tar.gz")
|
||||
assertEquals "syft_0.36.0_linux_amd64.tar.gz" "${actual}" "unable to find release asset"
|
||||
|
||||
# negative cases
|
||||
actual=$(search_for_asset "${fixture}" "syft" "Linux" "amd64" "tar.gz")
|
||||
assertEquals "" "${actual}" "found a release asset but did not expect to (os)"
|
||||
|
||||
actual=$(search_for_asset "${fixture}" "syft" "darwin" "amd64" "rpm")
|
||||
assertEquals "" "${actual}" "found a release asset but did not expect to (format)"
|
||||
|
||||
}
|
||||
|
||||
run_test_case test_search_for_asset_release
|
||||
|
||||
|
||||
# search for an asset in a snapshot checksums file
|
||||
test_search_for_asset_snapshot() {
|
||||
fixture=./test-fixtures/syft_0.35.1-SNAPSHOT-d461f63_checksums.txt
|
||||
|
||||
# search_for_asset [checksums-file-path] [name] [os] [arch] [format]
|
||||
|
||||
# positive case
|
||||
actual=$(search_for_asset "${fixture}" "syft" "linux" "amd64" "rpm")
|
||||
assertEquals "syft_0.35.1-SNAPSHOT-d461f63_linux_amd64.rpm" "${actual}" "unable to find snapshot asset"
|
||||
|
||||
# negative case
|
||||
actual=$(search_for_asset "${fixture}" "syft" "linux" "amd64" "zip")
|
||||
assertEquals "" "${actual}" "found a snapshot asset but did not expect to (format)"
|
||||
}
|
||||
|
||||
run_test_case test_search_for_asset_snapshot
|
||||
88
test/install/1_download_snapshot_asset_test.sh
Executable file
88
test/install/1_download_snapshot_asset_test.sh
Executable file
@ -0,0 +1,88 @@
|
||||
. test_harness.sh
|
||||
|
||||
DOWNLOAD_SNAPSHOT_POSITIVE_CASES=0
|
||||
|
||||
# helper for asserting test_positive_snapshot_download_asset positive cases
|
||||
test_positive_snapshot_download_asset() {
|
||||
os="$1"
|
||||
arch="$2"
|
||||
format="$3"
|
||||
|
||||
# for troubleshooting
|
||||
# log_set_priority 10
|
||||
|
||||
name=${PROJECT_NAME}
|
||||
github_download=$(snapshot_download_url)
|
||||
version=$(snapshot_version)
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
|
||||
actual_filepath=$(download_asset "${github_download}" "${tmpdir}" "${name}" "${os}" "${arch}" "${version}" "${format}" )
|
||||
|
||||
assertFileExists "${actual_filepath}" "download_asset os=${os} arch=${arch} format=${format}"
|
||||
|
||||
assertFilesEqual \
|
||||
"$(snapshot_dir)/${name}_${version}_${os}_${arch}.${format}" \
|
||||
"${actual_filepath}" \
|
||||
"unable to download os=${os} arch=${arch} format=${format}"
|
||||
|
||||
((DOWNLOAD_SNAPSHOT_POSITIVE_CASES++))
|
||||
|
||||
rm -rf -- "$tmpdir"
|
||||
}
|
||||
|
||||
|
||||
test_download_snapshot_asset_exercised_all_assets() {
|
||||
expected=$(snapshot_assets_count)
|
||||
|
||||
assertEquals "${expected}" "${DOWNLOAD_SNAPSHOT_POSITIVE_CASES}" "did not download all possible assets (missing an os/arch/format variant?)"
|
||||
}
|
||||
|
||||
# helper for asserting download_asset negative cases
|
||||
test_negative_snapshot_download_asset() {
|
||||
os="$1"
|
||||
arch="$2"
|
||||
format="$3"
|
||||
|
||||
# for troubleshooting
|
||||
# log_set_priority 10
|
||||
|
||||
name=${PROJECT_NAME}
|
||||
github_download=$(snapshot_download_url)
|
||||
version=$(snapshot_version)
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
|
||||
actual_filepath=$(download_asset "${github_download}" "${tmpdir}" "${name}" "${os}" "${arch}" "${version}" "${format}")
|
||||
|
||||
assertEquals "" "${actual_filepath}" "unable to download os=${os} arch=${arch} format=${format}"
|
||||
|
||||
rm -rf -- "$tmpdir"
|
||||
}
|
||||
|
||||
|
||||
worker_pid=$(setup_snapshot_server)
|
||||
trap 'teardown_snapshot_server ${worker_pid}' EXIT
|
||||
|
||||
# exercise all possible assets
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "amd64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "amd64" "rpm"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "amd64" "deb"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "arm64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "arm64" "rpm"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "arm64" "deb"
|
||||
run_test_case test_positive_snapshot_download_asset "darwin" "amd64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_download_asset "darwin" "amd64" "zip"
|
||||
run_test_case test_positive_snapshot_download_asset "darwin" "arm64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_download_asset "darwin" "arm64" "zip"
|
||||
run_test_case test_positive_snapshot_download_asset "windows" "amd64" "zip"
|
||||
# note: the mac signing process produces a dmg which is not part of the snapshot process (thus is not exercised here)
|
||||
|
||||
# let's make certain we covered all assets that were expected
|
||||
run_test_case test_download_snapshot_asset_exercised_all_assets
|
||||
|
||||
# make certain we handle missing assets alright
|
||||
run_test_case test_negative_snapshot_download_asset "bogus" "amd64" "zip"
|
||||
|
||||
trap - EXIT
|
||||
teardown_snapshot_server "${worker_pid}"
|
||||
43
test/install/2_download_release_asset_test.sh
Executable file
43
test/install/2_download_release_asset_test.sh
Executable file
@ -0,0 +1,43 @@
|
||||
. test_harness.sh
|
||||
|
||||
test_download_release_asset() {
|
||||
release="$1"
|
||||
os="$2"
|
||||
arch="$3"
|
||||
format="$4"
|
||||
expected_mime_type="$5"
|
||||
|
||||
# for troubleshooting
|
||||
# log_set_priority 10
|
||||
|
||||
name=${PROJECT_NAME}
|
||||
version=$(tag_to_version ${release})
|
||||
github_download="https://github.com/${OWNER}/${REPO}/releases/download/${release}"
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
|
||||
actual_filepath=$(download_asset "${github_download}" "${tmpdir}" "${name}" "${os}" "${arch}" "${version}" "${format}" )
|
||||
|
||||
assertFileExists "${actual_filepath}" "download_asset os=${os} arch=${arch} format=${format}"
|
||||
|
||||
actual_mime_type=$(file -b --mime-type ${actual_filepath})
|
||||
|
||||
assertEquals "${expected_mime_type}" "${actual_mime_type}" "unexpected mimetype for os=${os} arch=${arch} format=${format}"
|
||||
|
||||
rm -rf -- "$tmpdir"
|
||||
}
|
||||
|
||||
# always test against the latest release
|
||||
release=$(get_release_tag "${OWNER}" "${REPO}" "latest" )
|
||||
|
||||
# exercise all possible assets against a real github release (based on asset listing from https://github.com/anchore/syft/releases/tag/v0.36.0)
|
||||
run_test_case test_download_release_asset "${release}" "darwin" "amd64" "tar.gz" "application/gzip"
|
||||
run_test_case test_download_release_asset "${release}" "darwin" "arm64" "tar.gz" "application/gzip"
|
||||
run_test_case test_download_release_asset "${release}" "darwin" "arm64" "zip" "application/zip"
|
||||
run_test_case test_download_release_asset "${release}" "darwin" "amd64" "dmg" "application/zlib"
|
||||
run_test_case test_download_release_asset "${release}" "linux" "amd64" "tar.gz" "application/gzip"
|
||||
run_test_case test_download_release_asset "${release}" "linux" "amd64" "rpm" "application/x-rpm"
|
||||
run_test_case test_download_release_asset "${release}" "linux" "amd64" "deb" "application/vnd.debian.binary-package"
|
||||
run_test_case test_download_release_asset "${release}" "linux" "arm64" "tar.gz" "application/gzip"
|
||||
run_test_case test_download_release_asset "${release}" "linux" "arm64" "rpm" "application/x-rpm"
|
||||
run_test_case test_download_release_asset "${release}" "linux" "arm64" "deb" "application/vnd.debian.binary-package"
|
||||
98
test/install/3_install_asset_test.sh
Executable file
98
test/install/3_install_asset_test.sh
Executable file
@ -0,0 +1,98 @@
|
||||
. test_harness.sh
|
||||
|
||||
INSTALL_ARCHIVE_POSITIVE_CASES=0
|
||||
|
||||
# helper for asserting install_asset positive cases
|
||||
test_positive_snapshot_install_asset() {
|
||||
os="$1"
|
||||
arch="$2"
|
||||
format="$3"
|
||||
|
||||
# for troubleshooting
|
||||
# log_set_priority 10
|
||||
|
||||
name=${PROJECT_NAME}
|
||||
binary=$(get_binary_name "${os}" "${arch}" "${PROJECT_NAME}")
|
||||
github_download=$(snapshot_download_url)
|
||||
version=$(snapshot_version)
|
||||
|
||||
download_dir=$(mktemp -d)
|
||||
install_dir=$(mktemp -d)
|
||||
|
||||
download_and_install_asset "${github_download}" "${download_dir}" "${install_dir}" "${name}" "${os}" "${arch}" "${version}" "${format}" "${binary}"
|
||||
|
||||
assertEquals "0" "$?" "download/install did not succeed"
|
||||
|
||||
expected_path="${install_dir}/${binary}"
|
||||
assertFileExists "${expected_path}" "install_asset os=${os} arch=${arch} format=${format}"
|
||||
|
||||
build_dir_name="${name}"
|
||||
if [ "$os" == "darwin" ]; then
|
||||
# TODO: when we simplify the goreleaser build steps, this exception would not longer be expected
|
||||
build_dir_name="${name}-macos"
|
||||
fi
|
||||
|
||||
assertFilesEqual \
|
||||
"$(snapshot_dir)/${build_dir_name}_${os}_${arch}/${binary}" \
|
||||
"${expected_path}" \
|
||||
"unable to verify installation of os=${os} arch=${arch} format=${format}"
|
||||
|
||||
((INSTALL_ARCHIVE_POSITIVE_CASES++))
|
||||
|
||||
rm -rf -- "$download_dir"
|
||||
rm -rf -- "$install_dir"
|
||||
}
|
||||
|
||||
# helper for asserting install_asset negative cases
|
||||
test_negative_snapshot_install_asset() {
|
||||
os="$1"
|
||||
arch="$2"
|
||||
format="$3"
|
||||
|
||||
# for troubleshooting
|
||||
# log_set_priority 10
|
||||
|
||||
name=${PROJECT_NAME}
|
||||
binary=$(get_binary_name "${os}" "${arch}" "${PROJECT_NAME}")
|
||||
github_download=$(snapshot_download_url)
|
||||
version=$(snapshot_version)
|
||||
|
||||
download_dir=$(mktemp -d)
|
||||
install_dir=$(mktemp -d)
|
||||
|
||||
download_and_install_asset "${github_download}" "${download_dir}" "${install_dir}" "${name}" "${os}" "${arch}" "${version}" "${format}" "${binary}"
|
||||
|
||||
assertNotEquals "0" "$?" "download/install should have failed but did not"
|
||||
|
||||
rm -rf -- "$download_dir"
|
||||
rm -rf -- "$install_dir"
|
||||
}
|
||||
|
||||
|
||||
test_install_asset_exercised_all_archive_assets() {
|
||||
expected=$(snapshot_assets_archive_count)
|
||||
|
||||
assertEquals "${expected}" "${INSTALL_ARCHIVE_POSITIVE_CASES}" "did not download all possible archive assets (missing an os/arch/format variant?)"
|
||||
}
|
||||
|
||||
|
||||
worker_pid=$(setup_snapshot_server)
|
||||
trap 'teardown_snapshot_server ${worker_pid}' EXIT
|
||||
|
||||
# exercise all possible archive assets (not rpm/deb/dmg) against a snapshot build
|
||||
run_test_case test_positive_snapshot_install_asset "linux" "amd64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_install_asset "linux" "arm64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_install_asset "darwin" "amd64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_install_asset "darwin" "amd64" "zip"
|
||||
run_test_case test_positive_snapshot_install_asset "darwin" "arm64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_install_asset "darwin" "arm64" "zip"
|
||||
run_test_case test_positive_snapshot_install_asset "windows" "amd64" "zip"
|
||||
|
||||
# let's make certain we covered all assets that were expected
|
||||
run_test_case test_install_asset_exercised_all_archive_assets
|
||||
|
||||
# make certain we handle missing assets alright
|
||||
run_test_case test_negative_snapshot_install_asset "bogus" "amd64" "zip"
|
||||
|
||||
trap - EXIT
|
||||
teardown_snapshot_server "${worker_pid}"
|
||||
103
test/install/Makefile
Normal file
103
test/install/Makefile
Normal file
@ -0,0 +1,103 @@
|
||||
NAME=syft
|
||||
|
||||
IMAGE_NAME=$(NAME)-install.sh-env
|
||||
UBUNTU_IMAGE=$(IMAGE_NAME):ubuntu-20.04
|
||||
ALPINE_IMAGE=$(IMAGE_NAME):alpine-3.6
|
||||
BUSYBOX_IMAGE=busybox:1.35
|
||||
|
||||
ENVS=./environments
|
||||
DOCKER_RUN=docker run --rm -t -w /project/test/install -v $(shell pwd)/../../:/project
|
||||
UNIT=make unit-local
|
||||
|
||||
# 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 && syft version'
|
||||
|
||||
# CI cache busting values; change these if you want CI to not use previous stored cache
|
||||
INSTALL_TEST_CACHE_BUSTER=894d8ca
|
||||
|
||||
define title
|
||||
@printf '\n≡≡≡[ $(1) ]≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡\n'
|
||||
endef
|
||||
|
||||
.PHONY: test
|
||||
test: unit acceptance
|
||||
|
||||
.PHONY: ci-test-mac
|
||||
ci-test-mac: unit-local acceptance-local
|
||||
|
||||
# note: do not add acceptance-local to this list
|
||||
acceptance: acceptance-ubuntu-20.04 acceptance-alpine-3.6 acceptance-busybox-1.35
|
||||
|
||||
unit: unit-ubuntu-20.04
|
||||
|
||||
unit-local:
|
||||
$(call title,unit tests)
|
||||
@for f in $(shell ls *_test.sh); do echo "Running unit test suite '$${f}'"; bash $${f} || exit 1; done
|
||||
|
||||
acceptance-local:
|
||||
$(acceptance)
|
||||
|
||||
save: ubuntu-20.04 alpine-3.6 busybox-1.35
|
||||
@mkdir cache || true
|
||||
docker image save -o cache/ubuntu-env.tar $(UBUNTU_IMAGE)
|
||||
docker image save -o cache/alpine-env.tar $(ALPINE_IMAGE)
|
||||
docker image save -o cache/busybox-env.tar $(BUSYBOX_IMAGE)
|
||||
|
||||
load:
|
||||
docker image load -i cache/ubuntu-env.tar
|
||||
docker image load -i cache/alpine-env.tar
|
||||
docker image load -i cache/busybox-env.tar
|
||||
|
||||
## UBUNTU #######################################################
|
||||
|
||||
acceptance-ubuntu-20.04: ubuntu-20.04
|
||||
$(call title,ubuntu:20.04 - acceptance)
|
||||
$(DOCKER_RUN) $(UBUNTU_IMAGE) \
|
||||
$(ACCEPTANCE_CMD)
|
||||
|
||||
unit-ubuntu-20.04: ubuntu-20.04
|
||||
$(call title,ubuntu:20.04 - unit)
|
||||
$(DOCKER_RUN) $(UBUNTU_IMAGE) \
|
||||
$(UNIT)
|
||||
|
||||
ubuntu-20.04:
|
||||
$(call title,ubuntu:20.04 - build environment)
|
||||
docker build -t $(UBUNTU_IMAGE) -f $(ENVS)/Dockerfile-ubuntu-20.04 .
|
||||
|
||||
## ALPINE #######################################################
|
||||
|
||||
# note: unit tests cannot be run with sh (alpine dosn't have bash by default)
|
||||
|
||||
acceptance-alpine-3.6: alpine-3.6
|
||||
$(call title,alpine:3.6 - acceptance)
|
||||
$(DOCKER_RUN) $(ALPINE_IMAGE) \
|
||||
$(ACCEPTANCE_CMD)
|
||||
|
||||
alpine-3.6:
|
||||
$(call title,alpine:3.6 - build environment)
|
||||
docker build -t $(ALPINE_IMAGE) -f $(ENVS)/Dockerfile-alpine-3.6 .
|
||||
|
||||
## BUSYBOX #######################################################
|
||||
|
||||
# note: unit tests cannot be run with sh (busybox dosn't have bash by default)
|
||||
|
||||
# note: busybox by default will not have cacerts, so you will get TLS warnings (we want to test under these conditions)
|
||||
|
||||
acceptance-busybox-1.35: busybox-1.35
|
||||
$(call title,busybox-1.35 - acceptance)
|
||||
$(DOCKER_RUN) $(BUSYBOX_IMAGE) \
|
||||
$(ACCEPTANCE_CMD)
|
||||
@echo "\n*** test note: you should see syft spit out a 'x509: certificate signed by unknown authority' error --this is expected ***"
|
||||
|
||||
busybox-1.35:
|
||||
$(call title,busybox-1.35 - build environment)
|
||||
docker pull $(BUSYBOX_IMAGE)
|
||||
|
||||
## For CI ########################################################
|
||||
|
||||
.PHONY: cache.fingerprint
|
||||
cache.fingerprint:
|
||||
$(call title,Install test fixture fingerprint)
|
||||
@find ./environments/* -type f -exec md5sum {} + | awk '{print $1}' | sort | tee /dev/stderr | md5sum | tee cache.fingerprint && echo "$(INSTALL_TEST_CACHE_BUSTER)" >> cache.fingerprint
|
||||
2
test/install/environments/Dockerfile-alpine-3.6
Normal file
2
test/install/environments/Dockerfile-alpine-3.6
Normal file
@ -0,0 +1,2 @@
|
||||
FROM alpine:3.6
|
||||
RUN apk update && apk add python3 wget unzip make ca-certificates
|
||||
2
test/install/environments/Dockerfile-ubuntu-20.04
Normal file
2
test/install/environments/Dockerfile-ubuntu-20.04
Normal file
@ -0,0 +1,2 @@
|
||||
FROM ubuntu:20.04
|
||||
RUN apt update -y && apt install make python3 curl unzip -y
|
||||
68
test/install/github_test.sh
Executable file
68
test/install/github_test.sh
Executable file
@ -0,0 +1,68 @@
|
||||
. test_harness.sh
|
||||
|
||||
# check that we can extract single json values
|
||||
test_extract_json_value() {
|
||||
fixture=./test-fixtures/github-api-syft-v0.36.0-release.json
|
||||
content=$(cat ${fixture})
|
||||
|
||||
actual=$(extract_json_value "${content}" "tag_name")
|
||||
assertEquals "v0.36.0" "${actual}" "unable to find tag_name"
|
||||
|
||||
actual=$(extract_json_value "${content}" "id")
|
||||
assertEquals "57501596" "${actual}" "unable to find tag_name"
|
||||
}
|
||||
|
||||
run_test_case test_extract_json_value
|
||||
|
||||
|
||||
# check that we can extract github release tag from github api json
|
||||
test_github_release_tag() {
|
||||
fixture=./test-fixtures/github-api-syft-v0.36.0-release.json
|
||||
content=$(cat ${fixture})
|
||||
|
||||
actual=$(github_release_tag "${content}")
|
||||
assertEquals "v0.36.0" "${actual}" "unable to find release tag"
|
||||
}
|
||||
|
||||
run_test_case test_github_release_tag
|
||||
|
||||
|
||||
# download a known good github release checksums and compare against a test-fixture
|
||||
test_download_github_release_checksums() {
|
||||
tmpdir=$(mktemp -d)
|
||||
|
||||
tag=v0.36.0
|
||||
github_download="https://github.com/anchore/syft/releases/download/${tag}"
|
||||
name=${PROJECT_NAME}
|
||||
version=$(tag_to_version "${tag}")
|
||||
|
||||
actual_filepath=$(download_github_release_checksums "${github_download}" "${name}" "${version}" "${tmpdir}")
|
||||
assertFilesEqual \
|
||||
"./test-fixtures/syft_0.36.0_checksums.txt" \
|
||||
"${actual_filepath}" \
|
||||
"unable to find release tag"
|
||||
|
||||
rm -rf -- "$tmpdir"
|
||||
}
|
||||
|
||||
run_test_case test_download_github_release_checksums
|
||||
|
||||
|
||||
# download a checksums file from a locally served-up snapshot directory and compare against the file in the snapshot dir
|
||||
test_download_github_release_checksums_snapshot() {
|
||||
tmpdir=$(mktemp -d)
|
||||
|
||||
github_download=$(snapshot_download_url)
|
||||
name=${PROJECT_NAME}
|
||||
version=$(snapshot_version)
|
||||
|
||||
actual_filepath=$(download_github_release_checksums "${github_download}" "${name}" "${version}" "${tmpdir}")
|
||||
assertFilesEqual \
|
||||
"$(snapshot_checksums_path)" \
|
||||
"${actual_filepath}" \
|
||||
"unable to find release tag"
|
||||
|
||||
rm -rf -- "$tmpdir"
|
||||
}
|
||||
|
||||
run_test_case_with_snapshot_release test_download_github_release_checksums_snapshot
|
||||
@ -0,0 +1 @@
|
||||
{"id":57501596,"tag_name":"v0.36.0","update_url":"/anchore/syft/releases/tag/v0.36.0","update_authenticity_token":"7XbNZgRHpbHegdv-xRlbe84Y983YgyXa3YKWwv_e0ocqTHagsHq5dxCTQUQnuX3vbsgdWQU3A3__hkVNhKGHSg","delete_url":"/anchore/syft/releases/tag/v0.36.0","delete_authenticity_token":"6tLaRtXKUc-zz4tHIwCbbD7CksxIHK5imZE1gnA39oVCe6fYux5a8cPD9J52kGUzM1Hs9JPBjceG7yyszBk_2A","edit_url":"/anchore/syft/releases/edit/v0.36.0"}
|
||||
@ -0,0 +1,11 @@
|
||||
123745ee29779018ab386223a900f8cc704aa577f57ca43c157147c53c998a77 syft_0.35.1-SNAPSHOT-d461f63_linux_arm64.deb
|
||||
2083c5ad471028212e5ca72fdd3d60204052dbf3a9148c9579deac6af7865a3a syft_0.35.1-SNAPSHOT-d461f63_linux_arm64.tar.gz
|
||||
6b95e8b17fdbb5da094c2251c8ee5a8e97e6059b6556308f1ff2b657a6a080bc syft_0.35.1-SNAPSHOT-d461f63_darwin_x86_64.tar.gz
|
||||
940ea13dceedfcf3cf0ee2be24447123bf7efdb034c9f923e35549537b094aaa syft_0.35.1-SNAPSHOT-d461f63_Windows_x86_64.zip
|
||||
a96efc4139c79e0ecb526c7ab7c90fc94ee89c871c006c1089eb7c40c345ea65 syft_0.35.1-SNAPSHOT-d461f63_linux_x86_64.tar.gz
|
||||
b120a661ae5e24edc4b2c7932d5b4c9a54d6a90ceced6ba0acb9984ac45c0a4e syft_0.35.1-SNAPSHOT-d461f63_linux_arm64.rpm
|
||||
d1bc4ac460d5bd5bc173425e32b974a0a0d06f892bef4ab5b431394063b2963a syft_0.35.1-SNAPSHOT-d461f63_linux_amd64.rpm
|
||||
d65f963160acdc47a0f037bb42993866696181350e9901b8ad3d79f2dea35939 syft_0.35.1-SNAPSHOT-d461f63_darwin_arm64.zip
|
||||
d978c2bffaad36ea833203377f808725a4d3f8fd486f15552759f63909b210ba syft_0.35.1-SNAPSHOT-d461f63_darwin_arm64.tar.gz
|
||||
da76cc564d8e597f9c5b33423d2280eb6bf65ba2f2092d7851cdd67718e0cbe1 syft_0.35.1-SNAPSHOT-d461f63_darwin_amd64.zip
|
||||
e75f4cbf5c2b05663f49f683f99ed01d8e6ebe0e082631461dceae6641c3103f syft_0.35.1-SNAPSHOT-d461f63_linux_amd64.deb
|
||||
8
test/install/test-fixtures/syft_0.36.0_checksums.txt
Normal file
8
test/install/test-fixtures/syft_0.36.0_checksums.txt
Normal file
@ -0,0 +1,8 @@
|
||||
16541ac64378d4216ac9fe2065d20e188a89e8c9cce4e637940a559daddb213b syft_0.36.0_linux_amd64.rpm
|
||||
4596fdbb491251f6d8e3be38b64d361a9a35cf6a88da6bdad62c019511ffb1a5 syft_0.36.0_linux_amd64.deb
|
||||
5a69df410597d8649071b3419c17829f60d9f6f00edc8856b681842c2151f83c syft_0.36.0_linux_amd64.tar.gz
|
||||
5c06f09d370740fb017c6a51657911a87860450d929fa28a9eff1cf00faac303 syft_0.36.0_darwin_arm64.tar.gz
|
||||
71403ffa346612f9203ce7657d2d191794a0e4367da355605377b8b5d457b7ef syft_0.36.0_linux_arm64.tar.gz
|
||||
75989a83f0d361969b5f88f3ee3807ed9ddbdf9fae13b6edce1839cf5952a36c syft_0.36.0_linux_arm64.deb
|
||||
860b42c5d7d03e484c87e18031e6a473f48d3b088a6268fcf8f9567d5b5c90d3 syft_0.36.0_linux_arm64.rpm
|
||||
fba022c6fac6f2d2f648295af78f86e873488565e41a252a97efafe75622ccf6 syft_0.36.0_darwin_amd64.tar.gz
|
||||
163
test/install/test_harness.sh
Normal file
163
test/install/test_harness.sh
Normal file
@ -0,0 +1,163 @@
|
||||
# disable using the install.sh entrypoint such that we can unit test
|
||||
# script functions without invoking main()
|
||||
TEST_INSTALL_SH=true
|
||||
|
||||
. ../../install.sh
|
||||
set -u
|
||||
|
||||
assertTrue() {
|
||||
if eval "$1"; then
|
||||
echo "assertTrue failed: $2"
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
assertFalse() {
|
||||
if eval "$1"; then
|
||||
echo "assertFalse failed: $2"
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
assertEquals() {
|
||||
want=$1
|
||||
got=$2
|
||||
msg=$3
|
||||
if [ "$want" != "$got" ]; then
|
||||
echo "assertEquals failed: want='$want' got='$got' $msg"
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
assertFilesDoesNotExist() {
|
||||
path="$1"
|
||||
msg=$2
|
||||
if [ -f "${path}" ]; then
|
||||
echo "assertFilesDoesNotExist failed: path exists '$path': $msg"
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
assertFileExists() {
|
||||
path="$1"
|
||||
msg=$2
|
||||
if [ ! -f "${path}" ]; then
|
||||
echo "assertFileExists failed: path does not exist '$path': $msg"
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
assertFilesEqual() {
|
||||
want=$1
|
||||
got=$2
|
||||
msg=$3
|
||||
|
||||
diff "$1" "$2"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "assertFilesEqual failed: $msg"
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
assertNotEquals() {
|
||||
want=$1
|
||||
got=$2
|
||||
msg=$3
|
||||
if [ "$want" = "$got" ]; then
|
||||
echo "assertNotEquals failed: want='$want' got='$got' $msg"
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
log_test_case() {
|
||||
echo " running $@"
|
||||
}
|
||||
|
||||
run_test_case_with_snapshot_release() {
|
||||
log_test_case ${@:1}
|
||||
|
||||
worker_pid=$(setup_snapshot_server)
|
||||
trap "teardown_snapshot_server $worker_pid" EXIT
|
||||
|
||||
# run test function with all arguments
|
||||
${@:1}
|
||||
|
||||
trap - EXIT
|
||||
teardown_snapshot_server "${worker_pid}"
|
||||
}
|
||||
|
||||
serve_port=8000
|
||||
|
||||
setup_snapshot_server() {
|
||||
# if you want to see proof in the logs, feel free to adjust the redirection
|
||||
python3 -m http.server --directory "$(snapshot_dir)" $serve_port &> /dev/null &
|
||||
worker_pid=$!
|
||||
|
||||
# it takes some time for the server to be ready...
|
||||
sleep 0.5
|
||||
|
||||
echo "$worker_pid"
|
||||
}
|
||||
|
||||
teardown_snapshot_server() {
|
||||
worker_pid="$1"
|
||||
|
||||
kill $worker_pid
|
||||
}
|
||||
|
||||
snapshot_version() {
|
||||
partial=$(ls ../../snapshot/*_checksums.txt | grep -o "_.*_checksums.txt")
|
||||
partial="${partial%_checksums.txt}"
|
||||
echo "${partial#_}"
|
||||
}
|
||||
|
||||
snapshot_download_url() {
|
||||
echo "localhost:${serve_port}"
|
||||
}
|
||||
|
||||
snapshot_dir() {
|
||||
echo "../../snapshot"
|
||||
}
|
||||
|
||||
snapshot_checksums_path() {
|
||||
echo "$(ls $(snapshot_dir)/*_checksums.txt)"
|
||||
}
|
||||
|
||||
snapshot_assets_count() {
|
||||
# example output before wc -l:
|
||||
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_linux_arm64.deb
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_linux_arm64.tar.gz
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_linux_amd64.rpm
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_darwin_arm64.tar.gz
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_linux_amd64.deb
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_linux_arm64.rpm
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_darwin_amd64.zip
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_windows_amd64.zip
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_darwin_arm64.zip
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_linux_amd64.tar.gz
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_darwin_amd64.tar.gz
|
||||
|
||||
echo "$(find ../../snapshot -maxdepth 1 -type f | grep 'syft_' | grep -v checksums | wc -l | tr -d '[:space:]')"
|
||||
}
|
||||
|
||||
|
||||
snapshot_assets_archive_count() {
|
||||
# example output before wc -l:
|
||||
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_linux_arm64.tar.gz
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_darwin_arm64.tar.gz
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_darwin_amd64.zip
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_windows_amd64.zip
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_darwin_arm64.zip
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_linux_amd64.tar.gz
|
||||
# ../../snapshot/syft_0.36.0-SNAPSHOT-e5e847a_darwin_amd64.tar.gz
|
||||
|
||||
echo "$(find ../../snapshot -maxdepth 1 -type f | grep 'syft_' | grep 'tar\|zip' | wc -l | tr -d '[:space:]')"
|
||||
}
|
||||
|
||||
|
||||
run_test_case() {
|
||||
log_test_case ${@:1}
|
||||
${@:1}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user