Files
zot/Makefile
T
Andrei Aaron 9757f7cf41 ci: fix golangci-lint install URL (#4052)
1. Cause
SBOM assets were added to the release checksum file, so you get two lines that contain the same substring, e.g. …linux-amd64.tar.gz and …linux-amd64.tar.gz.sbom.json.
The old install.sh logic used something like grep "${BASENAME}", so both lines matched. That breaks want (wrong or ambiguous hash) and shows up as checksum verification errors (including the 8df… vs fd3… style mismatch you debugged).

2. The upstream fix is in https://github.com/golangci/golangci-lint/pull/6539
The matcher was changed so the checksum line must end with the archive name — i.e. grep "${BASENAME}$" — so the .sbom.json line no longer matches.

3. In the same thread they say master on raw.githubusercontent.com is not the right branch anymore and recommend the canonical installer URL:
https://golangci-lint.run/install.sh
(see the PR description and local install / binaries.)

Signed-off-by: Andrei Aaron <andreifdaaron@gmail.com>
2026-05-10 20:35:59 +03:00

678 lines
27 KiB
Makefile

export GO111MODULE=on
export GOEXPERIMENT=jsonv2
SHELL := /bin/bash
TOP_LEVEL=$(shell git rev-parse --show-toplevel)
COMMIT_HASH=$(shell git describe --always --tags --long)
RELEASE_TAG=$(shell git describe --tags --abbrev=0)
GO_VERSION=$(shell go version | awk '{print $$3}')
COMMIT ?= $(if $(shell git status --porcelain --untracked-files=no),$(COMMIT_HASH)-dirty,$(COMMIT_HASH))
CONTAINER_RUNTIME := $(shell command -v podman 2> /dev/null || echo docker)
TMPDIR := $(shell mktemp -d)
TOOLSDIR := $(shell pwd)/hack/tools
PATH := bin:$(TOOLSDIR)/bin:$(PATH)
STACKER := $(shell which stacker)
GOLINTER := $(TOOLSDIR)/bin/golangci-lint
GOLINTER_VERSION := v2.6.2
NOTATION := $(TOOLSDIR)/bin/notation
NOTATION_VERSION := 1.3.2
COSIGN := $(TOOLSDIR)/bin/cosign
COSIGN_VERSION := 3.0.6
HELM := $(TOOLSDIR)/bin/helm
ORAS := $(TOOLSDIR)/bin/oras
ORAS_VERSION := 1.2.1
HELM_VERSION := v3.9.1
REGCLIENT := $(TOOLSDIR)/bin/regctl
REGCLIENT_VERSION := v0.10.0
CRICTL := $(TOOLSDIR)/bin/crictl
CRICTL_VERSION := v1.26.1
ACTION_VALIDATOR := $(TOOLSDIR)/bin/action-validator
ACTION_VALIDATOR_VERSION := v0.5.3
ZUI_BUILD_PATH := ""
ZUI_VERSION := commit-c90dd09
ZUI_REPO_OWNER := project-zot
ZUI_REPO_NAME := zui
SWAGGER_VERSION := v1.16.2
STACKER := $(TOOLSDIR)/bin/stacker
STACKER_VERSION := v1.1.0-rc3
KIND := $(TOOLSDIR)/bin/kind
KIND_VERSION := v0.31.0
BATS := $(TOOLSDIR)/bin/bats
TESTDATA := $(TOP_LEVEL)/test/data
OS ?= $(shell go env GOOS)
ARCH ?= $(shell go env GOARCH)
GREP_BIN_PATH ?= $(shell which grep)
BLACKBOX_DOCKER_ENV = BUILDX_NO_DEFAULT_ATTESTATIONS=1 DOCKER_DEFAULT_PLATFORM=linux/amd64
MODULE_PATH := $(shell go list -m)
BUILDINFO_PACKAGE := $(MODULE_PATH)/pkg/buildinfo
BUILDINFO_RELEASE_TAG := $(BUILDINFO_PACKAGE).ReleaseTag
BUILDINFO_COMMIT := $(BUILDINFO_PACKAGE).Commit
BUILDINFO_BINARY_TYPE := $(BUILDINFO_PACKAGE).BinaryType
BUILDINFO_GO_VERSION := $(BUILDINFO_PACKAGE).GoVersion
PROTOC := $(TOOLSDIR)/bin/protoc
PROTOC_VERSION := 24.4
GO_PROTOC_VERSION := 1.31.0
HOST_OS := $(shell go env GOOS)
HOST_ARCH := $(shell go env GOARCH)
ifeq ($(HOST_OS),linux)
PROTOC_OS := linux
else ifeq ($(HOST_OS),darwin)
PROTOC_OS := osx
endif
ifeq ($(HOST_ARCH),amd64)
PROTOC_ARCH := x86_64
else ifeq ($(HOST_ARCH),arm64)
PROTOC_ARCH := aarch_64
endif
BENCH_OUTPUT ?= stdout
ALL_EXTENSIONS = debug,imagetrust,lint,metrics,mgmt,profile,scrub,search,sync,ui,userprefs,events
EXTENSIONS ?= sync,search,scrub,metrics,lint,ui,mgmt,profile,userprefs,imagetrust,events
UI_DEPENDENCIES := search,mgmt,userprefs
# freebsd is not supported for pie builds if CGO is disabled
# see supported platforms at https://cs.opensource.google/go/go/+/master:src/internal/platform/supported.go;l=222-231;drc=d7fcb5cf80953f1d63246f1ae9defa60c5ce2d76
BUILDMODE_FLAGS := -buildmode=pie
BASE_IMAGE=gcr.io/distroless/base-nossl-debian13:latest-$(ARCH)
ifeq ($(OS),freebsd)
BUILDMODE_FLAGS=
BASE_IMAGE=freebsd/freebsd-static:14.3
endif
BIN_EXT :=
ifeq ($(OS),windows)
BIN_EXT=.exe
endif
comma:= ,
space := $(null) #
hyphen:= -
merge-ui-extensions=$(subst $(1),$(2),$(if $(findstring ui,$(3)),$(3)$(1)$(4),$(3)))
merged-extensions = $(call merge-ui-extensions,$(comma),$(space),$(EXTENSIONS),$(UI_DEPENDENCIES))
filter-valid = $(foreach ext, $(merged-extensions), $(if $(findstring $(ext),$(ALL_EXTENSIONS)),$(ext),$(error unknown extension: $(ext))))
add-extensions = $(subst $(1),$(2),$(sort $(filter-valid)))
BUILD_LABELS = $(call add-extensions,$(space),$(comma))
extended-name = -$(subst $(comma),$(hyphen),$(BUILD_LABELS))
GO_CMD_TAGS := $(if $(BUILD_LABELS),-tags $(BUILD_LABELS),)
BATS_TEST_FILE_PATH ?= replace_me
ifeq ($(BATS_VERBOSITY),2)
BATS_FLAGS = --trace --verbose-run --show-output-of-passing-tests --print-output-on-failure
else ifeq ($(BATS_VERBOSITY),1)
BATS_FLAGS = --trace --verbose-run --print-output-on-failure
else
BATS_FLAGS = --print-output-on-failure
endif
.PHONY: all
all: swaggercheck binary binary-minimal binary-debug cli bench exporter-minimal verify-config check check-gh-actions test covhtml
.PHONY: modtidy
modtidy:
go mod tidy
.PHONY: modcheck
modcheck: modtidy
$(eval UNCOMMITED_FILES = $(shell git status --porcelain | grep -c 'go.mod\|go.sum'))
@if [ $(UNCOMMITED_FILES) != 0 ]; then \
echo "Updated go.mod and/or go.sum have uncommitted changes, commit the changes accordingly ";\
git status;\
exit 1;\
fi
.PHONY: swaggercheck
swaggercheck: swagger
$(eval UNCOMMITED_FILES = $(shell git status --porcelain | grep -c swagger))
@if [ $(UNCOMMITED_FILES) != 0 ]; then \
echo "Updated swagger files uncommitted, make sure all swagger files are committed:";\
git status;\
exit 1;\
fi
.PHONY: build-metadata
build-metadata: $(if $(findstring ui,$(BUILD_LABELS)), ui)
echo "Imports: \n"
env GOEXPERIMENT=jsonv2 go list $(GO_CMD_TAGS) -f '{{ join .Imports "\n" }}' ./... | sort -u
echo "\n Files: \n"
env GOEXPERIMENT=jsonv2 go list $(GO_CMD_TAGS) -f '{{ join .GoFiles "\n" }}' ./... | sort -u
.PHONY: gen-protobuf
gen-protobuf: $(PROTOC)
$(PROTOC) --experimental_allow_proto3_optional \
--proto_path=$(TOP_LEVEL)/pkg/meta/proto \
--go_out=$(TOP_LEVEL)/pkg/meta/proto \
--go_opt='Moci/oci.proto=./gen' \
--go_opt='Mmeta/meta.proto=./gen' \
--go_opt='Moci/config.proto=./gen' \
--go_opt='Moci/manifest.proto=./gen' \
--go_opt='Moci/index.proto=./gen' \
--go_opt='Moci/descriptor.proto=./gen' \
--go_opt='Moci/versioned.proto=./gen' \
$(TOP_LEVEL)/pkg/meta/proto/meta/meta.proto
$(PROTOC) --experimental_allow_proto3_optional \
--proto_path=$(TOP_LEVEL)/pkg/meta/proto \
--go_out=$(TOP_LEVEL)/pkg/meta/proto \
--go_opt='Moci/versioned.proto=./gen' \
$(TOP_LEVEL)/pkg/meta/proto/oci/versioned.proto
$(PROTOC) --experimental_allow_proto3_optional \
--proto_path=$(TOP_LEVEL)/pkg/meta/proto \
--go_out=$(TOP_LEVEL)/pkg/meta/proto \
--go_opt='Moci/descriptor.proto=./gen' \
$(TOP_LEVEL)/pkg/meta/proto/oci/descriptor.proto
$(PROTOC) --experimental_allow_proto3_optional \
--proto_path=$(TOP_LEVEL)/pkg/meta/proto \
--go_out=$(TOP_LEVEL)/pkg/meta/proto \
--go_opt='Moci/descriptor.proto=./gen' \
--go_opt='Moci/versioned.proto=./gen' \
--go_opt='Moci/index.proto=./gen' \
$(TOP_LEVEL)/pkg/meta/proto/oci/index.proto
$(PROTOC) --experimental_allow_proto3_optional \
--proto_path=$(TOP_LEVEL)/pkg/meta/proto \
--go_out=$(TOP_LEVEL)/pkg/meta/proto \
--go_opt='Moci/oci.proto=./gen' \
--go_opt='Moci/descriptor.proto=./gen' \
--go_opt='Moci/config.proto=./gen' \
$(TOP_LEVEL)/pkg/meta/proto/oci/config.proto
$(PROTOC) --experimental_allow_proto3_optional \
--proto_path=$(TOP_LEVEL)/pkg/meta/proto \
--go_out=$(TOP_LEVEL)/pkg/meta/proto \
--go_opt='Moci/versioned.proto=./gen' \
--go_opt='Moci/descriptor.proto=./gen' \
--go_opt='Moci/manifest.proto=./gen' \
$(TOP_LEVEL)/pkg/meta/proto/oci/manifest.proto
.PHONY: binary-minimal
binary-minimal: EXTENSIONS=
binary-minimal: build-metadata
env CGO_ENABLED=0 GOEXPERIMENT=jsonv2 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zot-$(OS)-$(ARCH)-minimal$(BIN_EXT) $(BUILDMODE_FLAGS) -v -trimpath -ldflags "-X $(BUILDINFO_RELEASE_TAG)=${RELEASE_TAG} -X $(BUILDINFO_COMMIT)=${COMMIT} -X $(BUILDINFO_BINARY_TYPE)=minimal -X $(BUILDINFO_GO_VERSION)=${GO_VERSION} -s -w" ./cmd/zot
.PHONY: binary
binary: $(if $(findstring ui,$(BUILD_LABELS)), ui)
binary: build-metadata
env CGO_ENABLED=0 GOEXPERIMENT=jsonv2 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zot-$(OS)-$(ARCH)$(BIN_EXT) $(BUILDMODE_FLAGS) $(GO_CMD_TAGS) -v -trimpath -ldflags "-X $(BUILDINFO_RELEASE_TAG)=${RELEASE_TAG} -X $(BUILDINFO_COMMIT)=${COMMIT} -X $(BUILDINFO_BINARY_TYPE)=$(extended-name) -X $(BUILDINFO_GO_VERSION)=${GO_VERSION} -s -w" ./cmd/zot
.PHONY: binary-debug
binary-debug: $(if $(findstring ui,$(BUILD_LABELS)), ui)
binary-debug: swaggercheck build-metadata
env CGO_ENABLED=0 GOEXPERIMENT=jsonv2 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zot-$(OS)-$(ARCH)-debug$(BIN_EXT) $(BUILDMODE_FLAGS) -tags $(BUILD_LABELS),debug -v -gcflags all='-N -l' -ldflags "-X $(BUILDINFO_RELEASE_TAG)=${RELEASE_TAG} -X $(BUILDINFO_COMMIT)=${COMMIT} -X $(BUILDINFO_BINARY_TYPE)=$(extended-name) -X $(BUILDINFO_GO_VERSION)=${GO_VERSION}" ./cmd/zot
.PHONY: cli
cli: build-metadata
env CGO_ENABLED=0 GOEXPERIMENT=jsonv2 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zli-$(OS)-$(ARCH)$(BIN_EXT) $(BUILDMODE_FLAGS) -tags $(BUILD_LABELS),search -v -trimpath -ldflags "-X $(BUILDINFO_COMMIT)=${COMMIT} -X $(BUILDINFO_BINARY_TYPE)=$(extended-name) -X $(BUILDINFO_GO_VERSION)=${GO_VERSION} -s -w" ./cmd/zli
.PHONY: bench
bench: build-metadata
env CGO_ENABLED=0 GOEXPERIMENT=jsonv2 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zb-$(OS)-$(ARCH)$(BIN_EXT) $(BUILDMODE_FLAGS) $(GO_CMD_TAGS) -v -trimpath -ldflags "-X $(BUILDINFO_COMMIT)=${COMMIT} -X $(BUILDINFO_BINARY_TYPE)=$(extended-name) -X $(BUILDINFO_GO_VERSION)=${GO_VERSION} -s -w" ./cmd/zb
.PHONY: exporter-minimal
exporter-minimal: EXTENSIONS=
exporter-minimal: build-metadata
env CGO_ENABLED=0 GOEXPERIMENT=jsonv2 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zxp-$(OS)-$(ARCH)$(BIN_EXT) $(BUILDMODE_FLAGS) -v -trimpath ./cmd/zxp
.PHONY: test-prereq
test-prereq: check-skopeo $(TESTDATA) $(ORAS)
.PHONY: test-extended
test-extended: $(if $(findstring ui,$(BUILD_LABELS)), ui)
test-extended: testdata-images
env GOEXPERIMENT=jsonv2 go test -failfast $(GO_CMD_TAGS) -trimpath -race -timeout 20m -cover -coverpkg ./... -coverprofile=coverage-extended.txt -covermode=atomic ./...
rm -rf /tmp/getter*; rm -rf /tmp/trivy*
.PHONY: test-minimal
test-minimal: testdata-images
env GOEXPERIMENT=jsonv2 go test -failfast -trimpath -race -timeout 12m -cover -coverpkg ./... -coverprofile=coverage-minimal.txt -covermode=atomic ./...
rm -rf /tmp/getter*; rm -rf /tmp/trivy*
.PHONY: test-devmode
test-devmode: $(if $(findstring ui,$(BUILD_LABELS)), ui)
test-devmode:
env GOEXPERIMENT=jsonv2 go test -failfast -tags dev,$(BUILD_LABELS) -trimpath -race -timeout 15m -cover -coverpkg ./... -coverprofile=coverage-dev-extended.txt -covermode=atomic ./pkg/test/... ./pkg/api/... ./pkg/storage/... ./pkg/extensions/sync/... -run ^TestInject
rm -rf /tmp/getter*; rm -rf /tmp/trivy*
env GOEXPERIMENT=jsonv2 go test -failfast -tags dev -trimpath -race -cover -coverpkg ./... -coverprofile=coverage-dev-minimal.txt -covermode=atomic ./pkg/test/... ./pkg/storage/... ./pkg/extensions/sync/... -run ^TestInject
rm -rf /tmp/getter*; rm -rf /tmp/trivy*
env GOEXPERIMENT=jsonv2 go test -failfast -tags stress,$(BUILD_LABELS) -trimpath -race -timeout 15m ./pkg/cli/server/stress_test.go
.PHONY: test
test: $(if $(findstring ui,$(BUILD_LABELS)), ui)
test: test-extended test-minimal test-devmode
.PHONY: privileged-test
privileged-test: $(if $(findstring ui,$(BUILD_LABELS)), ui)
privileged-test:
env GOEXPERIMENT=jsonv2 go test -failfast -tags needprivileges,$(BUILD_LABELS) -trimpath -race -timeout 15m -cover -coverpkg ./... -coverprofile=coverage-needprivileges-local.txt -covermode=atomic ./pkg/storage/local/... ./pkg/cli/client/... -run ^TestElevatedPrivileges
env GOEXPERIMENT=jsonv2 go test -failfast -tags needprivileges,$(BUILD_LABELS) -trimpath -race -timeout 15m -cover -coverpkg ./... -coverprofile=coverage-needprivileges-gcs.txt -covermode=atomic ./pkg/storage/gcs/...
.PHONY: testdata-certs
testdata-certs:
mkdir -p ${TESTDATA}; \
cd ${TESTDATA}; ../scripts/gen_certs.sh; \
mkdir -p noidentity; cd ${TESTDATA}/noidentity; ../../scripts/gen_nameless_certs.sh; \
chmod -R a=rwx ${TESTDATA}
.PHONY: testdata-images
testdata-images: check-skopeo
mkdir -p ${TESTDATA}; \
cd ${TOP_LEVEL}; \
skopeo --insecure-policy copy -q docker://public.ecr.aws/t0x7q1g8/centos:7 oci:${TESTDATA}/zot-test:0.0.1; \
skopeo --insecure-policy copy -q docker://public.ecr.aws/t0x7q1g8/centos:8 oci:${TESTDATA}/zot-cve-test:0.0.1; \
skopeo --insecure-policy copy -q docker://ghcr.io/project-zot/test-images/java:0.0.1 oci:${TESTDATA}/zot-cve-java-test:0.0.1; \
skopeo --insecure-policy copy -q docker://ghcr.io/project-zot/test-images/alpine:3.17.3 oci:${TESTDATA}/alpine:3.17.3; \
skopeo --insecure-policy copy -q docker://ghcr.io/project-zot/test-images/spring-web:5.3.31 oci:${TESTDATA}/spring-web:5.3.31; \
chmod -R a=rwx ${TESTDATA}
$(TESTDATA): testdata-certs testdata-images
ls -R -l ${TESTDATA}
.PHONY: run-bench
run-bench: binary bench
bin/zot-$(OS)-$(ARCH) serve examples/config-bench.json & echo $$! > zot.PID
curl --connect-timeout 3 --max-time 5 --retry 60 --retry-delay 1 --retry-max-time 180 --retry-connrefused http://localhost:8080/v2/
bin/zb-$(OS)-$(ARCH) -c 10 -n 100 -o $(BENCH_OUTPUT) http://localhost:8080
@if [ -e zot.PID ]; then \
kill -TERM $$(cat zot.PID) || true; \
fi; \
rm zot.PID
.PHONY: check-skopeo
check-skopeo:
skopeo -v || (echo "You need skopeo to be installed in order to run tests"; exit 1)
.PHONY: check-awslocal
check-awslocal:
awslocal --version || (echo "You need awslocal to be installed in order to run tests"; exit 1)
$(NOTATION):
mkdir -p $(TOOLSDIR)/bin
curl -Lo notation.tar.gz https://github.com/notaryproject/notation/releases/download/v$(NOTATION_VERSION)/notation_$(NOTATION_VERSION)_$(OS)_$(ARCH).tar.gz
tar xvzf notation.tar.gz -C $(TOOLSDIR)/bin notation
rm notation.tar.gz
$(ORAS):
mkdir -p $(TOOLSDIR)/bin
curl -Lo oras.tar.gz https://github.com/oras-project/oras/releases/download/v$(ORAS_VERSION)/oras_$(ORAS_VERSION)_$(OS)_$(ARCH).tar.gz
tar xvzf oras.tar.gz -C $(TOOLSDIR)/bin oras
rm oras.tar.gz
$(HELM):
mkdir -p $(TOOLSDIR)/bin
curl -Lo helm.tar.gz https://get.helm.sh/helm-$(HELM_VERSION)-$(OS)-$(ARCH).tar.gz
tar xvzf helm.tar.gz --strip-components=1 -C $(TOOLSDIR)/bin $(OS)-$(ARCH)/helm
rm helm.tar.gz
$(REGCLIENT):
mkdir -p $(TOOLSDIR)/bin
curl -Lo regctl https://github.com/regclient/regclient/releases/download/$(REGCLIENT_VERSION)/regctl-$(OS)-$(ARCH)
mv regctl $(TOOLSDIR)/bin/regctl
chmod +x $(TOOLSDIR)/bin/regctl
$(CRICTL):
mkdir -p $(TOOLSDIR)/bin
curl -Lo crictl.tar.gz https://github.com/kubernetes-sigs/cri-tools/releases/download/$(CRICTL_VERSION)/crictl-$(CRICTL_VERSION)-$(OS)-$(ARCH).tar.gz
tar xvzf crictl.tar.gz && rm crictl.tar.gz
mv crictl $(TOOLSDIR)/bin/crictl
chmod +x $(TOOLSDIR)/bin/crictl
$(PROTOC):
mkdir -p $(TOOLSDIR)/bin
curl -Lo protoc.zip https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)-$(PROTOC_OS)-$(PROTOC_ARCH).zip
unzip -o -d $(TOOLSDIR) protoc.zip bin/protoc
rm protoc.zip
chmod +x $(PROTOC)
go install google.golang.org/protobuf/cmd/protoc-gen-go@v$(GO_PROTOC_VERSION)
$(ACTION_VALIDATOR):
mkdir -p $(TOOLSDIR)/bin
curl -Lo action-validator https://github.com/mpalmer/action-validator/releases/download/$(ACTION_VALIDATOR_VERSION)/action-validator_$(OS)_$(ARCH)
mv action-validator $(TOOLSDIR)/bin/action-validator
chmod +x $(TOOLSDIR)/bin/action-validator
.PHONY: check-gh-actions
check-gh-actions: check-compatibility $(ACTION_VALIDATOR)
for i in $$(ls .github/workflows/*); do $(ACTION_VALIDATOR) $$i; done
.PHONY: covhtml
covhtml:
go install github.com/wadey/gocovmerge@latest
gocovmerge coverage*.txt > coverage.txt
go tool cover -html=coverage.txt -o coverage.html
$(GOLINTER): $(TOOLSDIR)/.golangci-lint-$(GOLINTER_VERSION)
$(TOOLSDIR)/.golangci-lint-$(GOLINTER_VERSION):
mkdir -p $(TOOLSDIR)/bin
rm -f $(TOOLSDIR)/.golangci-lint-*
curl -sSfL https://golangci-lint.run/install.sh | sh -s -- -b $(TOOLSDIR)/bin $(GOLINTER_VERSION)
$(GOLINTER) version
touch $@
.PHONY: check-logs
check-logs:
@./scripts/check_logs.sh
.PHONY: check
check: $(if $(findstring ui,$(BUILD_LABELS)), ui)
check: ./.golangci.yaml $(GOLINTER)
mkdir -p pkg/extensions/build; touch pkg/extensions/build/.empty
$(GOLINTER) run --output.text.colors --build-tags ./...
$(GOLINTER) run --output.text.colors --build-tags $(BUILD_LABELS) ./...
$(GOLINTER) run --output.text.colors --build-tags debug ./pkg/debug/swagger/ ./pkg/debug/gqlplayground
$(GOLINTER) run --output.text.colors --build-tags dev ./pkg/test/inject/
$(GOLINTER) run --output.text.colors --build-tags stress ./pkg/cli/server/
$(GOLINTER) run --output.text.colors --build-tags needprivileges,$(BUILD_LABELS) ./pkg/cli/client/ ./pkg/storage/local/ ./pkg/storage/gcs/ ./pkg/api/config/
rm pkg/extensions/build/.empty
.PHONY: swagger
swagger:
swag -v || go install github.com/swaggo/swag/cmd/swag@$(SWAGGER_VERSION)
swag init --parseDependency -o swagger -g pkg/api/routes.go -q
.PHONY: update-licenses
# note: for predictable output of below sort command we use locale LC_ALL=C
update-licenses: check-linux
@echo "Detecting and updating licenses ... please be patient!"
go install github.com/google/go-licenses@latest
./scripts/update_licenses.sh
$(eval UNCOMMITED_FILES = $(shell git status --porcelain | grep -c THIRD-PARTY-LICENSES.md))
@if [ $(UNCOMMITED_FILES) != 0 ]; then \
echo "THIRD-PARTY-LICENSES.md file needs to be updated";\
git status;\
exit 1;\
fi
.PHONY: check-licenses
check-licenses:
# note: "printf" works for darwin instead of "echo -n"
go install github.com/google/go-licenses@latest
@for tag_set in "$(BUILD_LABELS)" ""; do \
echo Evaluating tag set: $$tag_set; \
for mod in $$(go list -m -f '{{if not (or .Indirect .Main)}}{{.Path}}{{end}}' all); do \
while [ x$$mod != x ]; do \
printf "Checking $$mod ... "; \
if [ -n "$$tag_set" ]; then \
result=$$(GOFLAGS="-tags=$${tag_set}" go-licenses check $$mod 2>&1); \
else \
result=$$(go-licenses check $$mod 2>&1); \
fi; \
if [ $$? -eq 0 ]; then \
echo OK; \
break; \
fi; \
echo "$${result}" | grep -q "Forbidden"; \
if [ $$? -eq 0 ]; then \
echo FAIL; \
exit 1; \
fi; \
echo "$${result}" | egrep -q "missing go.sum entry|no required module provides package|build constraints exclude all|updates to go.mod needed|non-Go code"; \
if [ $$? -eq 0 ]; then \
echo UNKNOWN; \
break; \
fi; \
done; \
done; \
done
.PHONY: clean
clean:
rm -f bin/z*
rm -rf hack
rm -rf test/data/zot-test
rm -rf test/data/zot-cve-test
rm -rf test/data/zot-cve-java-test
rm -rf pkg/extensions/build
.PHONY: run
run: binary
./bin/zot-$(OS)-$(ARCH) serve examples/config-test.json
.PHONY: verify-config
verify-config: _verify-config verify-config-warnings verify-config-commited verify-config-schema
.PHONY: _verify-config
_verify-config: binary
rm -f output.txt
$(foreach file, $(filter-out $(wildcard examples/config-*-credentials.json), $(wildcard examples/config-*)), ./bin/zot-$(OS)-$(ARCH) verify $(file) 2>&1 | tee -a output.txt || exit 1;)
.PHONY: verify-config-warnings
verify-config-warnings: _verify-config
$(eval WARNINGS = $(shell cat output.txt | grep -c '"warn"'))
$(eval ERRORS = $(shell cat output.txt | grep -c '"error"'))
@if [ $(WARNINGS) != 0 ] || [ $(ERRORS) != 0 ]; then \
echo "verify-config-warnings: warnings or errors found while verifying configs"; \
rm output.txt; \
exit 1; \
fi
rm -f output.txt
.PHONY: verify-config-commited
verify-config-commited: _verify-config
$(eval UNCOMMITED_FILES = $(shell git status --porcelain | grep -c examples/config-))
@if [ $(UNCOMMITED_FILES) != 0 ]; then \
echo "Uncommited config files, make sure all config files are commited. Verify might have changed a config file.";\
exit 1;\
fi; \
.PHONY: check-jsonschema
check-jsonschema:
jsonschema --version || (echo "You need python3-jsonschema to validate config examples against generated schema"; exit 1)
.PHONY: verify-config-schema
verify-config-schema: binary check-jsonschema
./bin/zot-$(OS)-$(ARCH) schema > bin/zot-schema.json
for i in $(filter-out $(wildcard examples/config-*-credentials.json), $(wildcard examples/config-*.json)); do echo $$i; jsonschema bin/zot-schema.json -i "$$i" -o pretty; done
.PHONY: gqlgen
gqlgen:
cd pkg/extensions/search;\
go run github.com/99designs/gqlgen version;\
go run github.com/99designs/gqlgen generate
.PHONY: verify-gql-committed
verify-gql-committed:
$(eval UNCOMMITED_FILES = $(shell git status --porcelain | grep -c extensions/search))
@if [ $(UNCOMMITED_FILES) != 0 ]; then \
echo "Updated gql files uncommitted, make sure all gql files are committed:";\
git status;\
exit 1;\
fi; \
.PHONY: binary-container
binary-container:
${CONTAINER_RUNTIME} build ${BUILD_ARGS} \
--build-arg BASE_IMAGE=$(BASE_IMAGE) \
-f build/Dockerfile -t zot-build:latest .
.PHONY: run-container
run-container:
${CONTAINER_RUNTIME} run --rm --security-opt label=disable -v $$(pwd):/go/src/github.com/project-zot/zot \
zot-build:latest
.PHONY: binary-minimal-container
binary-minimal-container:
${CONTAINER_RUNTIME} build ${BUILD_ARGS} \
--build-arg BASE_IMAGE=$(BASE_IMAGE) \
-f build/Dockerfile-minimal -t zot-minimal:latest .
.PHONY: run-minimal-container
run-minimal-container:
${CONTAINER_RUNTIME} run --rm --security-opt label=disable -v $$(pwd):/go/src/github.com/project-zot/zot \
zot-minimal:latest
.PHONY: binary-exporter-container
binary-exporter-container:
${CONTAINER_RUNTIME} build ${BUILD_ARGS} \
--build-arg BASE_IMAGE=$(BASE_IMAGE) \
-f build/Dockerfile-zxp -t zxp:latest .
.PHONY: run-exporter-container
run-exporter-container:
${CONTAINER_RUNTIME} run --rm --security-opt label=disable zxp:latest
.PHONY: oci-image
oci-image: $(STACKER)
${STACKER} --debug build \
-f build/stacker.yaml \
--substitute COMMIT=$(COMMIT) \
--substitute ARCH=$(ARCH) \
--substitute OS=$(OS) \
--substitute RELEASE_TAG=$(RELEASE_TAG) \
--substitute REPO_NAME=zot-$(OS)-$(ARCH) \
--substitute BASE_IMAGE=$(BASE_IMAGE)
.PHONY: docker-image
docker-image:
${CONTAINER_RUNTIME} buildx build --platform $(OS)/$(ARCH) \
--build-arg BASE_IMAGE=$(BASE_IMAGE) \
-f build/Dockerfile .
$(BATS):
rm -rf bats-core; \
git clone https://github.com/bats-core/bats-core.git; \
cd bats-core; ./install.sh $(TOOLSDIR); cd ..; \
rm -rf bats-core
.PHONY: check-blackbox-prerequisites
check-blackbox-prerequisites: check-linux check-skopeo $(BATS) $(REGCLIENT) $(ORAS) $(HELM) $(CRICTL) $(NOTATION) $(COSIGN) $(STACKER) $(KIND)
which skopeo && skopeo --version; \
which stacker && stacker --version; \
which regctl && regctl version; \
which oras && oras version; \
which helm && helm version; \
which crictl && crictl version; \
which notation && notation version; \
which cosign && cosign version; \
which kind && kind version;
.PHONY: run-blackbox-tests
run-blackbox-tests: $(BATS_TEST_FILE_PATH) check-blackbox-prerequisites binary binary-minimal cli bench
echo running bats test "$(BATS_TEST_FILE_PATH)"; \
$(BLACKBOX_DOCKER_ENV) $(BATS) $(BATS_FLAGS) $(BATS_TEST_FILE_PATH)
.PHONY: run-cloud-scale-out-tests
run-cloud-scale-out-tests: check-blackbox-prerequisites check-awslocal binary bench test-prereq
echo running scale out bats test; \
$(BATS) $(BATS_FLAGS) test/scale-out/cloud_scale_out_no_auth.bats; \
$(BATS) $(BATS_FLAGS) test/scale-out/cloud_scale_out_basic_auth_tls.bats
.PHONY: run-cloud-scale-out-redis-tests
run-cloud-scale-out-redis-tests: check-blackbox-prerequisites check-awslocal binary bench test-prereq
echo running redis scale out bats test; \
$(BATS) $(BATS_FLAGS) test/scale-out/cloud_scale_out_redis.bats
.PHONY: run-cloud-scale-out-high-scale-tests
run-cloud-scale-out-high-scale-tests: check-blackbox-prerequisites check-awslocal binary bench test-prereq
echo running cloud scale out bats high scale test; \
$(BATS) $(BATS_FLAGS) test/scale-out/cloud_scale_out_basic_auth_tls_scale.bats
.PHONY: run-cloud-scale-out-redis-high-scale-tests
run-cloud-scale-out-redis-high-scale-tests: check-blackbox-prerequisites check-awslocal binary bench test-prereq
echo running redis scale out high scale bats test; \
$(BATS) $(BATS_FLAGS) test/scale-out/cloud_scale_out_redis_scale.bats
.PHONY: run-blackbox-ci
run-blackbox-ci: check-blackbox-prerequisites binary binary-minimal cli
echo running CI bats tests concurrently; \
$(BLACKBOX_DOCKER_ENV) BATS_FLAGS="$(BATS_FLAGS)" test/blackbox/ci.sh
.PHONY: run-blackbox-cloud-ci
run-blackbox-cloud-ci: check-blackbox-prerequisites check-awslocal binary $(BATS)
echo running cloud CI bats tests; \
$(BATS) $(BATS_FLAGS) test/blackbox/cloud_only.bats
$(BATS) $(BATS_FLAGS) test/blackbox/sync_cloud.bats
$(BATS) $(BATS_FLAGS) test/blackbox/redis_s3.bats
.PHONY: run-blackbox-dedupe-nightly
run-blackbox-dedupe-nightly: check-blackbox-prerequisites check-awslocal binary binary-minimal
echo running nightly dedupe tests; \
$(BATS) $(BATS_FLAGS) test/blackbox/restore_s3_blobs.bats && \
$(BATS) $(BATS_FLAGS) test/blackbox/pushpull_running_dedupe.bats
.PHONY: run-blackbox-sync-nightly
run-blackbox-sync-nightly: check-blackbox-prerequisites binary binary-minimal bench
echo running nightly sync tests; \
$(BATS) $(BATS_FLAGS) test/blackbox/sync_harness.bats
.PHONY: fuzz-all
fuzz-all: fuzztime=${1}
fuzz-all:
rm -rf test-data; \
rm -rf pkg/storage/testdata; \
git clone https://github.com/project-zot/test-data.git; \
mv test-data/storage pkg/storage/testdata; \
rm -rf test-data; \
bash test/scripts/fuzzAll.sh ${fuzztime}; \
rm -rf pkg/storage/testdata; \
$(STACKER): check-linux
mkdir -p $(TOOLSDIR)/bin; \
curl -fsSL https://github.com/project-stacker/stacker/releases/download/$(STACKER_VERSION)/stacker -o $@; \
chmod +x $@
$(COSIGN):
mkdir -p $(TOOLSDIR)/bin
curl -fsSL https://github.com/sigstore/cosign/releases/download/v$(COSIGN_VERSION)/cosign-$(OS)-$(ARCH) -o $@; \
chmod +x $@
$(KIND): check-linux
mkdir -p $(TOOLSDIR)/bin; \
curl -fsSL curl -Lo ./kind https://kind.sigs.k8s.io/dl/$(KIND_VERSION)/kind-$(OS)-$(ARCH) -o $@; \
chmod +x $@
# set ZUI_VERSION to empty string in order to clone zui locally and build default branch
.PHONY: ui
ui:
echo $(BUILD_LABELS);\
if [ -n $(ZUI_BUILD_PATH) ]; then\
rm -rf ./pkg/extensions/build;\
cp -R $(ZUI_BUILD_PATH) ./pkg/extensions/;\
exit 0;\
fi;\
if [ -z $(ZUI_VERSION) ]; then\
pwd=$$(pwd);\
tdir=$$(mktemp -d);\
cd $$tdir;\
git clone https://github.com/$(ZUI_REPO_OWNER)/$(ZUI_REPO_NAME).git zui;\
cd zui;\
npm install;\
npm run build;\
cd $$pwd;\
rm -rf ./pkg/extensions/build;\
cp -R $$tdir/zui/build ./pkg/extensions/;\
else\
curl --fail --head https://github.com/$(ZUI_REPO_OWNER)/$(ZUI_REPO_NAME)/releases/download/$(ZUI_VERSION)/zui.tgz;\
if [ $$? -ne 0 ]; then\
pwd=$$(pwd);\
tdir=$$(mktemp -d);\
cd $$tdir;\
git clone --depth=1 --branch $(ZUI_VERSION) https://github.com/$(ZUI_REPO_OWNER)/$(ZUI_REPO_NAME).git zui;\
cd zui;\
git checkout $(ZUI_VERSION);\
npm install;\
npm run build;\
cd $$pwd;\
rm -rf ./pkg/extensions/build;\
cp -R $$tdir/zui/build ./pkg/extensions/;\
else\
curl -fsSL https://github.com/$(ZUI_REPO_OWNER)/$(ZUI_REPO_NAME)/releases/download/$(ZUI_VERSION)/zui.tgz -o zui.tgz;\
tar xvzf zui.tgz -C ./pkg/extensions/;\
rm zui.tgz;\
fi;\
fi;\
.PHONY: check-linux
check-linux:
ifneq ($(shell go env GOOS),linux)
$(error makefile target can be run only on linux)
endif
.PHONY: check-compatibility
check-compatibility:
ifeq ($(OS),freebsd)
$(error makefile target can't be run on freebsd)
endif
ifneq ($(OS),$(shell go env GOOS))
$(error target can't be run on $(shell go env GOOS) as binary is compiled for $(OS))
endif
ifneq ($(ARCH),$(shell go env GOARCH))
$(error target can't be run on $(shell go env GOARCH) (binary is for $(ARCH)))
endif