Also unpack image during creation.
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
		| @@ -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}), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Lantao Liu
					Lantao Liu