diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index bc94b24d7b..35204b93d1 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -6,6 +6,14 @@ on: branches: [main] pull_request: branches: [main] + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: analyze: name: Analyze @@ -17,7 +25,6 @@ jobs: language: [go] runs-on: ubuntu-latest env: - IS_NOT_MERGE_GROUP: ${{ github.event_name != 'merge_group' }} GOOS: ${{ matrix.goos }} GOARCH: ${{ matrix.goarch }} timeout-minutes: 90 @@ -27,23 +34,18 @@ jobs: security-events: write steps: - name: Checkout repository - if: env.IS_NOT_MERGE_GROUP - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup go - if: env.IS_NOT_MERGE_GROUP - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod - name: Initialize CodeQL - if: env.IS_NOT_MERGE_GROUP - uses: github/codeql-action/init@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 + uses: github/codeql-action/init@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 with: languages: ${{ matrix.language }} - name: Autobuild - if: env.IS_NOT_MERGE_GROUP - uses: github/codeql-action/autobuild@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 + uses: github/codeql-action/autobuild@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 - name: Perform CodeQL Analysis - if: env.IS_NOT_MERGE_GROUP - uses: github/codeql-action/analyze@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8 + uses: github/codeql-action/analyze@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/commit-message.yaml b/.github/workflows/commit-message.yaml index ea7e1a1128..3c9d30a17d 100644 --- a/.github/workflows/commit-message.yaml +++ b/.github/workflows/commit-message.yaml @@ -8,10 +8,15 @@ on: - synchronize - edited - reopened + +permissions: + contents: read + jobs: commit-message: if: ${{ github.event_name != 'merge_group' }} runs-on: ubuntu-24.04 + timeout-minutes: 5 steps: - name: verify_commit_message env: diff --git a/.github/workflows/devcontainer.yaml b/.github/workflows/devcontainer.yaml new file mode 100644 index 0000000000..77161f5e39 --- /dev/null +++ b/.github/workflows/devcontainer.yaml @@ -0,0 +1,46 @@ +name: DevContainer +on: + merge_group: + push: + branches: [main] + paths: + - ".devcontainer/**" + - "go.mod" + pull_request: + branches: [main] + paths: + - ".devcontainer/**" + - "go.mod" + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build DevContainer + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Build and validate devcontainer + uses: devcontainers/ci@b63b30de439b47a52267f241112c5b453b673db5 # v0.3.1900000449 + with: + runCmd: | + clang --version + llvm-strip --version + go version + EXPECTED_GO=$(grep '^go ' go.mod | awk '{print $2}') + ACTUAL_GO=$(go version | grep -oP '\d+\.\d+\.\d+') + if [ "$EXPECTED_GO" != "$ACTUAL_GO" ]; then + echo "::error::Go version mismatch: devcontainer has $ACTUAL_GO but go.mod requires $EXPECTED_GO" + exit 1 + fi + kubectl version --client + helm version + kind version + grep -rl 'go:generate.*bpf2go' pkg/plugin/ | xargs -I{} go generate {} diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 6b35313530..12073387ac 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -3,6 +3,14 @@ name: Build and Deploy Retina.sh on: push: branches: ["main"] + paths: + - 'site/**' + - 'docs/**' + pull_request: + branches: ["main"] + paths: + - 'site/**' + - 'docs/**' workflow_dispatch: merge_group: permissions: @@ -13,28 +21,36 @@ concurrency: group: "pages" cancel-in-progress: false jobs: - deploy: - if: ${{ github.event_name != 'merge_group' }} - environment: - name: retina.sh - url: ${{ steps.deployment.outputs.page_url }} + build: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Setup Pages - uses: actions/configure-pages@v5 - - uses: actions/setup-node@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: 20 - name: build run: | npm install --prefix site/ npm run build --prefix site/ - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + - name: Upload build artifact + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: "./site/build" + + deploy: + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: build + environment: + name: retina.sh + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Setup Pages + uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0 - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 diff --git a/.github/workflows/e2e-test-event-writer.yml b/.github/workflows/e2e-test-event-writer.yml index 8dc2fba0ac..0f70bd9cbd 100644 --- a/.github/workflows/e2e-test-event-writer.yml +++ b/.github/workflows/e2e-test-event-writer.yml @@ -121,7 +121,7 @@ jobs: } echo "tag=$TAG" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append - - name: Build and push images + - name: Build image shell: pwsh working-directory: ${{ env.EVENT_WRITER_PATH }} run: | @@ -133,6 +133,14 @@ jobs: } $tag = "${{ steps.tag.outputs.tag }}" + echo "EVENT_WRITER_IMAGE=$image" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "EVENT_WRITER_TAG=$tag" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append docker build -f "./Dockerfile" -t "${image}:${tag}" -t "${image}:latest" . - docker push "${image}:${tag}" - docker push "${image}:latest" \ No newline at end of file + + - name: Push images + if: ${{ github.event_name != 'pull_request' }} + shell: pwsh + working-directory: ${{ env.EVENT_WRITER_PATH }} + run: | + docker push "${env:EVENT_WRITER_IMAGE}:${env:EVENT_WRITER_TAG}" + docker push "${env:EVENT_WRITER_IMAGE}:latest" \ No newline at end of file diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 8d1028594b..f35c2841fb 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -83,19 +83,22 @@ jobs: e2e: name: E2E runs-on: ubuntu-latest + timeout-minutes: 120 + env: + CLUSTER_NAME: retina-e2e-${{ github.run_id }}-${{ github.run_attempt }} steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup go - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod - run: go version - name: Az CLI login - uses: azure/login@v2 + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} @@ -115,4 +118,12 @@ jobs: fi go test -v ./test/e2e/. -timeout 60m -tags=e2e -count=1 -args -image-tag=${{ inputs.image_tag }} -image-registry=${{ inputs.image_registry }} -image-namespace=${{ inputs.image_namespace }} -create-infra=${{ !inputs.use_existing_infra }} -delete-infra=${{ !inputs.use_existing_infra }} - \ No newline at end of file + + - name: Cleanup resource group + if: always() + shell: bash + run: | + if az group exists --name "$CLUSTER_NAME" 2>/dev/null | grep -q true; then + echo "Deleting resource group $CLUSTER_NAME..." + az group delete --name "$CLUSTER_NAME" --yes --no-wait || true + fi diff --git a/.github/workflows/generate-check.yaml b/.github/workflows/generate-check.yaml new file mode 100644 index 0000000000..d337b2e9fc --- /dev/null +++ b/.github/workflows/generate-check.yaml @@ -0,0 +1,113 @@ +name: Check Generated Code +on: + pull_request: + branches: [main] + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + generate-check: + strategy: + fail-fast: false + matrix: + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm + name: Generate (${{ matrix.arch }}) + runs-on: ${{ matrix.runner }} + timeout-minutes: 15 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version-file: go.mod + + - name: Check that committed .o files are empty stubs + run: | + RED='\033[0;31m' + YELLOW='\033[1;33m' + CYAN='\033[0;36m' + NC='\033[0m' + # Tracked .o files must be empty (0 bytes) in the committed tree. + # They exist so Go source with bpf2go references compiles without + # running go generate. Real BPF objects are built at image build time. + # This check runs BEFORE generate since generate populates them. + non_empty=$(git ls-files '*.o' | while read -r f; do + size=$(git cat-file -s "HEAD:$f" 2>/dev/null || echo 0) + if [ "$size" -gt 0 ]; then echo "$f ($size bytes)"; fi + done || true) + if [ -n "$non_empty" ]; then + echo "" + echo -e "${RED}============================================================${NC}" + echo -e "${RED}ERROR: The following .o files must be empty stubs (0 bytes).${NC}" + echo "" + echo -e "${YELLOW}${non_empty}${NC}" + echo "" + echo -e "${CYAN}Run 'make empty-bpf-objects' to truncate them, then commit.${NC}" + echo -e "${RED}============================================================${NC}" + echo "::error::Non-empty .o files committed. Run 'make empty-bpf-objects' and commit the result." + exit 1 + fi + + - name: Install BPF build dependencies + run: | + sudo apt-get update -qq + sudo apt-get install -y --no-install-recommends clang llvm lld libbpf-dev linux-headers-$(uname -r) + sudo apt-get install -y --no-install-recommends linux-tools-$(uname -r) linux-tools-common || true + + - name: Run make generate for ${{ matrix.arch }} + run: | + # Generate BPF objects and Go bindings for this runner's native arch only, + # then run the remaining (non-BPF) generators. + GOARCH=${{ matrix.arch }} go generate ./pkg/plugin/... + go generate ./... + + - name: Check for uncommitted changes + run: | + RED='\033[0;31m' + YELLOW='\033[1;33m' + CYAN='\033[0;36m' + NC='\033[0m' + failed=0 + + # 1. Check generated .go files match committed code. + # Ignore .o files — they are empty stubs in the repo and get + # populated with real BPF objects during generate. + if ! git diff --quiet -- ':!*.o'; then + echo "" + echo -e "${RED}============================================================${NC}" + echo -e "${RED}ERROR: Generated code is out of date.${NC}" + echo "" + echo -e "${YELLOW}The following files differ after running 'make generate':${NC}" + git diff --name-only -- ':!*.o' + echo "" + echo -e "${CYAN}Please run 'make generate' locally and commit the changes.${NC}" + echo -e "${RED}============================================================${NC}" + echo "::error::Generated code is out of date. Run 'make generate' locally and commit the changes." + failed=1 + fi + + # 2. Check for new generated files that weren't committed. + untracked=$(git ls-files --others --exclude-standard -- '*.go' | head -20) + if [ -n "$untracked" ]; then + echo "" + echo -e "${RED}============================================================${NC}" + echo -e "${RED}ERROR: New generated files are not committed.${NC}" + echo "" + echo -e "${YELLOW}${untracked}${NC}" + echo "" + echo -e "${CYAN}Please run 'make generate' locally and commit the new files.${NC}" + echo -e "${RED}============================================================${NC}" + echo "::error::New generated files are not committed. Run 'make generate' locally and commit the new files." + failed=1 + fi + + exit $failed diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml index 95cb3cf847..a1d2202fb8 100644 --- a/.github/workflows/golangci-lint.yaml +++ b/.github/workflows/golangci-lint.yaml @@ -6,6 +6,14 @@ on: branches: [main] pull_request: branches: [main] + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: golangci: strategy: @@ -15,24 +23,19 @@ jobs: goarch: ["amd64", "arm64"] name: Lint runs-on: ubuntu-latest + timeout-minutes: 30 env: - IS_NOT_MERGE_GROUP: ${{ github.event_name != 'merge_group' }} GOOS: ${{ matrix.goos }} GOARCH: ${{ matrix.goarch }} steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - if: env.IS_NOT_MERGE_GROUP + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 - if: env.IS_NOT_MERGE_GROUP + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod + - name: Build golangci-lint + run: GOOS=linux GOARCH=amd64 go build -o "$RUNNER_TEMP/golangci-lint" github.com/golangci/golangci-lint/v2/cmd/golangci-lint - name: golangci-lint - if: env.IS_NOT_MERGE_GROUP - uses: golangci/golangci-lint-action@v6 - with: - version: latest - args: --concurrency 4 --verbose --config=.golangci.yaml --timeout=25m - only-new-issues: true - skip-cache: true + run: | + "$RUNNER_TEMP/golangci-lint" run --new-from-rev=${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before || 'HEAD~1' }} --concurrency 4 --verbose --config=.golangci.yaml --timeout=25m diff --git a/.github/workflows/goreleaser.yaml b/.github/workflows/goreleaser.yaml index 8b69aa3de6..c758d38e3c 100644 --- a/.github/workflows/goreleaser.yaml +++ b/.github/workflows/goreleaser.yaml @@ -4,25 +4,36 @@ on: branches: [main] push: tags: ["v*"] + permissions: contents: write packages: write + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: name: Build kubectl-retina if: github.ref_type == 'branch' runs-on: ubuntu-latest + timeout-minutes: 30 steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod + - name: Install Syft + uses: anchore/sbom-action/download-syft@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 - name: Run GoReleaser build - uses: goreleaser/goreleaser-action@v6 + uses: goreleaser/goreleaser-action@1a80836c5c9d9e5755a25cb59ec6f45a3b5f41a8 # v7.2.1 + env: + MCR_AGENT_IMAGE_NAME: mcr.microsoft.com/containernetworking/retina-agent with: distribution: goreleaser version: latest @@ -30,24 +41,36 @@ jobs: release: name: Release kubectl-retina runs-on: ubuntu-latest + timeout-minutes: 30 if: github.ref_type == 'tag' steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod + - name: Install Syft + uses: anchore/sbom-action/download-syft@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 - name: Run GoReleaser release - uses: goreleaser/goreleaser-action@v6 + uses: goreleaser/goreleaser-action@1a80836c5c9d9e5755a25cb59ec6f45a3b5f41a8 # v7.2.1 with: distribution: goreleaser version: latest args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + MCR_AGENT_IMAGE_NAME: mcr.microsoft.com/containernetworking/retina-agent + - name: Check if release tag + id: check-tag + run: | + if [[ "${{ github.ref_name }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "is_release=true" >> $GITHUB_OUTPUT + else + echo "is_release=false" >> $GITHUB_OUTPUT + fi - name: Update new version in krew-index - if: github.repository_owner == 'microsoft' - uses: rajatjindal/krew-release-bot@v0.0.47 + if: github.repository_owner == 'microsoft' && steps.check-tag.outputs.is_release == 'true' + uses: rajatjindal/krew-release-bot@c970b8a8f6dbc2f2285a26e3ae160903b87002c3 # v0.0.51 diff --git a/.github/workflows/images.yaml b/.github/workflows/images.yaml index 83d3835608..93b64756ee 100644 --- a/.github/workflows/images.yaml +++ b/.github/workflows/images.yaml @@ -16,12 +16,16 @@ permissions: jobs: retina-images: name: Build Images and Run E2E - runs-on: ubuntu-latest + runs-on: ${{ matrix.runner }} strategy: matrix: platform: ["linux"] - arch: ["amd64", "arm64"] + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm steps: - name: Checkout code @@ -127,12 +131,16 @@ jobs: operator-images: name: Build Operator Images - runs-on: ubuntu-latest + runs-on: ${{ matrix.runner }} strategy: matrix: platform: ["linux"] - arch: ["amd64", "arm64"] + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm steps: - name: Checkout code @@ -177,12 +185,16 @@ jobs: retina-shell-images: name: Build Retina Shell Images - runs-on: ubuntu-latest + runs-on: ${{ matrix.runner }} strategy: matrix: platform: ["linux"] - arch: ["amd64", "arm64"] + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm steps: - name: Checkout code @@ -226,12 +238,16 @@ jobs: kubectl-retina-images: name: Build Kubectl Retina Images - runs-on: ubuntu-latest + runs-on: ${{ matrix.runner }} strategy: matrix: platform: ["linux"] - arch: ["amd64", "arm64"] + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm steps: - name: Checkout code diff --git a/.github/workflows/kapinger.yaml b/.github/workflows/kapinger.yaml index 6a329412c0..6d6a1710fb 100644 --- a/.github/workflows/kapinger.yaml +++ b/.github/workflows/kapinger.yaml @@ -4,62 +4,173 @@ on: push: branches: - main + paths: + - "hack/tools/kapinger/**" + - ".github/workflows/kapinger.yaml" + tags: + - "v*" + pull_request: + branches: + - main + paths: + - "hack/tools/kapinger/**" + - ".github/workflows/kapinger.yaml" + merge_group: + types: [checks_requested] + +permissions: + contents: read + packages: write jobs: - build: - runs-on: ubuntu-latest + build-linux: + name: Build Linux Kapinger Image (${{ matrix.arch }}) + runs-on: ${{ matrix.runner }} + + strategy: + matrix: + arch: ["amd64", "arm64"] + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set outputs id: vars run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - - name: Check outputs - run: echo ${{ steps.vars.outputs.sha_short }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - # - name: Login to GitHub Container Registry - # uses: docker/login-action@v1 - # with: - # registry: ghcr.io - # username: ${{ github.repository_owner }} - # password: ${{ secrets.GITHUB_TOKEN }} + - name: Log in to GHCR + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin - - name: Build Windows Kapinger Image - uses: docker/build-push-action@v6 + - name: Build Linux Kapinger Image + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 with: context: hack/tools/kapinger file: hack/tools/kapinger/Dockerfile - platforms: windows/amd64 + platforms: linux/${{ matrix.arch }} + target: linux + load: true push: false provenance: false - tags: ghcr.io/${{ github.repository }}/kapinger:${{ steps.vars.outputs.sha_short }}-windows + tags: ghcr.io/${{ github.repository }}/kapinger:${{ steps.vars.outputs.sha_short }}-linux-${{ matrix.arch }} - - name: Build Linux Kapinger Image - uses: docker/build-push-action@v6 + - name: Smoke test kapinger binary + run: | + IMAGE=ghcr.io/${{ github.repository }}/kapinger:${{ steps.vars.outputs.sha_short }}-linux-${{ matrix.arch }} + # Verify the binary starts and prints the expected startup log. + # It will exit with an error because there's no K8s cluster, but + # that confirms the binary is correctly linked and executable. + docker run --rm "$IMAGE" 2>&1 | grep -q "starting kapinger" + + - name: Push Linux Kapinger Image + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 with: context: hack/tools/kapinger file: hack/tools/kapinger/Dockerfile - platforms: linux/amd64 - push: false + platforms: linux/${{ matrix.arch }} + target: linux + push: true provenance: false - tags: ghcr.io/${{ github.repository }}/kapinger:${{ steps.vars.outputs.sha_short }}-linux + tags: ghcr.io/${{ github.repository }}/kapinger:${{ steps.vars.outputs.sha_short }}-linux-${{ matrix.arch }} + + build-windows: + name: Build Windows Kapinger Image + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Set outputs + id: vars + run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 + + - name: Log in to GHCR + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin + + - name: Build Windows Kapinger Image + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 + with: + context: hack/tools/kapinger + file: hack/tools/kapinger/Dockerfile + platforms: windows/amd64 + target: windows + push: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) }} + provenance: false + tags: ghcr.io/${{ github.repository }}/kapinger:${{ steps.vars.outputs.sha_short }}-windows + + manifest: + name: Create and Push Manifest + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) + needs: [build-linux, build-windows] + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Set outputs + id: vars + run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 + + - name: Log in to GHCR + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin + + - name: Create and push manifest + run: | + TAG=${{ steps.vars.outputs.sha_short }} + REPO=ghcr.io/${{ github.repository }}/kapinger + TAGS="-t $REPO:$TAG" + if [[ "${{ github.ref }}" == refs/tags/v* ]]; then + TAGS="$TAGS -t $REPO:${{ github.ref_name }}" + fi + docker buildx imagetools create $TAGS \ + "$REPO:$TAG-linux-amd64" \ + "$REPO:$TAG-linux-arm64" \ + "$REPO:$TAG-windows" + + build-toolbox: + name: Build Linux Toolbox Image + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Set outputs + id: vars + run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 + + - name: Log in to GHCR + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin - name: Build Linux Toolbox Image - uses: docker/build-push-action@v6 + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 with: context: hack/tools file: hack/tools/toolbox/Dockerfile platforms: linux/amd64 - push: false + push: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) }} provenance: false tags: ghcr.io/${{ github.repository }}/toolbox:${{ steps.vars.outputs.sha_short }}-linux -# - name: Create and push manifest -# id: docker_manifest -# run: | -# docker manifest create ghcr.io/${{ github.repository }}/kapinger:latest ghcr.io/${{ github.repository }}/kapinger:${{ steps.vars.outputs.sha_short }}-windows ghcr.io/${{ github.repository }}/kapinger:${{ steps.vars.outputs.sha_short }}-linux -# docker manifest push ghcr.io/${{ github.repository }}/kapinger:latest diff --git a/.github/workflows/markdownlint.yaml b/.github/workflows/markdownlint.yaml index d11291efaf..1fb9fcca1d 100644 --- a/.github/workflows/markdownlint.yaml +++ b/.github/workflows/markdownlint.yaml @@ -3,17 +3,22 @@ on: merge_group: pull_request: branches: [main] + paths: + - '**/*.md' + +permissions: + contents: read + jobs: markdownlint: if: ${{ github.event_name != 'merge_group' }} name: markdownlint runs-on: ubuntu-latest + timeout-minutes: 10 steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: DavidAnson/markdownlint-cli2-action@v9 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: DavidAnson/markdownlint-cli2-action@07035fd053f7be764496c0f8d8f9f41f98305101 # v22.0.0 with: - command: config - globs: | - .github/.markdownlint.json - **/*.md + config: .github/.markdownlint.json + globs: '**/*.md' diff --git a/.github/workflows/perf-schedule.yaml b/.github/workflows/perf-schedule.yaml index ee0886626c..92eed22c78 100644 --- a/.github/workflows/perf-schedule.yaml +++ b/.github/workflows/perf-schedule.yaml @@ -10,11 +10,27 @@ permissions: id-token: write jobs: + get-tag: + name: Get Latest Release Tag + runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + tag: ${{ steps.get_tag.outputs.tag }} + steps: + - name: Get latest release tag + id: get_tag + env: + GH_TOKEN: ${{ github.token }} + run: | + TAG=$(gh release view --repo ${{ github.repository }} --json tagName -q .tagName) + echo "tag=$TAG" >> $GITHUB_OUTPUT + perf-test-basic: + needs: get-tag uses: ./.github/workflows/perf-template.yaml with: image-registry: ghcr.io - tag: $(curl -s https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r .tag_name) + tag: ${{ needs.get-tag.outputs.tag }} image-namespace: ${{ github.repository }} retina-mode: basic azure-location: ${{ vars.AZURE_LOCATION }} @@ -25,10 +41,11 @@ jobs: azure-app-insights-key: ${{ secrets.AZURE_APP_INSIGHTS_KEY }} perf-test-advanced: + needs: get-tag uses: ./.github/workflows/perf-template.yaml with: image-registry: ghcr.io - tag: $(curl -s https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r .tag_name) + tag: ${{ needs.get-tag.outputs.tag }} image-namespace: ${{ github.repository }} retina-mode: advanced azure-location: ${{ vars.AZURE_LOCATION }} diff --git a/.github/workflows/perf-template.yaml b/.github/workflows/perf-template.yaml index d202b45148..f232d9e932 100644 --- a/.github/workflows/perf-template.yaml +++ b/.github/workflows/perf-template.yaml @@ -46,18 +46,21 @@ jobs: perf-test: name: Retina ${{ inputs.retina-mode }} Performance Test runs-on: ubuntu-latest + timeout-minutes: 150 + env: + CLUSTER_NAME: retina-perf-${{ inputs.retina-mode }}-${{ github.run_id }}-${{ github.run_attempt }} steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup go - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod - run: go version - name: Az CLI login - uses: azure/login@v2 + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 with: client-id: ${{ secrets.azure-client-id }} tenant-id: ${{ secrets.azure-tenant-id }} @@ -71,11 +74,20 @@ jobs: shell: bash run: | set -euo pipefail - + TAG="${{ inputs.tag }}" REGISTRY="${{ inputs.image-registry }}" NAMESPACE="${{ inputs.image-namespace }}" MODE="${{ inputs.retina-mode }}" - + echo "Running in $MODE mode..." go test -v ./test/e2e/. -timeout 2h -tags=perf -count=1 -args -image-tag=$TAG -image-registry=$REGISTRY -image-namespace=$NAMESPACE -retina-mode=$MODE + + - name: Cleanup resource group + if: always() + shell: bash + run: | + if az group exists --name "$CLUSTER_NAME" 2>/dev/null | grep -q true; then + echo "Deleting resource group $CLUSTER_NAME..." + az group delete --name "$CLUSTER_NAME" --yes --no-wait || true + fi diff --git a/.github/workflows/release-charts.yaml b/.github/workflows/release-charts.yaml index 6ce60f8894..4d45eaa467 100644 --- a/.github/workflows/release-charts.yaml +++ b/.github/workflows/release-charts.yaml @@ -16,24 +16,25 @@ jobs: push-retina-charts: name: Publish Retina Helm Charts runs-on: ubuntu-latest + timeout-minutes: 30 if: github.ref_type == 'tag' steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: azure/setup-helm@v4.3.0 + - uses: azure/setup-helm@dda3372f752e03dde6b3237bc9431cdc2f7a02a2 # v5.0.0 id: install - + - name: Install Cosign - uses: sigstore/cosign-installer@v3.8.2 + uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1 - name: Log in to registry (Helm for pushing chart, Docker for signing and push signature) run: | echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u $ --password-stdin echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin - + - name: Build, Push and Sign chart id: build_chart shell: bash diff --git a/.github/workflows/release-images.yaml b/.github/workflows/release-images.yaml index 302a334590..d5a8a653e7 100644 --- a/.github/workflows/release-images.yaml +++ b/.github/workflows/release-images.yaml @@ -15,27 +15,30 @@ permissions: jobs: retina-images: name: Build Agent Images - runs-on: ubuntu-latest + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 strategy: matrix: platform: ["linux"] arch: ["amd64", "arm64"] + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod - run: go version - name: Install Cosign - uses: sigstore/cosign-installer@v3.8.2 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1 - name: Log in to registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin @@ -58,30 +61,81 @@ jobs: cosign sign --yes ${IMAGE_PATH}@${DIGEST} done - retina-win-images: - name: Build Agent Windows Images + build-windows-binaries: + name: Build Windows Binaries runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version-file: go.mod + - run: go version + + - name: Build Windows Binaries + shell: bash + run: | + TAG=$(make version) + echo "TAG=$TAG" >> $GITHUB_ENV + make build-windows-binaries \ + GOOS=windows \ + GOARCH=amd64 \ + TAG=$TAG + + - name: Upload Windows Binaries + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: windows-binaries + path: output/windows_amd64/ + retention-days: 1 + + retina-win-images: + name: Build Agent Image - Windows ${{ matrix.year }} + needs: build-windows-binaries + runs-on: windows-${{ matrix.year }} + timeout-minutes: 60 strategy: matrix: + year: ["2022"] platform: ["windows"] arch: ["amd64"] - year: ["2019", "2022"] steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + - name: Download Windows Binaries + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - go-version-file: go.mod - - run: go version + name: windows-binaries + path: output/windows_amd64/ - - name: Install Cosign - uses: sigstore/cosign-installer@v3.8.2 + - name: Ensure Docker daemon is running + shell: pwsh + run: | + $timeout = 120 + $timer = [Diagnostics.Stopwatch]::StartNew() + while ($timer.Elapsed.TotalSeconds -lt $timeout) { + $svc = Get-Service docker -ErrorAction SilentlyContinue + if ($svc -and $svc.Status -ne 'Running') { + Start-Service docker -ErrorAction SilentlyContinue + } + $result = docker info 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Host "Docker daemon is ready" + return + } + Write-Host "Waiting for Docker daemon to start..." + Start-Sleep -Seconds 5 + } + throw "Docker daemon failed to start within $timeout seconds" - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + - name: Install Cosign + uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1 - name: Log in to registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin @@ -90,44 +144,51 @@ jobs: shell: bash run: | set -euo pipefail - echo "TAG=$(make version)" >> $GITHUB_ENV + TAG=$(make version) + echo "TAG=$TAG" >> "$GITHUB_ENV" make retina-image-win \ - IMAGE_NAMESPACE=${{ github.repository }} \ - PLATFORM=${{ matrix.platform }}/${{ matrix.arch }} \ - WINDOWS_YEARS=${{ matrix.year }} \ - BUILDX_ACTION=--push - + IMAGE_NAMESPACE=${{ github.repository }} \ + PLATFORM=${{ matrix.platform }}/${{ matrix.arch }} \ + WINDOWS_YEARS=${{ matrix.year }} \ + BINARIES_PATH=output/windows_${{ matrix.arch }} \ + REPO_PATH=. + docker push ghcr.io/${{ github.repository }}/retina-agent:${TAG}-windows-ltsc${{ matrix.year }}-${{ matrix.arch }} + - name: Sign container image + shell: bash run: | for image in retina-agent ; do IMAGE_PATH="ghcr.io/${{ github.repository }}/$image:$TAG-windows-ltsc${{ matrix.year }}-${{ matrix.arch }}" - DIGEST=$(jq -r '.["containerimage.digest"]' image-metadata-$image-$TAG-windows-ltsc${{ matrix.year }}-${{ matrix.arch }}.json) + DIGEST=$(docker manifest inspect $IMAGE_PATH -v | jq -r '.Descriptor.digest') cosign sign --yes ${IMAGE_PATH}@${DIGEST} done operator-images: name: Build Operator Images - runs-on: ubuntu-latest + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 strategy: matrix: platform: ["linux"] - arch: ["amd64"] + arch: ["amd64", "arm64"] + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod - run: go version - name: Install Cosign - uses: sigstore/cosign-installer@v3.8.2 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1 - name: Log in to registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin @@ -151,28 +212,31 @@ jobs: done retina-shell-images: - name: Build Retina Shell Images - runs-on: ubuntu-latest + name: Build Retina Shell Images (${{ matrix.platform }}, ${{ matrix.arch }}) + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 strategy: matrix: - platform: ["linux"] - arch: ["amd64", "arm64"] + include: + - platform: linux + arch: amd64 + runner: ubuntu-latest + - platform: linux + arch: arm64 + runner: ubuntu-24.04-arm steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod - run: go version - name: Install Cosign - uses: sigstore/cosign-installer@v3.8.2 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1 - name: Log in to registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin @@ -195,27 +259,30 @@ jobs: kubectl-retina-images: name: Build Kubectl Retina Images - runs-on: ubuntu-latest + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 strategy: matrix: platform: ["linux"] arch: ["amd64", "arm64"] + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod - run: go version - name: Install Cosign - uses: sigstore/cosign-installer@v3.8.2 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1 - name: Log in to registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin @@ -239,6 +306,7 @@ jobs: manifests: name: Generate Manifests runs-on: ubuntu-latest + timeout-minutes: 30 needs: [ retina-images, @@ -254,13 +322,13 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 - name: Install Cosign - uses: sigstore/cosign-installer@v3.8.2 + uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1 - name: Log in to registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin diff --git a/.github/workflows/release-validation.yaml b/.github/workflows/release-validation.yaml index 45f303f9c5..e6b1506e86 100644 --- a/.github/workflows/release-validation.yaml +++ b/.github/workflows/release-validation.yaml @@ -6,13 +6,18 @@ on: types: - completed +permissions: + contents: read + jobs: release_validation: + if: ${{ github.event.workflow_run.conclusion == 'success' }} name: Release Validation runs-on: ubuntu-latest + timeout-minutes: 30 steps: - name: Checkout repository - uses: actions/checkout@v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Get latest tag id: get_latest_tag @@ -40,7 +45,7 @@ jobs: helm pull oci://ghcr.io/microsoft/retina/charts/retina --version ${{ env.TAG }} - name: Setup kind cluster - uses: helm/kind-action@v1.12.0 + uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0 # krew does not support installing a specific verison # so if this step fails it means there was something wrong diff --git a/.github/workflows/scale-test.yaml b/.github/workflows/scale-test.yaml index f46db14bae..36f0eefd18 100644 --- a/.github/workflows/scale-test.yaml +++ b/.github/workflows/scale-test.yaml @@ -65,19 +65,20 @@ jobs: scale-test: name: Scale Test runs-on: ubuntu-latest + timeout-minutes: 360 steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup go - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod - run: go version - name: Az CLI login - uses: azure/login@v2 + uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index 12eebe7143..f52cfed687 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -7,12 +7,13 @@ on: jobs: stale: runs-on: ubuntu-latest + timeout-minutes: 15 permissions: contents: write issues: write pull-requests: write steps: - - uses: actions/stale@main + - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 id: stale with: ascending: true @@ -31,4 +32,4 @@ jobs: stale-issue-message: "This issue will be closed in 7 days due to inactivity." stale-pr-message: "This PR will be closed in 7 days due to inactivity." - name: Print outputs - run: echo ${{ join(steps.stale.outputs.*, ',') }} + run: echo "${{ join(steps.stale.outputs.*, ',') }}" diff --git a/.github/workflows/test-ebpf.yaml b/.github/workflows/test-ebpf.yaml new file mode 100644 index 0000000000..234e78ccf3 --- /dev/null +++ b/.github/workflows/test-ebpf.yaml @@ -0,0 +1,49 @@ +name: eBPF Program Tests +on: + push: + branches: [main] + paths: + - 'pkg/plugin/**/_cprog/**' + - 'pkg/plugin/**/*_ebpf_test.go' + - 'pkg/plugin/ebpftest/**' + pull_request: + branches: [main] + paths: + - 'pkg/plugin/**/_cprog/**' + - 'pkg/plugin/**/*_ebpf_test.go' + - 'pkg/plugin/ebpftest/**' + workflow_dispatch: + +permissions: + contents: read + +jobs: + ebpf-tests: + strategy: + matrix: + include: + - arch: amd64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm + runs-on: ${{ matrix.runner }} + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + with: + go-version-file: go.mod + + - name: Install clang and llvm-strip + run: | + sudo apt-get update + sudo apt-get install -y clang llvm + + - name: Compile eBPF programs + run: | + GOARCH=${{ matrix.arch }} go generate ./pkg/plugin/... + + - name: Run eBPF program tests + run: | + sudo $(which go) test -tags=ebpf -v -count=1 ./pkg/plugin/... diff --git a/.github/workflows/test-multicloud.yml b/.github/workflows/test-multicloud.yml index 98c40277d7..1fb2150f93 100644 --- a/.github/workflows/test-multicloud.yml +++ b/.github/workflows/test-multicloud.yml @@ -5,20 +5,28 @@ on: paths: - 'test/multicloud/**' +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: multicloud-test: runs-on: ubuntu-latest + timeout-minutes: 30 steps: - - uses: opentofu/setup-opentofu@v1 + - uses: opentofu/setup-opentofu@fc711fa910b93cba0f3fbecaafc9f42fd0c411cb # v2.0.0 with: tofu_version: 1.8.3 - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Go - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod @@ -28,4 +36,4 @@ jobs: - name: Run tests run: make test - working-directory: test/multicloud/ \ No newline at end of file + working-directory: test/multicloud/ diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9144fa6c03..1d8d2fd454 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -9,22 +9,23 @@ on: workflow_dispatch: permissions: - actions: read contents: read - deployments: read - packages: none pull-requests: write - security-events: write - issues: write + actions: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: test-image: runs-on: ubuntu-latest + timeout-minutes: 30 steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5.4.0 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version-file: go.mod @@ -36,7 +37,86 @@ jobs: make test-image IMAGE_NAMESPACE=${{ github.repository }} PLATFORM=linux/amd64 - name: Upload Artifacts - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: coverage-files path: ./artifacts/coverage* + + - name: Generate coverage summary + run: | + COVERAGE_FILE="./artifacts/coverage.out" + if [ ! -s "$COVERAGE_FILE" ]; then + echo "::warning::Coverage file is empty or missing" + echo "## Test Coverage" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo ":warning: No coverage data available." >> "$GITHUB_STEP_SUMMARY" + exit 0 + fi + + # Filter out generated files (eBPF, mocks) + grep -Ev '_bpf\.go|_bpfel_x86\.go|_bpfel_arm64\.go|_generated\.go|mock_' "$COVERAGE_FILE" > coverage_filtered.out + + # Generate function-level coverage report + go tool cover -func=coverage_filtered.out > coverage_func.out + + # Extract total coverage percentage + TOTAL_COVERAGE=$(grep '^total:' coverage_func.out | awk '{print $NF}') + + # Write step summary + { + echo "## Test Coverage" + echo "" + echo ":white_check_mark: **Tests passed**" + echo "" + echo "| Metric | Value |" + echo "| --- | --- |" + echo "| Total Coverage | \`${TOTAL_COVERAGE}\` |" + echo "" + echo "
" + echo "Coverage by package (top 20 lowest)" + echo "" + echo '```' + grep -v '^total:' coverage_func.out | sort -t'%' -k1 -n | head -20 + echo '```' + echo "
" + } >> "$GITHUB_STEP_SUMMARY" + + - name: Compare coverage with main branch + if: github.event_name == 'pull_request' + continue-on-error: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} + run: | + COVERAGE_FILE="./artifacts/coverage.out" + if [ ! -s "$COVERAGE_FILE" ]; then + echo "Coverage file is empty or missing, skipping comparison" + exit 0 + fi + + # Filter generated files and prepare current branch coverage + grep -Ev '_bpf\.go|_bpfel_x86\.go|_bpfel_arm64\.go|_generated\.go|mock_' "$COVERAGE_FILE" > coveragenew.out + cp coveragenew.out coverage.out + go tool cover -func=coveragenew.out -o coverageexpanded.out + + # Install Python dependency for GitHub API calls + pip install --quiet requests + + # Fetch main branch coverage + python3 scripts/coverage/get_coverage.py + + # Check if main branch coverage was downloaded + if [ ! -f mainbranchcoverage/coverage.out ]; then + echo "No main branch coverage found, skipping comparison" + exit 0 + fi + + # Filter main branch coverage + grep -Ev '_bpf\.go|_bpfel_x86\.go|_bpfel_arm64\.go|_generated\.go|mock_' mainbranchcoverage/coverage.out > mainbranchcoverage/coverage_filtered.out + mv mainbranchcoverage/coverage_filtered.out mainbranchcoverage/coverage.out + + # Generate expanded coverage for main branch + go tool cover -func=mainbranchcoverage/coverage.out -o maincoverageexpanded.out + + # Post PR comment with coverage diff + python3 scripts/coverage/compare_cov.py diff --git a/.github/workflows/trivy.yaml b/.github/workflows/trivy.yaml index 39c6eba598..b22761c884 100644 --- a/.github/workflows/trivy.yaml +++ b/.github/workflows/trivy.yaml @@ -12,6 +12,7 @@ permissions: contents: read jobs: scan: + if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }} permissions: contents: read security-events: write @@ -21,16 +22,24 @@ jobs: matrix: image: ["retina-agent", "retina-init", "retina-operator", "kubectl-retina", "retina-shell"] runs-on: ubuntu-latest # trivy only supports running on Linux + timeout-minutes: 30 steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Get Tag + env: + GH_TOKEN: ${{ github.token }} run: | - echo "TAG=$(make version)" >> $GITHUB_ENV + if [ "${{ github.event_name }}" = "schedule" ] || [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + TAG=$(gh release view --repo ${{ github.repository }} --json tagName -q .tagName 2>/dev/null || make version) + else + TAG=$(make version) + fi + echo "TAG=$TAG" >> $GITHUB_ENV - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@6c175e9c4083a92bbca2f9724c8a5e33bc2d97a5 + uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # 0.36.0 with: image-ref: "ghcr.io/${{ github.repository }}/${{ matrix.image }}:${{ env.TAG }}" format: "template" @@ -39,6 +48,6 @@ jobs: severity: "CRITICAL,HIGH" - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 with: sarif_file: "trivy-results.sarif" diff --git a/.github/workflows/update-hubble.yaml b/.github/workflows/update-hubble.yaml index dc65eb5083..2e01141c4e 100644 --- a/.github/workflows/update-hubble.yaml +++ b/.github/workflows/update-hubble.yaml @@ -13,10 +13,11 @@ jobs: update-hubble: name: Update Hubble to latest version runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Get latest Hubble version id: get_version @@ -51,7 +52,7 @@ jobs: - name: Create pull request if: env.update_needed == 'true' - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 with: token: ${{ secrets.GITHUB_TOKEN }} branch: deps/update-hubble-to-${{ env.version }} diff --git a/cli/Dockerfile b/cli/Dockerfile index 5dfd12434c..29a43b5c45 100644 --- a/cli/Dockerfile +++ b/cli/Dockerfile @@ -1,8 +1,9 @@ -# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2-cbl-mariner2.0 --format "{{.Name}}@{{.Digest}}" -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:5341a0010ecff114ee2f11f5eaa4f73b721b54142954041523f3e785d5c4b978 AS builder +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0@sha256:637bcd53d7c139d2fa54d8d6e2bb3f9346b3ab1c9f03bb33ea56c3964d458f1b AS builder ARG VERSION ARG APP_INSIGHTS_ID +ARG AGENT_IMAGE_NAME="ghcr.io/microsoft/retina/retina-agent" WORKDIR /workspace COPY . . @@ -15,13 +16,33 @@ ARG GOARCH=amd64 ENV GOARCH=${GOARCH} RUN --mount=type=cache,target="/root/.cache/go-build" \ - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ + go build \ -ldflags "-X github.com/microsoft/retina/internal/buildinfo.Version="$VERSION" \ - -X "github.com/microsoft/retina/internal/buildinfo.ApplicationInsightsID"="$APP_INSIGHTS_ID"" \ + -X "github.com/microsoft/retina/internal/buildinfo.ApplicationInsightsID"="$APP_INSIGHTS_ID" \ + -X "github.com/microsoft/retina/internal/buildinfo.RetinaAgentImageName"="$AGENT_IMAGE_NAME"" \ -a -o kubectl-retina cli/main.go -# mcr.microsoft.com/cbl-mariner/distroless/minimal:2.0 -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/cbl-mariner/distroless/minimal@sha256:db87903c5d4d9d6760e86a274914efd6a3bb5914c0b5a6c6b35350ec297fea4f +# minimal libs stage — provides only the system libraries needed by the CGO-enabled binary, +# without the bloat of the full Go SDK image (python, gcc, systemd, etc.) +# skopeo inspect docker://mcr.microsoft.com/azurelinux/base/core:3.0 --format "{{.Name}}@{{.Digest}}" +FROM mcr.microsoft.com/azurelinux/base/core:3.0@sha256:35149ae8dd179684f969944f54a337c665a64e702486154eb44253fb39c2505b AS libs + +# Target 1: Distroless (secure, minimal) +# skopeo inspect docker://mcr.microsoft.com/azurelinux/distroless/minimal:3.0 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/azurelinux/distroless/minimal:3.0@sha256:5a66f9f16ac675db2a8229dac72d83811b73b502d6ad192d8b374c7f3be498af AS distroless-target +COPY --from=libs /lib/ /lib +COPY --from=libs /usr/lib/ /usr/lib +COPY --from=libs /etc/pki/tls/ /etc/pki/tls/ WORKDIR / COPY --from=builder /workspace/kubectl-retina . +# Target 2: Shell-enabled (operational, init container support) +# skopeo inspect docker://mcr.microsoft.com/azurelinux/base/core:3.0 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/azurelinux/base/core:3.0@sha256:35149ae8dd179684f969944f54a337c665a64e702486154eb44253fb39c2505b AS shell-target +WORKDIR / +COPY --from=builder /workspace/kubectl-retina /bin/kubectl-retina +RUN chmod +x /bin/kubectl-retina + +# Default target (distroless for backward compatibility) +FROM distroless-target + diff --git a/controller/Dockerfile b/controller/Dockerfile index 4802604098..c6e067d3c0 100644 --- a/controller/Dockerfile +++ b/controller/Dockerfile @@ -2,49 +2,49 @@ ARG OS_VERSION=ltsc2022 # pinned base images -# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2-cbl-mariner2.0 --format "{{.Name}}@{{.Digest}}" -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:5341a0010ecff114ee2f11f5eaa4f73b721b54142954041523f3e785d5c4b978 AS golang +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0@sha256:257614fe59a6e7fb56909eec9a59a6d0d0794a331ebc1d6dc93aa8ef995d34f5 AS golang -# skopeo inspect docker://mcr.microsoft.com/cbl-mariner/base/core:2.0 --format "{{.Name}}@{{.Digest}}" -FROM mcr.microsoft.com/cbl-mariner/base/core@sha256:8deab931d4af66264253cce66471a04742dc6f8d5d175d4c18e930eda615c0aa AS mariner-core +# skopeo inspect docker://mcr.microsoft.com/azurelinux/base/core:3.0 --format "{{.Name}}@{{.Digest}}" +FROM mcr.microsoft.com/azurelinux/base/core:3.0@sha256:35149ae8dd179684f969944f54a337c665a64e702486154eb44253fb39c2505b AS azurelinux-core -# skopeo inspect docker://mcr.microsoft.com/cbl-mariner/distroless/minimal:2.0 --format "{{.Name}}@{{.Digest}}" -FROM mcr.microsoft.com/cbl-mariner/distroless/minimal@sha256:0b09ee9e988e338f86432484c980c9c334d2b35b3bec6ce14298b754ecb6460b AS mariner-distroless +# skopeo inspect docker://mcr.microsoft.com/azurelinux/distroless/minimal:3.0 --format "{{.Name}}@{{.Digest}}" +FROM mcr.microsoft.com/azurelinux/distroless/minimal:3.0@sha256:5a66f9f16ac675db2a8229dac72d83811b73b502d6ad192d8b374c7f3be498af AS azurelinux-distroless -# mcr.microsoft.com/windows/servercore:ltsc2019 +# skopeo inspect docker://mcr.microsoft.com/windows/servercore:ltsc2019 --override-os windows --format "{{.Name}}@{{.Digest}}" FROM mcr.microsoft.com/windows/servercore@sha256:8077f3e5b0987c388735917f0d15a3dd5fc773f8b5699c612ccb539d42644185 AS ltsc2019 -# mcr.microsoft.com/windows/servercore:ltsc2022 +# skopeo inspect docker://mcr.microsoft.com/windows/servercore:ltsc2022 --override-os windows --format "{{.Name}}@{{.Digest}}" FROM mcr.microsoft.com/windows/servercore@sha256:e000e9a1712065a0218447c20ae19984b447fa741d11cf64696b8a1172fcd7da AS ltsc2022 - # build stages # intermediate go generate stage -FROM golang AS intermediate +FROM golang AS intermediate ARG APP_INSIGHTS_ID # set to enable AI telemetry ARG GOARCH=amd64 # default to amd64 ARG GOOS=linux # default to linux ENV GOARCH=${GOARCH} ENV GOOS=${GOOS} RUN if [ "$GOOS" = "linux" ] ; then \ - tdnf install -y clang16 lld16 bpftool libbpf-devel; \ + tdnf install -y clang lld bpftool libbpf-devel; \ fi COPY ./pkg/plugin /go/src/github.com/microsoft/retina/pkg/plugin WORKDIR /go/src/github.com/microsoft/retina RUN if [ "$GOOS" = "linux" ] ; then \ - go mod init github.com/microsoft/retina; \ - go generate -skip "mockgen" -x /go/src/github.com/microsoft/retina/pkg/plugin/...; \ - tar czf /gen.tar.gz ./pkg/plugin; \ - rm go.mod; \ + go mod init github.com/microsoft/retina; \ + go generate -skip "mockgen" -x /go/src/github.com/microsoft/retina/pkg/plugin/...; \ + tar czf /gen.tar.gz ./pkg/plugin; \ + rm go.mod; \ fi COPY ./go.mod ./go.sum ./ RUN go mod download COPY . . RUN if [ "$GOOS" = "linux" ] ; then \ - rm -rf ./pkg/plugin && tar xvf /gen.tar.gz ./pkg/plugin; \ + rm -rf ./pkg/plugin && tar xvf /gen.tar.gz ./pkg/plugin; \ fi +# eBPF for Windows: download retinaebpfapi.dll from NuGet FROM golang AS eBPFRetinaStage WORKDIR /tmp RUN tdnf install -y unzip && \ @@ -62,7 +62,6 @@ ENV GOARCH=${GOARCH} ENV GOOS=${GOOS} RUN --mount=type=cache,target="/root/.cache/go-build" go build -v -o /go/bin/retina/captureworkload -ldflags "-X github.com/microsoft/retina/internal/buildinfo.Version="$VERSION" -X github.com/microsoft/retina/internal/buildinfo.ApplicationInsightsID="$APP_INSIGHTS_ID"" captureworkload/main.go - # controller binary FROM intermediate AS controller-bin ARG APP_INSIGHTS_ID # set to enable AI telemetry @@ -71,8 +70,7 @@ ARG GOOS=linux # default to linux ARG VERSION ENV GOARCH=${GOARCH} ENV GOOS=${GOOS} -RUN --mount=type=cache,target="/root/.cache/go-build" go build -x -v -o /go/bin/retina/controller -ldflags "-X github.com/microsoft/retina/internal/buildinfo.Version="$VERSION" -X github.com/microsoft/retina/internal/buildinfo.ApplicationInsightsID="$APP_INSIGHTS_ID"" controller/main.go - +RUN --mount=type=cache,target="/root/.cache/go-build" go build -x -v -o /go/bin/retina/controller -ldflags "-X github.com/microsoft/retina/internal/buildinfo.Version="$VERSION" -X github.com/microsoft/retina/internal/buildinfo.ApplicationInsightsID="$APP_INSIGHTS_ID"" controller/main.go # init binary FROM intermediate AS init-bin @@ -84,11 +82,11 @@ ENV GOARCH=${GOARCH} ENV GOOS=${GOOS} RUN --mount=type=cache,target="/root/.cache/go-build" go build -v -o /go/bin/retina/initretina -ldflags "-X github.com/microsoft/retina/internal/buildinfo.Version="$VERSION" -X github.com/microsoft/retina/internal/buildinfo.ApplicationInsightsID="$APP_INSIGHTS_ID"" init/retina/main_linux.go - # tools image -FROM mariner-core AS tools +FROM azurelinux-core AS tools RUN tdnf install -y \ - clang16 \ + clang \ + bpftool \ iproute \ iptables \ tcpdump \ @@ -102,11 +100,13 @@ RUN arr="clang tcpdump ip ss iptables-legacy iptables-legacy-save iptables-nft i for i in $arr; do \ cp $(which $i) /tmp/bin; \ done +RUN mkdir -p /tmp/init-bin +RUN cp $(which bpftool) /tmp/init-bin # Download Hubble ARG GOARCH=amd64 ENV HUBBLE_ARCH=${GOARCH} # ARG HUBBLE_VERSION may be modified via the update-hubble GitHub Action -ARG HUBBLE_VERSION=v1.17.3 +ARG HUBBLE_VERSION=v1.18.6 ENV HUBBLE_VERSION=${HUBBLE_VERSION} RUN echo "Hubble version: $HUBBLE_VERSION" && \ wget --no-check-certificate https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-${HUBBLE_ARCH}.tar.gz && \ @@ -116,19 +116,21 @@ RUN echo "Hubble version: $HUBBLE_VERSION" && \ rm hubble-linux-${HUBBLE_ARCH}.tar.gz && rm hubble-linux-${HUBBLE_ARCH}.tar.gz.sha256sum # init final image -FROM mariner-distroless AS init +FROM azurelinux-distroless AS init COPY --from=init-bin /go/bin/retina/initretina /retina/initretina COPY --from=tools /lib/ /lib COPY --from=tools /usr/lib/ /usr/lib +COPY --from=tools /etc/pki/tls/ /etc/pki/tls/ +COPY --from=tools /tmp/init-bin/ /bin/ ENTRYPOINT ["./retina/initretina"] - # agent final image -# mcr.microsoft.com/cbl-mariner/distroless/minimal:2.0 -# mcr.microsoft.com/cbl-mariner/distroless/minimal@sha256:63a0a70ceaa1320bc6eb98b81106667d43e46b674731ea8d28e4de1b87e0747f -FROM mariner-distroless AS agent +# mcr.microsoft.com/azurelinux/distroless/minimal:3.0 +# mcr.microsoft.com/azurelinux/distroless/minimal@sha256:5a66f9f16ac675db2a8229dac72d83811b73b502d6ad192d8b374c7f3be498af +FROM azurelinux-distroless AS agent COPY --from=tools /lib/ /lib COPY --from=tools /usr/lib/ /usr/lib +COPY --from=tools /etc/pki/tls/ /etc/pki/tls/ COPY --from=tools /tmp/bin/ /bin COPY --from=controller-bin /go/bin/retina/controller /retina/controller COPY --from=controller-bin /go/src/github.com/microsoft/retina/pkg/plugin /go/src/github.com/microsoft/retina/pkg/plugin diff --git a/controller/Dockerfile.gogen b/controller/Dockerfile.gogen index 3097165c89..91e26a1811 100644 --- a/controller/Dockerfile.gogen +++ b/controller/Dockerfile.gogen @@ -1,5 +1,5 @@ -# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2-cbl-mariner2.0 --format "{{.Name}}@{{.Digest}}" -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:5341a0010ecff114ee2f11f5eaa4f73b721b54142954041523f3e785d5c4b978 +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0@sha256:257614fe59a6e7fb56909eec9a59a6d0d0794a331ebc1d6dc93aa8ef995d34f5 # Default linux/architecture. ARG GOOS=linux @@ -24,4 +24,4 @@ RUN ln -s /usr/bin/clang-14 /usr/bin/clang WORKDIR /app # Generate go code. -ENTRYPOINT mkdir /tmp/.cache && export GOCACHE=/tmp/.cache && CGO_ENABLED=0 go generate ./... +ENTRYPOINT mkdir /tmp/.cache && export GOCACHE=/tmp/.cache && go generate ./... diff --git a/controller/Dockerfile.proto b/controller/Dockerfile.proto index f6ba587974..51fcff84a0 100644 --- a/controller/Dockerfile.proto +++ b/controller/Dockerfile.proto @@ -1,5 +1,5 @@ -# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2-cbl-mariner2.0 --format "{{.Name}}@{{.Digest}}" -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:5341a0010ecff114ee2f11f5eaa4f73b721b54142954041523f3e785d5c4b978 +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0@sha256:257614fe59a6e7fb56909eec9a59a6d0d0794a331ebc1d6dc93aa8ef995d34f5 LABEL Name=retina-builder Version=0.0.1 @@ -13,4 +13,6 @@ RUN unzip protoc-24.2-linux-x86_64.zip -d protoc RUN mv protoc/bin/protoc /usr/bin/protoc WORKDIR /app -ENTRYPOINT protoc -I=. --go_out=paths=source_relative:. ./pkg/utils/metadata_linux.proto +ENTRYPOINT /bin/sh -c "protoc -I=. --go_out=paths=source_relative:. ./pkg/utils/metadata_linux.proto && \ + protoc -I=. --go_out=paths=source_relative:. ./pkg/utils/metadata_darwin.proto && \ + protoc -I=. --go_out=paths=source_relative:. ./pkg/utils/metadata_windows.proto" diff --git a/controller/Dockerfile.windows-2019 b/controller/Dockerfile.windows-2019 index 882cac36e7..24ca5b917a 100644 --- a/controller/Dockerfile.windows-2019 +++ b/controller/Dockerfile.windows-2019 @@ -1,5 +1,5 @@ -# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2-cbl-mariner2.0 --format "{{.Name}}@{{.Digest}}" -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:5341a0010ecff114ee2f11f5eaa4f73b721b54142954041523f3e785d5c4b978 AS builder +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.4-azurelinux3.0 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:250d01e55a37bd79d7014ae83f9f50aa6fa5570ca910e7f19faeff4bb0132ae1 AS builder # Build args ARG VERSION @@ -16,7 +16,8 @@ RUN --mount=type=cache,target="/root/.cache/go-build" go build -v -o /usr/bin/co RUN --mount=type=cache,target="/root/.cache/go-build" go build -v -o /usr/bin/captureworkload.exe ./captureworkload/ # Copy into final image -FROM mcr.microsoft.com/windows/servercore:ltsc2019 as final +# skopeo inspect docker://mcr.microsoft.com/windows/servercore:ltsc2019 --override-os windows --format "{{.Name}}@{{.Digest}}" +FROM mcr.microsoft.com/windows/servercore@sha256:862b24ccf5e399fc3bea746c7ac68c16f3fbcfa199532a3e506b7e03e57217b9 as final COPY --from=builder /usr/src/retina/windows/kubeconfigtemplate.yaml kubeconfigtemplate.yaml COPY --from=builder /usr/src/retina/windows/setkubeconfigpath.ps1 setkubeconfigpath.ps1 COPY --from=builder /usr/bin/controller.exe controller.exe diff --git a/controller/Dockerfile.windows-2022 b/controller/Dockerfile.windows-2022 index 0697cb69d5..7921db9176 100644 --- a/controller/Dockerfile.windows-2022 +++ b/controller/Dockerfile.windows-2022 @@ -1,5 +1,5 @@ -# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2-cbl-mariner2.0 --format "{{.Name}}@{{.Digest}}" -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:5341a0010ecff114ee2f11f5eaa4f73b721b54142954041523f3e785d5c4b978 AS builder +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0@sha256:257614fe59a6e7fb56909eec9a59a6d0d0794a331ebc1d6dc93aa8ef995d34f5 AS builder # Build args ARG VERSION @@ -16,12 +16,11 @@ RUN --mount=type=cache,target="/root/.cache/go-build" go build -v -o /usr/bin/co RUN --mount=type=cache,target="/root/.cache/go-build" go build -v -o /usr/bin/captureworkload.exe ./captureworkload/ # Copy into final image -FROM --platform=windows/amd64 mcr.microsoft.com/windows/servercore:ltsc2022 as final +# skopeo inspect docker://mcr.microsoft.com/windows/servercore:ltsc2022 --override-os windows --format "{{.Name}}@{{.Digest}}" +FROM --platform=windows/amd64 mcr.microsoft.com/windows/servercore:ltsc2022@sha256:e000e9a1712065a0218447c20ae19984b447fa741d11cf64696b8a1172fcd7da as final COPY --from=builder /usr/src/retina/windows/kubeconfigtemplate.yaml kubeconfigtemplate.yaml COPY --from=builder /usr/src/retina/windows/setkubeconfigpath.ps1 setkubeconfigpath.ps1 COPY --from=builder /usr/bin/controller.exe controller.exe COPY --from=builder /usr/bin/captureworkload.exe captureworkload.exe -ADD https://github.com/microsoft/etl2pcapng/releases/download/v1.10.0/etl2pcapng.exe /etl2pcapng.exe - CMD ["controller.exe", "start", "--kubeconfig=.\\kubeconfig"] diff --git a/controller/Dockerfile.windows-cgo b/controller/Dockerfile.windows-cgo index ad35301c04..9fd3b71748 100644 --- a/controller/Dockerfile.windows-cgo +++ b/controller/Dockerfile.windows-cgo @@ -1,5 +1,5 @@ -# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2-windowsservercore-ltsc2022 --format "{{.Name}}@{{.Digest}}" -FROM --platform=windows/amd64 mcr.microsoft.com/oss/go/microsoft/golang@sha256:0fb2afcf9c877c90ca609984303da41846c447ca62c0f9e42046be113cae117e AS cgo +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-windowsservercore-ltsc2022 --override-os windows --format "{{.Name}}@{{.Digest}}" +FROM --platform=windows/amd64 mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-windowsservercore-ltsc2022@sha256:7dc9ddecd32b6c338f2c9ac9b87f51eb7f1bc603af4fe389abefa0db310a8239 AS cgo SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] diff --git a/controller/Dockerfile.windows-native b/controller/Dockerfile.windows-native index e90cae6267..89faf7717e 100644 --- a/controller/Dockerfile.windows-native +++ b/controller/Dockerfile.windows-native @@ -3,8 +3,8 @@ # buildx targets, and this one requires legacy build. # Maybe one day: https://github.com/moby/buildkit/issues/616 ARG BUILDER_IMAGE -# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2-windowsservercore-ltsc2022 --format "{{.Name}}@{{.Digest}}" -FROM --platform=windows/amd64 mcr.microsoft.com/oss/go/microsoft/golang@sha256:0fb2afcf9c877c90ca609984303da41846c447ca62c0f9e42046be113cae117e AS builder +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-windowsservercore-ltsc2022 --override-os windows --format "{{.Name}}@{{.Digest}}" +FROM --platform=windows/amd64 mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-windowsservercore-ltsc2022@sha256:7dc9ddecd32b6c338f2c9ac9b87f51eb7f1bc603af4fe389abefa0db310a8239 AS builder WORKDIR C:\\retina COPY go.mod . COPY go.sum . @@ -23,7 +23,8 @@ RUN go build -v -o captureworkload.exe -ldflags="-X github.com/microsoft/retina/ FROM --platform=windows/amd64 ${BUILDER_IMAGE} as pktmon-builder WORKDIR C:\\retina -FROM --platform=windows/amd64 mcr.microsoft.com/windows/nanoserver:ltsc2022 AS final +# skopeo inspect docker://mcr.microsoft.com/windows/nanoserver:ltsc2022 --override-os windows --format "{{.Name}}@{{.Digest}}" +FROM --platform=windows/amd64 mcr.microsoft.com/windows/nanoserver:ltsc2022@sha256:3680dad0bb773da8efcd9d928eaf4e33817875ab71a43792640ab1bcc0b3c074 AS final ADD https://github.com/microsoft/etl2pcapng/releases/download/v1.10.0/etl2pcapng.exe /etl2pcapng.exe SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'Continue';"] COPY --from=builder C:\\retina\\windows\\kubeconfigtemplate.yaml kubeconfigtemplate.yaml @@ -31,4 +32,4 @@ COPY --from=builder C:\\retina\\windows\\setkubeconfigpath.ps1 setkubeconfigpath COPY --from=builder C:\\retina\\controller.exe controller.exe COPY --from=pktmon-builder C:\\pktmon\\controller-pktmon.exe controller-pktmon.exe COPY --from=builder C:\\retina\\captureworkload.exe captureworkload.exe -CMD ["controller.exe"] \ No newline at end of file +CMD ["controller.exe"] diff --git a/controller/Dockerfile.windows-retina-oss-build b/controller/Dockerfile.windows-retina-oss-build index 26391be94e..868c1fdd09 100644 --- a/controller/Dockerfile.windows-retina-oss-build +++ b/controller/Dockerfile.windows-retina-oss-build @@ -2,11 +2,11 @@ ARG OS_VERSION=ltsc2022 # pinned base images -# mcr.microsoft.com/windows/servercore:ltsc2019 +# skopeo inspect docker://mcr.microsoft.com/windows/servercore:ltsc2019 --override-os windows --format "{{.Name}}@{{.Digest}}" FROM mcr.microsoft.com/windows/servercore@sha256:8077f3e5b0987c388735917f0d15a3dd5fc773f8b5699c612ccb539d42644185 AS ltsc2019 -# mcr.microsoft.com/windows/servercore:ltsc2022 -FROM mcr.microsoft.com/windows/servercore@sha256:e000e9a1712065a0218447c20ae19984b447fa741d11cf64696b8a1172fcd7da AS ltsc2022 +# skopeo inspect docker://mcr.microsoft.com/windows/servercore:ltsc2022 --override-os windows --format "{{.Name}}@{{.Digest}}" +FROM mcr.microsoft.com/windows/servercore@sha256:e000e9a1712065a0218447c20ae19984b447fa741d11cf64696b8a1172fcd7da AS ltsc2022 FROM ${OS_VERSION} AS agent-win @@ -20,9 +20,12 @@ ENV GOOS=${GOOS} ENV OS_VERSION=${OS_VERSION} ENV BINARIES_PATH=${BINARIES_PATH} ENV REPO_PATH=${REPO_PATH} +# CVE-2013-3900 Mitigation +RUN reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\Wintrust\Config" /v "EnableCertPaddingCheck" /t REG_DWORD /d "1" /f +RUN reg add "HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config" /v "EnableCertPaddingCheck" /t REG_DWORD /d "1" /f COPY ${REPO_PATH}/retina/windows/kubeconfigtemplate.yaml kubeconfigtemplate.yaml COPY ${REPO_PATH}/retina/windows/setkubeconfigpath.ps1 setkubeconfigpath.ps1 COPY ${BINARIES_PATH}/captureworkload.exe captureworkload.exe COPY ${BINARIES_PATH}/controller.exe controller.exe ADD https://github.com/microsoft/etl2pcapng/releases/download/v1.10.0/etl2pcapng.exe /etl2pcapng.exe -CMD ["controller.exe", "start", "--kubeconfig=.\\kubeconfig"] \ No newline at end of file +CMD ["controller.exe", "start", "--kubeconfig=.\\kubeconfig"] diff --git a/go.mod b/go.mod index 04293b2404..2424c0a2cb 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/microsoft/retina -go 1.24.2 +go 1.24.3 require ( github.com/go-chi/chi/v5 v5.2.1 @@ -260,7 +260,6 @@ require ( require ( github.com/Azure/azure-container-networking/zapai v0.0.3 - github.com/Azure/azure-sdk-for-go v68.0.0+incompatible github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0 @@ -351,6 +350,7 @@ require ( github.com/Antonboom/errname v1.0.0 // indirect github.com/Antonboom/nilnil v1.0.1 // indirect github.com/Antonboom/testifylint v1.5.2 // indirect + github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.10.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.4.0 // indirect diff --git a/go.sum b/go.sum index 9d447abbe1..60ccb1d15b 100644 --- a/go.sum +++ b/go.sum @@ -478,8 +478,6 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/cli v26.0.0+incompatible h1:90BKrx1a1HKYpSnnBFR6AgDq/FqkHxwlUyzJVPxD30I= github.com/docker/cli v26.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= diff --git a/hack/tools/kapinger/Dockerfile b/hack/tools/kapinger/Dockerfile index 97394bac09..738c66f92c 100644 --- a/hack/tools/kapinger/Dockerfile +++ b/hack/tools/kapinger/Dockerfile @@ -1,30 +1,32 @@ -FROM --platform=linux/amd64 mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2 AS builder +# Linux builder - runs natively on the target platform (amd64 or arm64) +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2 --format "{{.Name}}@{{.Digest}}" +FROM mcr.microsoft.com/oss/go/microsoft/golang:1.26.2@sha256:61e607875d60ae21a7a4a49110fe7098355473fbc74ab13091e3c1160cc92f18 AS builder WORKDIR /build ADD . . -RUN go mod download +RUN go mod download +RUN go build -o kapinger . && mkdir -p /lib64 -# Build for Linux -RUN CGO_ENABLED=0 GOOS=linux go build -o kapinger . - -# Build for Windows -RUN CGO_ENABLED=0 GOOS=windows go build -o kapinger.exe . - -# Build for ARM64 Linux -RUN CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o kapinger-arm64 . - -FROM --platform=linux/amd64 scratch AS linux-amd64 +FROM scratch AS linux +COPY --from=builder /lib/ /lib +COPY --from=builder /lib64/ /lib64 +COPY --from=builder /usr/lib/ /usr/lib WORKDIR /app COPY --from=builder /build/kapinger . CMD ["./kapinger"] -FROM --platform=windows/amd64 mcr.microsoft.com/windows/servercore:ltsc2022 AS windows-amd64 +# Windows builder - cross-compiles from Linux amd64 (GOOS=windows is not affected by systemcrypto) +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:1.26.2@sha256:61e607875d60ae21a7a4a49110fe7098355473fbc74ab13091e3c1160cc92f18 AS windows-builder + +WORKDIR /build +ADD . . +RUN go mod download +RUN GOOS=windows go build -o kapinger.exe . + +# skopeo inspect docker://mcr.microsoft.com/windows/servercore:ltsc2022 --override-os windows --format "{{.Name}}@{{.Digest}}" +FROM mcr.microsoft.com/windows/servercore:ltsc2022@sha256:e000e9a1712065a0218447c20ae19984b447fa741d11cf64696b8a1172fcd7da AS windows WORKDIR /app -COPY --from=builder /build/kapinger.exe . +COPY --from=windows-builder /build/kapinger.exe . ENTRYPOINT [ "cmd.exe" ] CMD [ "/c", "kapinger.exe" ] - -FROM --platform=linux/arm64 scratch AS linux-arm64 -WORKDIR /app -COPY --from=builder /build/kapinger-arm64 . -CMD ["./kapinger-arm64"] diff --git a/hack/tools/toolbox/Dockerfile b/hack/tools/toolbox/Dockerfile index ab2a9f4c13..ae7e35b662 100644 --- a/hack/tools/toolbox/Dockerfile +++ b/hack/tools/toolbox/Dockerfile @@ -1,9 +1,11 @@ -FROM mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2 AS build +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2 --format "{{.Name}}@{{.Digest}}" +FROM mcr.microsoft.com/oss/go/microsoft/golang:1.26.2@sha256:61e607875d60ae21a7a4a49110fe7098355473fbc74ab13091e3c1160cc92f18 AS build ADD . . WORKDIR /go/toolbox/ -RUN CGO_ENABLED=0 GOOS=linux go build -o server . +RUN GOOS=linux go build -o server . -FROM mcr.microsoft.com/mirror/docker/library/ubuntu:24.04 +# skopeo inspect docker://mcr.microsoft.com/mirror/docker/library/ubuntu:24.04 --format "{{.Name}}@{{.Digest}}" +FROM mcr.microsoft.com/mirror/docker/library/ubuntu:24.04@sha256:c35e29c9450151419d9448b0fd75374fec4fff364a27f176fb458d472dfc9e54 RUN apt-get update RUN apt-get install -y \ axel \ diff --git a/operator/Dockerfile b/operator/Dockerfile index 7fd3c0b3b3..01fc869817 100644 --- a/operator/Dockerfile +++ b/operator/Dockerfile @@ -1,5 +1,5 @@ -# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2-cbl-mariner2.0 --format "{{.Name}}@{{.Digest}}" -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:5341a0010ecff114ee2f11f5eaa4f73b721b54142954041523f3e785d5c4b978 AS builder +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0@sha256:257614fe59a6e7fb56909eec9a59a6d0d0794a331ebc1d6dc93aa8ef995d34f5 AS builder ARG VERSION ARG APP_INSIGHTS_ID @@ -7,7 +7,6 @@ ARG APP_INSIGHTS_ID WORKDIR /workspace COPY . . -# Install jq, not sure why this went missing in the 1.24.1-2-cbl-mariner2.0 base go image. RUN tdnf install -y jq # Default linux/architecture. @@ -25,11 +24,12 @@ RUN --mount=type=cache,target="/root/.cache/go-build" \ -a -o retina-operator operator/main.go ##################### controller ####################### -# mcr.microsoft.com/cbl-mariner/distroless/minimal:2.0 -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/cbl-mariner/distroless/minimal@sha256:db87903c5d4d9d6760e86a274914efd6a3bb5914c0b5a6c6b35350ec297fea4f +# skopeo inspect docker://mcr.microsoft.com/azurelinux/distroless/minimal:3.0 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/azurelinux/distroless/minimal:3.0@sha256:5a66f9f16ac675db2a8229dac72d83811b73b502d6ad192d8b374c7f3be498af WORKDIR / COPY --from=builder /lib /lib COPY --from=builder /usr/lib/ /usr/lib +COPY --from=builder /etc/pki/tls/ /etc/pki/tls/ COPY --from=builder /workspace/retina-operator . USER 65532:65532 diff --git a/operator/Dockerfile.windows-2019 b/operator/Dockerfile.windows-2019 index b9a28bb094..65097f97d7 100644 --- a/operator/Dockerfile.windows-2019 +++ b/operator/Dockerfile.windows-2019 @@ -1,5 +1,5 @@ -# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2-cbl-mariner2.0 --format "{{.Name}}@{{.Digest}}" -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:5341a0010ecff114ee2f11f5eaa4f73b721b54142954041523f3e785d5c4b978 AS builder +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.4-azurelinux3.0 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:250d01e55a37bd79d7014ae83f9f50aa6fa5570ca910e7f19faeff4bb0132ae1 AS builder # Build args ARG VERSION @@ -15,7 +15,8 @@ COPY . . RUN --mount=type=cache,target="/root/.cache/go-build" go build -v -ldflags "-X github.com/microsoft/retina/internal/buildinfo.Version="$VERSION" -X "github.com/microsoft/retina/internal/buildinfo.ApplicationInsightsID"="$APP_INSIGHTS_ID"" -o -o /usr/bin/retina-operator.exe retina-operator operator/main.go # Copy into final image -FROM mcr.microsoft.com/windows/nanoserver:ltsc2019 +# skopeo inspect docker://mcr.microsoft.com/windows/nanoserver:ltsc2019 --override-os windows --format "{{.Name}}@{{.Digest}}" +FROM mcr.microsoft.com/windows/nanoserver@sha256:7c720f345ff7784cee12a5464bb5d5222c6348bd6da2cd29d666e49867958b0e COPY --from=builder /usr/src/retina/windows/kubeconfigtemplate.yaml kubeconfigtemplate.yaml COPY --from=builder /usr/src/retina/windows/setkubeconfigpath.ps1 setkubeconfigpath.ps1 diff --git a/operator/Dockerfile.windows-2022 b/operator/Dockerfile.windows-2022 index deccdca314..2b77ab6f63 100644 --- a/operator/Dockerfile.windows-2022 +++ b/operator/Dockerfile.windows-2022 @@ -1,5 +1,5 @@ -# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2-cbl-mariner2.0 --format "{{.Name}}@{{.Digest}}" -FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:5341a0010ecff114ee2f11f5eaa4f73b721b54142954041523f3e785d5c4b978 AS builder +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0 --format "{{.Name}}@{{.Digest}}" +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0@sha256:257614fe59a6e7fb56909eec9a59a6d0d0794a331ebc1d6dc93aa8ef995d34f5 AS builder # Build args ARG VERSION @@ -15,7 +15,8 @@ COPY . . RUN --mount=type=cache,target="/root/.cache/go-build" go build -v -ldflags "-X github.com/microsoft/retina/internal/buildinfo.Version="$VERSION" -X "github.com/microsoft/retina/internal/buildinfo.ApplicationInsightsID"="$APP_INSIGHTS_ID"" -o -o /usr/bin/retina-operator.exe retina-operator operator/main.go # Copy into final image -FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 +# skopeo inspect docker://mcr.microsoft.com/windows/nanoserver:ltsc2022 --override-os windows --format "{{.Name}}@{{.Digest}}" +FROM mcr.microsoft.com/windows/nanoserver:ltsc2022@sha256:3680dad0bb773da8efcd9d928eaf4e33817875ab71a43792640ab1bcc0b3c074 COPY --from=builder /usr/src/retina/windows/kubeconfigtemplate.yaml kubeconfigtemplate.yaml COPY --from=builder /usr/src/retina/windows/setkubeconfigpath.ps1 setkubeconfigpath.ps1 diff --git a/shell/Dockerfile b/shell/Dockerfile index 74f1716259..deedfdb9be 100644 --- a/shell/Dockerfile +++ b/shell/Dockerfile @@ -1,5 +1,5 @@ # skopeo inspect docker://mcr.microsoft.com/azurelinux/base/core:3.0 --format "{{.Name}}@{{.Digest}}" -FROM mcr.microsoft.com/azurelinux/base/core@sha256:9948138108a3d69f1dae62104599ac03132225c3b7a5ac57b85a214629c8567d +FROM mcr.microsoft.com/azurelinux/base/core:3.0@sha256:35149ae8dd179684f969944f54a337c665a64e702486154eb44253fb39c2505b RUN tdnf install -y \ bind-utils \ @@ -28,16 +28,20 @@ RUN tdnf install -y \ tar \ file \ bpftool \ + bpftrace \ ig \ && tdnf clean all -# Create the entrypoint script to mount debugfs +# Create the entrypoint script to mount debugfs and tracefs SHELL ["/bin/bash", "-c"] RUN echo $'#!/bin/bash\n\ if ! mountpoint -q /sys/kernel/debug; then\n\ mount -t debugfs none /sys/kernel/debug\n\ fi\n\ +if ! mountpoint -q /sys/kernel/tracing; then\n\ +mount -t tracefs tracefs /sys/kernel/tracing\n\ +fi\n\ exec "$@"' > /usr/local/bin/entrypoint.sh; # Set the host root directory for IG @@ -53,7 +57,7 @@ ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] ARG GOARCH=amd64 ENV ARCH=${GOARCH} # https://github.com/cilium/pwru/releases -ARG PWRU_TAG="v1.0.9" +ARG PWRU_TAG="v1.0.11" ENV PWRU_TAG=${PWRU_TAG} # Download and extract latest pwru release for the correct architecture (amd64 or arm64) diff --git a/test/image/Dockerfile b/test/image/Dockerfile index b17e6e4004..979b0b0516 100644 --- a/test/image/Dockerfile +++ b/test/image/Dockerfile @@ -1,10 +1,10 @@ # build stage -# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.24.2-2-cbl-mariner2.0 --format "{{.Name}}@{{.Digest}}" -FROM mcr.microsoft.com/oss/go/microsoft/golang@sha256:5341a0010ecff114ee2f11f5eaa4f73b721b54142954041523f3e785d5c4b978 AS builder -ENV CGO_ENABLED=0 +# skopeo inspect docker://mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0 --format "{{.Name}}@{{.Digest}}" +FROM mcr.microsoft.com/oss/go/microsoft/golang:1.26.2-azurelinux3.0@sha256:637bcd53d7c139d2fa54d8d6e2bb3f9346b3ab1c9f03bb33ea56c3964d458f1b AS builder +ENV CGO_ENABLED=1 COPY . /go/src/github.com/microsoft/retina WORKDIR /go/src/github.com/microsoft/retina -RUN tdnf install -y clang16 lld16 bpftool libbpf-devel make git jq +RUN tdnf install -y clang lld bpftool libbpf-devel make git jq RUN go generate /go/src/github.com/microsoft/retina/pkg/plugin/... # RUN go mod edit -module retina # RUN make all generate