Skip to content

Commit 99e8933

Browse files
committed
feat: generate SBOMs at build time for OPA, statsd_exporter and kafka
1 parent 1ddfdbf commit 99e8933

File tree

5 files changed

+137
-23
lines changed

5 files changed

+137
-23
lines changed

kafka/Dockerfile

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,49 @@
1-
# syntax=docker/dockerfile:1.10.0@sha256:865e5dd094beca432e8c0a1d5e1c465db5f998dca4e439981029b3b81fb39ed5
2-
# check=error=true
1+
# syntax=docker/dockerfile:1.8.1@sha256:e87caa74dcb7d46cd820352bfea12591f3dba3ddc4285e19c7dcd13359f7cefd
32

43
FROM stackable/image/kcat AS kcat
54

6-
FROM stackable/image/java-devel AS kafka-builder
5+
FROM stackable/image/java-devel as kafka-builder
76

87
ARG PRODUCT
98
ARG SCALA
109
ARG OPA_AUTHORIZER
1110
ARG JMX_EXPORTER
1211

12+
RUN <<EOF
13+
microdnf update
14+
15+
# patch: Required for the apply-patches.sh script
16+
microdnf install \
17+
patch
18+
19+
microdnf clean all
20+
rm -rf /var/cache/yum
21+
EOF
22+
1323
USER stackable
1424
WORKDIR /stackable
1525

16-
RUN curl "https://repo.stackable.tech/repository/packages/kafka/kafka-${PRODUCT}-src.tgz" | tar -xzC . && \
17-
cd kafka-${PRODUCT}-src && \
26+
COPY --chown=stackable:stackable kafka/stackable/patches/apply_patches.sh /stackable/kafka-${PRODUCT}-src/patches/apply_patches.sh
27+
COPY --chown=stackable:stackable kafka/stackable/patches/${PRODUCT} /stackable/kafka-${PRODUCT}-src/patches/${PRODUCT}
28+
29+
RUN curl --fail -L "https://repo.stackable.tech/repository/packages/kafka/kafka-${PRODUCT}-src.tgz" | tar -xzC .
30+
RUN cd kafka-${PRODUCT}-src && \
31+
./patches/apply_patches.sh ${PRODUCT} && \
1832
# TODO: Try to install gradle via package manager (if possible) instead of fetching it from the internet
1933
# We don't specify "-x test" to skip the tests, as we might bump some Kafka internal dependencies in the future and
2034
# it's a good idea to run the tests in this case.
2135
./gradlew clean releaseTarGz && \
36+
./gradlew cyclonedxBom && \
2237
tar -xf core/build/distributions/kafka_${SCALA}-${PRODUCT}.tgz -C /stackable && \
38+
cp build/reports/bom.json /stackable/kafka_${SCALA}-${PRODUCT}.cdx.json && \
2339
rm -rf /stackable/kafka_${SCALA}-${PRODUCT}/site-docs/ && \
2440
rm -rf /stackable/kafka-${PRODUCT}-src
2541

26-
# TODO (@NickLarsenNZ): Compile from source: https://github.com/StyraInc/opa-kafka-plugin
27-
RUN curl https://repo.stackable.tech/repository/packages/kafka-opa-authorizer/opa-authorizer-${OPA_AUTHORIZER}-all.jar \
42+
RUN curl --fail -L https://repo.stackable.tech/repository/packages/kafka-opa-authorizer/opa-authorizer-${OPA_AUTHORIZER}-all.jar \
2843
-o /stackable/kafka_${SCALA}-${PRODUCT}/libs/opa-authorizer-${OPA_AUTHORIZER}-all.jar
2944

