azure-container-networking/Makefile

417 строки
16 KiB
Makefile
Исходник Обычный вид История

# Default platform commands
SHELL=/bin/bash
MKDIR := mkdir -p
RMDIR := rm -rf
ARCHIVE_CMD = tar -czvf
# Default platform extensions
ARCHIVE_EXT = tgz
# Windows specific commands
ifeq ($(OS),Windows_NT)
MKDIR := powershell.exe -NoProfile -Command New-Item -ItemType Directory -Force
RMDIR := powershell.exe -NoProfile -Command Remove-Item -Recurse -Force
endif
# Build defaults.
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
GOOSES ?= "linux windows" # To override at the cli do: GOOSES="\"darwin bsd\""
GOARCHES ?= "amd64 arm64" # To override at the cli do: GOARCHES="\"ppc64 mips\""
# Windows specific extensions
ifeq ($(GOOS),windows)
ARCHIVE_CMD = zip -9lq
ARCHIVE_EXT = zip
EXE_EXT = .exe
endif
2017-03-11 03:49:07 +03:00
# Build directories.
REPO_ROOT = $(shell git rev-parse --show-toplevel)
CNM_DIR = $(REPO_ROOT)/cnm/plugin
CNI_NET_DIR = $(REPO_ROOT)/cni/network/plugin
CNI_IPAM_DIR = $(REPO_ROOT)/cni/ipam/plugin
CNI_IPAMV6_DIR = $(REPO_ROOT)/cni/ipam/pluginv6
CNI_TELEMETRY_DIR = $(REPO_ROOT)/cni/telemetry/service
ACNCLI_DIR = $(REPO_ROOT)/tools/acncli
CNS_DIR = $(REPO_ROOT)/cns/service
NPM_DIR = $(REPO_ROOT)/npm/cmd
OUTPUT_DIR = $(REPO_ROOT)/output
BUILD_DIR = $(OUTPUT_DIR)/$(GOOS)_$(GOARCH)
IMAGE_DIR = $(OUTPUT_DIR)/images
CNM_BUILD_DIR = $(BUILD_DIR)/cnm
CNI_BUILD_DIR = $(BUILD_DIR)/cni
ACNCLI_BUILD_DIR = $(BUILD_DIR)/acncli
CNI_MULTITENANCY_BUILD_DIR = $(BUILD_DIR)/cni-multitenancy
CNI_SWIFT_BUILD_DIR = $(BUILD_DIR)/cni-swift
CNI_BAREMETAL_BUILD_DIR = $(BUILD_DIR)/cni-baremetal
CNS_BUILD_DIR = $(BUILD_DIR)/cns
NPM_BUILD_DIR = $(BUILD_DIR)/npm
TOOLS_DIR = $(REPO_ROOT)/build/tools
TOOLS_BIN_DIR = $(TOOLS_DIR)/bin
CNI_AI_ID = 5515a1eb-b2bc-406a-98eb-ba462e6f0411
CNS_AI_ID = ce672799-8f08-4235-8c12-08563dc2acef
NPM_AI_ID = 014c22bd-4107-459e-8475-67909e96edcb
ACN_PACKAGE_PATH = github.com/Azure/azure-container-networking
CNI_AI_PATH=$(ACN_PACKAGE_PATH)/telemetry.aiMetadata
CNS_AI_PATH=$(ACN_PACKAGE_PATH)/cns/logger.aiMetadata
NPM_AI_PATH=$(ACN_PACKAGE_PATH)/npm.aiMetadata
2017-01-05 03:21:14 +03:00
# Tool paths
CONTROLLER_GEN := $(TOOLS_BIN_DIR)/controller-gen
GOCOV := $(TOOLS_BIN_DIR)/gocov
GOCOV_XML := $(TOOLS_BIN_DIR)/gocov-xml
GOFUMPT := $(TOOLS_BIN_DIR)/gofumpt
GOLANGCI_LINT := $(TOOLS_BIN_DIR)/golangci-lint
GO_JUNIT_REPORT := $(TOOLS_BIN_DIR)/go-junit-report
MOCKGEN := $(TOOLS_BIN_DIR)/mockgen
# Archive file names.
CNM_ARCHIVE_NAME = azure-vnet-cnm-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
CNI_ARCHIVE_NAME = azure-vnet-cni-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
ACNCLI_ARCHIVE_NAME = acncli-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
CNI_MULTITENANCY_ARCHIVE_NAME = azure-vnet-cni-multitenancy-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
CNI_SWIFT_ARCHIVE_NAME = azure-vnet-cni-swift-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
CNI_BAREMETAL_ARCHIVE_NAME = azure-vnet-cni-baremetal-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
CNS_ARCHIVE_NAME = azure-cns-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
2018-07-20 02:06:11 +03:00
NPM_ARCHIVE_NAME = azure-npm-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
NPM_IMAGE_INFO_FILE = azure-npm-$(VERSION).txt
CNI_IMAGE_ARCHIVE_NAME = azure-cni-manager-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
CNS_IMAGE_INFO_FILE = azure-cns-$(VERSION).txt
# Docker libnetwork (CNM) plugin v2 image parameters.
2017-05-20 02:31:08 +03:00
CNM_PLUGIN_IMAGE ?= microsoft/azure-vnet-plugin
CNM_PLUGIN_ROOTFS = azure-vnet-plugin-rootfs
2017-01-07 04:36:02 +03:00
IMAGE_REGISTRY ?= acnpublic.azurecr.io
# Azure network policy manager parameters.
AZURE_NPM_IMAGE ?= $(IMAGE_REGISTRY)/azure-npm
# Azure CNI installer parameters
AZURE_CNI_IMAGE = $(IMAGE_REGISTRY)/azure-cni-manager
# Azure container networking service image paramters.
AZURE_CNS_IMAGE = $(IMAGE_REGISTRY)/azure-cns
IMAGE_PLATFORM_ARCHES ?= linux/amd64,linux/arm64
IMAGE_ACTION ?= push
2016-10-07 02:34:47 +03:00
VERSION ?= $(shell git describe --tags --always --dirty)
# Default target
.PHONY: all-binaries-platforms
all-binaries-platforms: ## Make all platform binaries
@for goos in "$(GOOSES)"; do \
for goarch in "$(GOARCHES)"; do \
make all-binaries GOOS=$$goos GOARCH=$$goarch; \
done \
done
# OS specific binaries/images
ifeq ($(GOOS),linux)
all-binaries: azure-cnm-plugin azure-cni-plugin azure-cns azure-npm
all-images: azure-npm-image azure-cns-image
2019-01-23 04:07:32 +03:00
else
all-binaries: azure-cnm-plugin azure-cni-plugin azure-cns
2019-01-23 04:07:32 +03:00
all-images:
2018-07-21 23:15:04 +03:00
@echo "Nothing to build. Skip."
endif
# Shorthand target names for convenience.
azure-cnm-plugin: cnm-binary cnm-archive
azure-cni-plugin: azure-vnet-binary azure-vnet-ipam-binary azure-vnet-ipamv6-binary azure-vnet-telemetry-binary cni-archive
azure-cns: azure-cns-binary cns-archive
acncli: acncli-binary acncli-archive
azure-cnms: azure-cnms-binary cnms-archive
azure-npm: azure-npm-binary npm-archive
2016-10-07 02:34:47 +03:00
# Clean all build artifacts.
.PHONY: clean
clean:
$(RMDIR) $(OUTPUT_DIR)
$(RMDIR) $(TOOLS_BIN_DIR)
2017-01-05 03:21:14 +03:00
########################### Binaries ################################
# Build the Azure CNM binary.
.PHONY: cnm-binary
cnm-binary:
cd $(CNM_DIR) && CGO_ENABLED=0 go build -v -o $(CNM_BUILD_DIR)/azure-vnet-plugin$(EXE_EXT) -ldflags "-X main.version=$(VERSION)" -gcflags="-dwarflocationlists=true"
# Build the Azure CNI network binary.
.PHONY: azure-vnet-binary
azure-vnet-binary:
cd $(CNI_NET_DIR) && CGO_ENABLED=0 go build -v -o $(CNI_BUILD_DIR)/azure-vnet$(EXE_EXT) -ldflags "-X main.version=$(VERSION)" -gcflags="-dwarflocationlists=true"
# Build the Azure CNI IPAM binary.
.PHONY: azure-vnet-ipam-binary
azure-vnet-ipam-binary:
cd $(CNI_IPAM_DIR) && CGO_ENABLED=0 go build -v -o $(CNI_BUILD_DIR)/azure-vnet-ipam$(EXE_EXT) -ldflags "-X main.version=$(VERSION)" -gcflags="-dwarflocationlists=true"
# Build the Azure CNI IPAMV6 binary.
.PHONY: azure-vnet-ipamv6-binary
azure-vnet-ipamv6-binary:
cd $(CNI_IPAMV6_DIR) && CGO_ENABLED=0 go build -v -o $(CNI_BUILD_DIR)/azure-vnet-ipamv6$(EXE_EXT) -ldflags "-X main.version=$(VERSION)" -gcflags="-dwarflocationlists=true"
# Build the Azure CNI telemetry binary.
.PHONY: azure-vnet-telemetry-binary
azure-vnet-telemetry-binary:
cd $(CNI_TELEMETRY_DIR) && CGO_ENABLED=0 go build -v -o $(CNI_BUILD_DIR)/azure-vnet-telemetry$(EXE_EXT) -ldflags "-X main.version=$(VERSION) -X $(CNI_AI_PATH)=$(CNI_AI_ID)" -gcflags="-dwarflocationlists=true"
# Build the Azure CLI network binary.
.PHONY: acncli-binary
acncli-binary:
cd $(ACNCLI_DIR) && CGO_ENABLED=0 go build -v -o $(ACNCLI_BUILD_DIR)/acn$(EXE_EXT) -ldflags "-X main.version=$(VERSION)" -gcflags="-dwarflocationlists=true"
# Build the Azure CNS binary.
.PHONY: azure-cns-binary
azure-cns-binary:
cd $(CNS_DIR) && CGO_ENABLED=0 go build -v -o $(CNS_BUILD_DIR)/azure-cns$(EXE_EXT) -ldflags "-X main.version=$(VERSION) -X $(CNS_AI_PATH)=$(CNS_AI_ID)" -gcflags="-dwarflocationlists=true"
# Build the Azure NPM binary.
.PHONY: azure-npm-binary
azure-npm-binary:
cd $(CNI_TELEMETRY_DIR) && CGO_ENABLED=0 go build -v -o $(NPM_BUILD_DIR)/azure-vnet-telemetry$(EXE_EXT) -ldflags "-X main.version=$(VERSION)" -gcflags="-dwarflocationlists=true"
cd $(NPM_DIR) && CGO_ENABLED=0 go build -v -o $(NPM_BUILD_DIR)/azure-npm$(EXE_EXT) -ldflags "-X main.version=$(VERSION) -X $(NPM_AI_PATH)=$(NPM_AI_ID)" -gcflags="-dwarflocationlists=true"
########################### Container Images ########################
# Build the tools images
.PHONY: tools-images
tools-images:
$(MKDIR) $(IMAGE_DIR)
docker build --no-cache -f ./tools/acncli/Dockerfile --build-arg VERSION=$(VERSION) -t $(AZURE_CNI_IMAGE):$(VERSION) .
docker save $(AZURE_CNI_IMAGE):$(VERSION) | gzip -c > $(IMAGE_DIR)/$(CNI_IMAGE_ARCHIVE_NAME)
2017-01-07 04:36:02 +03:00
# Build the Azure CNM plugin image, installable with "docker plugin install".
.PHONY: azure-cnm-plugin-image
azure-cnm-plugin-image: azure-cnm-plugin
2017-01-07 04:36:02 +03:00
# Build the plugin image, keeping any old image during build for cache, but remove it afterwards.
docker images -q $(CNM_PLUGIN_ROOTFS):$(VERSION) > cid
docker build --no-cache \
-f Dockerfile.cnm \
-t $(CNM_PLUGIN_ROOTFS):$(VERSION) \
--build-arg CNM_BUILD_DIR=$(CNM_BUILD_DIR) \
.
2017-01-07 04:36:02 +03:00
$(eval CID := `cat cid`)
docker rmi $(CID) || true
# Create a container using the image and export its rootfs.
docker create $(CNM_PLUGIN_ROOTFS):$(VERSION) > cid
$(eval CID := `cat cid`)
$(MKDIR) $(OUTPUT_DIR)/$(CID)/rootfs
docker export $(CID) | tar -x -C $(OUTPUT_DIR)/$(CID)/rootfs
2017-01-07 04:36:02 +03:00
docker rm -vf $(CID)
# Copy the plugin configuration and set ownership.
cp cnm/config.json $(OUTPUT_DIR)/$(CID)
chgrp -R docker $(OUTPUT_DIR)/$(CID)
2017-01-07 04:36:02 +03:00
# Create the plugin.
docker plugin rm $(CNM_PLUGIN_IMAGE):$(VERSION) || true
docker plugin create $(CNM_PLUGIN_IMAGE):$(VERSION) $(OUTPUT_DIR)/$(CID)
2017-01-07 04:36:02 +03:00
# Cleanup temporary files.
rm -rf $(OUTPUT_DIR)/$(CID)
2017-01-07 04:36:02 +03:00
rm cid
# Build the Azure NPM image.
.PHONY: azure-npm-image
azure-npm-image:
2018-07-20 21:14:17 +03:00
ifeq ($(GOOS),linux)
$(MKDIR) $(IMAGE_DIR)
docker buildx create --use
docker buildx build \
--no-cache \
-f npm/Dockerfile \
-t $(AZURE_NPM_IMAGE):$(VERSION) \
--build-arg VERSION=$(VERSION) \
--build-arg NPM_AI_PATH=$(NPM_AI_PATH) \
--build-arg NPM_AI_ID=$(NPM_AI_ID) \
--platform=$(IMAGE_PLATFORM_ARCHES) \
--$(IMAGE_ACTION) \
.
echo $(AZURE_NPM_IMAGE):$(VERSION) > $(IMAGE_DIR)/$(NPM_IMAGE_INFO_FILE)
endif
# Build the Azure CNS image
.PHONY: azure-cns-image
azure-cns-image:
ifeq ($(GOOS),linux)
$(MKDIR) $(IMAGE_DIR)
docker buildx create --use
docker buildx build \
--no-cache \
-f cns/Dockerfile \
-t $(AZURE_CNS_IMAGE):$(VERSION) \
--build-arg VERSION=$(VERSION) \
--build-arg CNS_AI_PATH=$(CNS_AI_PATH) \
--build-arg CNS_AI_ID=$(CNS_AI_ID) \
--platform=$(IMAGE_PLATFORM_ARCHES) \
--$(IMAGE_ACTION) \
.
echo $(AZURE_CNS_IMAGE):$(VERSION) > $(IMAGE_DIR)/$(CNS_IMAGE_INFO_FILE)
endif
########################### Archives ################################
# Create a CNI archive for the target platform.
.PHONY: cni-archive
cni-archive: azure-vnet-binary azure-vnet-ipam-binary azure-vnet-ipamv6-binary azure-vnet-telemetry-binary
$(MKDIR) $(CNI_BUILD_DIR)
cp cni/azure-$(GOOS).conflist $(CNI_BUILD_DIR)/10-azure.conflist
cp telemetry/azure-vnet-telemetry.config $(CNI_BUILD_DIR)/azure-vnet-telemetry.config
cd $(CNI_BUILD_DIR) && $(ARCHIVE_CMD) $(CNI_ARCHIVE_NAME) azure-vnet$(EXE_EXT) azure-vnet-ipam$(EXE_EXT) azure-vnet-ipamv6$(EXE_EXT) azure-vnet-telemetry$(EXE_EXT) 10-azure.conflist azure-vnet-telemetry.config
$(MKDIR) $(CNI_MULTITENANCY_BUILD_DIR)
cp cni/azure-$(GOOS)-multitenancy.conflist $(CNI_MULTITENANCY_BUILD_DIR)/10-azure.conflist
cp telemetry/azure-vnet-telemetry.config $(CNI_MULTITENANCY_BUILD_DIR)/azure-vnet-telemetry.config
cp $(CNI_BUILD_DIR)/azure-vnet$(EXE_EXT) $(CNI_BUILD_DIR)/azure-vnet-ipam$(EXE_EXT) $(CNI_BUILD_DIR)/azure-vnet-telemetry$(EXE_EXT) $(CNI_MULTITENANCY_BUILD_DIR)
cd $(CNI_MULTITENANCY_BUILD_DIR) && $(ARCHIVE_CMD) $(CNI_MULTITENANCY_ARCHIVE_NAME) azure-vnet$(EXE_EXT) azure-vnet-ipam$(EXE_EXT) azure-vnet-telemetry$(EXE_EXT) 10-azure.conflist azure-vnet-telemetry.config
#baremetal mode is windows only (at least for now)
ifeq ($(GOOS),windows)
$(MKDIR) $(CNI_BAREMETAL_BUILD_DIR)
cp cni/azure-$(GOOS)-baremetal.conflist $(CNI_BAREMETAL_BUILD_DIR)/10-azure.conflist
cp $(CNI_BUILD_DIR)/azure-vnet$(EXE_EXT) $(CNI_BAREMETAL_BUILD_DIR)
cd $(CNI_BAREMETAL_BUILD_DIR) && $(ARCHIVE_CMD) $(CNI_BAREMETAL_ARCHIVE_NAME) azure-vnet$(EXE_EXT) 10-azure.conflist
endif
#swift mode is linux only
ifeq ($(GOOS),linux)
$(MKDIR) $(CNI_SWIFT_BUILD_DIR)
cp cni/azure-$(GOOS)-swift.conflist $(CNI_SWIFT_BUILD_DIR)/10-azure.conflist
cp telemetry/azure-vnet-telemetry.config $(CNI_SWIFT_BUILD_DIR)/azure-vnet-telemetry.config
cp $(CNI_BUILD_DIR)/azure-vnet$(EXE_EXT) $(CNI_BUILD_DIR)/azure-vnet-ipam$(EXE_EXT) $(CNI_BUILD_DIR)/azure-vnet-telemetry$(EXE_EXT) $(CNI_SWIFT_BUILD_DIR)
cd $(CNI_SWIFT_BUILD_DIR) && $(ARCHIVE_CMD) $(CNI_SWIFT_ARCHIVE_NAME) azure-vnet$(EXE_EXT) azure-vnet-ipam$(EXE_EXT) azure-vnet-telemetry$(EXE_EXT) 10-azure.conflist azure-vnet-telemetry.config
endif
# Create a CNM archive for the target platform.
.PHONY: cnm-archive
cnm-archive: cnm-binary
cd $(CNM_BUILD_DIR) && $(ARCHIVE_CMD) $(CNM_ARCHIVE_NAME) azure-vnet-plugin$(EXE_EXT)
# Create a cli archive for the target platform.
.PHONY: acncli-archive
acncli-archive: acncli-binary
ifeq ($(GOOS),linux)
$(MKDIR) $(ACNCLI_BUILD_DIR)
cd $(ACNCLI_BUILD_DIR) && $(ARCHIVE_CMD) $(ACNCLI_ARCHIVE_NAME) acn$(EXE_EXT)
endif
# Create a CNS archive for the target platform.
.PHONY: cns-archive
cns-archive: azure-cns-binary
cp cns/configuration/cns_config.json $(CNS_BUILD_DIR)/cns_config.json
cd $(CNS_BUILD_DIR) && $(ARCHIVE_CMD) $(CNS_ARCHIVE_NAME) azure-cns$(EXE_EXT) cns_config.json
2018-07-20 02:06:11 +03:00
# Create a NPM archive for the target platform. Only Linux is supported for now.
2018-07-20 02:06:11 +03:00
.PHONY: npm-archive
npm-archive: azure-npm-binary
2018-07-20 02:06:11 +03:00
ifeq ($(GOOS),linux)
cd $(NPM_BUILD_DIR) && $(ARCHIVE_CMD) $(NPM_ARCHIVE_NAME) azure-npm$(EXE_EXT)
endif
########################### Tasks ###################################
# Release tag
.PHONY: release
release:
./scripts/semver-release.sh
# Publish the Azure CNM plugin image to a Docker registry.
.PHONY: publish-azure-cnm-plugin-image
publish-azure-cnm-plugin-image:
docker plugin push $(CNM_PLUGIN_IMAGE):$(VERSION)
############################ Linting ################################
PRETTYGOTEST := $(shell command -v gotest 2> /dev/null)
LINT_PKG ?= .
lint: $(GOLANGCI_LINT) ## Fast lint vs default branch showing only new issues
2021-08-09 19:57:59 +03:00
$(GOLANGCI_LINT) run --new-from-rev master --timeout 10m -v $(LINT_PKG)/...
lint-old: $(GOLANGCI_LINT) ## Fast lint including previous issues
$(GOLANGCI_LINT) run -v $(LINT_PKG)/...
2021-08-09 19:57:59 +03:00
FMT_PKG ?= cni cns npm
fmt format: $(GOFUMPT) ## run gofumpt on $FMT_PKG (default "cni cns npm")
$(GOFUMPT) -s -w $(FMT_PKG)
COVER_PKG ?= .
# run all tests
# COVER_FILTER omits folders with all files tagged with one of 'unit', '!ignore_uncovered', or '!ignore_autogenerated'
.PHONY: test-all
test-all:
@$(eval COVER_FILTER=`go list --tags ignore_uncovered,ignore_autogenerated $(COVER_PKG)/... | tr '\n' ','`)
@echo Test coverpkg: $(COVER_FILTER)
go test -tags "unit" -coverpkg=$(COVER_FILTER) -v -race -covermode atomic -failfast -coverprofile=coverage.out $(COVER_PKG)/...
# run all tests
.PHONY: test-integration
test-integration:
go test -coverpkg=./... -v -race -covermode atomic -coverprofile=coverage.out -tags=integration ./test/integration...
.PHONY: test-cyclonus
test-cyclonus:
cd test/cyclonus && bash ./test-cyclonus.sh
cd ..
.PHONY: kind
kind:
kind create cluster --config ./test/kind/kind.yaml
version: ## prints the version
@echo $(VERSION)
######################## Build tools ################################
.PHONY: tools
tools: acncli
$(TOOLS_DIR)/go.mod:
cd $(TOOLS_DIR); go mod init && go mod tidy
$(CONTROLLER_GEN): $(TOOLS_DIR)/go.mod
cd $(TOOLS_DIR); go mod download; go build -tags=tools -o bin/controller-gen sigs.k8s.io/controller-tools/cmd/controller-gen
controller-gen: $(CONTROLLER_GEN) ## Build controller-gen
$(GOCOV): $(TOOLS_DIR)/go.mod
cd $(TOOLS_DIR); go mod download; go build -tags=tools -o bin/gocov github.com/axw/gocov/gocov
gocov: $(GOCOV) ## Build gocov
$(GOCOV_XML): $(TOOLS_DIR)/go.mod
cd $(TOOLS_DIR); go mod download; go build -tags=tools -o bin/gocov-xml github.com/AlekSi/gocov-xml
gocov-xml: $(GOCOV_XML) ## Build gocov-xml
2021-08-09 19:57:59 +03:00
$(GOFUMPT): $(TOOLS_DIR)/go.mod
cd $(TOOLS_DIR); go mod download; go build -tags=tools -o bin/gofumpt mvdan.cc/gofumpt
2021-08-09 19:57:59 +03:00
gofmt gofumpt: $(GOFUMPT) ## Build gofumpt
$(GOLANGCI_LINT): $(TOOLS_DIR)/go.mod
cd $(TOOLS_DIR); go mod download; go build -tags=tools -o bin/golangci-lint github.com/golangci/golangci-lint/cmd/golangci-lint
golangci-lint: $(GOLANGCI_LINT) ## Build golangci-lint
2021-08-09 19:57:59 +03:00
$(GO_JUNIT_REPORT): $(TOOLS_DIR)/go.mod
cd $(TOOLS_DIR); go mod download; go build -tags=tools -o bin/go-junit-report github.com/jstemmer/go-junit-report
go-junit-report: $(GO_JUNIT_REPORT) ## Build go-junit-report
$(MOCKGEN): $(TOOLS_DIR)/go.mod
cd $(TOOLS_DIR); go mod download; go build -tags=tools -o bin/mockgen github.com/golang/mock/mockgen
mockgen: $(MOCKGEN) ## Build mockgen
tools: gocov gocov-xml go-junit-report golangci-lint gofmt ## Build bins for build tools