Skip to content

[pull] main from containerd:main - #58

Open
pull[bot] wants to merge 291 commits into
fahedouch:mainfrom
containerd:main
Open

pull[bot] wants to merge 291 commits into
fahedouch:mainfrom
containerd:main

Conversation

@pull

@pull pull Bot commented Aug 5, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

@pull pull Bot locked and limited conversation to collaborators Aug 5, 2026
@pull pull Bot added the ⤵️ pull label Aug 5, 2026
akhilerm and others added 28 commits August 11, 2026 15:09
This reverts commit 21248d0.

Signed-off-by: Akhil Mohan <akhilerm@gmail.com>
Signed-off-by: Akhil Mohan <akhilerm@gmail.com>
…put-drain

ctr: drain exec output before cleanup
There was no way to tell whether a cache was doing anything: hits and
misses were only visible as trace log lines. Count lookups by result,
hits by the directory that served them so caches with different lifetimes
can be told apart, the blob bytes served, and lookup errors by reason,
which also makes an unreadable cache (a down FUSE mount, say) visible
instead of looking like a cold one.

Also add a span around the differ's Apply, carrying the layer descriptor
and which path handled it. The unpacker traces the fetch and the layer
lifecycle but not the apply, so a slow layer couldn't be pinned on the
download or the conversion.

Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
cri: add tracing spans for image pull and sandbox setup paths
The shim package could not be used by Windows shims due to missing implementation. This commit adds the Windows implementation for the shim package.

Signed-off-by: Harsh Rawat <harshrawat@microsoft.com>
Signed-off-by: Harsh Rawat <harshrawat@microsoft.com>
This release includes 10 security fixes covering module checksum
verification, denial-of-service protections, parser crashes, XSS, and
IDNA hostname validation, most notably:

- CVE-2026-56865: prevent malicious GOPROXY servers from bypassing sumdb transparency-log verification: https://go.dev/issue/80744
- CVE-2026-56864: prevent malicious GOSUMDB servers from serving unauthenticated module content: https://go.dev/issue/80745
- CVE-2026-56859: add recursion limits for XML decoding: https://go.dev/issue/80481
- CVE-2026-56853: apply ReadHeaderTimeout during unencrypted HTTP/2 detection: https://go.dev/issue/80205
- CVE-2026-56860: prevent quadratic behavior in URL path resolution: https://go.dev/issue/80494
- CVE-2026-46600: prevent panics when parsing malformed SVCB/HTTPS DNS records: https://go.dev/issue/79795
- CVE-2026-56862: limit excessive TLS post-handshake messages: https://go.dev/issue/80528
- CVE-2026-56858: fix JavaScript regexp context tracking in html/template: https://go.dev/issue/80435
- CVE-2026-39821: reject invalid ASCII-only Punycode labels: https://go.dev/issue/78760
- CVE-2026-33818: add recursion limits for ASN.1 unmarshalling: https://go.dev/issue/80405

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
loadShim runs during runtime plugin initialization and issued its task
RPCs on the caller's context, which carries no deadline. A shim that
still owns its socket but has stopped serving, for example one leaked by
a previous containerd whose shutdown timed out, accepts the connection
and then never answers. containerd then never finishes starting and its
API socket is never created.

Give loadShim a single loadTimeout budget covering the whole load. Nested
timeouts can only shorten a deadline, so the load stays bounded however
many calls it makes.

Reaping a shim we give up on runs on its own cleanup budget, detached
from the caller so that a cancelled load cannot leave the shim behind. A
failed delete returns before shutting the shim down and closing its
client, so both are done here, and the failure is now propagated: delete
removes the bundle only when it succeeds, and returning an error lets
loadShims remove it, so a shim that cannot be reaped is no longer
reloaded on every subsequent start.

Co-authored-by: Harshal Patel <106813066+HarshalPatel1972@users.noreply.github.com>
Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
Fix #13534

It impacts EROFS snapshotter which relies on the new mount manager
for example.

Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
…revent-stalled-startup

