api/services/images: define images metadata service

This is a first pass at the metadata required for supporting an image
store. We use a shallow approach to the problem, allowing this
component to centralize the naming. Resources for this image can then be
"snowballed" in for actual implementations. This is better understood
through example.

Let's take pull. One could register the name "docker.io/stevvooe/foo" as
pointing at a particular digest. When instructed to pull or fetch, the
system will notice that no components of that image are present locally.
It can then recursively resolve the resources for that image and fetch
them into the content store. Next time the instruction is issued, the
content will be present so no action will be taken.

Another example is preparing the rootfs. The requirements for a rootfs
can be resolved from a name. These "diff ids" will then be compared with
what is available in the snapshot manager. Any parts of the rootfs, such
as a layer, that isn't available in the snapshotter can be unpacked.
Once this process is satisified, the image will be runnable as a
container.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
Stephen J Day 2017-03-30 16:56:06 -07:00
parent e119f1dc03
commit a5c9d6d41b
No known key found for this signature in database
GPG Key ID: 67B3DED84EDC823F
6 changed files with 1478 additions and 13 deletions

View File

@ -0,0 +1 @@
package images

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
syntax = "proto3";
package containerd.v1;
import "gogoproto/gogo.proto";
import "google/protobuf/empty.proto";
import "github.com/containerd/containerd/api/types/mount/mount.proto";
import "github.com/containerd/containerd/api/types/descriptor/descriptor.proto";
// Images is a service that allows one to register images with containerd.
//
// In containerd, an image is merely the mapping of a name to a content root,
// described by a descriptor. The behavior and state of image is purely
// dictated by the type of the descriptor.
//
// From the perspective of this service, these references are mostly shallow,
// in that the existence of the required content won't be validated until
// required by consuming services.
//
// As such, this can really be considered a "metadata service".
service Images {
// Get returns an image by name.
rpc Get(GetRequest) returns (GetResponse);
// Put assigns the name to a given target image based on the provided
// image.
rpc Put(PutRequest) returns (google.protobuf.Empty);
// List returns a list of all images known to containerd.
rpc List(ListRequest) returns (ListResponse);
// Delete deletes the image by name.
rpc Delete(DeleteRequest) returns (google.protobuf.Empty);
}
message Image {
string name = 1;
types.Descriptor target = 2 [(gogoproto.nullable) = false];
}
message GetRequest {
string name = 1;
// TODO(stevvooe): Consider that we may want to have multiple images under
// the same name or multiple names for the same image. This mapping could
// be truly many to many but we'll need a way to identify an entry.
//
// For now, we consider it unique but an intermediary index could be
// created to allow for a dispatch of images.
}
message GetResponse {
Image image = 1;
}
message PutRequest {
Image image = 1 [(gogoproto.nullable) = false];
}
message ListRequest {
// TODO(stevvooe): empty for now, need to ad filtration
// Some common use cases we might consider:
//
// 1. Select by multiple names.
// 2. Select by platform.
// 3. Select by annotations.
}
message ListResponse {
repeated Image images = 1 [(gogoproto.nullable) = false];
// TODO(stevvooe): Add pagination.
}
message DeleteRequest {
string name = 1;
}

View File

