Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.*
*

# Keep in sync with the paths in .github/workflows/ci.yaml.
!src/
!files/
113 changes: 49 additions & 64 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -1,100 +1,85 @@
name: Build

on:
pull_request:
branches:
- main
push:
branches:
- main
tags:
- v?*
workflow_call:
inputs:
registry:
type: string
required: true
description: The registry to push the image to.
image-owner:
type: string
required: true
description: The owner of the image.
image-name:
type: string
required: true
description: The name of the image.
image-tag:
type: string
required: true
description: The tag of the image.
secrets:
registry-username:
description: The username for the registry.
registry-password:
description: The password for the registry.

jobs:
build:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04

steps:
- name: Prepare
id: prep
run: |
# If this is a git tag, use the tag name as a docker tag
if [[ $GITHUB_REF == refs/tags/v?* ]]; then
registry=quay.io
name="$GITHUB_REPOSITORY"
tag="${GITHUB_REF#refs/tags/v}"
tag="${tag//+/-}"
else
registry=ttl.sh
name="${GITHUB_REPOSITORY//\//-}-$GITHUB_SHA-$GITHUB_RUN_ID"
tag=1d
fi

{
echo registry="$registry"
echo name="$name"
echo tag="$tag"
} >>"$GITHUB_OUTPUT"
id: prepare
env:
# GitHub Actions doesn't seem to support the secrets
# context in if fields, hence this workaround.
REGISTRY_CREDENTIALS_AVAILABLE: "${{ case(secrets.registry-username != '', 'true', '') }}"
run: echo registry-credentials-available="$REGISTRY_CREDENTIALS_AVAILABLE" >>"$GITHUB_OUTPUT"

- name: Set up QEMU
uses: docker/setup-qemu-action@v3.6.0
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
with:
platforms: amd64,arm64,arm,riscv64

- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3.10.0
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0

- name: Build OCI image archive
id: build
uses: docker/build-push-action@v6.16.0
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
with:
builder: ${{ steps.buildx.outputs.name }}
platforms: linux/amd64,linux/arm64,linux/arm,linux/riscv64
tags: ${{ format('{0}/{1}:{2}', steps.prep.outputs.registry, steps.prep.outputs.name, steps.prep.outputs.tag) }}
tags: ${{ format('{0}/{1}/{2}:{3}', inputs.registry, inputs.image-owner, inputs.image-name, inputs.image-tag) }}
outputs: type=oci,dest=oci-image.tar

- name: Compress OCI image archive
# Pre-compress the image archive so that the upload-artifact action
# doesn't try to do it. The layers inside the tar archive are themselves
# already gzip compressed, so this is not for size reduction, but solely
# to prevent the very slow compression process in the upload-artifact
# action.
# See: https://github.com/actions/upload-artifact/issues/199
# See: https://github.com/actions/toolkit/blob/6c1f9eaae833355a0b212b66c5f2e3ac366de185/packages/artifact/src/internal/upload-gzip.ts#L11-L33
# Might be fixed when upload-artifact@v4 gets released: https://github.com/actions/toolkit/pull/1488
run: zstdmt --fast oci-image.tar

- name: Upload OCI image archive
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: oci-image.tar.zst
path: oci-image.tar.zst
name: ${{ format('{0}-{1}.tar', inputs.image-name, inputs.image-tag) }}
path: oci-image.tar
# The layers inside the tar archive are themselves already gzip
# compressed. No need to compress the metadata. Speeds things up a
# bit.
compression-level: 0

- name: Extract OCI image archive
run: mkdir image && tar xf oci-image.tar.zst -C image/

- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.30.0
with:
input: image/
format: table
list-all-pkgs: "true" # Flags a warning, but prints out stuff nevertheless
exit-code: "1"
run: mkdir image && tar xf oci-image.tar -C image/

- name: Log in to registry
if: steps.prep.outputs.registry != 'ttl.sh'
uses: redhat-actions/podman-login@v1
if: steps.prepare.outputs.registry-credentials-available
uses: redhat-actions/podman-login@4934294ad0449894bcd1e9f191899d7292469603 # v1.7
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
registry: ${{ steps.prep.outputs.registry }}
registry: ${{ inputs.registry }}
username: ${{ secrets.registry-username }}
password: ${{ secrets.registry-password }}

