Also unpack image during creation.
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
parent
8fb63c5664
commit
acc3f74d5c
@ -21,12 +21,41 @@ import (
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/docker/docker/pkg/chrootarchive"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/opencontainers/image-spec/identity"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// WithImageUnpack guarantees that the image used by the container is unpacked.
|
||||
func WithImageUnpack(i containerd.Image) containerd.NewContainerOpts {
|
||||
return func(ctx context.Context, client *containerd.Client, c *containers.Container) error {
|
||||
if c.Snapshotter == "" {
|
||||
return errors.New("no snapshotter set for container")
|
||||
}
|
||||
snapshotter := client.SnapshotService(c.Snapshotter)
|
||||
diffIDs, err := i.RootFS(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get image diff IDs")
|
||||
}
|
||||
chainID := identity.ChainID(diffIDs)
|
||||
_, err = snapshotter.Stat(ctx, chainID.String())
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if !errdefs.IsNotFound(err) {
|
||||
return errors.Wrap(err, "stat snapshot")
|
||||
}
|
||||
// Unpack the snapshot.
|
||||
if err := i.Unpack(ctx, c.Snapshotter); err != nil {
|
||||
return errors.Wrap(err, "unpack snapshot")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithVolumes copies ownership of volume in rootfs to its corresponding host path.
|
||||
// It doesn't update runtime spec.
|
||||
// The passed in map is a host path to container path map for all volumes.
|
||||
@ -34,10 +63,10 @@ import (
|
||||
func WithVolumes(volumeMounts map[string]string) containerd.NewContainerOpts {
|
||||
return func(ctx context.Context, client *containerd.Client, c *containers.Container) error {
|
||||
if c.Snapshotter == "" {
|
||||
return errors.Errorf("no snapshotter set for container")
|
||||
return errors.New("no snapshotter set for container")
|
||||
}
|
||||
if c.SnapshotKey == "" {
|
||||
return errors.Errorf("rootfs not created for container")
|
||||
return errors.New("rootfs not created for container")
|
||||
}
|
||||
snapshotter := client.SnapshotService(c.Snapshotter)
|
||||
mounts, err := snapshotter.Mounts(ctx, c.SnapshotKey)
|
||||
|
@ -150,6 +150,7 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
|
||||
// Set snapshotter before any other options.
|
||||
opts := []containerd.NewContainerOpts{
|
||||
containerd.WithSnapshotter(c.config.ContainerdConfig.Snapshotter),
|
||||
customopts.WithImageUnpack(image.Image),
|
||||
// Prepare container rootfs. This is always writeable even if
|
||||
// the container wants a readonly rootfs since we want to give
|
||||
// the runtime (runc) a chance to modify (e.g. to create mount
|
||||
|
@ -99,14 +99,20 @@ func (c *criContainerdService) PullImage(ctx context.Context, r *runtime.PullIma
|
||||
|
||||
// TODO(mikebrow): add truncIndex for image id
|
||||
image, err := c.client.Pull(ctx, ref,
|
||||
containerd.WithPullUnpack,
|
||||
containerd.WithSchema1Conversion,
|
||||
containerd.WithResolver(resolver),
|
||||
containerd.WithPullSnapshotter(c.config.ContainerdConfig.Snapshotter),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to pull image %q: %v", ref, err)
|
||||
}
|
||||
|
||||
// Do best effort unpack.
|
||||
glog.V(4).Info("Unpack image %q", imageRef)
|
||||
if err := image.Unpack(ctx, c.config.ContainerdConfig.Snapshotter); err != nil {
|
||||
glog.Warningf("Failed to unpack image %q: %v", imageRef, err)
|
||||
// Do not fail image pulling. Unpack will be retried before container creation.
|
||||
}
|
||||
|
||||
repoDigest, repoTag := getRepoDigestAndTag(namedRef, image.Target().Digest, isSchema1)
|
||||
for _, r := range []string{repoTag, repoDigest} {
|
||||
if r == "" {
|
||||
|
@ -391,7 +391,7 @@ func loadImages(ctx context.Context, cImages []containerd.Image, provider conten
|
||||
// Checking existence of top-level snapshot for each image being recovered.
|
||||
if _, err := snapshotter.Stat(ctx, image.ChainID); err != nil {
|
||||
glog.Warningf("Failed to stat the top-level snapshot for image %+v: %v", image, err)
|
||||
continue
|
||||
// TODO(random-liu): Consider whether we should try unpack here.
|
||||
}
|
||||
images = append(images, image)
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||
|
||||
customopts "github.com/kubernetes-incubator/cri-containerd/pkg/opts"
|
||||
sandboxstore "github.com/kubernetes-incubator/cri-containerd/pkg/store/sandbox"
|
||||
"github.com/kubernetes-incubator/cri-containerd/pkg/util"
|
||||
)
|
||||
@ -143,6 +144,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
|
||||
|
||||
opts := []containerd.NewContainerOpts{
|
||||
containerd.WithSnapshotter(c.config.ContainerdConfig.Snapshotter),
|
||||
customopts.WithImageUnpack(image.Image),
|
||||
containerd.WithNewSnapshot(id, image.Image),
|
||||
containerd.WithSpec(spec, specOpts...),
|
||||
containerd.WithContainerLabels(map[string]string{containerKindLabel: containerKindSandbox}),
|
||||
|
Loading…
Reference in New Issue
Block a user