Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .bazelignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ deploy
docs
fern
infra
# infra/cassandra is a nested, self-contained Bazel module (its own
# MODULE.bazel + rules_oci image graph, built via `cd infra/cassandra &&
# bazel build //:image_index`). Listed explicitly so the intent survives if
# the broad `infra` entry above is ever narrowed; keeps the root workspace
# from trying to load the nested module. Mirrors the function-autoscaler /
# stargate nested-module pattern.
infra/cassandra
migrations
tools

Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/bazel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ jobs:
worker-utils|src/compute-plane-services/worker-utils|false
function-autoscaler|src/control-plane-services/function-autoscaler|false
helm-reval|src/control-plane-services/helm-reval|false
stargate|src/libraries/rust/stargate|false'
stargate|src/libraries/rust/stargate|false
cassandra|infra/cassandra|false'
# Paths that affect the root-module workspace build (native
# root subtrees, Go and Java, plus the shared Bazel scaffold).
ROOT_GLOBS=(MODULE.bazel .bazelrc .bazelversion BUILD.bazel rules/ platforms/ tools/ ci/ src/clis/ src/libraries/ .github/bazel-root-test-quarantine.txt)
Expand Down
40 changes: 40 additions & 0 deletions infra/cassandra/.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# ============================================================================
# Bazel configuration for the NVCF Cassandra runtime image (image assembly
# only; no language toolchain). Tracks the Phase B OCI scaffold used by the
# stargate / function-autoscaler modules.
# ============================================================================

common --enable_bzlmod
common --enable_platform_specific_config
build --incompatible_strict_action_env

test --test_output=errors

# Workspace status (build stamping). Feeds STABLE_VERSION / STABLE_GIT_COMMIT
# / STABLE_OCI_TAG into the stamped remote tags on the nvidia-internal push
# targets.
build --workspace_status_command=tools/workspace_status.sh

# CI profile.
build:ci --jobs=16

# Release profile. The nvcf-internal bazel release backend builds the image
# with `--config=release` (uniform across services). This image is pure
# assembly (no compiled targets), so opt is effectively a no-op here; the
# config exists so the shared release script runs unmodified.
build:release -c opt
1 change: 1 addition & 0 deletions infra/cassandra/.bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
9.1.1
7 changes: 7 additions & 0 deletions infra/cassandra/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Bazel (nested module). Convenience symlinks + local caches/overrides.
bazel-*
.bazel-cache/
user.bazelrc
34 changes: 34 additions & 0 deletions infra/cassandra/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,40 @@ docker buildx build --platform linux/amd64,linux/arm64 -t <ref> infra/cassandra
The `--platform=$BUILDPLATFORM` on the yq stage is intentional: it lets yq
cross-download on the host arch without QEMU.

## Bazel image (rules_oci)

This subtree is also a self-contained Bazel module that builds the same image
via `rules_oci`, so it ships and releases like every other NVCF image (no
buildah). It is a nested module: the umbrella ignores it (root `.bazelignore`
lists `infra/cassandra`), so run Bazel from this directory.

```sh
cd infra/cassandra

# Public multi-arch image (amd64 + arm64), OSS-safe (no exporter jar).
bazel build //:image_index # or //:cassandra (non-manual alias)

# yq exec-bit guard.
bazel test //:yq_exec_bit_test
```

