99
1010.PHONY : build publish
1111
12+ TAG := $(shell git rev-parse --short HEAD)
1213OPERATOR_NAME := secret-operator
1314VERSION := $(shell cargo metadata --format-version 1 | jq -r '.packages[] | select(.name=="stackable-${OPERATOR_NAME}") | .version')
15+ ARCH := $(shell uname -m | sed -e 's#x86_64#amd64#' | sed -e 's#aarch64#arm64#')
1416
1517OCI_REGISTRY_HOSTNAME := oci.stackable.tech
1618OCI_REGISTRY_PROJECT_IMAGES := sdp
19+ OCI_REGISTRY_PROJECT_CHARTS := sdp-charts
20+ # This will be overwritten by an environmental variable if called from the github action
21+ HELM_CHART_NAME := ${OPERATOR_NAME}
22+ HELM_CHART_ARTIFACT := target/helm/${OPERATOR_NAME}-${VERSION}.tgz
1723
1824SHELL =/usr/bin/env bash -euo pipefail
1925
@@ -27,12 +33,78 @@ render-docs:
2733docker-build :
2834 docker build --force-rm --build-arg VERSION=${VERSION} -t " ${OCI_REGISTRY_HOSTNAME} /${OCI_REGISTRY_PROJECT_IMAGES} /${OPERATOR_NAME} :${VERSION} -${ARCH} " -f docker/Dockerfile .
2935
36+ docker-publish :
37+ # Push to Harbor
38+ # We need to use "value" here to prevent the variable from being recursively expanded by make (username contains a dollar sign, since it's a Harbor bot)
39+ docker login --username ' ${value OCI_REGISTRY_SDP_USERNAME}' --password ' ${OCI_REGISTRY_SDP_PASSWORD}' ' ${OCI_REGISTRY_HOSTNAME}'
40+ DOCKER_OUTPUT=$$(docker push --all-tags '${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}' ) ; \
41+ # Obtain the digest of the pushed image from the output of `docker push`, because signing by tag is deprecated and will be removed from cosign in the future\
42+ REPO_DIGEST_OF_IMAGE=$$(echo "$$DOCKER_OUTPUT" | awk '/^${VERSION}-${ARCH}: digest: sha256:[0-9a-f]{64} size: [0-9]+$$/ { print $$3 }' ) ; \
43+ if [ -z " $$ REPO_DIGEST_OF_IMAGE" ]; then\
44+ echo ' Could not find repo digest for container image: ${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-${ARCH}' ; \
45+ exit 1; \
46+ fi ; \
47+ # This generates a signature and publishes it to the registry, next to the image\
48+ # Uses the keyless signing flow with Github Actions as identity provider\
49+ cosign sign -y " ${OCI_REGISTRY_HOSTNAME} /${OCI_REGISTRY_PROJECT_IMAGES} /${OPERATOR_NAME} @$$ REPO_DIGEST_OF_IMAGE" ; \
50+ # Generate the SBOM for the operator image, this leverages the already generated SBOM for the operator binary by cargo-cyclonedx\
51+ syft scan --output cyclonedx-json@1.5=sbom.json --select-catalogers " -cargo-auditable-binary-cataloger,+sbom-cataloger" --scope all-layers --source-name " ${OPERATOR_NAME} " --source-version " ${VERSION} -${ARCH} " " ${OCI_REGISTRY_HOSTNAME} /${OCI_REGISTRY_PROJECT_IMAGES} /${OPERATOR_NAME} @$$ REPO_DIGEST_OF_IMAGE" ; \
52+ # Determine the PURL for the container image\
53+ URLENCODED_REPO_DIGEST_OF_IMAGE=$$(echo "$$REPO_DIGEST_OF_IMAGE" | sed 's/:/%3A/g' ) ; \
54+ PURL=" pkg:oci/${OPERATOR_NAME} @$$ URLENCODED_REPO_DIGEST_OF_IMAGE?arch=${ARCH} &repository_url=${OCI_REGISTRY_HOSTNAME} %2F${OCI_REGISTRY_PROJECT_IMAGES} %2F${OPERATOR_NAME} " ; \
55+ # Get metadata from the image\
56+ IMAGE_DESCRIPTION=$$(docker inspect --format='{{.Config.Labels.description}}' "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-${ARCH}" ) ; \
57+ IMAGE_NAME=$$(docker inspect --format='{{.Config.Labels.name}}' "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-${ARCH}" ) ; \
58+ # Merge the SBOM with the metadata for the operator\
59+ jq -s ' {"metadata":{"component":{"description":"' " $$ IMAGE_NAME. $$ IMAGE_DESCRIPTION" ' ","supplier":{"name":"Stackable GmbH","url":["https://stackable.tech/"]},"author":"Stackable GmbH","purl":"' " $$ PURL" ' ","publisher":"Stackable GmbH"}}} * .[0]' sbom.json > sbom.merged.json; \
60+ # Attest the SBOM to the image\
61+ cosign attest -y --predicate sbom.merged.json --type cyclonedx " ${OCI_REGISTRY_HOSTNAME} /${OCI_REGISTRY_PROJECT_IMAGES} /${OPERATOR_NAME} @$$ REPO_DIGEST_OF_IMAGE"
62+
63+ # This assumes "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-amd64 and "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}-arm64 are built and pushed
64+ docker-manifest-list-build :
65+ docker manifest create " ${OCI_REGISTRY_HOSTNAME} /${OCI_REGISTRY_PROJECT_IMAGES} /${OPERATOR_NAME} :${VERSION} " --amend " ${OCI_REGISTRY_HOSTNAME} /${OCI_REGISTRY_PROJECT_IMAGES} /${OPERATOR_NAME} :${VERSION} -amd64" --amend " ${OCI_REGISTRY_HOSTNAME} /${OCI_REGISTRY_PROJECT_IMAGES} /${OPERATOR_NAME} :${VERSION} -arm64"
66+
67+ docker-manifest-list-publish :
68+ # Push to Harbor
69+ # We need to use "value" here to prevent the variable from being recursively expanded by make (username contains a dollar sign, since it's a Harbor bot)
70+ docker login --username ' ${value OCI_REGISTRY_SDP_USERNAME}' --password ' ${OCI_REGISTRY_SDP_PASSWORD}' ' ${OCI_REGISTRY_HOSTNAME}'
71+ DIGEST_HARBOR=$$(docker manifest push "${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_IMAGES}/${OPERATOR_NAME}:${VERSION}" ) ; \
72+ # Refer to image via its digest (oci.stackable.tech/sdp/airflow@sha256:0a1b2c...);\
73+ # This generates a signature and publishes it to the registry, next to the image\
74+ # Uses the keyless signing flow with Github Actions as identity provider\
75+ cosign sign -y " ${OCI_REGISTRY_HOSTNAME} /${OCI_REGISTRY_PROJECT_IMAGES} /${OPERATOR_NAME} :${VERSION} @$$ DIGEST_HARBOR"
76+
77+ # TODO remove if not used/needed
78+ docker : docker-build docker-publish
79+
80+ print-docker-tag :
81+ @echo " ${OCI_REGISTRY_HOSTNAME} /${OCI_REGISTRY_PROJECT_IMAGES} /${OPERATOR_NAME} :${VERSION} "
82+
83+ helm-publish :
84+ # Push to Harbor
85+ # We need to use "value" here to prevent the variable from being recursively expanded by make (username contains a dollar sign, since it's a Harbor bot)
86+ helm registry login --username ' ${value OCI_REGISTRY_SDP_CHARTS_USERNAME}' --password ' ${OCI_REGISTRY_SDP_CHARTS_PASSWORD}' ' ${OCI_REGISTRY_HOSTNAME}'
87+ # Obtain the digest of the pushed artifact from the output of `helm push`, because signing by tag is deprecated and will be removed from cosign in the future\
88+ HELM_OUTPUT=$$(helm push '${HELM_CHART_ARTIFACT}' 'oci://${OCI_REGISTRY_HOSTNAME}/${OCI_REGISTRY_PROJECT_CHARTS}' 2>&1 ) ; \
89+ REPO_DIGEST_OF_ARTIFACT=$$(echo "$$HELM_OUTPUT" | awk '/^Digest: sha256:[0-9a-f]{64}$$/ { print $$2 }' ) ; \
90+ if [ -z " $$ REPO_DIGEST_OF_ARTIFACT" ]; then\
91+ echo ' Could not find repo digest for helm chart: ${HELM_CHART_NAME}' ; \
92+ exit 1; \
93+ fi ; \
94+ # Login to Harbor, needed for cosign to be able to push the signature for the Helm chart\
95+ docker login --username ' ${value OCI_REGISTRY_SDP_CHARTS_USERNAME}' --password ' ${OCI_REGISTRY_SDP_CHARTS_PASSWORD}' ' ${OCI_REGISTRY_HOSTNAME}' ; \
96+ # This generates a signature and publishes it to the registry, next to the chart artifact\
97+ # Uses the keyless signing flow with Github Actions as identity provider\
98+ cosign sign -y " ${OCI_REGISTRY_HOSTNAME} /${OCI_REGISTRY_PROJECT_CHARTS} /${HELM_CHART_NAME} @$$ REPO_DIGEST_OF_ARTIFACT"
99+
100+ helm-package :
101+ mkdir -p target/helm && helm package --destination target/helm deploy/helm/${OPERATOR_NAME}
102+
30103# # Chart related targets
31104compile-chart : version crds config
32105
33106chart-clean :
34107 rm -rf " deploy/helm/${OPERATOR_NAME} /configs"
35- rm -rf " deploy/helm/${OPERATOR_NAME} /crds"
36108
37109version :
38110 cat " deploy/helm/${OPERATOR_NAME} /Chart.yaml" | yq " .version = \" ${VERSION} \" | .appVersion = \" ${VERSION} \" " > " deploy/helm/${OPERATOR_NAME} /Chart.yaml.new"
@@ -44,9 +116,11 @@ config:
44116 cp -r deploy/config-spec/* " deploy/helm/${OPERATOR_NAME} /configs" ; \
45117 fi
46118
119+ # We generate a crds.yaml, so that the effect of code changes are visible.
120+ # The operator will take care of the CRD rollout itself.
47121crds :
48- mkdir -p deploy/helm/ " ${OPERATOR_NAME} " /crds
49- cargo run --bin stackable-" ${OPERATOR_NAME} " -- crd | yq eval ' .metadata.annotations["helm.sh/resource-policy"]="keep" ' - > " deploy/helm/ ${OPERATOR_NAME} / crds/crds .yaml"
122+ mkdir -p extra
123+ cargo run --bin stackable-" ${OPERATOR_NAME} " -- crd > extra/ crds.yaml
50124
51125chart-lint : compile-chart
52126 docker run -it -v $(shell pwd) :/build/helm-charts -w /build/helm-charts quay.io/helmpack/chart-testing:v3.5.0 ct lint --config deploy/helm/ct.yaml
@@ -60,7 +134,14 @@ regenerate-charts: chart-clean compile-chart
60134regenerate-nix :
61135 nix run --extra-experimental-features " nix-command flakes" -f . regenerateNixLockfiles
62136
63- build : regenerate-charts regenerate-nix docker-build
137+ build : regenerate-charts regenerate-nix helm-package docker-build
138+
139+ # This target is used by the CI
140+ # It doesn't make use of any nix dependencies and thus aviods building the
141+ # operator unnecessarily often.
142+ build-ci : regenerate-charts helm-package docker-build
143+
144+ publish : docker-publish helm-publish
64145
65146check-nix :
66147 @which nix || (echo " Error: 'nix' is not installed. Please install it to proceed." ; exit 1)
0 commit comments