From d3a1feb4f2c14558d1d817bda257c6ab1d4745d0 Mon Sep 17 00:00:00 2001 From: Muvaffak Onus Date: Wed, 15 May 2024 12:03:18 +0300 Subject: [PATCH] github: move builds out of Dockerfile to remove arm64 emulation overhead Signed-off-by: Muvaffak Onus --- .github/workflows/crik-publish.yaml | 210 ++++++++++++------ .gitignore | 2 + .../Chart.yaml | 2 +- .../templates/manager-deployment.yaml | 0 .../templates/manager-permissions.yaml | 0 .../values.yaml | 2 +- cmd/crik/Dockerfile | 37 +-- cmd/manager/Dockerfile | 22 -- cmd/node-state-server/Dockerfile | 8 + cmd/{manager => node-state-server}/main.go | 0 go.sum | 2 - 11 files changed, 152 insertions(+), 133 deletions(-) rename cluster/charts/{crik-node-state-server => node-state-server}/Chart.yaml (76%) rename cluster/charts/{crik-node-state-server => node-state-server}/templates/manager-deployment.yaml (100%) rename cluster/charts/{crik-node-state-server => node-state-server}/templates/manager-permissions.yaml (100%) rename cluster/charts/{crik-node-state-server => node-state-server}/values.yaml (51%) delete mode 100644 cmd/manager/Dockerfile create mode 100644 cmd/node-state-server/Dockerfile rename cmd/{manager => node-state-server}/main.go (100%) diff --git a/.github/workflows/crik-publish.yaml b/.github/workflows/crik-publish.yaml index c20793a..be04ff2 100644 --- a/.github/workflows/crik-publish.yaml +++ b/.github/workflows/crik-publish.yaml @@ -1,101 +1,163 @@ -name: publish crik - +name: Build and Push Images on: push: branches: - - "main" + - main tags: - - "v*" + - "*" env: - REGISTRY: ghcr.io - REGISTRY_IMAGE: ghcr.io/${{ github.repository }} + GO_VERSION: 1.22.2 jobs: - build: + version: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Calculate version + id: version + run: | + if [ -z "$(git tag)" ]; then + echo "No tags found" + echo "VERSION=$(echo "v0.0.0-$(git rev-list HEAD --count)-$(git describe --dirty --always)" | sed 's/-/./2' | sed 's/-/./2' | sed 's/-/./2')" >> $GITHUB_OUTPUT + else + echo "Tags found: $(git tag)" + echo "VERSION=$(git describe --dirty --always --tags --match 'v*' | sed 's|.*/||' | sed 's/-/./2' | sed 's/-/./2' | sed 's/-/./2')" >> $GITHUB_OUTPUT + fi + images: runs-on: ubuntu-latest + needs: version permissions: - contents: read packages: write + contents: read + id-token: write + attestations: write strategy: - fail-fast: false matrix: - platform: - - linux/amd64 - - linux/arm64 + app: [crik, node-state-server] steps: - - name: Prepare - run: | - platform=${{ matrix.platform }} - echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - - name: Checkout repository + - name: Checkout uses: actions/checkout@v4 - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 + - name: Setup Go + uses: actions/setup-go@v5 with: - images: ${{ env.REGISTRY_IMAGE }} - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + go-version: ${{ env.GO_VERSION }} + cache: false + - name: Find the Go Environment + id: go + run: | + echo "cache=$(go env GOCACHE)" >> $GITHUB_OUTPUT + echo "mod=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT + + - name: Cache Go Dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.go.outputs.mod }} + key: mod-cache-${{ hashFiles('**/go.sum') }} + restore-keys: mod-cache- + + - name: Cache Go Build Cache + uses: actions/cache@v4 + with: + path: ${{ steps.go.outputs.cache }} + key: build-cache-${{ matrix.app }}-${{ hashFiles('**/go.sum') }} + restore-keys: build-cache-${{ matrix.app }}- + + - name: Check if code-gen changes anything + run: | + go generate ./... + git diff --exit-code && echo "generated code is up to date" || (echo "go generate resulted in changes" && git diff && exit 1) + + - name: Build + env: + PLATFORMS: linux/amd64,linux/arm64 + run: | + for platform in $(echo $PLATFORMS | tr "," "\n"); do + export os=$(echo $platform | cut -d'/' -f1) + export arch=$(echo $platform | cut -d'/' -f2) + echo "Building for $os/$arch" + CGO_ENABLED=0 GOOS=${os} GOARCH=${arch} go build -o .work/bin/${{ matrix.app }}-${os}-${arch} cmd/${{ matrix.app }}/main.go & + done + wait + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Log in to the Github Container Registry - uses: docker/login-action@v3 + - name: Login to Github Container Registry + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + - name: Generate metadata for images + uses: docker/metadata-action@v5 + id: metadata with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push by digest - id: build + images: ghcr.io/qawolf/crik/${{ matrix.app }} + tags: | + type=ref,event=branch + type=sha,format=short,prefix= + ${{ steps.version.outputs.VERSION }} + - name: Build and push + id: push uses: docker/build-push-action@v5 with: context: . - file: cmd/crik/Dockerfile - platforms: ${{ matrix.platform }} - labels: ${{ steps.meta.outputs.labels }} - outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true - - name: Export digest - run: | - mkdir -p /tmp/digests - digest="${{ steps.build.outputs.digest }}" - touch "/tmp/digests/${digest#sha256:}" - - name: Upload digest - uses: actions/upload-artifact@v4 - with: - name: digests-${{ env.PLATFORM_PAIR }} - path: /tmp/digests/* - if-no-files-found: error - retention-days: 1 + file: cmd/${{ matrix.app }}/Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.metadata.outputs.tags }} + labels: ${{ steps.metadata.outputs.labels }} - merge: + - name: Attest + uses: actions/attest-build-provenance@v1 + with: + subject-name: ghcr.io/qawolf/crik/${{ matrix.app }} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true + chart: + permissions: + packages: write + contents: read + id-token: write runs-on: ubuntu-latest needs: - - build + - images + strategy: + matrix: + chart: [node-state-server] steps: - - name: Download digests - uses: actions/download-artifact@v4 - with: - path: /tmp/digests - pattern: digests-* - merge-multiple: true - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY_IMAGE }} - - name: Log in to the Github Container Registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Create manifest list and push - working-directory: /tmp/digests - run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) - - name: Inspect image + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Helm + uses: azure/setup-helm@v4 + - name: Log in to GitHub Container Registry + run: echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin + - name: Install yq + uses: dcarbone/install-yq-action@v1.1.1 + - name: Push the chart + id: push + env: + VERSION: ${{ steps.version.outputs.VERSION }} run: | - docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} \ No newline at end of file + # Helm doesn't accept v prefix in version. + TAG=$(echo ${{ steps.version.outputs.VERSION }} | cut -d'v' -f2) + if [ "${{ matrix.chart }}" == "node-state-server" ]; then + yq -i ".nodeStateServer.image.tag = \"${VERSION}\"" cluster/charts/${{ matrix.chart }}/values.yaml + echo "Final values.yaml" + cat cluster/charts/${{ matrix.chart }}/values.yaml + fi + helm dependency update cluster/charts/${{ matrix.chart }} + helm package cluster/charts/${{ matrix.chart }} --dependency-update --version=${VERSION} --app-version=${VERSION} + OUT=$(set +e; helm push ${{ matrix.chart }}-${VERSION}.tgz oci://ghcr.io/qawolf/crik/charts 2>&1) + EXIT_CODE=$? + set -e + echo "${OUT}" + if [[ $EXIT_STATUS -ne 0 ]]; then + exit $EXIT_STATUS + fi + DIGEST=$(echo ${OUT}| sed -n 's/.*sha256:\([^ ]*\).*/sha256:\1/p') + echo "digest=${DIGEST}" >> "$GITHUB_OUTPUT" + + - name: Attest + uses: actions/attest-build-provenance@v1 + with: + subject-name: ghcr.io/qawolf/crik/charts/${{ matrix.chart }} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true diff --git a/.gitignore b/.gitignore index 7a7feec..3a9b882 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ go.work *.swp *.swo *~ + +.work diff --git a/cluster/charts/crik-node-state-server/Chart.yaml b/cluster/charts/node-state-server/Chart.yaml similarity index 76% rename from cluster/charts/crik-node-state-server/Chart.yaml rename to cluster/charts/node-state-server/Chart.yaml index 5d33960..19c1ff8 100644 --- a/cluster/charts/crik-node-state-server/Chart.yaml +++ b/cluster/charts/node-state-server/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v2 -name: crik-node-state-server +name: node-state-server version: 0.1.0 description: A Helm chart for the Node State Server used by crik. diff --git a/cluster/charts/crik-node-state-server/templates/manager-deployment.yaml b/cluster/charts/node-state-server/templates/manager-deployment.yaml similarity index 100% rename from cluster/charts/crik-node-state-server/templates/manager-deployment.yaml rename to cluster/charts/node-state-server/templates/manager-deployment.yaml diff --git a/cluster/charts/crik-node-state-server/templates/manager-permissions.yaml b/cluster/charts/node-state-server/templates/manager-permissions.yaml similarity index 100% rename from cluster/charts/crik-node-state-server/templates/manager-permissions.yaml rename to cluster/charts/node-state-server/templates/manager-permissions.yaml diff --git a/cluster/charts/crik-node-state-server/values.yaml b/cluster/charts/node-state-server/values.yaml similarity index 51% rename from cluster/charts/crik-node-state-server/values.yaml rename to cluster/charts/node-state-server/values.yaml index 1456621..c8451da 100644 --- a/cluster/charts/crik-node-state-server/values.yaml +++ b/cluster/charts/node-state-server/values.yaml @@ -1,5 +1,5 @@ nodeStateServer: debug: false image: - repository: ghcr.io/qawolf/crik-node-state-server + repository: ghcr.io/qawolf/crik/node-state-server tag: v0.1.0 diff --git a/cmd/crik/Dockerfile b/cmd/crik/Dockerfile index 58ce6fc..2b44c6c 100644 --- a/cmd/crik/Dockerfile +++ b/cmd/crik/Dockerfile @@ -1,37 +1,8 @@ -FROM golang:1.22 as build +FROM gcr.io/distroless/static-debian12:nonroot ARG TARGETOS ARG TARGETARCH -WORKDIR /build +COPY .work/bin/crik-${TARGETOS}-${TARGETARCH} /usr/local/bin/crik +USER 65532 -COPY go.mod go.mod -COPY go.sum go.sum -RUN go mod download - -COPY cmd cmd -COPY internal internal - -RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o crik cmd/crik/main.go && \ - chmod +x crik - - -FROM ubuntu:22.04 - -RUN apt-get update && apt-get install --no-install-recommends --yes gnupg curl ca-certificates - -RUN curl "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x4E2A48715C45AEEC077B48169B29EEC9246B6CE2" | gpg --dearmor > /usr/share/keyrings/criu-ppa.gpg \ - && echo "deb [signed-by=/usr/share/keyrings/criu-ppa.gpg] https://ppa.launchpadcontent.net/criu/ppa/ubuntu jammy main" > /etc/apt/sources.list.d/criu.list \ - && apt-get update \ - && apt-get install --no-install-recommends --yes criu iptables - -# The PR https://github.com/checkpoint-restore/criu/pull/2360 is not merged yet, so we use criu from the docker image -# built from the PR. This is necessary if you get sched policy error during restore, which is the case with webkit-based -# browsers. - -#RUN apt-get update \ -# && apt install --no-install-recommends --yes libprotobuf-dev libprotobuf-c-dev protobuf-c-compiler protobuf-compiler python3-protobuf iptables nftables iproute2 libnftables-dev libcap-dev libnl-3-dev libnet-dev libaio-dev -#COPY --from=docker.io/muvaf/criu-x86_64:rst0git-6673a3b /criu/criu/criu /usr/sbin/criu - -COPY --from=build /build/crik /usr/local/bin/crik - -ENTRYPOINT ["crik", "run", "--"] +ENTRYPOINT ["crik"] diff --git a/cmd/manager/Dockerfile b/cmd/manager/Dockerfile deleted file mode 100644 index 3125939..0000000 --- a/cmd/manager/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM golang:1.22 as builder -ARG TARGETOS -ARG TARGETARCH - -WORKDIR /workspace - -COPY go.mod go.mod -COPY go.sum go.sum -RUN go mod download - -COPY cmd/ cmd/ -COPY internal/ internal/ - -RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/manager/main.go - -FROM gcr.io/distroless/static:nonroot -WORKDIR / -COPY --from=builder /workspace/manager . - -USER 65532:65532 - -ENTRYPOINT ["/manager"] diff --git a/cmd/node-state-server/Dockerfile b/cmd/node-state-server/Dockerfile new file mode 100644 index 0000000..ee45ab6 --- /dev/null +++ b/cmd/node-state-server/Dockerfile @@ -0,0 +1,8 @@ +FROM gcr.io/distroless/static-debian12:nonroot +ARG TARGETOS +ARG TARGETARCH + +COPY .work/bin/node-state-server-${TARGETOS}-${TARGETARCH} /usr/local/bin/node-state-server +USER 65532 + +ENTRYPOINT ["node-state-server"] diff --git a/cmd/manager/main.go b/cmd/node-state-server/main.go similarity index 100% rename from cmd/manager/main.go rename to cmd/node-state-server/main.go diff --git a/go.sum b/go.sum index 35c2824..db40a95 100644 --- a/go.sum +++ b/go.sum @@ -122,8 +122,6 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=