- name: Upload OCI image to registry
env:
REGISTRY: ${{ steps.prep.outputs.registry }}
NAME: ${{ steps.prep.outputs.name }}
TAG: ${{ steps.prep.outputs.tag }}
IMAGE: ${{ format('{0}/{1}/{2}:{3}', inputs.registry, inputs.image-owner, inputs.image-name, inputs.image-tag) }}
run: |
podmanArgs=(-v "$(realpath oci-image.tar):/image.tar:ro")
skopeoArgs=(--multi-arch all --preserve-digests)
Expand All @@ -107,4 +92,4 @@ jobs:
set -x
podman run "${podmanArgs[@]}" \
docker://quay.io/skopeo/stable:v1.18.0 copy "${skopeoArgs[@]}" \
oci-archive:/image.tar "docker://$REGISTRY/$NAME:$TAG"
oci-archive:/image.tar "docker://$IMAGE"
27 changes: 27 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: CI

on:
pull_request: &triggers
branches:
- main
- release-*
paths:
- .github/workflows/ci.yaml
- .github/workflows/build.yaml
- Dockerfile
- .dockerignore
# keep in sync with .dockerignore
- src/**
- files/**
push: *triggers

jobs:
build:
name: Build OCI image
uses: ./.github/workflows/build.yaml
with:
# This will produce images tagged like ttl.sh/k0sproject/cni-node-27741332811-1:1d.
registry: ttl.sh
image-owner: ${{ github.repository_owner }}
image-name: ${{ format('{0}-{1}-{2}', github.event.repository.name, github.run_id, github.run_attempt) }}
image-tag: 1d
4 changes: 2 additions & 2 deletions .github/workflows/dco.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout k0s
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v5
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}

Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Release

on:
push:
tags:
- v?*

jobs:
build:
name: Build OCI image
uses: ./.github/workflows/build.yaml
with:
registry: quay.io
image-owner: ${{ github.repository_owner }}
image-name: ${{ github.event.repository.name }}
image-tag: ${{ github.ref_name }}
secrets:
registry-username: ${{ secrets.DOCKER_USERNAME }}
registry-password: ${{ secrets.DOCKER_PASSWORD }}
36 changes: 9 additions & 27 deletions .github/workflows/scan.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ name: Security scan
on:
schedule:
- cron: 0 2 * * 1-5
release:
types:
- published
workflow_dispatch:

jobs:
Expand All @@ -14,46 +11,31 @@ jobs:
security-events: write # upload sarif results

steps:
- name: Prepare
id: prep
- name: Determine latest release
id: latest-release
if: github.event.release.tag_name == ''
env:
PUBLISHED_TAG: ${{ github.event.release.tag_name }}
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
run: |
if [ -n "$PUBLISHED_TAG" ]; then
gitTag="$PUBLISHED_TAG"
else
# Get the tag name from the latest GitHub release
gitTag="$(gh api repos/{owner}/{repo}/releases/latest --jq .tag_name)"
fi

# Determine OCI image tag
imageTag="${gitTag//+/-}"
imageTag="${imageTag#v}"

{
echo git-tag="$gitTag"
echo image-tag="$imageTag"
} >>"$GITHUB_OUTPUT"
run: gh api 'repos/{owner}/{repo}/releases/latest' --jq '"tag-name=\(.tag_name)"' >>"$GITHUB_OUTPUT"

# The checkout is solely required for the upload-sarif action. It needs to
# know the ref and sha. Providing those manually won't work, for unknown
# reasons.
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
ref: ${{ format('refs/tags/{0}', steps.prep.outputs.git-tag) }}
ref: ${{ format('refs/tags/{0}', github.event.release.tag_name || steps.latest-release.outputs.tag-name) }}
persist-credentials: false

- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.12.0
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
image-ref: ${{ format('quay.io/{0}:{1}', github.repository, steps.prep.outputs.image-tag) }}
image-ref: ${{ format('quay.io/{0}:{1}', github.repository, github.event.release.tag_name || steps.latest-release.outputs.tag-name) }}
format: sarif
output: trivy-results.sarif

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
uses: github/codeql-action/upload-sarif@b8d3b6e8af63cde30bdc382c0bc28114f4346c88 # v2.28.1
with:
sarif_file: trivy-results.sarif
53 changes: 28 additions & 25 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
ARG \
ALPINE_IMAGE=docker.io/library/alpine:3.22.2 \
GOLANG_IMAGE=docker.io/library/golang:1.25.2-alpine \
ALPINE_IMAGE=docker.io/library/alpine:3.22.7 \
GOLANG_IMAGE=docker.io/library/golang:1.26.10-alpine3.23 \
VERSION=1.8.0 \
HASH=f0510b4452dda4b08d4b088d02e005ac507cb96fb7247b4422ae591286390369

FROM --platform=$BUILDPLATFORM $GOLANG_IMAGE AS bins
FROM --platform=$BUILDPLATFORM $GOLANG_IMAGE AS sources
RUN apk add --no-cache patch
ENV GOTOOLCHAIN=local GOTELEMETRY=off
WORKDIR /go/src/containernetworking-plugins
ARG VERSION HASH

RUN wget https://github.com/containernetworking/plugins/archive/refs/tags/v${VERSION}.tar.gz \
&& { echo "${HASH} *v${VERSION}.tar.gz" | sha256sum -c -; } \
&& tar xf "v${VERSION}.tar.gz" -C /go \
&& rm -- "v${VERSION}.tar.gz"

WORKDIR /go/plugins-$VERSION

ARG TARGETPLATFORM
RUN set -x \
&& apk add bash \
&& mkdir -p /opt/stage/usr/local/bin \
&& case "${TARGETPLATFORM-~}" in \
linux/amd64) export GOARCH=amd64 ;; \
linux/arm64) export GOARCH=arm64 ;; \
linux/arm/v7) export GOARCH=arm ;; \
linux/riscv64) export GOARCH=riscv64 ;; \
~);; \
*) echo Unsupported target platform: "$TARGETPLATFORM" >&2; exit 1;; \
esac \
&& CGO_ENABLED=0 ./build_linux.sh -trimpath -buildvcs=false \
RUN --mount=source=files/patches,target=/run/patches,ro \
--mount=type=tmpfs,target=/tmp \
set -euo pipefail \
&& wget -qO /tmp/sources.tar.gz https://github.com/containernetworking/plugins/archive/refs/tags/v$VERSION.tar.gz \
&& { echo $HASH /tmp/sources.tar.gz | sha256sum -c -; } || { sha256sum /tmp/sources.tar.gz; exit 1; } \
&& tar xf /tmp/sources.tar.gz --strip-components=1 \
&& for p in /run/patches/*.patch; do \
[ "$p" != '/run/patches/*.patch' ] || { echo No patches found.; break; }; \
echo Applying "$p" >&2; \
patch -p1 <"$p"; \
done

# Re-vendor the dependencies, as the patches may have touched go.mod/go.sum
RUN go mod vendor


FROM sources AS bins
ARG TARGETARCH SOURCE_DATE_EPOCH
RUN --mount=type=cache,id=calico-gocache-$TARGETARCH,target=/root/.cache/go-build \
--network=none \
CGO_ENABLED=0 GOARCH=$TARGETARCH ./build_linux.sh -trimpath -buildvcs=false \
-ldflags "-s -w -extldflags -static -X github.com/containernetworking/plugins/pkg/utils/buildversion.BuildVersion=v$VERSION"


Expand All @@ -45,6 +48,6 @@ LABEL org.opencontainers.image.licenses="Apache-2.0" \
org.opencontainers.image.source="https://github.com/k0sproject/cni-node"
COPY --from=baselayout / /
ARG VERSION
COPY --from=bins /go/plugins-$VERSION/bin/ /opt/cni/bin/
COPY --from=bins /go/src/containernetworking-plugins/bin/ /opt/cni/bin/
ENTRYPOINT ["/bin/cni-node"]
CMD ["install"]
Empty file added files/patches/.keep
Empty file.
Loading
Loading