1- # Copyright 2018 The Prometheus Authors
1+ # Copyright The Prometheus Authors
22# Licensed under the Apache License, Version 2.0 (the "License");
33# you may not use this file except in compliance with the License.
44# You may obtain a copy of the License at
@@ -61,7 +61,7 @@ PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_
6161SKIP_GOLANGCI_LINT :=
6262GOLANGCI_LINT :=
6363GOLANGCI_LINT_OPTS ?=
64- GOLANGCI_LINT_VERSION ?= v2.6.0
64+ GOLANGCI_LINT_VERSION ?= v2.7.2
6565GOLANGCI_FMT_OPTS ?=
6666# golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64.
6767# windows isn't included here because of the path separator being different.
@@ -82,11 +82,32 @@ endif
8282PREFIX ?= $(shell pwd)
8383BIN_DIR ?= $(shell pwd)
8484DOCKER_IMAGE_TAG ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD))
85- DOCKERFILE_PATH ?= ./Dockerfile
8685DOCKERBUILD_CONTEXT ?= ./
8786DOCKER_REPO ?= prom
8887
88+ # Check if deprecated DOCKERFILE_PATH is set
89+ ifdef DOCKERFILE_PATH
90+ $(error DOCKERFILE_PATH is deprecated. Use DOCKERFILE_VARIANTS ?= $(DOCKERFILE_PATH) in the Makefile)
91+ endif
92+
8993DOCKER_ARCHS ?= amd64
94+ DOCKERFILE_VARIANTS ?= Dockerfile $(wildcard Dockerfile.*)
95+
96+ # Function to extract variant from Dockerfile label.
97+ # Returns the variant name from io.prometheus.image.variant label, or "default" if not found.
98+ define dockerfile_variant
99+ $(strip $(or $(shell sed -n 's/.*io\.prometheus\.image\.variant="\([^"]*\)".*/\1/p' $(1)),default))
100+ endef
101+
102+ # Check for duplicate variant names (including default for Dockerfiles without labels).
103+ DOCKERFILE_VARIANT_NAMES := $(foreach df,$(DOCKERFILE_VARIANTS),$(call dockerfile_variant,$(df)))
104+ DOCKERFILE_VARIANT_NAMES_SORTED := $(sort $(DOCKERFILE_VARIANT_NAMES))
105+ ifneq ($(words $(DOCKERFILE_VARIANT_NAMES)),$(words $(DOCKERFILE_VARIANT_NAMES_SORTED)))
106+ $(error Duplicate variant names found. Each Dockerfile must have a unique io.prometheus.image.variant label, and only one can be without a label (default))
107+ endif
108+
109+ # Build variant:dockerfile pairs for shell iteration.
110+ DOCKERFILE_VARIANTS_WITH_NAMES := $(foreach df,$(DOCKERFILE_VARIANTS),$(call dockerfile_variant,$(df)):$(df))
90111
91112BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS))
92113PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS))
@@ -112,7 +133,7 @@ common-all: precheck style check_license lint yamllint unused build test
112133.PHONY: common-style
113134common-style:
114135 @echo ">> checking code style"
115- @fmtRes=$$($(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print)); \
136+ @fmtRes=$$($(GOFMT) -d $$(git ls-files '*.go' ':!:vendor/*' || find . -path ./vendor -prune -o -name '*.go' -print)); \
116137 if [ -n "$${fmtRes}" ]; then \
117138 echo "gofmt checking failed!"; echo "$${fmtRes}"; echo; \
118139 echo "Please ensure you are using $$($(GO) version) for formatting code."; \
@@ -122,13 +143,19 @@ common-style:
122143.PHONY: common-check_license
123144common-check_license:
124145 @echo ">> checking license header"
125- @licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path ' ./vendor/*' ) ; do \
146+ @licRes=$$(for file in $$(git ls-files '*.go' ':!:vendor/*' || find . -path ./vendor -prune -o -type f -iname '*.go' -print ) ; do \
126147 awk 'NR<=3' $$file | grep -Eq "(Copyright|generated|GENERATED)" || echo $$file; \
127148 done); \
128149 if [ -n "$${licRes}" ]; then \
129150 echo "license header checking failed:"; echo "$${licRes}"; \
130151 exit 1; \
131152 fi
153+ @echo ">> checking for copyright years 2026 or later"
154+ @futureYearRes=$$(git grep -E 'Copyright (202[6-9]|20[3-9][0-9])' -- '*.go' ':!:vendor/*' || true); \
155+ if [ -n "$${futureYearRes}" ]; then \
156+ echo "Files with copyright year 2026 or later found (should use 'Copyright The Prometheus Authors'):"; echo "$${futureYearRes}"; \
157+ exit 1; \
158+ fi
132159
133160.PHONY: common-deps
134161common-deps:
@@ -220,28 +247,110 @@ common-docker-repo-name:
220247.PHONY: common-docker $(BUILD_DOCKER_ARCHS)
221248common-docker: $(BUILD_DOCKER_ARCHS)
222249$(BUILD_DOCKER_ARCHS): common-docker-%:
223- docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \
224- -f $(DOCKERFILE_PATH) \
225- --build-arg ARCH="$*" \
226- --build-arg OS="linux" \
227- $(DOCKERBUILD_CONTEXT)
250+ @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
251+ dockerfile=$${variant#*:}; \
252+ variant_name=$${variant%%:*}; \
253+ distroless_arch="$*"; \
254+ if [ "$*" = "armv7" ]; then \
255+ distroless_arch="arm"; \
256+ fi; \
257+ if [ "$$dockerfile" = "Dockerfile" ]; then \
258+ echo "Building default variant ($$variant_name) for linux-$* using $$dockerfile"; \
259+ docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \
260+ -f $$dockerfile \
261+ --build-arg ARCH="$*" \
262+ --build-arg OS="linux" \
263+ --build-arg DISTROLESS_ARCH="$$distroless_arch" \
264+ $(DOCKERBUILD_CONTEXT); \
265+ if [ "$$variant_name" != "default" ]; then \
266+ echo "Tagging default variant with $$variant_name suffix"; \
267+ docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" \
268+ "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
269+ fi; \
270+ else \
271+ echo "Building $$variant_name variant for linux-$* using $$dockerfile"; \
272+ docker build -t "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" \
273+ -f $$dockerfile \
274+ --build-arg ARCH="$*" \
275+ --build-arg OS="linux" \
276+ --build-arg DISTROLESS_ARCH="$$distroless_arch" \
277+ $(DOCKERBUILD_CONTEXT); \
278+ fi; \
279+ done
228280
229281.PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS)
230282common-docker-publish: $(PUBLISH_DOCKER_ARCHS)
231283$(PUBLISH_DOCKER_ARCHS): common-docker-publish-%:
232- docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)"
284+ @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
285+ dockerfile=$${variant#*:}; \
286+ variant_name=$${variant%%:*}; \
287+ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
288+ echo "Pushing $$variant_name variant for linux-$*"; \
289+ docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
290+ fi; \
291+ if [ "$$dockerfile" = "Dockerfile" ]; then \
292+ echo "Pushing default variant ($$variant_name) for linux-$*"; \
293+ docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)"; \
294+ fi; \
295+ if [ "$(DOCKER_IMAGE_TAG)" = "latest" ]; then \
296+ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
297+ echo "Pushing $$variant_name variant version tags for linux-$*"; \
298+ docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \
299+ fi; \
300+ if [ "$$dockerfile" = "Dockerfile" ]; then \
301+ echo "Pushing default variant version tag for linux-$*"; \
302+ docker push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"; \
303+ fi; \
304+ fi; \
305+ done
233306
234307DOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION)))
235308.PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS)
236309common-docker-tag-latest: $(TAG_DOCKER_ARCHS)
237310$(TAG_DOCKER_ARCHS): common-docker-tag-latest-%:
238- docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest"
239- docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"
311+ @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
312+ dockerfile=$${variant#*:}; \
313+ variant_name=$${variant%%:*}; \
314+ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
315+ echo "Tagging $$variant_name variant for linux-$* as latest"; \
316+ docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest-$$variant_name"; \
317+ docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \
318+ fi; \
319+ if [ "$$dockerfile" = "Dockerfile" ]; then \
320+ echo "Tagging default variant ($$variant_name) for linux-$* as latest"; \
321+ docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest"; \
322+ docker tag "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)" "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)"; \
323+ fi; \
324+ done
240325
241326.PHONY: common-docker-manifest
242327common-docker-manifest:
243- DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(SANITIZED_DOCKER_IMAGE_TAG))
244- DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)"
328+ @for variant in $(DOCKERFILE_VARIANTS_WITH_NAMES); do \
329+ dockerfile=$${variant#*:}; \
330+ variant_name=$${variant%%:*}; \
331+ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
332+ echo "Creating manifest for $$variant_name variant"; \
333+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name); \
334+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)-$$variant_name"; \
335+ fi; \
336+ if [ "$$dockerfile" = "Dockerfile" ]; then \
337+ echo "Creating default variant ($$variant_name) manifest"; \
338+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(SANITIZED_DOCKER_IMAGE_TAG)); \
339+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)"; \
340+ fi; \
341+ if [ "$(DOCKER_IMAGE_TAG)" = "latest" ]; then \
342+ if [ "$$dockerfile" != "Dockerfile" ] || [ "$$variant_name" != "default" ]; then \
343+ echo "Creating manifest for $$variant_name variant version tag"; \
344+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name); \
345+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)-$$variant_name"; \
346+ fi; \
347+ if [ "$$dockerfile" = "Dockerfile" ]; then \
348+ echo "Creating default variant version tag manifest"; \
349+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):v$(DOCKER_MAJOR_VERSION_TAG)); \
350+ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push "$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):v$(DOCKER_MAJOR_VERSION_TAG)"; \
351+ fi; \
352+ fi; \
353+ done
245354
246355.PHONY: promu
247356promu: $(PROMU)
0 commit comments