Merge pull request #1133 from crosbymichael/register

add typeurl package for TypeUrl handling for external types
This commit is contained in:
Phil Estes 2017-07-06 16:20:57 -04:00 committed by GitHub
commit e283b3802d
30 changed files with 465 additions and 438 deletions

View File

@ -68,15 +68,14 @@ func (x Status) String() string {
func (Status) EnumDescriptor() ([]byte, []int) { return fileDescriptorTask, []int{0} }
type Task struct {
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
ContainerID string `protobuf:"bytes,2,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"`
Pid uint32 `protobuf:"varint,3,opt,name=pid,proto3" json:"pid,omitempty"`
Status Status `protobuf:"varint,4,opt,name=status,proto3,enum=containerd.v1.types.Status" json:"status,omitempty"`
Spec *google_protobuf1.Any `protobuf:"bytes,5,opt,name=spec" json:"spec,omitempty"`
Stdin string `protobuf:"bytes,6,opt,name=stdin,proto3" json:"stdin,omitempty"`
Stdout string `protobuf:"bytes,7,opt,name=stdout,proto3" json:"stdout,omitempty"`
Stderr string `protobuf:"bytes,8,opt,name=stderr,proto3" json:"stderr,omitempty"`
Terminal bool `protobuf:"varint,9,opt,name=terminal,proto3" json:"terminal,omitempty"`
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
ContainerID string `protobuf:"bytes,2,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"`
Pid uint32 `protobuf:"varint,3,opt,name=pid,proto3" json:"pid,omitempty"`
Status Status `protobuf:"varint,4,opt,name=status,proto3,enum=containerd.v1.types.Status" json:"status,omitempty"`
Stdin string `protobuf:"bytes,5,opt,name=stdin,proto3" json:"stdin,omitempty"`
Stdout string `protobuf:"bytes,6,opt,name=stdout,proto3" json:"stdout,omitempty"`
Stderr string `protobuf:"bytes,7,opt,name=stderr,proto3" json:"stderr,omitempty"`
Terminal bool `protobuf:"varint,8,opt,name=terminal,proto3" json:"terminal,omitempty"`
}
func (m *Task) Reset() { *m = Task{} }
@ -155,36 +154,26 @@ func (m *Task) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintTask(dAtA, i, uint64(m.Status))
}
if m.Spec != nil {
dAtA[i] = 0x2a
i++
i = encodeVarintTask(dAtA, i, uint64(m.Spec.Size()))
n1, err := m.Spec.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n1
}
if len(m.Stdin) > 0 {
dAtA[i] = 0x32
dAtA[i] = 0x2a
i++
i = encodeVarintTask(dAtA, i, uint64(len(m.Stdin)))
i += copy(dAtA[i:], m.Stdin)
}
if len(m.Stdout) > 0 {
dAtA[i] = 0x3a
dAtA[i] = 0x32
i++
i = encodeVarintTask(dAtA, i, uint64(len(m.Stdout)))
i += copy(dAtA[i:], m.Stdout)
}
if len(m.Stderr) > 0 {
dAtA[i] = 0x42
dAtA[i] = 0x3a
i++
i = encodeVarintTask(dAtA, i, uint64(len(m.Stderr)))
i += copy(dAtA[i:], m.Stderr)
}
if m.Terminal {
dAtA[i] = 0x48
dAtA[i] = 0x40
i++
if m.Terminal {
dAtA[i] = 1
@ -250,11 +239,11 @@ func (m *Process) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x22
i++
i = encodeVarintTask(dAtA, i, uint64(m.User.Size()))
n2, err := m.User.MarshalTo(dAtA[i:])
n1, err := m.User.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n2
i += n1
}
if len(m.Cwd) > 0 {
dAtA[i] = 0x2a
@ -286,11 +275,11 @@ func (m *Process) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x4a
i++
i = encodeVarintTask(dAtA, i, uint64(m.RuntimeData.Size()))
n3, err := m.RuntimeData.MarshalTo(dAtA[i:])
n2, err := m.RuntimeData.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n3
i += n2
}
if len(m.Stdin) > 0 {
dAtA[i] = 0x52
@ -339,21 +328,21 @@ func (m *User) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintTask(dAtA, i, uint64(m.Gid))
}
if len(m.AdditionalGids) > 0 {
dAtA5 := make([]byte, len(m.AdditionalGids)*10)
var j4 int
dAtA4 := make([]byte, len(m.AdditionalGids)*10)
var j3 int
for _, num := range m.AdditionalGids {
for num >= 1<<7 {
dAtA5[j4] = uint8(uint64(num)&0x7f | 0x80)
dAtA4[j3] = uint8(uint64(num)&0x7f | 0x80)
num >>= 7
j4++
j3++
}
dAtA5[j4] = uint8(num)
j4++
dAtA4[j3] = uint8(num)
j3++
}
dAtA[i] = 0x1a
i++
i = encodeVarintTask(dAtA, i, uint64(j4))
i += copy(dAtA[i:], dAtA5[:j4])
i = encodeVarintTask(dAtA, i, uint64(j3))
i += copy(dAtA[i:], dAtA4[:j3])
}
return i, nil
}
@ -402,10 +391,6 @@ func (m *Task) Size() (n int) {
if m.Status != 0 {
n += 1 + sovTask(uint64(m.Status))
}
if m.Spec != nil {
l = m.Spec.Size()
n += 1 + l + sovTask(uint64(l))
}
l = len(m.Stdin)
if l > 0 {
n += 1 + l + sovTask(uint64(l))
@ -519,7 +504,6 @@ func (this *Task) String() string {
`ContainerID:` + fmt.Sprintf("%v", this.ContainerID) + `,`,
`Pid:` + fmt.Sprintf("%v", this.Pid) + `,`,
`Status:` + fmt.Sprintf("%v", this.Status) + `,`,
`Spec:` + strings.Replace(fmt.Sprintf("%v", this.Spec), "Any", "google_protobuf1.Any", 1) + `,`,
`Stdin:` + fmt.Sprintf("%v", this.Stdin) + `,`,
`Stdout:` + fmt.Sprintf("%v", this.Stdout) + `,`,
`Stderr:` + fmt.Sprintf("%v", this.Stderr) + `,`,
@ -695,39 +679,6 @@ func (m *Task) Unmarshal(dAtA []byte) error {
}
}
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTask
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTask
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Spec == nil {
m.Spec = &google_protobuf1.Any{}
}
if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Stdin", wireType)
}
@ -756,7 +707,7 @@ func (m *Task) Unmarshal(dAtA []byte) error {
}
m.Stdin = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 7:
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Stdout", wireType)
}
@ -785,7 +736,7 @@ func (m *Task) Unmarshal(dAtA []byte) error {
}
m.Stdout = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 8:
case 7:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Stderr", wireType)
}
@ -814,7 +765,7 @@ func (m *Task) Unmarshal(dAtA []byte) error {
}
m.Stderr = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 9:
case 8:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Terminal", wireType)
}
@ -1482,45 +1433,44 @@ func init() {
}
var fileDescriptorTask = []byte{
// 630 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xc1, 0x4e, 0xdb, 0x40,
0x14, 0x8c, 0x1d, 0xe3, 0x24, 0xeb, 0x04, 0xdc, 0x2d, 0x42, 0x26, 0xad, 0x8c, 0xc5, 0xa5, 0x56,
0xa5, 0x3a, 0x6a, 0x38, 0x54, 0xea, 0x0d, 0x48, 0x84, 0xa2, 0x4a, 0x21, 0xda, 0x10, 0xf5, 0x18,
0x2d, 0xd9, 0xad, 0xbb, 0x02, 0xd6, 0x96, 0x77, 0x0d, 0xe5, 0xd6, 0x63, 0xc5, 0x3f, 0x70, 0x6a,
0xfb, 0x0b, 0x3d, 0xf4, 0x0b, 0x38, 0xf6, 0xd8, 0x13, 0x2a, 0xf9, 0x85, 0xfe, 0x40, 0xe5, 0xb5,
0x49, 0x82, 0x14, 0xa4, 0x5e, 0xa2, 0x79, 0x33, 0xa3, 0xf8, 0xbd, 0x99, 0x05, 0x6f, 0x43, 0x26,
0x3f, 0xa6, 0xc7, 0xc1, 0x24, 0x3a, 0x6b, 0x4d, 0x22, 0x2e, 0x31, 0xe3, 0x34, 0x21, 0x8b, 0x10,
0xc7, 0xac, 0x25, 0x2f, 0x63, 0x2a, 0x5a, 0x12, 0x8b, 0x13, 0xf5, 0x13, 0xc4, 0x49, 0x24, 0x23,
0xf8, 0x74, 0xee, 0x0a, 0xce, 0x5f, 0x07, 0xca, 0xd4, 0x5c, 0x0f, 0xa3, 0x30, 0x52, 0x7a, 0x2b,
0x43, 0xb9, 0xb5, 0xb9, 0x19, 0x46, 0x51, 0x78, 0x4a, 0x5b, 0x6a, 0x3a, 0x4e, 0x3f, 0xb4, 0x30,
0xbf, 0xcc, 0xa5, 0xed, 0xef, 0x3a, 0x30, 0x8e, 0xb0, 0x38, 0x81, 0x1b, 0x40, 0x67, 0xc4, 0xd1,
0x3c, 0xcd, 0xaf, 0xed, 0x99, 0xd3, 0xdb, 0x2d, 0xbd, 0xd7, 0x41, 0x3a, 0x23, 0xb0, 0x0d, 0xea,
0xb3, 0x0f, 0x8d, 0x19, 0x71, 0x74, 0xe5, 0x58, 0x9b, 0xde, 0x6e, 0x59, 0xfb, 0xf7, 0x7c, 0xaf,
0x83, 0xac, 0x99, 0xa9, 0x47, 0xa0, 0x0d, 0xca, 0x31, 0x23, 0x4e, 0xd9, 0xd3, 0xfc, 0x06, 0xca,
0x20, 0xdc, 0x01, 0xa6, 0x90, 0x58, 0xa6, 0xc2, 0x31, 0x3c, 0xcd, 0x5f, 0x6d, 0x3f, 0x0b, 0x96,
0x6c, 0x1f, 0x0c, 0x95, 0x05, 0x15, 0x56, 0xe8, 0x03, 0x43, 0xc4, 0x74, 0xe2, 0xac, 0x78, 0x9a,
0x6f, 0xb5, 0xd7, 0x83, 0xfc, 0x8a, 0xe0, 0xfe, 0x8a, 0x60, 0x97, 0x5f, 0x22, 0xe5, 0x80, 0xeb,
0x60, 0x45, 0x48, 0xc2, 0xb8, 0x63, 0x66, 0xdb, 0xa1, 0x7c, 0x80, 0x1b, 0xd9, 0x47, 0x49, 0x94,
0x4a, 0xa7, 0xa2, 0xe8, 0x62, 0x2a, 0x78, 0x9a, 0x24, 0x4e, 0x75, 0xc6, 0xd3, 0x24, 0x81, 0x4d,
0x50, 0x95, 0x34, 0x39, 0x63, 0x1c, 0x9f, 0x3a, 0x35, 0x4f, 0xf3, 0xab, 0x68, 0x36, 0x6f, 0xff,
0xd5, 0x41, 0x65, 0x90, 0x44, 0x13, 0x2a, 0xc4, 0xfd, 0x79, 0xda, 0xfc, 0x3c, 0x08, 0x0c, 0x9c,
0x84, 0xc2, 0xd1, 0xbd, 0xb2, 0x5f, 0x43, 0x0a, 0x67, 0x2e, 0xca, 0xcf, 0x9d, 0xb2, 0xa2, 0x32,
0x08, 0x5f, 0x01, 0x23, 0x15, 0x34, 0x51, 0x11, 0x58, 0xed, 0xcd, 0xa5, 0x11, 0x8c, 0x04, 0x4d,
0x90, 0xb2, 0x65, 0x7f, 0x30, 0xb9, 0x20, 0xea, 0xfa, 0x1a, 0xca, 0xe0, 0x83, 0x05, 0xcd, 0x87,
0x0b, 0xc2, 0x2d, 0x60, 0xd1, 0x4f, 0x4c, 0x8e, 0x8b, 0x98, 0x2b, 0x6a, 0x39, 0x90, 0x51, 0x79,
0xaa, 0x0b, 0x15, 0x54, 0xff, 0xbf, 0x82, 0x37, 0xa0, 0x9e, 0xa4, 0x5c, 0xb2, 0x33, 0x3a, 0x26,
0x58, 0x62, 0x15, 0xcb, 0x63, 0x55, 0x58, 0x85, 0xb3, 0x83, 0x25, 0x9e, 0x37, 0x02, 0x96, 0x37,
0x62, 0x3d, 0xd2, 0x48, 0x7d, 0xb1, 0x91, 0xed, 0x21, 0x30, 0x46, 0x45, 0x14, 0xe9, 0x3c, 0xf1,
0x94, 0xa9, 0x27, 0x16, 0x16, 0xaf, 0xb1, 0x81, 0x32, 0x08, 0x5f, 0x80, 0x35, 0x4c, 0x08, 0x93,
0x2c, 0xe2, 0xf8, 0x74, 0x1c, 0x32, 0x22, 0x54, 0xf6, 0x0d, 0xb4, 0x3a, 0xa7, 0x0f, 0x18, 0x11,
0x2f, 0x7f, 0x68, 0xc0, 0x2c, 0x32, 0x71, 0x41, 0x65, 0xd4, 0x7f, 0xd7, 0x3f, 0x7c, 0xdf, 0xb7,
0x4b, 0xcd, 0x27, 0x57, 0xd7, 0x5e, 0x23, 0x17, 0x46, 0xfc, 0x84, 0x47, 0x17, 0x3c, 0xd3, 0xf7,
0x51, 0x77, 0xf7, 0xa8, 0xdb, 0xb1, 0xb5, 0x45, 0x7d, 0x3f, 0xa1, 0x58, 0x52, 0x92, 0xe9, 0x68,
0xd4, 0xef, 0xf7, 0xfa, 0x07, 0xb6, 0xbe, 0xa8, 0xa3, 0x94, 0x73, 0xc6, 0xc3, 0x4c, 0x1f, 0x1e,
0x1d, 0x0e, 0x06, 0xdd, 0x8e, 0x5d, 0x5e, 0xd4, 0x87, 0x32, 0x8a, 0x63, 0x4a, 0xe0, 0x73, 0x60,
0x0e, 0x76, 0x47, 0xc3, 0x6e, 0xc7, 0x36, 0x9a, 0xf6, 0xd5, 0xb5, 0x57, 0xcf, 0xe5, 0x01, 0x4e,
0x05, 0x25, 0xcd, 0xd5, 0x2f, 0x5f, 0xdd, 0xd2, 0xcf, 0x6f, 0x6e, 0xb1, 0xed, 0x9e, 0x73, 0x73,
0xe7, 0x96, 0x7e, 0xdf, 0xb9, 0xa5, 0xcf, 0x53, 0x57, 0xbb, 0x99, 0xba, 0xda, 0xaf, 0xa9, 0xab,
0xfd, 0x99, 0xba, 0xda, 0xb1, 0xa9, 0x8a, 0xd8, 0xf9, 0x17, 0x00, 0x00, 0xff, 0xff, 0xec, 0x58,
0x26, 0xdd, 0x50, 0x04, 0x00, 0x00,
// 616 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x31, 0x4f, 0x1b, 0x3f,
0x1c, 0xcd, 0x5d, 0xc2, 0x25, 0x38, 0x09, 0xdc, 0xdf, 0x7f, 0x84, 0x8e, 0xb4, 0x3a, 0x4e, 0x2c,
0x8d, 0x2a, 0xf5, 0xa2, 0xc2, 0x50, 0xa9, 0x1b, 0x90, 0x08, 0x45, 0x95, 0x42, 0xe4, 0x10, 0x75,
0x8c, 0x4c, 0xec, 0x5e, 0x2d, 0xc0, 0x8e, 0x6c, 0x1f, 0x94, 0xad, 0x63, 0xc5, 0x77, 0x60, 0x6a,
0x3f, 0x43, 0x87, 0x7e, 0x02, 0xc6, 0x8e, 0x9d, 0x50, 0xc9, 0x57, 0xe8, 0xd8, 0xa5, 0xb2, 0xef,
0x48, 0x82, 0x44, 0xa5, 0x2e, 0xa7, 0xe7, 0xf7, 0x9e, 0xce, 0xcf, 0xef, 0xf7, 0x03, 0xaf, 0x13,
0xa6, 0xdf, 0xa7, 0xc7, 0xf1, 0x58, 0x9c, 0xb5, 0xc6, 0x82, 0x6b, 0xcc, 0x38, 0x95, 0x64, 0x11,
0xe2, 0x09, 0x6b, 0xe9, 0xcb, 0x09, 0x55, 0x2d, 0x8d, 0xd5, 0x89, 0xfd, 0xc4, 0x13, 0x29, 0xb4,
0x80, 0xff, 0xcf, 0x5d, 0xf1, 0xf9, 0xcb, 0xd8, 0x9a, 0x1a, 0x6b, 0x89, 0x48, 0x84, 0xd5, 0x5b,
0x06, 0x65, 0xd6, 0xc6, 0x46, 0x22, 0x44, 0x72, 0x4a, 0x5b, 0xf6, 0x74, 0x9c, 0xbe, 0x6b, 0x61,
0x7e, 0x99, 0x49, 0x5b, 0xbf, 0x1d, 0x50, 0x3a, 0xc2, 0xea, 0x04, 0xae, 0x03, 0x97, 0x91, 0xc0,
0x89, 0x9c, 0xe6, 0xf2, 0x9e, 0x37, 0xbd, 0xdd, 0x74, 0xbb, 0x6d, 0xe4, 0x32, 0x02, 0xb7, 0x41,
0x6d, 0x76, 0xd1, 0x88, 0x91, 0xc0, 0xb5, 0x8e, 0xd5, 0xe9, 0xed, 0x66, 0x75, 0xff, 0x9e, 0xef,
0xb6, 0x51, 0x75, 0x66, 0xea, 0x12, 0xe8, 0x83, 0xe2, 0x84, 0x91, 0xa0, 0x18, 0x39, 0xcd, 0x3a,
0x32, 0x10, 0xee, 0x00, 0x4f, 0x69, 0xac, 0x53, 0x15, 0x94, 0x22, 0xa7, 0xb9, 0xb2, 0xfd, 0x24,
0x7e, 0x24, 0x7d, 0x3c, 0xb0, 0x16, 0x94, 0x5b, 0xe1, 0x1a, 0x58, 0x52, 0x9a, 0x30, 0x1e, 0x2c,
0x99, 0x3b, 0x51, 0x76, 0x80, 0xeb, 0xe6, 0x57, 0x44, 0xa4, 0x3a, 0xf0, 0x2c, 0x9d, 0x9f, 0x72,
0x9e, 0x4a, 0x19, 0x94, 0x67, 0x3c, 0x95, 0x12, 0x36, 0x40, 0x45, 0x53, 0x79, 0xc6, 0x38, 0x3e,
0x0d, 0x2a, 0x91, 0xd3, 0xac, 0xa0, 0xd9, 0x79, 0xeb, 0x97, 0x0b, 0xca, 0x7d, 0x29, 0xc6, 0x54,
0xa9, 0xfb, 0xd0, 0xce, 0x3c, 0x34, 0x04, 0x25, 0x2c, 0x13, 0x15, 0xb8, 0x51, 0xb1, 0xb9, 0x8c,
0x2c, 0x36, 0x2e, 0xca, 0xcf, 0x83, 0xa2, 0xa5, 0x0c, 0x84, 0x2f, 0x40, 0x29, 0x55, 0x54, 0xda,
0x87, 0x55, 0xb7, 0x37, 0x1e, 0x7d, 0xd8, 0x50, 0x51, 0x89, 0xac, 0xcd, 0xfc, 0x60, 0x7c, 0x41,
0xf2, 0x27, 0x19, 0xf8, 0x20, 0xa0, 0xf7, 0x30, 0x20, 0xdc, 0x04, 0x55, 0xfa, 0x81, 0xe9, 0x51,
0x5e, 0x5e, 0xd9, 0x86, 0x03, 0x86, 0xca, 0xba, 0x5a, 0x28, 0xb6, 0xf2, 0xef, 0xc5, 0xbe, 0x02,
0x35, 0x99, 0x72, 0xcd, 0xce, 0xe8, 0x88, 0x60, 0x8d, 0x83, 0x65, 0x1b, 0x7d, 0x2d, 0xce, 0xd6,
0x24, 0xbe, 0x5f, 0x93, 0x78, 0x97, 0x5f, 0xa2, 0x6a, 0xee, 0x6c, 0x63, 0x8d, 0xe7, 0x13, 0x01,
0x8f, 0x4f, 0xa4, 0xfa, 0x97, 0x89, 0xd4, 0x16, 0x27, 0xb2, 0x35, 0x00, 0xa5, 0x61, 0x5e, 0x45,
0x3a, 0x6f, 0x3c, 0x65, 0x76, 0x71, 0x92, 0x7c, 0xc7, 0xea, 0xc8, 0x40, 0xf8, 0x0c, 0xac, 0x62,
0x42, 0x98, 0x66, 0x82, 0xe3, 0xd3, 0x51, 0xc2, 0x88, 0xb2, 0xdd, 0xd7, 0xd1, 0xca, 0x9c, 0x3e,
0x60, 0x44, 0x3d, 0xff, 0xea, 0x00, 0x2f, 0xef, 0x24, 0x04, 0xe5, 0x61, 0xef, 0x4d, 0xef, 0xf0,
0x6d, 0xcf, 0x2f, 0x34, 0xfe, 0xbb, 0xba, 0x8e, 0xea, 0x99, 0x30, 0xe4, 0x27, 0x5c, 0x5c, 0x70,
0xa3, 0xef, 0xa3, 0xce, 0xee, 0x51, 0xa7, 0xed, 0x3b, 0x8b, 0xfa, 0xbe, 0xa4, 0x58, 0x53, 0x62,
0x74, 0x34, 0xec, 0xf5, 0xba, 0xbd, 0x03, 0xdf, 0x5d, 0xd4, 0x51, 0xca, 0x39, 0xe3, 0x89, 0xd1,
0x07, 0x47, 0x87, 0xfd, 0x7e, 0xa7, 0xed, 0x17, 0x17, 0xf5, 0x81, 0x16, 0x93, 0x09, 0x25, 0xf0,
0x29, 0xf0, 0xfa, 0xbb, 0xc3, 0x41, 0xa7, 0xed, 0x97, 0x1a, 0xfe, 0xd5, 0x75, 0x54, 0xcb, 0xe4,
0x3e, 0x4e, 0x15, 0x25, 0x8d, 0x95, 0x4f, 0x9f, 0xc3, 0xc2, 0xb7, 0x2f, 0x61, 0x9e, 0x76, 0x2f,
0xb8, 0xb9, 0x0b, 0x0b, 0x3f, 0xee, 0xc2, 0xc2, 0xc7, 0x69, 0xe8, 0xdc, 0x4c, 0x43, 0xe7, 0xfb,
0x34, 0x74, 0x7e, 0x4e, 0x43, 0xe7, 0xd8, 0xb3, 0x83, 0xd8, 0xf9, 0x13, 0x00, 0x00, 0xff, 0xff,
0x1e, 0xcd, 0x9c, 0x52, 0x26, 0x04, 0x00, 0x00,
}