Translation of the Dockerfile:
- `FROM cassandra:5.0.8` -> `oci.pull` of the Docker Hub manifest-list digest
in `MODULE.bazel` (the digest is the single Cassandra version source; bump it
by re-resolving the new tag's manifest-list digest).
- pinned `yq` -> `http_file` per arch in `rules/repos.bzl` (same version +
sha256s as the Dockerfile), packaged at `/usr/local/bin/yq`.
- `scripts/cassandra-env.sh` -> `pkg_tar` layer over `/etc/cassandra/`.
- `--add-opens` JVM flags -> `JVM_EXTRA_OPTS` env, shared as `JVM_ADD_OPENS`
in `rules/oci/defs.bzl`.

The exporter agent and NGC push destinations are internal-only and do not
live in this repo. The private release repo (nvcf-internal) owns the exporter
jar and a `nvidia-internal/` overlay package; at release time it injects that
overlay into this module (reusing the public `//:yq_layer` and `//:env_layer`
targets), adds the exporter layer plus the `-javaagent` flag, and pushes the
with-exporter image. Nothing exporter-related is declared in this OSS tree.

## Pairs with

- Helm chart `deploy/helm/cassandra` deploys this image; its config init
Expand Down
109 changes: 109 additions & 0 deletions infra/cassandra/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Public, OSS-safe Cassandra runtime image (Bazel port of the Dockerfile,
# minus the metrics exporter, which is internal-only). This target builds on
# the NVIDIA/nvcf GitHub mirror. The with-exporter image is produced by the
# private release repo (nvcf-internal), which injects a nvidia-internal/
# overlay package into this module at build time and reuses the public
# layers below; that overlay and its jar never live in this repo.

load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_files", "strip_prefix")
load("@rules_pkg//pkg:tar.bzl", "pkg_tar")
load("@rules_shell//shell:sh_test.bzl", "sh_test")
load("//rules/oci:defs.bzl", "JVM_ADD_OPENS", "create_oci_image")

exports_files(["scripts/cassandra-env.sh"])

# ----------------------------------------------------------------------------
# yq layer: the pinned static binary at /usr/local/bin/yq. Per-arch selection
# resolves under the image's platform transition, so the arm64 image gets the
# arm64 yq and the amd64 image the amd64 yq. Mode 0755 (the chart's config
# init container execs it). Dockerfile parity: `COPY --from=yq-downloader`.
# ----------------------------------------------------------------------------
pkg_files(
name = "yq_files",
srcs = select({
"@platforms//cpu:arm64": ["@yq_linux_arm64//file"],
"@platforms//cpu:x86_64": ["@yq_linux_amd64//file"],
}),
attributes = pkg_attributes(mode = "0755"),
prefix = "/usr/local/bin",
strip_prefix = strip_prefix.files_only(),
)

pkg_tar(
name = "yq_layer",
srcs = [":yq_files"],
# Reused by the nvidia-internal with-exporter variant.
visibility = ["//visibility:public"],
)

# ----------------------------------------------------------------------------
# cassandra-env.sh layer: overwrites the base image's
# /etc/cassandra/cassandra-env.sh with the NCP rack-from-pod variant. Sourced
# (not executed) by /opt/cassandra/bin/cassandra, so mode 0644 matches the
# base. Dockerfile parity: `COPY scripts/cassandra-env.sh`.
# ----------------------------------------------------------------------------
pkg_files(
name = "cassandra_env_files",
srcs = ["scripts/cassandra-env.sh"],
attributes = pkg_attributes(mode = "0644"),
prefix = "/etc/cassandra",
strip_prefix = strip_prefix.files_only(),
)

pkg_tar(
name = "env_layer",
srcs = [":cassandra_env_files"],
visibility = ["//visibility:public"],
)

# ----------------------------------------------------------------------------
# The exporter agent reflects into JDK-internal com.sun.jmx classes; on the
# JDK 17 runtime shipped in the official image those packages are not open to
# unnamed modules by default. These --add-opens are harmless when no agent is
# wired in, so they stay unconditional (matches the Dockerfile). The public
# image sets NO -javaagent (no exporter jar); the with-exporter variant in
# nvidia-internal/ prepends it. JVM_ADD_OPENS is shared from defs.bzl.
# ----------------------------------------------------------------------------
create_oci_image(
name = "image",
base = "@cassandra_base",
# EXPOSE 7000 9042 are already declared by the base; add 9500 for metrics
# scraping parity with the Dockerfile.
env = {"JVM_EXTRA_OPTS": JVM_ADD_OPENS},
exposed_ports = ["9500/tcp"],
tags = ["cassandra"],
tars = [
":yq_layer",
":env_layer",
],
visibility = ["//visibility:public"],
)

# Non-manual handle for the multi-arch image. create_oci_image tags every
# target it emits `manual` (so `bazel run //...` never fires a push/load), but
# that also excludes :image_index from `bazel build //...`. The CI matrix
# (.github/workflows/bazel.yml) builds `//...`, so without a non-manual target
# depending on the index, GHA would never build the image itself. This alias
# pulls the multi-arch index into the wildcard build. Mirrors the
# function-autoscaler `alias` handle for its binary.
alias(
name = "cassandra",
actual = ":image_index",
visibility = ["//visibility:public"],
)

# yq exec-bit guard: fail the build if /usr/local/bin/yq is missing or not
# executable in the assembled layer (rules_pkg pkg_files default-mode 0644
# trap). Mirrors the stargate image_entrypoint_mode_test.
sh_test(
name = "yq_exec_bit_test",
srcs = ["//tools/ci:image_entrypoint_mode_test.sh"],
args = [
"$(location :yq_layer)",
"/usr/local/bin/yq",
],
data = [":yq_layer"],
)
101 changes: 101 additions & 0 deletions infra/cassandra/MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Bzlmod module definition for the NVCF Cassandra runtime image.

Image-assembly only: no language toolchain. This is the Bazel rules_oci
port of infra/cassandra/Dockerfile. It layers, on top of the official
Apache Cassandra base:

- a pinned, checksum-verified `yq` binary at /usr/local/bin/yq (used by
the chart's config init container to deep-merge cassandra.yaml), and
- scripts/cassandra-env.sh at /etc/cassandra/cassandra-env.sh (rack from
pod-hostname suffix for GossipingPropertyFileSnitch).

The public //:image_index target is OSS-safe: no metrics exporter jar and
no tenant registry URLs. The with-exporter variant and the NGC push
destinations live under nvidia-internal/ (excluded from the OSS mirror).

The umbrella nvcf/nvcf lists infra/cassandra in .bazelignore, so this
nested module is built on its own (cd infra/cassandra && bazel build ...),
mirroring the function-autoscaler / stargate pattern.
"""

module(
name = "nvcf_cassandra_image",
version = "0.0.1",
)

bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "rules_oci", version = "2.2.7")
bazel_dep(name = "rules_pkg", version = "1.2.0")
bazel_dep(name = "aspect_bazel_lib", version = "2.19.3")
bazel_dep(name = "rules_python", version = "1.7.0")
bazel_dep(name = "rules_shell", version = "0.8.0")

# NVCF OCI image-push macro. Data-free module: destination URLs are inlined
# at the nvidia-internal/ call-site, not here, so this override resolves on
# both the private GitLab build and the public NVIDIA/nvcf GitHub mirror.
bazel_dep(name = "nvcf_nvcr_destinations", version = "0.0.0")
local_path_override(
module_name = "nvcf_nvcr_destinations",
path = "../../rules/oci-destinations",
)

# rules_pkg pulls a hermetic Python interpreter for its tar builder. That
# interpreter refuses to run as root unless told otherwise, which the CI
# container hits. ignore_root_user_error keeps `bazel build` green there.
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(
ignore_root_user_error = True,
python_version = "3.11",
)

# ============================================================================
# OCI base image: official Apache Cassandra (Docker Hub), pinned by the
# multi-arch manifest-list digest for the 5.0.8 tag. The tag/digest is the
# single source of truth for the Cassandra version (Dockerfile `FROM
# cassandra:5.0.8`). Bump by re-resolving the manifest-list digest of the
# new tag. Only linux/amd64 + linux/arm64 are selected; the list also
# carries armv7/ppc64le/s390x, which we do not build.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
# ============================================================================
oci = use_extension("@rules_oci//oci:extensions.bzl", "oci")
oci.pull(
name = "cassandra_base",
digest = "sha256:e52bb93c21f69cc5c2f5eb9e7d9736b10a047ad38bc7776480c7dbbf7d4e0ba7",
image = "index.docker.io/library/cassandra",
platforms = [
"linux/amd64",
"linux/arm64/v8",
],
)
use_repo(
oci,
"cassandra_base",
"cassandra_base_linux_amd64",
"cassandra_base_linux_arm64_v8",
)

# ============================================================================
# External artifacts fetched by digest: the pinned yq binaries (public,
# OSS-safe). The internal exporter-agent jar is not declared here; the
# with-exporter image is built in nvcf-internal (see //rules:repos.bzl).
# ============================================================================
artifacts = use_extension("//rules:repos.bzl", "external_artifacts")
use_repo(
artifacts,
"yq_linux_amd64",
"yq_linux_arm64",
)
Loading
Loading