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

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

View File

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

View File

@ -7,6 +7,7 @@ import (
"log" "log"
"net/http" "net/http"
"runtime" "runtime"
"strconv"
"sync" "sync"
"time" "time"
@ -31,9 +32,11 @@ import (
imagesservice "github.com/containerd/containerd/services/images" imagesservice "github.com/containerd/containerd/services/images"
snapshotservice "github.com/containerd/containerd/services/snapshot" snapshotservice "github.com/containerd/containerd/services/snapshot"
"github.com/containerd/containerd/snapshot" "github.com/containerd/containerd/snapshot"
"github.com/containerd/containerd/typeurl"
pempty "github.com/golang/protobuf/ptypes/empty" pempty "github.com/golang/protobuf/ptypes/empty"
"github.com/opencontainers/image-spec/identity" "github.com/opencontainers/image-spec/identity"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors" "github.com/pkg/errors"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/grpclog" "google.golang.org/grpc/grpclog"
@ -43,6 +46,13 @@ import (
func init() { func init() {
// reset the grpc logger so that it does not output in the STDIO of the calling process // 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)) 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 { type clientOpts struct {

View File

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

View File

@ -10,13 +10,11 @@ import (
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/containerd/console" "github.com/containerd/console"
"github.com/containerd/containerd" "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/api/services/tasks/v1"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/mount" "github.com/containerd/containerd/mount"
"github.com/containerd/containerd/windows" "github.com/containerd/containerd/windows"
"github.com/containerd/containerd/windows/hcs" "github.com/containerd/containerd/windows/hcs"
protobuf "github.com/gogo/protobuf/types"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go" 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) 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) { func newCreateTaskRequest(context *cli.Context, id, tmpDir string, checkpoint *ocispec.Descriptor, mounts []mount.Mount) (*tasks.CreateTaskRequest, error) {
create := &tasks.CreateTaskRequest{ create := &tasks.CreateTaskRequest{
ContainerID: id, ContainerID: id,

View File

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

View File

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

View File

@ -17,7 +17,7 @@ type Container struct {
Labels map[string]string Labels map[string]string
Image string Image string
Runtime RuntimeInfo Runtime RuntimeInfo
Spec []byte Spec *types.Any
RootFS string RootFS string
CreatedAt time.Time CreatedAt time.Time
UpdatedAt 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/api/services/events/v1"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/typeurl"
goevents "github.com/docker/go-events" goevents "github.com/docker/go-events"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -35,7 +36,7 @@ func (s *eventSink) Write(evt goevents.Event) error {
return nil return nil
} }
eventData, err := MarshalEvent(e.event) eventData, err := typeurl.MarshalAny(e.event)
if err != nil { if err != nil {
return err return err
} }

View File

@ -15,7 +15,7 @@ const (
MediaTypeContainerd1CheckpointPreDump = "application/vnd.containerd.container.criu.checkpoint.predump.tar" MediaTypeContainerd1CheckpointPreDump = "application/vnd.containerd.container.criu.checkpoint.predump.tar"
MediaTypeContainerd1Resource = "application/vnd.containerd.container.resource.tar" MediaTypeContainerd1Resource = "application/vnd.containerd.container.resource.tar"
MediaTypeContainerd1RW = "application/vnd.containerd.container.rw.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 // Legacy Docker schema1 manifest
MediaTypeDockerSchema1Manifest = "application/vnd.docker.distribution.manifest.v1+prettyjws" MediaTypeDockerSchema1Manifest = "application/vnd.docker.distribution.manifest.v1+prettyjws"
) )

View File

@ -6,7 +6,6 @@ import (
"bytes" "bytes"
"context" "context"
"io" "io"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -82,11 +81,6 @@ func (b *bundle) Connect(ctx context.Context, remote bool) (*client.Client, erro
}, opt) }, 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 // Delete deletes the bundle from disk
func (b *bundle) Delete() error { func (b *bundle) Delete() error {
return os.RemoveAll(b.path) return os.RemoveAll(b.path)

View File

@ -1,33 +1,14 @@
package runcopts package runcopts
import ( import (
"path/filepath"
tasks "github.com/containerd/containerd/api/services/tasks/v1" tasks "github.com/containerd/containerd/api/services/tasks/v1"
"github.com/gogo/protobuf/proto" "github.com/containerd/containerd/typeurl"
protobuf "github.com/gogo/protobuf/types"
) )
const URIBase = "types.containerd.io/linux/runc"
func WithExit(r *tasks.CheckpointTaskRequest) error { func WithExit(r *tasks.CheckpointTaskRequest) error {
a, err := marshal(&CheckpointOptions{ a, err := typeurl.MarshalAny(&CheckpointOptions{
Exit: true, Exit: true,
}, "CheckpointOptions") })
if err != nil { r.Options = a
return err 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
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@ type IO struct {
type CreateOpts struct { type CreateOpts struct {
// Spec is the OCI runtime spec // Spec is the OCI runtime spec
Spec []byte Spec *types.Any
// Rootfs mounts to perform to gain access to the container's filesystem // Rootfs mounts to perform to gain access to the container's filesystem
Rootfs []mount.Mount Rootfs []mount.Mount
// IO for the container's main process // IO for the container's main process

View File

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

View File

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

View File

@ -24,9 +24,7 @@ import (
"github.com/containerd/containerd/mount" "github.com/containerd/containerd/mount"
"github.com/containerd/containerd/plugin" "github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime"
protobuf "github.com/gogo/protobuf/types"
google_protobuf "github.com/golang/protobuf/ptypes/empty" google_protobuf "github.com/golang/protobuf/ptypes/empty"
specs "github.com/opencontainers/image-spec/specs-go"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -249,10 +247,6 @@ func taskFromContainerd(ctx context.Context, c runtime.Task) (*task.Task, error)
ContainerID: c.Info().ContainerID, ContainerID: c.Info().ContainerID,
Pid: state.Pid, Pid: state.Pid,
Status: status, Status: status,
Spec: &protobuf.Any{
TypeUrl: specs.Version,
Value: c.Info().Spec,
},
Stdin: state.Stdin, Stdin: state.Stdin,
Stdout: state.Stdout, Stdout: state.Stdout,
Stderr: state.Stderr, Stderr: state.Stderr,
@ -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) { 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 { if err != nil {
return nil, err return nil, err
} }
@ -428,7 +426,11 @@ func (s *Service) Checkpoint(ctx context.Context, r *api.CheckpointTaskRequest)
return nil, err return nil, err
} }
// write the config to the content store // 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) specD, err := s.writeContent(ctx, images.MediaTypeContainerd1CheckpointConfig, filepath.Join(image, "spec"), spec)
if err != nil { if err != nil {
return nil, err return nil, err
@ -472,19 +474,17 @@ func (s *Service) writeContent(ctx context.Context, mediaType, ref string, r io.
}, nil }, 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 var container containers.Container
if err := s.db.View(func(tx *bolt.Tx) error { if err := s.db.View(func(tx *bolt.Tx) error {
store := metadata.NewContainerStore(tx) store := metadata.NewContainerStore(tx)
var err error var err error
container, err = store.Get(ctx, id) container, err = store.Get(ctx, id)
return err return err
}); err != nil { }); 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) { 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 { if err != nil {
return nil, err 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) runtime, err := s.getRuntime(container.Runtime.Name)
if err != nil { 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, container.ID)
t, err := runtime.Get(ctx, id)
if err != nil { 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 return t, nil
} }
func (s *Service) getRuntime(name string) (runtime.Runtime, error) { 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/containers/v1"
"github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/api/services/tasks/v1"
"github.com/containerd/containerd/images" "github.com/containerd/containerd/images"
protobuf "github.com/gogo/protobuf/types" "github.com/containerd/containerd/typeurl"
"github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go" 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 { func WithSpec(spec *specs.Spec) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error { return func(ctx context.Context, client *Client, c *containers.Container) error {
data, err := json.Marshal(spec) any, err := typeurl.MarshalAny(spec)
if err != nil { if err != nil {
return err return err
} }
c.Spec = &protobuf.Any{ c.Spec = any
TypeUrl: spec.Version,
Value: data,
}
return nil return nil
} }
} }
func WithResources(resources *specs.LinuxResources) UpdateTaskOpts { func WithResources(resources *specs.LinuxResources) UpdateTaskOpts {
return func(ctx context.Context, client *Client, r *tasks.UpdateTaskRequest) error { return func(ctx context.Context, client *Client, r *tasks.UpdateTaskRequest) error {
data, err := json.Marshal(resources) any, err := typeurl.MarshalAny(resources)
if err != nil { if err != nil {
return err return err
} }
r.Resources = &protobuf.Any{ r.Resources = any
TypeUrl: specs.Version,
Value: data,
}
return nil return nil
} }
} }

View File

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

18
task.go
View File

@ -14,9 +14,9 @@ import (
eventsapi "github.com/containerd/containerd/api/services/events/v1" eventsapi "github.com/containerd/containerd/api/services/events/v1"
"github.com/containerd/containerd/api/services/tasks/v1" "github.com/containerd/containerd/api/services/tasks/v1"
"github.com/containerd/containerd/content" "github.com/containerd/containerd/content"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/rootfs" "github.com/containerd/containerd/rootfs"
"github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/typeurl"
"github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/image-spec/specs-go/v1"
specs "github.com/opencontainers/runtime-spec/specs-go" specs "github.com/opencontainers/runtime-spec/specs-go"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -149,38 +149,32 @@ 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 // 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) { 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{}) eventstream, err := t.client.EventService().Stream(ctx, &eventsapi.StreamEventsRequest{})
if err != nil { if err != nil {
return UnknownExitStatus, err return UnknownExitStatus, err
} }
<-t.pidSync <-t.pidSync
var e eventsapi.RuntimeEvent
for { for {
evt, err := eventstream.Recv() evt, err := eventstream.Recv()
if err != nil { if err != nil {
return UnknownExitStatus, err return UnknownExitStatus, err
} }
if typeurl.Is(evt.Event, &eventsapi.RuntimeEvent{}) {
if !events.Is(evt.Event, &eventsapi.RuntimeEvent{}) { v, err := typeurl.UnmarshalAny(evt.Event)
continue if err != nil {
}
if err := events.UnmarshalEvent(evt.Event, &e); err != nil {
return UnknownExitStatus, err return UnknownExitStatus, err
} }
e := v.(*eventsapi.RuntimeEvent)
if e.Type != eventsapi.RuntimeEvent_EXIT { if e.Type != eventsapi.RuntimeEvent_EXIT {
continue continue
} }
if e.ID == t.containerID && e.Pid == t.pid { if e.ID == t.containerID && e.Pid == t.pid {
return e.ExitStatus, nil return e.ExitStatus, nil
} }
} }
} }
}
// Delete deletes the task and its runtime state // Delete deletes the task and its runtime state
// it returns the exit status of the task and any errors that were encountered // it returns the exit status of the task and any errors that were encountered

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 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) cio, err := hcs.NewIO(io.Stdin, io.Stdout, io.Stderr, io.Terminal)
if err != nil { if err != nil {
return nil, err return nil, err

View File

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