diff --git a/.github/actions/certify-openshift-image/action.yml b/.github/actions/certify-openshift-image/action.yml new file mode 100644 index 0000000000..f9d423210c --- /dev/null +++ b/.github/actions/certify-openshift-image/action.yml @@ -0,0 +1,57 @@ +name: Certify Openshift Image +description: This action will attempt to certify an image for use in Openshift + +inputs: + image: + description: The image manifest to certify in the format /: + required: true + project_id: + description: The certification project id + required: true + pyxis_token: + description: The Pyxis API Token + required: true + preflight_version: + description: The version of the preflight utility to install + required: false + default: 1.9.1 + platforms: + description: A comma separated list of architectures in the image manifest to certify + required: false + default: "" + +outputs: + result: + description: Did the certification succeed? + value: ${{ steps.result.outputs.result == 0 && true || false }} + +runs: + using: composite + steps: + - name: Install openshift-preflight + run: | + curl -fsSL https://github.com/redhat-openshift-ecosystem/openshift-preflight/releases/download/${{ inputs.preflight_version }}/preflight-linux-amd64 --output preflight + chmod +x preflight + shell: bash + + - name: Certify Images + id: result + run: | + result=0 + if [ -z "${{ inputs.platforms }}" ]; then + # list of platforms passed + IFS=',' read -ra arch_list <<< "${{ inputs.platforms }}" + for arch in "${arch_list[@]}"; do + architecture=("${arch#*/}") + ./preflight check container ${{ inputs.image }} --pyxis-api-token ${{ inputs.pyxis_token }} --certification-project-id ${{ inputs.project_id }} --platform $architecture --submit + if [ $? -ne 0 ]; then + result=1 + fi + done + else + # no platforms passed, this is either a manifest or a single platform image + ./preflight check container ${{ inputs.image }} --pyxis-api-token ${{ inputs.pyxis_token }} --certification-project-id ${{ inputs.project_id }} --submit + result=$? + fi + echo "result=$result" >> $GITHUB_OUTPUT + shell: bash diff --git a/.github/workflows/patch-image.yml b/.github/workflows/patch-image.yml new file mode 100644 index 0000000000..44025679d5 --- /dev/null +++ b/.github/workflows/patch-image.yml @@ -0,0 +1,84 @@ +name: Patch Docker Image + +on: + workflow_call: + inputs: + image: + description: The image name to patch + required: true + type: string + target_image: + description: The target name of the patched image + required: true + type: string + tag: + description: The image tag to patch + required: true + type: string + target_tag: + description: The target tag of the patched image + required: true + type: string + ic_version: + description: The IC version to label + required: true + type: string + platforms: + description: The platforms to patch + required: true + type: string + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + patch-image: + name: Patch image + runs-on: ubuntu-22.04 + permissions: + contents: read + id-token: write + steps: + - name: Checkout Repository + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Docker Buildx + uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0 + + - name: Setup QEMU + uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 + with: + platforms: arm,arm64,ppc64le,s390x + + - name: Authenticate to Google Cloud + id: auth + uses: google-github-actions/auth@55bd3a7c6e2ae7cf1877fd1ccb9d54c0503c457c # v2.1.2 + with: + token_format: access_token + workload_identity_provider: ${{ secrets.GCR_WORKLOAD_IDENTITY }} + service_account: ${{ secrets.GCR_SERVICE_ACCOUNT }} + + - name: Login to GCR + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + with: + registry: gcr.io + username: oauth2accesstoken + password: ${{ steps.auth.outputs.access_token }} + + - name: Apply OS patches to Container + uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0 + with: + file: build/Dockerfile + context: "." + target: patched + tags: "${{ inputs.target_image }}:${{ inputs.target_tag }}" + platforms: ${{ inputs.platforms }} + pull: true + push: true + build-args: | + IMAGE_NAME=${{ inputs.image }}:${{ inputs.tag }} + IC_VERSION=${{ inputs.ic_version }} diff --git a/.github/workflows/update-docker-images.yml b/.github/workflows/update-docker-images.yml index 82466dd4ac..f496521dfd 100644 --- a/.github/workflows/update-docker-images.yml +++ b/.github/workflows/update-docker-images.yml @@ -2,13 +2,15 @@ name: Update Docker Images on: schedule: - - cron: "0 1 * * *" # run every day at 01:00 UTC + - cron: "0 1 * * 0" # run every week at 01:00 UTC on Sunday workflow_dispatch: inputs: - force: - description: "Force update of all images" - required: false - default: "false" + tag: + description: "Update images with tag" + required: true + dry_run: + type: boolean + default: false defaults: run: @@ -23,174 +25,328 @@ permissions: jobs: variables: - name: Get versions of base images + name: Set variables for workflow runs-on: ubuntu-22.04 outputs: - kic-tag: ${{ steps.kic.outputs.tag }} - versions: ${{ steps.versions.outputs.matrix }} - go-md5: ${{ steps.md5.outputs.go_code_md5 }} - binary-cache-hit: ${{ steps.binary-cache.outputs.cache-hit }} - base-image-md5: ${{ steps.md5.outputs.docker_md5 }} + tag: ${{ steps.kic.outputs.tag }} + short_tag: ${{ steps.kic.outputs.short }} + date: ${{ steps.kic.outputs.date }} steps: - name: Checkout Repository uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: 0 - - name: Set KIC version + - name: Set variables id: kic run: | tag="$(git tag --sort=-version:refname | head -n1)" - echo "tag=${tag//v}" >> $GITHUB_OUTPUT + if [ -n "${{ inputs.tag }}" ]; then + echo "tag=${{ inputs.tag }}" >> $GITHUB_OUTPUT + else + tag=${tag//v} + echo "tag=${tag//v}" >> $GITHUB_OUTPUT + fi + date=$(date "+%Y%m%d") + echo "date=${date}" >> $GITHUB_OUTPUT + short="${tag%.*}" + echo "short=$short" >> $GITHUB_OUTPUT + cat $GITHUB_OUTPUT - - name: Checkout Repository at ${{ steps.kic.outputs.tag }} - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - with: - ref: refs/tags/v${{ steps.kic.outputs.tag }} - - - name: Set NGINX versions - id: versions - run: | - nginx=library/$(grep -E "FROM nginx.*debian" < build/Dockerfile | awk -F" " '{print $2}' | cut -d '@' -f 1) - nginx_alpine=library/$(grep -E "FROM nginx.*alpine" < build/Dockerfile | awk -F" " '{print $2}' | cut -d '@' -f 1) - nginx_ubi=$(grep -m1 "FROM nginx.*ubi" < build/Dockerfile | awk -F" " '{print $2}' | cut -d '@' -f 1) - echo "matrix=[{\"version\": \"${nginx}\", \"distro\": \"debian\"}, {\"version\": \"${nginx_alpine}\", \"distro\": \"alpine\"}, {\"version\": \"${nginx_ubi}\", \"distro\": \"ubi\"}]" >> $GITHUB_OUTPUT - - - name: Set Go MD5sums - id: md5 - run: | - ./.github/scripts/variables.sh go_code_md5 >> $GITHUB_OUTPUT - ./.github/scripts/variables.sh docker_md5 >> $GITHUB_OUTPUT - - - name: Fetch Cached Binary Artifacts - id: binary-cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 - with: - path: ${{ github.workspace }}/dist - key: nginx-ingress-${{ steps.md5.outputs.go_code_md5 }} - lookup-only: true - - check: - name: Check if updates are needed - runs-on: ubuntu-22.04 - needs: variables - outputs: - needs-updating-debian: ${{ steps.needs.outputs.debian }} - needs-updating-alpine: ${{ steps.needs.outputs.alpine }} - needs-updating-ubi: ${{ steps.needs.outputs.ubi }} + patch-oss-images: + name: Build OSS Images + needs: [variables] strategy: + fail-fast: false matrix: - base_image: ${{ fromJson(needs.variables.outputs.versions) }} - steps: - - name: Build KIC tag - id: dist - run: | - if [ ${{ matrix.base_image.distro }} == "debian" ]; then dist=""; else dist="-${{ matrix.base_image.distro }}"; fi - echo "tag=${{ needs.variables.outputs.kic-tag }}${dist}" >> $GITHUB_OUTPUT - - - name: Check if update available for ${{ matrix.base_image.version }} - id: update - uses: lucacome/docker-image-update-checker@f50d56412b948cfdbb842c5419372681e0db3df1 # v1.2.1 - with: - base-image: ${{ matrix.base_image.version}} - image: nginx/nginx-ingress:${{ steps.dist.outputs.tag }} - env: - DEBUG: ${{ secrets.ACTIONS_STEP_DEBUG }} + include: + - tag: ${{ needs.variables.outputs.tag }} + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic/nginx-ingress + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress" + platforms: "linux/arm, linux/arm64, linux/amd64, linux/ppc64le, linux/s390x" + - tag: ${{ needs.variables.outputs.tag }}-alpine + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-alpine" + image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic/nginx-ingress + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress" + platforms: "linux/arm, linux/arm64, linux/amd64, linux/ppc64le, linux/s390x" + - tag: ${{ needs.variables.outputs.tag }}-ubi + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-ubi" + image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic/nginx-ingress + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-ingress" + platforms: "linux/arm64, linux/amd64, linux/ppc64le, linux/s390x" + uses: ./.github/workflows/patch-image.yml + with: + platforms: ${{ matrix.platforms }} + image: ${{ matrix.image }} + tag: ${{ matrix.tag }} + ic_version: ${{ needs.variables.outputs.tag }} + target_image: ${{ matrix.target_image }} + target_tag: ${{ matrix.target_tag }} + permissions: + contents: read + id-token: write + secrets: inherit - - id: needs - run: echo "${{ matrix.base_image.distro }}=${{ steps.update.outputs.needs-updating }}" >> $GITHUB_OUTPUT + patch-plus-images: + name: Build Plus Images + needs: [variables] + strategy: + fail-fast: false + matrix: + include: + - tag: ${{ needs.variables.outputs.tag }} + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic/nginx-plus-ingress + target_image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress + platforms: "linux/arm64, linux/amd64" + - tag: ${{ needs.variables.outputs.tag }}-alpine + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-alpine" + image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic/nginx-plus-ingress + target_image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress + platforms: "linux/arm64, linux/amd64" + - tag: ${{ needs.variables.outputs.tag }}-alpine-fips + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-alpine-fips" + image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic/nginx-plus-ingress + target_image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress + platforms: "linux/arm64, linux/amd64" + - tag: ${{ needs.variables.outputs.tag }}-mktpl + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-mktpl" + image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic/nginx-plus-ingress + target_image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress + platforms: "linux/arm64, linux/amd64" + - tag: ${{ needs.variables.outputs.tag }}-alpine-mktpl + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-alpine-mktpl" + image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic/nginx-plus-ingress + target_image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress + platforms: "linux/arm64, linux/amd64" + - tag: ${{ needs.variables.outputs.tag }}-alpine-mktpl-fips + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-alpine-mktpl-fips" + image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic/nginx-plus-ingress + target_image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress + platforms: "linux/arm64, linux/amd64" + - tag: ${{ needs.variables.outputs.tag }}-ubi + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-ubi" + image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic/nginx-plus-ingress + target_image: gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic/nginx-plus-ingress + platforms: "linux/arm64, linux/amd64, linux/s390x" + uses: ./.github/workflows/patch-image.yml + with: + platforms: ${{ matrix.platforms }} + image: ${{ matrix.image }} + tag: ${{ matrix.tag }} + ic_version: ${{ needs.variables.outputs.tag }} + target_image: ${{ matrix.target_image }} + target_tag: ${{ matrix.target_tag }} + permissions: + contents: read + id-token: write + secrets: inherit - binary: - if: ${{ needs.check.outputs.needs-updating-debian == 'true' || needs.check.outputs.needs-updating-alpine == 'true' || needs.check.outputs.needs-updating-ubi == 'true' || inputs.force == 'true' }} - name: Build binaries - runs-on: ubuntu-22.04 - needs: [check, variables] - steps: - - name: Checkout Repository - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - with: - fetch-depth: 0 - ref: refs/tags/v${{ needs.variables.outputs.kic-tag }} + patch-plus-nap-images: + name: Build Plus NAP Images + needs: [variables] + strategy: + fail-fast: false + matrix: + include: + - tag: "${{ needs.variables.outputs.tag }}" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-nap/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress" + platforms: "linux/amd64" + - tag: "${{ needs.variables.outputs.tag }}-ubi" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-ubi" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-nap/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress" + platforms: "linux/amd64" + - tag: "${{ needs.variables.outputs.tag }}-mktpl" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-mktpl" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-nap/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress" + platforms: "linux/amd64" + - tag: "${{ needs.variables.outputs.tag }}-ubi-mktpl" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-ubi-mktpl" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-nap/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress" + platforms: "linux/amd64" + - tag: "${{ needs.variables.outputs.tag }}-alpine-fips" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-alpine-fips" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-nap/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-nap/nginx-plus-ingress" + platforms: "linux/amd64" + - tag: "${{ needs.variables.outputs.tag }}" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-dos/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress" + platforms: "linux/amd64" + - tag: "${{ needs.variables.outputs.tag }}-ubi" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-ubi" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-dos/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress" + platforms: "linux/amd64" + - tag: "${{ needs.variables.outputs.tag }}-ubi-mktpl" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-ubi-mktpl" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-dos/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress" + platforms: "linux/amd64" + - tag: "${{ needs.variables.outputs.tag }}-mktpl" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-mktpl" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-dos/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos/nginx-plus-ingress" + platforms: "linux/amd64" + - tag: "${{ needs.variables.outputs.tag }}" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-dos-nap/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress" + platforms: "linux/amd64" + - tag: "${{ needs.variables.outputs.tag }}-ubi" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-ubi" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-dos-nap/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress" + platforms: "linux/amd64" + - tag: "${{ needs.variables.outputs.tag }}-ubi-mktpl" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-ubi-mktpl" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-dos-nap/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress" + platforms: "linux/amd64" + - tag: "${{ needs.variables.outputs.tag }}-mktpl" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}-mktpl" + image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release/nginx-ic-dos-nap/nginx-plus-ingress" + target_image: "gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-dos-nap/nginx-plus-ingress" + platforms: "linux/amd64" + uses: ./.github/workflows/patch-image.yml + with: + platforms: ${{ matrix.platforms }} + image: ${{ matrix.image }} + tag: ${{ matrix.tag }} + ic_version: ${{ needs.variables.outputs.tag }} + target_image: ${{ matrix.target_image }} + target_tag: ${{ matrix.target_tag }} + permissions: + contents: read + id-token: write + secrets: inherit - - name: Setup Golang Environment - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 - with: - go-version-file: go.mod + release-oss-internal: + name: "Publish Docker OSS ${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }} to internal release Registries" + needs: [variables, patch-oss-images] + uses: ./.github/workflows/oss-release.yml + with: + gcr_release_registry: true + ecr_public_registry: false + dockerhub_public_registry: false + quay_public_registry: false + github_public_registry: false + source_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + dry_run: ${{ inputs.dry_run || false }} + permissions: + contents: read + id-token: write + secrets: inherit - - name: Determine GOPATH - id: go - run: echo "go_path=$(go env GOPATH)" >> $GITHUB_OUTPUT + release-oss-public: + name: Publish Docker OSS ${{ needs.variables.outputs.tag }} to Public Registries + needs: [variables, patch-oss-images] + strategy: + fail-fast: false + matrix: + tag: + - "${{ needs.variables.outputs.tag }}" + - "${{ needs.variables.outputs.short_tag }}" + - "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + - "latest" + uses: ./.github/workflows/oss-release.yml + with: + gcr_release_registry: false + ecr_public_registry: true + dockerhub_public_registry: true + quay_public_registry: true + github_public_registry: true + source_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + target_tag: ${{ matrix.tag }} + dry_run: ${{ inputs.dry_run || false }} + permissions: + contents: read + id-token: write + secrets: inherit - - name: Build binaries - uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0 - with: - version: latest - args: build --clean --id kubernetes-ingress - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GOPATH: ${{ steps.go.outputs.go_path }} - if: ${{ needs.variables.outputs.binary-cache-hit != 'true' }} - - - name: Store Artifacts in Cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 - with: - path: ${{ github.workspace }}/dist - key: nginx-ingress-${{ needs.variables.outputs.go-md5 }} - if: ${{ needs.variables.outputs.binary-cache-hit != 'true' }} - - release-docker-debian: - name: Release Debian Image - needs: [binary, check, variables] - uses: ./.github/workflows/build-oss.yml + release-plus-nginx-gcr: + name: Publish Docker Plus ${{ needs.variables.outputs.tag }} to NGINX & GCR Marketplace registries + needs: [variables, patch-plus-images, patch-plus-nap-images] + strategy: + fail-fast: false + matrix: + tag: + - "${{ needs.variables.outputs.tag }}" + - "${{ needs.variables.outputs.short_tag }}" + - "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + - "latest" + uses: ./.github/workflows/plus-release.yml with: - platforms: linux/arm,linux/arm64,linux/amd64,linux/ppc64le,linux/s390x - image: debian - tag: ${{ needs.variables.outputs.kic-tag }} - go-md5: ${{ needs.variables.outputs.go-md5 }} - base-image-md5: ${{ needs.variables.outputs.base-image-md5 }} + nginx_registry: true + gcr_release_registry: false + gcr_mktpl_registry: true + ecr_mktpl_registry: false + az_mktpl_registry: false + source_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + target_tag: ${{ matrix.tag }} + dry_run: ${{ inputs.dry_run || false }} permissions: contents: read - actions: read - security-events: write id-token: write - packages: write secrets: inherit - if: ${{ needs.check.outputs.needs-updating-debian == 'true' || inputs.force == 'true' }} - release-docker-alpine: - name: Release Alpine Image - needs: [binary, check, variables] - uses: ./.github/workflows/build-oss.yml + release-plus-azure-ecr-marketplace: + name: Publish Docker Plus ${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }} to Azure & ECR Marketplace registries + needs: [variables, patch-plus-images, patch-plus-nap-images] + uses: ./.github/workflows/plus-release.yml with: - platforms: linux/arm,linux/arm64,linux/amd64,linux/ppc64le,linux/s390x - image: alpine - tag: ${{ needs.variables.outputs.kic-tag }} - go-md5: ${{ needs.variables.outputs.go-md5 }} - base-image-md5: ${{ needs.variables.outputs.base-image-md5 }} + nginx_registry: false + gcr_release_registry: false + gcr_mktpl_registry: false + ecr_mktpl_registry: true + az_mktpl_registry: true + source_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + dry_run: ${{ inputs.dry_run || false }} permissions: contents: read - actions: read - security-events: write id-token: write - packages: write secrets: inherit - if: ${{ needs.check.outputs.needs-updating-alpine == 'true' || inputs.force == 'true' }} - release-docker-ubi: - name: Release UBI Image - needs: [binary, check, variables] - uses: ./.github/workflows/build-oss.yml + release-plus-internal: + name: Publish Docker Plus ${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }} to internal release Registries + needs: [variables, patch-plus-images, patch-plus-nap-images] + uses: ./.github/workflows/plus-release.yml with: - platforms: linux/arm64,linux/amd64,linux/ppc64le,linux/s390x - image: ubi - tag: ${{ needs.variables.outputs.kic-tag }} - go-md5: ${{ needs.variables.outputs.go-md5 }} - base-image-md5: ${{ needs.variables.outputs.base-image-md5 }} + nginx_registry: false + gcr_release_registry: true + gcr_mktpl_registry: false + ecr_mktpl_registry: false + az_mktpl_registry: false + source_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + target_tag: "${{ needs.variables.outputs.tag }}-${{ needs.variables.outputs.date }}" + dry_run: ${{ inputs.dry_run || false }} permissions: contents: read - actions: read - security-events: write id-token: write - packages: write secrets: inherit - if: ${{ needs.check.outputs.needs-updating-ubi == 'true' || inputs.force == 'true' }} + + certify-openshift-images: + name: Certify OpenShift UBI images + runs-on: ubuntu-22.04 + needs: [variables, release-oss-public] + steps: + - name: Checkout Repository + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + + - name: Certify UBI OSS images in quay + uses: ./.github/actions/certify-openshift-image + with: + image: quay.io/nginx/nginx-ingress:${{ needs.variables.outputs.tag }}-ubi + project_id: ${{ secrets.CERTIFICATION_PROJECT_ID }} + pyxis_token: ${{ secrets.PYXIS_API_TOKEN }} + platforms: "" + if: ${{ ! inputs.dry_run || false }} diff --git a/Makefile b/Makefile index 8dcc541f0d..c44a581c90 100644 --- a/Makefile +++ b/Makefile @@ -184,6 +184,10 @@ ubi-image-nap-dos-plus: build ## Create Docker image for Ingress Controller (UBI .PHONY: all-images ## Create all the Docker images for Ingress Controller all-images: alpine-image alpine-image-plus alpine-image-plus-fips alpine-image-nap-plus-fips debian-image debian-image-plus debian-image-nap-plus debian-image-dos-plus debian-image-nap-dos-plus ubi-image ubi-image-plus ubi-image-nap-plus ubi-image-dos-plus ubi-image-nap-dos-plus +.PHONY: patch-os +patch-os: ## Patch supplied image + $(DOCKER_CMD) --build-arg IMAGE_NAME=$(IMAGE) + .PHONY: push push: ## Docker push to PREFIX and TAG docker push $(strip $(PREFIX)):$(strip $(TAG)) diff --git a/build/Dockerfile b/build/Dockerfile index bf522c6417..526e4dab99 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -5,6 +5,7 @@ ARG DOWNLOAD_TAG=edge ARG DEBIAN_FRONTEND=noninteractive ARG PREBUILT_BASE_IMG=nginx/nginx-ingress:${DOWNLOAD_TAG} ARG NGINX_AGENT=false +ARG IMAGE_NAME=nginx/nginx-ingress ############################################# Base images containing libs for Opentracing and FIPS ############################################# @@ -19,11 +20,9 @@ FROM nginx:1.26.0-alpine@sha256:ca16009a8c25f52193506d4c90c98efbad4b6cbe73372e2a RUN --mount=type=bind,from=alpine-opentracing-lib,target=/tmp/ot/ \ apk add --no-cache libcap libstdc++ \ - && apk upgrade --no-cache -U \ && cp -av /tmp/ot/usr/local/lib/libopentracing.so* /tmp/ot/usr/local/lib/libjaegertracing*so* /tmp/ot/usr/local/lib/libzipkin*so* /tmp/ot/usr/local/lib/libdd*so* /tmp/ot/usr/local/lib/libyaml*so* /usr/local/lib/ \ && cp -av /tmp/ot/usr/lib/nginx/modules/ngx_http_opentracing_module.so /usr/lib/nginx/modules/ \ - && ldconfig /usr/local/lib/ \ - && apk cache clean + && ldconfig /usr/local/lib/ ############################################# Base image for Debian ############################################# @@ -31,9 +30,7 @@ FROM nginx:1.26.0@sha256:ba9587717b056e1993b051f71cea30ddd5caf09ae2087b1eeb11329 RUN --mount=type=bind,from=opentracing-lib,target=/tmp/ot/ \ apt-get update \ - && apt-get upgrade -y \ && apt-get install --no-install-recommends --no-install-suggests -y libcap2-bin \ - && rm -rf /var/lib/apt/lists/* \ && cp -av /tmp/ot/usr/local/lib/libopentracing.so* /tmp/ot/usr/local/lib/libjaegertracing*so* /tmp/ot/usr/local/lib/libzipkin*so* /tmp/ot/usr/local/lib/libdd*so* /tmp/ot/usr/local/lib/libyaml*so* /usr/local/lib/ \ && cp -av /tmp/ot/usr/lib/nginx/modules/ngx_http_opentracing_module.so /usr/lib/nginx/modules/ \ && ldconfig @@ -54,8 +51,6 @@ LABEL name="NGINX Ingress Controller" \ io.openshift.tags="nginx,ingress-controller,ingress,controller,kubernetes,openshift" COPY --link --chown=101:0 LICENSE /licenses/ -RUN microdnf update -y \ - && microdnf clean all ############################################# NGINX files for NGINX Plus ############################################# @@ -88,6 +83,22 @@ RUN --mount=from=busybox:musl,src=/bin/,dst=/bin/ printf "%s\n" "Acquire::https: && echo HTTP_USER_AGENT="k8s-ic-$IC_VERSION${BUILD_OS##alpine-plus}-apk" > user_agent ADD --link --chown=101:0 https://cs.nginx.com/static/files/nginx-agent.repo nginx-agent.repo +ADD --link --chown=101:0 --chmod=0755 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/patch-os.sh patch-os.sh + + +############################################# Patch Image ############################################# +FROM ${IMAGE_NAME} as patched +ARG IMAGE_NAME +ARG IC_VERSION + +LABEL version="${IC_VERSION}" \ + org.opencontainers.image.version="${IC_VERSION}" + +USER 0 +RUN --mount=type=bind,from=nginx-files,src=patch-os.sh,target=/usr/local/bin/patch-os.sh \ + if [ -f /etc/apk/repositories ]; then sed -i -e '/nginx.com/d' /etc/apk/repositories; fi \ + && patch-os.sh +USER 101 ############################################# Base image for Alpine with NGINX Plus ############################################# FROM alpine:3.19@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b as alpine-plus @@ -100,11 +111,10 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/apk/cert.pem,mode=0644 \ --mount=type=bind,from=nginx-files,src=user_agent,target=/tmp/user_agent \ export $(cat /tmp/user_agent) \ && printf "%s\n" "https://pkgs.nginx.com/plus/${NGINX_PLUS_VERSION}/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ - && apk upgrade --no-cache -U \ && apk add --no-cache nginx-plus nginx-plus-module-njs nginx-plus-module-opentracing nginx-plus-module-fips-check libcap libcurl \ && cp -av /tmp/ot/usr/local/lib/libjaegertracing*so* /tmp/ot/usr/local/lib/libzipkin*so* /tmp/ot/usr/local/lib/libdd*so* /tmp/ot/usr/local/lib/libyaml*so* /usr/local/lib/ \ && ldconfig /usr/local/lib/ \ - && apk cache clean + && sed -i -e '/nginx.com/d' /etc/apk/repositories ############################################# Base image for Alpine with NGINX Plus and FIPS ############################################# @@ -131,7 +141,6 @@ RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ && printf "%s\n" "https://pkgs.nginx.com/app-protect/${NGINX_PLUS_VERSION}/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ && printf "%s\n" "https://pkgs.nginx.com/app-protect-security-updates/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ && printf "%s\n" "https://pkgs.nginx.com/nginx-agent/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ - && apk upgrade --no-cache -U \ && apk add --no-cache libcap-utils libcurl nginx-plus nginx-plus-module-njs nginx-plus-module-opentracing nginx-plus-module-fips-check \ && if [ -z "${NGINX_AGENT##true}" ]; then apk add --no-cache nginx-agent; fi \ && mkdir -p /usr/ssl \ @@ -140,7 +149,8 @@ RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ && cp -av /tmp/fips/etc/ssl/openssl.cnf /etc/ssl/openssl.cnf \ && cp -av /tmp/ot/usr/local/lib/libjaegertracing*so* /tmp/ot/usr/local/lib/libzipkin*so* /tmp/ot/usr/local/lib/libdd*so* /tmp/ot/usr/local/lib/libyaml*so* /usr/local/lib/ \ && ldconfig /usr/local/lib/ \ - && apk add --no-cache app-protect=~31.4.815 app-protect-attack-signatures app-protect-threat-campaigns + && apk add --no-cache app-protect=~31.4.815 app-protect-attack-signatures app-protect-threat-campaigns \ + && sed -i -e '/nginx.com/d' /etc/apk/repositories ############################################# Base image for Debian with NGINX Plus ############################################# @@ -154,7 +164,6 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode --mount=type=bind,from=nginx-files,src=90pkgs-nginx,target=/etc/apt/apt.conf.d/90pkgs-nginx \ --mount=type=bind,from=nginx-files,src=debian-plus-12.sources,target=/etc/apt/sources.list.d/nginx-plus.sources \ apt-get update \ - && apt-get upgrade -y \ && apt-get install --no-install-recommends --no-install-suggests -y sq ca-certificates libcap2-bin libcurl4 \ && groupadd --system --gid 101 nginx \ && useradd --system --gid nginx --no-create-home --home-dir /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \ @@ -189,7 +198,6 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode cp /tmp/app-protect-dos.sources /etc/apt/sources.list.d/app-protect-dos.sources; \ fi \ && apt-get update \ - && apt-get upgrade -y \ && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates sq \ && groupadd --system --gid 101 nginx \ && useradd --system --gid nginx --no-create-home --home-dir /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \ @@ -232,7 +240,6 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode --mount=type=bind,from=nginx-files,src=nginx_signing.key,target=/tmp/nginx_signing.key \ --mount=type=bind,from=nginx-files,src=nginx-plus-9.repo,target=/etc/yum.repos.d/nginx-plus.repo \ microdnf --nodocs install -y shadow-utils \ - && microdnf update -y \ && cat /etc/yum.repos.d/nginx-plus.repo \ && groupadd --system --gid 101 nginx \ && useradd --system --gid nginx --no-create-home --home-dir /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \ @@ -260,7 +267,6 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode fi \ ## the code below is duplicated from the ubi-plus image because NAP WAF doesn't support UBI minimal versions && dnf --nodocs install -y shadow-utils ca-certificates \ - && dnf update -y \ && groupadd --system --gid 101 nginx \ && useradd --system --gid nginx --no-create-home --home-dir /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \ && rpm --import /tmp/nginx_signing.key \ @@ -307,8 +313,6 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode cp /tmp/app-protect-dos-8.repo /etc/yum.repos.d/app-protect-dos-8.repo; \ fi \ ## the code below is duplicated from the ubi-plus image because NAP DOS doesn't support UBI 9 and minimal versions - && dnf --nodocs install -y shadow-utils ca-certificates \ - && dnf update -y \ && groupadd --system --gid 101 nginx \ && useradd --system --gid nginx --no-create-home --home-dir /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \ && rpm --import /tmp/nginx_signing.key \ @@ -380,6 +384,10 @@ RUN --mount=type=bind,target=/tmp mkdir -p /var/lib/nginx /etc/nginx/secrets /et && chmod -R g=u /etc/nginx /var/cache/nginx /var/lib/nginx /var/log/nginx /*.tmpl \ && rm -f /etc/nginx/conf.d/* +# Patch OS +RUN --mount=type=bind,from=nginx-files,src=patch-os.sh,target=/usr/local/bin/patch-os.sh \ + patch-os.sh + # Uncomment the line below if you would like to add the default.pem to the image # and use it as a certificate and key for the default server # ADD default.pem /etc/nginx/secrets/default