Open-Source Wikis

/

containerd

/

Background

/

v2 reorganization

containerd/containerd

v2 reorganization

The directory layout you see today is the result of a deliberate reorganization carried out in early 2024. This page explains what changed and why.

Before v2

In containerd 1.x, the repository root held the containerd package. Every file at the root (container.go, client.go, task.go, image.go, …) was imported as github.com/containerd/containerd. Subpackages were sprawling: images/, snapshots/, runtime/, metadata/, etc. all sat at the root, mingling user-facing types with daemon internals.

This had a few painful consequences:

  • The Go module's import path (github.com/containerd/containerd) was the same as the root package, making the root a hot zone for breaking changes.
  • Internal-only daemon code was importable from the outside (people accidentally took dependencies on packages they shouldn't have).
  • containerd config dump had to know about every config struct, but those structs lived next to their plugins, scattered around the tree.

What changed

The v2 reorg, done in a burst of move-only commits in January–February 2024, did the following:

  • Renamed the module from github.com/containerd/containerd to github.com/containerd/containerd/v2.
  • Moved the embeddable client from the repository root to client/ (preserving the type names).
  • Moved core subsystem interfaces (and their built-in implementations) into core/ (core/content, core/images, core/runtime, core/snapshots, core/sandbox, core/transfer, core/diff, core/leases, core/metadata, core/mount, core/metrics, core/remotes, core/streaming, core/unpack).
  • Moved daemon-internal packages into internal/ (most importantly the CRI plugin in internal/cri/).
  • Forbade source files at the repository root from this point forward (only configuration and build files allowed).

The blamed commits include:

  • 21b4f3f0a "Move content to core/content"
  • 9456048f4 "Move containers to core/containers"
  • 913edcd48 "Move diff to core/diff"
  • 57ea8aef3 "Move images to core/images"
  • f80760f9f "Move leases to core/leases"
  • 1a1e0e8c8 "Move metadata to core/metadata"
  • 6e5408dce "Move mount to core/mount"
  • 0dabf6f15 "Move remotes to core/remotes"
  • 228ad5a5c "Move sandbox to core/sandbox"
  • fcd39ccc5 "Move snapshots to core/snapshots"
  • df9b0a067 "Move metrics to core/metrics"
  • dbc74db6a "Move runtime to core/runtime"
  • f46aea618 (Feb 2024) "Move transfer and unpack packages"
  • 72f21833b (Feb 2024) "Move events to plugins and core"

What stayed

  • pkg/ — reusable helpers, kept as-is.
  • api/ — already a separate module, kept.
  • cmd/ — already had per-binary subdirectories, kept.
  • defaults/, version/ — small leaf packages, kept.

What this means for contributors

CONTRIBUTING.md codifies the rule:

Try to put a new package under the appropriate root directories. The root directory is reserved for configuration and build files, no source files will be accepted in root since containerd v2.0.

The directory you choose now matters for visibility:

  • core/ — interface + built-ins, importable by plugins and clients
  • pkg/ — generic helpers, importable by anyone
  • internal/ — daemon-internal, not importable outside this module (Go enforces this)
  • client/ — public Go embedding API
  • plugins/ — register-by-import plugin code

Migration helper

contrib/v2-migrate.sh is a sed-on-imports script for downstream consumers updating from v1.x to v2.x. It rewrites github.com/containerd/containerd (and the well-known subpackage paths) to their v2 equivalents.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

v2 reorganization – containerd wiki | Factory