From ac4f238f48889ffb00ccbf269b71855d5f852126 Mon Sep 17 00:00:00 2001 From: Lantao Liu Date: Wed, 30 Aug 2017 07:34:00 +0000 Subject: [PATCH] Cleanup image operations. Signed-off-by: Lantao Liu --- pkg/server/container_create.go | 2 +- pkg/server/helpers.go | 98 +++++++++---------- pkg/server/image_pull.go | 13 +-- pkg/server/sandbox_run.go | 2 +- vendor.conf | 2 +- .../containerd/containerd/README.md | 5 + .../containerd/containerd/apparmor.go | 18 ---- .../containerd/containerd/container_opts.go | 17 +++- .../containerd/containerd/events/exchange.go | 4 +- .../github.com/containerd/containerd/image.go | 11 ++- .../containerd/containerd/runtime/events.go | 2 + .../containerd/runtime/task_list.go | 4 +- .../containerd/containerd/vendor.conf | 3 +- 13 files changed, 96 insertions(+), 85 deletions(-) delete mode 100644 vendor/github.com/containerd/containerd/apparmor.go diff --git a/pkg/server/container_create.go b/pkg/server/container_create.go index 217b849a6..c8c5a1f0c 100644 --- a/pkg/server/container_create.go +++ b/pkg/server/container_create.go @@ -156,7 +156,7 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C } opts = append(opts, containerd.WithSpec(spec, specOpts...), - containerd.WithRuntime(defaultRuntime), + containerd.WithRuntime(defaultRuntime, nil), containerd.WithContainerLabels(labels)) var cntr containerd.Container if cntr, err = c.client.NewContainer(ctx, id, opts...); err != nil { diff --git a/pkg/server/helpers.go b/pkg/server/helpers.go index e3606ec18..afd532066 100644 --- a/pkg/server/helpers.go +++ b/pkg/server/helpers.go @@ -25,6 +25,7 @@ import ( "strings" "github.com/containerd/cgroups" + "github.com/containerd/containerd" "github.com/containerd/containerd/content" "github.com/containerd/containerd/errdefs" "github.com/docker/distribution/reference" @@ -204,50 +205,6 @@ func normalizeImageRef(ref string) (reference.Named, error) { return reference.TagNameOnly(named), nil } -// getImageInfo returns image chainID, compressed size, oci config, imageID. Note that getImageInfo -// assumes that the image has been pulled or it will return an error. -func (c *criContainerdService) getImageInfo(ctx context.Context, ref string) ( - imagedigest.Digest, int64, *imagespec.ImageConfig, imagedigest.Digest, error) { - - // Get image config - normalized, err := normalizeImageRef(ref) - if err != nil { - return "", 0, nil, "", fmt.Errorf("failed to normalize image reference %q: %v", ref, err) - } - normalizedRef := normalized.String() - //TODO(Abhi): Switch to using containerd client GetImage() api - image, err := c.imageStoreService.Get(ctx, normalizedRef) - if err != nil { - return "", 0, nil, "", fmt.Errorf("failed to get image %q from containerd image store: %v", - normalizedRef, err) - } - // Get image config - desc, err := image.Config(ctx, c.contentStoreService) - if err != nil { - return "", 0, nil, "", fmt.Errorf("failed to get image config descriptor: %v", err) - } - rb, err := content.ReadBlob(ctx, c.contentStoreService, desc.Digest) - if err != nil { - return "", 0, nil, "", fmt.Errorf("failed to get image config reader: %v", err) - } - var imageConfig imagespec.Image - if err = json.Unmarshal(rb, &imageConfig); err != nil { - return "", 0, nil, "", err - } - // Get image chainID - diffIDs, err := image.RootFS(ctx, c.contentStoreService) - if err != nil { - return "", 0, nil, "", fmt.Errorf("failed to get image diff ids: %v", err) - } - chainID := identity.ChainID(diffIDs) - // Get image size - size, err := image.Size(ctx, c.contentStoreService) - if err != nil { - return "", 0, nil, "", fmt.Errorf("failed to get image size: %v", err) - } - return chainID, size, &imageConfig.Config, desc.Digest, nil -} - // getRepoDigestAngTag returns image repoDigest and repoTag of the named image reference. func getRepoDigestAndTag(namedRef reference.Named, digest imagedigest.Digest, schema1 bool) (string, string) { var repoTag, repoDigest string @@ -273,16 +230,14 @@ func (c *criContainerdService) localResolve(ctx context.Context, ref string) (*i if err != nil { return nil, fmt.Errorf("invalid image reference %q: %v", ref, err) } - //TODO(Abhi): Switch to using containerd client GetImage() api - imageInContainerd, err := c.imageStoreService.Get(ctx, normalized.String()) + image, err := c.client.GetImage(ctx, normalized.String()) if err != nil { if errdefs.IsNotFound(err) { return nil, nil } - return nil, fmt.Errorf("an error occurred when getting image %q from containerd image store: %v", - normalized.String(), err) + return nil, fmt.Errorf("failed to get image from containerd: %v", err) } - desc, err := imageInContainerd.Config(ctx, c.contentStoreService) + desc, err := image.Config(ctx) if err != nil { return nil, fmt.Errorf("failed to get image config descriptor: %v", err) } @@ -374,3 +329,48 @@ func loadCgroup(cgroupPath string) (cgroups.Cgroup, error) { } return cg, nil } + +// imageInfo is the information about the image got from containerd. +type imageInfo struct { + id string + chainID imagedigest.Digest + size int64 + config imagespec.ImageConfig +} + +// getImageInfo gets image info from containerd. +func getImageInfo(ctx context.Context, image containerd.Image, provider content.Provider) (*imageInfo, error) { + // Get image information. + diffIDs, err := image.RootFS(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get image diffIDs: %v", err) + } + chainID := identity.ChainID(diffIDs) + + size, err := image.Size(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get image compressed resource size: %v", err) + } + + desc, err := image.Config(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get image config descriptor: %v", err) + } + id := desc.Digest.String() + + rb, err := content.ReadBlob(ctx, provider, desc.Digest) + if err != nil { + return nil, fmt.Errorf("failed to read image config from content store: %v", err) + } + var ociimage imagespec.Image + if err := json.Unmarshal(rb, &ociimage); err != nil { + return nil, fmt.Errorf("failed to unmarshal image config %s: %v", rb, err) + } + + return &imageInfo{ + id: id, + chainID: chainID, + size: size, + config: ociimage.Config, + }, nil +} diff --git a/pkg/server/image_pull.go b/pkg/server/image_pull.go index 80d6816dc..e2dbd9f52 100644 --- a/pkg/server/image_pull.go +++ b/pkg/server/image_pull.go @@ -110,11 +110,12 @@ func (c *criContainerdService) PullImage(ctx context.Context, r *runtime.PullIma } } // Get image information. - chainID, size, config, id, err := c.getImageInfo(ctx, imageRef) + info, err := getImageInfo(ctx, image, c.client.ContentStore()) if err != nil { - return nil, fmt.Errorf("failed to get image %q information: %v", imageRef, err) + return nil, fmt.Errorf("failed to get image information: %v", err) } - imageID := id.String() + imageID := info.id + if err := c.createImageReference(ctx, imageID, image.Target()); err != nil { return nil, fmt.Errorf("failed to update image reference %q: %v", imageID, err) } @@ -122,9 +123,9 @@ func (c *criContainerdService) PullImage(ctx context.Context, r *runtime.PullIma repoTag, repoDigest) img := imagestore.Image{ ID: imageID, - ChainID: chainID.String(), - Size: size, - Config: config, + ChainID: info.chainID.String(), + Size: info.size, + Config: &info.config, Image: image, } if repoDigest != "" { diff --git a/pkg/server/sandbox_run.go b/pkg/server/sandbox_run.go index 4d7ee2d79..6941643af 100644 --- a/pkg/server/sandbox_run.go +++ b/pkg/server/sandbox_run.go @@ -135,7 +135,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run containerd.WithNewSnapshotView(id, image.Image), containerd.WithSpec(spec, specOpts...), containerd.WithContainerLabels(labels), - containerd.WithRuntime(defaultRuntime)} + containerd.WithRuntime(defaultRuntime, nil)} container, err := c.client.NewContainer(ctx, id, opts...) if err != nil { return nil, fmt.Errorf("failed to create containerd container: %v", err) diff --git a/vendor.conf b/vendor.conf index ea5877984..e368cdde4 100644 --- a/vendor.conf +++ b/vendor.conf @@ -1,6 +1,6 @@ github.com/blang/semver v3.1.0 github.com/boltdb/bolt v1.3.0-58-ge9cf4fa -github.com/containerd/containerd cf09e32618398fc59fcb45bcfe9b4c0335972733 +github.com/containerd/containerd c1c2aafffec89aefaff2ba80b81be2277b2903dd github.com/containerd/continuity cf279e6ac893682272b4479d4c67fd3abf878b4e github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6 github.com/containerd/cgroups 7a5fdd8330119dc70d850260db8f3594d89d6943 diff --git a/vendor/github.com/containerd/containerd/README.md b/vendor/github.com/containerd/containerd/README.md index 08a68145d..b7c352c29 100644 --- a/vendor/github.com/containerd/containerd/README.md +++ b/vendor/github.com/containerd/containerd/README.md @@ -192,6 +192,11 @@ For sync communication we have a community slack with a #containerd channel that **Slack:** https://dockr.ly/community +### Reporting security issues + +__If you are reporting a security issue, please follow the responsible +disclosure guidelines and reach out discreetly at containerd-security@googlegroups.com__. + ## Copyright and license Copyright ©2016-2017 Docker, Inc. All rights reserved, except as follows. Code diff --git a/vendor/github.com/containerd/containerd/apparmor.go b/vendor/github.com/containerd/containerd/apparmor.go deleted file mode 100644 index e8485c3f5..000000000 --- a/vendor/github.com/containerd/containerd/apparmor.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build linux - -package containerd - -import ( - "context" - - "github.com/containerd/containerd/containers" - specs "github.com/opencontainers/runtime-spec/specs-go" -) - -// WithApparmor sets the provided apparmor profile to the spec -func WithApparmorProfile(profile string) SpecOpts { - return func(_ context.Context, _ *Client, _ *containers.Container, s *specs.Spec) error { - s.Process.ApparmorProfile = profile - return nil - } -} diff --git a/vendor/github.com/containerd/containerd/container_opts.go b/vendor/github.com/containerd/containerd/container_opts.go index 8e90be36c..4600dcf26 100644 --- a/vendor/github.com/containerd/containerd/container_opts.go +++ b/vendor/github.com/containerd/containerd/container_opts.go @@ -5,6 +5,8 @@ import ( "github.com/containerd/containerd/containers" "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/typeurl" + "github.com/gogo/protobuf/types" "github.com/opencontainers/image-spec/identity" "github.com/pkg/errors" ) @@ -14,10 +16,21 @@ type NewContainerOpts func(ctx context.Context, client *Client, c *containers.Co // WithRuntime allows a user to specify the runtime name and additional options that should // be used to create tasks for the container -func WithRuntime(name string) NewContainerOpts { +func WithRuntime(name string, options interface{}) NewContainerOpts { return func(ctx context.Context, client *Client, c *containers.Container) error { + var ( + any *types.Any + err error + ) + if options != nil { + any, err = typeurl.MarshalAny(options) + if err != nil { + return err + } + } c.Runtime = containers.RuntimeInfo{ - Name: name, + Name: name, + Options: any, } return nil } diff --git a/vendor/github.com/containerd/containerd/events/exchange.go b/vendor/github.com/containerd/containerd/events/exchange.go index eeb4b1fcb..93f6dfa91 100644 --- a/vendor/github.com/containerd/containerd/events/exchange.go +++ b/vendor/github.com/containerd/containerd/events/exchange.go @@ -185,11 +185,11 @@ func validateTopic(topic string) error { } if topic[0] != '/' { - return errors.Wrapf(errdefs.ErrInvalidArgument, "must start with '/'", topic) + return errors.Wrapf(errdefs.ErrInvalidArgument, "must start with '/'") } if len(topic) == 1 { - return errors.Wrapf(errdefs.ErrInvalidArgument, "must have at least one component", topic) + return errors.Wrapf(errdefs.ErrInvalidArgument, "must have at least one component") } components := strings.Split(topic[1:], "/") diff --git a/vendor/github.com/containerd/containerd/image.go b/vendor/github.com/containerd/containerd/image.go index 3737b7234..bf725cba6 100644 --- a/vendor/github.com/containerd/containerd/image.go +++ b/vendor/github.com/containerd/containerd/image.go @@ -20,10 +20,12 @@ type Image interface { Target() ocispec.Descriptor // Unpack unpacks the image's content into a snapshot Unpack(context.Context, string) error - // RootFS returns the image digests + // RootFS returns the unpacked diffids that make up images rootfs. RootFS(ctx context.Context) ([]digest.Digest, error) - // Size returns the image size + // Size returns the total size of the image's packed resources. Size(ctx context.Context) (int64, error) + // Config descriptor for the image. + Config(ctx context.Context) (ocispec.Descriptor, error) } var _ = (Image)(&image{}) @@ -52,6 +54,11 @@ func (i *image) Size(ctx context.Context) (int64, error) { return i.i.Size(ctx, provider) } +func (i *image) Config(ctx context.Context) (ocispec.Descriptor, error) { + provider := i.client.ContentStore() + return i.i.Config(ctx, provider) +} + func (i *image) Unpack(ctx context.Context, snapshotterName string) error { layers, err := i.getLayers(ctx) if err != nil { diff --git a/vendor/github.com/containerd/containerd/runtime/events.go b/vendor/github.com/containerd/containerd/runtime/events.go index 2c7a54174..fd69c0312 100644 --- a/vendor/github.com/containerd/containerd/runtime/events.go +++ b/vendor/github.com/containerd/containerd/runtime/events.go @@ -7,7 +7,9 @@ const ( TaskExitEventTopic = "/tasks/exit" TaskDeleteEventTopic = "/tasks/delete" TaskExecAddedEventTopic = "/tasks/exec-added" + TaskExecStartedEventTopic = "/tasks/exec-started" TaskPausedEventTopic = "/tasks/paused" TaskResumedEventTopic = "/tasks/resumed" TaskCheckpointedEventTopic = "/tasks/checkpointed" + TaskUnknownTopic = "/tasks/?" ) diff --git a/vendor/github.com/containerd/containerd/runtime/task_list.go b/vendor/github.com/containerd/containerd/runtime/task_list.go index e5d5c0e53..12062cef5 100644 --- a/vendor/github.com/containerd/containerd/runtime/task_list.go +++ b/vendor/github.com/containerd/containerd/runtime/task_list.go @@ -2,10 +2,10 @@ package runtime import ( "context" - "errors" "sync" "github.com/containerd/containerd/namespaces" + "github.com/pkg/errors" ) var ( @@ -75,7 +75,7 @@ func (l *TaskList) AddWithNamespace(namespace string, t Task) error { l.tasks[namespace] = make(map[string]Task) } if _, ok := l.tasks[namespace][id]; ok { - return ErrTaskAlreadyExists + return errors.Wrap(ErrTaskAlreadyExists, id) } l.tasks[namespace][id] = t return nil diff --git a/vendor/github.com/containerd/containerd/vendor.conf b/vendor/github.com/containerd/containerd/vendor.conf index a3cb9ba11..b93e27e1c 100644 --- a/vendor/github.com/containerd/containerd/vendor.conf +++ b/vendor/github.com/containerd/containerd/vendor.conf @@ -34,8 +34,9 @@ golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c github.com/BurntSushi/toml v0.2.0-21-g9906417 github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0 github.com/Microsoft/go-winio v0.4.4 +github.com/Microsoft/hcsshim v0.6.3 +github.com/Microsoft/opengcs v0.3.2 github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd -github.com/Microsoft/hcsshim v0.6.1 github.com/Azure/go-ansiterm 19f72df4d05d31cbe1c56bfc8045c96babff6c7e google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4