113 lines
5.3 KiB
Makefile
113 lines
5.3 KiB
Makefile
# novox/hq ADR 0006 — the control plane, in Go.
|
|
#
|
|
# The image the bundle pins holds the program and nothing else, so the build is static and the
|
|
# container is built FROM scratch. That is not a size optimisation: this image is fetched by
|
|
# digest and run on a machine where no mesh exists to check anything, and everything in it is
|
|
# something a person would have to audit.
|
|
|
|
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo development)
|
|
LDFLAGS := -s -w -X main.version=$(VERSION)
|
|
|
|
# Where `make check` raises PostgreSQL. A high port and a throwaway container: nothing here
|
|
# touches a database anybody else is using. Override PG_PORT if this one is taken -- the first
|
|
# port chosen was already serving something that had been up for six days.
|
|
PG_PORT ?= 55532
|
|
PG_CONTAINER ?= mesh-controller-check
|
|
PG_IMAGE ?= postgres:17-alpine
|
|
export MESH_TEST_POSTGRES ?= postgres://postgres:check@127.0.0.1:$(PG_PORT)/postgres?sslmode=disable
|
|
|
|
.PHONY: build image check test vet fmt postgres postgres-stop clean
|
|
|
|
build:
|
|
CGO_ENABLED=0 go build -trimpath -ldflags '$(LDFLAGS)' -o build/mesh-controller ./cmd/mesh-controller
|
|
|
|
# Tagged 'development' as well as by version, because the lab places images by name and a
|
|
# scenario naming a version would have to be edited on every build. The version tag is what a
|
|
# real bundle pins.
|
|
IMAGE ?= mesh-controller:$(VERSION)
|
|
DEV_TAG ?= mesh-controller:development
|
|
|
|
# The Go base the image is built on.
|
|
#
|
|
# **`make image` was broken and stayed broken**, because the Dockerfile's fallback base was a Go
|
|
# older than go.mod asks for: every build died at `go mod download` with "go.mod requires go >=
|
|
# 1.26.0", and the pipeline never saw it because the pipeline passes the declared base in. Anybody
|
|
# building the image by hand hit it and had to find the digest themselves (novox/hq 04-ISSUES/146,
|
|
# what it cost).
|
|
#
|
|
# **Pinned here since the manifest stopped building an image** (novox/hq issue 213): the mesh builds
|
|
# the controller as a Go bundle with its own toolchain, and only `make image` — genesis and the lab —
|
|
# still needs a Go base. The digest is the one the manifest declared until then.
|
|
GO_BASE ?= golang@sha256:8ac98ca534ac3f51e1f420a1dd2c15e74c75cfa0f23f3ad27eb5d7236c349a0c
|
|
|
|
image:
|
|
@test -n "$(GO_BASE)" || { echo "no GO_BASE; pass GO_BASE=<image>"; exit 1; }
|
|
docker build --build-arg GO_BASE=$(GO_BASE) --build-arg VERSION=$(VERSION) -t $(IMAGE) -t $(DEV_TAG) .
|
|
@echo
|
|
@docker image inspect $(IMAGE) --format 'built {{.RepoTags}} {{.Size}} bytes'
|
|
|
|
# The provisioner ships as an image too, because it is the thing that makes a sealed credential
|
|
# true on a machine -- and the mesh cannot, having discarded the plaintext.
|
|
PROVISIONER_IMAGE ?= mesh-provision-postgres:$(VERSION)
|
|
PROVISIONER_DEV_TAG ?= mesh-provision-postgres:development
|
|
|
|
provisioner-image:
|
|
docker build --build-arg GO_BASE=$(GO_BASE) -f examples/postgres-provisioner/Dockerfile \
|
|
-t $(PROVISIONER_IMAGE) -t $(PROVISIONER_DEV_TAG) .
|
|
@echo
|
|
@docker image inspect $(PROVISIONER_IMAGE) --format 'built {{.RepoTags}} {{.Size}} bytes'
|
|
|
|
# The object store's provisioner, for the same reason: a bucket and a policy are not files, and
|
|
# the mesh cannot make them -- it discarded the credential it would have to use.
|
|
OBJECTSTORE_IMAGE ?= mesh-provision-objectstore:$(VERSION)
|
|
OBJECTSTORE_DEV_TAG ?= mesh-provision-objectstore:development
|
|
|
|
objectstore-image:
|
|
docker build --build-arg GO_BASE=$(GO_BASE) -f examples/objectstore-provisioner/Dockerfile \
|
|
-t $(OBJECTSTORE_IMAGE) -t $(OBJECTSTORE_DEV_TAG) .
|
|
@echo
|
|
@docker image inspect $(OBJECTSTORE_IMAGE) --format 'built {{.RepoTags}} {{.Size}} bytes'
|
|
|
|
# The cache's provisioner, for the same reason as the database's: an ACL user is not a file,
|
|
# and the mesh cannot make one -- it discarded the credential it would have to use.
|
|
REDIS_PROVISIONER_IMAGE ?= mesh-provision-redis:$(VERSION)
|
|
REDIS_PROVISIONER_DEV_TAG ?= mesh-provision-redis:development
|
|
|
|
redis-provisioner-image:
|
|
docker build --build-arg GO_BASE=$(GO_BASE) -f examples/redis-provisioner/Dockerfile \
|
|
-t $(REDIS_PROVISIONER_IMAGE) -t $(REDIS_PROVISIONER_DEV_TAG) .
|
|
@echo
|
|
@docker image inspect $(REDIS_PROVISIONER_IMAGE) --format 'built {{.RepoTags}} {{.Size}} bytes'
|
|
|
|
# The unit level alone (untagged: no bus, no store, no other process), which a developer runs continuously. The tests
|
|
# that need a bus or the store carry `//go:build integration` and run in `check`, not here; without a database the
|
|
# store's tests would skip rather than fail anyway.
|
|
test:
|
|
go test -timeout 15m ./...
|
|
|
|
vet:
|
|
go vet ./...
|
|
|
|
# A quick step for a developer: the checker runs the build module's own formatting and vet (ADR 0501 §5, D7).
|
|
fmt:
|
|
@unformatted=$$(gofmt -l cmd internal examples) ; \
|
|
if [ -n "$$unformatted" ] ; then echo "not gofmt'd:" ; echo "$$unformatted" ; exit 1 ; fi
|
|
|
|
postgres:
|
|
@docker rm -f -v $(PG_CONTAINER) >/dev/null 2>&1 || true
|
|
@docker run -d --name $(PG_CONTAINER) -e POSTGRES_PASSWORD=check \
|
|
-p 127.0.0.1:$(PG_PORT):5432 $(PG_IMAGE) >/dev/null
|
|
@printf 'waiting for postgres'
|
|
@for i in $$(seq 1 60) ; do \
|
|
if docker exec $(PG_CONTAINER) pg_isready -U postgres >/dev/null 2>&1 ; then \
|
|
echo ' — ready' ; exit 0 ; fi ; \
|
|
printf '.' ; sleep 1 ; \
|
|
done ; \
|
|
echo ' — never came up' ; docker logs $(PG_CONTAINER) | tail -20 ; exit 1
|
|
|
|
postgres-stop:
|
|
@docker rm -f -v $(PG_CONTAINER) >/dev/null 2>&1 || true
|
|
|
|
clean:
|
|
rm -rf build/
|