From 8ab75f17982c700b3d2b4a79ce8122d7d06aa53b Mon Sep 17 00:00:00 2001 From: Francis Charette Migneault Date: Fri, 7 Mar 2025 23:12:18 -0500 Subject: [PATCH 1/3] add docker provenance & SBOM --- Makefile | 93 ++++++++++++++++++++++++++++++++------- docker/Dockerfile-manager | 3 +- docker/Dockerfile-worker | 3 +- 3 files changed, 80 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 17590dd31..ad593b05d 100644 --- a/Makefile +++ b/Makefile @@ -11,8 +11,6 @@ APP_ROOT := $(abspath $(lastword $(MAKEFILE_NAME))/..) APP_NAME := $(shell basename $(APP_ROOT)) APP_VERSION ?= 6.4.0 APP_INI ?= $(APP_ROOT)/config/$(APP_NAME).ini -DOCKER_REPO ?= pavics/weaver -#DOCKER_REPO ?= docker-registry.crim.ca/ogc/weaver # guess OS (Linux, Darwin,...) OS_NAME := $(shell uname -s 2>/dev/null || echo "unknown") @@ -834,6 +832,51 @@ generate-archive: ## generate ZIP and TAR.GZ archives using current contents ## -- Docker targets ------------------------------------------------------------------------------------------------ ## +DOCKER_REPO ?= pavics/weaver +#DOCKER_REPO ?= docker-registry.crim.ca/ogc/weaver + +# NOTE: +# Because of the --push requirement when involving provenance/SBOM +# only full '[registry.uri/]org/weaver:tag' can be passed as '-t' label +# since the build must actively register the built image with a trusted authority. +# Additional "alias" tags provided for convenience must be applied separately. +# Also, any intermediate image used as base for derived ones must explicitly +# employ the remote registry reference to provide the relevant traceability. + +# whether to enable Provenance and SBOM tracking of built images +DOCKER_PROV ?= true +ifeq ($(DOCKER_PROV),true) + DOCKER_BUILDER_STEP := docker-builder + DOCKER_BUILDER_NAME ?= docker-prov + DOCKER_BUILDER_BASE ?= $(DOCKER_REPO):$(APP_VERSION) + DOCKER_BUILDER_ARGS ?= \ + --provenance=true \ + --sbom=true \ + --builder="$(DOCKER_BUILDER_NAME)" \ + --build-arg "DOCKER_BASE=$(DOCKER_BUILDER_BASE)" \ + --push + # tag aliases is not required since images are pushed directly to the registry + # if explicitly required, they need to be pulled as they won't resolve locally + DOCKER_BUILDER_PULL := docker pull + DOCKER_TAG_ALIASES ?= false +else + # tag aliases is required to obtain the 'weaver:base' name used by derived images + # use 'true' command to mute the arguments used in the other case + override DOCKER_BUILDER_PULL := true + override DOCKER_TAG_ALIASES := true +endif + +.PHONY: docker-builder +docker-builder: + @echo "Checking docker-container builder required for Docker provenance..." + @( \ + docker buildx inspect "$(DOCKER_BUILDER_NAME)" >/dev/null && \ + echo "Container Builder [$(DOCKER_BUILDER_NAME)] already exists." \ + ) || ( \ + echo "Creating Docker Container [$(DOCKER_BUILDER_NAME)]..." \ + docker buildx create --name "$(DOCKER_BUILDER_NAME)" --driver=docker-container \ + ) + .PHONY: docker-info docker-info: ## obtain docker image information @echo "Docker image will be built as: " @@ -842,25 +885,41 @@ docker-info: ## obtain docker image information @echo "$(DOCKER_REPO):$(APP_VERSION)" .PHONY: docker-build-base -docker-build-base: ## build the base docker image - docker build "$(APP_ROOT)" -f "$(APP_ROOT)/docker/Dockerfile-base" -t "$(APP_NAME):base" - docker tag "$(APP_NAME):base" "$(APP_NAME):latest" - docker tag "$(APP_NAME):base" "$(DOCKER_REPO):latest" - docker tag "$(APP_NAME):base" "$(DOCKER_REPO):$(APP_VERSION)" +docker-build-base: $(DOCKER_BUILDER_STEP) ## build the base docker image + docker build "$(APP_ROOT)" \ + $(DOCKER_BUILDER_ARGS) \ + -f "$(APP_ROOT)/docker/Dockerfile-base" \ + -t "$(DOCKER_REPO):$(APP_VERSION)" + docker tag "$(DOCKER_REPO):$(APP_VERSION)" "$(DOCKER_REPO):latest" + docker tag "$(DOCKER_REPO):$(APP_VERSION)" "$(APP_NAME):$(APP_VERSION)" + docker tag "$(DOCKER_REPO):$(APP_VERSION)" "$(APP_NAME):latest" + docker tag "$(DOCKER_REPO):$(APP_VERSION)" "$(APP_NAME):base" .PHONY: docker-build-manager -docker-build-manager: docker-build-base ## build the manager docker image - docker build "$(APP_ROOT)" -f "$(APP_ROOT)/docker/Dockerfile-manager" -t "$(APP_NAME):$(APP_VERSION)-manager" - docker tag "$(APP_NAME):$(APP_VERSION)-manager" "$(APP_NAME):latest-manager" - docker tag "$(APP_NAME):$(APP_VERSION)-manager" "$(DOCKER_REPO):latest-manager" - docker tag "$(APP_NAME):$(APP_VERSION)-manager" "$(DOCKER_REPO):$(APP_VERSION)-manager" +docker-build-manager: $(DOCKER_BUILDER_STEP) docker-build-base ## build the manager docker image + docker build "$(APP_ROOT)" \ + $(DOCKER_BUILDER_ARGS) \ + -f "$(APP_ROOT)/docker/Dockerfile-manager" \ + -t "$(DOCKER_REPO):$(APP_VERSION)-manager" + @[ "$(DOCKER_TAG_ALIASES)" = "true" ] && ( \ + $(DOCKER_BUILDER_PULL) "$(DOCKER_REPO):$(APP_VERSION)-manager" && \ + docker tag "$(DOCKER_REPO):$(APP_VERSION)-manager" "$(DOCKER_REPO):latest-manager" && \ + docker tag "$(DOCKER_REPO):$(APP_VERSION)-manager" "$(APP_NAME):$(APP_VERSION)-manager" && \ + docker tag "$(DOCKER_REPO):$(APP_VERSION)-manager" "$(APP_NAME):latest-manager" \ + ) || true .PHONY: docker-build-worker -docker-build-worker: docker-build-base ## build the worker docker image - docker build "$(APP_ROOT)" -f "$(APP_ROOT)/docker/Dockerfile-worker" -t "$(APP_NAME):$(APP_VERSION)-worker" - docker tag "$(APP_NAME):$(APP_VERSION)-worker" "$(APP_NAME):latest-worker" - docker tag "$(APP_NAME):$(APP_VERSION)-worker" "$(DOCKER_REPO):latest-worker" - docker tag "$(APP_NAME):$(APP_VERSION)-worker" "$(DOCKER_REPO):$(APP_VERSION)-worker" +docker-build-worker: $(DOCKER_BUILDER_STEP) docker-build-base ## build the worker docker image + docker build "$(APP_ROOT)" \ + $(DOCKER_BUILDER_ARGS) \ + -f "$(APP_ROOT)/docker/Dockerfile-worker" \ + -t "$(DOCKER_REPO):$(APP_VERSION)-worker" + @[ "$(DOCKER_TAG_ALIASES)" = "true" ] && ( \ + $(DOCKER_BUILDER_PULL) "$(DOCKER_REPO):$(APP_VERSION)-worker" ] && \ + docker tag "$(DOCKER_REPO):$(APP_VERSION)-worker" "$(DOCKER_REPO):latest-worker" && \ + docker tag "$(DOCKER_REPO):$(APP_VERSION)-worker" "$(APP_NAME):$(APP_VERSION)-worker" && \ + docker tag "$(DOCKER_REPO):$(APP_VERSION)-worker" "$(APP_NAME):latest-worker" \ + ) || true .PHONY: docker-build docker-build: docker-build-base docker-build-manager docker-build-worker ## build all docker images diff --git a/docker/Dockerfile-manager b/docker/Dockerfile-manager index e489ad46e..ea6d394ee 100644 --- a/docker/Dockerfile-manager +++ b/docker/Dockerfile-manager @@ -1,4 +1,5 @@ -FROM weaver:base +ARG DOCKER_BASE="weaver:base" +FROM ${DOCKER_BASE} LABEL description.short="Weaver Manager" CMD pserve "${APP_CONFIG_DIR}/weaver.ini" diff --git a/docker/Dockerfile-worker b/docker/Dockerfile-worker index 24c23491c..c71bebfb6 100644 --- a/docker/Dockerfile-worker +++ b/docker/Dockerfile-worker @@ -1,4 +1,5 @@ -FROM weaver:base +ARG DOCKER_BASE="weaver:base" +FROM ${DOCKER_BASE} LABEL description.short="Weaver Worker" RUN apt-get update && apt-get install -y --no-install-recommends \ From c1ab4d32efc67676a5686fdd22ffbac1741eb73e Mon Sep 17 00:00:00 2001 From: Francis Charette Migneault Date: Fri, 7 Mar 2025 23:33:08 -0500 Subject: [PATCH 2/3] fix builder creation command --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ad593b05d..1edd59f0d 100644 --- a/Makefile +++ b/Makefile @@ -873,7 +873,7 @@ docker-builder: docker buildx inspect "$(DOCKER_BUILDER_NAME)" >/dev/null && \ echo "Container Builder [$(DOCKER_BUILDER_NAME)] already exists." \ ) || ( \ - echo "Creating Docker Container [$(DOCKER_BUILDER_NAME)]..." \ + echo "Creating Docker Container [$(DOCKER_BUILDER_NAME)]..." && \ docker buildx create --name "$(DOCKER_BUILDER_NAME)" --driver=docker-container \ ) From a894cd98dd88eff785c543bb0afd17e6d24719c1 Mon Sep 17 00:00:00 2001 From: Francis Charette Migneault Date: Sat, 8 Mar 2025 00:05:04 -0500 Subject: [PATCH 3/3] invert behavior of docker prov for quicker CI docker smoke-test without push side-effect --- .github/workflows/tests.yml | 3 +++ Makefile | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c76113032..7eb4d0be0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -158,6 +158,9 @@ jobs: needs: tests if: ${{ success() && (contains(github.ref, 'refs/tags') || github.ref == 'refs/heads/master') }} runs-on: ubuntu-latest + env: + # enabled provenance attestation during build/push (see Makefile for details) + DOCKER_PROV: "true" steps: - uses: actions/checkout@v2 with: diff --git a/Makefile b/Makefile index 1edd59f0d..3d4c244a6 100644 --- a/Makefile +++ b/Makefile @@ -844,7 +844,10 @@ DOCKER_REPO ?= pavics/weaver # employ the remote registry reference to provide the relevant traceability. # whether to enable Provenance and SBOM tracking of built images -DOCKER_PROV ?= true +# Disable by default to ensure that any operation that needs a local docker (eg: 'docker-test' target) +# doesn't lead to an unintended push to the remote registry. This should be enabled explicitly only +# for tagged releases for which we explicitly want traceability. +DOCKER_PROV ?= false ifeq ($(DOCKER_PROV),true) DOCKER_BUILDER_STEP := docker-builder DOCKER_BUILDER_NAME ?= docker-prov