containerd integration: `docker run`
<!--
Please make sure you've read and understood our contributing guidelines;
https://github.com/moby/moby/blob/master/CONTRIBUTING.md

** Make sure all your commits include a signature generated with `git commit -s` **

For additional information on our contributing process, read our contributing
guide https://docs.docker.com/opensource/code/

If this is a bug fix, make sure your description includes "fixes #xxxx", or
"closes #xxxx"

Please provide the following information:
-->

**- What I did**

Implemented `docker run` with the containerd store.

Upstreams:
* https://github.com/rumpl/moby/pull/25
* https://github.com/rumpl/moby/pull/62
* https://github.com/rumpl/moby/pull/104
* https://github.com/rumpl/moby/pull/65
* https://github.com/rumpl/moby/pull/70
* https://github.com/rumpl/moby/pull/98
* https://github.com/rumpl/moby/pull/71

I added the second and third commit because parts of the code changes are needed for run to work.

**- How I did it**

Mostly avoiding doing anything with layers if containerd is used as an image store and using snapshots instead. Some tweaks were also needed in the way we create the OCI spec for the container.

**- How to verify it**

Run:
```console
$ docker run hello-world
$ docker run busybox arch
$ docker run --platform linux/arm64 arch
$ docker run --platform linux/amd64 arch
$ docker run -it docker/doodle
```

All of these should work after #44756 is merged.

**- Description for the changelog**
<!--
Write a short (one line) summary that describes the changes in this
pull request for inclusion in the changelog:
-->


**- A picture of a cute animal (not mandatory but encouraged)**


daemon/image_service.go
package daemon

import (
	"context"
	"io"

	"github.com/docker/distribution"
	"github.com/docker/distribution/reference"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/backend"
	"github.com/docker/docker/api/types/filters"
	imagetype "github.com/docker/docker/api/types/image"
	"github.com/docker/docker/api/types/registry"
	"github.com/docker/docker/builder"
	"github.com/docker/docker/container"
	"github.com/docker/docker/daemon/images"
	"github.com/docker/docker/image"
	"github.com/docker/docker/layer"
	v1 "github.com/opencontainers/image-spec/specs-go/v1"
)

// ImageService is a temporary interface to assist in the migration to the
// containerd image-store. This interface should not be considered stable,
// and may change over time.
type ImageService interface {
	// Images

	PullImage(ctx context.Context, image, tag string, platform *v1.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
	PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
	CreateImage(config []byte, parent string) (builder.Image, error)
	ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error)
	ExportImage(ctx context.Context, names []string, outStream io.Writer) error
	LoadImage(ctx context.Context, inTar io.ReadCloser, outStream io.Writer, quiet bool) error
	Images(ctx context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error)
	LogImageEvent(imageID, refName, action string)
	LogImageEventWithAttributes(imageID, refName, action string, attributes map[string]string)
	CountImages() int
	ImagesPrune(ctx context.Context, pruneFilters filters.Args) (*types.ImagesPruneReport, error)
	ImportImage(ctx context.Context, ref reference.Named, platform *v1.Platform, msg string, layerReader io.Reader, changes []string) (image.ID, error)
	TagImage(imageName, repository, tag string) (string, error)
	TagImageWithReference(imageID image.ID, newTag reference.Named) error
	GetImage(ctx context.Context, refOrID string, options imagetype.GetImageOpts) (*image.Image, error)
	ImageHistory(ctx context.Context, name string) ([]*imagetype.HistoryResponseItem, error)
	CommitImage(ctx context.Context, c backend.CommitConfig) (image.ID, error)
	SquashImage(id, parent string) (string, error)

	// Layers

	GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts backend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error)
	CreateLayer(container *container.Container, initFunc layer.MountInit) (layer.RWLayer, error)
	GetLayerByID(cid string) (layer.RWLayer, error)
	LayerStoreStatus() [][2]string
	GetLayerMountID(cid string) (string, error)
	ReleaseLayer(rwlayer layer.RWLayer) error
	LayerDiskUsage(ctx context.Context) (int64, error)
	GetContainerLayerSize(containerID string) (int64, int64)

	// Windows specific

	GetLayerFolders(img *image.Image, rwLayer layer.RWLayer) ([]string, error)

	// Build

	MakeImageCache(ctx context.Context, cacheFrom []string) (builder.ImageCache, error)
	CommitBuildStep(ctx context.Context, c backend.CommitConfig) (image.ID, error)

	// Other

	GetRepository(ctx context.Context, ref reference.Named, authConfig *registry.AuthConfig) (distribution.Repository, error)
	SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *registry.AuthConfig, headers map[string][]string) (*registry.SearchResults, error)
	DistributionServices() images.DistributionServices
	Children(id image.ID) []image.ID
	Cleanup() error
	StorageDriver() string
	UpdateConfig(maxDownloads, maxUploads int)
}