@ -42,7 +42,7 @@ const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
// oci descriptor found in a manifest.
// See https://godoc.org/github.com/opencontainers/image-spec/specs-go/v1#Descriptor
type Descriptor struct {
MediaType string `protobuf:"bytes,1,opt,name=mediaType,proto3" json:"mediaType,omitempty"`
MediaType string `protobuf:"bytes,1,opt,name=media_type,json=mediaType,proto3" json:"media_type,omitempty"`
Digest github_com_opencontainers_go_digest.Digest `protobuf:"bytes,2,opt,name=digest,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"digest"`
Size_ int64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"`
}
@ -403,20 +403,20 @@ func init() {
}
var fileDescriptorDescriptor = []byte{
// 225 bytes of a gzipped FileDescriptorProto
// 229 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x72, 0x4b, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0xcf, 0x2b, 0x49, 0xcc, 0xcc, 0x4b, 0x2d,
0x4a, 0x41, 0x66, 0x26, 0x16, 0x64, 0xea, 0x97, 0x54, 0x16, 0xa4, 0x16, 0xeb, 0xa7, 0xa4, 0x16,
0x27, 0x17, 0x65, 0x16, 0x94, 0xe4, 0x17, 0x21, 0x31, 0xf5, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85,
0x84, 0x11, 0x3a, 0xf4, 0xca, 0x0c, 0xf5, 0xc0, 0x1a, 0xa4, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1,
0xf2, 0xfa, 0x20, 0x16, 0x44, 0xa9, 0x52, 0x17, 0x23, 0x17, 0x97, 0x0b, 0x5c, 0xbf, 0x90, 0x0c,
0x17, 0x67, 0x6e, 0x6a, 0x4a, 0x66, 0x62, 0x48, 0x65, 0x41, 0xaa, 0x04, 0xa3, 0x02, 0xa3, 0x06,
0x67, 0x10, 0x42, 0x40, 0xc8, 0x8b, 0x8b, 0x2d, 0x25, 0x33, 0x3d, 0xb5, 0xb8, 0x44, 0x82, 0x09,
0x24, 0xe5, 0x64, 0x74, 0xe2, 0x9e, 0x3c, 0xc3, 0xad, 0x7b, 0xf2, 0x5a, 0x48, 0xee, 0xce, 0x2f,
0x48, 0xcd, 0x83, 0x5b, 0x5f, 0xac, 0x9f, 0x9e, 0xaf, 0x0b, 0xd1, 0xa2, 0xe7, 0x02, 0xa6, 0x82,
0xa0, 0x26, 0x08, 0x09, 0x71, 0xb1, 0x14, 0x67, 0x56, 0xa5, 0x4a, 0x30, 0x2b, 0x30, 0x6a, 0x30,
0x07, 0x81, 0xd9, 0x4e, 0x12, 0x27, 0x1e, 0xca, 0x31, 0xdc, 0x78, 0x28, 0xc7, 0xd0, 0xf0, 0x48,
0x8e, 0xf1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x4c, 0x62,
0x03, 0xbb, 0xd6, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x18, 0xd2, 0x1a, 0xc3, 0x22, 0x01, 0x00,
0x00,
0xf2, 0xfa, 0x20, 0x16, 0x44, 0xa9, 0x52, 0x37, 0x23, 0x17, 0x97, 0x0b, 0x5c, 0xbf, 0x90, 0x2c,
0x17, 0x57, 0x6e, 0x6a, 0x4a, 0x66, 0x62, 0x3c, 0x48, 0x8f, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67,
0x10, 0x27, 0x58, 0x24, 0xa4, 0xb2, 0x20, 0x55, 0xc8, 0x8b, 0x8b, 0x2d, 0x25, 0x33, 0x3d, 0xb5,
0xb8, 0x44, 0x82, 0x09, 0x24, 0xe5, 0x64, 0x74, 0xe2, 0x9e, 0x3c, 0xc3, 0xad, 0x7b, 0xf2, 0x5a,
0x48, 0x0e, 0xcf, 0x2f, 0x48, 0xcd, 0x83, 0xdb, 0x5f, 0xac, 0x9f, 0x9e, 0xaf, 0x0b, 0xd1, 0xa2,
0xe7, 0x02, 0xa6, 0x82, 0xa0, 0x26, 0x08, 0x09, 0x71, 0xb1, 0x14, 0x67, 0x56, 0xa5, 0x4a, 0x30,
0x2b, 0x30, 0x6a, 0x30, 0x07, 0x81, 0xd9, 0x4e, 0x12, 0x27, 0x1e, 0xca, 0x31, 0xdc, 0x78, 0x28,
0xc7, 0xd0, 0xf0, 0x48, 0x8e, 0xf1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c,
0x92, 0x63, 0x4c, 0x62, 0x03, 0x3b, 0xd7, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x45, 0x60, 0xfd,
0x5b, 0x23, 0x01, 0x00, 0x00,
}

View File

@ -10,7 +10,7 @@ import "gogoproto/gogo.proto";
// oci descriptor found in a manifest.
// See https://godoc.org/github.com/opencontainers/image-spec/specs-go/v1#Descriptor
message Descriptor {
string mediaType = 1;
string media_type = 1;
string digest = 2 [(gogoproto.customtype) = "github.com/opencontainers/go-digest.Digest", (gogoproto.nullable) = false];
int64 size = 3;
}

View File

@ -0,0 +1,32 @@
package images
import (
imagesapi "github.com/docker/containerd/api/services/images"
"github.com/docker/containerd/images"
"github.com/golang/protobuf/ptypes/empty"
"golang.org/x/net/context"
)
type Service struct {
store images.Store
}
func NewService(store images.Store) imagesapi.ImagesServer {
return &Service{store: store}
}
func (s *Service) Get(context.Context, *imagesapi.GetRequest) (*imagesapi.GetResponse, error) {
panic("not implemented")
}
func (s *Service) Register(context.Context, *imagesapi.RegisterRequest) (*imagesapi.RegisterRequest, error) {
panic("not implemented")
}
func (s *Service) List(context.Context, *imagesapi.ListRequest) (*imagesapi.ListResponse, error) {
panic("not implemented")
}
func (s *Service) Delete(context.Context, *imagesapi.DeleteRequest) (*empty.Empty, error) {
panic("not implemented")
}