Repository: containerd/containerd
File: internal/cri/server/images/image_pull.go (Go)

Code before:
	resp, err := rt.rt.RoundTrip(req)
	if err != nil {
		rt.reqReporter.decRequest()
		return nil, err
	}

	resp.Body = &countingReadCloser{
		rc:          resp.Body,
		reqReporter: rt.reqReporter,
	}
	return resp, err
}

// snapshotterFromPodSandboxConfig returns the snapshotter to use for the given
// runtime handler. If a runtime-specific snapshotter is configured, it will be
// returned; otherwise the default snapshotter is used.
// See https://github.com/containerd/containerd/issues/6657
func (c *CRIImageService) snapshotterFromPodSandboxConfig(ctx context.Context, imageRef string,
	s *runtime.PodSandboxConfig, runtimeHandler string) (string, error) {
	snapshotter := c.config.Snapshotter
	if s == nil {
		return snapshotter, nil
	}

	if c.runtimePlatforms != nil {
		if p, ok := c.runtimePlatforms[runtimeHandler]; ok && p.Snapshotter != snapshotter {
			snapshotter = p.Snapshotter
			log.G(ctx).Infof("PullImage %q for runtime %s, using snapshotter %s", imageRef, runtimeHandler, snapshotter)
		}
	}

	return snapshotter, nil
}

type criCredentials struct {
	ref         string
	credentials func(string) (string, string, error)
}

func newCRICredentials(ref string, credentials func(string) (string, string, error)) registry.CredentialHelper {
	return &criCredentials{
		ref:         ref,
		credentials: credentials,
	}
}

// GetCredentials gets credential from criCredentials makes criCredentials a registry.CredentialHelper
func (cc *criCredentials) GetCredentials(ctx context.Context, ref string, host string) (registry.Credentials, error) {
	if cc.credentials == nil {
		return registry.Credentials{}, fmt.Errorf("credential handler not initialized for ref %q", ref)
	}

Review comment (suggestion):
we have more clients to the CRI than just the kubelet..

So, just in case let's check your newly forwarded runtimeHandler parameter against nil  and if it is nil continue to use the runtime handler annotation if available...  

we can deprecate the annotation and then remove it in 2.4/5 

  

Code after:

	resp, err := rt.rt.RoundTrip(req)
	if err != nil {
		rt.reqReporter.decRequest()
		return nil, err
	}

	resp.Body = &countingReadCloser{
		rc:          resp.Body,
		reqReporter: rt.reqReporter,
	}
	return resp, err
}

// snapshotterFromPodSandboxConfig returns the snapshotter to use for the given
// runtime handler. If a runtime-specific snapshotter is configured, it will be
// returned; otherwise the default snapshotter is used.
//
// The runtimeHandler parameter (from CRI PullImageRequest, available since cri-api v0.29.0)
// takes precedence. If empty, we fall back to the experimental annotation for backward
// compatibility with clients that don't pass the runtime handler.
//
// Deprecated: The annotation-based fallback (io.containerd.cri.runtime-handler) is
// deprecated and will be removed in containerd 2.5.
//
// See https://github.com/containerd/containerd/issues/6657
func (c *CRIImageService) snapshotterFromPodSandboxConfig(ctx context.Context, imageRef string,
	s *runtime.PodSandboxConfig, runtimeHandler string) (string, error) {
	snapshotter := c.config.Snapshotter
	if s == nil {
		return snapshotter, nil
	}

	// If runtimeHandler parameter is empty, fall back to annotation for backward compatibility
	if runtimeHandler == "" {
		if s.Annotations == nil {
			return snapshotter, nil
		}
		var ok bool
		runtimeHandler, ok = s.Annotations[annotations.RuntimeHandler]
		if !ok {
			return snapshotter, nil
		}
		log.G(ctx).Warnf("Using deprecated annotation %q for runtime handler. "+
			"This will be removed in a future release (2.5). "+
			"Please update your CRI client to pass runtime handler in PullImageRequest.",
			annotations.RuntimeHandler)
	}

	if c.runtimePlatforms != nil {
		if p, ok := c.runtimePlatforms[runtimeHandler]; ok && p.Snapshotter != snapshotter {