diff --git a/client.go b/client.go index eb5bd9a11..6c5814425 100644 --- a/client.go +++ b/client.go @@ -33,11 +33,6 @@ import ( "github.com/containerd/containerd/remotes" "github.com/containerd/containerd/remotes/docker" "github.com/containerd/containerd/remotes/docker/schema1" - contentservice "github.com/containerd/containerd/services/content" - diffservice "github.com/containerd/containerd/services/diff" - imagesservice "github.com/containerd/containerd/services/images" - namespacesservice "github.com/containerd/containerd/services/namespaces" - snapshotservice "github.com/containerd/containerd/services/snapshot" "github.com/containerd/containerd/snapshot" "github.com/containerd/typeurl" ptypes "github.com/gogo/protobuf/types" @@ -426,7 +421,7 @@ func (c *Client) Close() error { // NamespaceService returns the underlying Namespaces Store func (c *Client) NamespaceService() namespaces.Store { - return namespacesservice.NewStoreFromClient(namespacesapi.NewNamespacesClient(c.conn)) + return NewNamespaceStoreFromClient(namespacesapi.NewNamespacesClient(c.conn)) } // ContainerService returns the underlying container Store @@ -436,12 +431,12 @@ func (c *Client) ContainerService() containers.Store { // ContentStore returns the underlying content Store func (c *Client) ContentStore() content.Store { - return contentservice.NewStoreFromClient(contentapi.NewContentClient(c.conn)) + return NewContentStoreFromClient(contentapi.NewContentClient(c.conn)) } // SnapshotService returns the underlying snapshotter for the provided snapshotter name func (c *Client) SnapshotService(snapshotterName string) snapshot.Snapshotter { - return snapshotservice.NewSnapshotterFromClient(snapshotapi.NewSnapshotsClient(c.conn), snapshotterName) + return NewSnapshotterFromClient(snapshotapi.NewSnapshotsClient(c.conn), snapshotterName) } // TaskService returns the underlying TasksClient @@ -451,12 +446,12 @@ func (c *Client) TaskService() tasks.TasksClient { // ImageService returns the underlying image Store func (c *Client) ImageService() images.Store { - return imagesservice.NewStoreFromClient(imagesapi.NewImagesClient(c.conn)) + return NewImageStoreFromClient(imagesapi.NewImagesClient(c.conn)) } // DiffService returns the underlying Differ func (c *Client) DiffService() diff.Differ { - return diffservice.NewDiffServiceFromClient(diffapi.NewDiffClient(c.conn)) + return NewDiffServiceFromClient(diffapi.NewDiffClient(c.conn)) } // IntrospectionService returns the underlying Introspection Client diff --git a/services/content/reader.go b/content_reader.go similarity index 97% rename from services/content/reader.go rename to content_reader.go index 024251c6d..7acd2d30e 100644 --- a/services/content/reader.go +++ b/content_reader.go @@ -1,4 +1,4 @@ -package content +package containerd import ( "context" diff --git a/services/content/store.go b/content_store.go similarity index 74% rename from services/content/store.go rename to content_store.go index b5aaa8577..1b539694d 100644 --- a/services/content/store.go +++ b/content_store.go @@ -1,4 +1,4 @@ -package content +package containerd import ( "context" @@ -11,18 +11,18 @@ import ( digest "github.com/opencontainers/go-digest" ) -type remoteStore struct { +type remoteContent struct { client contentapi.ContentClient } -// NewStoreFromClient returns a new content store -func NewStoreFromClient(client contentapi.ContentClient) content.Store { - return &remoteStore{ +// NewContentStoreFromClient returns a new content store +func NewContentStoreFromClient(client contentapi.ContentClient) content.Store { + return &remoteContent{ client: client, } } -func (rs *remoteStore) Info(ctx context.Context, dgst digest.Digest) (content.Info, error) { +func (rs *remoteContent) Info(ctx context.Context, dgst digest.Digest) (content.Info, error) { resp, err := rs.client.Info(ctx, &contentapi.InfoRequest{ Digest: dgst, }) @@ -33,7 +33,7 @@ func (rs *remoteStore) Info(ctx context.Context, dgst digest.Digest) (content.In return infoFromGRPC(resp.Info), nil } -func (rs *remoteStore) Walk(ctx context.Context, fn content.WalkFunc, filters ...string) error { +func (rs *remoteContent) Walk(ctx context.Context, fn content.WalkFunc, filters ...string) error { session, err := rs.client.List(ctx, &contentapi.ListContentRequest{ Filters: filters, }) @@ -61,7 +61,7 @@ func (rs *remoteStore) Walk(ctx context.Context, fn content.WalkFunc, filters .. return nil } -func (rs *remoteStore) Delete(ctx context.Context, dgst digest.Digest) error { +func (rs *remoteContent) Delete(ctx context.Context, dgst digest.Digest) error { if _, err := rs.client.Delete(ctx, &contentapi.DeleteContentRequest{ Digest: dgst, }); err != nil { @@ -71,7 +71,7 @@ func (rs *remoteStore) Delete(ctx context.Context, dgst digest.Digest) error { return nil } -func (rs *remoteStore) ReaderAt(ctx context.Context, dgst digest.Digest) (content.ReaderAt, error) { +func (rs *remoteContent) ReaderAt(ctx context.Context, dgst digest.Digest) (content.ReaderAt, error) { i, err := rs.Info(ctx, dgst) if err != nil { return nil, err @@ -85,7 +85,7 @@ func (rs *remoteStore) ReaderAt(ctx context.Context, dgst digest.Digest) (conten }, nil } -func (rs *remoteStore) Status(ctx context.Context, ref string) (content.Status, error) { +func (rs *remoteContent) Status(ctx context.Context, ref string) (content.Status, error) { resp, err := rs.client.Status(ctx, &contentapi.StatusRequest{ Ref: ref, }) @@ -104,7 +104,7 @@ func (rs *remoteStore) Status(ctx context.Context, ref string) (content.Status, }, nil } -func (rs *remoteStore) Update(ctx context.Context, info content.Info, fieldpaths ...string) (content.Info, error) { +func (rs *remoteContent) Update(ctx context.Context, info content.Info, fieldpaths ...string) (content.Info, error) { resp, err := rs.client.Update(ctx, &contentapi.UpdateRequest{ Info: infoToGRPC(info), UpdateMask: &protobuftypes.FieldMask{ @@ -117,7 +117,7 @@ func (rs *remoteStore) Update(ctx context.Context, info content.Info, fieldpaths return infoFromGRPC(resp.Info), nil } -func (rs *remoteStore) ListStatuses(ctx context.Context, filters ...string) ([]content.Status, error) { +func (rs *remoteContent) ListStatuses(ctx context.Context, filters ...string) ([]content.Status, error) { resp, err := rs.client.ListStatuses(ctx, &contentapi.ListStatusesRequest{ Filters: filters, }) @@ -140,7 +140,7 @@ func (rs *remoteStore) ListStatuses(ctx context.Context, filters ...string) ([]c return statuses, nil } -func (rs *remoteStore) Writer(ctx context.Context, ref string, size int64, expected digest.Digest) (content.Writer, error) { +func (rs *remoteContent) Writer(ctx context.Context, ref string, size int64, expected digest.Digest) (content.Writer, error) { wrclient, offset, err := rs.negotiate(ctx, ref, size, expected) if err != nil { return nil, errdefs.FromGRPC(err) @@ -154,7 +154,7 @@ func (rs *remoteStore) Writer(ctx context.Context, ref string, size int64, expec } // Abort implements asynchronous abort. It starts a new write session on the ref l -func (rs *remoteStore) Abort(ctx context.Context, ref string) error { +func (rs *remoteContent) Abort(ctx context.Context, ref string) error { if _, err := rs.client.Abort(ctx, &contentapi.AbortRequest{ Ref: ref, }); err != nil { @@ -164,7 +164,7 @@ func (rs *remoteStore) Abort(ctx context.Context, ref string) error { return nil } -func (rs *remoteStore) negotiate(ctx context.Context, ref string, size int64, expected digest.Digest) (contentapi.Content_WriteClient, int64, error) { +func (rs *remoteContent) negotiate(ctx context.Context, ref string, size int64, expected digest.Digest) (contentapi.Content_WriteClient, int64, error) { wrclient, err := rs.client.Write(ctx) if err != nil { return nil, 0, err diff --git a/services/content/writer.go b/content_writer.go similarity index 99% rename from services/content/writer.go rename to content_writer.go index b164a7c6a..b18f3512a 100644 --- a/services/content/writer.go +++ b/content_writer.go @@ -1,4 +1,4 @@ -package content +package containerd import ( "context" diff --git a/services/diff/client.go b/diff.go similarity index 85% rename from services/diff/client.go rename to diff.go index d34848be2..4e47efafc 100644 --- a/services/diff/client.go +++ b/diff.go @@ -1,4 +1,4 @@ -package diff +package containerd import ( diffapi "github.com/containerd/containerd/api/services/diff/v1" @@ -12,16 +12,16 @@ import ( // NewDiffServiceFromClient returns a new diff service which communicates // over a GRPC connection. func NewDiffServiceFromClient(client diffapi.DiffClient) diff.Differ { - return &remote{ + return &diffRemote{ client: client, } } -type remote struct { +type diffRemote struct { client diffapi.DiffClient } -func (r *remote) Apply(ctx context.Context, diff ocispec.Descriptor, mounts []mount.Mount) (ocispec.Descriptor, error) { +func (r *diffRemote) Apply(ctx context.Context, diff ocispec.Descriptor, mounts []mount.Mount) (ocispec.Descriptor, error) { req := &diffapi.ApplyRequest{ Diff: fromDescriptor(diff), Mounts: fromMounts(mounts), @@ -33,7 +33,7 @@ func (r *remote) Apply(ctx context.Context, diff ocispec.Descriptor, mounts []mo return toDescriptor(resp.Applied), nil } -func (r *remote) DiffMounts(ctx context.Context, a, b []mount.Mount, opts ...diff.Opt) (ocispec.Descriptor, error) { +func (r *diffRemote) DiffMounts(ctx context.Context, a, b []mount.Mount, opts ...diff.Opt) (ocispec.Descriptor, error) { var config diff.Config for _, opt := range opts { if err := opt(&config); err != nil { diff --git a/image_store.go b/image_store.go new file mode 100644 index 000000000..daa18f7f5 --- /dev/null +++ b/image_store.go @@ -0,0 +1,129 @@ +package containerd + +import ( + "context" + + imagesapi "github.com/containerd/containerd/api/services/images/v1" + "github.com/containerd/containerd/api/types" + "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/images" + ptypes "github.com/gogo/protobuf/types" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +type remoteImages struct { + client imagesapi.ImagesClient +} + +// NewImageStoreFromClient returns a new image store client +func NewImageStoreFromClient(client imagesapi.ImagesClient) images.Store { + return &remoteImages{ + client: client, + } +} + +func (s *remoteImages) Get(ctx context.Context, name string) (images.Image, error) { + resp, err := s.client.Get(ctx, &imagesapi.GetImageRequest{ + Name: name, + }) + if err != nil { + return images.Image{}, errdefs.FromGRPC(err) + } + + return imageFromProto(resp.Image), nil +} + +func (s *remoteImages) List(ctx context.Context, filters ...string) ([]images.Image, error) { + resp, err := s.client.List(ctx, &imagesapi.ListImagesRequest{ + Filters: filters, + }) + if err != nil { + return nil, errdefs.FromGRPC(err) + } + + return imagesFromProto(resp.Images), nil +} + +func (s *remoteImages) Create(ctx context.Context, image images.Image) (images.Image, error) { + created, err := s.client.Create(ctx, &imagesapi.CreateImageRequest{ + Image: imageToProto(&image), + }) + if err != nil { + return images.Image{}, errdefs.FromGRPC(err) + } + + return imageFromProto(&created.Image), nil +} + +func (s *remoteImages) Update(ctx context.Context, image images.Image, fieldpaths ...string) (images.Image, error) { + var updateMask *ptypes.FieldMask + if len(fieldpaths) > 0 { + updateMask = &ptypes.FieldMask{ + Paths: fieldpaths, + } + } + + updated, err := s.client.Update(ctx, &imagesapi.UpdateImageRequest{ + Image: imageToProto(&image), + UpdateMask: updateMask, + }) + if err != nil { + return images.Image{}, errdefs.FromGRPC(err) + } + + return imageFromProto(&updated.Image), nil +} + +func (s *remoteImages) Delete(ctx context.Context, name string) error { + _, err := s.client.Delete(ctx, &imagesapi.DeleteImageRequest{ + Name: name, + }) + + return errdefs.FromGRPC(err) +} + +func imageToProto(image *images.Image) imagesapi.Image { + return imagesapi.Image{ + Name: image.Name, + Labels: image.Labels, + Target: descToProto(&image.Target), + CreatedAt: image.CreatedAt, + UpdatedAt: image.UpdatedAt, + } +} + +func imageFromProto(imagepb *imagesapi.Image) images.Image { + return images.Image{ + Name: imagepb.Name, + Labels: imagepb.Labels, + Target: descFromProto(&imagepb.Target), + CreatedAt: imagepb.CreatedAt, + UpdatedAt: imagepb.UpdatedAt, + } +} + +func imagesFromProto(imagespb []imagesapi.Image) []images.Image { + var images []images.Image + + for _, image := range imagespb { + images = append(images, imageFromProto(&image)) + } + + return images +} + +func descFromProto(desc *types.Descriptor) ocispec.Descriptor { + return ocispec.Descriptor{ + MediaType: desc.MediaType, + Size: desc.Size_, + Digest: desc.Digest, + } +} + +func descToProto(desc *ocispec.Descriptor) types.Descriptor { + return types.Descriptor{ + MediaType: desc.MediaType, + Size_: desc.Size, + Digest: desc.Digest, + } +} diff --git a/services/namespaces/client.go b/namespaces.go similarity index 67% rename from services/namespaces/client.go rename to namespaces.go index fd59ec619..36fc50cab 100644 --- a/services/namespaces/client.go +++ b/namespaces.go @@ -1,4 +1,4 @@ -package namespaces +package containerd import ( "context" @@ -10,16 +10,16 @@ import ( "github.com/gogo/protobuf/types" ) -// NewStoreFromClient returns a new namespace store -func NewStoreFromClient(client api.NamespacesClient) namespaces.Store { - return &remote{client: client} +// NewNamespaceStoreFromClient returns a new namespace store +func NewNamespaceStoreFromClient(client api.NamespacesClient) namespaces.Store { + return &remoteNamespaces{client: client} } -type remote struct { +type remoteNamespaces struct { client api.NamespacesClient } -func (r *remote) Create(ctx context.Context, namespace string, labels map[string]string) error { +func (r *remoteNamespaces) Create(ctx context.Context, namespace string, labels map[string]string) error { var req api.CreateNamespaceRequest req.Namespace = api.Namespace{ @@ -35,7 +35,7 @@ func (r *remote) Create(ctx context.Context, namespace string, labels map[string return nil } -func (r *remote) Labels(ctx context.Context, namespace string) (map[string]string, error) { +func (r *remoteNamespaces) Labels(ctx context.Context, namespace string) (map[string]string, error) { var req api.GetNamespaceRequest req.Name = namespace @@ -47,7 +47,7 @@ func (r *remote) Labels(ctx context.Context, namespace string) (map[string]strin return resp.Namespace.Labels, nil } -func (r *remote) SetLabel(ctx context.Context, namespace, key, value string) error { +func (r *remoteNamespaces) SetLabel(ctx context.Context, namespace, key, value string) error { var req api.UpdateNamespaceRequest req.Namespace = api.Namespace{ @@ -67,7 +67,7 @@ func (r *remote) SetLabel(ctx context.Context, namespace, key, value string) err return nil } -func (r *remote) List(ctx context.Context) ([]string, error) { +func (r *remoteNamespaces) List(ctx context.Context) ([]string, error) { var req api.ListNamespacesRequest resp, err := r.client.List(ctx, &req) @@ -84,7 +84,7 @@ func (r *remote) List(ctx context.Context) ([]string, error) { return namespaces, nil } -func (r *remote) Delete(ctx context.Context, namespace string) error { +func (r *remoteNamespaces) Delete(ctx context.Context, namespace string) error { var req api.DeleteNamespaceRequest req.Name = namespace diff --git a/services/content/service.go b/services/content/service.go index 173ef17fb..b7573cf7b 100644 --- a/services/content/service.go +++ b/services/content/service.go @@ -452,3 +452,23 @@ func (s *service) Abort(ctx context.Context, req *api.AbortRequest) (*ptypes.Emp return &ptypes.Empty{}, nil } + +func infoToGRPC(info content.Info) api.Info { + return api.Info{ + Digest: info.Digest, + Size_: info.Size, + CreatedAt: info.CreatedAt, + UpdatedAt: info.UpdatedAt, + Labels: info.Labels, + } +} + +func infoFromGRPC(info api.Info) content.Info { + return content.Info{ + Digest: info.Digest, + Size: info.Size_, + CreatedAt: info.CreatedAt, + UpdatedAt: info.UpdatedAt, + Labels: info.Labels, + } +} diff --git a/services/diff/service.go b/services/diff/service.go index 81e44dcf6..f847693a4 100644 --- a/services/diff/service.go +++ b/services/diff/service.go @@ -140,3 +140,19 @@ func toMounts(apim []*types.Mount) []mount.Mount { } return mounts } + +func toDescriptor(d *types.Descriptor) ocispec.Descriptor { + return ocispec.Descriptor{ + MediaType: d.MediaType, + Digest: d.Digest, + Size: d.Size_, + } +} + +func fromDescriptor(d ocispec.Descriptor) *types.Descriptor { + return &types.Descriptor{ + MediaType: d.MediaType, + Digest: d.Digest, + Size_: d.Size, + } +} diff --git a/services/images/client.go b/services/images/client.go deleted file mode 100644 index f746ddce8..000000000 --- a/services/images/client.go +++ /dev/null @@ -1,81 +0,0 @@ -package images - -import ( - "context" - - imagesapi "github.com/containerd/containerd/api/services/images/v1" - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/images" - ptypes "github.com/gogo/protobuf/types" -) - -type remoteStore struct { - client imagesapi.ImagesClient -} - -// NewStoreFromClient returns a new image store client -func NewStoreFromClient(client imagesapi.ImagesClient) images.Store { - return &remoteStore{ - client: client, - } -} - -func (s *remoteStore) Get(ctx context.Context, name string) (images.Image, error) { - resp, err := s.client.Get(ctx, &imagesapi.GetImageRequest{ - Name: name, - }) - if err != nil { - return images.Image{}, errdefs.FromGRPC(err) - } - - return imageFromProto(resp.Image), nil -} - -func (s *remoteStore) List(ctx context.Context, filters ...string) ([]images.Image, error) { - resp, err := s.client.List(ctx, &imagesapi.ListImagesRequest{ - Filters: filters, - }) - if err != nil { - return nil, errdefs.FromGRPC(err) - } - - return imagesFromProto(resp.Images), nil -} - -func (s *remoteStore) Create(ctx context.Context, image images.Image) (images.Image, error) { - created, err := s.client.Create(ctx, &imagesapi.CreateImageRequest{ - Image: imageToProto(&image), - }) - if err != nil { - return images.Image{}, errdefs.FromGRPC(err) - } - - return imageFromProto(&created.Image), nil -} - -func (s *remoteStore) Update(ctx context.Context, image images.Image, fieldpaths ...string) (images.Image, error) { - var updateMask *ptypes.FieldMask - if len(fieldpaths) > 0 { - updateMask = &ptypes.FieldMask{ - Paths: fieldpaths, - } - } - - updated, err := s.client.Update(ctx, &imagesapi.UpdateImageRequest{ - Image: imageToProto(&image), - UpdateMask: updateMask, - }) - if err != nil { - return images.Image{}, errdefs.FromGRPC(err) - } - - return imageFromProto(&updated.Image), nil -} - -func (s *remoteStore) Delete(ctx context.Context, name string) error { - _, err := s.client.Delete(ctx, &imagesapi.DeleteImageRequest{ - Name: name, - }) - - return errdefs.FromGRPC(err) -} diff --git a/services/snapshot/service.go b/services/snapshot/service.go index 7d5a20ec2..3e08d60c5 100644 --- a/services/snapshot/service.go +++ b/services/snapshot/service.go @@ -293,3 +293,24 @@ func fromMounts(mounts []mount.Mount) []*types.Mount { } return out } + +func toInfo(info snapshotapi.Info) snapshot.Info { + return snapshot.Info{ + Name: info.Name, + Parent: info.Parent, + Kind: toKind(info.Kind), + Created: info.CreatedAt, + Updated: info.UpdatedAt, + Labels: info.Labels, + } +} + +func toKind(kind snapshotapi.Kind) snapshot.Kind { + if kind == snapshotapi.KindActive { + return snapshot.KindActive + } + if kind == snapshotapi.KindView { + return snapshot.KindView + } + return snapshot.KindCommitted +} diff --git a/services/snapshot/client.go b/snapshot.go similarity index 91% rename from services/snapshot/client.go rename to snapshot.go index 812b00ce0..e29d21ca3 100644 --- a/services/snapshot/client.go +++ b/snapshot.go @@ -1,4 +1,4 @@ -package snapshot +package containerd import ( "context" @@ -206,3 +206,24 @@ func toMounts(mm []*types.Mount) []mount.Mount { } return mounts } + +func fromKind(kind snapshot.Kind) snapshotapi.Kind { + if kind == snapshot.KindActive { + return snapshotapi.KindActive + } + if kind == snapshot.KindView { + return snapshotapi.KindView + } + return snapshotapi.KindCommitted +} + +func fromInfo(info snapshot.Info) snapshotapi.Info { + return snapshotapi.Info{ + Name: info.Name, + Parent: info.Parent, + Kind: fromKind(info.Kind), + CreatedAt: info.Created, + UpdatedAt: info.Updated, + Labels: info.Labels, + } +}