Add containerd image ref to created containers
This populates the "Image" field on containerd containers, but only when using the containerd image store. This allows containerd clients to look up the image information. Signed-off-by: Brian Goff <cpuguy83@gmail.com> Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
This commit is contained in:
parent
84c0103448
commit
9d4bf2cba4
3 changed files with 62 additions and 1 deletions
|
@ -273,6 +273,11 @@ func (i *ImageService) resolveDescriptor(ctx context.Context, refOrID string) (o
|
|||
return img.Target, nil
|
||||
}
|
||||
|
||||
// ResolveImage looks up an image by reference or identifier in the image store.
|
||||
func (i *ImageService) ResolveImage(ctx context.Context, refOrID string) (containerdimages.Image, error) {
|
||||
return i.resolveImage(ctx, refOrID)
|
||||
}
|
||||
|
||||
func (i *ImageService) resolveImage(ctx context.Context, refOrID string) (containerdimages.Image, error) {
|
||||
parsed, err := reference.ParseAnyReference(refOrID)
|
||||
if err != nil {
|
||||
|
|
|
@ -4,10 +4,13 @@ import (
|
|||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
"github.com/docker/docker/container"
|
||||
mobyc8dstore "github.com/docker/docker/daemon/containerd"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/internal/compatcontext"
|
||||
"github.com/docker/docker/libcontainerd"
|
||||
|
@ -166,7 +169,22 @@ func (daemon *Daemon) containerStart(ctx context.Context, daemonCfg *configStore
|
|||
return err
|
||||
}
|
||||
|
||||
ctr, err := libcontainerd.ReplaceContainer(ctx, daemon.containerd, container.ID, spec, shim, createOptions)
|
||||
ctr, err := libcontainerd.ReplaceContainer(ctx, daemon.containerd, container.ID, spec, shim, createOptions, func(ctx context.Context, client *containerd.Client, c *containers.Container) error {
|
||||
// Only set the image if we are using containerd for image storage.
|
||||
// This is for metadata purposes only.
|
||||
// Other lower-level components may make use of this information.
|
||||
is, ok := daemon.imageService.(*mobyc8dstore.ImageService)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
img, err := is.ResolveImage(ctx, container.Config.Image)
|
||||
if err != nil {
|
||||
log.G(ctx).WithError(err).WithField("container", container.ID).Warn("Failed to resolve containerd image reference")
|
||||
return nil
|
||||
}
|
||||
c.Image = img.Name
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return setExitCodeFromError(container.SetExitCode, err)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
|
@ -668,3 +669,40 @@ func TestCreateWithCustomMACs(t *testing.T) {
|
|||
assert.Equal(t, mac, "02:32:1c:23:00:04")
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that when using containerd backed storage the containerd container has the image referenced stored.
|
||||
func TestContainerdContainerImageInfo(t *testing.T) {
|
||||
skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.45"), "requires API v1.45")
|
||||
|
||||
ctx := setupTest(t)
|
||||
|
||||
apiClient := testEnv.APIClient()
|
||||
defer apiClient.Close()
|
||||
|
||||
info, err := apiClient.Info(ctx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
skip.If(t, info.Containerd == nil, "requires containerd")
|
||||
|
||||
// Currently a containerd container is only created when the container is started.
|
||||
// So start the container and then inspect the containerd container to verify the image info.
|
||||
id := ctr.Run(ctx, t, apiClient, func(cfg *ctr.TestContainerConfig) {
|
||||
// busybox is the default (as of this writing) used by the test client, but lets be explicit here.
|
||||
cfg.Config.Image = "busybox"
|
||||
})
|
||||
defer apiClient.ContainerRemove(ctx, id, container.RemoveOptions{Force: true})
|
||||
|
||||
client, err := containerd.New(info.Containerd.Address, containerd.WithDefaultNamespace(info.Containerd.Namespaces.Containers))
|
||||
assert.NilError(t, err)
|
||||
defer client.Close()
|
||||
|
||||
ctr, err := client.ContainerService().Get(ctx, id)
|
||||
assert.NilError(t, err)
|
||||
|
||||
if testEnv.UsingSnapshotter() {
|
||||
assert.Equal(t, ctr.Image, "docker.io/library/busybox:latest")
|
||||
} else {
|
||||
// This field is not set when not using contianerd backed storage.
|
||||
assert.Equal(t, ctr.Image, "")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue