Merge pull request #278 from Random-Liu/update-containerd

Update containerd to v1.0.0-beta.1
This commit is contained in:
Mike Brown 2017-09-23 12:08:05 -05:00 committed by GitHub
commit 529971a1dd
41 changed files with 707 additions and 563 deletions

View File

@ -1,5 +1,5 @@
RUNC_VERSION=593914b8bd5448a93f7c3e4902a03408b6d5c0ce
CNI_VERSION=v0.6.0
CONTAINERD_VERSION=9934acb27147f6b25707ba486e30c4dc040ba040
CONTAINERD_VERSION=v1.0.0-beta.1
CRITOOL_VERSION=48f8614feab2e345647aa8c923c55b98bd1e842c
KUBERNETES_VERSION=11a836078d0c78a4253a77a3ff6f4a555c4121f9

View File

@ -2,7 +2,7 @@ github.com/blang/semver v3.1.0
github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
github.com/containerd/cgroups 5933ab4dc4f7caa3a73a1dc141bd11f42b5c9163
github.com/containerd/containerd 9934acb27147f6b25707ba486e30c4dc040ba040
github.com/containerd/containerd v1.0.0-beta.1
github.com/containerd/continuity cf279e6ac893682272b4479d4c67fd3abf878b4e
github.com/containerd/fifo fbfb6a11ec671efbe94ad1c12c2e98773f19e1e6
github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788

View File

@ -9,6 +9,8 @@ containerd is an industry-standard container runtime with an emphasis on simplic
containerd is designed to be embedded into a larger system, rather than being used directly by developers or end-users.
![architecture](design/architecture.png)
## Getting Started
If you are interested in trying out containerd please see our [Getting Started Guide](docs/getting-started.md).

View File

