diff --git a/.github/workflows/images.yaml b/.github/workflows/images.yaml index d0b0b41921..7987794729 100644 --- a/.github/workflows/images.yaml +++ b/.github/workflows/images.yaml @@ -69,6 +69,7 @@ jobs: matrix: platform: ["windows"] arch: ["amd64"] + year: ["2019", "2022"] steps: - name: Checkout code @@ -101,11 +102,13 @@ jobs: IMAGE_NAMESPACE=${{ github.repository }} \ PLATFORM=${{ matrix.platform }}/${{ matrix.arch }} \ IMAGE_REGISTRY=${{ vars.ACR_NAME }} \ + YEAR=${{ matrix.year }} \ BUILDX_ACTION=--push else make retina-image-win \ IMAGE_NAMESPACE=${{ github.repository }} \ - PLATFORM=${{ matrix.platform }}/${{ matrix.arch }} + PLATFORM=${{ matrix.platform }}/${{ matrix.arch }} \ + WINDOWS_YEARS=${{ matrix.year }} fi env: IS_MERGE_GROUP: ${{ github.event_name == 'merge_group' }} diff --git a/.pipelines/cg-pipeline.yaml b/.pipelines/cg-pipeline.yaml index 71f6fa0be6..97c2692ac6 100644 --- a/.pipelines/cg-pipeline.yaml +++ b/.pipelines/cg-pipeline.yaml @@ -2,16 +2,14 @@ pr: none trigger: none schedules: -- cron: '0 0 * * *' - displayName: Daily midnight Retina OSS CG pipeline - branches: - include: - - main - - vakr/newadocg - + - cron: "0 0 * * *" + displayName: Daily midnight Retina OSS CG pipeline + branches: + include: + - main stages: - stage: setup - displayName: Retina Setup + displayName: Linux Buildx jobs: - job: env displayName: Setup @@ -43,4 +41,159 @@ stages: fi name: "EnvironmentalVariables" displayName: "Set environmental variables" - condition: always() \ No newline at end of file + condition: always() + + - job: retinaagentimages + displayName: Build Retina Agent Images + pool: + name: "$(BUILD_POOL_NAME_DEFAULT)" + strategy: + matrix: + agent-linux-arm: + platform: "linux" + arch: "arm64" + target: "agent" + + agent-linux-amd64: + platform: "linux" + arch: "amd64" + target: "agent" + + init-linux-arm: + platform: "linux" + arch: "arm64" + target: "init" + + init-linux-amd64: + platform: "linux" + arch: "amd64" + target: "init" + + steps: + - checkout: self + fetchTags: true + - script: | + set -euo pipefail + echo "VERSION=$(make version)" + export VERSION=$(make version) + mkdir -p ./output/images/$(platform)/$(arch)/$(year) + make retina-image \ + AGENT_TARGETS=$(target) \ + TAG=$(make version) \ + IMAGE_NAMESPACE=retina \ + PLATFORM=$(platform)/$(arch) \ + IMAGE_REGISTRY=ghcr.io/microsoft \ + BUILDX_ACTION="-o type=docker,dest=./output/images/$(platform)/$(arch)/retina-$(target)-$VERSION-$(platform)-$(arch).tar" + # make manifest-skopeo-archive IMAGE_ARCHIVE_DIR=$(Build.ArtifactStagingDirectory)/images + displayName: "Build Retina Linux Images" + + - bash: | + mkdir -p $(Build.ArtifactStagingDirectory) + cp -r output/* $(Build.ArtifactStagingDirectory) + displayName: "Copy binaries to the binaries artifact folder" + + - task: PublishBuildArtifacts@1 + inputs: + artifactName: output + pathtoPublish: "$(Build.ArtifactStagingDirectory)" + condition: succeeded() + + - job: retinaoperatorimages + displayName: Build Retina Operator Images + pool: + name: "$(BUILD_POOL_NAME_DEFAULT)" + strategy: + matrix: + operator-linux-amd64: + platform: "linux" + arch: "amd64" + + steps: + - checkout: self + fetchTags: true + - script: | + set -euo pipefail + echo "VERSION=$(make version)" + export VERSION=$(make version) + mkdir -p ./output/images/$(platform)/$(arch)/$(year) + make retina-operator-image \ + TAG=$(make version) \ + IMAGE_NAMESPACE=retina \ + PLATFORM=$(platform)/$(arch) \ + IMAGE_REGISTRY=ghcr.io/microsoft \ + BUILDX_ACTION="-o type=docker,dest=./output/images/$(platform)/$(arch)/retina-operator-$VERSION-$(platform)-$(arch).tar" + displayName: "Build Retina Operator Linux Images" + + - bash: | + mkdir -p $(Build.ArtifactStagingDirectory) + cp -r output/* $(Build.ArtifactStagingDirectory) + displayName: "Copy binaries to the binaries artifact folder" + + - task: PublishBuildArtifacts@1 + inputs: + artifactName: output + pathtoPublish: "$(Build.ArtifactStagingDirectory)" + condition: succeeded() + + # windows 2019 only in buildx, windows server 2022 requires native windows container build because of cgo + - job: retinaagentimageswin2019 + displayName: Build Retina Windows Images (buildx) + pool: + name: "$(BUILD_POOL_NAME_DEFAULT)" + strategy: + matrix: + windows-ltsc2019: + platform: "windows" + arch: "amd64" + year: "2019" + + steps: + - checkout: self + fetchTags: true + - script: | + set -euo pipefail + echo "VERSION=$(make version)" + export VERSION=$(make version) + mkdir -p ./output/images/$(platform)/$(arch)/$(year) + make retina-image-win \ + TARGET=final \ + WINDOWS_YEARS=$(year) \ + TAG=$(make version) \ + BUILDX_ACTION="-o type=docker,dest=./output/images/$(platform)/$(arch)/$(year)/retina-agent-$VERSION-windows-ltsc$(year)-$(arch).tar" + displayName: "Build Retina Windows Image" + + - task: PublishBuildArtifacts@1 + inputs: + artifactName: output + pathtoPublish: ./output + condition: succeeded() + + - job: windowsnative + displayName: Build Retina Windows Images (native) + pool: + name: "$(BUILD_POOL_NAME_WINDOWS_DEFAULT)" + steps: + - checkout: self + fetchTags: true + + - task: Docker@2 + displayName: Docker Login + inputs: + containerRegistry: $(WINDOWS_BUILDER_REGISTRY) + command: "login" + addPipelineData: false + + - task: PowerShell@2 + displayName: "Build Retina Windows Image (LTSC2022)" + inputs: + targetType: "inline" + script: | + Import-Module -Name "$(Build.SourcesDirectory)\windows\docker\DockerBuildModule.psm1" -Force + Build-RetinaAgentImage -fullBuilderImageName $(WINDOWS_BUILDER_IMAGE) -registry $(BUILD_REGISTRY) + Save-Image -imageName retina-agent -registry $(BUILD_REGISTRY) + + - task: PublishBuildArtifacts@1 + inputs: + artifactName: output + pathtoPublish: ./output + condition: succeeded() diff --git a/Makefile b/Makefile index 355d44562a..0ffb838d0c 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,11 @@ ALL_ARCH.windows = amd64 # while RETINA_PLATFORM_TAG is platform specific, which can be used for image built for specific platforms. RETINA_PLATFORM_TAG ?= $(TAG)-$(subst /,-,$(PLATFORM)) +# used for looping through components in container build +AGENT_TARGETS ?= init agent + +WINDOWS_YEARS ?= "2019 2022" + # for windows os, add year to the platform tag ifeq ($(OS),windows) RETINA_PLATFORM_TAG = $(TAG)-windows-ltsc$(YEAR)-amd64 @@ -53,8 +58,14 @@ endif qemu-user-static: ## Set up the host to run qemu multiplatform container builds. sudo $(CONTAINER_RUNTIME) run --rm --privileged multiarch/qemu-user-static --reset -p yes +.PHONY: version version: ## prints the root version - @echo $(TAG) + @if [ "$(shell git tag --points-at HEAD)" != "" ]; then \ + export VERSION="$$(git tag --points-at HEAD)"; \ + else \ + export VERSION="$$(git rev-parse --short HEAD)"; \ + fi; \ + echo "$${VERSION}" ##@ Help @@ -192,6 +203,11 @@ retina-skopeo-export: REF=$(IMAGE_REGISTRY)/$(RETINA_IMAGE):$(RETINA_PLATFORM_TAG) \ IMG=$(RETINA_IMAGE) TAG=$(RETINA_PLATFORM_TAG) + + +manifest-skopeo-archive: # util target to export tar archive of multiarch container manifest. + skopeo copy --all docker://$(IMAGE_REGISTRY)/$(IMAGE):$(TAG) oci-archive:$(IMAGE_ARCHIVE_DIR)/$(IMAGE)-$(TAG).tar --debug + buildx: if docker buildx inspect retina > /dev/null 2>&1; then \ @@ -203,6 +219,8 @@ buildx: echo "Buildx instance retina created."; \ fi; + + container-docker: buildx # util target to build container images using docker buildx. do not invoke directly. os=$$(echo $(PLATFORM) | cut -d'/' -f1); \ arch=$$(echo $(PLATFORM) | cut -d'/' -f2); \ @@ -211,7 +229,6 @@ container-docker: buildx # util target to build container images using docker bu touch $$image_metadata_filename; \ echo "Building $$image_name for $$os/$$arch "; \ docker buildx build \ - $(BUILDX_ACTION) \ --platform $(PLATFORM) \ --metadata-file=$$image_metadata_filename \ -f $(DOCKERFILE) \ @@ -222,12 +239,13 @@ container-docker: buildx # util target to build container images using docker bu --build-arg VERSION=$(VERSION) $(EXTRA_BUILD_ARGS) \ --target=$(TARGET) \ -t $(IMAGE_REGISTRY)/$(IMAGE):$(TAG) \ - $(CONTEXT_DIR) + $(BUILDX_ACTION) \ + $(CONTEXT_DIR) + retina-image: ## build the retina linux container image. echo "Building for $(PLATFORM)" - set -e ; \ - for target in init agent; do \ + for target in $(AGENT_TARGETS); do \ echo "Building for $$target"; \ if [ "$$target" = "init" ]; then \ image_name=$(RETINA_INIT_IMAGE); \ @@ -247,7 +265,7 @@ retina-image: ## build the retina linux container image. done retina-image-win: ## build the retina Windows container image. - for year in 2019 2022; do \ + for year in $(WINDOWS_YEARS); do \ tag=$(TAG)-windows-ltsc$$year-amd64; \ echo "Building $(RETINA_PLATFORM_TAG)"; \ set -e ; \ diff --git a/controller/Dockerfile.windows-2019 b/controller/Dockerfile.windows-2019 new file mode 100644 index 0000000000..988d53ec57 --- /dev/null +++ b/controller/Dockerfile.windows-2019 @@ -0,0 +1,25 @@ +FROM --platform=linux/amd64 mcr.microsoft.com/oss/go/microsoft/golang:1.21 as builder +# Build args +ARG VERSION +ARG APP_INSIGHTS_ID + +ENV GOOS=windows +ENV GOARCH=amd64 + +WORKDIR /usr/src/retina +# Copy the source +COPY . . + +RUN --mount=type=cache,target="/root/.cache/go-build" go build -v -o /usr/bin/controller.exe -ldflags "-X main.version="$VERSION" -X "main.applicationInsightsID"="$APP_INSIGHTS_ID"" ./controller/ +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 +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-2022 b/controller/Dockerfile.windows-2022 new file mode 100644 index 0000000000..da2d68824c --- /dev/null +++ b/controller/Dockerfile.windows-2022 @@ -0,0 +1,26 @@ +FROM --platform=linux/amd64 mcr.microsoft.com/oss/go/microsoft/golang:1.21 as builder + +# Build args +ARG VERSION +ARG APP_INSIGHTS_ID + +ENV GOOS=windows +ENV GOARCH=amd64 + +WORKDIR /usr/src/retina +# Copy the source +COPY . . + +RUN --mount=type=cache,target="/root/.cache/go-build" go build -v -o /usr/bin/controller.exe -ldflags "-X main.version="$VERSION" -X "main.applicationInsightsID"="$APP_INSIGHTS_ID"" ./controller/ +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:ltsc2022 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 new file mode 100644 index 0000000000..b58e5208a2 --- /dev/null +++ b/controller/Dockerfile.windows-cgo @@ -0,0 +1,20 @@ +FROM --platform=windows/amd64 mcr.microsoft.com/oss/go/microsoft/golang:1.22.2-windowsservercore-ltsc2022 as cgo + +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \ + Invoke-WebRequest -UseBasicParsing -uri "https://github.com/msys2/msys2-installer/releases/download/2024-01-13/msys2-base-x86_64-20240113.sfx.exe" -OutFile msys2.exe; \ + .\msys2.exe -y -oC:\; \ + Remove-Item msys2.exe ; \ + function msys() { C:\msys64\usr\bin\bash.exe @('-lc') + @Args; } \ + msys ' '; \ + msys 'pacman --noconfirm -Syuu'; \ + msys 'pacman --noconfirm -S mingw-w64-x86_64-gcc'; \ + msys 'pacman --noconfirm -Scc'; + +# pure magic: https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/3f7c7ed7ef8d582c74ec740414c54f25bf5850c0/windows-container-samples/golang/Dockerfile#L15C1-L15C179 +RUN setx path "C:\msys64\mingw64\bin" + +FROM cgo as builder +WORKDIR C:\\pktmon +COPY .\\pkg\\plugin\\windows\\pktmon\\packetmonitorsupport . diff --git a/controller/Dockerfile.windows-native b/controller/Dockerfile.windows-native new file mode 100644 index 0000000000..d0ce4138f4 --- /dev/null +++ b/controller/Dockerfile.windows-native @@ -0,0 +1,35 @@ +# This dockerfile requires building natively on windows +# It can't be placed in the other Windows Dockerfile, as those use +# buildx targets, and this one requires legacy build. +# Maybe one day: https://github.com/moby/buildkit/issues/616 + +ARG BUILDER_IMAGE +FROM --platform=windows/amd64 ${BUILDER_IMAGE} as builder +# Build args +WORKDIR C:\\retina +RUN gcc.exe --version +RUN go version +COPY go.mod . +COPY go.sum . +ENV CGO_ENABLED=1 +RUN go mod download +RUN go mod verify +ADD . . +RUN cp -r c:/pktmon/ pkg/plugin/windows/pktmon/packetmonitorsupport/ +RUN ls pkg/plugin/windows/pktmon/packetmonitorsupport/ +ARG VERSION +ARG APP_INSIGHTS_ID +SHELL ["cmd", "/S", "/C"] +ENV VERSION=$VERSION +ENV APP_INSIGHTS_ID=$APP_INSIGHTS_ID + +RUN go build -v -o controller.exe -ldflags="-X main.version=%VERSION% -X main.applicationInsightsID=%APP_INSIGHTS_ID%" .\controller +RUN go build -v -o captureworkload.exe -ldflags="-X main.version=%VERSION% -X main.applicationInsightsID=%APP_INSIGHTS_ID%" .\captureworkload + + +FROM --platform=windows/amd64 mcr.microsoft.com/windows/nanoserver:ltsc2022 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\\controller.exe controller.exe +COPY --from=builder C:\\retina\\captureworkload.exe captureworkload.exe +CMD ["controller.exe"] diff --git a/controller/Dockerfile.windows-native.dockerignore b/controller/Dockerfile.windows-native.dockerignore new file mode 100644 index 0000000000..32287a00ac --- /dev/null +++ b/controller/Dockerfile.windows-native.dockerignore @@ -0,0 +1,2 @@ +pkg/plugin/windows/pktmon/packetmonitorsupport/* +*.tar diff --git a/deploy/manifests/controller/helm/retina/templates/daemonset.yaml b/deploy/manifests/controller/helm/retina/templates/daemonset.yaml index 9930a52d7a..c712ca9405 100644 --- a/deploy/manifests/controller/helm/retina/templates/daemonset.yaml +++ b/deploy/manifests/controller/helm/retina/templates/daemonset.yaml @@ -163,9 +163,7 @@ spec: containerPort: {{ .Values.retinaPort }} workingDir: $env:CONTAINER_SANDBOX_MOUNT_POINT command: - - powershell.exe - - -command - - .\setkubeconfigpath.ps1; ./controller.exe --config ./retina/config.yaml --kubeconfig ./kubeconfig + - controller.exe --config ./retina/config.yaml env: - name: POD_NAME valueFrom: diff --git a/windows/docker/DockerBuild.ps1 b/windows/docker/DockerBuild.ps1 new file mode 100644 index 0000000000..b3d5bbc7cf --- /dev/null +++ b/windows/docker/DockerBuild.ps1 @@ -0,0 +1,17 @@ +# Import the DockerBuildModule +#Import-Module -Name .\DockerBuildModule.psm1 +$ErrorActionPreference = "Stop" + +Build-RetinaBuilderImage -version "v2" + +# Get the version for the Retina builder image +$builderVersion = Get-GitVersion + +# Define the builder image version you want to use +#$customBuilderImageVersion = "custom-version" + +# Define the full custom builder image name with the custom version +$customBuilderImageName = "$defaultRegistry/retina-builder:$customBuilderImageVersion" + +# Call the Build-RetinaAgentImage function with the custom builder image name +Build-RetinaAgentImage diff --git a/windows/docker/DockerBuildModule.psm1 b/windows/docker/DockerBuildModule.psm1 new file mode 100644 index 0000000000..4fc1a747d2 --- /dev/null +++ b/windows/docker/DockerBuildModule.psm1 @@ -0,0 +1,70 @@ +# DockerBuildModule.psm1 +$ErrorActionPreference = "Stop" +function Get-GitVersion { + # Get the SHA of the current commit + $sha = git rev-parse --short HEAD + + # Get the latest tag if available + $tag = git describe --tags --abbrev=0 2>$null + + # Check if the current commit is tagged + $isTaggedCommit = git tag --contains $sha + + if ($isTaggedCommit) { + # If the current commit is tagged, return the tag + return $tag + } + else { + # If the current commit is not tagged, return the current tag followed by the SHA + return $sha + } +} + + +function Build-RetinaAgentImage { + param( + [string]$imageName = "retina-agent", + [string]$tag = "$(Get-GitVersion)-windows-ltsc2022-amd64", + [string]$appInsightsID = "", + [Parameter(Mandatory = $true)][string]$fullBuilderImageName = "", + [Parameter(Mandatory = $true)][string]$registry = "" + ) + + # Get the version using the Get-GitVersion function + $version = Get-GitVersion + + # Hardcoded file path for Retina agent Dockerfile + $filePath = "controller/Dockerfile.windows-native" + + # Full image name with registry, image name, and version + $fullImageName = "${registry}/${imageName}:$tag" + + Write-Host "Building Retina agent Docker image $fullImageName with builder image $fullBuilderImageName" + + # Building the Retina agent Docker image with a build argument + docker build -f $filePath -t $fullImageName --target final --build-arg BUILDER_IMAGE="$fullBuilderImageName" --build-arg VERSION=$version --build-arg APP_INSIGHTS_ID="$appInsightsID" . +} + + +function Save-Image { + param( + [Parameter(Mandatory = $true)][string]$imageName, + [string]$tag = "$(Get-GitVersion)-windows-ltsc2022-amd64", + [Parameter(Mandatory = $true)][string]$registry = "", + [string]$directory = "./output/images/windows/amd64/2022" + ) + + + New-Item -ItemType Directory -Path $directory -Force + + $savePath = "$directory/$imageName-$tag.tar" + + $fullImageName = "${registry}/${imageName}:$tag" + + Write-Host "Saving Docker image $fullImageName to $savePath" + + docker save -o $savePath $fullImageName + Write-Host "Docker image saved to $savePath" +} + +Export-ModuleMember -Function Get-GitVersion, Build-RetinaBuilderImage, Build-RetinaAgentImage, Save-Image diff --git a/windows/docker/notes.md b/windows/docker/notes.md new file mode 100644 index 0000000000..59e52aaf53 --- /dev/null +++ b/windows/docker/notes.md @@ -0,0 +1 @@ +# Used for CI, but also useful locally