Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
67 changes: 67 additions & 0 deletions .github/actions/setup-olm-bundle-tools/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Copyright NVIDIA CORPORATION
#
# 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.

name: Set up OLM bundle tools
description: Install Python 3.12 with PyYAML, and Go, regctl, and Operator SDK at the versions the repository pins

runs:
using: composite
steps:
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with:
python-version: "3.12"

- name: Get Golang version
shell: bash
run: |
GOLANG_VERSION=$(grep "GOLANG_VERSION ?=" versions.mk)
echo "GOLANG_VERSION=${GOLANG_VERSION##GOLANG_VERSION ?= }" >> "${GITHUB_ENV}"

- name: Get regctl version
shell: bash
run: |
REGCTL_VERSION=$(grep "REGCTL_VERSION ?=" versions.mk)
echo "REGCTL_VERSION=${REGCTL_VERSION##REGCTL_VERSION ?= }" >> "${GITHUB_ENV}"

- name: Get Operator SDK version
shell: bash
run: |
OPERATOR_SDK_VERSION=$(grep "OPERATOR_SDK_VERSION ?=" versions.mk)
echo "OPERATOR_SDK_VERSION=${OPERATOR_SDK_VERSION##OPERATOR_SDK_VERSION ?= }" >> "${GITHUB_ENV}"

- name: Install Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
with:
go-version: ${{ env.GOLANG_VERSION }}

- name: Install PyYAML
shell: bash
run: pip install --quiet pyyaml

- name: Install regctl
uses: regclient/actions/regctl-installer@148669fe4b19151fcab6e00c6df2db43b9e2b097
with:
release: ${{ env.REGCTL_VERSION }}

- name: Install Operator SDK
shell: bash
run: |
set -euo pipefail

curl -fsSLo operator-sdk \
"https://github.com/operator-framework/operator-sdk/releases/download/${OPERATOR_SDK_VERSION}/operator-sdk_linux_amd64"
chmod +x operator-sdk
sudo mv operator-sdk /usr/local/bin/operator-sdk
operator-sdk version
84 changes: 84 additions & 0 deletions .github/actions/validate-and-push-olm-bundle/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Copyright NVIDIA CORPORATION
#
# 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.

name: Validate and push OLM bundle
description: Validate the OLM bundle, then build the multi-arch bundle image and push it to GHCR

inputs:
release-tag:
description: Release tag the CSV release metadata must match; the release metadata is not validated when empty
required: false
default: ""
bundle-image-tag:
description: Tag of the pushed bundle image
required: true
github-token:
description: Token used to log in to GHCR
required: true

outputs:
bundle-image:
description: Reference of the pushed bundle image
value: ${{ steps.build.outputs.bundle_image }}

runs:
using: composite
steps:
- name: Validate OLM release metadata
if: ${{ inputs.release-tag != '' }}
shell: bash
env:
RELEASE_TAG: ${{ inputs.release-tag }}
CSV: bundle/manifests/gpu-operator-certified.clusterserviceversion.yaml
run: |
python3 .github/scripts/validate-olm-release-metadata.py \
--release-tag "${RELEASE_TAG}" \
--csv "${CSV}"

- name: Validate OLM bundle
shell: bash
run: |
set -euo pipefail

operator-sdk bundle validate ./bundle
make validate-csv

- name: Login to GitHub Container Registry for Docker
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ inputs.github-token }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4

- name: Build and push OLM bundle image
id: build
shell: bash
env:
BUNDLE_IMAGE_TAG: ${{ inputs.bundle-image-tag }}
GH_REPOSITORY: ${{ github.repository }}
VERSION: ""
DEFAULT_CHANNEL: "stable"
CHANNELS: "stable"
BUNDLE_IMAGE_BUILD_PLATFORM_OPTIONS: "--platform=linux/amd64,linux/arm64 --push"
run: |
set -euo pipefail

repository="$(echo "${GH_REPOSITORY}" | tr '[:upper:]' '[:lower:]')"
bundle_image="ghcr.io/${repository}/gpu-operator-bundle:${BUNDLE_IMAGE_TAG}"
make build-bundle-image DOCKER="docker buildx" BUNDLE_IMAGE="${bundle_image}"
echo "bundle_image=${bundle_image}" >> "${GITHUB_OUTPUT}"
echo "::notice::Published OLM bundle image ${bundle_image}"
68 changes: 68 additions & 0 deletions .github/scripts/apply-values-overrides.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env bash
# Copyright NVIDIA CORPORATION
#
# 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.

set -euo pipefail

readonly IMAGE_REFERENCE_EXPRESSION='eval(strenv(VALUES_PATH)) | (.repository // "") + "/" + (.image // "") + ":" + (.version // "")'

