diff --git a/.github/workflows/dependency-images.yaml b/.github/workflows/dependency-images.yaml index d306357c1..05d208d4c 100644 --- a/.github/workflows/dependency-images.yaml +++ b/.github/workflows/dependency-images.yaml @@ -20,15 +20,14 @@ permissions: contents: read jobs: - fluentd: - name: Fluentd - runs-on: ubuntu-latest + fluentd-image: + name: Fluentd image + runs-on: ${{ matrix.platform == 'linux/arm64' && 'linux-arm64' || 'ubuntu-latest' }} permissions: contents: read packages: write id-token: write - security-events: write outputs: name: ${{ steps.image-name.outputs.value }} @@ -38,12 +37,28 @@ jobs: strategy: matrix: + platform: + - linux/amd64 + - linux/arm64 image-type: - base - filters - full steps: + - name: Prepare arm64 environment + if: matrix.platform == 'linux/arm64' + run: | + sudo install -m 0755 -d /etc/apt/keyrings + sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc + echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + sudo apt-get update && sudo apt-get install -y acl docker-ce docker-ce-cli containerd.io docker-buildx-plugin + USERID=$(id -u) + sudo setfacl --modify user:${USERID}:rw /var/run/docker.sock + - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -67,13 +82,6 @@ jobs: uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1 with: images: ${{ steps.image-name.outputs.value }} - flavor: | - latest = false - tags: | - type=ref,event=branch - type=ref,event=pr,prefix=pr- - type=semver,pattern={{raw}} - type=raw,value=latest,enable={{is_default_branch}} labels: | org.opencontainers.image.description=Custom Fluentd image for the Logging operator. org.opencontainers.image.title=Logging operator Fluentd image @@ -87,18 +95,34 @@ jobs: username: ${{ github.actor }} password: ${{ github.token }} - - name: Build and push fluentd-${{ matrix.image-type }} + - name: Build and push fluentd-${{ matrix.platform }}-${{ matrix.image-type }} id: build uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0 with: context: images/fluentd - platforms: linux/amd64,linux/arm64 - tags: ${{ steps.meta.outputs.tags }} + platforms: ${{ matrix.platform }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max target: ${{ matrix.image-type }} - outputs: type=image,push=true,name=target,annotation-index.org.opencontainers.image.description=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.description'] }} + outputs: type=image,name=${{ steps.image-name.outputs.value }},push-by-digest=true,push=true,annotation-index.org.opencontainers.image.description=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.description'] }} + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + + platform=${{ matrix.platform }} + echo "PLATFORM=${platform//\//-}" >> $GITHUB_ENV + + - name: Upload digest + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + with: + name: digests-${{ matrix.image-type }}-${{ env.PLATFORM }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 - name: Sign image with GitHub OIDC Token if: ${{ github.repository_owner == 'kube-logging' }} # Check if the workflow is called by the same GitHub organization @@ -126,12 +150,108 @@ jobs: --certificate-oidc-issuer "https://token.actions.githubusercontent.com" | jq done + merge-fluentd-image: + name: Merge Fluentd image + runs-on: ubuntu-latest + needs: fluentd-image + + permissions: + contents: read + packages: write + id-token: write + security-events: write + + strategy: + matrix: + image-type: + - base + - filters + - full + + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 + + - name: Set up Cosign + uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 + + - name: Login to GitHub Container Registry + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Download digests + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + with: + path: /tmp/digests + pattern: digests-${{ matrix.image-type }}-* + merge-multiple: true + + - name: Gather build metadata + id: meta + uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1 + with: + images: ${{ needs.fluentd-image.outputs.name }} + flavor: | + latest = false + tags: | + type=ref,event=branch,suffix=-${{ matrix.image-type }} + type=ref,event=pr,prefix=pr-,suffix=-${{ matrix.image-type }} + type=semver,pattern={{raw}},suffix=-${{ matrix.image-type }} + type=raw,value=latest,enable={{is_default_branch}},suffix=-${{ matrix.image-type }} + + - name: Create multi-arch manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ needs.fluentd-image.outputs.name }}@sha256:%s ' *) + # Fetch the digest of the manifest list + + # wait a moment for registry propagation + sleep 5 + + for i in {1..3}; do + if DIGEST=$(docker buildx imagetools inspect --raw ${{ needs.fluentd-image.outputs.name }} | jq -r '.manifests[0].digest'); then + echo "DIGEST=$DIGEST" >> $GITHUB_ENV + break + fi + sleep 5 + done + + - name: Sign image with GitHub OIDC Token + if: ${{ github.repository_owner == 'kube-logging' }} # Check if the workflow is called by the same GitHub organization + env: + DIGEST: ${{ env.DIGEST }} + TAGS: ${{ steps.meta.outputs.tags }} + run: | + images="" + for tag in ${TAGS[@]}; do + images+="${tag}@${DIGEST} " + done + + cosign sign --yes --rekor-url "https://rekor.sigstore.dev/" ${images} + + - name: Verify signed image with cosign + if: ${{ github.repository_owner == 'kube-logging' }} # Check if the workflow is called by the same GitHub organization + env: + DIGEST: ${{ env.DIGEST }} + TAGS: ${{ steps.meta.outputs.tags }} + run: | + for tag in ${TAGS[@]}; do + cosign verify "${tag}@${DIGEST}" \ + --rekor-url "https://rekor.sigstore.dev/" \ + --certificate-identity "https://github.com/${{ github.repository }}/.github/workflows/dependency-images.yaml@${{ github.ref }}" \ + --certificate-oidc-issuer "https://token.actions.githubusercontent.com" | jq + done + - name: Set image ref id: image-ref - run: echo "value=${{ steps.image-name.outputs.value }}@${{ steps.build.outputs.digest }}" >> "$GITHUB_OUTPUT" + run: echo "value=${{ needs.fluentd-image.outputs.name }}@${{ env.DIGEST }}" >> "$GITHUB_OUTPUT" - name: Fetch image - run: skopeo --insecure-policy copy docker://${{ steps.image-name.outputs.value }}:${{ steps.meta.outputs.version }} oci-archive:image.tar + run: skopeo --insecure-policy copy docker://${{ needs.fluentd-image.outputs.name }}${{ steps.meta.outputs.version }} oci-archive:image.tar - name: Extract OCI tarball run: |