This document provides a guide for agents developing in the cri-tools repository.
cri-tools is a set of command-line tools for interacting with CRI (Container Runtime Interface) compatible container runtimes. The project is written in Go and uses the Ginkgo testing framework for its extensive test suite.
To contribute to this project, you will need a Go development environment.
To test code you need to have a functioning container runtime installed. The two popular container runtimes are Containerd and CRI-O.
The project uses make for building and running tests.
Before completing any task, agents must verify their changes by running make verify and ensuring relevant tests pass (see the Testing section).
Failure to run these checks may result in CI failures.
If your patch depends on new packages, add that package to the go.mod file,
run make vendor and commit the changes.
To build the critest binary, run the following command:
make critestTo build crictl run:
make crictlTo build the crictl e2e tests binary, run:
make crictl-e2eTo install the recommended linter (golangci-lint), run:
make install.lintThe right way to run linter in this repository is using makefile:
make verify-lintIf you encounter linting issues, first attempt to automatically fix them by lint-fix target:
make lint-fixRemoving linter rules or adding linter ignore directives must be the last resort. The detailed explanation must be added to each ignore directive.
Prettier is used to maintain consistent formatting, primarily for Markdown files. To use these targets, you must have the Node.js toolchain (npm and npx) installed on your system.
To install Prettier locally, run:
make install.prettierTo verify the formatting (highly recommended when modifying .md files), run:
make verify-prettierTo automatically fix formatting issues, run:
make prettier-fixZizmor is a static analyzer for GitHub Actions workflows. It runs as part
of make verify (and the linters CI matrix), and new findings will fail
the build.
To install zizmor locally, run:
make install.zizmorTo run zizmor against .github/workflows/, run:
make verify-zizmorThere is no auto-fix target — findings must be fixed by hand. When a
finding is a confirmed false positive, suppress it with an inline
# zizmor: ignore[<rule>] comment on the offending line, and put a short
justification on the line above.
The test suite is built on top of the Ginkgo testing framework. To run the tests, you will need to first build the critest binary and then execute it.
The tests can be run in parallel to speed up execution. The following command runs the tests in parallel with 8 processes (replace <GOOS> and <GOARCH> with your operating system and architecture, e.g., linux and amd64):
sudo PATH="$PATH:$(pwd)/build/bin/<GOOS>/<GOARCH>" ./build/bin/<GOOS>/<GOARCH>/critest --ginkgo.vv --parallel=8This is how tests will run on CI/CD. In order to run a single test while debugging, run the following command:
sudo PATH="$PATH:$(pwd)/build/bin/<GOOS>/<GOARCH>" ./build/bin/<GOOS>/<GOARCH>/critest --ginkgo.vv --ginkgo.focus="<regex_to_match_test_description>"If you don't have a local container runtime installed, you can run the tests in a container using Docker. This will build a local image with containerd and run the tests inside it. This approach doesn't require sudo if your user has access to Docker.
Note: AppArmor tests must be skipped as the containerized environment does not support them. The make targets below already include the skip flag.
To run all critest validation tests:
make test-critest-containerdTo run crictl e2e tests:
make test-crictl-e2e-containerdYou can pass TESTFLAGS to focus on a specific test.
make test-critest-containerd TESTFLAGS='--ginkgo.focus="public image"'Or for crictl e2e:
make test-crictl-e2e-containerd TESTFLAGS='--ginkgo.focus="pull"'By default the image builds containerd from source at the main git ref,
matching CI's primary matrix entry (NRI enabled, --parallel=8). Pass
CONTAINERD_VERSION to test another ref, and RUNC_FLAVOR / RUNTIME to
change the runtime:
make test-critest-containerd CONTAINERD_VERSION=release/1.7
make test-critest-containerd CONTAINERD_VERSION=main RUNC_FLAVOR=cruncritest runs with --parallel=8 by default (mirroring CI); override with
make test-critest-containerd PARALLEL=4.
The built image is tagged per version (containerd-local-test:<version>, with
-<flavor> appended for a non-default RUNC_FLAVOR, e.g.
containerd-local-test:main-crun) and each version gets its own data volume,
so images are cached and reused across runs — only a changed
CONTAINERD_VERSION/RUNC_FLAVOR triggers a rebuild. Set FORCE_REBUILD=1 to
force a fresh build that bypasses the Docker layer cache (--no-cache --pull),
which is needed to refetch a moving ref such as main. To delete the cached
images and volumes so they are regenerated:
make clean-containerd-test-imagesSome tests are sensitive to parallel execution and may fail due to race conditions. To avoid these issues, you can run the tests serially by adding the Serial decorator to the test case in the source code.
For example, to run a test serially, modify the test case as follows:
It("should not fail on simultaneous RemoveImage calls [Conformance]", Serial, func() {
// ...
})The project's CI/CD pipeline is defined in the .github/workflows directory. The containerd.yml file defines the workflow for running tests against containerd.
The containerd.yml workflow runs tests against different versions of containerd on both Linux and Windows. It also tests against different runtimes and CNI configurations.
- After Release — Update the master branch after a release is created