Comment thread
rahulait marked this conversation as resolved.
if [[ $# -ne 2 ]]; then
echo "Usage: $0 CHART_DIRECTORY VALUES_OVERRIDES_FILE" >&2
exit 1
fi

chart_directory="$1"
values_overrides_file="$2"
chart_values_file="${chart_directory}/values.yaml"
script_directory=$(dirname "${BASH_SOURCE[0]}")

override_path_list=$(yq '.. | select(tag == "!!map" and has("image")) | path | join(".")' "${values_overrides_file}")
if [[ -z "${override_path_list}" ]]; then
echo "Error: ${values_overrides_file} has no image overrides" >&2
exit 1
fi
mapfile -t override_paths <<< "${override_path_list}"

missing_path_count=0
for override_path in "${override_paths[@]}"; do
if ! VALUES_PATH=".${override_path}" yq -e 'eval(strenv(VALUES_PATH)) | has("image")' "${chart_values_file}" &> /dev/null; then
echo "Error: ${override_path}.image is not a value in ${chart_values_file}" >&2
missing_path_count=$((missing_path_count + 1))
fi
done
if [[ ${missing_path_count} -gt 0 ]]; then
exit 1
fi

python3 "${script_directory}/merge-yaml.py" \
--base "${chart_values_file}" \
--override "${values_overrides_file}" \
--output "${chart_values_file}"

rendered_cluster_policy_spec=$(helm template gpu-operator "${chart_directory}" | yq 'select(.kind == "ClusterPolicy") | .spec')

mismatched_path_count=0
for override_path in "${override_paths[@]}"; do
expected_image_reference=$(VALUES_PATH=".${override_path}" yq "${IMAGE_REFERENCE_EXPRESSION}" "${values_overrides_file}")
rendered_image_reference=$(VALUES_PATH=".${override_path}" yq "${IMAGE_REFERENCE_EXPRESSION}" <<< "${rendered_cluster_policy_spec}")
if [[ "${rendered_image_reference}" != "${expected_image_reference}" ]]; then
echo "Error: ${override_path} renders as '${rendered_image_reference}' in the ClusterPolicy, expected '${expected_image_reference}'" >&2
mismatched_path_count=$((mismatched_path_count + 1))
fi
done
if [[ ${mismatched_path_count} -gt 0 ]]; then
exit 1
fi

echo "Applied ${#override_paths[@]} image overrides to ${chart_values_file}"
81 changes: 38 additions & 43 deletions .github/scripts/generate-values-overrides.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,58 +16,53 @@

set -euo pipefail

# Usage: generate-values-overrides.sh OUTPUT_FILE TOOLKIT_IMAGE DEVICE_PLUGIN_IMAGE MIG_MANAGER_IMAGE
#
# Generates a Helm values override file for GPU Operator component images.
# This file can be used with `helm install -f values-overrides.yaml` to
# override default component image versions.

if [[ $# -ne 4 ]]; then
echo "Usage: $0 OUTPUT_FILE TOOLKIT_IMAGE DEVICE_PLUGIN_IMAGE MIG_MANAGER_IMAGE" >&2
if [[ $# -lt 2 ]]; then
echo "Usage: $0 OUTPUT_FILE VALUES_PATH=IMAGE [VALUES_PATH=IMAGE ...]" >&2
echo "" >&2
echo "Example:" >&2
echo " $0 values.yaml \\" >&2
echo " ghcr.io/nvidia/container-toolkit:v1.18.0-ubuntu20.04 \\" >&2
echo " ghcr.io/nvidia/k8s-device-plugin:v0.17.0-ubi8 \\" >&2
echo " ghcr.io/nvidia/k8s-mig-manager:v0.10.0-ubuntu20.04" >&2
echo " $0 values-overrides.yaml \\" >&2
echo " toolkit=ghcr.io/nvidia/container-toolkit:3e112b4a \\" >&2
echo " driver.manager=ghcr.io/nvidia/k8s-driver-manager:357e757f" >&2
exit 1
fi

OUTPUT_FILE="$1"
TOOLKIT_IMAGE="$2"
DEVICE_PLUGIN_IMAGE="$3"
MIG_MANAGER_IMAGE="$4"
output_file="$1"
shift

# Generate values override file
cat > "${OUTPUT_FILE}" <<EOF
# Generated by generate-values-overrides.sh
#
# This file overrides default GPU Operator component images with
# specific versions for forward compatibility testing.
: > "${output_file}"

toolkit:
repository: ""
version: ""
image: "${TOOLKIT_IMAGE}"
for image_override in "$@"; do
if [[ "${image_override}" != *=* ]]; then
echo "Error: '${image_override}' is not in VALUES_PATH=IMAGE form" >&2
exit 1
fi

devicePlugin:
repository: ""
version: ""
image: "${DEVICE_PLUGIN_IMAGE}"
values_path="${image_override%%=*}"
image_reference="${image_override#*=}"

migManager:
repository: ""
version: ""
image: "${MIG_MANAGER_IMAGE}"
EOF
if [[ ! "${values_path}" =~ ^[A-Za-z][A-Za-z0-9]*(\.[A-Za-z][A-Za-z0-9]*)*$ ]]; then
echo "Error: invalid values path '${values_path}'" >&2
exit 1
fi

echo "Generated values override file: ${OUTPUT_FILE}"
echo ""
echo "=== Component Images ==="
echo "Container Toolkit: ${TOOLKIT_IMAGE}"
echo "Device Plugin: ${DEVICE_PLUGIN_IMAGE}"
echo "MIG Manager: ${MIG_MANAGER_IMAGE}"
if [[ ! "${image_reference}" =~ ^(.+)/([^/:@]+):([^/:@]+)$ ]]; then
echo "Error: image '${image_reference}' for '${values_path}' is not in REPOSITORY/IMAGE:TAG form" >&2
exit 1
fi

VALUES_PATH=".${values_path}" \
IMAGE_REPOSITORY="${BASH_REMATCH[1]}" \
IMAGE_NAME="${BASH_REMATCH[2]}" \
IMAGE_VERSION="${BASH_REMATCH[3]}" \
yq -i '
eval(strenv(VALUES_PATH) + ".repository") = strenv(IMAGE_REPOSITORY) |
eval(strenv(VALUES_PATH) + ".image") = strenv(IMAGE_NAME) |
eval(strenv(VALUES_PATH) + ".version") = strenv(IMAGE_VERSION) |
eval(strenv(VALUES_PATH) + ".version") style="double"
' "${output_file}"
done

echo "Generated values override file: ${output_file}"
echo ""
echo "=== File Contents ==="
cat "${OUTPUT_FILE}"

cat "${output_file}"
Loading
Loading