Files
akvorado/Makefile
Vincent Bernat f9eee6f509
Some checks failed
CI / 🤖 Check dependabot status (push) Has been cancelled
CI / 🐧 Test on Linux (${{ github.ref_type == 'tag' }}, misc) (push) Has been cancelled
CI / 🐧 Test on Linux (coverage) (push) Has been cancelled
CI / 🐧 Test on Linux (regular) (push) Has been cancelled
CI / ❄️ Build on Nix (push) Has been cancelled
CI / 🍏 Build and test on macOS (push) Has been cancelled
CI / 🧪 End-to-end testing (push) Has been cancelled
CI / 🔍 Upload code coverage (push) Has been cancelled
CI / 🔬 Test only Go (push) Has been cancelled
CI / 🔬 Test only JS (${{ needs.dependabot.outputs.package-ecosystem }}, 20) (push) Has been cancelled
CI / 🔬 Test only JS (${{ needs.dependabot.outputs.package-ecosystem }}, 22) (push) Has been cancelled
CI / 🔬 Test only JS (${{ needs.dependabot.outputs.package-ecosystem }}, 24) (push) Has been cancelled
CI / ⚖️ Check licenses (push) Has been cancelled
CI / 🐋 Build Docker images (push) Has been cancelled
CI / 🐋 Tag Docker images (push) Has been cancelled
CI / 🚀 Publish release (push) Has been cancelled
Update Nix dependency hashes / Update dependency hashes (push) Has been cancelled
conntrackfixer: removal of the service
This is not needed anymore since Docker Engine v23. This version is
unmaintained since May 2025 (not that old).

See:
- https://github.com/moby/moby/pull/44752
- https://github.com/moby/moby/pull/44742

Fix #2153 (in a way)
2025-12-08 15:05:56 +01:00

313 lines
15 KiB
Makefile

