#!/usr/bin/make -f # Common variables REPO ?= $(shell go list -m) VERSION ?= $(shell git describe --tags --dirty --match "v*" --always --abbrev=8 2>/dev/null || cat VERSION 2>/dev/null || echo "develop") GO_VERSION ?= 1.22 LINT_VERSION ?= 1.56.1 TRUECLOUDLAB_LINT_VERSION ?= 0.0.5 BINDIR = bin METRICS_DUMP_OUT ?= ./metrics-dump.json # Binaries to build CMDS = $(addprefix frostfs-, $(notdir $(wildcard cmd/*))) BINS = $(addprefix $(BINDIR)/, $(CMDS)) # Variables for docker REPO_BASENAME = $(shell basename `go list -m`) HUB_IMAGE ?= "truecloudlab/$(REPO_BASENAME)" HUB_TAG ?= "$(shell echo ${VERSION} | sed 's/^v//')" OUTPUT_LINT_DIR ?= $(shell pwd)/bin LINT_DIR = $(OUTPUT_LINT_DIR)/golangci-lint-$(LINT_VERSION)-v$(TRUECLOUDLAB_LINT_VERSION) TMP_DIR := .cache # Variables for fuzzing FUZZ_NGFUZZ_DIR ?= "" FUZZ_TIMEOUT ?= 30 FUZZ_FUNCTIONS ?= "all" FUZZ_AUX ?= "" .PHONY: all $(BINS) $(BINDIR) dep docker/ test cover format image image-push dirty-image lint docker/lint pre-commit unpre-commit version clean protoc # .deb package versioning OS_RELEASE = $(shell lsb_release -cs) PKG_VERSION ?= $(shell echo $(VERSION) | sed "s/^v//" | \ sed -E "s/(.*)-(g[a-fA-F0-9]{6,8})(.*)/\1\3~\2/" | \ sed "s/-/~/")-${OS_RELEASE} .PHONY: debpackage debclean # Make all binaries all: $(BINS) $(BINS): $(BINDIR) dep @echo "⇒ Build $@" CGO_ENABLED=0 \ go build -v -trimpath \ -ldflags "-X $(REPO)/internal/version.Version=$(VERSION)" \ -o $@ ./cmd/$(subst frostfs-,,$(notdir $@)) $(BINDIR): @echo "⇒ Ensure dir: $@" @mkdir -p $@ # Pull go dependencies dep: @printf "⇒ Download requirements: " @CGO_ENABLED=0 \ go mod download && echo OK @printf "⇒ Tidy requirements: " @CGO_ENABLED=0 \ go mod tidy -v && echo OK # Run `make %` in Golang container, for more information run `make help.docker/%` docker/%: $(if $(filter $*,all $(BINS)), \ @echo "=> Running 'make $*' in clean Docker environment" && \ docker run --rm -t \ -v `pwd`:/src \ -w /src \ -u `stat -c "%u:%g" .` \ --env HOME=/src \ golang:$(GO_VERSION) make $*,\ @echo "supported docker targets: all $(BINS) lint") # Run tests test: @go test ./... -cover # Run tests with race detection and produce coverage output cover: @go test -v -race ./... -coverprofile=coverage.txt -covermode=atomic @go tool cover -html=coverage.txt -o coverage.html # Run fuzzing CLANG := $(shell which clang-17 2>/dev/null) .PHONY: check-clang all check-clang: ifeq ($(CLANG),) @echo "clang-17 is not installed. Please install it before proceeding - https://apt.llvm.org/llvm.sh " @exit 1 endif .PHONY: check-ngfuzz all check-ngfuzz: @if [ -z "$(FUZZ_NGFUZZ_DIR)" ]; then \ echo "Please set a variable FUZZ_NGFUZZ_DIR to specify path to the ngfuzz"; \ exit 1; \ fi .PHONY: install-fuzzing-deps install-fuzzing-deps: check-clang check-ngfuzz .PHONY: fuzz fuzz: install-fuzzing-deps @START_PATH=$$(pwd); \ ROOT_PATH=$$(realpath --relative-to=$(FUZZ_NGFUZZ_DIR) $$START_PATH) ; \ cd $(FUZZ_NGFUZZ_DIR) && \ ./ngfuzz -clean && \ ./ngfuzz -fuzz $(FUZZ_FUNCTIONS) -rootdir $$ROOT_PATH -timeout $(FUZZ_TIMEOUT) $(FUZZ_AUX) && \ ./ngfuzz -report # Reformat code format: @echo "⇒ Processing gofmt check" @gofmt -s -w ./ # Build clean Docker image image: @echo "⇒ Build FrostFS S3 Gateway docker image " @docker build \ --build-arg REPO=$(REPO) \ --build-arg VERSION=$(VERSION) \ --rm \ -f .docker/Dockerfile \ -t $(HUB_IMAGE):$(HUB_TAG) . # Push Docker image to the hub image-push: @echo "⇒ Publish image" @docker push $(HUB_IMAGE):$(HUB_TAG) # Build dirty Docker image dirty-image: @echo "⇒ Build FrostFS S3 Gateway dirty docker image " @docker build \ --build-arg REPO=$(REPO) \ --build-arg VERSION=$(VERSION) \ --rm \ -f .docker/Dockerfile.dirty \ -t $(HUB_IMAGE)-dirty:$(HUB_TAG) . # Install linters lint-install: @mkdir -p $(TMP_DIR) @rm -rf $(TMP_DIR)/linters @git -c advice.detachedHead=false clone --branch v$(TRUECLOUDLAB_LINT_VERSION) https://git.frostfs.info/TrueCloudLab/linters.git $(TMP_DIR)/linters @@make -C $(TMP_DIR)/linters lib CGO_ENABLED=1 OUT_DIR=$(OUTPUT_LINT_DIR) @rm -rf $(TMP_DIR)/linters @rmdir $(TMP_DIR) 2>/dev/null || true @CGO_ENABLED=1 GOBIN=$(LINT_DIR) go install github.com/golangci/golangci-lint/cmd/golangci-lint@v$(LINT_VERSION) # Run linters lint: @if [ ! -d "$(LINT_DIR)" ]; then \ echo "Run make lint-install"; \ exit 1; \ fi $(LINT_DIR)/golangci-lint --timeout=5m run # Run linters in Docker docker/lint: docker run --rm -it \ -v `pwd`:/src \ -u `stat -c "%u:%g" .` \ --env HOME=/src \ golangci/golangci-lint:v$(LINT_VERSION) bash -c 'cd /src/ && make lint' # Activate pre-commit hooks pre-commit: pre-commit install -t pre-commit -t commit-msg # Deactivate pre-commit hooks unpre-commit: pre-commit uninstall -t pre-commit -t commit-msg # Show current version version: @echo $(VERSION) # Clean up files clean: rm -rf .cache rm -rf $(BINDIR) # Generate code from .proto files protoc: # Install specific version for protobuf lib @GOBIN=$(abspath $(BINDIR)) go install -mod=mod -v git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/protogen @for f in `find . -type f -name '*.proto' -not -path './vendor/*'`; do \ echo "⇒ Processing $$f "; \ protoc \ --go_out=paths=source_relative:. \ --plugin=protoc-gen-go-frostfs=$(BINDIR)/protogen \ --go-frostfs_out=. --go-frostfs_opt=paths=source_relative \ --go-grpc_opt=require_unimplemented_servers=false \ --go-grpc_out=. --go-grpc_opt=paths=source_relative $$f; \ done rm -rf vendor # Package for Debian debpackage: dch --package frostfs-s3-gw \ --controlmaint \ --newversion $(PKG_VERSION) \ --distribution $(OS_RELEASE) \ "Please see CHANGELOG.md for code changes for $(VERSION)" dpkg-buildpackage --no-sign -b debclean: dh clean # Dump metrics (use METRICS_DUMP_OUT variable to override default out file './metrics-dump.json') .PHONY: dump-metrics dump-metrics: @go test ./metrics -run TestDescribeAll --tags=dump_metrics --out=$(abspath $(METRICS_DUMP_OUT)) include help.mk