fix(runtime): apply load timeout to load shim
Bumps [github.com/klauspost/compress](https://github.com/klauspost/compress) from 1.19.1 to 1.19.2.
- [Release notes](https://github.com/klauspost/compress/releases)
- [Commits](klauspost/compress@v1.19.1...v1.19.2)

---
updated-dependencies:
- dependency-name: github.com/klauspost/compress
  dependency-version: 1.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 4.1.1 to 4.2.2.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](actions/attest-build-provenance@0f67c3f...4d10147)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-version: 4.2.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
[pkg/shim] implement Windows support for the shim server
Signed-off-by: Philip Laine <philip.laine@gmail.com>
A pre-2.3 containerd daemon can start a newly installed shim through the
deprecated CLI, environment, and stdin API.
The shim currently accepts that request but returns a protobuf bootstrap
result, which the old daemon cannot parse.
It treats the protobuf bytes as a socket address and fails later with a
cryptic error:

```
failed to create TTRPC connection: unsupported protocol: \b\x03\x12Yunix
```

This patch makes the shim reject the deprecated startup request before
starting and tell the user that the containerd daemon may need to be
restarted.
The 2.2 daemon includes the shim's stderr in its start error, so this
message reaches the user directly.

This explicitly removes input-side support for the deprecated startup
API, but it does not break a working standard containerd pairing.
Pre-2.3 daemons already cannot consume the response from the new shim.
After a package upgrade, a restarted daemon uses the new bootstrap API.

Custom callers that send the deprecated request format while supporting
the new protobuf response will now also be rejected.

Signed-off-by: Paweł Gronowski <git@grono.dev>
TaskService.Shutdown may be invoked multiple times. A grouped shim
itself does not terminate while it still has active tasks. It terminates only
after receiving a Shutdown request when no active tasks remain.

The shim manager should invoke TaskService.Shutdown after deleting every task,
regardless of whether the task represents sandbox or not. This ensures that the
shim receives Shutdown when the last active task is deleted.

In CRI, the pause container uses oom_score_adj=-998, making it unlikely to be
OOM-killed. However, it may still exit or be killed before the other containers
in the sandbox. SandboxService.Shutdown and TaskService.Shutdown are independent
APIs. Sandbox service should make sure there is no active containers
before shutdown. So, for the task service, we should invoke Shutdown for
each task.

Removing the supportSandboxAPIVersion check does not change behavior for shims
using task API versions below v3. Those shims were already forced down the
non-sandboxed path and received Shutdown after every task deletion. The behavior
change applies only to sandboxed tasks using task API v3, which now receive
Shutdown after deletion as well.

Signed-off-by: Wei Fu <fuweid89@gmail.com>
…containers

runtime: invoke Shutdown after every task deletion
full diff: microsoft/hcsshim@v0.15.0-rc.3...v0.15.0-rc.4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: golang/mod@v0.38.0...v0.39.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: golang/text@v0.38.0...v0.41.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: golang/crypto@v0.53.0...v0.55.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: golang/net@v0.57.0...v0.58.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: golang/mod@v0.39.0...v0.40.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: felixge/httpsnoop@v1.0.4...v1.1.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
full diff: go-logr/logr@v1.4.3...v1.4.4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
thaJeztah and others added 30 commits September 10, 2026 01:14
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Mask /proc/interrupts and /sys/devices/system/cpu/cpu<x>/thermal_throttle
inside Linux containers by default, matching moby, kubernetes, podman,
buildah, and cri-o.

See also: kubernetes/kubernetes#138512 (comment)

Assisted-by: Antigravity
Signed-off-by: Samuel Karp <samuelkarp@google.com>
shim-runc-v2: record exit status in bundle
Both image volumes and its activated mount objects are tied to sandbox
lease. Removing the snapshot from defered cleanup may leave activated
mount object referencing to missing snapshot.

Keep a successfully image volume mount even if a later step (subpath check)
fails. Only roll back the mount when mount.All itself fails. Sandbox cleanup
and GC will release the remaining resources.

Signed-off-by: Wei Fu <fuweid89@gmail.com>
migrate to github.com/urfave/cli/v3
full diff: containerd/nri@v0.12.2...v0.12.3

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
cri: only unmount image volumes when mounting fails
vendor: github.com/containerd/nri v0.12.3
pkg/oci: mask thermal interrupt info
Staging a cached layer blob was gated on the Prepare having no parent,
which sequential unpacking only does for the first layer, so a warm
cache missed on every layer but layer 0 and a pull ended up slower than
with no cache at all.

Serve any image-layer extraction, and mount a staged blob read-only
whatever its parents, so the differ is never handed a writable view of a
blob shared with every other snapshot of that layer. A read-only mount
is a report to the caller and not an enforcement, so the erofs differ
also refuses a layer whose blob is a symlink, which would otherwise
truncate the cache entry through it.

Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
Bumps the golang-x group with 4 updates: [golang.org/x/mod](https://github.com/golang/mod), [golang.org/x/sync](https://github.com/golang/sync), [golang.org/x/sys](https://github.com/golang/sys) and [golang.org/x/time](https://github.com/golang/time).


Updates `golang.org/x/mod` from 0.40.0 to 0.41.0
- [Commits](golang/mod@v0.40.0...v0.41.0)

Updates `golang.org/x/sync` from 0.22.0 to 0.23.0
- [Commits](golang/sync@v0.22.0...v0.23.0)

Updates `golang.org/x/sys` from 0.47.0 to 0.48.0
- [Commits](golang/sys@v0.47.0...v0.48.0)

Updates `golang.org/x/time` from 0.15.0 to 0.16.0
- [Commits](golang/time@v0.15.0...v0.16.0)

---
updated-dependencies:
- dependency-name: golang.org/x/mod
  dependency-version: 0.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: golang-x
- dependency-name: golang.org/x/sync
  dependency-version: 0.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: golang-x
- dependency-name: golang.org/x/sys
  dependency-version: 0.48.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: golang-x
- dependency-name: golang.org/x/time
  dependency-version: 0.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: golang-x
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [github.com/klauspost/compress](https://github.com/klauspost/compress) from 1.19.2 to 1.20.0.
- [Release notes](https://github.com/klauspost/compress/releases)
- [Commits](klauspost/compress@v1.19.2...v1.20.0)

---
updated-dependencies:
- dependency-name: github.com/klauspost/compress
  dependency-version: 1.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
The differ found an already-populated snapshot by looking for a
symlinked layer.erofs in the layer directory. That check needs a
particular on-disk layout, and it needs erofsutils.MountsToLayer to
infer the snapshot directory from a mount source that lives inside it.
Neither holds for a snapshot whose content is not a local file.

Refuse on the signal the unpacker already uses. Mounts handed to Apply
that are read-only belong to a snapshot the snapshotter populated
itself, whose content is shared with every other snapshot of that layer.
This does not need path inference, covers parented and parentless
snapshots alike, and stays correct for any content the snapshotter does
not store as a plain file in the snapshot directory.

The error stays ErrFailedPrecondition. plugins/services/diff/local.go
falls through to the next differ on ErrNotImplemented. Another differ
would fail on this layer for the same reason.

Signed-off-by: Derek McGowan <derek@mcg.dev>
A layer served from the layer content cache was symlinked into the
snapshot as its layer.erofs. That put a path inside the snapshot
directory aliasing a blob owned by the operator and shared with every
other snapshot of that layer. Everything written to that path went
straight into the cache entry. Each write site then needed its own
guard: the differ had to refuse to apply, Commit had to refuse to
convert through a dangling link, and Remove had to avoid clearing
IMMUTABLE_FL on a file it did not own. A missed guard corrupted content
shared across images. A pruned entry left a dangling link that read as
an absent blob on one path and as populated content on another.

Record where the blob is on the snapshot and mount it from there.
Nothing in the snapshot directory refers to content it does not own. A
stray write creates a local file, conversion cannot reach the cache, and
removal has nothing to follow. The guards Commit and Remove needed for a
symlink are gone. The differ still refuses, on the read-only mounts the
snapshotter hands out.

resolveBlob is the one place a blob is located. It reports whether the
blob is already populated, meaning there is nothing to apply or convert,
and whether it belongs to this snapshot, meaning it may be written.
Mounts are then assembled without consulting the filesystem to find out
what a layer is. A source that does not resolve is an error on every
path, including the parentless path in mounts(). A flattened parent's
device= is resolved the same way.

fsverity is only measured for a blob the snapshot owns. Measuring a
cache entry would require the operator to enable fsverity on content
this snapshotter never wrote. NewSnapshotter already rejects fsverity
together with the layer content cache.

The record is kept in labels outside the containerd.io/snapshot/
namespace. Labels in that namespace are inherited from image
annotations, which would let an image name any path on the host. The
same filter runs on everything the metadata snapshotter passes down. A
client cannot set these labels, and cannot send them back after reading
them through Stat. Commit and Update carry them across.

The dm-verity sidecar is read from beside the cache entry. Nothing is
copied into the snapshot. The sidecar cannot fall out of step with the
blob it pins. An entry required to have one is rejected at Prepare.

Signed-off-by: Derek McGowan <derek@mcg.dev>
The mount handler built the device name from the source path, taking the
base of the parent directory as a snapshot id. That reads an identity
out of a layout only a snapshot directory has. A layer served from a
layer content cache is mounted from the cache, whose parent directory is
a shard named for the first two characters of the digest. Every blob in
a shard then names one device.

A second layer in a shard fails to mount. dmverity.Open finds the name
taken, VerifyDevice compares the existing device's root hash against the
one being mounted, and the mismatch is an error. No layer is served
against the wrong root hash, and none of the colliding layers can be
mounted.

Name the device for the source and the mount point together. Mount
closes the device it creates when the mount fails, so the name has to be
unique to the mount. Neither half is unique alone: a cache serves one
blob to every snapshot of that layer, and a mount point is reused once
the mount before it is gone. A device left behind by a crash is reused
only for the same blob in the same place, where its root hash still
matches. Unmount reads the name back from the mounted source and needs
nothing from either.

Signed-off-by: Derek McGowan <derek@mcg.dev>
…b.com/klauspost/compress-1.20.0

build(deps): bump github.com/klauspost/compress from 1.19.2 to 1.20.0
…g-x-e7a3917753

build(deps): bump the golang-x group with 4 updates
Update erofs snapshotter to record blob source
Signed-off-by: Derek McGowan <derek@mcg.dev>
Co-authored-by: Samuel Karp <samuelkarp@google.com>
Signed-off-by: Derek McGowan <derek@mcg.dev>
Signed-off-by: Samuel Karp <samuelkarp@google.com>
Signed-off-by: Derek McGowan <derek@mcg.dev>
Signed-off-by: Derek McGowan <derek@mcg.dev>
Prepare release notes for v2.4.0-rc.0
Delay the removal of the auths, configs, and mirrors properties in
[plugins."io.containerd.grpc.v1.cri".registry] until containerd 2.7.

Assisted-by: Antigravity
Signed-off-by: Samuel Karp <samuelkarp@google.com>
Remove the `enable_cdi` configuration option in
`[plugins."io.containerd.cri.v1.runtime"]`, which was deprecated in
v2.2. CDI support is now always enabled.

Assisted-by: Antigravity
Signed-off-by: Samuel Karp <samuelkarp@google.com>
The `bin_dir` property of `[plugins."io.containerd.cri.v1.runtime".cni]`
was deprecated in containerd v2.1 in favor of `bin_dirs` and was
scheduled for removal in v2.4.

Assisted-by: Antigravity
Signed-off-by: Samuel Karp <samuelkarp@google.com>
Remove the deprecated endpoint, protocol, and insecure configuration
options for the io.containerd.tracing.processor.v1.otlp plugin.
These were deprecated in v1.6.29 and replaced by standard OTLP
environment variables.

Assisted-by: Antigravity
Signed-off-by: Samuel Karp <samuelkarp@google.com>
Add unit tests in pkg/tracing/plugin/otlp_test.go to verify newExporter,
checkDisabled, and newTracer with the OpenTelemetry environment
variables that replaced the deprecated OTLP plugin configuration fields.

Assisted-by: Antigravity
Signed-off-by: Samuel Karp <samuelkarp@google.com>
Remove support for service_name and sampling_ratio in the
io.containerd.internal.v1.tracing plugin configuration, which was
previously deprecated in v1.6.29. Users should use standard OTel
environment variables instead (OTEL_SERVICE_NAME, OTEL_TRACES_SAMPLER,
etc.).

Re-add unit tests in pkg/tracing/plugin/otlp_test.go to verify
OTel environment variable configuration for service name, sampling,
exporters, and SDK disabling.

Assisted-by: Antigravity
Signed-off-by: Samuel Karp <samuelkarp@google.com>
…or-2.4

Deprecations and removals for 2.4
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.