@ -65,6 +65,8 @@ type Container struct {
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
// Labels provides an area to include arbitrary data on containers.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
//
// Note that to add a new value to this field, read the existing set and
// include the entire result in the update call.
Labels map[string]string `protobuf:"bytes,2,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`

View File

@ -42,6 +42,8 @@ message Container {
// Labels provides an area to include arbitrary data on containers.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
//
// Note that to add a new value to this field, read the existing set and
// include the entire result in the update call.
map<string, string> labels = 2;

View File

@ -115,7 +115,9 @@ type Info struct {
CreatedAt time.Time `protobuf:"bytes,3,opt,name=created_at,json=createdAt,stdtime" json:"created_at"`
// UpdatedAt provides the time the info was last updated.
UpdatedAt time.Time `protobuf:"bytes,4,opt,name=updated_at,json=updatedAt,stdtime" json:"updated_at"`
// Labels are arbitrary data on content.
// Labels are arbitrary data on snapshots.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
Labels map[string]string `protobuf:"bytes,5,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
@ -321,7 +323,9 @@ type WriteContentRequest struct {
// If this is empty and the message is not a commit, a response will be
// returned with the current write state.
Data []byte `protobuf:"bytes,6,opt,name=data,proto3" json:"data,omitempty"`
// Labels are arbitrary data to set on commit.
// Labels are arbitrary data on snapshots.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
Labels map[string]string `protobuf:"bytes,7,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}

View File

@ -87,7 +87,9 @@ message Info {
// UpdatedAt provides the time the info was last updated.
google.protobuf.Timestamp updated_at = 4 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
// Labels are arbitrary data on content.
// Labels are arbitrary data on snapshots.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
map<string, string> labels = 5;
}
@ -270,7 +272,9 @@ message WriteContentRequest {
// returned with the current write state.
bytes data = 6;
// Labels are arbitrary data to set on commit.
// Labels are arbitrary data on snapshots.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
map<string, string> labels = 7;
}

View File

@ -67,6 +67,7 @@ type Image struct {
// and do not get inherited into the package image in any way.
//
// Labels may be updated using the field mask.
// The combined size of a key/value pair cannot exceed 4096 bytes.
Labels map[string]string `protobuf:"bytes,2,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
// Target describes the content entry point of the image.
Target containerd_types.Descriptor `protobuf:"bytes,3,opt,name=target" json:"target"`

View File

@ -51,6 +51,7 @@ message Image {
// and do not get inherited into the package image in any way.
//
// Labels may be updated using the field mask.
// The combined size of a key/value pair cannot exceed 4096 bytes.
map<string, string> labels = 2;
// Target describes the content entry point of the image.

View File

@ -55,6 +55,8 @@ type Namespace struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// Labels provides an area to include arbitrary data on namespaces.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
//
// Note that to add a new value to this field, read the existing set and
// include the entire result in the update call.
Labels map[string]string `protobuf:"bytes,2,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`

View File

@ -32,6 +32,8 @@ message Namespace {
// Labels provides an area to include arbitrary data on namespaces.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
//
// Note that to add a new value to this field, read the existing set and
// include the entire result in the update call.
map<string, string> labels = 2;

View File

@ -97,6 +97,8 @@ type PrepareSnapshotRequest struct {
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
Parent string `protobuf:"bytes,3,opt,name=parent,proto3" json:"parent,omitempty"`
// Labels are arbitrary data on snapshots.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
Labels map[string]string `protobuf:"bytes,4,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
@ -117,6 +119,8 @@ type ViewSnapshotRequest struct {
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
Parent string `protobuf:"bytes,3,opt,name=parent,proto3" json:"parent,omitempty"`
// Labels are arbitrary data on snapshots.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
Labels map[string]string `protobuf:"bytes,4,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
@ -163,6 +167,8 @@ type CommitSnapshotRequest struct {
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"`
// Labels are arbitrary data on snapshots.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
Labels map[string]string `protobuf:"bytes,4,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
@ -188,6 +194,8 @@ type Info struct {
// UpdatedAt provides the time the info was last updated.
UpdatedAt time.Time `protobuf:"bytes,5,opt,name=updated_at,json=updatedAt,stdtime" json:"updated_at"`
// Labels are arbitrary data on snapshots.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
Labels map[string]string `protobuf:"bytes,6,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}

View File

@ -29,6 +29,8 @@ message PrepareSnapshotRequest {
string parent = 3;
// Labels are arbitrary data on snapshots.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
map<string, string> labels = 4;
}
@ -42,6 +44,8 @@ message ViewSnapshotRequest {
string parent = 3;
// Labels are arbitrary data on snapshots.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
map<string, string> labels = 4;
}
@ -69,6 +73,8 @@ message CommitSnapshotRequest {
string key = 3;
// Labels are arbitrary data on snapshots.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
map<string, string> labels = 4;
}
@ -99,6 +105,8 @@ message Info {
google.protobuf.Timestamp updated_at = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
// Labels are arbitrary data on snapshots.
//
// The combined size of a key/value pair cannot exceed 4096 bytes.
map<string, string> labels = 6;
}

View File

@ -34,6 +34,8 @@
UpdateTaskRequest
MetricsRequest
MetricsResponse
WaitRequest
WaitResponse
*/
package tasks
@ -316,6 +318,24 @@ func (m *MetricsResponse) Reset() { *m = MetricsResponse{} }
func (*MetricsResponse) ProtoMessage() {}
func (*MetricsResponse) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{24} }
type WaitRequest struct {
ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"`
ExecID string `protobuf:"bytes,2,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"`
}
func (m *WaitRequest) Reset() { *m = WaitRequest{} }
func (*WaitRequest) ProtoMessage() {}
func (*WaitRequest) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{25} }
type WaitResponse struct {
ExitStatus uint32 `protobuf:"varint,1,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"`
ExitedAt time.Time `protobuf:"bytes,2,opt,name=exited_at,json=exitedAt,stdtime" json:"exited_at"`
}
func (m *WaitResponse) Reset() { *m = WaitResponse{} }
func (*WaitResponse) ProtoMessage() {}
func (*WaitResponse) Descriptor() ([]byte, []int) { return fileDescriptorTasks, []int{26} }
func init() {
proto.RegisterType((*CreateTaskRequest)(nil), "containerd.services.tasks.v1.CreateTaskRequest")
proto.RegisterType((*CreateTaskResponse)(nil), "containerd.services.tasks.v1.CreateTaskResponse")
@ -342,6 +362,8 @@ func init() {
proto.RegisterType((*UpdateTaskRequest)(nil), "containerd.services.tasks.v1.UpdateTaskRequest")
proto.RegisterType((*MetricsRequest)(nil), "containerd.services.tasks.v1.MetricsRequest")
proto.RegisterType((*MetricsResponse)(nil), "containerd.services.tasks.v1.MetricsResponse")
proto.RegisterType((*WaitRequest)(nil), "containerd.services.tasks.v1.WaitRequest")
proto.RegisterType((*WaitResponse)(nil), "containerd.services.tasks.v1.WaitResponse")
}
// Reference imports to suppress errors if they are not otherwise used.
@ -375,6 +397,7 @@ type TasksClient interface {
Checkpoint(ctx context.Context, in *CheckpointTaskRequest, opts ...grpc.CallOption) (*CheckpointTaskResponse, error)
Update(ctx context.Context, in *UpdateTaskRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error)
Metrics(ctx context.Context, in *MetricsRequest, opts ...grpc.CallOption) (*MetricsResponse, error)
Wait(ctx context.Context, in *WaitRequest, opts ...grpc.CallOption) (*WaitResponse, error)
}
type tasksClient struct {
@ -529,6 +552,15 @@ func (c *tasksClient) Metrics(ctx context.Context, in *MetricsRequest, opts ...g
return out, nil
}
func (c *tasksClient) Wait(ctx context.Context, in *WaitRequest, opts ...grpc.CallOption) (*WaitResponse, error) {
out := new(WaitResponse)
err := grpc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Wait", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Tasks service
type TasksServer interface {
@ -552,6 +584,7 @@ type TasksServer interface {
Checkpoint(context.Context, *CheckpointTaskRequest) (*CheckpointTaskResponse, error)
Update(context.Context, *UpdateTaskRequest) (*google_protobuf.Empty, error)
Metrics(context.Context, *MetricsRequest) (*MetricsResponse, error)
Wait(context.Context, *WaitRequest) (*WaitResponse, error)
}
func RegisterTasksServer(s *grpc.Server, srv TasksServer) {
@ -846,6 +879,24 @@ func _Tasks_Metrics_Handler(srv interface{}, ctx context.Context, dec func(inter
return interceptor(ctx, in, info, handler)
}
func _Tasks_Wait_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(WaitRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TasksServer).Wait(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/containerd.services.tasks.v1.Tasks/Wait",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TasksServer).Wait(ctx, req.(*WaitRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Tasks_serviceDesc = grpc.ServiceDesc{
ServiceName: "containerd.services.tasks.v1.Tasks",
HandlerType: (*TasksServer)(nil),
@ -914,6 +965,10 @@ var _Tasks_serviceDesc = grpc.ServiceDesc{
MethodName: "Metrics",
Handler: _Tasks_Metrics_Handler,
},
{
MethodName: "Wait",
Handler: _Tasks_Wait_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "github.com/containerd/containerd/api/services/tasks/v1/tasks.proto",
@ -1778,6 +1833,67 @@ func (m *MetricsResponse) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *WaitRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *WaitRequest) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.ContainerID) > 0 {
dAtA[i] = 0xa
i++
i = encodeVarintTasks(dAtA, i, uint64(len(m.ContainerID)))
i += copy(dAtA[i:], m.ContainerID)
}
if len(m.ExecID) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintTasks(dAtA, i, uint64(len(m.ExecID)))
i += copy(dAtA[i:], m.ExecID)
}
return i, nil
}
func (m *WaitResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *WaitResponse) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.ExitStatus != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintTasks(dAtA, i, uint64(m.ExitStatus))
}
dAtA[i] = 0x12
i++
i = encodeVarintTasks(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.ExitedAt)))
n10, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ExitedAt, dAtA[i:])
if err != nil {
return 0, err
}
i += n10
return i, nil
}
func encodeFixed64Tasks(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
@ -2175,6 +2291,31 @@ func (m *MetricsResponse) Size() (n int) {
return n
}
func (m *WaitRequest) Size() (n int) {
var l int
_ = l
l = len(m.ContainerID)
if l > 0 {
n += 1 + l + sovTasks(uint64(l))
}
l = len(m.ExecID)
if l > 0 {
n += 1 + l + sovTasks(uint64(l))
}
return n
}
func (m *WaitResponse) Size() (n int) {
var l int
_ = l
if m.ExitStatus != 0 {
n += 1 + sovTasks(uint64(m.ExitStatus))
}
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.ExitedAt)
n += 1 + l + sovTasks(uint64(l))
return n
}
func sovTasks(x uint64) (n int) {
for {
n++
@ -2468,6 +2609,28 @@ func (this *MetricsResponse) String() string {
}, "")
return s
}
func (this *WaitRequest) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&WaitRequest{`,
`ContainerID:` + fmt.Sprintf("%v", this.ContainerID) + `,`,
`ExecID:` + fmt.Sprintf("%v", this.ExecID) + `,`,
`}`,
}, "")
return s
}
func (this *WaitResponse) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&WaitResponse{`,
`ExitStatus:` + fmt.Sprintf("%v", this.ExitStatus) + `,`,
`ExitedAt:` + strings.Replace(strings.Replace(this.ExitedAt.String(), "Timestamp", "google_protobuf3.Timestamp", 1), `&`, ``, 1) + `,`,
`}`,
}, "")
return s
}
func valueToStringTasks(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
@ -5281,6 +5444,213 @@ func (m *MetricsResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *WaitRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: WaitRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: WaitRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ContainerID", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTasks
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ContainerID = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ExecID", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTasks
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ExecID = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTasks(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthTasks
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *WaitResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: WaitResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: WaitResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ExitStatus", wireType)
}
m.ExitStatus = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ExitStatus |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ExitedAt", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTasks
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.ExitedAt, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTasks(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthTasks
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipTasks(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
@ -5391,85 +5761,88 @@ func init() {
}
var fileDescriptorTasks = []byte{
// 1274 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x4f, 0x6f, 0x1b, 0x45,
0x14, 0xef, 0xc6, 0xf6, 0xda, 0x7e, 0x6e, 0xda, 0x64, 0x48, 0xc3, 0xb2, 0x54, 0x71, 0x58, 0x24,
0x64, 0x02, 0xdd, 0xa5, 0x2e, 0xaa, 0x10, 0xad, 0x90, 0x9a, 0x3f, 0x44, 0x16, 0x54, 0x4d, 0xb7,
0x05, 0xa1, 0x5e, 0xc2, 0x76, 0x77, 0xe2, 0x8c, 0x62, 0xef, 0x6e, 0x77, 0xc6, 0x69, 0x03, 0x07,
0xf8, 0x08, 0xbd, 0x72, 0xe1, 0xf3, 0xe4, 0xc8, 0x11, 0x21, 0x14, 0xa8, 0xbf, 0x05, 0x07, 0x24,
0x34, 0x7f, 0x76, 0xb3, 0xb1, 0xe3, 0xd8, 0xa9, 0x1b, 0x2e, 0xed, 0xcc, 0xec, 0xef, 0xbd, 0x79,
0xf3, 0x9b, 0x37, 0xef, 0xfd, 0x1c, 0x58, 0x6d, 0x13, 0xb6, 0xdb, 0x7b, 0x6a, 0xfb, 0x51, 0xd7,
0xf1, 0xa3, 0x90, 0x79, 0x24, 0xc4, 0x49, 0x90, 0x1f, 0x7a, 0x31, 0x71, 0x28, 0x4e, 0xf6, 0x89,
0x8f, 0xa9, 0xc3, 0x3c, 0xba, 0x47, 0x9d, 0xfd, 0x9b, 0x72, 0x60, 0xc7, 0x49, 0xc4, 0x22, 0x74,
0xfd, 0x18, 0x6d, 0xa7, 0x48, 0x5b, 0x02, 0xf6, 0x6f, 0x9a, 0xef, 0xb6, 0xa3, 0xa8, 0xdd, 0xc1,
0x8e, 0xc0, 0x3e, 0xed, 0xed, 0x38, 0xb8, 0x1b, 0xb3, 0x03, 0x69, 0x6a, 0xbe, 0x33, 0xf8, 0xd1,
0x0b, 0xd3, 0x4f, 0x0b, 0xed, 0xa8, 0x1d, 0x89, 0xa1, 0xc3, 0x47, 0x6a, 0xf5, 0xf6, 0x44, 0xf1,
0xb2, 0x83, 0x18, 0x53, 0xa7, 0x1b, 0xf5, 0x42, 0xa6, 0xec, 0x3e, 0x3b, 0x8f, 0x1d, 0x66, 0x09,
0xf1, 0xd5, 0xe9, 0xcc, 0x3b, 0xe7, 0xb0, 0x0c, 0x30, 0xf5, 0x13, 0x12, 0xb3, 0x28, 0x51, 0xc6,
0x9f, 0x9f, 0xc3, 0x98, 0x33, 0x26, 0xfe, 0x51, 0xb6, 0xf5, 0x41, 0x6e, 0x18, 0xe9, 0x62, 0xca,
0xbc, 0x6e, 0x2c, 0x01, 0xd6, 0xe1, 0x0c, 0xcc, 0xaf, 0x25, 0xd8, 0x63, 0xf8, 0xb1, 0x47, 0xf7,
0x5c, 0xfc, 0xac, 0x87, 0x29, 0x43, 0x4d, 0xb8, 0x9c, 0xb9, 0xdf, 0x26, 0x81, 0xa1, 0x2d, 0x6b,
0x8d, 0xea, 0xea, 0xd5, 0xfe, 0x51, 0xbd, 0xb6, 0x96, 0xae, 0xb7, 0xd6, 0xdd, 0x5a, 0x06, 0x6a,
0x05, 0xc8, 0x01, 0x3d, 0x89, 0x22, 0xb6, 0x43, 0x8d, 0xc2, 0x72, 0xa1, 0x51, 0x6b, 0xbe, 0x6d,
0xe7, 0xae, 0x54, 0x44, 0x67, 0xdf, 0xe7, 0x64, 0xba, 0x0a, 0x86, 0x16, 0xa0, 0x44, 0x59, 0x40,
0x42, 0xa3, 0xc8, 0xbd, 0xbb, 0x72, 0x82, 0x16, 0x41, 0xa7, 0x2c, 0x88, 0x7a, 0xcc, 0x28, 0x89,
0x65, 0x35, 0x53, 0xeb, 0x38, 0x49, 0x0c, 0x3d, 0x5b, 0xc7, 0x49, 0x82, 0x4c, 0xa8, 0x30, 0x9c,
0x74, 0x49, 0xe8, 0x75, 0x8c, 0xf2, 0xb2, 0xd6, 0xa8, 0xb8, 0xd9, 0x1c, 0xdd, 0x05, 0xf0, 0x77,
0xb1, 0xbf, 0x17, 0x47, 0x24, 0x64, 0x46, 0x65, 0x59, 0x6b, 0xd4, 0x9a, 0xd7, 0x87, 0xc3, 0x5a,
0xcf, 0x18, 0x77, 0x73, 0x78, 0x64, 0x43, 0x39, 0x8a, 0x19, 0x89, 0x42, 0x6a, 0x54, 0x85, 0xe9,
0x82, 0x2d, 0xd9, 0xb4, 0x53, 0x36, 0xed, 0x7b, 0xe1, 0x81, 0x9b, 0x82, 0xac, 0x27, 0x80, 0xf2,
0x4c, 0xd2, 0x38, 0x0a, 0x29, 0x7e, 0x2d, 0x2a, 0xe7, 0xa0, 0x10, 0x93, 0xc0, 0x98, 0x59, 0xd6,
0x1a, 0xb3, 0x2e, 0x1f, 0x5a, 0x6d, 0xb8, 0xfc, 0x88, 0x79, 0x09, 0x9b, 0xe6, 0x82, 0xde, 0x87,
0x32, 0x7e, 0x81, 0xfd, 0x6d, 0xe5, 0xb9, 0xba, 0x0a, 0xfd, 0xa3, 0xba, 0xbe, 0xf1, 0x02, 0xfb,
0xad, 0x75, 0x57, 0xe7, 0x9f, 0x5a, 0x81, 0xf5, 0x1e, 0xcc, 0xaa, 0x8d, 0x54, 0xfc, 0x2a, 0x16,
0xed, 0x38, 0x96, 0x4d, 0x98, 0x5f, 0xc7, 0x1d, 0x3c, 0x75, 0xc6, 0x58, 0xbf, 0x6a, 0x70, 0x45,
0x7a, 0xca, 0x76, 0x5b, 0x84, 0x99, 0xcc, 0x58, 0xef, 0x1f, 0xd5, 0x67, 0x5a, 0xeb, 0xee, 0x0c,
0x39, 0x85, 0x11, 0x54, 0x87, 0x1a, 0x7e, 0x41, 0xd8, 0x36, 0x65, 0x1e, 0xeb, 0xf1, 0x9c, 0xe3,
0x5f, 0x80, 0x2f, 0x3d, 0x12, 0x2b, 0xe8, 0x1e, 0x54, 0xf9, 0x0c, 0x07, 0xdb, 0x1e, 0x13, 0x29,
0x56, 0x6b, 0x9a, 0x43, 0x17, 0xf8, 0x38, 0x7d, 0x0e, 0xab, 0x95, 0xc3, 0xa3, 0xfa, 0xa5, 0x97,
0x7f, 0xd5, 0x35, 0xb7, 0x22, 0xcd, 0xee, 0x31, 0x2b, 0x82, 0x05, 0x19, 0xdf, 0x56, 0x12, 0xf9,
0x98, 0xd2, 0x0b, 0x67, 0x1f, 0x03, 0x6c, 0xe2, 0x8b, 0xbf, 0xe4, 0x0d, 0xa8, 0x89, 0x6d, 0x14,
0xe9, 0xb7, 0xa1, 0x1c, 0xcb, 0x03, 0x8a, 0x2d, 0x06, 0xde, 0xc8, 0xfe, 0x4d, 0xf5, 0x4c, 0x52,
0x12, 0x52, 0xb0, 0xb5, 0x02, 0x73, 0x5f, 0x13, 0xca, 0x78, 0x1a, 0x64, 0xd4, 0x2c, 0x82, 0xbe,
0x43, 0x3a, 0x0c, 0x27, 0x32, 0x5a, 0x57, 0xcd, 0x78, 0xd2, 0xe4, 0xb0, 0xd9, 0xdb, 0x28, 0x89,
0x12, 0x6f, 0x68, 0xa2, 0x62, 0x9c, 0xbd, 0xad, 0x84, 0x5a, 0x2f, 0x35, 0xa8, 0x7d, 0x45, 0x3a,
0x9d, 0x8b, 0x26, 0x49, 0x14, 0x1c, 0xd2, 0xe6, 0x65, 0x45, 0xe6, 0x96, 0x9a, 0xf1, 0x54, 0xf4,
0x3a, 0x1d, 0x91, 0x51, 0x15, 0x97, 0x0f, 0xad, 0x7f, 0x34, 0x40, 0xdc, 0xf8, 0x0d, 0x64, 0x49,
0x56, 0x13, 0x67, 0x4e, 0xaf, 0x89, 0x85, 0x11, 0x35, 0xb1, 0x38, 0xb2, 0x26, 0x96, 0x06, 0x6a,
0x62, 0x03, 0x8a, 0x34, 0xc6, 0xbe, 0xa8, 0xa2, 0xa3, 0x4a, 0x9a, 0x40, 0xe4, 0x59, 0x2a, 0x8f,
0x4c, 0xa5, 0x6b, 0xf0, 0xd6, 0x89, 0xa3, 0xcb, 0x9b, 0xb5, 0x7e, 0xd1, 0x60, 0xce, 0xc5, 0x94,
0xfc, 0x80, 0xb7, 0xd8, 0xc1, 0x85, 0x5f, 0xd5, 0x02, 0x94, 0x9e, 0x93, 0x80, 0xed, 0xaa, 0x9b,
0x92, 0x13, 0xce, 0xce, 0x2e, 0x26, 0xed, 0x5d, 0xf9, 0xfa, 0x67, 0x5d, 0x35, 0xb3, 0x7e, 0x82,
0x2b, 0x6b, 0x9d, 0x88, 0xe2, 0xd6, 0x83, 0xff, 0x23, 0x30, 0x79, 0x9d, 0x05, 0x71, 0x0b, 0x72,
0x62, 0x7d, 0x09, 0x73, 0x5b, 0x5e, 0x8f, 0x4e, 0x5d, 0x3f, 0x37, 0x61, 0xde, 0xc5, 0xb4, 0xd7,
0x9d, 0xda, 0xd1, 0x06, 0x5c, 0xe5, 0x8f, 0x73, 0x8b, 0x04, 0xd3, 0x24, 0xaf, 0xf5, 0x81, 0xac,
0x07, 0xd2, 0x8d, 0x7a, 0xe2, 0x08, 0x8a, 0x31, 0x09, 0xe4, 0x0b, 0x9f, 0x75, 0xc5, 0xd8, 0xfa,
0x53, 0x83, 0x6b, 0x6b, 0x59, 0x9f, 0x9d, 0x56, 0x77, 0x6c, 0xc3, 0x7c, 0xec, 0x25, 0x38, 0x64,
0xdb, 0xb9, 0x5e, 0x2f, 0xaf, 0xa4, 0xc9, 0x6b, 0xfa, 0x1f, 0x47, 0xf5, 0x95, 0x9c, 0x82, 0x8a,
0x62, 0x1c, 0x66, 0xe6, 0xd4, 0x69, 0x47, 0x37, 0x02, 0xd2, 0xc6, 0x94, 0xd9, 0xeb, 0xe2, 0x3f,
0x77, 0x4e, 0x3a, 0x5b, 0x3b, 0x55, 0x07, 0x14, 0x26, 0xd1, 0x01, 0xdf, 0xc1, 0xe2, 0xe0, 0xe9,
0x14, 0x19, 0x5f, 0x40, 0xed, 0x58, 0xdd, 0x9d, 0x5a, 0xf5, 0x86, 0x04, 0x49, 0xde, 0xc0, 0xfa,
0x11, 0xe6, 0xbf, 0x89, 0x83, 0x37, 0xa0, 0xd5, 0x9a, 0x50, 0x4d, 0x30, 0x8d, 0x7a, 0x89, 0x8f,
0xa9, 0xe0, 0x6a, 0xd4, 0xa1, 0x8e, 0x61, 0xd6, 0x0a, 0x5c, 0xb9, 0x2f, 0x45, 0x6d, 0xba, 0xb3,
0x01, 0x65, 0x59, 0xdd, 0xe5, 0x51, 0xaa, 0x6e, 0x3a, 0xe5, 0x09, 0x95, 0x61, 0xb3, 0x5a, 0x5f,
0x56, 0x9a, 0x58, 0x9d, 0xdb, 0x38, 0x45, 0x1f, 0x0a, 0x80, 0x9b, 0x02, 0x9b, 0xff, 0xd6, 0xa0,
0x24, 0x3a, 0x06, 0xda, 0x03, 0x5d, 0x6a, 0x2b, 0xe4, 0xd8, 0x67, 0xfd, 0x52, 0xb0, 0x87, 0xb4,
0xac, 0xf9, 0xc9, 0xe4, 0x06, 0x2a, 0xd4, 0xef, 0xa1, 0x24, 0x34, 0x10, 0x5a, 0x39, 0xdb, 0x34,
0xaf, 0xc8, 0xcc, 0x8f, 0x26, 0xc2, 0xaa, 0x1d, 0xda, 0xa0, 0x4b, 0x61, 0x31, 0xee, 0x38, 0x43,
0x42, 0xcb, 0xfc, 0x78, 0x12, 0x83, 0x6c, 0xa3, 0x67, 0x30, 0x7b, 0x42, 0xc1, 0xa0, 0xe6, 0x24,
0xe6, 0x27, 0x1b, 0xd9, 0x39, 0xb7, 0x7c, 0x02, 0x85, 0x4d, 0xcc, 0x50, 0xe3, 0x6c, 0xa3, 0x63,
0x99, 0x63, 0x7e, 0x38, 0x01, 0x32, 0xe3, 0xad, 0xc8, 0x2b, 0x0c, 0xb2, 0xcf, 0x36, 0x19, 0x54,
0x25, 0xa6, 0x33, 0x31, 0x5e, 0x6d, 0xd4, 0x82, 0x22, 0x17, 0x19, 0x68, 0x4c, 0x6c, 0x39, 0x21,
0x62, 0x2e, 0x0e, 0x3d, 0xa0, 0x0d, 0xfe, 0x23, 0x15, 0x6d, 0x41, 0x91, 0x77, 0x05, 0x34, 0x26,
0x0f, 0x87, 0x05, 0xc4, 0x48, 0x8f, 0x8f, 0xa0, 0x9a, 0xf5, 0xd6, 0x71, 0x54, 0x0c, 0x36, 0xe1,
0x91, 0x4e, 0x1f, 0x40, 0x59, 0x75, 0x45, 0x34, 0xe6, 0xbe, 0x4f, 0x36, 0xcf, 0x33, 0x1c, 0x96,
0x44, 0x97, 0x1b, 0x17, 0xe1, 0x60, 0x2b, 0x1c, 0xe9, 0xf0, 0x21, 0xe8, 0xb2, 0xdd, 0x8d, 0x7b,
0x34, 0x43, 0x4d, 0x71, 0xa4, 0x4b, 0x02, 0x95, 0xb4, 0x63, 0xa1, 0x1b, 0xe3, 0x73, 0x24, 0xd7,
0x20, 0x4d, 0x7b, 0x52, 0xb8, 0xca, 0xa8, 0xe7, 0x00, 0xb9, 0x9e, 0x72, 0x6b, 0x0c, 0xc5, 0xa7,
0x75, 0x47, 0xf3, 0xd3, 0xf3, 0x19, 0xa9, 0x8d, 0x1f, 0x82, 0x2e, 0x9b, 0xc6, 0x38, 0xda, 0x86,
0x5a, 0xcb, 0x48, 0xda, 0x76, 0xa0, 0xac, 0xca, 0xfb, 0xb8, 0x5c, 0x39, 0xd9, 0x31, 0xcc, 0x1b,
0x13, 0xa2, 0x65, 0xe8, 0xab, 0xdf, 0x1e, 0xbe, 0x5a, 0xba, 0xf4, 0xfb, 0xab, 0xa5, 0x4b, 0x3f,
0xf7, 0x97, 0xb4, 0xc3, 0xfe, 0x92, 0xf6, 0x5b, 0x7f, 0x49, 0xfb, 0xbb, 0xbf, 0xa4, 0x3d, 0xb9,
0xfb, 0x7a, 0x7f, 0x72, 0xba, 0x23, 0x06, 0x4f, 0x75, 0x71, 0x9e, 0x5b, 0xff, 0x05, 0x00, 0x00,
0xff, 0xff, 0x5e, 0xf6, 0xae, 0x85, 0xb9, 0x12, 0x00, 0x00,
// 1313 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x5b, 0x6f, 0x1b, 0x45,
0x14, 0xee, 0xfa, 0xee, 0xe3, 0xa4, 0x4d, 0x86, 0x34, 0x98, 0xa5, 0x8a, 0xc3, 0x22, 0x21, 0x13,
0xe8, 0x2e, 0x75, 0x51, 0x85, 0x68, 0x85, 0xd4, 0x5c, 0x88, 0x2c, 0xa8, 0x9a, 0x6e, 0xcb, 0x45,
0x95, 0x50, 0xd8, 0xee, 0x4e, 0x9c, 0x51, 0xec, 0xdd, 0xed, 0xce, 0x38, 0x6d, 0xe0, 0x01, 0x7e,
0x42, 0x5f, 0x79, 0xe1, 0xf7, 0xe4, 0x91, 0x47, 0x84, 0xaa, 0x40, 0xfd, 0x2f, 0x78, 0x43, 0x73,
0xd9, 0xcd, 0xc6, 0x8e, 0xbd, 0x4e, 0xd3, 0xf0, 0xd2, 0xce, 0xcc, 0x7e, 0xe7, 0xcc, 0x99, 0x6f,
0xce, 0x9c, 0xf3, 0x39, 0xb0, 0xda, 0x21, 0x6c, 0xb7, 0xff, 0xc4, 0x74, 0x83, 0x9e, 0xe5, 0x06,
0x3e, 0x73, 0x88, 0x8f, 0x23, 0x2f, 0x3d, 0x74, 0x42, 0x62, 0x51, 0x1c, 0xed, 0x13, 0x17, 0x53,
0x8b, 0x39, 0x74, 0x8f, 0x5a, 0xfb, 0x37, 0xe4, 0xc0, 0x0c, 0xa3, 0x80, 0x05, 0xe8, 0xda, 0x31,
0xda, 0x8c, 0x91, 0xa6, 0x04, 0xec, 0xdf, 0xd0, 0xdf, 0xed, 0x04, 0x41, 0xa7, 0x8b, 0x2d, 0x81,
0x7d, 0xd2, 0xdf, 0xb1, 0x70, 0x2f, 0x64, 0x07, 0xd2, 0x54, 0x7f, 0x67, 0xf8, 0xa3, 0xe3, 0xc7,
0x9f, 0x16, 0x3a, 0x41, 0x27, 0x10, 0x43, 0x8b, 0x8f, 0xd4, 0xea, 0xad, 0xa9, 0xe2, 0x65, 0x07,
0x21, 0xa6, 0x56, 0x2f, 0xe8, 0xfb, 0x4c, 0xd9, 0x7d, 0x76, 0x16, 0x3b, 0xcc, 0x22, 0xe2, 0xaa,
0xd3, 0xe9, 0xb7, 0xcf, 0x60, 0xe9, 0x61, 0xea, 0x46, 0x24, 0x64, 0x41, 0xa4, 0x8c, 0x3f, 0x3f,
0x83, 0x31, 0x67, 0x4c, 0xfc, 0xa3, 0x6c, 0x1b, 0xc3, 0xdc, 0x30, 0xd2, 0xc3, 0x94, 0x39, 0xbd,
0x50, 0x02, 0x8c, 0xc3, 0x1c, 0xcc, 0xaf, 0x45, 0xd8, 0x61, 0xf8, 0x91, 0x43, 0xf7, 0x6c, 0xfc,
0xb4, 0x8f, 0x29, 0x43, 0x2d, 0x98, 0x49, 0xdc, 0x6f, 0x13, 0xaf, 0xae, 0x2d, 0x6b, 0xcd, 0xea,
0xea, 0x95, 0xc1, 0x51, 0xa3, 0xb6, 0x16, 0xaf, 0xb7, 0xd7, 0xed, 0x5a, 0x02, 0x6a, 0x7b, 0xc8,
0x82, 0x52, 0x14, 0x04, 0x6c, 0x87, 0xd6, 0xf3, 0xcb, 0xf9, 0x66, 0xad, 0xf5, 0xb6, 0x99, 0xba,
0x52, 0x11, 0x9d, 0x79, 0x8f, 0x93, 0x69, 0x2b, 0x18, 0x5a, 0x80, 0x22, 0x65, 0x1e, 0xf1, 0xeb,
0x05, 0xee, 0xdd, 0x96, 0x13, 0xb4, 0x08, 0x25, 0xca, 0xbc, 0xa0, 0xcf, 0xea, 0x45, 0xb1, 0xac,
0x66, 0x6a, 0x1d, 0x47, 0x51, 0xbd, 0x94, 0xac, 0xe3, 0x28, 0x42, 0x3a, 0x54, 0x18, 0x8e, 0x7a,
0xc4, 0x77, 0xba, 0xf5, 0xf2, 0xb2, 0xd6, 0xac, 0xd8, 0xc9, 0x1c, 0xdd, 0x01, 0x70, 0x77, 0xb1,
0xbb, 0x17, 0x06, 0xc4, 0x67, 0xf5, 0xca, 0xb2, 0xd6, 0xac, 0xb5, 0xae, 0x8d, 0x86, 0xb5, 0x9e,
0x30, 0x6e, 0xa7, 0xf0, 0xc8, 0x84, 0x72, 0x10, 0x32, 0x12, 0xf8, 0xb4, 0x5e, 0x15, 0xa6, 0x0b,
0xa6, 0x64, 0xd3, 0x8c, 0xd9, 0x34, 0xef, 0xfa, 0x07, 0x76, 0x0c, 0x32, 0x1e, 0x03, 0x4a, 0x33,
0x49, 0xc3, 0xc0, 0xa7, 0xf8, 0xb5, 0xa8, 0x9c, 0x83, 0x7c, 0x48, 0xbc, 0x7a, 0x6e, 0x59, 0x6b,
0xce, 0xda, 0x7c, 0x68, 0x74, 0x60, 0xe6, 0x21, 0x73, 0x22, 0x76, 0x9e, 0x0b, 0x7a, 0x1f, 0xca,
0xf8, 0x39, 0x76, 0xb7, 0x95, 0xe7, 0xea, 0x2a, 0x0c, 0x8e, 0x1a, 0xa5, 0x8d, 0xe7, 0xd8, 0x6d,
0xaf, 0xdb, 0x25, 0xfe, 0xa9, 0xed, 0x19, 0xef, 0xc1, 0xac, 0xda, 0x48, 0xc5, 0xaf, 0x62, 0xd1,
0x8e, 0x63, 0xd9, 0x84, 0xf9, 0x75, 0xdc, 0xc5, 0xe7, 0xce, 0x18, 0xe3, 0x77, 0x0d, 0x2e, 0x4b,
0x4f, 0xc9, 0x6e, 0x8b, 0x90, 0x4b, 0x8c, 0x4b, 0x83, 0xa3, 0x46, 0xae, 0xbd, 0x6e, 0xe7, 0xc8,
0x29, 0x8c, 0xa0, 0x06, 0xd4, 0xf0, 0x73, 0xc2, 0xb6, 0x29, 0x73, 0x58, 0x9f, 0xe7, 0x1c, 0xff,
0x02, 0x7c, 0xe9, 0xa1, 0x58, 0x41, 0x77, 0xa1, 0xca, 0x67, 0xd8, 0xdb, 0x76, 0x98, 0x48, 0xb1,
0x5a, 0x4b, 0x1f, 0xb9, 0xc0, 0x47, 0xf1, 0x73, 0x58, 0xad, 0x1c, 0x1e, 0x35, 0x2e, 0xbd, 0xf8,
0xbb, 0xa1, 0xd9, 0x15, 0x69, 0x76, 0x97, 0x19, 0x01, 0x2c, 0xc8, 0xf8, 0xb6, 0xa2, 0xc0, 0xc5,
0x94, 0x5e, 0x38, 0xfb, 0x18, 0x60, 0x13, 0x5f, 0xfc, 0x25, 0x6f, 0x40, 0x4d, 0x6c, 0xa3, 0x48,
0xbf, 0x05, 0xe5, 0x50, 0x1e, 0x50, 0x6c, 0x31, 0xf4, 0x46, 0xf6, 0x6f, 0xa8, 0x67, 0x12, 0x93,
0x10, 0x83, 0x8d, 0x15, 0x98, 0xfb, 0x9a, 0x50, 0xc6, 0xd3, 0x20, 0xa1, 0x66, 0x11, 0x4a, 0x3b,
0xa4, 0xcb, 0x70, 0x24, 0xa3, 0xb5, 0xd5, 0x8c, 0x27, 0x4d, 0x0a, 0x9b, 0xbc, 0x8d, 0xa2, 0x28,
0xf1, 0x75, 0x4d, 0x54, 0x8c, 0xc9, 0xdb, 0x4a, 0xa8, 0xf1, 0x42, 0x83, 0xda, 0x57, 0xa4, 0xdb,
0xbd, 0x68, 0x92, 0x44, 0xc1, 0x21, 0x1d, 0x5e, 0x56, 0x64, 0x6e, 0xa9, 0x19, 0x4f, 0x45, 0xa7,
0xdb, 0x15, 0x19, 0x55, 0xb1, 0xf9, 0xd0, 0xf8, 0x57, 0x03, 0xc4, 0x8d, 0xdf, 0x40, 0x96, 0x24,
0x35, 0x31, 0x77, 0x7a, 0x4d, 0xcc, 0x8f, 0xa9, 0x89, 0x85, 0xb1, 0x35, 0xb1, 0x38, 0x54, 0x13,
0x9b, 0x50, 0xa0, 0x21, 0x76, 0x45, 0x15, 0x1d, 0x57, 0xd2, 0x04, 0x22, 0xcd, 0x52, 0x79, 0x6c,
0x2a, 0x5d, 0x85, 0xb7, 0x4e, 0x1c, 0x5d, 0xde, 0xac, 0xf1, 0x9b, 0x06, 0x73, 0x36, 0xa6, 0xe4,
0x27, 0xbc, 0xc5, 0x0e, 0x2e, 0xfc, 0xaa, 0x16, 0xa0, 0xf8, 0x8c, 0x78, 0x6c, 0x57, 0xdd, 0x94,
0x9c, 0x70, 0x76, 0x76, 0x31, 0xe9, 0xec, 0xca, 0xd7, 0x3f, 0x6b, 0xab, 0x99, 0xf1, 0x0b, 0x5c,
0x5e, 0xeb, 0x06, 0x14, 0xb7, 0xef, 0xff, 0x1f, 0x81, 0xc9, 0xeb, 0xcc, 0x8b, 0x5b, 0x90, 0x13,
0xe3, 0x4b, 0x98, 0xdb, 0x72, 0xfa, 0xf4, 0xdc, 0xf5, 0x73, 0x13, 0xe6, 0x6d, 0x4c, 0xfb, 0xbd,
0x73, 0x3b, 0xda, 0x80, 0x2b, 0xfc, 0x71, 0x6e, 0x11, 0xef, 0x3c, 0xc9, 0x6b, 0x7c, 0x20, 0xeb,
0x81, 0x74, 0xa3, 0x9e, 0x38, 0x82, 0x42, 0x48, 0x3c, 0xf9, 0xc2, 0x67, 0x6d, 0x31, 0x36, 0x5e,
0x6a, 0x70, 0x75, 0x2d, 0xe9, 0xb3, 0xe7, 0xd5, 0x1d, 0xdb, 0x30, 0x1f, 0x3a, 0x11, 0xf6, 0xd9,
0x76, 0xaa, 0xd7, 0xcb, 0x2b, 0x69, 0xf1, 0x9a, 0xfe, 0xd7, 0x51, 0x63, 0x25, 0xa5, 0xa0, 0x82,
0x10, 0xfb, 0x89, 0x39, 0xb5, 0x3a, 0xc1, 0x75, 0x8f, 0x74, 0x30, 0x65, 0xe6, 0xba, 0xf8, 0xcf,
0x9e, 0x93, 0xce, 0xd6, 0x4e, 0xd5, 0x01, 0xf9, 0x69, 0x74, 0xc0, 0xf7, 0xb0, 0x38, 0x7c, 0x3a,
0x45, 0xc6, 0x17, 0x50, 0x3b, 0x56, 0x77, 0xa7, 0x56, 0xbd, 0x11, 0x41, 0x92, 0x36, 0x30, 0x7e,
0x86, 0xf9, 0x6f, 0x42, 0xef, 0x0d, 0x68, 0xb5, 0x16, 0x54, 0x23, 0x4c, 0x83, 0x7e, 0xe4, 0x62,
0x2a, 0xb8, 0x1a, 0x77, 0xa8, 0x63, 0x98, 0xb1, 0x02, 0x97, 0xef, 0x49, 0x51, 0x1b, 0xef, 0x5c,
0x87, 0xb2, 0xac, 0xee, 0xf2, 0x28, 0x55, 0x3b, 0x9e, 0xf2, 0x84, 0x4a, 0xb0, 0x49, 0xad, 0x2f,
0x2b, 0x4d, 0xac, 0xce, 0x5d, 0x3f, 0x45, 0x1f, 0x0a, 0x80, 0x1d, 0x03, 0x8d, 0x1d, 0xa8, 0x7d,
0xe7, 0x90, 0x8b, 0xef, 0x87, 0x11, 0xcc, 0xc8, 0x7d, 0x54, 0xac, 0x43, 0xda, 0x42, 0x9b, 0xac,
0x2d, 0x72, 0xaf, 0xa3, 0x2d, 0x5a, 0x2f, 0x67, 0xa0, 0x28, 0xba, 0x21, 0xda, 0x83, 0x92, 0xd4,
0x8d, 0xc8, 0x32, 0x27, 0xfd, 0x0a, 0x32, 0x47, 0x74, 0xba, 0xfe, 0xc9, 0xf4, 0x06, 0xea, 0x68,
0x3f, 0x42, 0x51, 0xe8, 0x3b, 0xb4, 0x32, 0xd9, 0x34, 0xad, 0x36, 0xf5, 0x8f, 0xa6, 0xc2, 0xaa,
0x1d, 0x3a, 0x50, 0x92, 0xa2, 0x29, 0xeb, 0x38, 0x23, 0x22, 0x52, 0xff, 0x78, 0x1a, 0x83, 0x64,
0xa3, 0xa7, 0x30, 0x7b, 0x42, 0x9d, 0xa1, 0xd6, 0x34, 0xe6, 0x27, 0x9b, 0xf4, 0x19, 0xb7, 0x7c,
0x0c, 0xf9, 0x4d, 0xcc, 0x50, 0x73, 0xb2, 0xd1, 0xb1, 0x84, 0xd3, 0x3f, 0x9c, 0x02, 0x99, 0xf0,
0x56, 0xe0, 0xd5, 0x13, 0x99, 0x93, 0x4d, 0x86, 0x15, 0x97, 0x6e, 0x4d, 0x8d, 0x57, 0x1b, 0xb5,
0xa1, 0xc0, 0x05, 0x14, 0xca, 0x88, 0x2d, 0x25, 0xb2, 0xf4, 0xc5, 0x91, 0xe4, 0xde, 0xe0, 0x3f,
0xc0, 0xd1, 0x16, 0x14, 0xf8, 0x53, 0x42, 0x19, 0x79, 0x38, 0x2a, 0x8e, 0xc6, 0x7a, 0x7c, 0x08,
0xd5, 0x44, 0x37, 0x64, 0x51, 0x31, 0x2c, 0x30, 0xc6, 0x3a, 0xbd, 0x0f, 0x65, 0xd5, 0xf1, 0x51,
0xc6, 0x7d, 0x9f, 0x14, 0x06, 0x13, 0x1c, 0x16, 0x45, 0x07, 0xcf, 0x8a, 0x70, 0xb8, 0xcd, 0x8f,
0x75, 0xf8, 0x00, 0x4a, 0xb2, 0x95, 0x67, 0x3d, 0x9a, 0x91, 0x86, 0x3f, 0xd6, 0x25, 0x81, 0x4a,
0xdc, 0x8d, 0xd1, 0xf5, 0xec, 0x1c, 0x49, 0x35, 0x7f, 0xdd, 0x9c, 0x16, 0xae, 0x32, 0xea, 0x19,
0x40, 0xaa, 0x5f, 0xde, 0xcc, 0xa0, 0xf8, 0xb4, 0xce, 0xaf, 0x7f, 0x7a, 0x36, 0x23, 0xb5, 0xf1,
0x03, 0x28, 0xc9, 0x86, 0x98, 0x45, 0xdb, 0x48, 0xdb, 0x1c, 0x4b, 0xdb, 0x0e, 0x94, 0x55, 0xeb,
0xca, 0xca, 0x95, 0x93, 0xdd, 0x50, 0xbf, 0x3e, 0x25, 0x5a, 0x85, 0xfe, 0x03, 0x14, 0x78, 0xcf,
0xc9, 0x7a, 0x85, 0xa9, 0xfe, 0xa7, 0xaf, 0x4c, 0x03, 0x95, 0xee, 0x57, 0xbf, 0x3d, 0x7c, 0xb5,
0x74, 0xe9, 0xcf, 0x57, 0x4b, 0x97, 0x7e, 0x1d, 0x2c, 0x69, 0x87, 0x83, 0x25, 0xed, 0x8f, 0xc1,
0x92, 0xf6, 0xcf, 0x60, 0x49, 0x7b, 0x7c, 0xe7, 0xf5, 0xfe, 0x5a, 0x77, 0x5b, 0x0c, 0x9e, 0x94,
0x04, 0x5d, 0x37, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xe9, 0xe2, 0x8e, 0x41, 0xf4, 0x13, 0x00,
0x00,
}

View File

@ -49,6 +49,8 @@ service Tasks {
rpc Update(UpdateTaskRequest) returns (google.protobuf.Empty);
rpc Metrics(MetricsRequest) returns (MetricsResponse);
rpc Wait(WaitRequest) returns (WaitResponse);
}
message CreateTaskRequest {
@ -194,3 +196,13 @@ message MetricsRequest {
message MetricsResponse {
repeated types.Metric metrics = 1;
}
message WaitRequest {
string container_id = 1;
string exec_id = 2;
}
message WaitResponse {
uint32 exit_status = 1;
google.protobuf.Timestamp exited_at = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
}

View File

@ -23,6 +23,7 @@ import (
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/reference"
"github.com/containerd/containerd/remotes"
@ -226,7 +227,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpts) (Imag
} else {
handler = images.Handlers(append(pullCtx.BaseHandlers,
remotes.FetchHandler(store, fetcher),
images.ChildrenHandler(store))...,
images.ChildrenHandler(store, platforms.Default()))...,
)
}
@ -307,7 +308,7 @@ func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor,
pushHandler := remotes.PushHandler(cs, pusher)
handlers := append(pushCtx.BaseHandlers,
images.ChildrenHandler(cs),
images.ChildrenHandler(cs, platforms.Default()),
filterHandler,
pushHandler,
)

View File

@ -229,15 +229,12 @@ func (c *container) NewTask(ctx context.Context, ioCreate IOCreation, opts ...Ne
}
if info.Checkpoint != nil {
request.Checkpoint = info.Checkpoint
// we need to defer the create call to start
t.deferred = request
} else {
}
response, err := c.client.TaskService().Create(ctx, request)
if err != nil {
return nil, errdefs.FromGRPC(err)
}
t.pid = response.Pid
}
return t, nil
}

View File

@ -38,7 +38,7 @@ func WithCheckpoint(desc v1.Descriptor, snapshotKey string) NewContainerOpts {
case v1.MediaTypeImageLayer:
fk := m
rw = &fk
case images.MediaTypeDockerSchema2Manifest:
case images.MediaTypeDockerSchema2Manifest, images.MediaTypeDockerSchema2ManifestList:
config, err := images.Config(ctx, store, m, platforms.Default())
if err != nil {
return err

View File

@ -117,6 +117,8 @@ func containerFromProto(containerpb *containersapi.Container) containers.Contain
Spec: containerpb.Spec,
Snapshotter: containerpb.Snapshotter,
SnapshotKey: containerpb.SnapshotKey,
CreatedAt: containerpb.CreatedAt,
UpdatedAt: containerpb.UpdatedAt,
Extensions: containerpb.Extensions,
}
}

View File

@ -9,6 +9,7 @@ import (
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/platforms"
ocispecs "github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
@ -32,7 +33,7 @@ func (c *Client) exportToOCITar(ctx context.Context, desc ocispec.Descriptor, wr
}
handlers := images.Handlers(
images.ChildrenHandler(cs),
images.ChildrenHandler(cs, platforms.Default()),
images.HandlerFunc(exportHandler),
)

View File

@ -50,7 +50,7 @@ func (i *image) RootFS(ctx context.Context) ([]digest.Digest, error) {
func (i *image) Size(ctx context.Context) (int64, error) {
provider := i.client.ContentStore()
return i.i.Size(ctx, provider)
return i.i.Size(ctx, provider, platforms.Default())
}
func (i *image) Config(ctx context.Context) (ocispec.Descriptor, error) {

View File

@ -7,6 +7,7 @@ import (
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/platforms"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
@ -127,7 +128,7 @@ func Dispatch(ctx context.Context, handler Handler, descs ...ocispec.Descriptor)
//
// One can also replace this with another implementation to allow descending of
// arbitrary types.
func ChildrenHandler(provider content.Provider) HandlerFunc {
func ChildrenHandler(provider content.Provider, platform string) HandlerFunc {
return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
var descs []ocispec.Descriptor
switch desc.MediaType {
@ -157,10 +158,26 @@ func ChildrenHandler(provider content.Provider) HandlerFunc {
return nil, err
}
if platform != "" {
matcher, err := platforms.Parse(platform)
if err != nil {
return nil, err
}
for _, d := range index.Manifests {
if d.Platform == nil || matcher.Match(*d.Platform) {
descs = append(descs, d)
}
}
} else {
descs = append(descs, index.Manifests...)
}
case MediaTypeDockerSchema2Layer, MediaTypeDockerSchema2LayerGzip,
MediaTypeDockerSchema2LayerForeign, MediaTypeDockerSchema2LayerForeignGzip,
MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig,
ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerGzip:
ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerGzip,
ocispec.MediaTypeImageLayerNonDistributable, ocispec.MediaTypeImageLayerNonDistributableGzip:
// childless data types.
return nil, nil
default:

View File

@ -58,7 +58,7 @@ func (image *Image) RootFS(ctx context.Context, provider content.Provider, platf
}
// Size returns the total size of an image's packed resources.
func (image *Image) Size(ctx context.Context, provider content.Provider) (int64, error) {
func (image *Image) Size(ctx context.Context, provider content.Provider, platform string) (int64, error) {
var size int64
return size, Walk(ctx, Handlers(HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
if desc.Size < 0 {
@ -66,7 +66,7 @@ func (image *Image) Size(ctx context.Context, provider content.Provider) (int64,
}
size += desc.Size
return nil, nil
}), ChildrenHandler(provider)), image.Target)
}), ChildrenHandler(provider, platform)), image.Target)
}
func Manifest(ctx context.Context, provider content.Provider, image ocispec.Descriptor, platform string) (ocispec.Manifest, error) {
@ -196,7 +196,7 @@ func Platforms(ctx context.Context, provider content.Provider, image ocispec.Des
platforms.Normalize(ocispec.Platform{OS: image.OS, Architecture: image.Architecture}))
}
return nil, nil
}), ChildrenHandler(provider)), image)
}), ChildrenHandler(provider, "")), image)
}
// RootFS returns the unpacked diffids that make up and images rootfs.

