version: '3' vars: OUTPUT_DIR: '_output' GO_TAGS: '-tags "no_grpc"' LDFLAGS: '-s -w' GO_LDFLAGS: '-ldflags "{{.LDFLAGS}}"' # Map Go's GOARCH to the kernel arch naming convention (amd64 → x86_64). KERNEL_ARCH: sh: 'a=$(go env GOARCH); case "$a" in amd64) echo x86_64;; *) echo "$a";; esac' tasks: default: desc: Build all outputs via Docker Buildx Bake deps: [build] # # Build tasks # build: desc: Build all outputs via Docker Buildx Bake cmds: - HOST_OS={{OS}} KERNEL_ARCH={{.KERNEL_ARCH}} docker buildx bake build:shim: desc: "Build containerd-shim-nerdbox-v1. Override target with GOOS/GOARCH env vars for cross-compilation." vars: # Resolve target GOOS/GOARCH: env vars override, then fall back to # the Go toolchain's native values. TARGET_GOOS: sh: 'if [ -n "$GOOS" ]; then echo "$GOOS"; else go env GOOS; fi' TARGET_GOARCH: sh: 'if [ -n "$GOARCH" ]; then echo "$GOARCH"; else go env GOARCH; fi' TARGET_SUFFIX: '{{if eq .TARGET_GOOS "windows"}}.exe{{end}}' cmds: - mkdir -p {{.OUTPUT_DIR}} - GOOS={{.TARGET_GOOS}} GOARCH={{.TARGET_GOARCH}} go build {{.GO_TAGS}} {{.GO_LDFLAGS}} -o {{.OUTPUT_DIR}}/containerd-shim-nerdbox-v1{{.TARGET_SUFFIX}} ./cmd/containerd-shim-nerdbox-v1 - cmd: codesign --entitlements cmd/containerd-shim-nerdbox-v1/containerd-shim-nerdbox-v1.entitlements --force -s - {{.OUTPUT_DIR}}/containerd-shim-nerdbox-v1 platforms: [darwin] build:guest: desc: Build guest artifacts (kernel and rootfs) via Docker Buildx Bake cmds: - KERNEL_ARCH={{.KERNEL_ARCH}} docker buildx bake kernel rootfs build:rootfs: desc: Build the nerdbox erofs rootfs via Docker Buildx Bake cmds: - KERNEL_ARCH={{.KERNEL_ARCH}} docker buildx bake rootfs build:integration: desc: Build the integration test binary cmds: - mkdir -p {{.OUTPUT_DIR}} - go test -c -o {{.OUTPUT_DIR}}/integration.test{{if eq OS "windows"}}.exe{{end}} {{.GO_LDFLAGS}} {{.GO_TAGS}} ./integration - cmd: codesign --entitlements cmd/containerd-shim-nerdbox-v1/containerd-shim-nerdbox-v1.entitlements --force -s - {{.OUTPUT_DIR}}/integration.test platforms: [darwin] build:testbin: desc: Build the testbin container binary (always linux) for use in shim and stress test suites cmds: - mkdir -p test/shim/testdata test/stress/testdata - CGO_ENABLED=0 GOOS=linux GOARCH={{.GOARCH}} go build -ldflags='-s -w' -o test/shim/testdata/testbin ./test/testbin/ - cp test/shim/testdata/testbin test/stress/testdata/testbin vars: GOARCH: sh: go env GOARCH sources: - test/testbin/main.go - vendor/github.com/containerd/shimtest/testbin/testbin.go generates: - test/shim/testdata/testbin - test/stress/testdata/testbin # # Test tasks # test:unit: desc: Run unit tests (excludes integration and shim test packages) cmds: - go test -count=1 ./api/... ./cmd/... ./internal/... ./pkg/... ./plugins/... test:fuzz: desc: "Run all fuzz targets for a short duration (default 60s each). Override with FUZZTIME env var: FUZZTIME=30s task test:fuzz" vars: FUZZTIME: '{{default "60s" .FUZZTIME}}' cmds: - cmd: | # Find all packages containing fuzz tests and run each target. # go test -fuzz only accepts one package at a time and one # matching fuzz target, so we discover and iterate. grep -r --include='*_test.go' -l '^func Fuzz' . --exclude-dir=test | while read -r file; do pkg=$(dirname "$file") grep -o '^func Fuzz[A-Za-z0-9_]*' "$file" | sed 's/^func //' | while read -r target; do echo "=== Fuzzing ${target} in ${pkg} ===" go test "${pkg}" -fuzz="^${target}$" -fuzztime={{.FUZZTIME}} done done platforms: [linux, darwin] test:integration: desc: "Run integration tests (each test in its own process). Extra flags are forwarded to the test binary: task test:integration -- -run TestSystemInfo -v" deps: [build:integration] vars: # When -v is in the extra flags, switch gotestsum to standard-verbose so # t.Log() output is shown; otherwise testname format suppresses it. GOTESTSUM_FORMAT: sh: | case " {{.CLI_ARGS}} " in *" -v "*|*" -v") echo standard-verbose ;; *) echo testname ;; esac env: TESTFLAGS: '{{.CLI_ARGS}}' cmds: - cmd: gotestsum -f {{.GOTESTSUM_FORMAT}} --raw-command bash integration/test.sh platforms: [darwin, linux] - cmd: gotestsum -f {{.GOTESTSUM_FORMAT}} --raw-command powershell -ExecutionPolicy Bypass -File integration/test.ps1 platforms: [windows] test:shim: desc: "Run shimtest conformance suites against containerd-shim-nerdbox-v1. Builds the shim first. Extra go test flags can be passed after --: task test:shim -- -run TestShim/Exec -v" deps: [build:shim, build:testbin] cmds: - go test {{.GO_TAGS}} -count=1 -timeout 120s {{.CLI_ARGS}} ./test/shim/... test:stress:lifecycle: desc: "Stress-test container lifecycle (create/start/run/kill/delete) for one timeout period (default 10m). Extra flags: task test:stress:lifecycle -- -timeout 20m -v" deps: [build:shim, build:testbin] cmds: - go test {{.GO_TAGS}} -count=1 -run TestShimStress/Lifecycle {{.CLI_ARGS}} ./test/stress/... test:stress:exec: desc: "Stress-test exec inside a running container for one timeout period (default 10m), monitoring for leaks. Extra flags: task test:stress:exec -- -timeout 20m -v" deps: [build:shim, build:testbin] cmds: - go test {{.GO_TAGS}} -count=1 -run TestShimStress/Exec {{.CLI_ARGS}} ./test/stress/... test:stress:transfer: desc: "Stress-test the transfer service (concurrent stat/write/read) for one timeout period (default 10m). Extra flags: task test:stress:transfer -- -timeout 20m -v" deps: [build:shim, build:testbin] cmds: - go test {{.GO_TAGS}} -count=1 -run TestShimStress/Transfer {{.CLI_ARGS}} ./test/stress/... test:stress: desc: "Run all stress tests sequentially, each in its own process with the default 10m timeout (30m total). Extra flags apply to every invocation: task test:stress -- -timeout 20m -v" deps: [build:shim] cmds: - task: test:stress:lifecycle vars: {CLI_ARGS: '{{.CLI_ARGS}}'} - task: test:stress:exec vars: {CLI_ARGS: '{{.CLI_ARGS}}'} - task: test:stress:transfer vars: {CLI_ARGS: '{{.CLI_ARGS}}'} # # Code quality tasks # validate: desc: Validate via Docker Buildx Bake cmds: - docker buildx bake validate lint: desc: Run linters via Docker Buildx Bake cmds: - docker buildx bake lint protos: desc: Regenerate protobuf bindings dir: api cmds: - buf generate - buf build --exclude-imports -o next.txtpb - go-fix-acronym -w -a '^Os' $(find . -name '*.pb.go') - go-fix-acronym -w -a '(Id|Io|Uuid|Os)$' $(find . -name '*.pb.go') generate: desc: Regenerate all derived artifacts (protobuf) deps: [protos] check-protos: desc: Verify protobuf bindings are up to date deps: [protos] cmds: - cmd: | if [ -n "$(git status --short | grep ".pb.go")" ]; then git diff | cat echo "please run 'task protos' when making changes to proto files" exit 1 fi check-api-descriptors: desc: Verify protobuf descriptor files are up to date deps: [protos] cmds: - cmd: | if [ -n "$(git status --short | grep ".txtpb")" ]; then git diff $(find ./api/ -name '*.txtpb') | cat echo "please run 'task protos' when making changes to proto files and check-in the generated descriptor file changes" exit 1 fi proto-fmt: desc: Check proto files use tabs (not spaces) for indentation cmds: - cmd: | if [ -n "$(find ./api/ -name '*.proto' -type f -exec grep -Hn -e "^ " {} \;)" ]; then echo "please indent proto files with tabs only" exit 1 fi verify-vendor: desc: Verify go.mod/go.sum and vendor directory are up to date cmds: - cmd: | tmpdir=$(mktemp -d) cp -R . "$tmpdir/nerdbox" (cd "$tmpdir/nerdbox" && go mod tidy && go mod verify) diff -r -u . "$tmpdir/nerdbox" || (rm -rf "$tmpdir" && exit 1) rm -rf "$tmpdir" # # Clean # clean: desc: Remove all build outputs cmds: - rm -rf {{.OUTPUT_DIR}}