Add event support to execution subsystem

The implementation relies on nats.io

Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
This commit is contained in:
Kenfe-Mickael Laventure 2016-12-11 11:07:32 -08:00
parent dd39b4dcf0
commit 2ef399b315
11 changed files with 441 additions and 125 deletions

View file

@ -113,7 +113,8 @@ func (*CreateContainerRequest) ProtoMessage() {}
func (*CreateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptorExecution, []int{1} } func (*CreateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptorExecution, []int{1} }
type CreateContainerResponse struct { type CreateContainerResponse struct {
Container *Container `protobuf:"bytes,1,opt,name=container" json:"container,omitempty"` Container *Container `protobuf:"bytes,1,opt,name=container" json:"container,omitempty"`
InitProcess *Process `protobuf:"bytes,2,opt,name=initProcess" json:"initProcess,omitempty"`
} }
func (m *CreateContainerResponse) Reset() { *m = CreateContainerResponse{} } func (m *CreateContainerResponse) Reset() { *m = CreateContainerResponse{} }
@ -347,11 +348,14 @@ func (this *CreateContainerResponse) GoString() string {
if this == nil { if this == nil {
return "nil" return "nil"
} }
s := make([]string, 0, 5) s := make([]string, 0, 6)
s = append(s, "&execution.CreateContainerResponse{") s = append(s, "&execution.CreateContainerResponse{")
if this.Container != nil { if this.Container != nil {
s = append(s, "Container: "+fmt.Sprintf("%#v", this.Container)+",\n") s = append(s, "Container: "+fmt.Sprintf("%#v", this.Container)+",\n")
} }
if this.InitProcess != nil {
s = append(s, "InitProcess: "+fmt.Sprintf("%#v", this.InitProcess)+",\n")
}
s = append(s, "}") s = append(s, "}")
return strings.Join(s, "") return strings.Join(s, "")
} }
@ -1182,6 +1186,16 @@ func (m *CreateContainerResponse) MarshalTo(dAtA []byte) (int, error) {
} }
i += n1 i += n1
} }
if m.InitProcess != nil {
dAtA[i] = 0x12
i++
i = encodeVarintExecution(dAtA, i, uint64(m.InitProcess.Size()))
n2, err := m.InitProcess.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n2
}
return i, nil return i, nil
} }
@ -1297,11 +1311,11 @@ func (m *StartProcessRequest) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x12 dAtA[i] = 0x12
i++ i++
i = encodeVarintExecution(dAtA, i, uint64(m.Process.Size())) i = encodeVarintExecution(dAtA, i, uint64(m.Process.Size()))
n2, err := m.Process.MarshalTo(dAtA[i:]) n3, err := m.Process.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n2 i += n3
} }
if m.Console { if m.Console {
dAtA[i] = 0x18 dAtA[i] = 0x18
@ -1353,11 +1367,11 @@ func (m *StartProcessResponse) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa dAtA[i] = 0xa
i++ i++
i = encodeVarintExecution(dAtA, i, uint64(m.Process.Size())) i = encodeVarintExecution(dAtA, i, uint64(m.Process.Size()))
n3, err := m.Process.MarshalTo(dAtA[i:]) n4, err := m.Process.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n3 i += n4
} }
return i, nil return i, nil
} }
@ -1457,11 +1471,11 @@ func (m *Process) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x2a dAtA[i] = 0x2a
i++ i++
i = encodeVarintExecution(dAtA, i, uint64(m.User.Size())) i = encodeVarintExecution(dAtA, i, uint64(m.User.Size()))
n4, err := m.User.MarshalTo(dAtA[i:]) n5, err := m.User.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n4 i += n5
} }
if len(m.Cwd) > 0 { if len(m.Cwd) > 0 {
dAtA[i] = 0x32 dAtA[i] = 0x32
@ -1513,21 +1527,21 @@ func (m *User) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintExecution(dAtA, i, uint64(m.Gid)) i = encodeVarintExecution(dAtA, i, uint64(m.Gid))
} }
if len(m.AdditionalGids) > 0 { if len(m.AdditionalGids) > 0 {
dAtA6 := make([]byte, len(m.AdditionalGids)*10) dAtA7 := make([]byte, len(m.AdditionalGids)*10)
var j5 int var j6 int
for _, num := range m.AdditionalGids { for _, num := range m.AdditionalGids {
for num >= 1<<7 { for num >= 1<<7 {
dAtA6[j5] = uint8(uint64(num)&0x7f | 0x80) dAtA7[j6] = uint8(uint64(num)&0x7f | 0x80)
num >>= 7 num >>= 7
j5++ j6++
} }
dAtA6[j5] = uint8(num) dAtA7[j6] = uint8(num)
j5++ j6++
} }
dAtA[i] = 0x1a dAtA[i] = 0x1a
i++ i++
i = encodeVarintExecution(dAtA, i, uint64(j5)) i = encodeVarintExecution(dAtA, i, uint64(j6))
i += copy(dAtA[i:], dAtA6[:j5]) i += copy(dAtA[i:], dAtA7[:j6])
} }
return i, nil return i, nil
} }
@ -1575,11 +1589,11 @@ func (m *GetContainerResponse) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa dAtA[i] = 0xa
i++ i++
i = encodeVarintExecution(dAtA, i, uint64(m.Container.Size())) i = encodeVarintExecution(dAtA, i, uint64(m.Container.Size()))
n7, err := m.Container.MarshalTo(dAtA[i:]) n8, err := m.Container.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n7 i += n8
} }
return i, nil return i, nil
} }
@ -1711,11 +1725,11 @@ func (m *GetProcessResponse) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa dAtA[i] = 0xa
i++ i++
i = encodeVarintExecution(dAtA, i, uint64(m.Process.Size())) i = encodeVarintExecution(dAtA, i, uint64(m.Process.Size()))
n8, err := m.Process.MarshalTo(dAtA[i:]) n9, err := m.Process.MarshalTo(dAtA[i:])
if err != nil { if err != nil {
return 0, err return 0, err
} }
i += n8 i += n9
} }
return i, nil return i, nil
} }
@ -1912,6 +1926,10 @@ func (m *CreateContainerResponse) Size() (n int) {
l = m.Container.Size() l = m.Container.Size()
n += 1 + l + sovExecution(uint64(l)) n += 1 + l + sovExecution(uint64(l))
} }
if m.InitProcess != nil {
l = m.InitProcess.Size()
n += 1 + l + sovExecution(uint64(l))
}
return n return n
} }
@ -2238,6 +2256,7 @@ func (this *CreateContainerResponse) String() string {
} }
s := strings.Join([]string{`&CreateContainerResponse{`, s := strings.Join([]string{`&CreateContainerResponse{`,
`Container:` + strings.Replace(fmt.Sprintf("%v", this.Container), "Container", "Container", 1) + `,`, `Container:` + strings.Replace(fmt.Sprintf("%v", this.Container), "Container", "Container", 1) + `,`,
`InitProcess:` + strings.Replace(fmt.Sprintf("%v", this.InitProcess), "Process", "Process", 1) + `,`,
`}`, `}`,
}, "") }, "")
return s return s
@ -2817,6 +2836,39 @@ func (m *CreateContainerResponse) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field InitProcess", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowExecution
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthExecution
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.InitProcess == nil {
m.InitProcess = &Process{}
}
if err := m.InitProcess.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipExecution(dAtA[iNdEx:]) skippy, err := skipExecution(dAtA[iNdEx:])
@ -5035,67 +5087,68 @@ var (
func init() { proto.RegisterFile("execution.proto", fileDescriptorExecution) } func init() { proto.RegisterFile("execution.proto", fileDescriptorExecution) }
var fileDescriptorExecution = []byte{ var fileDescriptorExecution = []byte{
// 992 bytes of a gzipped FileDescriptorProto // 1007 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x56, 0xdd, 0x6e, 0xe3, 0x44, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x56, 0xdd, 0x6e, 0xe3, 0x44,
0x14, 0xae, 0xf3, 0xdb, 0x9c, 0xac, 0x77, 0xc3, 0x34, 0x35, 0x56, 0x40, 0x69, 0x31, 0xbb, 0x4b, 0x14, 0xae, 0xf3, 0xdb, 0x9c, 0xac, 0x77, 0xc3, 0x34, 0x35, 0x56, 0x40, 0x69, 0x31, 0xbb, 0x4b,
0x85, 0x68, 0x5a, 0x02, 0x42, 0x48, 0x5c, 0x6d, 0x9b, 0x10, 0x22, 0x95, 0x90, 0x9d, 0x6c, 0xb4, 0x85, 0x68, 0x5a, 0x02, 0x42, 0x2b, 0x71, 0xb5, 0x6d, 0x42, 0x88, 0x54, 0x42, 0x98, 0x6c, 0xb4,
0x12, 0x37, 0x95, 0x1b, 0x0f, 0x59, 0x4b, 0xa9, 0x1d, 0x3c, 0x76, 0xb7, 0xdc, 0xf1, 0x08, 0xbc, 0x12, 0x37, 0x95, 0x1b, 0x0f, 0x59, 0x4b, 0xa9, 0x1d, 0x3c, 0xe3, 0x6e, 0xb9, 0xe3, 0x9e, 0x1b,
0x00, 0x0f, 0xc1, 0x5b, 0xec, 0x25, 0xdc, 0x21, 0x21, 0x55, 0x34, 0x4f, 0xc0, 0x23, 0xa0, 0xf9, 0x5e, 0x80, 0x87, 0xe0, 0x2d, 0xf6, 0x12, 0xee, 0x90, 0x90, 0x2a, 0x9a, 0x27, 0xe0, 0x11, 0xd0,
0xb1, 0xf3, 0x63, 0xe7, 0x47, 0x85, 0xed, 0xdd, 0xcc, 0xf1, 0x37, 0x67, 0xbe, 0x73, 0x8e, 0xcf, 0x8c, 0xc7, 0xce, 0x8f, 0x9d, 0x1f, 0x15, 0xe8, 0xdd, 0xcc, 0x99, 0x6f, 0xce, 0x7c, 0xe7, 0xcc,
0x37, 0x07, 0x1e, 0x91, 0x6b, 0x32, 0x08, 0x7c, 0xdb, 0x75, 0x6a, 0x63, 0xcf, 0xf5, 0x5d, 0xa4, 0x9c, 0x6f, 0x0e, 0x3c, 0x22, 0xd7, 0x64, 0xe0, 0x33, 0xdb, 0x75, 0x6a, 0x63, 0xcf, 0x65, 0x2e,
0x0e, 0x5c, 0xc7, 0x37, 0x6d, 0x87, 0x78, 0x56, 0xed, 0xea, 0xd3, 0xca, 0x7b, 0x43, 0xd7, 0x1d, 0x52, 0x07, 0xae, 0xc3, 0x4c, 0xdb, 0x21, 0x9e, 0x55, 0xbb, 0xfa, 0xb8, 0xf2, 0xce, 0xd0, 0x75,
0x8e, 0xc8, 0x11, 0xff, 0x78, 0x11, 0xfc, 0x70, 0x44, 0x2e, 0xc7, 0xfe, 0x4f, 0x02, 0x5b, 0x29, 0x87, 0x23, 0x72, 0x24, 0x16, 0x2f, 0xfc, 0xef, 0x8e, 0xc8, 0xe5, 0x98, 0xfd, 0x10, 0x60, 0x2b,
0x0f, 0xdd, 0xa1, 0xcb, 0x97, 0x47, 0x6c, 0x25, 0xac, 0xc6, 0x11, 0xec, 0xf6, 0x7c, 0xd3, 0xf3, 0xe5, 0xa1, 0x3b, 0x74, 0xc5, 0xf0, 0x88, 0x8f, 0x02, 0xab, 0x71, 0x04, 0xbb, 0x3d, 0x66, 0x7a,
0x4f, 0x43, 0x47, 0x98, 0xfc, 0x18, 0x10, 0xea, 0x23, 0x0d, 0x52, 0xb6, 0xa5, 0x2b, 0xfb, 0xca, 0xec, 0x34, 0x74, 0x84, 0xc9, 0xf7, 0x3e, 0xa1, 0x0c, 0x69, 0x90, 0xb2, 0x2d, 0x5d, 0xd9, 0x57,
0x41, 0xe1, 0x24, 0x37, 0xb9, 0xd9, 0x4b, 0xb5, 0x1b, 0x38, 0x65, 0x5b, 0xc6, 0x6f, 0x0a, 0x68, 0x0e, 0x0a, 0x27, 0xb9, 0xc9, 0xcd, 0x5e, 0xaa, 0xdd, 0xc0, 0x29, 0xdb, 0x32, 0x7e, 0x55, 0x40,
0xa7, 0x1e, 0x31, 0x7d, 0xb2, 0xe9, 0x11, 0xb4, 0x07, 0xc5, 0x8b, 0xc0, 0xb1, 0x46, 0xe4, 0x7c, 0x3b, 0xf5, 0x88, 0xc9, 0xc8, 0xa6, 0x5b, 0xd0, 0x1e, 0x14, 0x2f, 0x7c, 0xc7, 0x1a, 0x91, 0xf3,
0x6c, 0xfa, 0xaf, 0xf4, 0x14, 0x03, 0x60, 0x10, 0xa6, 0xae, 0xe9, 0xbf, 0x42, 0x3a, 0xe4, 0x07, 0xb1, 0xc9, 0x5e, 0xe9, 0x29, 0x0e, 0xc0, 0x10, 0x98, 0xba, 0x26, 0x7b, 0x85, 0x74, 0xc8, 0x0f,
0xae, 0x43, 0xdd, 0x11, 0xd1, 0xd3, 0xfb, 0xca, 0xc1, 0x36, 0x0e, 0xb7, 0xa8, 0x0c, 0x59, 0xea, 0x5c, 0x87, 0xba, 0x23, 0xa2, 0xa7, 0xf7, 0x95, 0x83, 0x6d, 0x1c, 0x4e, 0x51, 0x19, 0xb2, 0x94,
0x5b, 0xb6, 0xa3, 0x67, 0xf8, 0x21, 0xb1, 0x41, 0x1a, 0xe4, 0xa8, 0x6f, 0xb9, 0x81, 0xaf, 0x67, 0x59, 0xb6, 0xa3, 0x67, 0xc4, 0xa6, 0x60, 0x82, 0x34, 0xc8, 0x51, 0x66, 0xb9, 0x3e, 0xd3, 0xb3,
0xb9, 0x59, 0xee, 0xa4, 0x9d, 0x78, 0x9e, 0x9e, 0x8b, 0xec, 0xc4, 0xf3, 0x8c, 0xe7, 0xf0, 0x6e, 0xc2, 0x2c, 0x67, 0xd2, 0x4e, 0x3c, 0x4f, 0xcf, 0x45, 0x76, 0xe2, 0x79, 0xc6, 0x4f, 0x0a, 0xbc,
0x8c, 0x32, 0x1d, 0xbb, 0x0e, 0x25, 0xe8, 0x0b, 0x28, 0x44, 0x39, 0xe4, 0xd4, 0x8b, 0x75, 0xbd, 0x1d, 0xe3, 0x4c, 0xc7, 0xae, 0x43, 0x09, 0xfa, 0x0c, 0x0a, 0x51, 0x12, 0x05, 0xf7, 0x62, 0x5d,
0x36, 0x97, 0xd5, 0xda, 0xf4, 0xd0, 0x14, 0x6a, 0x1c, 0x83, 0xd6, 0x20, 0x23, 0xb2, 0x79, 0x16, 0xaf, 0xcd, 0xa5, 0xb5, 0x36, 0xdd, 0x34, 0x85, 0xa2, 0x67, 0x50, 0xb4, 0x1d, 0x9b, 0x75, 0x3d,
0x8c, 0x43, 0xd8, 0x3d, 0xb3, 0xe9, 0x34, 0xd1, 0x34, 0x3c, 0x50, 0x86, 0xac, 0xfb, 0x5a, 0x5c, 0x77, 0x40, 0x28, 0x15, 0x41, 0x15, 0xeb, 0xda, 0xc2, 0x4e, 0xb9, 0x8a, 0x67, 0xa1, 0xc6, 0x31,
0x9f, 0x66, 0x31, 0xf2, 0x8d, 0x81, 0x41, 0x5b, 0x84, 0x4b, 0xca, 0x5f, 0x02, 0x44, 0x3c, 0x28, 0x68, 0x0d, 0x32, 0x22, 0x9b, 0x27, 0xd0, 0x38, 0x84, 0xdd, 0x33, 0x9b, 0x4e, 0xef, 0x88, 0x86,
0x3f, 0xb4, 0x8a, 0xf3, 0x0c, 0xd6, 0xf8, 0x4b, 0x81, 0x1d, 0x5e, 0xed, 0xae, 0xe7, 0x0e, 0x08, 0x1b, 0xca, 0x90, 0x75, 0x5f, 0x07, 0xc4, 0xd3, 0x3c, 0x3d, 0x62, 0x62, 0x60, 0xd0, 0x16, 0xe1,
0x8d, 0x18, 0xd4, 0xe1, 0x41, 0x84, 0x3a, 0x8f, 0xc8, 0x3f, 0x9a, 0xdc, 0xec, 0x15, 0x23, 0x47, 0x32, 0xd8, 0x67, 0x00, 0x11, 0x41, 0x2a, 0x36, 0xad, 0x8a, 0x76, 0x06, 0x6b, 0xfc, 0xa9, 0xc0,
0xed, 0x06, 0x2e, 0x46, 0xa0, 0xb6, 0x85, 0x8e, 0x21, 0x3f, 0x16, 0x5e, 0x78, 0x41, 0x8b, 0x75, 0x8e, 0x78, 0x28, 0x61, 0x48, 0x92, 0x41, 0x1d, 0x1e, 0x44, 0xa8, 0xf3, 0x88, 0xfc, 0xa3, 0xc9,
0x6d, 0x81, 0x42, 0x78, 0x47, 0x08, 0x7b, 0xeb, 0x55, 0xfe, 0x06, 0xca, 0xf3, 0xc1, 0xc9, 0x7c, 0xcd, 0x5e, 0x31, 0x72, 0xd4, 0x6e, 0xe0, 0x62, 0x04, 0x6a, 0x5b, 0xe8, 0x18, 0xf2, 0xe3, 0x8d,
0xcd, 0x30, 0x55, 0x36, 0x62, 0x6a, 0x50, 0x28, 0x44, 0x71, 0xdf, 0xfd, 0xaf, 0x3e, 0x64, 0x3c, 0xd2, 0x16, 0xc2, 0xfe, 0xf7, 0x07, 0xf2, 0x25, 0x94, 0xe7, 0x83, 0x93, 0xf9, 0x9a, 0x61, 0xaa,
0x4d, 0x3f, 0xa0, 0x3c, 0xac, 0x87, 0xf5, 0xdd, 0x85, 0x6b, 0x7b, 0xfc, 0x23, 0x96, 0x20, 0xe3, 0x6c, 0xc4, 0xd4, 0xa0, 0x50, 0x88, 0xe2, 0xbe, 0x7b, 0x41, 0x1c, 0x72, 0x9e, 0x26, 0xf3, 0xa9,
0x0f, 0x05, 0xf2, 0x92, 0xc9, 0xd2, 0x3b, 0x4b, 0x90, 0x1e, 0xdb, 0x16, 0xbf, 0x2b, 0x8d, 0xd9, 0x08, 0xeb, 0x61, 0x7d, 0x77, 0xe1, 0xd8, 0x9e, 0x58, 0xc4, 0x12, 0x64, 0xfc, 0xae, 0x40, 0x5e,
0x12, 0x21, 0xc8, 0x98, 0xde, 0x90, 0xea, 0x69, 0xfe, 0xef, 0xf0, 0x35, 0x43, 0x11, 0xe7, 0x4a, 0x32, 0x59, 0x7a, 0x66, 0x09, 0xd2, 0x63, 0xdb, 0x12, 0x67, 0xa5, 0x31, 0x1f, 0x22, 0x04, 0x19,
0xcf, 0x70, 0x13, 0x5b, 0xa2, 0x8f, 0x20, 0x13, 0x50, 0xe2, 0xf1, 0x44, 0x16, 0xeb, 0x3b, 0x0b, 0xd3, 0x1b, 0x52, 0x3d, 0x2d, 0xde, 0x8e, 0x18, 0x73, 0x14, 0x71, 0xae, 0xf4, 0x8c, 0x30, 0xf1,
0x44, 0xfa, 0x94, 0x78, 0x98, 0x03, 0xd8, 0xd1, 0xc1, 0x6b, 0x4b, 0x26, 0x96, 0x2d, 0x51, 0x05, 0x21, 0xfa, 0x00, 0x32, 0x3e, 0x25, 0x9e, 0x48, 0x64, 0xb1, 0xbe, 0xb3, 0x40, 0xa4, 0x4f, 0x89,
0xb6, 0x7d, 0xe2, 0x5d, 0xda, 0x8e, 0x39, 0xd2, 0xf3, 0xbc, 0x6c, 0xd1, 0x9e, 0xa5, 0x80, 0x5c, 0x87, 0x05, 0x80, 0x6f, 0x1d, 0xbc, 0xb6, 0x64, 0x62, 0xf9, 0x10, 0x55, 0x60, 0x9b, 0x11, 0xef,
0xdb, 0xfe, 0xb9, 0x0c, 0x73, 0x7b, 0x5f, 0x39, 0x50, 0x31, 0x30, 0x93, 0x88, 0xcd, 0xc0, 0x90, 0xd2, 0x76, 0xcc, 0x91, 0x9e, 0x17, 0xd7, 0x16, 0xcd, 0x79, 0x0a, 0xc8, 0xb5, 0xcd, 0xce, 0x65,
0xe9, 0x4b, 0xb7, 0x81, 0x0c, 0x48, 0xc5, 0x6c, 0xc9, 0x2c, 0x43, 0x19, 0x89, 0x8a, 0xd9, 0x12, 0x98, 0xdb, 0xfb, 0xca, 0x81, 0x8a, 0x81, 0x9b, 0x82, 0xd8, 0x0c, 0x0c, 0x99, 0xbe, 0x74, 0xeb,
0x3d, 0x85, 0x87, 0xa6, 0x65, 0xd9, 0x4c, 0xdd, 0xcc, 0x51, 0xcb, 0xb6, 0x44, 0x4c, 0x2a, 0x5e, 0xcb, 0x80, 0x54, 0xcc, 0x87, 0xdc, 0x32, 0x94, 0x91, 0xa8, 0x98, 0x0f, 0xd1, 0x53, 0x78, 0x68,
0xb0, 0x1a, 0x87, 0xb0, 0xd3, 0x22, 0x9b, 0xeb, 0x55, 0x07, 0xca, 0xf3, 0xf0, 0xff, 0xd8, 0xf8, 0x5a, 0x96, 0xcd, 0x85, 0xd1, 0x1c, 0xb5, 0x6c, 0x2b, 0x88, 0x49, 0xc5, 0x0b, 0x56, 0xe3, 0x10,
0x97, 0xa0, 0xf5, 0xc7, 0x56, 0x92, 0xfc, 0xdd, 0xa5, 0x8b, 0xd6, 0xfd, 0x44, 0x4c, 0x9f, 0xbb, 0x76, 0x5a, 0x64, 0x73, 0xa9, 0xeb, 0x40, 0x79, 0x1e, 0xfe, 0xef, 0x24, 0xc3, 0xb8, 0x04, 0xad,
0x66, 0x40, 0x37, 0x97, 0x99, 0x63, 0xd0, 0x30, 0xa1, 0xc1, 0xe5, 0xe6, 0x27, 0x02, 0x78, 0xa7, 0x3f, 0xb6, 0x92, 0x94, 0xf3, 0x2e, 0x55, 0xb4, 0xee, 0x11, 0x71, 0x69, 0xef, 0x9a, 0x3e, 0xdd,
0x45, 0xfe, 0x0f, 0x49, 0xf8, 0x04, 0x40, 0x76, 0xd0, 0xb9, 0x2c, 0x6d, 0xe1, 0x44, 0x9d, 0xdc, 0x5c, 0x66, 0x8e, 0x41, 0xc3, 0x84, 0xfa, 0x97, 0x9b, 0xef, 0xf0, 0xe1, 0xad, 0x16, 0xf9, 0x2f,
0xec, 0x15, 0xa4, 0xef, 0x76, 0x03, 0x17, 0x24, 0xa0, 0x6d, 0x19, 0x5f, 0x03, 0x9a, 0xbd, 0xf6, 0x24, 0xe1, 0x23, 0x00, 0x59, 0x41, 0xe7, 0xf2, 0x6a, 0x0b, 0x27, 0xea, 0xe4, 0x66, 0xaf, 0x20,
0xce, 0xcd, 0xfa, 0x8b, 0x02, 0xe5, 0x9e, 0x3d, 0x74, 0xcc, 0xd1, 0x7d, 0x87, 0xc0, 0x95, 0x88, 0x7d, 0xb7, 0x1b, 0xb8, 0x20, 0x01, 0x6d, 0xcb, 0xf8, 0x02, 0xd0, 0xec, 0xb1, 0x77, 0x2e, 0xd6,
0xdf, 0xcc, 0x05, 0x4d, 0xc5, 0x72, 0x67, 0x5c, 0x43, 0x59, 0x3c, 0x0e, 0xf7, 0x9e, 0xd4, 0x1a, 0x9f, 0x15, 0x28, 0xf7, 0xec, 0xa1, 0x63, 0x8e, 0xee, 0x3b, 0x04, 0xa1, 0x44, 0xe2, 0x64, 0x21,
0x94, 0xd9, 0xab, 0x21, 0xbf, 0x11, 0xba, 0xae, 0xf6, 0xdf, 0x8a, 0x47, 0x69, 0x06, 0x2f, 0xeb, 0x68, 0x2a, 0x96, 0x33, 0xe3, 0x1a, 0xca, 0xc1, 0xe7, 0x70, 0xef, 0x49, 0xad, 0x41, 0x99, 0xff,
0xf0, 0x39, 0x84, 0x5e, 0x49, 0xf8, 0xc6, 0x2c, 0xab, 0xc4, 0x14, 0xf8, 0xf1, 0x57, 0x90, 0x13, 0x1a, 0x72, 0x8d, 0xd0, 0x75, 0x77, 0xff, 0x55, 0xf0, 0x29, 0xcd, 0xe0, 0xe5, 0x3d, 0x7c, 0x0a,
0x9d, 0x8f, 0x8a, 0x90, 0x3f, 0xc5, 0xcd, 0x67, 0x2f, 0x9a, 0x8d, 0xd2, 0x16, 0xdb, 0xe0, 0x7e, 0xa1, 0x57, 0x12, 0xfe, 0x31, 0xcb, 0x6e, 0x62, 0x0a, 0xfc, 0xf0, 0x73, 0xc8, 0x05, 0x95, 0x8f,
0xa7, 0xd3, 0xee, 0xb4, 0x4a, 0x0a, 0xdb, 0xf4, 0x5e, 0x7c, 0xd7, 0xed, 0x36, 0x1b, 0xa5, 0x14, 0x8a, 0x90, 0x3f, 0xc5, 0xcd, 0xe7, 0x2f, 0x9a, 0x8d, 0xd2, 0x16, 0x9f, 0xe0, 0x7e, 0xa7, 0xd3,
0x02, 0xc8, 0x75, 0x9f, 0xf5, 0x7b, 0xcd, 0x46, 0x29, 0x5d, 0xff, 0x75, 0x1b, 0x4a, 0xcd, 0x70, 0xee, 0xb4, 0x4a, 0x0a, 0x9f, 0xf4, 0x5e, 0x7c, 0xdd, 0xed, 0x36, 0x1b, 0xa5, 0x14, 0x02, 0xc8,
0xc0, 0xe9, 0x11, 0xef, 0xca, 0x1e, 0x10, 0xf4, 0x12, 0x72, 0xe2, 0xe9, 0x46, 0x4f, 0x16, 0xbb, 0x75, 0x9f, 0xf7, 0x7b, 0xcd, 0x46, 0x29, 0x5d, 0xff, 0x65, 0x1b, 0x4a, 0xcd, 0xb0, 0x37, 0xea,
0x33, 0x71, 0x08, 0xa9, 0x3c, 0x5d, 0x07, 0x93, 0x01, 0x36, 0x21, 0xcb, 0x5f, 0x0b, 0xf4, 0x38, 0x11, 0xef, 0xca, 0x1e, 0x10, 0xf4, 0x12, 0x72, 0xc1, 0xa7, 0x8f, 0x9e, 0x2c, 0x56, 0x67, 0x62,
0x2e, 0xcb, 0xf1, 0x71, 0xa8, 0xa2, 0xd5, 0xc4, 0x6c, 0x55, 0x0b, 0x67, 0xab, 0x5a, 0x93, 0xcd, 0xff, 0x52, 0x79, 0xba, 0x0e, 0x26, 0x03, 0x6c, 0x42, 0x56, 0xfc, 0x16, 0xe8, 0x71, 0x5c, 0x96,
0x56, 0xa8, 0x05, 0x39, 0x21, 0x07, 0x31, 0x7e, 0xc9, 0x2a, 0xb1, 0xd4, 0x51, 0x13, 0xb2, 0xbc, 0xe3, 0x9d, 0x54, 0x45, 0xab, 0x05, 0x6d, 0x59, 0x2d, 0x6c, 0xcb, 0x6a, 0x4d, 0xde, 0x96, 0xa1,
0xd1, 0x63, 0x7c, 0x12, 0xdb, 0x7f, 0x15, 0x1f, 0xd1, 0xfe, 0x31, 0x3e, 0xc9, 0xaa, 0xb0, 0xca, 0x16, 0xe4, 0x02, 0x39, 0x88, 0xf1, 0x4b, 0x56, 0x89, 0xa5, 0x8e, 0x9a, 0x90, 0x15, 0x85, 0x1e,
0x91, 0xf8, 0x87, 0x63, 0x8e, 0x92, 0xe7, 0x9e, 0xa5, 0x8e, 0x3a, 0x90, 0x6e, 0x11, 0x1f, 0x19, 0xe3, 0x93, 0x58, 0xfe, 0xab, 0xf8, 0x04, 0xe5, 0x1f, 0xe3, 0x93, 0xac, 0x0a, 0xab, 0x1c, 0x05,
0x0b, 0x5e, 0x12, 0x34, 0xbc, 0xf2, 0xe1, 0x4a, 0x8c, 0x2c, 0x5c, 0x0f, 0x32, 0xec, 0x97, 0x8d, 0x6f, 0x38, 0xe6, 0x28, 0xb9, 0xef, 0x59, 0xea, 0xa8, 0x03, 0xe9, 0x16, 0x61, 0xc8, 0x58, 0xf0,
0xe5, 0x29, 0x71, 0xb8, 0xaa, 0x3c, 0x59, 0x83, 0x92, 0x4e, 0x5f, 0xc2, 0x83, 0xd9, 0xd9, 0x21, 0x92, 0xa0, 0xe1, 0x95, 0xf7, 0x57, 0x62, 0xe4, 0xc5, 0xf5, 0x20, 0xc3, 0x9f, 0x6c, 0x2c, 0x4f,
0xc6, 0x36, 0x61, 0x6a, 0x8a, 0xb1, 0x4d, 0x1c, 0x3e, 0x9e, 0x03, 0x4c, 0x55, 0x0e, 0xed, 0xc7, 0x89, 0xcd, 0x55, 0xe5, 0xc9, 0x1a, 0x94, 0x74, 0xfa, 0x12, 0x1e, 0xcc, 0xf6, 0x0e, 0x31, 0xb6,
0x03, 0x5c, 0x70, 0xfa, 0xc1, 0x0a, 0x84, 0x74, 0x79, 0x06, 0xea, 0x9c, 0xde, 0xa1, 0x18, 0x91, 0x09, 0x5d, 0x53, 0x8c, 0x6d, 0x62, 0xf3, 0xf1, 0x0d, 0xc0, 0x54, 0xe5, 0xd0, 0x7e, 0x3c, 0xc0,
0x04, 0x35, 0x5c, 0x5a, 0x9e, 0x33, 0x50, 0xe7, 0xb4, 0x2a, 0xe6, 0x2d, 0x49, 0xc9, 0x96, 0x7a, 0x05, 0xa7, 0xef, 0xad, 0x40, 0x48, 0x97, 0x67, 0xa0, 0xce, 0xe9, 0x1d, 0x8a, 0x11, 0x49, 0x50,
0xfb, 0x1e, 0xd4, 0x39, 0x3d, 0x89, 0x79, 0x4b, 0x52, 0xa7, 0xca, 0xe3, 0xd5, 0x20, 0x11, 0xf7, 0xc3, 0xa5, 0xd7, 0x73, 0x06, 0xea, 0x9c, 0x56, 0xc5, 0xbc, 0x25, 0x29, 0xd9, 0x52, 0x6f, 0xdf,
0xc9, 0xfb, 0x6f, 0x6e, 0xab, 0x5b, 0x7f, 0xde, 0x56, 0xb7, 0xfe, 0xb9, 0xad, 0x2a, 0x3f, 0x4f, 0x82, 0x3a, 0xa7, 0x27, 0x31, 0x6f, 0x49, 0xea, 0x54, 0x79, 0xbc, 0x1a, 0x14, 0xc4, 0x7d, 0xf2,
0xaa, 0xca, 0x9b, 0x49, 0x55, 0xf9, 0x7d, 0x52, 0x55, 0xfe, 0x9e, 0x54, 0x95, 0x8b, 0x1c, 0x67, 0xee, 0x9b, 0xdb, 0xea, 0xd6, 0x1f, 0xb7, 0xd5, 0xad, 0xbf, 0x6f, 0xab, 0xca, 0x8f, 0x93, 0xaa,
0xf2, 0xd9, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x3e, 0xf2, 0x89, 0x40, 0x24, 0x0d, 0x00, 0x00, 0xf2, 0x66, 0x52, 0x55, 0x7e, 0x9b, 0x54, 0x95, 0xbf, 0x26, 0x55, 0xe5, 0x22, 0x27, 0x98, 0x7c,
0xf2, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x83, 0x5f, 0xe2, 0xb2, 0x5f, 0x0d, 0x00, 0x00,
} }

View file

@ -38,6 +38,7 @@ message CreateContainerRequest {
message CreateContainerResponse { message CreateContainerResponse {
Container container = 1; Container container = 1;
Process initProcess = 2;
} }
message DeleteContainerRequest { message DeleteContainerRequest {

View file

@ -3,9 +3,14 @@ package main
import ( import (
"fmt" "fmt"
"net" "net"
"net/http"
"net/url"
"os" "os"
"os/signal" "os/signal"
"path/filepath" "path/filepath"
"runtime"
"strconv"
"strings"
"syscall" "syscall"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -15,8 +20,11 @@ import (
api "github.com/docker/containerd/api/execution" api "github.com/docker/containerd/api/execution"
"github.com/docker/containerd/execution" "github.com/docker/containerd/execution"
"github.com/docker/containerd/execution/executors/oci" "github.com/docker/containerd/execution/executors/oci"
// metrics "github.com/docker/go-metrics" metrics "github.com/docker/go-metrics"
"github.com/urfave/cli" "github.com/urfave/cli"
"github.com/nats-io/go-nats"
stand "github.com/nats-io/nats-streaming-server/server"
) )
func main() { func main() {
@ -57,6 +65,11 @@ high performance container runtime
Usage: "tcp address to serve metrics on", Usage: "tcp address to serve metrics on",
Value: "127.0.0.1:7897", Value: "127.0.0.1:7897",
}, },
cli.StringFlag{
Name: "events-address, e",
Usage: "nats address to serve events on",
Value: nats.DefaultURL,
},
} }
app.Before = func(context *cli.Context) error { app.Before = func(context *cli.Context) error {
if context.GlobalBool("debug") { if context.GlobalBool("debug") {
@ -66,11 +79,29 @@ high performance container runtime
} }
app.Action = func(context *cli.Context) error { app.Action = func(context *cli.Context) error {
signals := make(chan os.Signal, 2048) signals := make(chan os.Signal, 2048)
signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT) signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT, syscall.SIGUSR1)
// if address := context.GlobalString("metrics-address"); address != "" { if address := context.GlobalString("metrics-address"); address != "" {
// go serveMetrics(address) go serveMetrics(address)
// } }
eventsURL, err := url.Parse(context.GlobalString("events-address"))
if err != nil {
return err
}
no := stand.DefaultNatsServerOptions
nOpts := &no
nOpts.NoSigs = true
parts := strings.Split(eventsURL.Host, ":")
nOpts.Host = parts[0]
if len(parts) == 2 {
nOpts.Port, err = strconv.Atoi(parts[1])
} else {
nOpts.Port = nats.DefaultPort
}
s := stand.RunServerWithOpts(nil, nOpts)
defer s.Shutdown()
path := context.GlobalString("socket") path := context.GlobalString("socket")
if path == "" { if path == "" {
@ -84,10 +115,25 @@ high performance container runtime
var executor execution.Executor var executor execution.Executor
switch context.GlobalString("runtime") { switch context.GlobalString("runtime") {
case "runc": case "runc":
executor = oci.New(context.GlobalString("root")) executor, err = oci.New(context.GlobalString("root"))
if err != nil {
return err
}
} }
execService, err := execution.New(executor) // Start events listener
nc, err := nats.Connect(context.GlobalString("events-address"))
if err != nil {
return err
}
nec, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
if err != nil {
nc.Close()
return err
}
defer nec.Close()
execService, err := execution.New(executor, nec)
if err != nil { if err != nil {
return err return err
} }
@ -98,6 +144,8 @@ high performance container runtime
for s := range signals { for s := range signals {
switch s { switch s {
case syscall.SIGUSR1:
dumpStacks()
default: default:
logrus.WithField("signal", s).Info("containerd: stopping GRPC server") logrus.WithField("signal", s).Info("containerd: stopping GRPC server")
server.Stop() server.Stop()
@ -122,13 +170,13 @@ func createUnixSocket(path string) (net.Listener, error) {
return net.Listen("unix", path) return net.Listen("unix", path)
} }
// func serveMetrics(address string) { func serveMetrics(address string) {
// m := http.NewServeMux() m := http.NewServeMux()
// m.Handle("/metrics", metrics.Handler()) m.Handle("/metrics", metrics.Handler())
// if err := http.ListenAndServe(address, m); err != nil { if err := http.ListenAndServe(address, m); err != nil {
// logrus.WithError(err).Fatal("containerd: metrics server failure") logrus.WithError(err).Fatal("containerd: metrics server failure")
// } }
// } }
func serveGRPC(server *grpc.Server, l net.Listener) { func serveGRPC(server *grpc.Server, l net.Listener) {
defer l.Close() defer l.Close()
@ -137,3 +185,19 @@ func serveGRPC(server *grpc.Server, l net.Listener) {
logrus.WithError(err).Fatal("containerd: GRPC server failure") logrus.WithError(err).Fatal("containerd: GRPC server failure")
} }
} }
// DumpStacks dumps the runtime stack.
func dumpStacks() {
var (
buf []byte
stackSize int
)
bufferLen := 16384
for stackSize == len(buf) {
buf = make([]byte, bufferLen)
stackSize = runtime.Stack(buf, true)
bufferLen *= 2
}
buf = buf[:stackSize]
logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
}

View file

@ -4,11 +4,12 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"time"
gocontext "context" gocontext "context"
"github.com/docker/containerd/api/execution" "github.com/docker/containerd/api/execution"
execEvents "github.com/docker/containerd/execution"
"github.com/nats-io/go-nats"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -56,6 +57,27 @@ var runCommand = cli.Command{
return err return err
} }
// setup our event subscriber
nc, err := nats.Connect(nats.DefaultURL)
if err != nil {
return err
}
nec, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
if err != nil {
nc.Close()
return err
}
defer nec.Close()
evCh := make(chan *execEvents.ContainerExitEvent, 64)
sub, err := nec.Subscribe(execEvents.ContainersEventsSubjectSubscriber, func(e *execEvents.ContainerExitEvent) {
evCh <- e
})
if err != nil {
return err
}
defer sub.Unsubscribe()
tmpDir, err := getTempDir(id) tmpDir, err := getTempDir(id)
if err != nil { if err != nil {
return err return err
@ -87,18 +109,17 @@ var runCommand = cli.Command{
return err return err
} }
// wait for it to die var ec uint32
for { for {
gcr, err := executionService.Get(gocontext.Background(), &execution.GetContainerRequest{ e, more := <-evCh
ID: cr.Container.ID, if !more {
}) break
if err != nil { }
return err
} if e.ID == cr.Container.ID && e.PID == cr.InitProcess.ID {
if gcr.Container.Status != execution.Status_RUNNING { ec = e.StatusCode
break break
} }
time.Sleep(100 * time.Millisecond)
} }
if _, err := executionService.Delete(gocontext.Background(), &execution.DeleteContainerRequest{ if _, err := executionService.Delete(gocontext.Background(), &execution.DeleteContainerRequest{
@ -110,6 +131,8 @@ var runCommand = cli.Command{
// Ensure we read all io // Ensure we read all io
fwg.Wait() fwg.Wait()
os.Exit(int(ec))
return nil return nil
}, },
} }

View file

@ -2,7 +2,7 @@ package execution
import "fmt" import "fmt"
func NewContainer(stateRoot, id, bundle, status string) (*Container, error) { func NewContainer(stateRoot, id, bundle string) (*Container, error) {
stateDir, err := NewStateDir(stateRoot, id) stateDir, err := NewStateDir(stateRoot, id)
if err != nil { if err != nil {
return nil, err return nil, err
@ -11,7 +11,7 @@ func NewContainer(stateRoot, id, bundle, status string) (*Container, error) {
id: id, id: id,
bundle: bundle, bundle: bundle,
stateDir: stateDir, stateDir: stateDir,
status: status, status: "created",
processes: make(map[string]Process), processes: make(map[string]Process),
}, nil }, nil
} }

21
execution/events.go Normal file
View file

@ -0,0 +1,21 @@
package execution
type ContainerEvent struct {
ID string
Action string
}
type ContainerExitEvent struct {
ContainerEvent
PID string
StatusCode uint32
}
const (
ContainersEventsSubjectSubscriber = "containerd.execution.container.>"
)
const (
containerEventsSubjectFormat = "containerd.execution.container.%s"
containerProcessEventsSubjectFormat = "containerd.execution.container.%s.%s"
)

View file

@ -0,0 +1,61 @@
package oci
import (
"io"
"os"
"github.com/crosbymichael/go-runc"
)
type OIO struct {
master *os.File // master holds a fd to the created pty if any
console string // console holds the path the the slave linked to master
rio runc.IO // rio holds the open fifos for stdios
}
func newOIO(stdin, stdout, stderr string, console bool) (o OIO, err error) {
defer func() {
if err != nil {
o.cleanup()
}
}()
if o.rio.Stdin, err = os.OpenFile(stdin, os.O_RDONLY, 0); err != nil {
return
}
if o.rio.Stdout, err = os.OpenFile(stdout, os.O_WRONLY, 0); err != nil {
return
}
if o.rio.Stderr, err = os.OpenFile(stderr, os.O_WRONLY, 0); err != nil {
return
}
if console {
o.master, o.console, err = newConsole(0, 0)
if err != nil {
return
}
go io.Copy(o.master, o.rio.Stdin)
go func() {
io.Copy(o.rio.Stdout, o.master)
o.master.Close()
}()
}
return
}
func (o OIO) cleanup() {
if o.master != nil {
o.master.Close()
}
if o.rio.Stdin != nil {
o.rio.Stdin.(*os.File).Close()
}
if o.rio.Stdout != nil {
o.rio.Stdout.(*os.File).Close()
}
if o.rio.Stderr != nil {
o.rio.Stderr.(*os.File).Close()
}
}

View file

@ -14,23 +14,24 @@ import (
var ErrRootEmpty = errors.New("oci: runtime root cannot be an empty string") var ErrRootEmpty = errors.New("oci: runtime root cannot be an empty string")
func New(root string) *OCIRuntime { func New(root string) (*OCIRuntime, error) {
err := SetSubreaper(1)
if err != nil {
return nil, err
}
return &OCIRuntime{ return &OCIRuntime{
root: root, root: root,
runc: &runc.Runc{ runc: &runc.Runc{
Root: filepath.Join(root, "runc"), Root: filepath.Join(root, "runc"),
}, },
ios: make(map[string]OIO), ios: make(map[string]OIO),
} }, nil
} }
type OCIRuntime struct { type OCIRuntime struct {
// root holds runtime state information for the containers
root string root string
runc *runc.Runc runc *runc.Runc
ios map[string]OIO // ios tracks created process io for cleanup purpose on delete
// We need to keep track of the created IO for
ios map[string]OIO
} }
func (r *OCIRuntime) Create(ctx context.Context, id string, o execution.CreateOpts) (container *execution.Container, err error) { func (r *OCIRuntime) Create(ctx context.Context, id string, o execution.CreateOpts) (container *execution.Container, err error) {
@ -44,7 +45,7 @@ func (r *OCIRuntime) Create(ctx context.Context, id string, o execution.CreateOp
} }
}() }()
if container, err = execution.NewContainer(r.root, id, o.Bundle, "created"); err != nil { if container, err = execution.NewContainer(r.root, id, o.Bundle); err != nil {
return nil, err return nil, err
} }
defer func(c *execution.Container) { defer func(c *execution.Container) {
@ -141,11 +142,16 @@ func (r *OCIRuntime) List(ctx context.Context) ([]*execution.Container, error) {
var containers []*execution.Container var containers []*execution.Container
for _, c := range runcCs { for _, c := range runcCs {
container, err := r.load(c) select {
if err != nil { case <-ctx.Done():
return nil, err return nil, ctx.Err()
default:
container, err := r.load(c)
if err != nil {
return nil, err
}
containers = append(containers, container)
} }
containers = append(containers, container)
} }
return containers, nil return containers, nil

View file

@ -0,0 +1,43 @@
package oci
import (
"syscall"
"unsafe"
)
// PR_SET_CHILD_SUBREAPER allows setting the child subreaper.
// If arg2 is nonzero, set the "child subreaper" attribute of the
// calling process; if arg2 is zero, unset the attribute. When a
// process is marked as a child subreaper, all of the children
// that it creates, and their descendants, will be marked as
// having a subreaper. In effect, a subreaper fulfills the role
// of init(1) for its descendant processes. Upon termination of
// a process that is orphaned (i.e., its immediate parent has
// already terminated) and marked as having a subreaper, the
// nearest still living ancestor subreaper will receive a SIGCHLD
// signal and be able to wait(2) on the process to discover its
// termination status.
const prSetChildSubreaper = 36
// PR_GET_CHILD_SUBREAPER allows retrieving the current child
// subreaper.
// Return the "child subreaper" setting of the caller, in the
// location pointed to by (int *) arg2.
const prGetChildSubreaper = 37
// GetSubreaper returns the subreaper setting for the calling process
func GetSubreaper() (int, error) {
var i uintptr
if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, prGetChildSubreaper, uintptr(unsafe.Pointer(&i)), 0); err != 0 {
return -1, err
}
return int(i), nil
}
// SetSubreaper sets the value i as the subreaper setting for the calling process
func SetSubreaper(i int) error {
if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, prSetChildSubreaper, uintptr(i), 0); err != 0 {
return err
}
return nil
}

View file

@ -6,6 +6,7 @@ import (
api "github.com/docker/containerd/api/execution" api "github.com/docker/containerd/api/execution"
google_protobuf "github.com/golang/protobuf/ptypes/empty" google_protobuf "github.com/golang/protobuf/ptypes/empty"
"github.com/nats-io/go-nats"
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
@ -15,19 +16,20 @@ var (
ErrProcessNotFound = fmt.Errorf("Process not found") ErrProcessNotFound = fmt.Errorf("Process not found")
) )
func New(executor Executor) (*Service, error) { func New(executor Executor, nec *nats.EncodedConn) (*Service, error) {
return &Service{ return &Service{
executor: executor, executor: executor,
nec: nec,
}, nil }, nil
} }
type Service struct { type Service struct {
executor Executor executor Executor
supervisor *Supervisor supervisor *Supervisor
nec *nats.EncodedConn
} }
func (s *Service) Create(ctx context.Context, r *api.CreateContainerRequest) (*api.CreateContainerResponse, error) { func (s *Service) Create(ctx context.Context, r *api.CreateContainerRequest) (*api.CreateContainerResponse, error) {
// TODO: write io and bundle path to dir
var err error var err error
container, err := s.executor.Create(ctx, r.ID, CreateOpts{ container, err := s.executor.Create(ctx, r.ID, CreateOpts{
@ -41,10 +43,14 @@ func (s *Service) Create(ctx context.Context, r *api.CreateContainerRequest) (*a
return nil, err return nil, err
} }
s.supervisor.Add(container) procs := container.Processes()
initProcess := procs[0]
s.monitorProcess(container, initProcess)
return &api.CreateContainerResponse{ return &api.CreateContainerResponse{
Container: toGRPCContainer(container), Container: toGRPCContainer(container),
InitProcess: toGRPCProcess(initProcess),
}, nil }, nil
} }
@ -138,7 +144,8 @@ func (s *Service) StartProcess(ctx context.Context, r *api.StartProcessRequest)
if err != nil { if err != nil {
return nil, err return nil, err
} }
s.supervisor.Add(process)
s.monitorProcess(container, process)
return &api.StartProcessResponse{ return &api.StartProcessResponse{
Process: toGRPCProcess(process), Process: toGRPCProcess(process),
@ -198,6 +205,43 @@ var (
_ = (api.ExecutionServiceServer)(&Service{}) _ = (api.ExecutionServiceServer)(&Service{})
) )
func (s *Service) publishEvent(name string, v interface{}) {
if s.nec == nil {
return
}
err := s.nec.Publish(name, v)
if err != nil {
// TODO: Use logrus?
fmt.Println("Failed to publish '%s:%#v': %v", name, v, err)
}
}
func (s *Service) monitorProcess(container *Container, process Process) {
go func() {
status, err := process.Wait()
if err == nil {
subject := GetContainerProcessEventSubject(container.ID(), process.ID())
s.publishEvent(subject, &ContainerExitEvent{
ContainerEvent: ContainerEvent{
ID: container.ID(),
Action: "exit",
},
PID: process.ID(),
StatusCode: status,
})
}
}()
}
func GetContainerEventSubject(id string) string {
return fmt.Sprintf(containerEventsSubjectFormat, id)
}
func GetContainerProcessEventSubject(containerID, processID string) string {
return fmt.Sprintf(containerProcessEventsSubjectFormat, containerID, processID)
}
func toGRPCContainer(container *Container) *api.Container { func toGRPCContainer(container *Container) *api.Container {
c := &api.Container{ c := &api.Container{
ID: container.ID(), ID: container.ID(),

View file

@ -7,6 +7,6 @@ type waiter interface {
Wait() (uint32, error) Wait() (uint32, error)
} }
func (s *Supervisor) Add(w waiter) { func (s *Supervisor) Monitor(w waiter, cb func(uint32, error)) {
go cb(w.Wait())
} }