From 760ac7c98286e9e9f54344fc596bfcdc3987686c Mon Sep 17 00:00:00 2001 From: Mike Camp Date: Fri, 21 Aug 2026 20:36:29 -0400 Subject: [PATCH] fix(stargate): include Kubernetes router in runtime image Signed-off-by: Mike Camp --- src/libraries/rust/stargate/Dockerfile | 1 + src/libraries/rust/stargate/README.md | 4 +++ .../crates/stargate-k8s-router/BUILD.bazel | 6 ++-- .../rust/stargate/crates/stargate/BUILD.bazel | 13 +++++++ .../rust/stargate/tools/ci/BUILD.bazel | 1 + .../tools/ci/test-oci-image-contains-path.sh | 35 +++++++++++++++++++ 6 files changed, 57 insertions(+), 3 deletions(-) create mode 100755 src/libraries/rust/stargate/tools/ci/test-oci-image-contains-path.sh diff --git a/src/libraries/rust/stargate/Dockerfile b/src/libraries/rust/stargate/Dockerfile index 0a301e513..217a98932 100644 --- a/src/libraries/rust/stargate/Dockerfile +++ b/src/libraries/rust/stargate/Dockerfile @@ -129,6 +129,7 @@ ARG TARGETARCH # Health probe changes less often than the binary, so copy it first for layer caching. COPY --from=health-probe-downloader /usr/local/bin/grpc_health_probe /usr/local/bin/grpc_health_probe COPY --from=binary-builder /out/stargate /usr/local/bin/stargate +COPY --from=binary-builder /out/stargate-k8s-router /usr/local/bin/stargate-k8s-router ENTRYPOINT ["stargate"] CMD [] diff --git a/src/libraries/rust/stargate/README.md b/src/libraries/rust/stargate/README.md index 70cfe3b5d..6bad98426 100644 --- a/src/libraries/rust/stargate/README.md +++ b/src/libraries/rust/stargate/README.md @@ -91,6 +91,10 @@ load-balancer topology for production backend traffic. - `crates/mock-dynamo`: local OpenAI-style backend - `crates/stargate-bench`: benchmark runner +The versioned Stargate runtime image also includes +`/usr/local/bin/stargate-k8s-router`. Kubernetes deployments can run the main +Stargate process and the backend router from the same immutable image tag. + ## Benchmarks ```bash diff --git a/src/libraries/rust/stargate/crates/stargate-k8s-router/BUILD.bazel b/src/libraries/rust/stargate/crates/stargate-k8s-router/BUILD.bazel index bf65e0377..d34789325 100644 --- a/src/libraries/rust/stargate/crates/stargate-k8s-router/BUILD.bazel +++ b/src/libraries/rust/stargate/crates/stargate-k8s-router/BUILD.bazel @@ -48,7 +48,7 @@ rust_test( # Multi-arch OCI image. distroless/cc base, binary at # /usr/local/bin/stargate-k8s-router. rust_oci_image( - name = "image", + name = "stargate-k8s-router-image", base = "@distroless_cc", binary = ":stargate-k8s-router", binary_path = "/usr/local/bin/stargate-k8s-router", @@ -62,8 +62,8 @@ sh_test( name = "image_entrypoint_mode_test", srcs = ["//src/libraries/rust/stargate/tools/ci:image_entrypoint_mode_test.sh"], args = [ - "$(location :image_layer)", + "$(location :stargate-k8s-router-image_layer)", "/usr/local/bin/stargate-k8s-router", ], - data = [":image_layer"], + data = [":stargate-k8s-router-image_layer"], ) diff --git a/src/libraries/rust/stargate/crates/stargate/BUILD.bazel b/src/libraries/rust/stargate/crates/stargate/BUILD.bazel index a813c2f6a..810482c6b 100644 --- a/src/libraries/rust/stargate/crates/stargate/BUILD.bazel +++ b/src/libraries/rust/stargate/crates/stargate/BUILD.bazel @@ -116,6 +116,7 @@ rust_oci_image( base = "@distroless_cc", binary = ":stargate", binary_path = "/usr/local/bin/stargate", + extra_layers = ["//src/libraries/rust/stargate/crates/stargate-k8s-router:stargate-k8s-router-image_layer"], tags = ["stargate"], visibility = ["//visibility:public"], ) @@ -132,3 +133,15 @@ sh_test( ], data = [":image_layer"], ) + +# Composite-image guard. Inspect the assembled OCI layout so removing the +# router's extra layer fails this test. +sh_test( + name = "image_router_binary_test", + srcs = ["//src/libraries/rust/stargate/tools/ci:test-oci-image-contains-path.sh"], + args = [ + "$(location :image)", + "/usr/local/bin/stargate-k8s-router", + ], + data = [":image"], +) diff --git a/src/libraries/rust/stargate/tools/ci/BUILD.bazel b/src/libraries/rust/stargate/tools/ci/BUILD.bazel index 96e468f21..92885fc84 100644 --- a/src/libraries/rust/stargate/tools/ci/BUILD.bazel +++ b/src/libraries/rust/stargate/tools/ci/BUILD.bazel @@ -4,6 +4,7 @@ exports_files( [ "image_entrypoint_mode_test.sh", + "test-oci-image-contains-path.sh", ], visibility = ["//visibility:public"], ) diff --git a/src/libraries/rust/stargate/tools/ci/test-oci-image-contains-path.sh b/src/libraries/rust/stargate/tools/ci/test-oci-image-contains-path.sh new file mode 100755 index 000000000..c389a8607 --- /dev/null +++ b/src/libraries/rust/stargate/tools/ci/test-oci-image-contains-path.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +set -euo pipefail + +if [[ $# -ne 2 ]]; then + echo "usage: $0 " >&2 + exit 2 +fi + +image_layout="$1" +image_path="${2#/}" + +if [[ ! -f "${image_layout}/index.json" || ! -d "${image_layout}/blobs/sha256" ]]; then + echo "${image_layout} is not an OCI image layout" >&2 + exit 1 +fi + +while IFS= read -r -d '' blob; do + if entries="$(tar -tf "${blob}" 2>/dev/null)"; then + while IFS= read -r entry; do + entry="${entry#./}" + entry="${entry#/}" + if [[ "${entry}" == "${image_path}" ]]; then + exit 0 + fi + done <<< "${entries}" + fi +# rules_oci may symlink blob files to their source layers. Select those links +# directly without following symlinked directories outside the blob tree. +done < <(find "${image_layout}/blobs/sha256" \( -type f -o -type l \) -print0) + +echo "missing /${image_path} in ${image_layout}" >&2 +exit 1