View File

@ -6,7 +6,9 @@ package images
// here for clarity.
const (
MediaTypeDockerSchema2Layer = "application/vnd.docker.image.rootfs.diff.tar"
MediaTypeDockerSchema2LayerForeign = "application/vnd.docker.image.rootfs.foreign.diff.tar"
MediaTypeDockerSchema2LayerGzip = "application/vnd.docker.image.rootfs.diff.tar.gzip"
MediaTypeDockerSchema2LayerForeignGzip = "application/vnd.docker.image.rootfs.foreign.diff.tar.gzip"
MediaTypeDockerSchema2Config = "application/vnd.docker.container.image.v1+json"
MediaTypeDockerSchema2Manifest = "application/vnd.docker.distribution.manifest.v2+json"
MediaTypeDockerSchema2ManifestList = "application/vnd.docker.distribution.manifest.list.v2+json"

View File

@ -0,0 +1,23 @@
package labels
import (
"github.com/containerd/containerd/errdefs"
"github.com/pkg/errors"
)
const (
maxSize = 4096
)
func Validate(k, v string) error {
// A label key and value should be under 4096 bytes
if (len(k) + len(v)) > maxSize {
if len(k) > 10 {
k = k[:10]
}
return errors.Wrapf(errdefs.ErrInvalidArgument, "label key and value greater than maximum size (%d bytes), key: %s", maxSize, k)
}
return nil
}

View File

@ -10,6 +10,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/filters"
"github.com/containerd/containerd/identifiers"
"github.com/containerd/containerd/labels"
"github.com/containerd/containerd/metadata/boltutil"
"github.com/containerd/containerd/namespaces"
"github.com/gogo/protobuf/proto"
@ -243,7 +244,13 @@ func validateContainer(container *containers.Container) error {
}
}
// labels and image have no validation
// image has no validation
for k, v := range container.Labels {
if err := labels.Validate(k, v); err == nil {
return errors.Wrapf(err, "containers.Labels")
}
}
if container.Runtime.Name == "" {
return errors.Wrapf(errdefs.ErrInvalidArgument, "container.Runtime.Name must be set")
}

