# Copyright (c) 2021-2022, 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. include: - local: '.common-ci.yml' default: tags: - cnt - container-dev - docker/multi-arch - docker/privileged - os/linux - type/docker variables: DOCKER_DRIVER: overlay2 DOCKER_TLS_CERTDIR: "/certs" # Release "devel"-tagged images off the main branch RELEASE_DEVEL_BRANCH: "main" DEVEL_RELEASE_IMAGE_VERSION: "devel" # On the multi-arch builder we don't need the qemu setup. SKIP_QEMU_SETUP: "1" # Define the public staging registry STAGING_REGISTRY: ghcr.io/nvidia STAGING_VERSION: ${CI_COMMIT_SHORT_SHA} ARTIFACTORY_REPO_BASE: "https://urm.nvidia.com/artifactory/sw-gpu-cloudnative" KITMAKER_RELEASE_FOLDER: "kitmaker" PACKAGE_ARCHIVE_RELEASE_FOLDER: "releases" # .copy-images copies the required application and packaging images from the # IN_IMAGE="${IN_IMAGE_NAME}:${IN_IMAGE_TAG}${TAG_SUFFIX}" # to # OUT_IMAGE="${OUT_IMAGE_NAME}:${OUT_IMAGE_TAG}${TAG_SUFFIX}" # The script also logs into IN_REGISTRY and OUT_REGISTRY using the supplied # username and tokens. .copy-images: parallel: matrix: - TAG_SUFFIX: ["", "-packaging"] before_script: - !reference [.regctl-setup, before_script] - apk add --no-cache make bash variables: REGCTL: regctl script: - | if [ -n ${IN_REGISTRY} ] && [ -n ${IN_REGISTRY_USER} ]; then echo "Logging in to ${IN_REGISTRY}" ${REGCTL} registry login "${IN_REGISTRY}" -u "${IN_REGISTRY_USER}" -p "${IN_REGISTRY_TOKEN}" || exit 1 fi if [ -n ${OUT_REGISTRY} ] && [ -n ${OUT_REGISTRY_USER} ] && [ "${IN_REGISTRY}" != "${OUT_REGISTRY}" ]; then echo "Logging in to ${OUT_REGISTRY}" ${REGCTL} registry login "${OUT_REGISTRY}" -u "${OUT_REGISTRY_USER}" -p "${OUT_REGISTRY_TOKEN}" || exit 1 fi export IN_IMAGE="${IN_IMAGE_NAME}:${IN_IMAGE_TAG}${TAG_SUFFIX}" export OUT_IMAGE="${OUT_IMAGE_NAME}:${OUT_IMAGE_TAG}${TAG_SUFFIX}" echo "Copying ${IN_IMAGE} to ${OUT_IMAGE}" ${REGCTL} image copy ${IN_IMAGE} ${OUT_IMAGE} # pull-images pulls images from the public CI registry to the internal CI registry. pull-images: extends: - .copy-images stage: pull variables: IN_REGISTRY: "${STAGING_REGISTRY}" IN_IMAGE_NAME: ${STAGING_REGISTRY}/container-toolkit IN_IMAGE_TAG: "${STAGING_VERSION}" OUT_REGISTRY: "${CI_REGISTRY}" OUT_REGISTRY_USER: "${CI_REGISTRY_USER}" OUT_REGISTRY_TOKEN: "${CI_REGISTRY_PASSWORD}" OUT_IMAGE_NAME: "${CI_REGISTRY_IMAGE}/container-toolkit" OUT_IMAGE_TAG: "${CI_COMMIT_SHORT_SHA}" # We delay the job start to allow the public pipeline to generate the required images. rules: # If the pipeline is triggered from a tag or the WEB UI we don't delay the # start of the pipeline. - if: $CI_COMMIT_TAG || $CI_PIPELINE_SOURCE == "web" # If the pipeline is triggered through other means (i.e. a branch or MR) # we add a 30 minute delay to ensure that the images are available in the # public CI registry. - when: delayed start_in: 30 minutes timeout: 30 minutes retry: max: 2 when: - job_execution_timeout - stuck_or_timeout_failure # We skip the integration tests for the internal CI: .integration: stage: test before_script: - echo "Skipped in internal CI" script: - echo "Skipped in internal CI" # The .scan step forms the base of the image scan operation performed before releasing # images. scan-images: stage: scan needs: - pull-images image: "${PULSE_IMAGE}" parallel: matrix: - TAG_SUFFIX: [""] PLATFORM: ["linux/amd64", "linux/arm64"] - TAG_SUFFIX: "-packaging" PLATFORM: "linux/amd64" variables: IMAGE: "${CI_REGISTRY_IMAGE}/container-toolkit:${CI_COMMIT_SHORT_SHA}" IMAGE_ARCHIVE: "container-toolkit-${CI_JOB_ID}.tar" rules: - if: $IGNORE_SCANS == "yes" allow_failure: true - when: on_success script: - | docker login -u "${CI_REGISTRY_USER}" -p "${CI_REGISTRY_PASSWORD}" "${CI_REGISTRY}" export SCAN_IMAGE=${IMAGE}${TAG_SUFFIX} echo "Scanning image ${SCAN_IMAGE} for ${PLATFORM}" docker pull --platform="${PLATFORM}" "${SCAN_IMAGE}" docker save "${SCAN_IMAGE}" -o "${IMAGE_ARCHIVE}" AuthHeader=$(echo -n $SSA_CLIENT_ID:$SSA_CLIENT_SECRET | base64 -w0) export SSA_TOKEN=$(curl --request POST --header "Authorization: Basic $AuthHeader" --header "Content-Type: application/x-www-form-urlencoded" ${SSA_ISSUER_URL} | jq ".access_token" | tr -d '"') if [ -z "$SSA_TOKEN" ]; then exit 1; else echo "SSA_TOKEN set!"; fi pulse-cli -n $NSPECT_ID --ssa $SSA_TOKEN scan -i $IMAGE_ARCHIVE -p $CONTAINER_POLICY -o rm -f "${IMAGE_ARCHIVE}" artifacts: when: always expire_in: 1 week paths: - pulse-cli.log - licenses.json - sbom.json - vulns.json - policy_evaluation.json upload-kitmaker-packages: stage: release needs: - pull-images variables: VERSION: "${CI_COMMIT_SHORT_SHA}" PACKAGE_REGISTRY: "${CI_REGISTRY}" PACKAGE_REGISTRY_USER: "${CI_REGISTRY_USER}" PACKAGE_REGISTRY_TOKEN: "${CI_REGISTRY_PASSWORD}" PACKAGE_IMAGE_NAME: "${CI_REGISTRY_IMAGE}/container-toolkit" PACKAGE_IMAGE_TAG: "${CI_COMMIT_SHORT_SHA}-packaging" KITMAKER_ARTIFACTORY_REPO: "${ARTIFACTORY_REPO_BASE}-generic-local/${KITMAKER_RELEASE_FOLDER}" ARTIFACTS_DIR: "${CI_PROJECT_DIR}/artifacts" script: - !reference [.regctl-setup, before_script] - apk add --no-cache bash git - regctl registry login "${PACKAGE_REGISTRY}" -u "${PACKAGE_REGISTRY_USER}" -p "${PACKAGE_REGISTRY_TOKEN}" - ./scripts/extract-packages.sh "${PACKAGE_IMAGE_NAME}:${PACKAGE_IMAGE_TAG}" - ./scripts/release-kitmaker-artifactory.sh "${KITMAKER_ARTIFACTORY_REPO}" - rm -rf ${ARTIFACTS_DIR} push-images-to-staging: extends: - .copy-images stage: release needs: - scan-images variables: IN_REGISTRY: "${CI_REGISTRY}" IN_REGISTRY_USER: "${CI_REGISTRY_USER}" IN_REGISTRY_TOKEN: "${CI_REGISTRY_PASSWORD}" IN_IMAGE_NAME: "${CI_REGISTRY_IMAGE}/container-toolkit" IN_IMAGE_TAG: "${CI_COMMIT_SHORT_SHA}" OUT_REGISTRY: "${NGC_REGISTRY}" OUT_REGISTRY_USER: "${NGC_REGISTRY_USER}" OUT_REGISTRY_TOKEN: "${NGC_REGISTRY_TOKEN}" OUT_IMAGE_NAME: "${NGC_STAGING_REGISTRY}/container-toolkit" OUT_IMAGE_TAG: "${CI_COMMIT_SHORT_SHA}" .release-images: extends: - .copy-images stage: release needs: - scan-images - push-images-to-staging variables: IN_REGISTRY: "${CI_REGISTRY}" IN_REGISTRY_USER: "${CI_REGISTRY_USER}" IN_REGISTRY_TOKEN: "${CI_REGISTRY_PASSWORD}" IN_IMAGE_NAME: "${CI_REGISTRY_IMAGE}/container-toolkit" IN_IMAGE_TAG: "${CI_COMMIT_SHORT_SHA}" OUT_REGISTRY: "${NGC_REGISTRY}" OUT_REGISTRY_USER: "${NGC_REGISTRY_USER}" OUT_REGISTRY_TOKEN: "${NGC_REGISTRY_TOKEN}" OUT_IMAGE_NAME: "${NGC_REGISTRY_IMAGE}" OUT_IMAGE_TAG: "${CI_COMMIT_TAG}" release-images-to-ngc: extends: - .release-images rules: - if: $CI_COMMIT_TAG release-images-dummy: extends: - .release-images variables: REGCTL: "echo [DUMMY] regctl" rules: - if: $CI_COMMIT_TAG == null || $CI_COMMIT_TAG == "" # .sign-images forms the base of the jobs which sign images in the NGC registry. .sign-images: stage: sign image: ubuntu:latest parallel: matrix: - TAG_SUFFIX: ["", "-packaging"] variables: IMAGE_NAME: "${NGC_REGISTRY_IMAGE}" IMAGE_TAG: "${CI_COMMIT_TAG}" NGC_CLI: "ngc-cli/ngc" before_script: - !reference [.ngccli-setup, before_script] script: - | # We ensure that the IMAGE_NAME and IMAGE_TAG is set echo Image Name: ${IMAGE_NAME} && [[ -n "${IMAGE_NAME}" ]] || exit 1 echo Image Tag: ${IMAGE_TAG} && [[ -n "${IMAGE_TAG}" ]] || exit 1 export IMAGE=${IMAGE_NAME}:${IMAGE_TAG}${TAG_SUFFIX} echo "Signing the image ${IMAGE}" ${NGC_CLI} registry image publish --source ${IMAGE} ${IMAGE} --public --discoverable --allow-guest --sign --org nvidia # Define the external image signing steps for NGC # Download the ngc cli binary for use in the sign steps .ngccli-setup: before_script: - apt-get update && apt-get install -y curl unzip jq - | if [ -z "${NGCCLI_VERSION}" ]; then NGC_VERSION_URL="https://api.ngc.nvidia.com/v2/resources/nvidia/ngc-apps/ngc_cli/versions" # Extract the latest version from the JSON data using jq export NGCCLI_VERSION=$(curl -s $NGC_VERSION_URL | jq -r '.recipe.latestVersionIdStr') fi echo "NGCCLI_VERSION ${NGCCLI_VERSION}" - curl -sSLo ngccli_linux.zip https://api.ngc.nvidia.com/v2/resources/nvidia/ngc-apps/ngc_cli/versions/${NGCCLI_VERSION}/files/ngccli_linux.zip - unzip ngccli_linux.zip - chmod u+x ngc-cli/ngc sign-ngc-images: extends: - .sign-images needs: - release-images-to-ngc rules: - if: $CI_COMMIT_TAG variables: NGC_CLI_API_KEY: "${NGC_REGISTRY_TOKEN}" retry: max: 2 sign-images-dummy: extends: - .sign-images needs: - release-images-dummy variables: NGC_CLI: "echo [DUMMY] ngc-cli/ngc" IMAGE_TAG: "${CI_COMMIT_SHORT_SHA}" rules: - if: $CI_COMMIT_TAG == null || $CI_COMMIT_TAG == ""