View File

@ -21,11 +21,10 @@ message Task {
string container_id = 2;
uint32 pid = 3;
Status status = 4;
google.protobuf.Any spec = 5;
string stdin = 6;
string stdout = 7;
string stderr = 8;
bool terminal = 9;
string stdin = 5;
string stdout = 6;
string stderr = 7;
bool terminal = 8;
}
message Process {

View File

@ -7,6 +7,7 @@ import (
"log"
"net/http"
"runtime"
"strconv"
"sync"
"time"
@ -31,9 +32,11 @@ import (
imagesservice "github.com/containerd/containerd/services/images"
snapshotservice "github.com/containerd/containerd/services/snapshot"
"github.com/containerd/containerd/snapshot"
"github.com/containerd/containerd/typeurl"
pempty "github.com/golang/protobuf/ptypes/empty"
"github.com/opencontainers/image-spec/identity"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
@ -43,6 +46,13 @@ import (
func init() {
// reset the grpc logger so that it does not output in the STDIO of the calling process
grpclog.SetLogger(log.New(ioutil.Discard, "", log.LstdFlags))
// register TypeUrls for commonly marshaled external types
major := strconv.Itoa(specs.VersionMajor)
typeurl.Register(&specs.Spec{}, "opencontainers/runtime-spec", major, "Spec")
typeurl.Register(&specs.Process{}, "opencontainers/runtime-spec", major, "Process")
typeurl.Register(&specs.LinuxResources{}, "opencontainers/runtime-spec", major, "LinuxResources")
typeurl.Register(&specs.WindowsResources{}, "opencontainers/runtime-spec", major, "WindowsResources")
}
type clientOpts struct {

View File

@ -7,7 +7,7 @@ import (
"text/tabwriter"
eventsapi "github.com/containerd/containerd/api/services/events/v1"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/typeurl"
"github.com/urfave/cli"
)
@ -57,13 +57,11 @@ var eventsCommand = cli.Command{
func getEventOutput(env *eventsapi.Envelope) (string, error) {
out := ""
var de events.DynamicEvent
if err := events.UnmarshalEvent(env.Event, &de); err != nil {
v, err := typeurl.UnmarshalAny(env.Event)
if err != nil {
return "", err
}
switch e := de.Event.(type) {
switch e := v.(type) {
case *eventsapi.ContainerCreate:
out = fmt.Sprintf("id=%s image=%s runtime=%s", e.ContainerID, e.Image, e.Runtime)
case *eventsapi.TaskCreate:
@ -105,6 +103,5 @@ func getEventOutput(env *eventsapi.Envelope) (string, error) {
default:
out = env.Event.TypeUrl
}
return out, nil
}

View File

@ -10,13 +10,11 @@ import (
"github.com/Sirupsen/logrus"
"github.com/containerd/console"
"github.com/containerd/containerd"
containersapi "github.com/containerd/containerd/api/services/containers/v1"
"github.com/containerd/containerd/api/services/tasks/v1"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/windows"
"github.com/containerd/containerd/windows/hcs"
protobuf "github.com/gogo/protobuf/types"
digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
@ -136,25 +134,6 @@ func newContainerSpec(context *cli.Context, config *ocispec.ImageConfig, imageRe
return json.Marshal(rtSpec)
}
func newCreateContainerRequest(context *cli.Context, id, snapshot, image string, spec []byte) (*containersapi.CreateContainerRequest, error) {
create := &containersapi.CreateContainerRequest{
Container: containersapi.Container{
ID: id,
Image: image,
Spec: &protobuf.Any{
TypeUrl: specs.Version,
Value: spec,
},
Runtime: &containersapi.Container_Runtime{
Name: context.String("runtime"),
},
RootFS: snapshot,
},
}
return create, nil
}
func newCreateTaskRequest(context *cli.Context, id, tmpDir string, checkpoint *ocispec.Descriptor, mounts []mount.Mount) (*tasks.CreateTaskRequest, error) {
create := &tasks.CreateTaskRequest{
ContainerID: id,

View File

@ -20,6 +20,7 @@ import (
"github.com/Sirupsen/logrus"
"github.com/containerd/console"
shim "github.com/containerd/containerd/linux/shim/v1"
"github.com/containerd/containerd/typeurl"
protobuf "github.com/gogo/protobuf/types"
google_protobuf "github.com/golang/protobuf/ptypes/empty"
"github.com/opencontainers/runtime-spec/specs-go"
@ -235,10 +236,14 @@ var shimExecCommand = cli.Command{
if err != nil {
return err
}
url, err := typeurl.TypeURL(specs.Process{})
if err != nil {
return err
}
rq := &shim.ExecProcessRequest{
Spec: &protobuf.Any{
TypeUrl: specs.Version,
TypeUrl: url,
Value: spec,
},
Stdin: context.String("stdin"),

View File

@ -14,11 +14,11 @@ import (
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/gogo/protobuf/proto"
protobuf "github.com/gogo/protobuf/types"
digest "github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/identity"
"github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
func WithCheckpoint(desc v1.Descriptor, rootfsID string) NewContainerOpts {
@ -61,10 +61,11 @@ func WithCheckpoint(desc v1.Descriptor, rootfsID string) NewContainerOpts {
if err != nil {
return err
}
c.Spec = &protobuf.Any{
TypeUrl: specs.Version,
Value: data,
var any protobuf.Any
if err := proto.Unmarshal(data, &any); err != nil {
return err
}
c.Spec = &any
}
}
if rw != nil {

View File

@ -17,7 +17,7 @@ type Container struct {
Labels map[string]string
Image string
Runtime RuntimeInfo
Spec []byte
Spec *types.Any
RootFS string
CreatedAt time.Time
UpdatedAt time.Time

View File

@ -1,72 +0,0 @@
package events
import (
"github.com/gogo/protobuf/proto"
"github.com/gogo/protobuf/types"
"github.com/pkg/errors"
)
const (
typesPrefix = "types.containerd.io/"
)
// MarshalEvent marshal the event into an any, namespacing the type url to the
// containerd types.
func MarshalEvent(event Event) (*types.Any, error) {
pb, ok := event.(proto.Message)
if !ok {
return nil, errors.Errorf("%T not a protobuf", event)
}
url := typesPrefix + proto.MessageName(pb)
val, err := proto.Marshal(pb)
if err != nil {
return nil, err
}
return &types.Any{
TypeUrl: url,
Value: val,
}, nil
}
// DynamEvent acts as a holder type for unmarshaling events where the type is
// not previously known.
type DynamicEvent struct {
Event
}
// UnmarshalEvent provides an event object based on the provided any.
//
// Use with DynamicEvent (or protobuf/types.DynamicAny) if the type is not
// known before hand.
func UnmarshalEvent(any *types.Any, event Event) error {
switch v := event.(type) {
case proto.Message:
if err := types.UnmarshalAny(any, v); err != nil {
return errors.Wrapf(err, "failed to unmarshal event %v", any)
}
case *DynamicEvent:
var da types.DynamicAny
if err := types.UnmarshalAny(any, &da); err != nil {
return errors.Wrapf(err, "failed to unmarshal event %v", any)
}
v.Event = da.Message
default:
return errors.Errorf("unsupported event type: %T", event)
}
return nil
}
// Is returns true if the event in any will unmarashal into the provided event.
func Is(any *types.Any, event Event) bool {
pb, ok := event.(proto.Message)
if !ok {
return false
}
return types.Is(any, pb)
}

View File

@ -1,62 +0,0 @@
package events
import (
"fmt"
"reflect"
"testing"
events "github.com/containerd/containerd/api/services/events/v1"
)
func TestMarshalEvent(t *testing.T) {
for _, testcase := range []struct {
event Event
url string
}{
{
event: &events.TaskStart{},
url: "types.containerd.io/containerd.services.events.v1.TaskStart",
},
{
event: &events.NamespaceUpdate{},
url: "types.containerd.io/containerd.services.events.v1.NamespaceUpdate",
},
} {
t.Run(fmt.Sprintf("%T", testcase.event), func(t *testing.T) {
a, err := MarshalEvent(testcase.event)
if err != nil {
t.Fatal(err)
}
if a.TypeUrl != testcase.url {
t.Fatalf("unexpected url: %v != %v", a.TypeUrl, testcase.url)
}
var de DynamicEvent
if err := UnmarshalEvent(a, &de); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(de.Event, testcase.event) {
t.Fatalf("round trip failed %v != %v", de.Event, testcase.event)
}
})
}
}
func BenchmarkMarshalEvent(b *testing.B) {
ev := &events.TaskStart{}
expected, err := MarshalEvent(ev)
if err != nil {
b.Fatal(err)
}
for i := 0; i < b.N; i++ {
a, err := MarshalEvent(ev)
if err != nil {
b.Fatal(err)
}
if a.TypeUrl != expected.TypeUrl {
b.Fatalf("incorrect type url: %v != %v", a, expected)
}
}
}

View File

@ -8,6 +8,7 @@ import (
"github.com/containerd/containerd/api/services/events/v1"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/typeurl"
goevents "github.com/docker/go-events"
"github.com/pkg/errors"
)
@ -35,7 +36,7 @@ func (s *eventSink) Write(evt goevents.Event) error {
return nil
}
eventData, err := MarshalEvent(e.event)
eventData, err := typeurl.MarshalAny(e.event)
if err != nil {
return err
}

View File

@ -15,7 +15,7 @@ const (
MediaTypeContainerd1CheckpointPreDump = "application/vnd.containerd.container.criu.checkpoint.predump.tar"
MediaTypeContainerd1Resource = "application/vnd.containerd.container.resource.tar"
MediaTypeContainerd1RW = "application/vnd.containerd.container.rw.tar"
MediaTypeContainerd1CheckpointConfig = "application/vnd.containerd.container.checkpoint.config.v1+json"
MediaTypeContainerd1CheckpointConfig = "application/vnd.containerd.container.checkpoint.config.v1+proto"
// Legacy Docker schema1 manifest
MediaTypeDockerSchema1Manifest = "application/vnd.docker.distribution.manifest.v1+prettyjws"
)

View File

@ -6,7 +6,6 @@ import (
"bytes"
"context"
"io"
"io/ioutil"
"os"
"path/filepath"
@ -82,11 +81,6 @@ func (b *bundle) Connect(ctx context.Context, remote bool) (*client.Client, erro
}, opt)
}
// spec returns the spec written to the bundle
func (b *bundle) Spec() ([]byte, error) {
return ioutil.ReadFile(filepath.Join(b.path, configFilename))
}
// Delete deletes the bundle from disk
func (b *bundle) Delete() error {
return os.RemoveAll(b.path)

View File

@ -1,33 +1,14 @@
package runcopts
import (
"path/filepath"
tasks "github.com/containerd/containerd/api/services/tasks/v1"
"github.com/gogo/protobuf/proto"
protobuf "github.com/gogo/protobuf/types"
"github.com/containerd/containerd/typeurl"
)
const URIBase = "types.containerd.io/linux/runc"
func WithExit(r *tasks.CheckpointTaskRequest) error {
a, err := marshal(&CheckpointOptions{
a, err := typeurl.MarshalAny(&CheckpointOptions{
Exit: true,
}, "CheckpointOptions")
if err != nil {
return err
}
})
r.Options = a
return nil
}
func marshal(m proto.Message, name string) (*protobuf.Any, error) {
data, err := proto.Marshal(m)
if err != nil {
return nil, err
}
return &protobuf.Any{
TypeUrl: filepath.Join(URIBase, name),
Value: data,
}, nil
return err
}

View File

@ -139,7 +139,7 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts
if err != nil {
return nil, err
}
bundle, err := newBundle(filepath.Join(r.root, namespace), namespace, id, opts.Spec)
bundle, err := newBundle(filepath.Join(r.root, namespace), namespace, id, opts.Spec.Value)
if err != nil {
return nil, err
}
@ -183,7 +183,7 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts
if _, err = s.Create(ctx, sopts); err != nil {
return nil, errors.New(grpc.ErrorDesc(err))
}
t := newTask(id, namespace, opts.Spec, s)
t := newTask(id, namespace, s)
if err := r.tasks.add(ctx, t); err != nil {
return nil, err
}
@ -323,14 +323,9 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
}
continue
}
spec, err := bundle.Spec()
if err != nil {
log.G(ctx).WithError(err).Error("load task spec")
}
o = append(o, &Task{
containerID: id,
shim: s,
spec: spec,
namespace: ns,
})
}

View File

@ -22,9 +22,9 @@ import (
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/typeurl"
"github.com/containerd/fifo"
runc "github.com/containerd/go-runc"
"github.com/gogo/protobuf/proto"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@ -58,9 +58,11 @@ type initProcess struct {
func newInitProcess(context context.Context, path, namespace string, r *shimapi.CreateTaskRequest) (*initProcess, error) {
var options runcopts.CreateOptions
if r.Options != nil {
if err := proto.Unmarshal(r.Options.Value, &options); err != nil {
v, err := typeurl.UnmarshalAny(r.Options)
if err != nil {
return nil, err
}
options = *v.(*runcopts.CreateOptions)
}
for _, rm := range r.Rootfs {
m := &mount.Mount{
@ -266,9 +268,11 @@ func (p *initProcess) Stdin() io.Closer {
func (p *initProcess) Checkpoint(context context.Context, r *shimapi.CheckpointTaskRequest) error {
var options runcopts.CheckpointOptions
if r.Options != nil {
if err := proto.Unmarshal(r.Options.Value, &options); err != nil {
v, err := typeurl.UnmarshalAny(r.Options)
if err != nil {
return err
}
options = *v.(*runcopts.CheckpointOptions)
}
var actions []runc.CheckpointAction
if !options.Exit {

View File

@ -17,16 +17,14 @@ import (
type Task struct {
containerID string
spec []byte
shim *client.Client
namespace string
}
func newTask(id, namespace string, spec []byte, shim *client.Client) *Task {
func newTask(id, namespace string, shim *client.Client) *Task {
return &Task{
containerID: id,
shim: shim,
spec: spec,
namespace: namespace,
}
}
@ -36,7 +34,6 @@ func (t *Task) Info() runtime.TaskInfo {
ID: t.containerID,
ContainerID: t.containerID,
Runtime: pluginID,
Spec: t.spec,
Namespace: t.namespace,
}
}

View File

@ -230,8 +230,11 @@ func readContainer(container *containers.Container, bkt *bolt.Bucket) error {
}
container.Runtime.Options = &any
case string(bucketKeySpec):
container.Spec = make([]byte, len(v))
copy(container.Spec, v)
var any types.Any
if err := proto.Unmarshal(v, &any); err != nil {
return err
}
container.Spec = &any
case string(bucketKeyRootFS):
container.RootFS = string(v)
case string(bucketKeyCreatedAt):
@ -269,10 +272,14 @@ func writeContainer(container *containers.Container, bkt *bolt.Bucket) error {
if err != nil {
return err
}
spec, err := container.Spec.Marshal()
if err != nil {
return err
}
for _, v := range [][2][]byte{
{bucketKeyImage, []byte(container.Image)},
{bucketKeySpec, container.Spec},
{bucketKeySpec, spec},
{bucketKeyRootFS, []byte(container.RootFS)},
{bucketKeyCreatedAt, createdAt},
{bucketKeyUpdatedAt, updatedAt},

View File

@ -2,13 +2,11 @@ package containerd
import (
"context"
"encoding/json"
"syscall"
eventsapi "github.com/containerd/containerd/api/services/events/v1"
"github.com/containerd/containerd/api/services/tasks/v1"
"github.com/containerd/containerd/events"
protobuf "github.com/gogo/protobuf/types"
"github.com/containerd/containerd/typeurl"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
@ -35,7 +33,7 @@ func (p *process) Pid() uint32 {
// Start starts the exec process
func (p *process) Start(ctx context.Context) error {
data, err := json.Marshal(p.spec)
any, err := typeurl.MarshalAny(p.spec)
if err != nil {
return err
}
@ -45,10 +43,7 @@ func (p *process) Start(ctx context.Context) error {
Stdin: p.io.Stdin,
Stdout: p.io.Stdout,
Stderr: p.io.Stderr,
Spec: &protobuf.Any{
TypeUrl: specs.Version,
Value: data,
},
Spec: any,
}
response, err := p.task.client.TaskService().Exec(ctx, request)
if err != nil {
@ -71,7 +66,6 @@ func (p *process) Kill(ctx context.Context, s syscall.Signal) error {
}
func (p *process) Wait(ctx context.Context) (uint32, error) {
// TODO (ehazlett): add filtering for specific event
eventstream, err := p.task.client.EventService().Stream(ctx, &eventsapi.StreamEventsRequest{})
if err != nil {
return UnknownExitStatus, err
@ -83,18 +77,15 @@ evloop:
if err != nil {
return UnknownExitStatus, err
}
switch {
case events.Is(evt.Event, &eventsapi.RuntimeEvent{}):
var e eventsapi.RuntimeEvent
if err := events.UnmarshalEvent(evt.Event, &e); err != nil {
if typeurl.Is(evt.Event, &eventsapi.RuntimeEvent{}) {
v, err := typeurl.UnmarshalAny(evt.Event)
if err != nil {
return UnknownExitStatus, err
}
e := v.(*eventsapi.RuntimeEvent)
if e.Type != eventsapi.RuntimeEvent_EXIT {
continue evloop
}
if e.ID == p.task.containerID && e.Pid == p.pid {
return e.ExitStatus, nil
}

View File

@ -17,7 +17,7 @@ type IO struct {
type CreateOpts struct {
// Spec is the OCI runtime spec
Spec []byte
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

View File

@ -10,7 +10,6 @@ type TaskInfo struct {
ID string
ContainerID string
Runtime string
Spec []byte
Namespace string
}

View File

@ -3,8 +3,6 @@ package containers
import (
api "github.com/containerd/containerd/api/services/containers/v1"
"github.com/containerd/containerd/containers"
"github.com/gogo/protobuf/types"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
func containersToProto(containers []containers.Container) []api.Container {
@ -26,10 +24,7 @@ func containerToProto(container *containers.Container) api.Container {
Name: container.Runtime.Name,
Options: container.Runtime.Options,
},
Spec: &types.Any{
TypeUrl: specs.Version,
Value: container.Spec,
},
Spec: container.Spec,
RootFS: container.RootFS,
}
}
@ -42,18 +37,12 @@ func containerFromProto(containerpb *api.Container) containers.Container {
Options: containerpb.Runtime.Options,
}
}
var spec []byte
if containerpb.Spec != nil {
spec = containerpb.Spec.Value
}
return containers.Container{
ID: containerpb.ID,
Labels: containerpb.Labels,
Image: containerpb.Image,
Runtime: runtime,
Spec: spec,
Spec: containerpb.Spec,
RootFS: containerpb.RootFS,
}
}

View File

@ -24,9 +24,7 @@ import (
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/runtime"
protobuf "github.com/gogo/protobuf/types"
google_protobuf "github.com/golang/protobuf/ptypes/empty"
specs "github.com/opencontainers/image-spec/specs-go"
"github.com/pkg/errors"
"golang.org/x/net/context"
"google.golang.org/grpc"
@ -249,14 +247,10 @@ func taskFromContainerd(ctx context.Context, c runtime.Task) (*task.Task, error)
ContainerID: c.Info().ContainerID,
Pid: state.Pid,
Status: status,
Spec: &protobuf.Any{
TypeUrl: specs.Version,
Value: c.Info().Spec,
},
Stdin: state.Stdin,
Stdout: state.Stdout,
Stderr: state.Stderr,
Terminal: state.Terminal,
Stdin: state.Stdin,
Stdout: state.Stdout,
Stderr: state.Stderr,
Terminal: state.Terminal,
}, nil
}
@ -405,7 +399,11 @@ func (s *Service) CloseIO(ctx context.Context, r *api.CloseIORequest) (*google_p
}
func (s *Service) Checkpoint(ctx context.Context, r *api.CheckpointTaskRequest) (*api.CheckpointTaskResponse, error) {
t, err := s.getTask(ctx, r.ContainerID)
container, err := s.getContainer(ctx, r.ContainerID)
if err != nil {
return nil, err
}
t, err := s.getTaskFromContainer(ctx, container)
if err != nil {
return nil, err
}
@ -428,7 +426,11 @@ func (s *Service) Checkpoint(ctx context.Context, r *api.CheckpointTaskRequest)
return nil, err
}
// write the config to the content store
spec := bytes.NewReader(t.Info().Spec)
data, err := container.Spec.Marshal()
if err != nil {
return nil, err
}
spec := bytes.NewReader(data)
specD, err := s.writeContent(ctx, images.MediaTypeContainerd1CheckpointConfig, filepath.Join(image, "spec"), spec)
if err != nil {
return nil, err
@ -472,19 +474,17 @@ func (s *Service) writeContent(ctx context.Context, mediaType, ref string, r io.
}, nil
}
func (s *Service) getContainer(ctx context.Context, id string) (containers.Container, error) {
func (s *Service) getContainer(ctx context.Context, id string) (*containers.Container, error) {
var container containers.Container
if err := s.db.View(func(tx *bolt.Tx) error {
store := metadata.NewContainerStore(tx)
var err error
container, err = store.Get(ctx, id)
return err
}); err != nil {
return containers.Container{}, errdefs.ToGRPC(err)
return nil, errdefs.ToGRPC(err)
}
return container, nil
return &container, nil
}
func (s *Service) getTask(ctx context.Context, id string) (runtime.Task, error) {
@ -492,18 +492,20 @@ func (s *Service) getTask(ctx context.Context, id string) (runtime.Task, error)
if err != nil {
return nil, err
}
return s.getTaskFromContainer(ctx, container)
}
func (s *Service) getTaskFromContainer(ctx context.Context, container *containers.Container) (runtime.Task, error) {
runtime, err := s.getRuntime(container.Runtime.Name)
if err != nil {
return nil, errdefs.ToGRPCf(err, "runtime for task %v", id)
return nil, errdefs.ToGRPCf(err, "runtime for task %s", container.Runtime.Name)
}
t, err := runtime.Get(ctx, id)
t, err := runtime.Get(ctx, container.ID)
if err != nil {
return nil, grpc.Errorf(codes.NotFound, "task %v not found", id)
return nil, grpc.Errorf(codes.NotFound, "task %v not found", container.ID)
}
return t, nil
}
func (s *Service) getRuntime(name string) (runtime.Runtime, error) {

View File

@ -12,7 +12,7 @@ import (
"github.com/containerd/containerd/api/services/containers/v1"
"github.com/containerd/containerd/api/services/tasks/v1"
"github.com/containerd/containerd/images"
protobuf "github.com/gogo/protobuf/types"
"github.com/containerd/containerd/typeurl"
"github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
@ -275,28 +275,22 @@ func WithImageConfig(ctx context.Context, i Image) SpecOpts {
func WithSpec(spec *specs.Spec) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
data, err := json.Marshal(spec)
any, err := typeurl.MarshalAny(spec)
if err != nil {
return err
}
c.Spec = &protobuf.Any{
TypeUrl: spec.Version,
Value: data,
}
c.Spec = any
return nil
}
}
func WithResources(resources *specs.LinuxResources) UpdateTaskOpts {
return func(ctx context.Context, client *Client, r *tasks.UpdateTaskRequest) error {
data, err := json.Marshal(resources)
any, err := typeurl.MarshalAny(resources)
if err != nil {
return err
}
r.Resources = &protobuf.Any{
TypeUrl: specs.Version,
Value: data,
}
r.Resources = any
return nil
}
}

View File

@ -8,7 +8,7 @@ import (
"github.com/containerd/containerd/api/services/containers/v1"
tasks "github.com/containerd/containerd/api/services/tasks/v1"
"github.com/containerd/containerd/images"
protobuf "github.com/gogo/protobuf/types"
"github.com/containerd/containerd/typeurl"
"github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
@ -77,28 +77,22 @@ func WithTTY(width, height int) SpecOpts {
func WithSpec(spec *specs.Spec) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
data, err := json.Marshal(spec)
any, err := typeurl.MarshalAny(spec)
if err != nil {
return err
}
c.Spec = &protobuf.Any{
TypeUrl: spec.Version,
Value: data,
}
c.Spec = any
return nil
}
}
func WithResources(resources *specs.WindowsResources) UpdateTaskOpts {
return func(ctx context.Context, client *Client, r *tasks.UpdateTaskRequest) error {
data, err := json.Marshal(resources)
any, err := typeurl.MarshalAny(resources)
if err != nil {
return err
}
r.Resources = &protobuf.Any{
TypeUrl: specs.Version,
Value: data,
}
r.Resources = any
return nil
}
}

32
task.go
View File

@ -14,9 +14,9 @@ import (
eventsapi "github.com/containerd/containerd/api/services/events/v1"
"github.com/containerd/containerd/api/services/tasks/v1"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/rootfs"
"github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/typeurl"
"github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
"google.golang.org/grpc"
@ -149,35 +149,29 @@ func (t *task) Status(ctx context.Context) (TaskStatus, error) {
// Wait is a blocking call that will wait for the task to exit and return the exit status
func (t *task) Wait(ctx context.Context) (uint32, error) {
// TODO (ehazlett): add filtering for specific event
eventstream, err := t.client.EventService().Stream(ctx, &eventsapi.StreamEventsRequest{})
if err != nil {
return UnknownExitStatus, err
}
<-t.pidSync
var e eventsapi.RuntimeEvent
for {
evt, err := eventstream.Recv()
if err != nil {
return UnknownExitStatus, err
}
if !events.Is(evt.Event, &eventsapi.RuntimeEvent{}) {
continue
}
if err := events.UnmarshalEvent(evt.Event, &e); err != nil {
return UnknownExitStatus, err
}
if e.Type != eventsapi.RuntimeEvent_EXIT {
continue
}
if e.ID == t.containerID && e.Pid == t.pid {
return e.ExitStatus, nil
if typeurl.Is(evt.Event, &eventsapi.RuntimeEvent{}) {
v, err := typeurl.UnmarshalAny(evt.Event)
if err != nil {
return UnknownExitStatus, err
}
e := v.(*eventsapi.RuntimeEvent)
if e.Type != eventsapi.RuntimeEvent_EXIT {
continue
}
if e.ID == t.containerID && e.Pid == t.pid {
return e.ExitStatus, nil
}
}
}
}

129
typeurl/types.go Normal file
View File

@ -0,0 +1,129 @@
package typeurl
import (
"encoding/json"
"path"
"reflect"
"strings"
"sync"
"github.com/containerd/containerd/errdefs"
"github.com/gogo/protobuf/proto"
"github.com/gogo/protobuf/types"
)
const Prefix = "types.containerd.io"
var (
mu sync.Mutex
registry = make(map[reflect.Type]string)
)
// Register a type with the base url of the type
func Register(v interface{}, args ...string) {
t := tryDereference(v)
mu.Lock()
defer mu.Unlock()
if _, ok := registry[t]; ok {
panic(errdefs.ErrAlreadyExists)
}
registry[t] = path.Join(append([]string{Prefix}, args...)...)
}
// TypeURL returns the type url for a registred type
func TypeURL(v interface{}) (string, error) {
mu.Lock()
u, ok := registry[tryDereference(v)]
mu.Unlock()
if !ok {
// fallback to the proto registry if it is a proto message
pb, ok := v.(proto.Message)
if !ok {
return "", errdefs.ErrNotFound
}
return path.Join(Prefix, proto.MessageName(pb)), nil
}
return u, nil
}
// Is returns true if the type of the Any is the same as v
func Is(any *types.Any, v interface{}) bool {
// call to check that v is a pointer
tryDereference(v)
url, err := TypeURL(v)
if err != nil {
return false
}
return any.TypeUrl == url
}
// MarshalAny marshals the value v into an any with the correct TypeUrl
func MarshalAny(v interface{}) (*types.Any, error) {
var data []byte
url, err := TypeURL(v)
if err != nil {
return nil, err
}
switch t := v.(type) {
case proto.Message:
data, err = proto.Marshal(t)
default:
data, err = json.Marshal(v)
}
if err != nil {
return nil, err
}
return &types.Any{
TypeUrl: url,
Value: data,
}, nil
}
// UnmarshalAny unmarshals the any type into a concrete type
func UnmarshalAny(any *types.Any) (interface{}, error) {
t, err := getTypeByUrl(any.TypeUrl)
if err != nil {
return nil, err
}
v := reflect.New(t.t).Interface()
if t.isProto {
err = proto.Unmarshal(any.Value, v.(proto.Message))
} else {
err = json.Unmarshal(any.Value, v)
}
return v, err
}
type urlType struct {
t reflect.Type
isProto bool
}
func getTypeByUrl(url string) (urlType, error) {
for t, u := range registry {
if u == url {
return urlType{
t: t,
}, nil
}
}
// fallback to proto registry
t := proto.MessageType(strings.TrimPrefix(url, Prefix+"/"))
if t != nil {
return urlType{
// get the underlying Elem because proto returns a pointer to the type
t: t.Elem(),
isProto: true,
}, nil
}
return urlType{}, errdefs.ErrNotFound
}
func tryDereference(v interface{}) reflect.Type {
t := reflect.TypeOf(v)
if t.Kind() == reflect.Ptr {
// require check of pointer but dereference to register
return t.Elem()
}
panic("v is not a pointer to a type")
}

148
typeurl/types_test.go Normal file
View File

@ -0,0 +1,148 @@
package typeurl
import (
"fmt"
"path/filepath"
"reflect"
"testing"
eventsapi "github.com/containerd/containerd/api/services/events/v1"
)
type test struct {
Name string
Age int
}
func clear() {
registry = make(map[reflect.Type]string)
}
func TestRegisterPointerGetPointer(t *testing.T) {
clear()
expected := filepath.Join(Prefix, "test")
Register(&test{}, "test")
url, err := TypeURL(&test{})
if err != nil {
t.Fatal(err)
}
if url != expected {
t.Fatalf("expected %q but received %q", expected, url)
}
}
func TestMarshal(t *testing.T) {
clear()
expected := filepath.Join(Prefix, "test")
Register(&test{}, "test")
v := &test{
Name: "koye",
Age: 6,
}
any, err := MarshalAny(v)
if err != nil {
t.Fatal(err)
}
if any.TypeUrl != expected {
t.Fatalf("expected %q but received %q", expected, any.TypeUrl)
}
}
func TestMarshalUnmarshal(t *testing.T) {
clear()
Register(&test{}, "test")
v := &test{
Name: "koye",
Age: 6,
}
any, err := MarshalAny(v)
if err != nil {
t.Fatal(err)
}
nv, err := UnmarshalAny(any)
if err != nil {
t.Fatal(err)
}
td, ok := nv.(*test)
if !ok {
t.Fatal("expected value to cast to *test")
}
if td.Name != "koye" {
t.Fatal("invalid name")
}
if td.Age != 6 {
t.Fatal("invalid age")
}
}
func TestIs(t *testing.T) {
clear()
Register(&test{}, "test")
v := &test{
Name: "koye",
Age: 6,
}
any, err := MarshalAny(v)
if err != nil {
t.Fatal(err)
}
if !Is(any, &test{}) {
t.Fatal("Is(any, test{}) should be true")
}
}
func TestMarshalEvent(t *testing.T) {
for _, testcase := range []struct {
event interface{}
url string
}{
{
event: &eventsapi.TaskStart{},
url: "types.containerd.io/containerd.services.events.v1.TaskStart",
},
{
event: &eventsapi.NamespaceUpdate{},
url: "types.containerd.io/containerd.services.events.v1.NamespaceUpdate",
},
} {
t.Run(fmt.Sprintf("%T", testcase.event), func(t *testing.T) {
a, err := MarshalAny(testcase.event)
if err != nil {
t.Fatal(err)
}
if a.TypeUrl != testcase.url {
t.Fatalf("unexpected url: %v != %v", a.TypeUrl, testcase.url)
}
v, err := UnmarshalAny(a)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(v, testcase.event) {
t.Fatalf("round trip failed %v != %v", v, testcase.event)
}
})
}
}
func BenchmarkMarshalEvent(b *testing.B) {
ev := &eventsapi.TaskStart{}
expected, err := MarshalAny(ev)
if err != nil {
b.Fatal(err)
}
for i := 0; i < b.N; i++ {
a, err := MarshalAny(ev)
if err != nil {
b.Fatal(err)
}
if a.TypeUrl != expected.TypeUrl {
b.Fatalf("incorrect type url: %v != %v", a, expected)
}
}
}

View File

@ -41,7 +41,7 @@ func loadContainers(ctx context.Context, h *hcs.HCS, sendEvent eventCallback) ([
return containers, nil
}
func newContainer(ctx context.Context, h *hcs.HCS, id string, spec RuntimeSpec, io runtime.IO, sendEvent eventCallback) (*container, error) {
func newContainer(ctx context.Context, h *hcs.HCS, id string, spec *RuntimeSpec, io runtime.IO, sendEvent eventCallback) (*container, error) {
cio, err := hcs.NewIO(io.Stdin, io.Stdout, io.Stderr, io.Terminal)
if err != nil {
return nil, err

View File

@ -4,7 +4,6 @@ package windows
import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
@ -15,6 +14,7 @@ import (
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/typeurl"
"github.com/containerd/containerd/windows/hcs"
"github.com/containerd/containerd/windows/pid"
specs "github.com/opencontainers/runtime-spec/specs-go"
@ -34,6 +34,7 @@ func init() {
Type: plugin.RuntimePlugin,
Init: New,
})
typeurl.Register(&RuntimeSpec{}, "windows/Spec")
}
func New(ic *plugin.InitContext) (interface{}, error) {
@ -107,11 +108,11 @@ func (r *Runtime) ID() string {
}
func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts) (runtime.Task, error) {
var rtSpec RuntimeSpec
if err := json.Unmarshal(opts.Spec, &rtSpec); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal oci spec")
v, err := typeurl.UnmarshalAny(opts.Spec)
if err != nil {
return nil, err
}
rtSpec := v.(*RuntimeSpec)
ctr, err := newContainer(ctx, r.hcs, id, rtSpec, opts.IO, r.sendEvent)
if err != nil {
return nil, err