package daemon

import (
	"context"
	"io"

	"github.com/docker/distribution"
	"github.com/docker/distribution/reference"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/backend"
	"github.com/docker/docker/api/types/filters"
	imagetype "github.com/docker/docker/api/types/image"
	"github.com/docker/docker/api/types/registry"
	"github.com/docker/docker/builder"
	"github.com/docker/docker/container"
	"github.com/docker/docker/daemon/images"
	"github.com/docker/docker/image"
	"github.com/docker/docker/layer"
	v1 "github.com/opencontainers/image-spec/specs-go/v1"
)

// ImageService is a temporary interface to assist in the migration to the
// containerd image-store. This interface should not be considered stable,
// and may change over time.
type ImageService interface {
	// Images

	PullImage(ctx context.Context, image, tag string, platform *v1.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
	PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
	CreateImage(config []byte, parent string) (builder.Image, error)
	ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error)
	ExportImage(ctx context.Context, names []string, outStream io.Writer) error
	LoadImage(ctx context.Context, inTar io.ReadCloser, outStream io.Writer, quiet bool) error
	Images(ctx context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error)
	LogImageEvent(imageID, refName, action string)
	LogImageEventWithAttributes(imageID, refName, action string, attributes map[string]string)
	CountImages() int
	ImagesPrune(ctx context.Context, pruneFilters filters.Args) (*types.ImagesPruneReport, error)
	ImportImage(ctx context.Context, ref reference.Named, platform *v1.Platform, msg string, layerReader io.Reader, changes []string) (image.ID, error)
	TagImage(imageName, repository, tag string) (string, error)
	TagImageWithReference(imageID image.ID, newTag reference.Named) error
	GetImage(ctx context.Context, refOrID string, options imagetype.GetImageOpts) (*image.Image, error)
	ImageHistory(ctx context.Context, name string) ([]*imagetype.HistoryResponseItem, error)
	CommitImage(ctx context.Context, c backend.CommitConfig) (image.ID, error)
	SquashImage(id, parent string) (string, error)

	// Containerd related methods

	PrepareSnapshot(ctx context.Context, id string, image string, platform *v1.Platform) error

	// Layers

	GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts backend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error)
	CreateLayer(container *container.Container, initFunc layer.MountInit) (layer.RWLayer, error)
	GetLayerByID(cid string) (layer.RWLayer, error)
	LayerStoreStatus() [][2]string
	GetLayerMountID(cid string) (string, error)
	ReleaseLayer(rwlayer layer.RWLayer) error
	LayerDiskUsage(ctx context.Context) (int64, error)
	GetContainerLayerSize(containerID string) (int64, int64)
	Mount(ctx context.Context, container *container.Container) error
	Unmount(ctx context.Context, container *container.Container) error

	// Windows specific

	GetLayerFolders(img *image.Image, rwLayer layer.RWLayer) ([]string, error)

	// Build

	MakeImageCache(ctx context.Context, cacheFrom []string) (builder.ImageCache, error)
	CommitBuildStep(ctx context.Context, c backend.CommitConfig) (image.ID, error)

	// Other

	GetRepository(ctx context.Context, ref reference.Named, authConfig *registry.AuthConfig) (distribution.Repository, error)
	SearchRegistryForImages(ctx context.Context, searchFilters filters.Args, term string, limit int, authConfig *registry.AuthConfig, headers map[string][]string) (*registry.SearchResults, error)
	DistributionServices() images.DistributionServices
	Children(id image.ID) []image.ID
	Cleanup() error
	StorageDriver() string
	UpdateConfig(maxDownloads, maxUploads int)
}

In my fork we had an [interface](https://github.com/rumpl/moby/blob/c8d/daemon/create.go#L39-L41) that we would [use only in the case we use the containerd store](https://github.com/rumpl/moby/blob/c8d/daemon/create.go#L186) but that sucked.

I realise this isn't ideal, having an interface that does too much and having one of the implementors `panic`... 

I considered moving some of the things over to the `libcontainerd` but I'm not sure it would help and also I'm not really a fan of that wrapper.

Thoughts?