From a1f2411c5c6069452bcbaa385f6bf1d83acc9031 Mon Sep 17 00:00:00 2001 From: Aryan Gorwade Date: Fri, 28 Aug 2026 15:37:03 -0700 Subject: [PATCH 1/7] Created first version of TPN doc Signed-off-by: Aryan Gorwade --- scripts/generate-in-image-tpn.sh | 936 +++++++++++++++++++++++++++++++ 1 file changed, 936 insertions(+) create mode 100644 scripts/generate-in-image-tpn.sh diff --git a/scripts/generate-in-image-tpn.sh b/scripts/generate-in-image-tpn.sh new file mode 100644 index 000000000..e85d053be --- /dev/null +++ b/scripts/generate-in-image-tpn.sh @@ -0,0 +1,936 @@ +#!/usr/bin/env bash +# Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved. +# +# 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. +# Generate a third-party notice directly from an already-built container +# root filesystem. Syft is the source of truth for package inventory, package +# ownership, declared licenses, Go modules, and license content it can recover. +# Package archives remain a last-resort source of missing notice text. + +set -euo pipefail + +SYFT="${SYFT:-syft}" +JQ="${JQ:-jq}" +OUTPUT_DIR="${1:-${TPN_OUTPUT_DIR:-/licenses}}" +DOCUMENT_NAME="${TPN_DOCUMENT_NAME:-THIRD_PARTY_NOTICES.md}" +INVENTORY_NAME="${TPN_INVENTORY_NAME:-third-party-packages.tsv}" +TPN_SYFT_ALL_CATALOGERS="${TPN_SYFT_ALL_CATALOGERS:-0}" +TPN_RECOVER_ARCHIVES="${TPN_RECOVER_ARCHIVES:-1}" +TPN_FETCH_UPSTREAM="${TPN_FETCH_UPSTREAM:-1}" +TPN_STRICT="${TPN_STRICT:-0}" + +# Syft cannot reliably map arbitrary binaries and scripts downloaded outside +# RPM/DPKG to an upstream name, version, and license. +# These are the things directly curled by the Dockerfile. +standalone_manifest() { + cat <<'EOF' +rhel8|/usr/local/bin/donkey|donkey|1.1.0|ISC|https://raw.githubusercontent.com/3XX0/donkey/v1.1.0/donkey.c|c-header|binary-stderr|https://github.com/3XX0/donkey +rhel8|/usr/local/bin/extract-vmlinux|extract-vmlinux||GPL-2.0-only|https://raw.githubusercontent.com/torvalds/linux/master/LICENSES/preferred/GPL-2.0|file|sha256|https://github.com/torvalds/linux +rhel9|/usr/local/bin/donkey|donkey|1.1.0|ISC|https://raw.githubusercontent.com/3XX0/donkey/v1.1.0/donkey.c|c-header|binary-stderr|https://github.com/3XX0/donkey +rhel9|/usr/local/bin/extract-vmlinux|extract-vmlinux||GPL-2.0-only|https://raw.githubusercontent.com/torvalds/linux/master/LICENSES/preferred/GPL-2.0|file|sha256|https://github.com/torvalds/linux +rhel10|/usr/local/bin/donkey|donkey|1.1.0|ISC|https://raw.githubusercontent.com/3XX0/donkey/v1.1.0/donkey.c|c-header|binary-stderr|https://github.com/3XX0/donkey +rhel10|/usr/local/bin/extract-vmlinux|extract-vmlinux||GPL-2.0-only|https://raw.githubusercontent.com/torvalds/linux/master/LICENSES/preferred/GPL-2.0|file|sha256|https://github.com/torvalds/linux +rhel10|/usr/bin/unzboot|unzboot|0.1|GPL-2.0-or-later|https://raw.githubusercontent.com/eballetbo/unzboot/main/LICENSE|file|version-sha256|https://github.com/eballetbo/unzboot +ubuntu22.04|/usr/local/bin/donkey|donkey|1.1.0|ISC|https://raw.githubusercontent.com/3XX0/donkey/v1.1.0/donkey.c|c-header|binary-stderr|https://github.com/3XX0/donkey +EOF +} + +WORK_ROOT="" +WARNINGS=0 + +die() { + printf 'ERROR: %s\n' "$1" >&2 + shift + (( $# == 0 )) || printf '%s\n' "$@" >&2 + exit 1 +} + +log() { + printf '%s\n' "$*" >&2 +} + +warn() { + WARNINGS=$((WARNINGS + 1)) + printf 'WARNING: %s\n' "$*" >&2 +} + +cleanup() { + if [[ -n "${WORK_ROOT}" && -d "${WORK_ROOT}" ]]; then + chmod -R u+w "${WORK_ROOT}" 2>/dev/null || true + rm -rf "${WORK_ROOT}" + fi +} + +trap cleanup EXIT + +require_command() { + command -v "$1" >/dev/null 2>&1 || die "$1 is required." +} + +check_boolean() { + local name="$1" value="$2" + [[ "${value}" == 0 || "${value}" == 1 ]] \ + || die "${name} must be 0 or 1." +} + +hash_file() { + sha256sum "$1" | awk '{print $1}' +} + +safe_component() { + printf '%s' "$1" | tr '/[:space:]' '__' +} + +detect_distribution() { + local id version major + [[ -r /etc/os-release ]] \ + || die "/etc/os-release is missing; cannot identify the distribution." + + id="$(. /etc/os-release >/dev/null 2>&1; printf '%s' "${ID:-}")" + version="$(. /etc/os-release >/dev/null 2>&1; printf '%s' "${VERSION_ID:-}")" + [[ -n "${id}" && -n "${version}" ]] \ + || die "/etc/os-release does not declare both ID and VERSION_ID." + major="${version%%.*}" + + case "${id}" in + rhel|redhat|rocky|almalinux|centos) DISTRIBUTION="rhel${major}" ;; + ubuntu) DISTRIBUTION="ubuntu${version}" ;; + debian) DISTRIBUTION="debian${major}" ;; + *) + die "unsupported distribution ${id}${version}; expected an RPM- or DPKG-based image." + ;; + esac +} + +detect_architecture() { + local machine + if [[ -n "${TARGETARCH:-}" ]]; then + ARCHITECTURE="${TARGETARCH}" + return + fi + + machine="$(uname -m)" + case "${machine}" in + x86_64|amd64) ARCHITECTURE="amd64" ;; + aarch64|arm64) ARCHITECTURE="arm64" ;; + ppc64le) ARCHITECTURE="ppc64le" ;; + *) ARCHITECTURE="${machine}" ;; + esac +} + +validate_vgpu_binary_modules() { + local inventory="$1" stdlib_version expected + + stdlib_version="$(awk -F '\t' '$3 == "go-standard-library" { print $2 }' \ + "${inventory}" | LC_ALL=C sort -u)" + [[ -n "${stdlib_version}" && "${stdlib_version}" != *$'\n'* ]] \ + || die "Syft did not find exactly one Go standard library in vgpu-util." + + if [[ -n "${GOLANG_VERSION:-}" ]]; then + expected="${GOLANG_VERSION#go}" + [[ "${stdlib_version#go}" == "${expected}" ]] \ + || die "vgpu-util reports ${stdlib_version}, but GOLANG_VERSION is ${GOLANG_VERSION}." + fi + + awk -F '\t' ' + $3 == "go-module" { + count++ + if ($1 == "" || $2 == "") bad = 1 + } + END { exit !(count > 0 && !bad) } + ' "${inventory}" \ + || die "Syft did not produce a complete third-party Go module inventory for vgpu-util." +} + +scan_rootfs() { + local records="$1" + local json="${WORK_ROOT}/rootfs.syft.json" + local remote_go_licenses=0 + local include_vgpu=false + local -a syft_args=( + "dir:/" --scope squashed + --source-name "nvidia-driver-container-${DISTRIBUTION}" + --source-version "${DRIVER_LABEL}" + -o "syft-json=${json}" + ) + + if [[ "${DRIVER_TYPE:-passthrough}" == vgpu ]]; then + remote_go_licenses="${TPN_FETCH_UPSTREAM}" + include_vgpu=true + fi + if [[ "${TPN_SYFT_ALL_CATALOGERS}" != 1 && "${include_vgpu}" != true ]]; then + syft_args+=( + --override-default-catalogers rpm-db-cataloger \ + --override-default-catalogers dpkg-db-cataloger \ + --select-catalogers=-file + ) + fi + log "Scanning the final root filesystem with Syft..." + SYFT_CHECK_FOR_APP_UPDATE=false \ + SYFT_LICENSE_CONTENT=all \ + SYFT_GOLANG_SEARCH_REMOTE_LICENSES="${remote_go_licenses}" \ + "${SYFT}" "${syft_args[@]}" + + # Emit one normalized stream. P is a component, F is a package-owned file, + # and L is license content supplied by Syft. Only opaque file contents and + # paths are base64 encoded. + "${JQ}" -r \ + --arg architecture "${ARCHITECTURE}" \ + --argjson include_vgpu "${include_vgpu}" ' + def from_vgpu: + $include_vgpu + and .type == "go-module" + and any(.locations[]?; + (.path | ltrimstr("/")) == "usr/local/bin/vgpu-util"); + def component_type: + if .type == "go-module" and .name == "stdlib" then "go-standard-library" + else .type end; + def component_arch: + (.metadata.architecture // .metadata.arch // "") as $value + | if $value == "" then $architecture else $value end; + def component_licenses: + ([ + .licenses[]? + | if (.spdxExpression // "") != "" then .spdxExpression + else (.value // empty) end + ] | unique | join(" / ")) as $value + | if $value == "" then "Unknown" else $value end; + def package_source: + if .type == "rpm" and (.metadata.sourceRpm // "") != "" + then .metadata.sourceRpm + elif .type == "deb" and (.metadata.source // "") != "" + then .metadata.source + else .name + end; + def component_purl: + if (.purl // "") != "" then .purl + elif .type == "go-module" then "pkg:golang/\(.name)@\(.version)" + else "" end; + .artifacts[] as $package + | ( + if (($package.type == "rpm" or $package.type == "deb") + and $package.name != "gpg-pubkey") then + { + type: ($package | component_type), + arch: ($package | component_arch), + source: ($package | package_source), + files: true + } + elif (($package | from_vgpu) + and $package.name != "vgpu-util" + and $package.name != "command-line-arguments") then + { + type: ($package | component_type), + arch: $architecture, + source: "", + files: false + } + else empty end + ) as $component + | ( + ["P", $package.name, $package.version, $component.type, $component.arch, + ($package | component_licenses), ($package | component_purl), + $component.source], + ( + select($component.files) + | ( + ($package.metadata.files // [])[], + ($package.locations[]? + | select((.path // "") + | test("^/?usr/share/doc/.+/copyright")) + | {path: .path, flags: ""}) + ) + | select((.path // "") != "") + | ["F", $package.name, $package.version, $component.arch, + ((if (.path | startswith("/")) then .path + else "/" + .path end) | @base64), + (.flags // "")] + ), + ( + ($package.licenses // [] | to_entries[]?) + | select((.value.contents // "") != "") + | ["L", $package.name, $package.version, + $component.type, $component.arch, (.key | tostring), + (if (.value.spdxExpression // "") != "" + then .value.spdxExpression + else (.value.value // "license") end), + (.value.contents | @base64)] + ) + ) + | @tsv + ' "${json}" > "${records}" +} + +process_syft_records() { + local records="$1" inventory="$2" package_keys="$3" ownership="$4" + local source_map="$5" staged="$6" + local tag name version type package_arch field5 field6 field7 + local path flags source license_id content destination decoded suffix=0 + local coverage="${PLATFORM} (${DRIVER_LABEL})" + + : > "${inventory}" + : > "${package_keys}" + : > "${ownership}" + : > "${source_map}" + while IFS=$'\t' read -r tag name version type package_arch field5 field6 field7; do + case "${tag}" in + P) + printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \ + "${name}" "${version}" "${type}" "${package_arch}" \ + "${field5}" "${field6}" "${coverage}" >> "${inventory}" + if [[ "${type}" == rpm || "${type}" == deb ]]; then + printf '%s\t%s\t%s\n' \ + "${name}" "${version}" "${package_arch}" >> "${package_keys}" + source="${field7:-${name}}" + printf '%s\t%s\n' "${name}" "${source}" >> "${source_map}" + fi + ;; + F) + path="$(printf '%s' "${package_arch}" | base64 -d)" + flags="${field5}" + printf '%s\t%s\t%s\t%s\t%s\n' \ + "${name}" "${version}" "${type}" "${path}" "${flags}" >> "${ownership}" + ;; + L) + license_id="${field6:-license}" + content="${field7}" + destination="${staged}/${type}/${name}/${version}/${package_arch}/syft" + mkdir -p "${destination}" + decoded="${WORK_ROOT}/decoded-license" + printf '%s' "${content}" | base64 -d > "${decoded}" + [[ -s "${decoded}" ]] || continue + suffix=$((suffix + 1)) + save_license_file "${decoded}" \ + "${destination}/${field5}-$(safe_component "${license_id}").txt" \ + "duplicate.${suffix}" + ;; + esac + done < "${records}" + + LC_ALL=C sort -u -o "${package_keys}" "${package_keys}" + LC_ALL=C sort -u -o "${ownership}" "${ownership}" + LC_ALL=C sort -u -o "${source_map}" "${source_map}" + [[ -s "${ownership}" ]] || die \ + "Syft did not emit RPM/DPKG package ownership data." \ + "Use a current Syft release with metadata.files support." +} + +is_license_path() { + local path flags base + path="$(printf '%s' "$1" | LC_ALL=C tr '[:upper:]' '[:lower:]')" + flags="$(printf '%s' "$2" | LC_ALL=C tr '[:upper:]' '[:lower:]')" + base="${path##*/}" + + [[ "${flags}" == *l* ]] && return 0 + case "${path}" in + /usr/share/licenses/*|/usr/share/doc/*/copyright*) return 0 ;; + esac + case "${base}" in + license|license[-._]*|licence|licence[-._]*|notice|notice[-._]*|\ + copying|copying[-._]*|copyright|copyright[-._]*|authors|authors[-._]*|\ + patents|patents[-._]*) return 0 ;; + esac + return 1 +} + +save_license_file() { + local source="$1" destination="$2" suffix="$3" + [[ -f "${source}" ]] || return 0 + mkdir -p "$(dirname "${destination}")" + if [[ ! -e "${destination}" ]]; then + cp -L "${source}" "${destination}" 2>/dev/null || return 0 + elif [[ "$(hash_file "${source}")" != "$(hash_file "${destination}")" ]]; then + cp -L "${source}" "${destination}.${suffix}" 2>/dev/null || return 0 + fi +} + +path_is_package_owned() { + local ownership="$1" wanted="$2" + awk -F '\t' -v wanted="${wanted}" '$4 == wanted { found = 1 } END { exit !found }' "${ownership}" +} + +filter_license_rows() { + awk -F '\t' ' + { + path = tolower($4) + flags = tolower($5) + if (index(flags, "l") > 0) { print; next } + if (path ~ /^\/usr\/share\/licenses\//) { print; next } + if (path ~ /^\/usr\/share\/doc\/.*\/copyright/) { print; next } + n = split(path, segment, "/") + base = segment[n] + if (base ~ /^(license|licence|notice|copying|copyright|authors|patents)([-._]|$)/) { + print + } + } + ' +} + +detect_standalone_version() { + local path="$1" expected="$2" mode="$3" + local detected digest output + + case "${mode}" in + binary-stderr) + output="$("${path}" 2>&1 || true)" + detected="$(printf '%s\n' "${output}" | sed -n 's/^version: //p' | head -n 1)" + [[ -n "${detected}" ]] \ + || die "could not detect the version of ${path}." + [[ -z "${expected}" || "${detected}" == "${expected}" ]] \ + || die "${path} reports ${detected}, but its manifest expects ${expected}." + printf '%s\n' "${detected}" + ;; + sha256) + digest="$(hash_file "${path}")" + printf 'sha256:%s\n' "${digest}" + ;; + version-sha256) + digest="$(hash_file "${path}")" + [[ -n "${expected}" ]] || die "${path} needs a declared project version." + printf '%s+sha256.%s\n' "${expected}" "${digest}" + ;; + *) + die "unknown standalone version mode '${mode}' for ${path}." + ;; + esac +} + +download_standalone_license() { + local url="$1" mode="$2" destination="$3" + local download + + [[ -f "${destination}" ]] && return 0 + [[ "${TPN_FETCH_UPSTREAM}" == 1 ]] || return 1 + mkdir -p "$(dirname "${destination}")" + download="$(mktemp "${WORK_ROOT}/standalone-license.XXXXXX")" + curl -fsSL --retry 3 "${url}" > "${download}" || { + rm -f "${download}" + return 1 + } + + case "${mode}" in + file) + mv "${download}" "${destination}" + ;; + c-header) + awk 'NR == 1 && $0 == "/*" { copying = 1 } + copying { print } + copying && $0 == " */" { exit }' "${download}" > "${destination}" + rm -f "${download}" + if [[ ! -s "${destination}" ]]; then + rm -f "${destination}" + return 1 + fi + ;; + *) + rm -f "${download}" + die "unknown standalone license mode '${mode}'." + ;; + esac +} + +collect_standalone_components() { + local distribution="$1" ownership="$2" license_root="$3" inventory="$4" + local manifest_distribution path name expected license url license_mode version_mode source + local version destination coverage + + coverage="${PLATFORM} (${DRIVER_LABEL})" + while IFS='|' read -r manifest_distribution path name expected license url license_mode version_mode source; do + [[ "${manifest_distribution}" == "${distribution}" ]] || continue + [[ -f "${path}" ]] || continue + path_is_package_owned "${ownership}" "${path}" && continue + + version="$(detect_standalone_version "${path}" "${expected}" "${version_mode}")" + destination="${license_root}/${name}/${version}/${ARCHITECTURE}/upstream/LICENSE" + download_standalone_license "${url}" "${license_mode}" "${destination}" \ + || warn "could not download the license text for ${name} from ${url}." + + printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \ + "${name}" "${version}" standalone "${ARCHITECTURE}" "${license}" "${source}" "${coverage}" \ + >> "${inventory}" + done < <(standalone_manifest) +} + +directory_has_files() { + local directory="$1" + find "${directory}" -type f -print -quit 2>/dev/null | grep -q . +} + +apply_syft_license_content() { + local inventory="$1" staged="$2" license_root="$3" + local name version type package_arch _licenses _purl _coverage + local source destination + + while IFS=$'\t' read -r name version type package_arch _licenses _purl _coverage; do + source="${staged}/${type}/${name}/${version}/${package_arch}" + destination="${license_root}/${name}/${version}/${package_arch}" + [[ -d "${source}" ]] || continue + if [[ "${type}" == rpm || "${type}" == deb ]]; then + directory_has_files "${destination}" && continue + fi + mkdir -p "${destination}" + cp -R "${source}/." "${destination}/" + done < "${inventory}" +} + +collect_image_licenses() { + local distribution="$1" ownership="$2" license_root="$3" inventory="$4" + local name version package_arch path flags relative destination suffix + suffix="$(safe_component "${PLATFORM}")" + while IFS=$'\t' read -r name version package_arch path flags; do + [[ -n "${name}" && -n "${version}" && "${path}" == /* ]] || continue + relative="${path#/}" + destination="${license_root}/${name}/${version}/${package_arch}/${relative}" + save_license_file "${path}" "${destination}" "${suffix}" + done < <(filter_license_rows < "${ownership}") + + collect_standalone_components \ + "${distribution}" "${ownership}" "${license_root}" "${inventory}" +} + +component_version() { + local inventory="$1" name="$2" + awk -F '\t' -v name="${name}" '$1 == name { print $2; exit }' "${inventory}" +} + +collect_embedded_notice() { + local url="$1" destination="$2" mode="$3" + local source="${WORK_ROOT}/embedded-notice-source" + + mkdir -p "$(dirname "${destination}")" + curl -fsSL --retry 3 "${url}" > "${source}" || return 0 + case "${mode}" in + logrus) + awk ' + /^\/\/ The following code was sourced/ { copying = 1 } + copying { line = $0; sub(/^\/\/ ?/, "", line); print line } + copying && /^\/\/ CONNECTION WITH THE SOFTWARE\.$/ { exit } + ' "${source}" > "${destination}" + ;; + urfave) + awk ' + /Copyright \(c\) 2009 The Go Authors/ { copying = 1 } + copying { + line = $0 + sub(/^[[:space:]]*/, "", line) + sub(/[[:space:]]*$/, "", line) + print line + } + copying && /OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\./ { exit } + ' "${source}" > "${destination}" + ;; + esac + [[ -s "${destination}" ]] || rm -f "${destination}" +} + +collect_vgpu_additional_notices() { + local inventory="$1" license_root="$2" + local version destination + + [[ "${TPN_FETCH_UPSTREAM}" == 1 ]] || return 0 + + version="$(component_version "${inventory}" stdlib)" + destination="${license_root}/stdlib/${version}/${ARCHITECTURE}/upstream/LICENSE" + download_standalone_license \ + "https://raw.githubusercontent.com/golang/go/${version}/LICENSE" file "${destination}" \ + || warn "could not download the Go standard library license for ${version}." + + version="$(component_version "${inventory}" github.com/sirupsen/logrus)" + if [[ -n "${version}" ]]; then + collect_embedded_notice \ + "https://raw.githubusercontent.com/sirupsen/logrus/${version}/alt_exit.go" \ + "${license_root}/github.com/sirupsen/logrus/${version}/${ARCHITECTURE}/syft/ATEEXIT-LICENSE" \ + logrus + fi + + version="$(component_version "${inventory}" github.com/urfave/cli/v2)" + if [[ -n "${version}" ]]; then + collect_embedded_notice \ + "https://raw.githubusercontent.com/urfave/cli/${version}/sliceflag.go" \ + "${license_root}/github.com/urfave/cli/v2/${version}/${ARCHITECTURE}/syft/GO-FLAG-BSD-LICENSE" \ + urfave + fi +} + +recover_missing_package_licenses() { + local distribution="$1" package_keys="$2" license_root="$3" + local missing="${WORK_ROOT}/missing.tsv" archives="${WORK_ROOT}/archives" + local name version package_arch package_archives nevra archive + local archive_name archive_version archive_arch + local extract path relative suffix="archive.$(safe_component "${PLATFORM}")" + + : > "${missing}" + while IFS=$'\t' read -r name version package_arch; do + directory_has_files "${license_root}/${name}/${version}/${package_arch}" \ + || printf '%s\t%s\t%s\n' "${name}" "${version}" "${package_arch}" >> "${missing}" + done < "${package_keys}" + [[ "${TPN_RECOVER_ARCHIVES}" == 1 && -s "${missing}" ]] || return 0 + + log "Recovering license text from exact installed package archives..." + mkdir -p "${archives}" + if [[ "${distribution}" == rhel* ]]; then + (dnf install -y 'dnf-command(download)' cpio \ + || dnf install -y dnf-plugins-core cpio) >/dev/null + else + apt-get update >/dev/null + fi + + while IFS=$'\t' read -r name version package_arch; do + package_archives="${archives}/${name}/${package_arch}" + mkdir -p "${package_archives}" + if [[ "${distribution}" == rhel* ]]; then + while IFS= read -r nevra; do + dnf download --destdir "${package_archives}" "${nevra}" || true + done < <(rpm -q --qf '%{NAME}-%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}.%{ARCH}\n' \ + "${name}.${package_arch}" 2>/dev/null || true) + else + if [[ -d /usr/local/repos ]]; then + while IFS= read -r archive; do + archive_name="$(dpkg-deb -f "${archive}" Package)" + archive_version="$(dpkg-deb -f "${archive}" Version)" + archive_arch="$(dpkg-deb -f "${archive}" Architecture)" + [[ "${archive_name}" == "${name}" \ + && "${archive_version}" == "${version}" \ + && "${archive_arch}" == "${package_arch}" ]] \ + && cp "${archive}" "${package_archives}/" + done < <(find /usr/local/repos -maxdepth 1 -type f -name '*.deb' 2>/dev/null) + fi + directory_has_files "${package_archives}" \ + || (cd "${package_archives}" \ + && apt-get download "${name}:${package_arch}=${version}") || true + fi + + while IFS= read -r -d '' archive; do + extract="${WORK_ROOT}/archive-extract/$(safe_component \ + "${distribution}-${name}-${version}-${package_arch}-${RANDOM}")" + mkdir -p "${extract}" + case "${archive}" in + *.rpm) rpm2cpio "${archive}" | (cd "${extract}" && cpio -idm --quiet) ;; + *.deb) dpkg-deb -x "${archive}" "${extract}" ;; + esac + while IFS= read -r -d '' path; do + relative="${path#${extract}/}" + is_license_path "/${relative}" "" || continue + save_license_file "${path}" \ + "${license_root}/${name}/${version}/${package_arch}/${relative}" "${suffix}" + done < <(find "${extract}" -type f -print0) + chmod -R u+w "${extract}" + rm -rf "${extract}" + done < <(find "${package_archives}" \ + -type f \( -name '*.rpm' -o -name '*.deb' \) -print0) + done < "${missing}" +} + +# Some packages intentionally share notice text through a same-source sibling. +# That sharing is intentional; the link can become dangling when the sibling is +# absent or renamed. Archive extraction cannot repair a cross-package link, so +# this addition copies the sibling's recovered text and identifier. +# If a package's license text is unknown, this is a best-effort fallback. +recover_license_text_from_siblings() { + local inventory="$1" license_root="$2" source_map="$3" + local haves="${WORK_ROOT}/source-haves.tsv" + local inherited="${WORK_ROOT}/source-inherited.tsv" + local name version _type package_arch license _rest + local source sibling_root sibling_license package_root recovered=0 + + [[ -s "${source_map}" ]] || return 0 + + : > "${haves}" + while IFS=$'\t' read -r name version _type package_arch license _rest; do + package_root="${license_root}/${name}/${version}/${package_arch}" + directory_has_files "${package_root}" || continue + source="$(awk -F '\t' -v name="${name}" '$1 == name { print $2; exit }' "${source_map}")" + [[ -n "${source}" ]] || continue + printf '%s\t%s\t%s\n' "${source}" "${package_root}" "${license}" >> "${haves}" + done < "${inventory}" + [[ -s "${haves}" ]] || return 0 + + : > "${inherited}" + while IFS=$'\t' read -r name version _type package_arch license _rest; do + package_root="${license_root}/${name}/${version}/${package_arch}" + directory_has_files "${package_root}" && continue + source="$(awk -F '\t' -v name="${name}" '$1 == name { print $2; exit }' "${source_map}")" + [[ -n "${source}" ]] || continue + sibling_root="$(awk -F '\t' -v source="${source}" '$1 == source { print $2; exit }' "${haves}")" + [[ -n "${sibling_root}" && -d "${sibling_root}" ]] || continue + mkdir -p "${package_root}" + cp -R "${sibling_root}/." "${package_root}/" 2>/dev/null || continue + recovered=$((recovered + 1)) + + if [[ "${license}" == Unknown || "${license}" == NOASSERTION ]]; then + sibling_license="$(awk -F '\t' -v source="${source}" ' + $1 == source && $3 != "" && $3 != "Unknown" && $3 != "NOASSERTION" { + print $3 + exit + } + ' "${haves}")" + [[ -n "${sibling_license}" ]] \ + && printf '%s\t%s\n' "${name}" "${sibling_license}" >> "${inherited}" + fi + done < "${inventory}" + + if [[ -s "${inherited}" ]]; then + awk -F '\t' -v inherited="${inherited}" ' + BEGIN { + OFS = "\t" + while ((getline line < inherited) > 0) { + split(line, field, "\t") + license[field[1]] = field[2] + } + close(inherited) + } + { if ($1 in license) $5 = license[$1]; print } + ' "${inventory}" > "${inventory}.new" + mv "${inventory}.new" "${inventory}" + log "Adopted a same-source license identifier for $(wc -l < "${inherited}" | tr -d ' ') component(s)." + fi + + (( recovered > 0 )) \ + && log "Recovered license text for ${recovered} component(s) from same-source siblings." + return 0 +} + +collapse_inventory() { + LC_ALL=C sort -t $'\t' -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 -k7,7 -u "$1" | awk -F '\t' ' + { + key = $1 SUBSEP $2 SUBSEP $3 SUBSEP $4 + if (!(key in present)) { + present[key] = 1; order[++count] = key + name[key] = $1; version[key] = $2; type[key] = $3 + architecture[key] = $4; purl[key] = $6 + } + if (!((key SUBSEP $5) in license_seen)) { + license_seen[key SUBSEP $5] = 1 + licenses[key] = licenses[key] (licenses[key] == "" ? "" : " / ") $5 + } + if (!((key SUBSEP $7) in coverage_seen)) { + coverage_seen[key SUBSEP $7] = 1 + coverage[key] = coverage[key] (coverage[key] == "" ? "" : ", ") $7 + } + } + END { + OFS = "\t" + for (i = 1; i <= count; i++) { + key = order[i] + print name[key], version[key], type[key], architecture[key], licenses[key], purl[key], coverage[key] + } + } + ' +} + +fence_for() { + local file="$1" longest width + longest=$( (LC_ALL=C grep -oaE '`+' "${file}" 2>/dev/null || true) \ + | awk '{ if (length($0) > max) max = length($0) } END { print max+0 }') + width=$((longest + 1)) + (( width < 3 )) && width=3 + printf '%*s' "${width}" '' | tr ' ' '`' +} + +materialize_text() { + local source="$1" destination="$2" + case "${source}" in + *.gz) + command -v gzip >/dev/null 2>&1 || return 1 + gzip -cd "${source}" > "${destination}" 2>/dev/null + ;; + *.xz) + command -v xz >/dev/null 2>&1 || return 1 + xz -cd "${source}" > "${destination}" 2>/dev/null + ;; + *.bz2) + command -v bzip2 >/dev/null 2>&1 || return 1 + bzip2 -cd "${source}" > "${destination}" 2>/dev/null + ;; + *.zst|*.zstd) + command -v zstd >/dev/null 2>&1 || return 1 + zstd -qcd "${source}" > "${destination}" 2>/dev/null + ;; + *) + cp "${source}" "${destination}" + ;; + esac +} + +emit_sections() { + local index="$1" license_root="$2" + local name version type architecture licenses _purl _coverage + local package_root file relative text fence digest + local hashes="${WORK_ROOT}/emitted-hashes" + + while IFS=$'\t' read -r name version type architecture licenses _purl _coverage; do + printf '### %s %s (%s)\n\n' "${name}" "${version}" "${architecture}" + printf '* License: %s\n' "${licenses}" + printf '* Package type: %s\n' "${type}" + printf '* Architecture: %s\n\n' "${architecture}" + + package_root="${license_root}/${name}/${version}/${architecture}" + : > "${hashes}" + if ! find "${package_root}" -type f -print -quit 2>/dev/null | grep -q .; then + printf 'License text unavailable. See the package source for the full license.\n\n' + continue + fi + + while IFS= read -r -d '' file; do + digest="$(hash_file "${file}")" + grep -Fqx "${digest}" "${hashes}" && continue + printf '%s\n' "${digest}" >> "${hashes}" + + relative="${file#${package_root}/}" + text="${WORK_ROOT}/license-text" + if ! materialize_text "${file}" "${text}"; then + printf '#### %s\n\n' "${relative}" + printf 'License text is stored in a compression format this image cannot decode.\n\n' + continue + fi + fence="$(fence_for "${text}")" + printf '#### %s\n\n' "${relative}" + printf '%stext\n' "${fence}" + cat "${text}" + [[ ! -s "${text}" || $(tail -c 1 "${text}" | wc -l) -eq 1 ]] || printf '\n' + printf '%s\n\n' "${fence}" + rm -f "${text}" + done < <(find "${package_root}" -type f -print0 | LC_ALL=C sort -z) + done < "${index}" +} + +compose_document() { + local index="$1" license_root="$2" + local output="${OUTPUT_DIR}/${DOCUMENT_NAME}" + local temporary="${output}.tmp" + local name version type architecture licenses _purl _coverage + + log "Composing ${output}..." + { + printf '# Third-Party Notices\n\n' + printf 'NVIDIA GPU driver container %s for %s\n\n' "${DRIVER_LABEL}" "${DISTRIBUTION}" + printf 'This document covers packages discovered by Syft plus manifested standalone\n' + printf 'components present in this final %s root filesystem. Build-stage-only\n' "${PLATFORM}" + printf 'components are excluded.\n\n' + + if [[ "${DRIVER_TYPE:-}" == vgpu ]]; then + printf '**Scope limitation:** A release-specific vGPU/GRID driver `.run` payload is\n' + printf 'supplied separately and is not covered by this document.\n\n' + fi + + printf '## Dependency Index\n\n' + printf '| Package | Version | Type | Architecture | License |\n' + printf '|---------|---------|------|--------------|---------|\n' + while IFS=$'\t' read -r name version type architecture licenses _purl _coverage; do + printf '| `%s` | `%s` | %s | `%s` | %s |\n' \ + "${name}" "${version}" "${type}" "${architecture}" "${licenses}" + done < "${index}" + printf '\n## License Texts\n\n' + emit_sections "${index}" "${license_root}" + } > "${temporary}" + + chmod 644 "${temporary}" + mv "${temporary}" "${output}" + cp "${index}" "${OUTPUT_DIR}/${INVENTORY_NAME}" + chmod 644 "${OUTPUT_DIR}/${INVENTORY_NAME}" +} + +report_gaps() { + local index="$1" license_root="$2" + local name version _type architecture licenses _purl _coverage + local missing=0 unknown=0 + + while IFS=$'\t' read -r name version _type architecture licenses _purl _coverage; do + [[ "${licenses}" =~ (^| / )(Unknown|NOASSERTION)( / |$) ]] \ + && unknown=$((unknown + 1)) + if ! directory_has_files "${license_root}/${name}/${version}/${architecture}"; then + missing=$((missing + 1)) + printf 'no license text for %s %s (%s)\n' \ + "${name}" "${version}" "${architecture}" >&2 + fi + done < "${index}" + + (( unknown == 0 )) || warn "Syft reported an unknown license for ${unknown} component(s)." + (( missing == 0 )) \ + || warn "${missing} of $(wc -l < "${index}" | tr -d ' ') components have no license text." +} + +main() { + local records raw_inventory package_keys ownership source_map staged_content + local license_root index + local command + + for command in "${SYFT}" "${JQ}" base64 curl awk sort grep find mktemp sha256sum; do + require_command "${command}" + done + check_boolean TPN_SYFT_ALL_CATALOGERS "${TPN_SYFT_ALL_CATALOGERS}" + check_boolean TPN_RECOVER_ARCHIVES "${TPN_RECOVER_ARCHIVES}" + check_boolean TPN_FETCH_UPSTREAM "${TPN_FETCH_UPSTREAM}" + check_boolean TPN_STRICT "${TPN_STRICT}" + + detect_distribution + detect_architecture + PLATFORM="linux/${ARCHITECTURE}" + DRIVER_LABEL="${DRIVER_VERSION:-unknown}" + + WORK_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/in-image-tpn.XXXXXX")" + records="${WORK_ROOT}/syft-records.tsv" + raw_inventory="${WORK_ROOT}/inventory.tsv" + package_keys="${WORK_ROOT}/packages.tsv" + ownership="${WORK_ROOT}/ownership.tsv" + source_map="${WORK_ROOT}/source-map.tsv" + staged_content="${WORK_ROOT}/syft-license-content" + license_root="${WORK_ROOT}/licenses" + index="${WORK_ROOT}/index.tsv" + mkdir -p "${license_root}" "${staged_content}" "${OUTPUT_DIR}" + + scan_rootfs "${records}" + process_syft_records \ + "${records}" "${raw_inventory}" "${package_keys}" "${ownership}" \ + "${source_map}" "${staged_content}" + [[ -s "${package_keys}" ]] \ + || die "Syft found no RPM/DEB packages in the final root filesystem." + if [[ "${DRIVER_TYPE:-passthrough}" == vgpu ]]; then + validate_vgpu_binary_modules "${raw_inventory}" + fi + + collect_image_licenses \ + "${DISTRIBUTION}" "${ownership}" "${license_root}" "${raw_inventory}" + apply_syft_license_content "${raw_inventory}" "${staged_content}" "${license_root}" + if [[ "${DRIVER_TYPE:-passthrough}" == vgpu ]]; then + collect_vgpu_additional_notices "${raw_inventory}" "${license_root}" + fi + + # Resolve cross-package symlinks before archive recovery so only packages + # that genuinely still lack text are downloaded. + recover_license_text_from_siblings \ + "${raw_inventory}" "${license_root}" "${source_map}" + recover_missing_package_licenses \ + "${DISTRIBUTION}" "${package_keys}" "${license_root}" + + # An archive may provide the first usable text for a source-package family. + recover_license_text_from_siblings \ + "${raw_inventory}" "${license_root}" "${source_map}" + collapse_inventory "${raw_inventory}" > "${index}" + [[ -s "${index}" ]] || die "Syft produced an empty component index." + + report_gaps "${index}" "${license_root}" + compose_document "${index}" "${license_root}" + + log "Wrote ${OUTPUT_DIR}/${DOCUMENT_NAME} covering $(wc -l < "${index}" | tr -d ' ') components." + if (( WARNINGS > 0 )); then + if [[ "${TPN_STRICT}" == 1 ]]; then + die "${WARNINGS} warning(s) were raised and TPN_STRICT=1." + fi + log "${WARNINGS} warning(s) were raised; set TPN_STRICT=1 to treat these as fatal." + fi +} + +if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then + main "$@" +fi From a90dce0a90c9d5ef1dd55aec0fe8dbe2e1d206b5 Mon Sep 17 00:00:00 2001 From: Aryan Gorwade Date: Fri, 28 Aug 2026 18:17:27 -0700 Subject: [PATCH 2/7] Add TPN generation to base ubuntu Signed-off-by: Aryan Gorwade --- ubuntu22.04/Dockerfile | 32 ++++++++++++++++++++++++++------ ubuntu24.04/Dockerfile | 32 ++++++++++++++++++++++++++------ ubuntu26.04/Dockerfile | 32 ++++++++++++++++++++++++++------ 3 files changed, 78 insertions(+), 18 deletions(-) diff --git a/ubuntu22.04/Dockerfile b/ubuntu22.04/Dockerfile index 4adb77be3..19d23f79d 100644 --- a/ubuntu22.04/Dockerfile +++ b/ubuntu22.04/Dockerfile @@ -1,5 +1,8 @@ ARG BASE_IMAGE=ubuntu:jammy-20260731.1 +FROM anchore/syft:v1.51.1 AS syft +FROM ghcr.io/jqlang/jq:1.8.2 AS jq + FROM ${BASE_IMAGE} AS build ARG TARGETARCH @@ -34,13 +37,12 @@ ENV PATH=/usr/local/go/bin:$PATH WORKDIR /work -RUN if [ "$DRIVER_TYPE" = "vgpu" ]; then \ - git clone https://github.com/NVIDIA/gpu-driver-container driver && \ - cd driver/vgpu/src && \ - go build -o vgpu-util && \ - mv vgpu-util /work; fi +RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ + cp driver/scripts/generate-in-image-tpn.sh /work/generate-in-image-tpn.sh && \ + if [ "$DRIVER_TYPE" = "vgpu" ]; then \ + (cd driver/vgpu/src && go build -o /work/vgpu-util); fi -FROM ${BASE_IMAGE} +FROM ${BASE_IMAGE} AS runtime SHELL ["/bin/bash", "-c"] @@ -118,3 +120,21 @@ LABEL summary="Provision the NVIDIA driver through containers" LABEL description="See summary" ENTRYPOINT ["nvidia-driver", "init"] + +# Generate third-party notices from the completed runtime filesystem +FROM runtime AS tpn + +ARG GOLANG_VERSION + +COPY --from=syft /syft /tmp/tpn-tools/syft +COPY --from=jq /jq /tmp/tpn-tools/jq +COPY --from=build /work/generate-in-image-tpn.sh /tmp/generate-in-image-tpn.sh + +RUN PATH="/tmp/tpn-tools:${PATH}" \ + SYFT=/tmp/tpn-tools/syft \ + JQ=/tmp/tpn-tools/jq \ + bash /tmp/generate-in-image-tpn.sh /licenses + +FROM runtime + +COPY --from=tpn /licenses /licenses diff --git a/ubuntu24.04/Dockerfile b/ubuntu24.04/Dockerfile index e606fb792..4e78c1df8 100644 --- a/ubuntu24.04/Dockerfile +++ b/ubuntu24.04/Dockerfile @@ -1,5 +1,8 @@ ARG BASE_IMAGE=ubuntu:noble-20260730.1 +FROM anchore/syft:v1.51.1 AS syft +FROM ghcr.io/jqlang/jq:1.8.2 AS jq + FROM ${BASE_IMAGE} AS build ARG TARGETARCH @@ -36,13 +39,12 @@ ENV PATH=/usr/local/go/bin:$PATH WORKDIR /work -RUN if [ "$DRIVER_TYPE" = "vgpu" ]; then \ - git clone https://github.com/NVIDIA/gpu-driver-container driver && \ - cd driver/vgpu/src && \ - go build -o vgpu-util && \ - mv vgpu-util /work; fi +RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ + cp driver/scripts/generate-in-image-tpn.sh /work/generate-in-image-tpn.sh && \ + if [ "$DRIVER_TYPE" = "vgpu" ]; then \ + (cd driver/vgpu/src && go build -o /work/vgpu-util); fi -FROM ${BASE_IMAGE} +FROM ${BASE_IMAGE} AS runtime SHELL ["/bin/bash", "-c"] @@ -107,3 +109,21 @@ LABEL summary="Provision the NVIDIA driver through containers" LABEL description="See summary" ENTRYPOINT ["nvidia-driver", "init"] + +# Generate third-party notices from the completed runtime filesystem +FROM runtime AS tpn + +ARG GOLANG_VERSION + +COPY --from=syft /syft /tmp/tpn-tools/syft +COPY --from=jq /jq /tmp/tpn-tools/jq +COPY --from=build /work/generate-in-image-tpn.sh /tmp/generate-in-image-tpn.sh + +RUN PATH="/tmp/tpn-tools:${PATH}" \ + SYFT=/tmp/tpn-tools/syft \ + JQ=/tmp/tpn-tools/jq \ + bash /tmp/generate-in-image-tpn.sh /licenses + +FROM runtime + +COPY --from=tpn /licenses /licenses diff --git a/ubuntu26.04/Dockerfile b/ubuntu26.04/Dockerfile index b4825cef3..555bfcf0d 100644 --- a/ubuntu26.04/Dockerfile +++ b/ubuntu26.04/Dockerfile @@ -1,5 +1,8 @@ ARG BASE_IMAGE=ubuntu:resolute-20260724.1 +FROM anchore/syft:v1.51.1 AS syft +FROM ghcr.io/jqlang/jq:1.8.2 AS jq + FROM ${BASE_IMAGE} AS build ARG TARGETARCH @@ -31,13 +34,12 @@ ENV PATH=/usr/local/go/bin:$PATH WORKDIR /work -RUN if [ "$DRIVER_TYPE" = "vgpu" ]; then \ - git clone https://github.com/NVIDIA/gpu-driver-container driver && \ - cd driver/vgpu/src && \ - go build -o vgpu-util && \ - mv vgpu-util /work; fi +RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ + cp driver/scripts/generate-in-image-tpn.sh /work/generate-in-image-tpn.sh && \ + if [ "$DRIVER_TYPE" = "vgpu" ]; then \ + (cd driver/vgpu/src && go build -o /work/vgpu-util); fi -FROM ${BASE_IMAGE} +FROM ${BASE_IMAGE} AS runtime SHELL ["/bin/bash", "-c"] @@ -98,3 +100,21 @@ LABEL summary="Provision the NVIDIA driver through containers" LABEL description="See summary" ENTRYPOINT ["nvidia-driver", "init"] + +# Generate third-party notices from the completed runtime filesystem +FROM runtime AS tpn + +ARG GOLANG_VERSION + +COPY --from=syft /syft /tmp/tpn-tools/syft +COPY --from=jq /jq /tmp/tpn-tools/jq +COPY --from=build /work/generate-in-image-tpn.sh /tmp/generate-in-image-tpn.sh + +RUN PATH="/tmp/tpn-tools:${PATH}" \ + SYFT=/tmp/tpn-tools/syft \ + JQ=/tmp/tpn-tools/jq \ + bash /tmp/generate-in-image-tpn.sh /licenses + +FROM runtime + +COPY --from=tpn /licenses /licenses From a013e553ed1431a65c0d47c97910332133f7c77c Mon Sep 17 00:00:00 2001 From: Aryan Gorwade Date: Fri, 28 Aug 2026 18:24:06 -0700 Subject: [PATCH 3/7] Added TPN generation to base rhel images Signed-off-by: Aryan Gorwade --- rhel10/Dockerfile | 32 ++++++++++++++++++++++++++------ rhel8/Dockerfile | 33 +++++++++++++++++++++++++++------ rhel9/Dockerfile | 33 +++++++++++++++++++++++++++------ 3 files changed, 80 insertions(+), 18 deletions(-) diff --git a/rhel10/Dockerfile b/rhel10/Dockerfile index b11e2fb01..b85dba7ac 100644 --- a/rhel10/Dockerfile +++ b/rhel10/Dockerfile @@ -1,5 +1,8 @@ ARG BASE_IMAGE=registry.access.redhat.com/ubi10/ubi:10.2-1786960026 +FROM anchore/syft:v1.51.1 AS syft +FROM ghcr.io/jqlang/jq:1.8.2 AS jq + FROM ${BASE_IMAGE} as build ARG TARGETARCH @@ -22,13 +25,12 @@ ENV PATH /usr/local/go/bin:$PATH WORKDIR /work -RUN if [ "$DRIVER_TYPE" = "vgpu" ]; then \ - git clone https://github.com/NVIDIA/gpu-driver-container driver && \ - cd driver/vgpu/src && \ - go build -o vgpu-util && \ - mv vgpu-util /work; fi +RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ + cp driver/scripts/generate-in-image-tpn.sh /work/generate-in-image-tpn.sh && \ + if [ "$DRIVER_TYPE" = "vgpu" ]; then \ + (cd driver/vgpu/src && go build -o /work/vgpu-util); fi -FROM ${BASE_IMAGE} +FROM ${BASE_IMAGE} AS runtime ARG TARGETARCH ENV TARGETARCH=$TARGETARCH @@ -116,3 +118,21 @@ RUN if [ -n "${CVE_UPDATES}" ]; then \ RUN rm -f /etc/yum.repos.d/cuda.repo ENTRYPOINT ["nvidia-driver", "init"] + +# Generate third-party notices from the completed runtime filesystem +FROM runtime AS tpn + +ARG GOLANG_VERSION + +COPY --from=syft /syft /tmp/tpn-tools/syft +COPY --from=jq /jq /tmp/tpn-tools/jq +COPY --from=build /work/generate-in-image-tpn.sh /tmp/generate-in-image-tpn.sh + +RUN PATH="/tmp/tpn-tools:${PATH}" \ + SYFT=/tmp/tpn-tools/syft \ + JQ=/tmp/tpn-tools/jq \ + bash /tmp/generate-in-image-tpn.sh /licenses + +FROM runtime + +COPY --from=tpn /licenses /licenses diff --git a/rhel8/Dockerfile b/rhel8/Dockerfile index 967c7333b..45e087119 100644 --- a/rhel8/Dockerfile +++ b/rhel8/Dockerfile @@ -1,4 +1,8 @@ ARG BASE_IMAGE=registry.access.redhat.com/ubi8/ubi:8.10-1786654249 + +FROM anchore/syft:v1.51.1 AS syft +FROM ghcr.io/jqlang/jq:1.8.2 AS jq + FROM ${BASE_IMAGE} as build ARG TARGETARCH @@ -21,13 +25,12 @@ ENV PATH /usr/local/go/bin:$PATH WORKDIR /work -RUN if [ "$DRIVER_TYPE" = "vgpu" ]; then \ - git clone https://github.com/NVIDIA/gpu-driver-container driver && \ - cd driver/vgpu/src && \ - go build -o vgpu-util && \ - mv vgpu-util /work; fi +RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ + cp driver/scripts/generate-in-image-tpn.sh /work/generate-in-image-tpn.sh && \ + if [ "$DRIVER_TYPE" = "vgpu" ]; then \ + (cd driver/vgpu/src && go build -o /work/vgpu-util); fi -FROM ${BASE_IMAGE} +FROM ${BASE_IMAGE} AS runtime ARG TARGETARCH ENV TARGETARCH=$TARGETARCH @@ -114,3 +117,21 @@ RUN if [ -n "${CVE_UPDATES}" ]; then \ RUN rm -f /etc/yum.repos.d/cuda.repo ENTRYPOINT ["nvidia-driver", "init"] + +# Generate third-party notices from the completed runtime filesystem +FROM runtime AS tpn + +ARG GOLANG_VERSION + +COPY --from=syft /syft /tmp/tpn-tools/syft +COPY --from=jq /jq /tmp/tpn-tools/jq +COPY --from=build /work/generate-in-image-tpn.sh /tmp/generate-in-image-tpn.sh + +RUN PATH="/tmp/tpn-tools:${PATH}" \ + SYFT=/tmp/tpn-tools/syft \ + JQ=/tmp/tpn-tools/jq \ + bash /tmp/generate-in-image-tpn.sh /licenses + +FROM runtime + +COPY --from=tpn /licenses /licenses diff --git a/rhel9/Dockerfile b/rhel9/Dockerfile index 8fb288ce1..f297a593a 100644 --- a/rhel9/Dockerfile +++ b/rhel9/Dockerfile @@ -1,4 +1,8 @@ ARG BASE_IMAGE=registry.access.redhat.com/ubi9/ubi:9.8-1786957459 + +FROM anchore/syft:v1.51.1 AS syft +FROM ghcr.io/jqlang/jq:1.8.2 AS jq + FROM ${BASE_IMAGE} as build ARG TARGETARCH @@ -21,13 +25,12 @@ ENV PATH /usr/local/go/bin:$PATH WORKDIR /work -RUN if [ "$DRIVER_TYPE" = "vgpu" ]; then \ - git clone https://github.com/NVIDIA/gpu-driver-container driver && \ - cd driver/vgpu/src && \ - go build -o vgpu-util && \ - mv vgpu-util /work; fi +RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ + cp driver/scripts/generate-in-image-tpn.sh /work/generate-in-image-tpn.sh && \ + if [ "$DRIVER_TYPE" = "vgpu" ]; then \ + (cd driver/vgpu/src && go build -o /work/vgpu-util); fi -FROM ${BASE_IMAGE} +FROM ${BASE_IMAGE} AS runtime ARG TARGETARCH ENV TARGETARCH=$TARGETARCH @@ -115,3 +118,21 @@ RUN if [ -n "${CVE_UPDATES}" ]; then \ RUN rm -f /etc/yum.repos.d/cuda.repo ENTRYPOINT ["nvidia-driver", "init"] + +# Generate third-party notices from the completed runtime filesystem +FROM runtime AS tpn + +ARG GOLANG_VERSION + +COPY --from=syft /syft /tmp/tpn-tools/syft +COPY --from=jq /jq /tmp/tpn-tools/jq +COPY --from=build /work/generate-in-image-tpn.sh /tmp/generate-in-image-tpn.sh + +RUN PATH="/tmp/tpn-tools:${PATH}" \ + SYFT=/tmp/tpn-tools/syft \ + JQ=/tmp/tpn-tools/jq \ + bash /tmp/generate-in-image-tpn.sh /licenses + +FROM runtime + +COPY --from=tpn /licenses /licenses From cf6e41e5a5f427a5f7657d8efb5a0a5a4a508bb5 Mon Sep 17 00:00:00 2001 From: Aryan Gorwade Date: Fri, 28 Aug 2026 18:41:38 -0700 Subject: [PATCH 4/7] Added TPN generation for precompiled ubuntu Signed-off-by: Aryan Gorwade --- ubuntu22.04/precompiled/Dockerfile | 29 ++++++++++++++++++++++++++++- ubuntu24.04/precompiled/Dockerfile | 30 +++++++++++++++++++++++++++++- ubuntu26.04/precompiled/Dockerfile | 30 +++++++++++++++++++++++++++++- 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/ubuntu22.04/precompiled/Dockerfile b/ubuntu22.04/precompiled/Dockerfile index 02ef76071..8a79c4a7a 100644 --- a/ubuntu22.04/precompiled/Dockerfile +++ b/ubuntu22.04/precompiled/Dockerfile @@ -1,6 +1,17 @@ ARG BASE_IMAGE=ubuntu:jammy-20260731.1 -FROM ${BASE_IMAGE} +FROM anchore/syft:v1.51.1 AS syft +FROM ghcr.io/jqlang/jq:1.8.2 AS jq + +FROM ${BASE_IMAGE} AS tpn-script + +RUN apt-get update && \ + apt-get install -y --no-install-recommends ca-certificates git && \ + git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ + cp driver/scripts/generate-in-image-tpn.sh /generate-in-image-tpn.sh && \ + rm -rf /var/lib/apt/lists/* + +FROM ${BASE_IMAGE} AS runtime ENV DEBIAN_FRONTEND=noninteractive @@ -81,3 +92,19 @@ LABEL summary="Provision the NVIDIA driver through containers" LABEL description="See summary" ENTRYPOINT ["nvidia-driver", "init"] + +# Generate third-party notices from the completed runtime filesystem +FROM runtime AS tpn + +COPY --from=syft /syft /tmp/tpn-tools/syft +COPY --from=jq /jq /tmp/tpn-tools/jq +COPY --from=tpn-script /generate-in-image-tpn.sh /tmp/generate-in-image-tpn.sh + +RUN PATH="/tmp/tpn-tools:${PATH}" \ + SYFT=/tmp/tpn-tools/syft \ + JQ=/tmp/tpn-tools/jq \ + bash /tmp/generate-in-image-tpn.sh /licenses + +FROM runtime + +COPY --from=tpn /licenses /licenses diff --git a/ubuntu24.04/precompiled/Dockerfile b/ubuntu24.04/precompiled/Dockerfile index 09eae71a2..6eb11ee5a 100644 --- a/ubuntu24.04/precompiled/Dockerfile +++ b/ubuntu24.04/precompiled/Dockerfile @@ -1,5 +1,17 @@ ARG BASE_IMAGE=ubuntu:noble-20260730.1 -FROM ${BASE_IMAGE} + +FROM anchore/syft:v1.51.1 AS syft +FROM ghcr.io/jqlang/jq:1.8.2 AS jq + +FROM ${BASE_IMAGE} AS tpn-script + +RUN apt-get update && \ + apt-get install -y --no-install-recommends ca-certificates git && \ + git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ + cp driver/scripts/generate-in-image-tpn.sh /generate-in-image-tpn.sh && \ + rm -rf /var/lib/apt/lists/* + +FROM ${BASE_IMAGE} AS runtime ENV DEBIAN_FRONTEND=noninteractive @@ -73,3 +85,19 @@ LABEL summary="Provision the NVIDIA driver through containers" LABEL description="See summary" ENTRYPOINT ["nvidia-driver", "init"] + +# Generate third-party notices from the completed runtime filesystem +FROM runtime AS tpn + +COPY --from=syft /syft /tmp/tpn-tools/syft +COPY --from=jq /jq /tmp/tpn-tools/jq +COPY --from=tpn-script /generate-in-image-tpn.sh /tmp/generate-in-image-tpn.sh + +RUN PATH="/tmp/tpn-tools:${PATH}" \ + SYFT=/tmp/tpn-tools/syft \ + JQ=/tmp/tpn-tools/jq \ + bash /tmp/generate-in-image-tpn.sh /licenses + +FROM runtime + +COPY --from=tpn /licenses /licenses diff --git a/ubuntu26.04/precompiled/Dockerfile b/ubuntu26.04/precompiled/Dockerfile index 77ceade14..0b018f66b 100644 --- a/ubuntu26.04/precompiled/Dockerfile +++ b/ubuntu26.04/precompiled/Dockerfile @@ -1,5 +1,17 @@ ARG BASE_IMAGE=ubuntu:resolute-20260724.1 -FROM ${BASE_IMAGE} + +FROM anchore/syft:v1.51.1 AS syft +FROM ghcr.io/jqlang/jq:1.8.2 AS jq + +FROM ${BASE_IMAGE} AS tpn-script + +RUN apt-get update && \ + apt-get install -y --no-install-recommends ca-certificates git && \ + git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ + cp driver/scripts/generate-in-image-tpn.sh /generate-in-image-tpn.sh && \ + rm -rf /var/lib/apt/lists/* + +FROM ${BASE_IMAGE} AS runtime ENV DEBIAN_FRONTEND=noninteractive @@ -70,3 +82,19 @@ LABEL summary="Provision the NVIDIA driver through containers" LABEL description="See summary" ENTRYPOINT ["nvidia-driver", "init"] + +# Generate third-party notices from the completed runtime filesystem +FROM runtime AS tpn + +COPY --from=syft /syft /tmp/tpn-tools/syft +COPY --from=jq /jq /tmp/tpn-tools/jq +COPY --from=tpn-script /generate-in-image-tpn.sh /tmp/generate-in-image-tpn.sh + +RUN PATH="/tmp/tpn-tools:${PATH}" \ + SYFT=/tmp/tpn-tools/syft \ + JQ=/tmp/tpn-tools/jq \ + bash /tmp/generate-in-image-tpn.sh /licenses + +FROM runtime + +COPY --from=tpn /licenses /licenses From 7ade92c2cb69d53051e558d3ed0d1d2bfcbef1ad Mon Sep 17 00:00:00 2001 From: Aryan Gorwade Date: Fri, 28 Aug 2026 18:49:04 -0700 Subject: [PATCH 5/7] Added TPN generation for precompiled rhel Signed-off-by: Aryan Gorwade --- rhel10/precompiled/Dockerfile | 24 +++++++++++++++++++++++- rhel8/precompiled/Dockerfile | 24 +++++++++++++++++++++++- rhel9/precompiled/Dockerfile | 24 +++++++++++++++++++++++- 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/rhel10/precompiled/Dockerfile b/rhel10/precompiled/Dockerfile index bae8a0e61..141344692 100644 --- a/rhel10/precompiled/Dockerfile +++ b/rhel10/precompiled/Dockerfile @@ -2,6 +2,9 @@ ARG DRIVER_TOOLKIT_IMAGE ARG CUDA_VERSION ARG CUDA_DIST +FROM anchore/syft:v1.51.1 AS syft +FROM ghcr.io/jqlang/jq:1.8.2 AS jq + FROM ${DRIVER_TOOLKIT_IMAGE} as builder ARG BASE_URL='https://us.download.nvidia.com/tesla' @@ -70,7 +73,10 @@ RUN export KVER=$(echo ${KERNEL_VERSION} | cut -d '-' -f 1) \ --define "driver_branch ${DRIVER_STREAM}" \ -v -bb SPECS/kmod-nvidia.spec -FROM nvcr.io/nvidia/cuda:${CUDA_VERSION}-base-${CUDA_DIST} +RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container gpu-driver-container && \ + cp gpu-driver-container/scripts/generate-in-image-tpn.sh /home/builder/generate-in-image-tpn.sh + +FROM nvcr.io/nvidia/cuda:${CUDA_VERSION}-base-${CUDA_DIST} AS runtime ARG BASE_URL='https://us.download.nvidia.com/tesla' @@ -205,3 +211,19 @@ RUN mkdir /licenses && mv /NGC-DL-CONTAINER-LICENSE /licenses/NGC-DL-CONTAINER-L RUN rm -f /etc/yum.repos.d/cuda.repo ENTRYPOINT ["nvidia-driver", "init"] + +# Generate third-party notices from the completed runtime filesystem +FROM runtime AS tpn + +COPY --from=syft /syft /tmp/tpn-tools/syft +COPY --from=jq /jq /tmp/tpn-tools/jq +COPY --from=builder /home/builder/generate-in-image-tpn.sh /tmp/generate-in-image-tpn.sh + +RUN PATH="/tmp/tpn-tools:${PATH}" \ + SYFT=/tmp/tpn-tools/syft \ + JQ=/tmp/tpn-tools/jq \ + bash /tmp/generate-in-image-tpn.sh /licenses + +FROM runtime + +COPY --from=tpn /licenses /licenses diff --git a/rhel8/precompiled/Dockerfile b/rhel8/precompiled/Dockerfile index 3d8d88b0b..f75b3bbf0 100644 --- a/rhel8/precompiled/Dockerfile +++ b/rhel8/precompiled/Dockerfile @@ -1,6 +1,9 @@ ARG DRIVER_TOOLKIT_IMAGE='' ARG CUDA_DIST='' +FROM anchore/syft:v1.51.1 AS syft +FROM ghcr.io/jqlang/jq:1.8.2 AS jq + FROM ${DRIVER_TOOLKIT_IMAGE} as builder ARG BASE_URL='https://us.download.nvidia.com/tesla' @@ -53,7 +56,10 @@ RUN export KVER=$(echo ${KERNEL_VERSION} | cut -d '-' -f 1) \ --define "driver_branch ${DRIVER_STREAM}" \ -v -bb SPECS/kmod-nvidia.spec -FROM nvcr.io/nvidia/cuda:12.6.2-base-${CUDA_DIST} +RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container gpu-driver-container && \ + cp gpu-driver-container/scripts/generate-in-image-tpn.sh /home/builder/generate-in-image-tpn.sh + +FROM nvcr.io/nvidia/cuda:12.6.2-base-${CUDA_DIST} AS runtime ARG KERNEL_VERSION='' ARG RHEL_VERSION='' @@ -160,3 +166,19 @@ RUN mkdir /licenses && mv /NGC-DL-CONTAINER-LICENSE /licenses/NGC-DL-CONTAINER-L RUN rm -f /etc/yum.repos.d/cuda.repo ENTRYPOINT ["nvidia-driver", "init"] + +# Generate third-party notices from the completed runtime filesystem +FROM runtime AS tpn + +COPY --from=syft /syft /tmp/tpn-tools/syft +COPY --from=jq /jq /tmp/tpn-tools/jq +COPY --from=builder /home/builder/generate-in-image-tpn.sh /tmp/generate-in-image-tpn.sh + +RUN PATH="/tmp/tpn-tools:${PATH}" \ + SYFT=/tmp/tpn-tools/syft \ + JQ=/tmp/tpn-tools/jq \ + bash /tmp/generate-in-image-tpn.sh /licenses + +FROM runtime + +COPY --from=tpn /licenses /licenses diff --git a/rhel9/precompiled/Dockerfile b/rhel9/precompiled/Dockerfile index bae8a0e61..141344692 100644 --- a/rhel9/precompiled/Dockerfile +++ b/rhel9/precompiled/Dockerfile @@ -2,6 +2,9 @@ ARG DRIVER_TOOLKIT_IMAGE ARG CUDA_VERSION ARG CUDA_DIST +FROM anchore/syft:v1.51.1 AS syft +FROM ghcr.io/jqlang/jq:1.8.2 AS jq + FROM ${DRIVER_TOOLKIT_IMAGE} as builder ARG BASE_URL='https://us.download.nvidia.com/tesla' @@ -70,7 +73,10 @@ RUN export KVER=$(echo ${KERNEL_VERSION} | cut -d '-' -f 1) \ --define "driver_branch ${DRIVER_STREAM}" \ -v -bb SPECS/kmod-nvidia.spec -FROM nvcr.io/nvidia/cuda:${CUDA_VERSION}-base-${CUDA_DIST} +RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container gpu-driver-container && \ + cp gpu-driver-container/scripts/generate-in-image-tpn.sh /home/builder/generate-in-image-tpn.sh + +FROM nvcr.io/nvidia/cuda:${CUDA_VERSION}-base-${CUDA_DIST} AS runtime ARG BASE_URL='https://us.download.nvidia.com/tesla' @@ -205,3 +211,19 @@ RUN mkdir /licenses && mv /NGC-DL-CONTAINER-LICENSE /licenses/NGC-DL-CONTAINER-L RUN rm -f /etc/yum.repos.d/cuda.repo ENTRYPOINT ["nvidia-driver", "init"] + +# Generate third-party notices from the completed runtime filesystem +FROM runtime AS tpn + +COPY --from=syft /syft /tmp/tpn-tools/syft +COPY --from=jq /jq /tmp/tpn-tools/jq +COPY --from=builder /home/builder/generate-in-image-tpn.sh /tmp/generate-in-image-tpn.sh + +RUN PATH="/tmp/tpn-tools:${PATH}" \ + SYFT=/tmp/tpn-tools/syft \ + JQ=/tmp/tpn-tools/jq \ + bash /tmp/generate-in-image-tpn.sh /licenses + +FROM runtime + +COPY --from=tpn /licenses /licenses From 5ec5d6bd6b4316b034f10c5a9b7ec7d3c902b97e Mon Sep 17 00:00:00 2001 From: Aryan Gorwade Date: Fri, 28 Aug 2026 20:50:10 -0700 Subject: [PATCH 6/7] Pointed repo cloning during build to my branch for demonstration Signed-off-by: Aryan Gorwade --- rhel10/Dockerfile | 2 +- rhel10/precompiled/Dockerfile | 2 +- rhel8/Dockerfile | 2 +- rhel8/precompiled/Dockerfile | 2 +- rhel9/Dockerfile | 2 +- rhel9/precompiled/Dockerfile | 2 +- ubuntu22.04/Dockerfile | 2 +- ubuntu22.04/precompiled/Dockerfile | 2 +- ubuntu24.04/Dockerfile | 2 +- ubuntu24.04/precompiled/Dockerfile | 2 +- ubuntu26.04/Dockerfile | 2 +- ubuntu26.04/precompiled/Dockerfile | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/rhel10/Dockerfile b/rhel10/Dockerfile index b85dba7ac..888d212df 100644 --- a/rhel10/Dockerfile +++ b/rhel10/Dockerfile @@ -25,7 +25,7 @@ ENV PATH /usr/local/go/bin:$PATH WORKDIR /work -RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ +RUN git clone --depth 1 -b dynamic-tpn-generation https://github.com/aryangorwade/gpu-driver-container driver && \ cp driver/scripts/generate-in-image-tpn.sh /work/generate-in-image-tpn.sh && \ if [ "$DRIVER_TYPE" = "vgpu" ]; then \ (cd driver/vgpu/src && go build -o /work/vgpu-util); fi diff --git a/rhel10/precompiled/Dockerfile b/rhel10/precompiled/Dockerfile index 141344692..bac984bea 100644 --- a/rhel10/precompiled/Dockerfile +++ b/rhel10/precompiled/Dockerfile @@ -73,7 +73,7 @@ RUN export KVER=$(echo ${KERNEL_VERSION} | cut -d '-' -f 1) \ --define "driver_branch ${DRIVER_STREAM}" \ -v -bb SPECS/kmod-nvidia.spec -RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container gpu-driver-container && \ +RUN git clone --depth 1 -b dynamic-tpn-generation https://github.com/aryangorwade/gpu-driver-container gpu-driver-container && \ cp gpu-driver-container/scripts/generate-in-image-tpn.sh /home/builder/generate-in-image-tpn.sh FROM nvcr.io/nvidia/cuda:${CUDA_VERSION}-base-${CUDA_DIST} AS runtime diff --git a/rhel8/Dockerfile b/rhel8/Dockerfile index 45e087119..852aca11c 100644 --- a/rhel8/Dockerfile +++ b/rhel8/Dockerfile @@ -25,7 +25,7 @@ ENV PATH /usr/local/go/bin:$PATH WORKDIR /work -RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ +RUN git clone --depth 1 -b dynamic-tpn-generation https://github.com/aryangorwade/gpu-driver-container driver && \ cp driver/scripts/generate-in-image-tpn.sh /work/generate-in-image-tpn.sh && \ if [ "$DRIVER_TYPE" = "vgpu" ]; then \ (cd driver/vgpu/src && go build -o /work/vgpu-util); fi diff --git a/rhel8/precompiled/Dockerfile b/rhel8/precompiled/Dockerfile index f75b3bbf0..955d2cda1 100644 --- a/rhel8/precompiled/Dockerfile +++ b/rhel8/precompiled/Dockerfile @@ -56,7 +56,7 @@ RUN export KVER=$(echo ${KERNEL_VERSION} | cut -d '-' -f 1) \ --define "driver_branch ${DRIVER_STREAM}" \ -v -bb SPECS/kmod-nvidia.spec -RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container gpu-driver-container && \ +RUN git clone --depth 1 -b dynamic-tpn-generation https://github.com/aryangorwade/gpu-driver-container gpu-driver-container && \ cp gpu-driver-container/scripts/generate-in-image-tpn.sh /home/builder/generate-in-image-tpn.sh FROM nvcr.io/nvidia/cuda:12.6.2-base-${CUDA_DIST} AS runtime diff --git a/rhel9/Dockerfile b/rhel9/Dockerfile index f297a593a..33c68c0a0 100644 --- a/rhel9/Dockerfile +++ b/rhel9/Dockerfile @@ -25,7 +25,7 @@ ENV PATH /usr/local/go/bin:$PATH WORKDIR /work -RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ +RUN git clone --depth 1 -b dynamic-tpn-generation https://github.com/aryangorwade/gpu-driver-container driver && \ cp driver/scripts/generate-in-image-tpn.sh /work/generate-in-image-tpn.sh && \ if [ "$DRIVER_TYPE" = "vgpu" ]; then \ (cd driver/vgpu/src && go build -o /work/vgpu-util); fi diff --git a/rhel9/precompiled/Dockerfile b/rhel9/precompiled/Dockerfile index 141344692..bac984bea 100644 --- a/rhel9/precompiled/Dockerfile +++ b/rhel9/precompiled/Dockerfile @@ -73,7 +73,7 @@ RUN export KVER=$(echo ${KERNEL_VERSION} | cut -d '-' -f 1) \ --define "driver_branch ${DRIVER_STREAM}" \ -v -bb SPECS/kmod-nvidia.spec -RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container gpu-driver-container && \ +RUN git clone --depth 1 -b dynamic-tpn-generation https://github.com/aryangorwade/gpu-driver-container gpu-driver-container && \ cp gpu-driver-container/scripts/generate-in-image-tpn.sh /home/builder/generate-in-image-tpn.sh FROM nvcr.io/nvidia/cuda:${CUDA_VERSION}-base-${CUDA_DIST} AS runtime diff --git a/ubuntu22.04/Dockerfile b/ubuntu22.04/Dockerfile index 19d23f79d..8276a2c1f 100644 --- a/ubuntu22.04/Dockerfile +++ b/ubuntu22.04/Dockerfile @@ -37,7 +37,7 @@ ENV PATH=/usr/local/go/bin:$PATH WORKDIR /work -RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ +RUN git clone --depth 1 -b dynamic-tpn-generation https://github.com/aryangorwade/gpu-driver-container driver && \ cp driver/scripts/generate-in-image-tpn.sh /work/generate-in-image-tpn.sh && \ if [ "$DRIVER_TYPE" = "vgpu" ]; then \ (cd driver/vgpu/src && go build -o /work/vgpu-util); fi diff --git a/ubuntu22.04/precompiled/Dockerfile b/ubuntu22.04/precompiled/Dockerfile index 8a79c4a7a..a28052f2a 100644 --- a/ubuntu22.04/precompiled/Dockerfile +++ b/ubuntu22.04/precompiled/Dockerfile @@ -7,7 +7,7 @@ FROM ${BASE_IMAGE} AS tpn-script RUN apt-get update && \ apt-get install -y --no-install-recommends ca-certificates git && \ - git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ + git clone --depth 1 -b dynamic-tpn-generation https://github.com/aryangorwade/gpu-driver-container driver && \ cp driver/scripts/generate-in-image-tpn.sh /generate-in-image-tpn.sh && \ rm -rf /var/lib/apt/lists/* diff --git a/ubuntu24.04/Dockerfile b/ubuntu24.04/Dockerfile index 4e78c1df8..6fe39d2fa 100644 --- a/ubuntu24.04/Dockerfile +++ b/ubuntu24.04/Dockerfile @@ -39,7 +39,7 @@ ENV PATH=/usr/local/go/bin:$PATH WORKDIR /work -RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ +RUN git clone --depth 1 -b dynamic-tpn-generation https://github.com/aryangorwade/gpu-driver-container driver && \ cp driver/scripts/generate-in-image-tpn.sh /work/generate-in-image-tpn.sh && \ if [ "$DRIVER_TYPE" = "vgpu" ]; then \ (cd driver/vgpu/src && go build -o /work/vgpu-util); fi diff --git a/ubuntu24.04/precompiled/Dockerfile b/ubuntu24.04/precompiled/Dockerfile index 6eb11ee5a..e54cbc959 100644 --- a/ubuntu24.04/precompiled/Dockerfile +++ b/ubuntu24.04/precompiled/Dockerfile @@ -7,7 +7,7 @@ FROM ${BASE_IMAGE} AS tpn-script RUN apt-get update && \ apt-get install -y --no-install-recommends ca-certificates git && \ - git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ + git clone --depth 1 -b dynamic-tpn-generation https://github.com/aryangorwade/gpu-driver-container driver && \ cp driver/scripts/generate-in-image-tpn.sh /generate-in-image-tpn.sh && \ rm -rf /var/lib/apt/lists/* diff --git a/ubuntu26.04/Dockerfile b/ubuntu26.04/Dockerfile index 555bfcf0d..06a58ffc4 100644 --- a/ubuntu26.04/Dockerfile +++ b/ubuntu26.04/Dockerfile @@ -34,7 +34,7 @@ ENV PATH=/usr/local/go/bin:$PATH WORKDIR /work -RUN git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ +RUN git clone --depth 1 -b dynamic-tpn-generation https://github.com/aryangorwade/gpu-driver-container driver && \ cp driver/scripts/generate-in-image-tpn.sh /work/generate-in-image-tpn.sh && \ if [ "$DRIVER_TYPE" = "vgpu" ]; then \ (cd driver/vgpu/src && go build -o /work/vgpu-util); fi diff --git a/ubuntu26.04/precompiled/Dockerfile b/ubuntu26.04/precompiled/Dockerfile index 0b018f66b..93b314573 100644 --- a/ubuntu26.04/precompiled/Dockerfile +++ b/ubuntu26.04/precompiled/Dockerfile @@ -7,7 +7,7 @@ FROM ${BASE_IMAGE} AS tpn-script RUN apt-get update && \ apt-get install -y --no-install-recommends ca-certificates git && \ - git clone --depth 1 https://github.com/NVIDIA/gpu-driver-container driver && \ + git clone --depth 1 -b dynamic-tpn-generation https://github.com/aryangorwade/gpu-driver-container driver && \ cp driver/scripts/generate-in-image-tpn.sh /generate-in-image-tpn.sh && \ rm -rf /var/lib/apt/lists/* From 089616a0c4eeddd5ac342576bc6a202db9569daf Mon Sep 17 00:00:00 2001 From: Aryan Gorwade Date: Fri, 28 Aug 2026 22:56:39 -0700 Subject: [PATCH 7/7] Update Syft version to avoid QEMU emulation issues Signed-off-by: Aryan Gorwade --- rhel10/Dockerfile | 2 +- rhel10/precompiled/Dockerfile | 2 +- rhel8/Dockerfile | 2 +- rhel8/precompiled/Dockerfile | 2 +- rhel9/Dockerfile | 2 +- rhel9/precompiled/Dockerfile | 2 +- ubuntu22.04/Dockerfile | 2 +- ubuntu22.04/precompiled/Dockerfile | 2 +- ubuntu24.04/Dockerfile | 2 +- ubuntu24.04/precompiled/Dockerfile | 2 +- ubuntu26.04/Dockerfile | 2 +- ubuntu26.04/precompiled/Dockerfile | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/rhel10/Dockerfile b/rhel10/Dockerfile index 888d212df..b88735cf9 100644 --- a/rhel10/Dockerfile +++ b/rhel10/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=registry.access.redhat.com/ubi10/ubi:10.2-1786960026 -FROM anchore/syft:v1.51.1 AS syft +FROM anchore/syft:v1.42.1 AS syft FROM ghcr.io/jqlang/jq:1.8.2 AS jq FROM ${BASE_IMAGE} as build diff --git a/rhel10/precompiled/Dockerfile b/rhel10/precompiled/Dockerfile index bac984bea..08e076371 100644 --- a/rhel10/precompiled/Dockerfile +++ b/rhel10/precompiled/Dockerfile @@ -2,7 +2,7 @@ ARG DRIVER_TOOLKIT_IMAGE ARG CUDA_VERSION ARG CUDA_DIST -FROM anchore/syft:v1.51.1 AS syft +FROM anchore/syft:v1.42.1 AS syft FROM ghcr.io/jqlang/jq:1.8.2 AS jq FROM ${DRIVER_TOOLKIT_IMAGE} as builder diff --git a/rhel8/Dockerfile b/rhel8/Dockerfile index 852aca11c..17a8f4419 100644 --- a/rhel8/Dockerfile +++ b/rhel8/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=registry.access.redhat.com/ubi8/ubi:8.10-1786654249 -FROM anchore/syft:v1.51.1 AS syft +FROM anchore/syft:v1.42.1 AS syft FROM ghcr.io/jqlang/jq:1.8.2 AS jq FROM ${BASE_IMAGE} as build diff --git a/rhel8/precompiled/Dockerfile b/rhel8/precompiled/Dockerfile index 955d2cda1..c62923906 100644 --- a/rhel8/precompiled/Dockerfile +++ b/rhel8/precompiled/Dockerfile @@ -1,7 +1,7 @@ ARG DRIVER_TOOLKIT_IMAGE='' ARG CUDA_DIST='' -FROM anchore/syft:v1.51.1 AS syft +FROM anchore/syft:v1.42.1 AS syft FROM ghcr.io/jqlang/jq:1.8.2 AS jq FROM ${DRIVER_TOOLKIT_IMAGE} as builder diff --git a/rhel9/Dockerfile b/rhel9/Dockerfile index 33c68c0a0..a43166432 100644 --- a/rhel9/Dockerfile +++ b/rhel9/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=registry.access.redhat.com/ubi9/ubi:9.8-1786957459 -FROM anchore/syft:v1.51.1 AS syft +FROM anchore/syft:v1.42.1 AS syft FROM ghcr.io/jqlang/jq:1.8.2 AS jq FROM ${BASE_IMAGE} as build diff --git a/rhel9/precompiled/Dockerfile b/rhel9/precompiled/Dockerfile index bac984bea..08e076371 100644 --- a/rhel9/precompiled/Dockerfile +++ b/rhel9/precompiled/Dockerfile @@ -2,7 +2,7 @@ ARG DRIVER_TOOLKIT_IMAGE ARG CUDA_VERSION ARG CUDA_DIST -FROM anchore/syft:v1.51.1 AS syft +FROM anchore/syft:v1.42.1 AS syft FROM ghcr.io/jqlang/jq:1.8.2 AS jq FROM ${DRIVER_TOOLKIT_IMAGE} as builder diff --git a/ubuntu22.04/Dockerfile b/ubuntu22.04/Dockerfile index 8276a2c1f..121b2fd59 100644 --- a/ubuntu22.04/Dockerfile +++ b/ubuntu22.04/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=ubuntu:jammy-20260731.1 -FROM anchore/syft:v1.51.1 AS syft +FROM anchore/syft:v1.42.1 AS syft FROM ghcr.io/jqlang/jq:1.8.2 AS jq FROM ${BASE_IMAGE} AS build diff --git a/ubuntu22.04/precompiled/Dockerfile b/ubuntu22.04/precompiled/Dockerfile index a28052f2a..465c1b62e 100644 --- a/ubuntu22.04/precompiled/Dockerfile +++ b/ubuntu22.04/precompiled/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=ubuntu:jammy-20260731.1 -FROM anchore/syft:v1.51.1 AS syft +FROM anchore/syft:v1.42.1 AS syft FROM ghcr.io/jqlang/jq:1.8.2 AS jq FROM ${BASE_IMAGE} AS tpn-script diff --git a/ubuntu24.04/Dockerfile b/ubuntu24.04/Dockerfile index 6fe39d2fa..07a1827f9 100644 --- a/ubuntu24.04/Dockerfile +++ b/ubuntu24.04/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=ubuntu:noble-20260730.1 -FROM anchore/syft:v1.51.1 AS syft +FROM anchore/syft:v1.42.1 AS syft FROM ghcr.io/jqlang/jq:1.8.2 AS jq FROM ${BASE_IMAGE} AS build diff --git a/ubuntu24.04/precompiled/Dockerfile b/ubuntu24.04/precompiled/Dockerfile index e54cbc959..8d33067ed 100644 --- a/ubuntu24.04/precompiled/Dockerfile +++ b/ubuntu24.04/precompiled/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=ubuntu:noble-20260730.1 -FROM anchore/syft:v1.51.1 AS syft +FROM anchore/syft:v1.42.1 AS syft FROM ghcr.io/jqlang/jq:1.8.2 AS jq FROM ${BASE_IMAGE} AS tpn-script diff --git a/ubuntu26.04/Dockerfile b/ubuntu26.04/Dockerfile index 06a58ffc4..bc07cc5ee 100644 --- a/ubuntu26.04/Dockerfile +++ b/ubuntu26.04/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=ubuntu:resolute-20260724.1 -FROM anchore/syft:v1.51.1 AS syft +FROM anchore/syft:v1.42.1 AS syft FROM ghcr.io/jqlang/jq:1.8.2 AS jq FROM ${BASE_IMAGE} AS build diff --git a/ubuntu26.04/precompiled/Dockerfile b/ubuntu26.04/precompiled/Dockerfile index 93b314573..c9b583b65 100644 --- a/ubuntu26.04/precompiled/Dockerfile +++ b/ubuntu26.04/precompiled/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=ubuntu:resolute-20260724.1 -FROM anchore/syft:v1.51.1 AS syft +FROM anchore/syft:v1.42.1 AS syft FROM ghcr.io/jqlang/jq:1.8.2 AS jq FROM ${BASE_IMAGE} AS tpn-script