export CGO_ENABLED = 0
export GOTOOLCHAIN ?= local+auto
MODULE = $(shell $(GO) list -m)
VERSION ?= $(shell git describe --tags --always --dirty --match=v* 2> /dev/null || \
cat .version 2> /dev/null || echo v0)
PKGS = $(or $(PKG),$(shell $(GO) list ./...))
GO = go
PNPM = $(or $(shell command -v pnpm 2>/dev/null),\
$(shell command -v corepack 2>/dev/null | sed 's/$$/ pnpm/'),\
$(error No pnpm command found))
CLANG = clang
TIMEOUT = 45s
LSFILES = git ls-files -cmo --exclude-standard --
V = 0
Q = $(if $(filter 1,$V),,@)
M = $(shell if [ "$$(tput colors 2> /dev/null || echo 0)" -ge 8 ]; then printf "\033[34;1m▶\033[0m"; else printf "▶"; fi)
GENERATED_JS = \
console/frontend/node_modules
GENERATED_GO = \
common/pb/rawflow.pb.go \
common/pb/rawflow_vtproto.pb.go \
common/schema/definition_gen.go \
inlet/flow/input/udp/reuseport_bpfeb.o \
inlet/flow/input/udp/reuseport_bpfel.o \
orchestrator/clickhouse/data/asns.csv \
orchestrator/clickhouse/data/protocols.csv \
orchestrator/clickhouse/data/tcp.csv \
orchestrator/clickhouse/data/udp.csv \
console/filter/parser.go \
inlet/kafka/loadbalancealgorithm_enumer.go \
outlet/core/asnprovider_enumer.go \
outlet/core/netprovider_enumer.go \
outlet/metadata/provider/snmp/authprotocol_enumer.go \
outlet/metadata/provider/snmp/privprotocol_enumer.go \
outlet/metadata/provider/gnmi/ifspeedpathunit_enumer.go \
console/homepagetopwidget_enumer.go \
common/kafka/saslmechanism_enumer.go
GENERATED_TEST_GO = \
common/clickhousedb/mocks/mock_driver.go
GENERATED = \
$(GENERATED_GO) \
$(GENERATED_JS) \
console/data/frontend \
common/embed/data/embed.zip
.PHONY: all all-indep
BUILD_ARGS =
# For architecture variants, see:
# - https://go.dev/wiki/MinimumRequirements#amd64
# - https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels
# - https://clang.llvm.org/docs/UsersManual.html#x86
# - https://go.dev/wiki/MinimumRequirements#arm64
# - https://github.com/golang/go/issues/60905
# - https://github.com/llvm/llvm-project/blob/main/llvm/unittests/TargetParser/TargetParserTest.cpp#L1077
# - https://en.wikipedia.org/wiki/Comparison_of_ARM_processors
# - https://docs.docker.com/build/building/variables/#pre-defined-build-arguments
# - https://github.com/containerd/platforms/pull/8
all: fmt lint all-indep ; $(info $(M) building executable) @ ## Build program binary
$Q env GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) \
$(if $(filter amd64,$(TARGETARCH)),GOAMD64=$(TARGETVARIANT),\
$(if $(filter arm64,$(TARGETARCH)),GOARM64=$(if $(findstring .,$(TARGETVARIANT)),$(TARGETVARIANT),$(TARGETVARIANT:%=%.0)),\
$(if $(filter arm,$(TARGETARCH)),GOARM=$(TARGETVARIANT:v%=%)))) \
$(GO) build \
-tags release,grpcnotrace \
-ldflags '-X $(MODULE)/common/helpers.AkvoradoVersion=$(VERSION)' \
$(BUILD_ARGS) \
-o bin/$(basename $(MODULE)) .
all-indep: $(GENERATED)
# Tools
BUF = env GO=$(GO) ./bin/external-tool buf
ENUMER = go tool enumer
GOIMPORTS = go tool goimports
GOTESTSUM = go tool gotestsum
MOCKGEN = go tool mockgen
PIGEON = go tool pigeon
REVIVE = go tool revive
STATICCHECK = go tool staticcheck
WWHRD = go tool wwhrd
# Generated files
.SUFFIXES:
.DELETE_ON_ERROR:
$(filter %.go, $(GENERATED_GO) $(GENERATED_TEST_GO)): go.mod
common/pb/rawflow.pb.go common/pb/rawflow_vtproto.pb.go &: .buf.gen.yaml common/pb/rawflow.proto ; $(info $(M) compiling protocol buffers $@…)
$Q $(BUF) generate --template $(PWD)/.buf.gen.yaml --path $(@:.pb.go=.proto)
common/clickhousedb/mocks/mock_driver.go: ; $(info $(M) generate mocks for ClickHouse driver)
$Q $(MOCKGEN) -package mocks -build_constraint "!release" -destination $@ \
github.com/ClickHouse/clickhouse-go/v2/lib/driver Conn,Row,Rows,ColumnType
$Q touch $@
inlet/flow/input/udp/reuseport_%.o: inlet/flow/input/udp/reuseport_kern.c inlet/flow/input/udp/vmlinux.h ; $(info $(M) generate eBPF program for input/udp ($*))
$Q ! $(CLANG) -print-targets 2> /dev/null | grep -qF $* || \
$(CLANG) -O2 -g -Wall -target $* -c $< -o $@
inlet/kafka/loadbalancealgorithm_enumer.go: inlet/kafka/config.go ; $(info $(M) generate enums for LoadBalanceAlgorithm)
$Q $(ENUMER) -type=LoadBalanceAlgorithm -text -transform=kebab -trimprefix=LoadBalance inlet/kafka/config.go
outlet/core/asnprovider_enumer.go: outlet/core/config.go ; $(info $(M) generate enums for ASNProvider)
$Q $(ENUMER) -type=ASNProvider -text -transform=kebab -trimprefix=ASNProvider outlet/core/config.go
outlet/core/netprovider_enumer.go: outlet/core/config.go ; $(info $(M) generate enums for NetProvider)
$Q $(ENUMER) -type=NetProvider -text -transform=kebab -trimprefix=NetProvider outlet/core/config.go
outlet/metadata/provider/snmp/authprotocol_enumer.go: outlet/metadata/provider/snmp/config.go ; $(info $(M) generate enums for AuthProtocol)
$Q $(ENUMER) -type=AuthProtocol -text -transform=kebab -trimprefix=AuthProtocol outlet/metadata/provider/snmp/config.go
outlet/metadata/provider/snmp/privprotocol_enumer.go: outlet/metadata/provider/snmp/config.go ; $(info $(M) generate enums for PrivProtocol)
$Q $(ENUMER) -type=PrivProtocol -text -transform=kebab -trimprefix=PrivProtocol outlet/metadata/provider/snmp/config.go
outlet/metadata/provider/gnmi/ifspeedpathunit_enumer.go: outlet/metadata/provider/gnmi/config.go ; $(info $(M) generate enums for IfSpeedPathUnit)
$Q $(ENUMER) -type=IfSpeedPathUnit -text -transform=kebab -trimprefix=Speed outlet/metadata/provider/gnmi/config.go
console/homepagetopwidget_enumer.go: console/config.go ; $(info $(M) generate enums for HomepageTopWidget)
$Q $(ENUMER) -type=HomepageTopWidget -text -json -transform=kebab -trimprefix=HomepageTopWidget console/config.go
common/kafka/saslmechanism_enumer.go: common/kafka/config.go ; $(info $(M) generate enums for SASLMechanism)
$Q $(ENUMER) -type=SASLMechanism -text -transform=kebab -trimprefix=SASL common/kafka/config.go
common/schema/definition_gen.go: common/schema/definition.go common/schema/definition_gen.sh ; $(info $(M) generate column definitions)
$Q ./common/schema/definition_gen.sh > $@
$Q $(GOIMPORTS) -w $@
console/filter/parser.go: console/filter/parser.peg ; $(info $(M) generate PEG parser for filters)
$Q $(PIGEON) -optimize-basic-latin $< > $@
console/frontend/node_modules: console/frontend/package.json console/frontend/pnpm-lock.yaml
console/frontend/node_modules: ; $(info $(M) fetching node modules)
$Q (cd console/frontend ; $(PNPM) install --loglevel=error --frozen-lockfile) && touch $@
console/data/frontend: $(GENERATED_JS)
console/data/frontend: $(shell $(LSFILES) console/frontend 2> /dev/null)
console/data/frontend: ; $(info $(M) building console frontend)
$Q cd console/frontend && $(PNPM) run --silent build
ASNS_URL = https://vincentbernat.github.io/asn2org/asns.csv
PROTOCOLS_URL = http://www.iana.org/assignments/protocol-numbers/protocol-numbers-1.csv
SERVICES_URL = https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.csv
define caturl
$(if $(filter http://% https://%, $(1)),curl --retry 3 --no-progress-meter --location --fail $(1),cat $(1))
endef
orchestrator/clickhouse/data/asns.csv: ; $(info $(M) generate ASN map)
$Q $(call caturl,$(ASNS_URL)) | sed 's|,[^,]*$$||' > $@
$Q test -s $@
orchestrator/clickhouse/data/protocols.csv: ; $(info $(M) generate protocol map)
$Q $(call caturl,$(PROTOCOLS_URL)) \
| sed -nE -e "1 s/.*/proto,name,description/p" -e "2,$$ s/^([0-9]+,[^ ,]+,[^\",]+),.*/\1/p" \
> $@
$Q test -s $@
orchestrator/clickhouse/data/udp.csv orchestrator/clickhouse/data/tcp.csv: orchestrator/clickhouse/data/%.csv: ; $(info $(M) generate $* port numbers)
$Q $(call caturl,$(SERVICES_URL)) \
| sed -nE -e "1 s/.*/port,name/p" -e "2,$$ s/^([^,]+),([0-9]+),$*,.*/\2,\1/p" \
| awk -F',' '!seen[$$1]++' \
> $@
$Q test -s $@
changelog.md: docs/99-changelog.md # To be used by GitHub actions only.
$Q > $@ < docs/99-changelog.md \
sed -n '/^## '$${GITHUB_REF##*/v}' -/,/^## /{//!p}'
$Q >> $@ echo "**Docker image**: \`docker pull ghcr.io/$${GITHUB_REPOSITORY}:$${GITHUB_REF##*/v}\`"
$Q >> $@ echo "**Full changelog**: https://github.com/$${GITHUB_REPOSITORY}/compare/v$$(< docs/99-changelog.md sed -n '/^## '$${GITHUB_REF##*/v}' -/,/^## /{s/^## \([0-9.a-z-]*\) -.*/\1/p}' | tail -1)...v$${GITHUB_REF##*/v}"
# Update default.pgo with the locally running "docker compose" instance.
# Use: "make -j default.pgo".
default.pgo: default-inlet.pgo default-outlet.pgo default-console.pgo
$Q go tool pprof -proto $^ > $@
$Q rm $^
default-%.pgo:
$Q container=akvorado-akvorado-$*-1 ; \
ip=$$(docker container inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $$container) ; \
[ -n $$ip ] ; \
curl -so $@ "http://$$ip:8080/debug/pprof/profile?seconds=30"
common/embed/data/embed.zip: console/data/frontend console/authentication/data/avatars console/data/docs
common/embed/data/embed.zip: orchestrator/clickhouse/data/protocols.csv orchestrator/clickhouse/data/icmp.csv orchestrator/clickhouse/data/asns.csv orchestrator/clickhouse/data/tcp.csv orchestrator/clickhouse/data/udp.csv
common/embed/data/embed.zip: ; $(info $(M) generate embed.zip)
$Q mkdir -p common/embed/data
$Q TMPDIR=$$(mktemp -d) \
&& trap 'rm -rf "$$TMPDIR"' EXIT \
&& tar -cf - $^ | tar -C "$$TMPDIR" -xf - \
&& find "$$TMPDIR"/console/data/docs -name "*.svg" -type f -print0 | xargs -0 sed -i.bak 's/ content="[^"]*"//g' \
&& ( cd "$$TMPDIR" && zip --quiet --recurse-paths --exclude "*.svg.bak" - .) > $@
# Tests
.PHONY: check test tests test-race test-short test-bench test-coverage
.PHONY: test-go test-go-units test-go-staticcheck test-js test-coverage-go test-coverage-js
check test tests: test-go test-js ## Run tests
test-coverage: test-coverage-go test-coverage-js ## Run coverage tests
test-go-units test-go-checks test-bench test-race test-coverage-go: .fmt-go~ .lint-go~ $(GENERATED) $(GENERATED_TEST_GO)
test-go: test-go-units test-go-checks ## Run Go tests
test-go-checks: ; $(info $(M) running Go static checks)
$Q $(STATICCHECK) -f stylish -checks inherit,-SA1012 $(PKGS)
test-go-units: ; $(info $(M) running Go tests$(GOTEST_MORE))
$Q mkdir -p test/go
$Q env PATH=$(dir $(abspath $(shell command -v $(GO)))):$(PATH) \
$(GOTESTSUM) --junitfile test/go/tests.xml -- \
-timeout $(TIMEOUT) \
-fullpath \
$(GOTEST_ARGS) $(PKGS)
test-race: CGO_ENABLED=1
test-race: GOTEST_ARGS=-race
test-race: GOTEST_MORE=, with race detector
test-race: test-go-units ## Run Go tests with race detector
test-short: GOTEST_ARGS=-short
test-short: GOTEST_MORE=, only short tests
test-short: test-go ## Run only short Go tests
test-bench: ; $(info $(M) running benchmarks) @ ## Run Go benchmarks
$Q $(GO) test \
-fullpath -run=__absolutelynothing__ -bench=. \
$(PKGS) # -benchmem -memprofile test/go/memprofile.out -cpuprofile test/go/cpuprofile.out
test-coverage-go: ; $(info $(M) running Go coverage tests) @ ## Run Go coverage tests
$Q mkdir -p test/go
$Q env PATH=$(dir $(abspath $(shell command -v $(GO)))):$(PATH) \
$(GOTESTSUM) -- \
-fullpath \
-coverpkg=$(shell echo $(PKGS) | tr ' ' ',') \
-covermode=atomic \
-coverprofile=test/go/profile.out.tmp $(PKGS)
$Q GENERATED=$$(awk -F: '(NR > 1) {print $$1}' test/go/profile.out.tmp \
| sort | uniq | sed "s+^$(MODULE)/++" \
| xargs grep -l "^//.*DO NOT EDIT\.$$" \
| sed "s+\(.*\)+^$(MODULE)/\1:+" | paste -s -d '|' -) ; \
if [ -n "$$GENERATED" ]; then grep -Ev "$$GENERATED" test/go/profile.out.tmp > test/go/profile.out ; \
else cp test/go/profile.out.tmp test/go/profile.out ; \
fi
$Q $(GO) tool cover -html=test/go/profile.out -o test/go/coverage.html
@printf "Code coverage: "; \
go tool cover -func test/go/profile.out | awk '($$1 == "total:") { print $$NF}'
test-js: .fmt-js~ .lint-js~ $(GENERATED_JS)
test-js: ; $(info $(M) running JS tests) @ ## Run JS tests
$Q cd console/frontend && $(PNPM) run --silent type-check && $(PNPM) run --silent test
test-coverage-js: ; $(info $(M) running JS coverage tests) @ ## Run JS coverage tests
$Q cd console/frontend && $(PNPM) run --silent type-check && $(PNPM) run --silent test -- --coverage
.PHONY: lint
lint: .lint-go~ .lint-js~ ## Run linting
.lint-go~: .revive.toml $(shell $(LSFILES) '*.go' 2> /dev/null) ; $(info $(M) running golint)
$Q $(REVIVE) -config $(PWD)/.revive.toml -formatter stylish -set_exit_status ./...
$Q touch $@
.lint-js~: $(shell $(LSFILES) '*.js' '*.ts' '*.vue' '*.html' 2> /dev/null)
.lint-js~: $(GENERATED_JS) ; $(info $(M) running jslint)
$Q cd console/frontend && $(PNPM) run --silent lint
$Q touch $@
.PHONY: fmt
fmt: .fmt-go~ .fmt-js~ ## Format all source files
.fmt-go~: $(shell $(LSFILES) '*.go' 2> /dev/null) ; $(info $(M) formatting Go code)
$Q $(GOIMPORTS) -local $(MODULE) -w $? < /dev/null
$Q touch $@
.fmt-js~: $(shell $(LSFILES) '*.js' '*.ts' '*.vue' '*.html' 2> /dev/null)
.fmt-js~: $(GENERATED_JS) ; $(info $(M) formatting JS code)
$Q cd console/frontend && $(PNPM) run --silent format
$Q touch $@
# Misc
.PHONY: licensecheck
licensecheck: console/frontend/node_modules ; $(info $(M) check dependency licenses) @ ## Check licenses
$Q ! git grep -L SPDX-License-Identifier: "*.go" "*.ts" "*.js" || \
(>&2 echo "*** Missing license identifiers!"; false)
$Q err=0 ; $(GO) mod vendor && $(WWHRD) --quiet check || err=$$? ; rm -rf vendor/ ; exit $$err
$Q cd console/frontend ; \
allowed="$$(sed -n '/^allowlist:/,/^[a-z]/p' ../../.wwhrd.yml | sed -n 's/^ - //p' | paste -sd "|")" ; \
! $(PNPM) licenses ls --json | jq -r --exit-status --arg allowed "$$allowed" \
'to_entries[] | select(.key | test("^('"$$allowed"')$$") | not) | "Unallowed license: " + .key + " (" + (.value | map(.name) | join(", ")) + ")"'
.PHONY: clean
clean: ; $(info $(M) cleaning) @ ## Cleanup everything
@rm -rf test $(GENERATED) $(GENERATED_TEST_GO) *~ bin/akvorado
.PHONY: help
help:
@grep -hE '^[ a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-17s\033[0m %s\n", $$1, $$2}'
.PHONY: version
version:
@echo $(VERSION)
.PHONY: docker docker-dev
DOCKER_BUILD_ARGS =
docker: ; $(info $(M) build Docker image) @ ## Build Docker image
$Q git ls-files | tar -T- -cf- | docker build --pull -f docker/Dockerfile $(DOCKER_BUILD_ARGS) \
--build-arg VERSION=$(VERSION) -t ghcr.io/akvorado/akvorado:main -
docker-dev: TARGETOS=linux
docker-dev: all ; $(info $(M) build development Docker image) @ ## Build development Docker image
$Q docker build -f docker/Dockerfile.dev $(DOCKER_BUILD_ARGS) \
--build-arg VERSION=$(VERSION) -t ghcr.io/akvorado/akvorado:main .
.PHONY: all-coverage docker-dev-coverage
all-coverage: BUILD_ARGS=-cover -covermode=atomic
all-coverage: all
docker-dev-coverage: BUILD_ARGS=-cover -covermode=atomic
docker-dev-coverage: docker-dev
# This requires "skopeo". I fetch it from nix.
.PHONY: docker-upgrade-versions
docker-upgrade-versions: ; $(info $(M) check for Docker image updates) @ ## Check for Docker image updates
$Q sed -En 's/^\s*image:\s+(.+):(.+)\s+#\s+(.+)$$/\1 \2 \3/p' docker/versions.yml \
| while read -r image version regex; do \
latest=$$(nix run nixpkgs\#skopeo -- list-tags docker://"$$image" \
| sed -En 's/\s+"(.*)",?/\1/p' \
| grep -xP "$$regex" \
| sort -Vr | head -1); \
[ "$$version" = "$$latest" ] || { \
>&2 echo "$$image $$version→$$latest"; \
sed -i "s,$$image:$$version,$$image:$$latest," docker/versions.yml; }; \
done