View File

@ -10,6 +10,7 @@ import (
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/filters"
"github.com/containerd/containerd/labels"
"github.com/containerd/containerd/metadata/boltutil"
"github.com/containerd/containerd/namespaces"
digest "github.com/opencontainers/go-digest"
@ -94,6 +95,9 @@ func (cs *contentStore) Update(ctx context.Context, info content.Info, fieldpath
// Set mutable fields
updated.Labels = info.Labels
}
if err := validateInfo(&updated); err != nil {
return err
}
updated.UpdatedAt = time.Now().UTC()
return writeInfo(&updated, bkt)
@ -371,6 +375,10 @@ func (nw *namespacedWriter) commit(ctx context.Context, tx *bolt.Tx, size int64,
return err
}
}
if err := validateInfo(&base); err != nil {
return err
}
status, err := nw.Writer.Status()
if err != nil {
return err
@ -446,6 +454,16 @@ func (cs *contentStore) checkAccess(ctx context.Context, dgst digest.Digest) err
})
}
func validateInfo(info *content.Info) error {
for k, v := range info.Labels {
if err := labels.Validate(k, v); err == nil {
return errors.Wrapf(err, "info.Labels")
}
}
return nil
}
func readInfo(info *content.Info, bkt *bolt.Bucket) error {
if err := boltutil.ReadTimestamps(bkt, &info.CreatedAt, &info.UpdatedAt); err != nil {
return err

View File

@ -11,6 +11,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/filters"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/labels"
"github.com/containerd/containerd/metadata/boltutil"
"github.com/containerd/containerd/namespaces"
digest "github.com/opencontainers/go-digest"
@ -101,6 +102,10 @@ func (s *imageStore) Create(ctx context.Context, image images.Image) (images.Ima
return images.Image{}, errors.Wrapf(errdefs.ErrInvalidArgument, "image name is required for create")
}
if err := validateImage(&image); err != nil {
return images.Image{}, err
}
return image, withImagesBucket(s.tx, namespace, func(bkt *bolt.Bucket) error {
ibkt, err := bkt.CreateBucket([]byte(image.Name))
if err != nil {
@ -170,6 +175,10 @@ func (s *imageStore) Update(ctx context.Context, image images.Image, fieldpaths
updated = image
}
if err := validateImage(&image); err != nil {
return err
}
updated.CreatedAt = createdat
updated.UpdatedAt = time.Now().UTC()
return writeImage(ibkt, &updated)
@ -191,6 +200,16 @@ func (s *imageStore) Delete(ctx context.Context, name string) error {
})
}
func validateImage(image *images.Image) error {
for k, v := range image.Labels {
if err := labels.Validate(k, v); err != nil {
return errors.Wrapf(err, "image.Labels")
}
}
return nil
}
func readImage(image *images.Image, bkt *bolt.Bucket) error {
if err := boltutil.ReadTimestamps(bkt, &image.CreatedAt, &image.UpdatedAt); err != nil {
return err

View File

@ -5,6 +5,7 @@ import (
"github.com/boltdb/bolt"
"github.com/containerd/containerd/errdefs"
l "github.com/containerd/containerd/labels"
"github.com/containerd/containerd/namespaces"
"github.com/pkg/errors"
)
@ -27,6 +28,12 @@ func (s *namespaceStore) Create(ctx context.Context, namespace string, labels ma
return err
}
for k, v := range labels {
if err := l.Validate(k, v); err != nil {
return errors.Wrapf(err, "namespace.Labels")
}
}
// provides the already exists error.
bkt, err := topbkt.CreateBucket([]byte(namespace))
if err != nil {
@ -70,6 +77,10 @@ func (s *namespaceStore) Labels(ctx context.Context, namespace string) (map[stri
}
func (s *namespaceStore) SetLabel(ctx context.Context, namespace, key, value string) error {
if err := l.Validate(key, value); err != nil {
return errors.Wrapf(err, "namespace.Labels")
}
return withNamespacesLabelsBucket(s.tx, namespace, func(bkt *bolt.Bucket) error {
if value == "" {
return bkt.Delete([]byte(key))

View File

@ -8,6 +8,7 @@ import (
"github.com/boltdb/bolt"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/labels"
"github.com/containerd/containerd/metadata/boltutil"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/namespaces"
@ -180,6 +181,9 @@ func (s *snapshotter) Update(ctx context.Context, info snapshot.Info, fieldpaths
} else {
local.Labels = info.Labels
}
if err := validateSnapshot(&local); err != nil {
return err
}
local.Updated = time.Now().UTC()
if err := boltutil.WriteTimestamps(sbkt, local.Created, local.Updated); err != nil {
@ -257,6 +261,10 @@ func (s *snapshotter) createSnapshot(ctx context.Context, key, parent string, re
}
}
if err := validateSnapshot(&base); err != nil {
return nil, err
}
var m []mount.Mount
if err := update(ctx, s.db, func(tx *bolt.Tx) error {
bkt, err := createSnapshotterBucket(tx, ns, s.name)
@ -328,6 +336,10 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
}
}
if err := validateSnapshot(&base); err != nil {
return err
}
return update(ctx, s.db, func(tx *bolt.Tx) error {
bkt := getSnapshotterBucket(tx, ns, s.name)
if bkt == nil {
@ -502,3 +514,13 @@ func (s *snapshotter) Walk(ctx context.Context, fn func(context.Context, snapsho
return nil
}
func validateSnapshot(info *snapshot.Info) error {
for k, v := range info.Labels {
if err := labels.Validate(k, v); err != nil {
return errors.Wrapf(err, "info.Labels")
}
}
return nil
}

View File

@ -6,11 +6,8 @@ import (
"syscall"
"time"
eventsapi "github.com/containerd/containerd/api/services/events/v1"
"github.com/containerd/containerd/api/services/tasks/v1"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/runtime"
"github.com/containerd/typeurl"
"github.com/pkg/errors"
)
@ -121,54 +118,25 @@ func (p *process) Kill(ctx context.Context, s syscall.Signal, opts ...KillOpts)
}
func (p *process) Wait(ctx context.Context) (<-chan ExitStatus, error) {
cancellable, cancel := context.WithCancel(ctx)
eventstream, err := p.task.client.EventService().Subscribe(cancellable, &eventsapi.SubscribeRequest{
Filters: []string{"topic==" + runtime.TaskExitEventTopic},
c := make(chan ExitStatus, 1)
go func() {
r, err := p.task.client.TaskService().Wait(ctx, &tasks.WaitRequest{
ContainerID: p.task.id,
ExecID: p.id,
})
if err != nil {
cancel()
return nil, err
c <- ExitStatus{
code: UnknownExitStatus,
err: err,
}
// first check if the task has exited
status, err := p.Status(ctx)
if err != nil {
cancel()
return nil, errdefs.FromGRPC(err)
}
chStatus := make(chan ExitStatus, 1)
if status.Status == Stopped {
cancel()
chStatus <- ExitStatus{code: status.ExitStatus, exitedAt: status.ExitTime}
return chStatus, nil
}
go func() {
defer cancel()
chStatus <- ExitStatus{} // signal that the goroutine is running
for {
evt, err := eventstream.Recv()
if err != nil {
chStatus <- ExitStatus{code: UnknownExitStatus, err: err}
return
}
if typeurl.Is(evt.Event, &eventsapi.TaskExit{}) {
v, err := typeurl.UnmarshalAny(evt.Event)
if err != nil {
chStatus <- ExitStatus{code: UnknownExitStatus, err: err}
return
}
e := v.(*eventsapi.TaskExit)
if e.ID == p.id && e.ContainerID == p.task.id {
chStatus <- ExitStatus{code: e.ExitStatus, exitedAt: e.ExitedAt}
return
}
}
c <- ExitStatus{
code: r.ExitStatus,
exitedAt: r.ExitedAt,
}
}()
<-chStatus // wait for the goroutine to be running
return chStatus, nil
return c, nil
}
func (p *process) CloseIO(ctx context.Context, opts ...IOCloserOpts) error {

View File

@ -7,6 +7,7 @@ import (
"path"
"strings"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/log"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@ -26,7 +27,7 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
},
))
paths, err := getV2URLPaths(desc)
urls, err := r.getV2URLPaths(ctx, desc)
if err != nil {
return nil, err
}
@ -36,9 +37,7 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
return nil, err
}
for _, path := range paths {
u := r.url(path)
for _, u := range urls {
req, err := http.NewRequest(http.MethodGet, u, nil)
if err != nil {
return nil, err
@ -51,34 +50,44 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
}
if resp.StatusCode > 299 {
resp.Body.Close()
if resp.StatusCode == http.StatusNotFound {
continue // try one of the other urls.
}
resp.Body.Close()
return nil, errors.Errorf("unexpected status code %v: %v", u, resp.Status)
}
return resp.Body, nil
}
return nil, errors.New("not found")
return nil, errors.Wrapf(errdefs.ErrNotFound,
"could not fetch content descriptor %v (%v) from remote",
desc.Digest, desc.MediaType)
}
// getV2URLPaths generates the candidate urls paths for the object based on the
// set of hints and the provided object id. URLs are returned in the order of
// most to least likely succeed.
func getV2URLPaths(desc ocispec.Descriptor) ([]string, error) {
func (r *dockerFetcher) getV2URLPaths(ctx context.Context, desc ocispec.Descriptor) ([]string, error) {
var urls []string
if len(desc.URLs) > 0 {
// handle fetch via external urls.
for _, u := range desc.URLs {
log.G(ctx).WithField("url", u).Debug("adding alternative url")
urls = append(urls, u)
}
}
switch desc.MediaType {
case images.MediaTypeDockerSchema2Manifest, images.MediaTypeDockerSchema2ManifestList,
images.MediaTypeDockerSchema1Manifest,
ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex:
urls = append(urls, path.Join("manifests", desc.Digest.String()))
urls = append(urls, r.url(path.Join("manifests", desc.Digest.String())))
}
// always fallback to attempting to get the object out of the blobs store.
urls = append(urls, path.Join("blobs", desc.Digest.String()))
urls = append(urls, r.url(path.Join("blobs", desc.Digest.String())))
return urls, nil
}

View File

@ -27,6 +27,7 @@ func MakeRefKey(ctx context.Context, desc ocispec.Descriptor) string {
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
return "index-" + desc.Digest.String()
case images.MediaTypeDockerSchema2Layer, images.MediaTypeDockerSchema2LayerGzip,
images.MediaTypeDockerSchema2LayerForeign, images.MediaTypeDockerSchema2LayerForeignGzip,
ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerGzip,
ocispec.MediaTypeImageLayerNonDistributable, ocispec.MediaTypeImageLayerNonDistributableGzip:
return "layer-" + desc.Digest.String()

View File

@ -1,15 +0,0 @@
package runtime
const (
TaskCreateEventTopic = "/tasks/create"
TaskStartEventTopic = "/tasks/start"
TaskOOMEventTopic = "/tasks/oom"
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/?"
)

View File

@ -1,52 +0,0 @@
package runtime
// TaskMonitor provides an interface for monitoring of containers within containerd
type TaskMonitor interface {
// Monitor adds the provided container to the monitor
Monitor(Task) error
// Stop stops and removes the provided container from the monitor
Stop(Task) error
}
func NewMultiTaskMonitor(monitors ...TaskMonitor) TaskMonitor {
return &multiTaskMonitor{
monitors: monitors,
}
}
func NewNoopMonitor() TaskMonitor {
return &noopTaskMonitor{}
}
type noopTaskMonitor struct {
}
func (mm *noopTaskMonitor) Monitor(c Task) error {
return nil
}
func (mm *noopTaskMonitor) Stop(c Task) error {
return nil
}
type multiTaskMonitor struct {
monitors []TaskMonitor
}
func (mm *multiTaskMonitor) Monitor(c Task) error {
for _, m := range mm.monitors {
if err := m.Monitor(c); err != nil {
return err
}
}
return nil
}
func (mm *multiTaskMonitor) Stop(c Task) error {
for _, m := range mm.monitors {
if err := m.Stop(c); err != nil {
return err
}
}
return nil
}

View File

@ -1,51 +0,0 @@
package runtime
import (
"context"
"time"
"github.com/containerd/containerd/mount"
"github.com/gogo/protobuf/types"
)
type IO struct {
Stdin string
Stdout string
Stderr string
Terminal bool
}
type CreateOpts struct {
// Spec is the OCI runtime spec
Spec *types.Any
// Rootfs mounts to perform to gain access to the container's filesystem
Rootfs []mount.Mount
// IO for the container's main process
IO IO
// Checkpoint digest to restore container state
Checkpoint string
// Options for the runtime and container
Options *types.Any
}
type Exit struct {
Pid uint32
Status uint32
Timestamp time.Time
}
// Runtime is responsible for the creation of containers for a certain platform,
// arch, or custom usage.
type Runtime interface {
// ID of the runtime
ID() string
// Create creates a task with the provided id and options.
Create(ctx context.Context, id string, opts CreateOpts) (Task, error)
// Get returns a task.
Get(context.Context, string) (Task, error)
// Tasks returns all the current tasks for the runtime.
// Any container runs at most one task at a time.
Tasks(context.Context) ([]Task, error)
// Delete removes the task in the runtime.
Delete(context.Context, Task) (*Exit, error)
}

View File

@ -1,92 +0,0 @@
package runtime
import (
"context"
"time"
"github.com/gogo/protobuf/types"
)
type TaskInfo struct {
ID string
Runtime string
Spec []byte
Namespace string
}
type Process interface {
ID() string
// State returns the process state
State(context.Context) (State, error)
// Kill signals a container
Kill(context.Context, uint32, bool) error
// Pty resizes the processes pty/console
ResizePty(context.Context, ConsoleSize) error
// CloseStdin closes the processes stdin
CloseIO(context.Context) error
// Start the container's user defined process
Start(context.Context) error
}
type Task interface {
Process
// Information of the container
Info() TaskInfo
// Pause pauses the container process
Pause(context.Context) error
// Resume unpauses the container process
Resume(context.Context) error
// Exec adds a process into the container
Exec(context.Context, string, ExecOpts) (Process, error)
// Pids returns all pids
Pids(context.Context) ([]uint32, error)
// Checkpoint checkpoints a container to an image with live system data
Checkpoint(context.Context, string, *types.Any) error
// DeleteProcess deletes a specific exec process via its id
DeleteProcess(context.Context, string) (*Exit, error)
// Update sets the provided resources to a running task
Update(context.Context, *types.Any) error
// Process returns a process within the task for the provided id
Process(context.Context, string) (Process, error)
// Metrics returns runtime specific metrics for a task
Metrics(context.Context) (interface{}, error)
}
type ExecOpts struct {
Spec *types.Any
IO IO
}
type ConsoleSize struct {
Width uint32
Height uint32
}
type Status int
const (
CreatedStatus Status = iota + 1
RunningStatus
StoppedStatus
DeletedStatus
PausedStatus
PausingStatus
)
type State struct {
// Status is the current status of the container
Status Status
// Pid is the main process id for the container
Pid uint32
// ExitStatus of the process
// Only valid if the Status is Stopped
ExitStatus uint32
// ExitedAt is the time at which the process exited
// Only valid if the Status is Stopped
ExitedAt time.Time
Stdin string
Stdout string
Stderr string
Terminal bool
}

View File

@ -1,95 +0,0 @@
package runtime
import (
"context"
"sync"
"github.com/containerd/containerd/namespaces"
"github.com/pkg/errors"
)
var (
ErrTaskNotExists = errors.New("task does not exist")
ErrTaskAlreadyExists = errors.New("task already exists")
)
func NewTaskList() *TaskList {
return &TaskList{
tasks: make(map[string]map[string]Task),
}
}
type TaskList struct {
mu sync.Mutex
tasks map[string]map[string]Task
}
func (l *TaskList) Get(ctx context.Context, id string) (Task, error) {
l.mu.Lock()
defer l.mu.Unlock()
namespace, err := namespaces.NamespaceRequired(ctx)
if err != nil {
return nil, err
}
tasks, ok := l.tasks[namespace]
if !ok {
return nil, ErrTaskNotExists
}
t, ok := tasks[id]
if !ok {
return nil, ErrTaskNotExists
}
return t, nil
}
func (l *TaskList) GetAll(ctx context.Context) ([]Task, error) {
namespace, err := namespaces.NamespaceRequired(ctx)
if err != nil {
return nil, err
}
var o []Task
tasks, ok := l.tasks[namespace]
if !ok {
return o, nil
}
for _, t := range tasks {
o = append(o, t)
}
return o, nil
}
func (l *TaskList) Add(ctx context.Context, t Task) error {
namespace, err := namespaces.NamespaceRequired(ctx)
if err != nil {
return err
}
return l.AddWithNamespace(namespace, t)
}
func (l *TaskList) AddWithNamespace(namespace string, t Task) error {
l.mu.Lock()
defer l.mu.Unlock()
id := t.ID()
if _, ok := l.tasks[namespace]; !ok {
l.tasks[namespace] = make(map[string]Task)
}
if _, ok := l.tasks[namespace][id]; ok {
return errors.Wrap(ErrTaskAlreadyExists, id)
}
l.tasks[namespace][id] = t
return nil
}
func (l *TaskList) Delete(ctx context.Context, t Task) {
l.mu.Lock()
defer l.mu.Unlock()
namespace, err := namespaces.NamespaceRequired(ctx)
if err != nil {
return
}
tasks, ok := l.tasks[namespace]
if ok {
delete(tasks, t.ID())
}
}

View File

@ -1,18 +0,0 @@
package runtime
import (
"strconv"
"github.com/containerd/typeurl"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
func init() {
const prefix = "types.containerd.io"
// register TypeUrls for commonly marshaled external types
major := strconv.Itoa(specs.VersionMajor)
typeurl.Register(&specs.Spec{}, prefix, "opencontainers/runtime-spec", major, "Spec")
typeurl.Register(&specs.Process{}, prefix, "opencontainers/runtime-spec", major, "Process")
typeurl.Register(&specs.LinuxResources{}, prefix, "opencontainers/runtime-spec", major, "LinuxResources")
typeurl.Register(&specs.WindowsResources{}, prefix, "opencontainers/runtime-spec", major, "WindowsResources")
}

View File

@ -354,7 +354,7 @@ func (s *Service) Write(session api.Content_WriteServer) (err error) {
// 2. Compress inline.
// 3. Validate digest and size (maybe).
//
// Supporting these two paths is quite awkward but it let's both API
// Supporting these two paths is quite awkward but it lets both API
// users use the same writer style for each with a minimum of overhead.
if req.Expected != "" {
if expected != "" && expected != req.Expected {

View File

@ -12,7 +12,6 @@ import (
"syscall"
"time"
eventsapi "github.com/containerd/containerd/api/services/events/v1"
"github.com/containerd/containerd/api/services/tasks/v1"
"github.com/containerd/containerd/api/types"
"github.com/containerd/containerd/content"
@ -20,7 +19,6 @@ import (
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/rootfs"
"github.com/containerd/containerd/runtime"
"github.com/containerd/typeurl"
digest "github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/specs-go/v1"
@ -136,7 +134,6 @@ type task struct {
pid uint32
mu sync.Mutex
deferred *tasks.CreateTaskRequest
}
// Pid returns the pid or process id for the task
@ -145,29 +142,16 @@ func (t *task) Pid() uint32 {
}
func (t *task) Start(ctx context.Context) error {
t.mu.Lock()
deferred := t.deferred
t.mu.Unlock()
if deferred != nil {
response, err := t.client.TaskService().Create(ctx, deferred)
t.mu.Lock()
t.deferred = nil
t.mu.Unlock()
if err != nil {
t.io.Close()
return errdefs.FromGRPC(err)
}
t.pid = response.Pid
return nil
}
_, err := t.client.TaskService().Start(ctx, &tasks.StartRequest{
r, err := t.client.TaskService().Start(ctx, &tasks.StartRequest{
ContainerID: t.id,
})
if err != nil {
t.io.Close()
}
return errdefs.FromGRPC(err)
}
t.pid = r.Pid
return nil
}
func (t *task) Kill(ctx context.Context, s syscall.Signal, opts ...KillOpts) error {
var i KillInfo
@ -216,60 +200,24 @@ func (t *task) Status(ctx context.Context) (Status, error) {
}
func (t *task) Wait(ctx context.Context) (<-chan ExitStatus, error) {
cancellable, cancel := context.WithCancel(ctx)
eventstream, err := t.client.EventService().Subscribe(cancellable, &eventsapi.SubscribeRequest{
Filters: []string{"topic==" + runtime.TaskExitEventTopic},
c := make(chan ExitStatus, 1)
go func() {
r, err := t.client.TaskService().Wait(ctx, &tasks.WaitRequest{
ContainerID: t.id,
})
if err != nil {
cancel()
return nil, errdefs.FromGRPC(err)
c <- ExitStatus{
code: UnknownExitStatus,
err: err,
}
chStatus := make(chan ExitStatus, 1)
t.mu.Lock()
checkpoint := t.deferred != nil
t.mu.Unlock()
if !checkpoint {
// first check if the task has exited
status, err := t.Status(ctx)
if err != nil {
cancel()
return nil, errdefs.FromGRPC(err)
}
if status.Status == Stopped {
cancel()
chStatus <- ExitStatus{code: status.ExitStatus, exitedAt: status.ExitTime}
return chStatus, nil
}
}
go func() {
defer cancel()
chStatus <- ExitStatus{} // signal that goroutine is running
for {
evt, err := eventstream.Recv()
if err != nil {
chStatus <- ExitStatus{code: UnknownExitStatus, err: errdefs.FromGRPC(err)}
return
}
if typeurl.Is(evt.Event, &eventsapi.TaskExit{}) {
v, err := typeurl.UnmarshalAny(evt.Event)
if err != nil {
chStatus <- ExitStatus{code: UnknownExitStatus, err: err}
return
}
e := v.(*eventsapi.TaskExit)
if e.ContainerID == t.id && e.Pid == t.pid {
chStatus <- ExitStatus{code: e.ExitStatus, exitedAt: e.ExitedAt}
return
}
}
c <- ExitStatus{
code: r.ExitStatus,
exitedAt: r.ExitedAt,
}
}()
<-chStatus // wait for the goroutine to be running
return chStatus, nil
return c, nil
}
// Delete deletes the task and its runtime state