3045
COPY --chown=stackable:stackable kafka/stackable/jmx/ /stackable/jmx/
31-
RUN curl https://repo.stackable.tech/repository/packages/jmx-exporter/jmx_prometheus_javaagent-${JMX_EXPORTER}.jar \
46+
RUN curl --fail -L https://repo.stackable.tech/repository/packages/jmx-exporter/jmx_prometheus_javaagent-${JMX_EXPORTER}.jar \
3247
-o /stackable/jmx/jmx_prometheus_javaagent-${JMX_EXPORTER}.jar && \
3348
chmod +x /stackable/jmx/jmx_prometheus_javaagent-${JMX_EXPORTER}.jar && \
3449
ln -s /stackable/jmx/jmx_prometheus_javaagent-${JMX_EXPORTER}.jar /stackable/jmx/jmx_prometheus_javaagent.jar
@@ -69,8 +84,6 @@ LABEL name="Apache Kafka" \
6984
COPY kafka/kubernetes.repo /etc/yum.repos.d/kubernetes.repo
7085
RUN microdnf update && \
7186
microdnf install \
72-
# needed by kcat for kerberos
73-
cyrus-sasl-gssapi \
7487
# Can be removed once listener-operator integration is used
7588
kubectl && \
7689
microdnf clean all && \
@@ -85,6 +98,7 @@ COPY --chown=stackable:stackable kafka/licenses /licenses
8598
# We copy opa-authorizer.jar and jmx-exporter through the builder image to have an absolutely minimal final image
8699
# (e.g. we don't even need curl in it).
87100
COPY --chown=stackable:stackable --from=kafka-builder /stackable/kafka_${SCALA}-${PRODUCT} /stackable/kafka_${SCALA}-${PRODUCT}
101+
COPY --chown=stackable:stackable --from=kafka-builder /stackable/kafka_${SCALA}-${PRODUCT}.cdx.json /stackable/kafka_${SCALA}-${PRODUCT}.cdx.json
88102
COPY --chown=stackable:stackable --from=kafka-builder /stackable/jmx/ /stackable/jmx/
89103
COPY --chown=stackable:stackable --from=kcat /stackable/kcat-${KCAT}/kcat /stackable/bin/kcat-${KCAT}
90104
COPY --chown=stackable:stackable --from=kcat /licenses /licenses
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
diff --git a/build.gradle b/build.gradle
2+
index 32e6e8f..7bfe6c2 100644
3+
--- a/build.gradle
4+
+++ b/build.gradle
5+
@@ -48,6 +48,22 @@ plugins {
6+
// artifacts - see https://github.com/johnrengelman/shadow/issues/901
7+
id 'com.github.johnrengelman.shadow' version '8.1.0' apply false
8+
id 'com.diffplug.spotless' version '6.14.0' apply false // 6.14.1 and newer require Java 11 at compile time, so we can't upgrade until AK 4.0
9+
+ id 'org.cyclonedx.bom' version '1.9.0'
10+
+}
11+
+
12+
+cyclonedxBom {
13+
+ // Specified the type of project being built. Defaults to 'library'
14+
+ projectType = "application"
15+
+ // Specified the version of the CycloneDX specification to use. Defaults to '1.5'
16+
+ schemaVersion = "1.5"
17+
+ // Boms destination directory. Defaults to 'build/reports'
18+
+ destination = file("build/reports")
19+
+ // The file name for the generated BOMs (before the file format suffix). Defaults to 'bom'
20+
+ outputName = "bom"
21+
+ // The file format generated, can be xml, json or all for generating both. Defaults to 'all'
22+
+ outputFormat = "json"
23+
+ // Fixes: https://github.com/gradle/gradle/issues/6854
24+
+ skipConfigs = ["incrementalScalaAnalysisFortest", "incrementalScalaAnalysisFormain", "compileClasspath", "testCompileClasspath"]
25+
}
26+
27+
ext {
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env bash
2+
3+
# Enable error handling and unset variable checking
4+
set -eu
5+
set -o pipefail
6+
7+
# Check if $1 (VERSION) is provided
8+
if [ -z "${1-}" ]; then
9+
echo "Please provide a value for VERSION as the first argument."
10+
exit 1
11+
fi
12+
13+
VERSION="$1"
14+
PATCH_DIR="patches/$VERSION"
15+
16+
# Check if version-specific patches directory exists
17+
if [ ! -d "$PATCH_DIR" ]; then
18+
echo "Patches directory '$PATCH_DIR' does not exist."
19+
exit 1
20+
fi
21+
22+
# Create an array to hold the patches in sorted order
23+
declare -a patch_files=()
24+
25+
echo "Applying patches from ${PATCH_DIR}" now
26+
27+
# Read the patch files into the array
28+
while IFS= read -r -d $'\0' file; do
29+
patch_files+=("$file")
30+
done < <(find "$PATCH_DIR" -name "*.patch" -print0 | sort -zV)
31+
32+
echo "Found ${#patch_files[@]} patches, applying now"
33+
34+
# Iterate through sorted patch files
35+
for patch_file in "${patch_files[@]}"; do
36+
echo "Applying $patch_file"
37+
# We can not use Git here, as we are not within a Git repo
38+
patch --directory "." --strip=1 < "$patch_file" || {
39+
echo "Failed to apply $patch_file"
40+
exit 1
41+
}
42+
done
43+
44+
echo "All patches applied successfully."

opa/Dockerfile

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,22 +65,36 @@ ARG TARGETOS
6565
ENV GOARCH=$TARGETARCH
6666
ENV GOOS=$TARGETOS
6767

68-
# go - used to build OPA
6968
# gzip, tar - used to unpack the OPA source
69+
# git - needed by the cyclonedx-gomod tool to determine the version of OPA
70+
# golang - used to build OPA
7071
RUN microdnf update && \
71-
microdnf install \
72-
go \
73-
gzip \
74-
tar && \
75-
microdnf clean all
76-
77-
RUN curl "https://repo.stackable.tech/repository/packages/opa/opa_${PRODUCT}.tar.gz" -o opa.tar.gz && \
72+
microdnf install \
73+
gzip \
74+
git \
75+
golang \
76+
tar && \
77+
microdnf clean all
78+
79+
# We use version 1.7.0, since a newer version of cyclonedx-gomod is not compatible with the version of Golang (>= 1.23.1)
80+
RUN go install github.com/CycloneDX/cyclonedx-gomod/cmd/[email protected]
81+
RUN curl --fail -L "https://repo.stackable.tech/repository/packages/opa/opa_${PRODUCT}.tar.gz" -o opa.tar.gz && \
7882
tar -zxvf opa.tar.gz && \
79-
mv opa-${PRODUCT} opa
83+
mv "opa-${PRODUCT}" opa
8084

8185
WORKDIR /opa
8286

83-
RUN go build -o opa -buildmode=exe
87+
RUN <<EOF
88+
# Unfortunately, we need to create a dummy Git repository to allow cyclonedx-gomod to determine the version of OPA
89+
git init
90+
git add go.mod
91+
git config --global user.email "[email protected]"
92+
git config --global user.name "dummy"
93+
git commit -m "dummy"
94+
git tag "${PRODUCT}"
95+
go build -o opa -buildmode=exe
96+
~/go/bin/cyclonedx-gomod app -json -output-version 1.5 -output "opa_${PRODUCT}.cdx.json" -packages -files
97+
EOF
8498

8599
FROM stackable/image/vector
86100

@@ -107,7 +121,8 @@ COPY opa/licenses /licenses
107121
USER stackable
108122
WORKDIR /stackable/opa
109123

110-
COPY --from=opa-builder /opa/opa /stackable/opa/opa
124+
COPY --from=opa-builder /opa/opa_${PRODUCT}.cdx.json /stackable/opa/
125+
COPY --from=opa-builder /opa/opa /stackable/opa/
111126
COPY --from=opa-bundle-builder --chown=stackable:stackable /opa-bundle-builder/target/release/stackable-opa-bundle-builder /stackable/opa-bundle-builder
112127
COPY --from=multilog-builder --chown=stackable:stackable /daemontools/admin/daemontools/command/multilog /stackable/multilog
113128

statsd_exporter/Dockerfile

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,33 @@ microdnf update
1111

1212
# Tar and gzip are used to unpack the statsd_exporter source
1313
# Golang is used to build statsd_exporter
14+
# Git is needed by the cyclonedx-gomod tool to determine the version of statsd_exporter
1415
microdnf install \
1516
tar \
1617
gzip \
18+
git \
1719
golang
1820

1921
microdnf clean all
2022
rm -rf /var/cache/yum
2123

2224
export GOPATH=/go_cache
23-
curl "https://repo.stackable.tech/repository/packages/statsd_exporter/statsd_exporter-${PRODUCT}.src.tar.gz" | tar -xzC .
25+
go install github.com/CycloneDX/cyclonedx-gomod/cmd/[email protected]
26+
EOF
27+
28+
RUN --mount=type=cache,id=go-statsd-exporter,uid=1000,target=/go_cache <<EOF
29+
curl --fail -L "https://repo.stackable.tech/repository/packages/statsd_exporter/statsd_exporter-${PRODUCT}.src.tar.gz" | tar -xzC .
2430
(
2531
cd "statsd_exporter-${PRODUCT}" || exit
32+
33+
# Unfortunately, we need to create a dummy Git repository to allow cyclonedx-gomod to determine the version of statsd_exporter
34+
git init
35+
git add go.mod
36+
git config --global user.email "[email protected]"
37+
git config --global user.name "dummy"
38+
git commit -m "dummy"
39+
git tag "${PRODUCT}"
2640
go build -o ../statsd_exporter
41+
/go_cache/bin/cyclonedx-gomod app -json -output-version 1.5 -output ../statsd_exporter-${PRODUCT}.cdx.json -packages -files
2742
)
28-
rm -rf "statsd_exporter-${PRODUCT}"
2943
EOF

0 commit comments

Comments
 (0)