From 2063de390cb50d0aeffb7262e781b50ebbbb742f Mon Sep 17 00:00:00 2001 From: Yair Podemsky Date: Wed, 17 Jun 2026 10:08:29 +0300 Subject: [PATCH] Unified Container Build with Cargo Cache Mounts Until now our builds have compiled the same files 4 times, As the builds were done in separate containers and had no access to the compilation objects from the other containers or previous builds. By Unifying the Build stage into one Container and interceding build caches we will prevent unnecessary work and achieve faster builds. Also adding: - Git commit pinning for the reference-values repo with dependabot autoupdates. - Adding entrypoints to the operator and compute-pcrs containers - Builder LABEL for cleanups - more robust build_type selection - cleaner copying of build products Signed-off-by: Yair Podemsky Assisted-by: AI --- .containerignore | 14 ++++ Cargo.lock | 1 + Cargo.toml | 1 + Containerfile | 94 ++++++++++++++++++++++---- Makefile | 15 ++-- attestation-key-register/Containerfile | 31 --------- compute-pcrs/Cargo.toml | 2 + compute-pcrs/Containerfile | 32 --------- register-server/Containerfile | 32 --------- 9 files changed, 110 insertions(+), 112 deletions(-) create mode 100644 .containerignore delete mode 100644 attestation-key-register/Containerfile delete mode 100644 compute-pcrs/Containerfile delete mode 100644 register-server/Containerfile diff --git a/.containerignore b/.containerignore new file mode 100644 index 00000000..044d9bb4 --- /dev/null +++ b/.containerignore @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: Yair Podemsky +# +# SPDX-License-Identifier: CC0-1.0 + + +target/ +.git/ +bin/ +tests/ +test_utils/ +must-gather/ +bundle/ +.github/ +*.tar diff --git a/Cargo.lock b/Cargo.lock index 31d91b60..6c4bf390 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -575,6 +575,7 @@ dependencies = [ "compute-pcrs-lib", "k8s-openapi 0.28.0", "kube 4.2.0", + "reference-values", "serde_json", "tokio", "trusted-cluster-operator-lib", diff --git a/Cargo.toml b/Cargo.toml index 2c8e2591..9fd97931 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,4 +30,5 @@ serde = { version = "1.0.228", features = ["derive"] } serde_json = "1.0.150" tokio = { version = "1.52.3", features = ["macros", "rt-multi-thread"] } uuid = { version = "1.23", features = ["v4", "serde"] } +reference-values = { git = "https://github.com/trusted-execution-clusters/reference-values" } warp = { version = "0.3", default-features = false } diff --git a/Containerfile b/Containerfile index d4c42b1d..d434168d 100644 --- a/Containerfile +++ b/Containerfile @@ -1,34 +1,102 @@ # SPDX-FileCopyrightText: Alice Frosi # SPDX-FileCopyrightText: Jakob Naucke +# SPDX-FileCopyrightText: Yair Podemsky # # SPDX-License-Identifier: CC0-1.0 -ARG build_type -# Dependency build stage +ARG build_type=release + +# Unified builder stage — compiles all binaries in a single cargo invocation. FROM ghcr.io/trusted-execution-clusters/buildroot:fedora AS builder +LABEL project=trusted-cluster-operator ARG build_type WORKDIR /build COPY Makefile Cargo.toml Cargo.lock go.mod go.sum . + COPY api api COPY lib lib + +# Copy Cargo.toml and lib.rs stubs for dependency pre-build caching. COPY operator/Cargo.toml operator/ COPY operator/src/lib.rs operator/src/ +COPY compute-pcrs/Cargo.toml compute-pcrs/ +COPY compute-pcrs/src/lib.rs compute-pcrs/src/ +COPY register-server/Cargo.toml register-server/ +COPY register-server/src/lib.rs register-server/src/ +COPY attestation-key-register/Cargo.toml attestation-key-register/ +COPY attestation-key-register/src/lib.rs attestation-key-register/src/ -# Set only required crates as members to minimize rebuilds upon changes. -RUN sed -i 's/members = .*/members = ["lib", "operator"]/' Cargo.toml && \ +RUN sed -i 's/members = .*/members = ["lib", "operator", "compute-pcrs", "register-server", "attestation-key-register"]/' Cargo.toml && \ sed -i '/\[dev-dependencies\]/,$d' operator/Cargo.toml && \ - sed -i '/trusted-cluster-operator-test-utils/d' lib/Cargo.toml && \ + sed -i '/\[dev-dependencies\]/,$d' register-server/Cargo.toml && \ + sed -i '/trusted-cluster-operator-test-utils/d' lib/Cargo.toml + +RUN --mount=type=cache,target=/build/target \ + --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/root/.cache/go-build \ + --mount=type=cache,target=/root/go/pkg/mod \ make crds-rs -# In debug builds, build dependencies to avoid full rebuild. -RUN if [ "$build_type" = debug ]; then cargo build -p operator; fi +# In debug builds, pre-build dependencies to avoid full rebuild on source changes. +RUN --mount=type=cache,target=/build/target \ + --mount=type=cache,target=/usr/local/cargo/registry \ + if [ "$build_type" = debug ]; then \ + cargo build -p operator -p compute-pcrs -p register-server -p attestation-key-register; \ + fi -# Target build stage COPY operator/src operator/src -RUN cargo build -p operator $(if [ "$build_type" = release ]; then echo --release; fi) +COPY compute-pcrs/src compute-pcrs/src +COPY register-server/src register-server/src +COPY attestation-key-register/src attestation-key-register/src -# Distribution stage -FROM quay.io/fedora/fedora:43 -ARG build_type -COPY --from=builder "/build/target/$build_type/operator" /usr/bin +RUN --mount=type=cache,target=/build/target \ + --mount=type=cache,target=/usr/local/cargo/registry \ + release_flag="" && \ + if [ "$build_type" = release ]; then release_flag="--release"; fi && \ + cargo build \ + -p operator \ + -p compute-pcrs \ + -p register-server \ + -p attestation-key-register \ + $release_flag + +RUN --mount=type=cache,target=/build/target \ + profile_dir="debug" && \ + if [ "$build_type" = release ]; then profile_dir="release"; fi && \ + mkdir -p /output && \ + cp /build/target/${profile_dir}/operator /output/ && \ + cp /build/target/${profile_dir}/compute-pcrs /output/ && \ + cp /build/target/${profile_dir}/register-server /output/ && \ + cp /build/target/${profile_dir}/attestation-key-register /output/ + +# Distribution stages +FROM quay.io/fedora/fedora:43 AS operator +COPY --from=builder /output/operator /usr/bin +ENTRYPOINT ["/usr/bin/operator"] + +FROM quay.io/fedora/fedora:43 AS attestation-key-register +COPY --from=builder /output/attestation-key-register /usr/bin +EXPOSE 8001 +ENTRYPOINT ["/usr/bin/attestation-key-register"] + +FROM quay.io/fedora/fedora:43 AS register-server +COPY --from=builder /output/register-server /usr/bin +EXPOSE 3030 +ENTRYPOINT ["/usr/bin/register-server"] + + +FROM builder AS compute-pcrs-data +RUN rv_line=$(cargo metadata --format-version=1 | jq -r '.packages[] | select(.name == "reference-values") | .source') && \ + rv_repo=$(echo "$rv_line" | sed 's/^git+//;s/[?#].*//') && \ + rv_commit=$(echo "$rv_line" | sed 's/.*#//') && \ + git clone "$rv_repo" reference-values && \ + git -C reference-values checkout "$rv_commit" +RUN mkdir -p /output/reference-values && \ + mv /build/reference-values/efivars /output/reference-values/ && \ + mv /build/reference-values/mok-variables /output/reference-values/ + +FROM quay.io/fedora/fedora:43 AS compute-pcrs +COPY --from=compute-pcrs-data /output/compute-pcrs /usr/bin +COPY --from=compute-pcrs-data /output/reference-values /reference-values +ENTRYPOINT ["/usr/bin/compute-pcrs"] diff --git a/Makefile b/Makefile index 0a65d4dc..48c464f6 100644 --- a/Makefile +++ b/Makefile @@ -126,13 +126,13 @@ CONTAINER_CLI ?= podman RUNTIME ?= podman operator-image: - $(CONTAINER_CLI) build $(IMAGE_BUILD_OPTIONS) -t $(OPERATOR_IMAGE) -f Containerfile . + $(CONTAINER_CLI) build $(IMAGE_BUILD_OPTIONS) --target operator -t $(OPERATOR_IMAGE) -f Containerfile . compute-pcrs-image: - $(CONTAINER_CLI) build $(IMAGE_BUILD_OPTIONS) -t $(COMPUTE_PCRS_IMAGE) -f compute-pcrs/Containerfile . + $(CONTAINER_CLI) build $(IMAGE_BUILD_OPTIONS) --target compute-pcrs -t $(COMPUTE_PCRS_IMAGE) -f Containerfile . reg-server-image: - $(CONTAINER_CLI) build $(IMAGE_BUILD_OPTIONS) -t $(REG_SERVER_IMAGE) -f register-server/Containerfile . + $(CONTAINER_CLI) build $(IMAGE_BUILD_OPTIONS) --target register-server -t $(REG_SERVER_IMAGE) -f Containerfile . attestation-key-register-image: - $(CONTAINER_CLI) build $(IMAGE_BUILD_OPTIONS) -t $(ATTESTATION_KEY_REGISTER_IMAGE) -f attestation-key-register/Containerfile . + $(CONTAINER_CLI) build $(IMAGE_BUILD_OPTIONS) --target attestation-key-register -t $(ATTESTATION_KEY_REGISTER_IMAGE) -f Containerfile . image: operator-image compute-pcrs-image reg-server-image attestation-key-register-image @@ -220,6 +220,13 @@ clean: cargo clean rm -rf bin manifests $(CRD_YAML_PATH) $(CRD_RS_PATH) rm -f trusted-cluster-gen config/rbac/role.yaml .crates.toml .crates2.json + $(CONTAINER_CLI) image prune --all --force --filter label=project=trusted-cluster-operator + # Prune --mount=type=cache data: podman uses --build-cache, docker uses builder prune (no label filter supported by either) + @if $(CONTAINER_CLI) image prune --help 2>&1 | grep -q -- '--build-cache'; then \ + $(CONTAINER_CLI) image prune --force --build-cache; \ + else \ + $(CONTAINER_CLI) builder prune --force --filter type=exec.cachemount; \ + fi fmt-check: cargo fmt -- --check diff --git a/attestation-key-register/Containerfile b/attestation-key-register/Containerfile deleted file mode 100644 index d58ddbf4..00000000 --- a/attestation-key-register/Containerfile +++ /dev/null @@ -1,31 +0,0 @@ -# SPDX-FileCopyrightText: Alice Frosi -# -# SPDX-License-Identifier: CC0-1.0 - -ARG build_type -FROM ghcr.io/trusted-execution-clusters/buildroot:fedora AS builder -ARG build_type -WORKDIR /build - -COPY Makefile Cargo.toml Cargo.lock go.mod go.sum . -COPY api api -COPY lib lib -COPY attestation-key-register/Cargo.toml attestation-key-register/ -COPY attestation-key-register/src/lib.rs attestation-key-register/src/ - -# Set only required crates as members to minimize rebuilds upon changes. -RUN sed -i 's/members =.*/members = ["lib", "attestation-key-register"]/' Cargo.toml && \ - sed -i '/trusted-cluster-operator-test-utils/d' lib/Cargo.toml && \ - make crds-rs - -# In debug builds, build dependencies to avoid full rebuild. -RUN if [ "$build_type" = debug ]; then cargo build -p attestation-key-register; fi - -COPY attestation-key-register/src attestation-key-register/src -RUN cargo build -p attestation-key-register $(if [ "$build_type" = release ]; then echo --release; fi) - -FROM quay.io/fedora/fedora:43 -ARG build_type -COPY --from=builder "/build/target/$build_type/attestation-key-register" /usr/bin -EXPOSE 8001 -ENTRYPOINT ["/usr/bin/attestation-key-register"] diff --git a/compute-pcrs/Cargo.toml b/compute-pcrs/Cargo.toml index 49d4cb26..d3e4580b 100644 --- a/compute-pcrs/Cargo.toml +++ b/compute-pcrs/Cargo.toml @@ -19,3 +19,5 @@ k8s-openapi.workspace = true kube.workspace = true serde_json.workspace = true tokio.workspace = true +# Pins the reference-values repo+commit in Cargo.lock for the container build (see Containerfile). +reference-values.workspace = true diff --git a/compute-pcrs/Containerfile b/compute-pcrs/Containerfile deleted file mode 100644 index 78b12cbd..00000000 --- a/compute-pcrs/Containerfile +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-FileCopyrightText: Alice Frosi -# SPDX-FileCopyrightText: Jakob Naucke -# -# SPDX-License-Identifier: CC0-1.0 - -ARG build_type -FROM ghcr.io/trusted-execution-clusters/buildroot:fedora AS builder -ARG build_type -WORKDIR /build - -COPY Makefile Cargo.toml Cargo.lock go.mod go.sum . -COPY api api -COPY lib lib -COPY compute-pcrs/Cargo.toml compute-pcrs/ -COPY compute-pcrs/src/lib.rs compute-pcrs/src/ - -# Set only required crates as members to minimize rebuilds upon changes. -RUN sed -i 's/members =.*/members = ["compute-pcrs", "lib"]/' Cargo.toml && \ - sed -i '/trusted-cluster-operator-test-utils/d' lib/Cargo.toml && \ - git clone --depth 1 https://github.com/trusted-execution-clusters/reference-values && \ - make crds-rs - -# Build dependencies in lower layer to make use of caching. -RUN if [ "$build_type" = debug ]; then cargo build -p compute-pcrs; fi - -COPY compute-pcrs/src compute-pcrs/src -RUN cargo build -p compute-pcrs $(if [ "$build_type" = release ]; then echo --release; fi) - -FROM quay.io/fedora/fedora:43 -ARG build_type -COPY --from=builder "/build/target/$build_type/compute-pcrs" /usr/bin -COPY --from=builder /build/reference-values /reference-values diff --git a/register-server/Containerfile b/register-server/Containerfile deleted file mode 100644 index 91e79062..00000000 --- a/register-server/Containerfile +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-FileCopyrightText: Jakob Naucke -# -# SPDX-License-Identifier: CC0-1.0 - -ARG build_type -FROM ghcr.io/trusted-execution-clusters/buildroot:fedora AS builder -ARG build_type -WORKDIR /build - -COPY Makefile Cargo.toml Cargo.lock go.mod go.sum . -COPY api api -COPY lib lib -COPY register-server/Cargo.toml register-server/ -COPY register-server/src/lib.rs register-server/src/ - -# Set only required crates as members to minimize rebuilds upon changes. -RUN sed -i 's/members =.*/members = ["lib", "register-server"]/' Cargo.toml && \ - sed -i '/\[dev-dependencies\]/,$d' register-server/Cargo.toml && \ - sed -i '/trusted-cluster-operator-test-utils/d' lib/Cargo.toml && \ - make crds-rs - -# In debug builds, build dependencies to avoid full rebuild. -RUN if [ "$build_type" = debug ]; then cargo build -p register-server --lib; fi - -COPY register-server/src register-server/src -RUN cargo build -p register-server $(if [ "$build_type" = release ]; then echo --release; fi) - -FROM quay.io/fedora/fedora:43 -ARG build_type -COPY --from=builder "/build/target/$build_type/register-server" /usr/bin -EXPOSE 3030 -ENTRYPOINT ["/usr/bin/register-server"]