Move fifo creation to client
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
f5fdc548e8
commit
36eb83cb99
14 changed files with 305 additions and 313 deletions
|
@ -34,6 +34,9 @@ func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContaine
|
||||||
e := supervisor.NewEvent(supervisor.StartContainerEventType)
|
e := supervisor.NewEvent(supervisor.StartContainerEventType)
|
||||||
e.ID = c.Id
|
e.ID = c.Id
|
||||||
e.BundlePath = c.BundlePath
|
e.BundlePath = c.BundlePath
|
||||||
|
e.Stdin = c.Stdin
|
||||||
|
e.Stdout = c.Stdout
|
||||||
|
e.Stderr = c.Stderr
|
||||||
e.StartResponse = make(chan supervisor.StartResponse, 1)
|
e.StartResponse = make(chan supervisor.StartResponse, 1)
|
||||||
if c.Checkpoint != "" {
|
if c.Checkpoint != "" {
|
||||||
e.Checkpoint = &runtime.Checkpoint{
|
e.Checkpoint = &runtime.Checkpoint{
|
||||||
|
@ -44,12 +47,8 @@ func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContaine
|
||||||
if err := <-e.Err; err != nil {
|
if err := <-e.Err; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sr := <-e.StartResponse
|
<-e.StartResponse
|
||||||
return &types.CreateContainerResponse{
|
return &types.CreateContainerResponse{}, nil
|
||||||
Stdin: sr.Stdin,
|
|
||||||
Stdout: sr.Stdout,
|
|
||||||
Stderr: sr.Stderr,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *apiServer) Signal(ctx context.Context, r *types.SignalRequest) (*types.SignalResponse, error) {
|
func (s *apiServer) Signal(ctx context.Context, r *types.SignalRequest) (*types.SignalResponse, error) {
|
||||||
|
@ -86,17 +85,16 @@ func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest)
|
||||||
e.ID = r.Id
|
e.ID = r.Id
|
||||||
e.Pid = r.Pid
|
e.Pid = r.Pid
|
||||||
e.ProcessSpec = process
|
e.ProcessSpec = process
|
||||||
|
e.Stdin = r.Stdin
|
||||||
|
e.Stdout = r.Stdout
|
||||||
|
e.Stderr = r.Stderr
|
||||||
e.StartResponse = make(chan supervisor.StartResponse, 1)
|
e.StartResponse = make(chan supervisor.StartResponse, 1)
|
||||||
s.sv.SendEvent(e)
|
s.sv.SendEvent(e)
|
||||||
if err := <-e.Err; err != nil {
|
if err := <-e.Err; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sr := <-e.StartResponse
|
<-e.StartResponse
|
||||||
return &types.AddProcessResponse{
|
return &types.AddProcessResponse{}, nil
|
||||||
Stdin: sr.Stdin,
|
|
||||||
Stdout: sr.Stdout,
|
|
||||||
Stderr: sr.Stderr,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *apiServer) CreateCheckpoint(ctx context.Context, r *types.CreateCheckpointRequest) (*types.CreateCheckpointResponse, error) {
|
func (s *apiServer) CreateCheckpoint(ctx context.Context, r *types.CreateCheckpointRequest) (*types.CreateCheckpointResponse, error) {
|
||||||
|
|
|
@ -88,7 +88,10 @@ func (*UpdateProcessResponse) Descriptor() ([]byte, []int) { return fileDescript
|
||||||
type CreateContainerRequest struct {
|
type CreateContainerRequest struct {
|
||||||
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
|
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
|
||||||
BundlePath string `protobuf:"bytes,2,opt,name=bundlePath" json:"bundlePath,omitempty"`
|
BundlePath string `protobuf:"bytes,2,opt,name=bundlePath" json:"bundlePath,omitempty"`
|
||||||
Checkpoint string `protobuf:"bytes,7,opt,name=checkpoint" json:"checkpoint,omitempty"`
|
Checkpoint string `protobuf:"bytes,3,opt,name=checkpoint" json:"checkpoint,omitempty"`
|
||||||
|
Stdin string `protobuf:"bytes,4,opt,name=stdin" json:"stdin,omitempty"`
|
||||||
|
Stdout string `protobuf:"bytes,5,opt,name=stdout" json:"stdout,omitempty"`
|
||||||
|
Stderr string `protobuf:"bytes,6,opt,name=stderr" json:"stderr,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CreateContainerRequest) Reset() { *m = CreateContainerRequest{} }
|
func (m *CreateContainerRequest) Reset() { *m = CreateContainerRequest{} }
|
||||||
|
@ -97,10 +100,6 @@ func (*CreateContainerRequest) ProtoMessage() {}
|
||||||
func (*CreateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
|
func (*CreateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
|
||||||
|
|
||||||
type CreateContainerResponse struct {
|
type CreateContainerResponse struct {
|
||||||
Pid uint32 `protobuf:"varint,1,opt,name=pid" json:"pid,omitempty"`
|
|
||||||
Stdin string `protobuf:"bytes,2,opt,name=stdin" json:"stdin,omitempty"`
|
|
||||||
Stdout string `protobuf:"bytes,3,opt,name=stdout" json:"stdout,omitempty"`
|
|
||||||
Stderr string `protobuf:"bytes,4,opt,name=stderr" json:"stderr,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CreateContainerResponse) Reset() { *m = CreateContainerResponse{} }
|
func (m *CreateContainerResponse) Reset() { *m = CreateContainerResponse{} }
|
||||||
|
@ -135,6 +134,9 @@ type AddProcessRequest struct {
|
||||||
Env []string `protobuf:"bytes,5,rep,name=env" json:"env,omitempty"`
|
Env []string `protobuf:"bytes,5,rep,name=env" json:"env,omitempty"`
|
||||||
Cwd string `protobuf:"bytes,6,opt,name=cwd" json:"cwd,omitempty"`
|
Cwd string `protobuf:"bytes,6,opt,name=cwd" json:"cwd,omitempty"`
|
||||||
Pid string `protobuf:"bytes,7,opt,name=pid" json:"pid,omitempty"`
|
Pid string `protobuf:"bytes,7,opt,name=pid" json:"pid,omitempty"`
|
||||||
|
Stdin string `protobuf:"bytes,8,opt,name=stdin" json:"stdin,omitempty"`
|
||||||
|
Stdout string `protobuf:"bytes,9,opt,name=stdout" json:"stdout,omitempty"`
|
||||||
|
Stderr string `protobuf:"bytes,10,opt,name=stderr" json:"stderr,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AddProcessRequest) Reset() { *m = AddProcessRequest{} }
|
func (m *AddProcessRequest) Reset() { *m = AddProcessRequest{} }
|
||||||
|
@ -161,9 +163,6 @@ func (*User) ProtoMessage() {}
|
||||||
func (*User) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
|
func (*User) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
|
||||||
|
|
||||||
type AddProcessResponse struct {
|
type AddProcessResponse struct {
|
||||||
Stdin string `protobuf:"bytes,1,opt,name=stdin" json:"stdin,omitempty"`
|
|
||||||
Stdout string `protobuf:"bytes,2,opt,name=stdout" json:"stdout,omitempty"`
|
|
||||||
Stderr string `protobuf:"bytes,3,opt,name=stderr" json:"stderr,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AddProcessResponse) Reset() { *m = AddProcessResponse{} }
|
func (m *AddProcessResponse) Reset() { *m = AddProcessResponse{} }
|
||||||
|
@ -1136,99 +1135,99 @@ var _API_serviceDesc = grpc.ServiceDesc{
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptor0 = []byte{
|
var fileDescriptor0 = []byte{
|
||||||
// 1497 bytes of a gzipped FileDescriptorProto
|
// 1493 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x58, 0xdb, 0x72, 0xdc, 0x44,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x58, 0xd9, 0x72, 0x1b, 0x45,
|
||||||
0x10, 0xf5, 0xde, 0x77, 0x7b, 0x2f, 0xb6, 0xe5, 0xdb, 0x7a, 0x43, 0x48, 0x10, 0x81, 0xa4, 0xa8,
|
0x17, 0xb6, 0xa4, 0xd1, 0x76, 0xb4, 0xd8, 0x1e, 0x2f, 0x91, 0x95, 0x3f, 0x7f, 0xc2, 0x10, 0x48,
|
||||||
0x94, 0x2b, 0x38, 0x5c, 0x42, 0x78, 0x80, 0xe0, 0xa4, 0x12, 0xa8, 0x04, 0x5c, 0xb1, 0x4d, 0x15,
|
0x8a, 0x4a, 0xb9, 0x82, 0xc3, 0x12, 0xc2, 0x05, 0x04, 0x27, 0x95, 0x40, 0x25, 0xe0, 0x8a, 0x6d,
|
||||||
0x2f, 0x6c, 0xc9, 0xd2, 0xb0, 0x3b, 0xac, 0x56, 0x12, 0xd2, 0xc8, 0x97, 0x47, 0x5e, 0x79, 0xe5,
|
0xaa, 0xb8, 0x41, 0x35, 0x9e, 0x69, 0xa4, 0x46, 0xa3, 0x99, 0x61, 0xa6, 0xc7, 0x4b, 0xf1, 0x06,
|
||||||
0x5f, 0xf8, 0x00, 0xbe, 0x80, 0xef, 0xe0, 0x2b, 0xe8, 0xb9, 0xae, 0xa4, 0xbd, 0x04, 0x1e, 0x78,
|
0xdc, 0xf2, 0x22, 0x5c, 0xf1, 0x00, 0x3c, 0x01, 0xcf, 0xc1, 0x53, 0x70, 0x7a, 0x9b, 0x4d, 0x8b,
|
||||||
0x71, 0xd5, 0xcc, 0x74, 0x9f, 0x3e, 0x7d, 0xba, 0x7b, 0x56, 0x63, 0x68, 0x39, 0x11, 0x3d, 0x88,
|
0xe1, 0x82, 0x1b, 0x55, 0x75, 0xf7, 0x59, 0xbe, 0xf3, 0x9d, 0x65, 0xba, 0x05, 0x6d, 0x3b, 0xa4,
|
||||||
0xe2, 0x90, 0x85, 0x56, 0x8d, 0x5d, 0x47, 0x24, 0xb1, 0xcf, 0x61, 0xfb, 0x2c, 0xf2, 0x1c, 0x46,
|
0xfb, 0x61, 0x14, 0xb0, 0xc0, 0xac, 0xb3, 0xab, 0x90, 0xc4, 0xd6, 0x19, 0x6c, 0x9f, 0x86, 0xae,
|
||||||
0x8e, 0xe3, 0xd0, 0x25, 0x49, 0xf2, 0x9a, 0xfc, 0x92, 0x92, 0x84, 0x59, 0x00, 0x65, 0xea, 0xf5,
|
0xcd, 0xc8, 0x51, 0x14, 0x38, 0x24, 0x8e, 0xdf, 0x90, 0x9f, 0x12, 0x12, 0x33, 0x13, 0xa0, 0x4a,
|
||||||
0x4b, 0xb7, 0x4b, 0xf7, 0x5a, 0x56, 0x1b, 0x2a, 0x11, 0x2e, 0xca, 0x62, 0x81, 0x27, 0xae, 0x1f,
|
0xdd, 0x41, 0xe5, 0x4e, 0xe5, 0x7e, 0xdb, 0xec, 0x40, 0x2d, 0xc4, 0x45, 0x55, 0x2c, 0xf0, 0xc4,
|
||||||
0x26, 0xe4, 0x84, 0x79, 0x34, 0xe8, 0x57, 0x70, 0xaf, 0x69, 0x75, 0xa1, 0x76, 0x49, 0x3d, 0x36,
|
0xf1, 0x82, 0x98, 0x1c, 0x33, 0x97, 0xfa, 0x83, 0x1a, 0xee, 0xb5, 0xcc, 0x1e, 0xd4, 0x2f, 0xa8,
|
||||||
0xee, 0x57, 0x71, 0xd9, 0xb5, 0x7a, 0x50, 0x1f, 0x13, 0x3a, 0x1a, 0xb3, 0x7e, 0x8d, 0xaf, 0xed,
|
0xcb, 0x26, 0x03, 0x03, 0x97, 0x3d, 0xb3, 0x0f, 0x8d, 0x09, 0xa1, 0xe3, 0x09, 0x1b, 0xd4, 0xf9,
|
||||||
0x3d, 0xd8, 0x29, 0xc4, 0x48, 0xa2, 0x30, 0x48, 0x88, 0xfd, 0x12, 0x76, 0x8f, 0x62, 0x82, 0x07,
|
0xda, 0xba, 0x01, 0x3b, 0x25, 0x1f, 0x71, 0x18, 0xf8, 0x31, 0xb1, 0x7e, 0x86, 0xdd, 0xc3, 0x88,
|
||||||
0x47, 0x61, 0xc0, 0x1c, 0x1a, 0x90, 0x78, 0x51, 0x78, 0x5c, 0x9c, 0xa7, 0x81, 0xe7, 0x93, 0x63,
|
0xe0, 0xc1, 0x61, 0xe0, 0x33, 0x9b, 0xfa, 0x24, 0x5a, 0xe4, 0x1e, 0x17, 0x67, 0x89, 0xef, 0x7a,
|
||||||
0x07, 0x43, 0xcc, 0x58, 0x8c, 0x89, 0x3b, 0x89, 0x42, 0x1a, 0xb0, 0x7e, 0x83, 0xef, 0xd9, 0x67,
|
0xe4, 0xc8, 0x46, 0x17, 0x19, 0x8a, 0x09, 0x71, 0xa6, 0x61, 0x40, 0x7d, 0x26, 0x50, 0xb4, 0x39,
|
||||||
0xb0, 0x37, 0x87, 0x26, 0x03, 0xe9, 0x0c, 0x4a, 0x82, 0x1e, 0xb2, 0x4d, 0x04, 0x79, 0x09, 0x85,
|
0x8a, 0x58, 0x80, 0x32, 0xc4, 0x12, 0x51, 0xe0, 0x32, 0x48, 0x24, 0x0a, 0xbd, 0x26, 0x51, 0x34,
|
||||||
0x6c, 0x71, 0x19, 0xa6, 0x4c, 0x24, 0xa3, 0xd7, 0x24, 0x8e, 0x45, 0x36, 0x2d, 0xfb, 0x11, 0x74,
|
0x68, 0xf0, 0xb5, 0xb5, 0x07, 0x37, 0xe6, 0x9c, 0x2b, 0x5c, 0x8f, 0xa1, 0x77, 0x4c, 0xc7, 0xbe,
|
||||||
0x4f, 0xe8, 0x28, 0x70, 0xfc, 0x37, 0x4a, 0xc3, 0x3d, 0x85, 0xa5, 0x40, 0xea, 0xda, 0x1b, 0xd0,
|
0xed, 0x5d, 0xcb, 0x06, 0x37, 0x2a, 0x24, 0x05, 0x86, 0x9e, 0xb5, 0x01, 0x7d, 0xad, 0xa9, 0x6c,
|
||||||
0xd3, 0x9e, 0x2a, 0xe1, 0x5f, 0x4b, 0xb0, 0xf9, 0xc4, 0xf3, 0x56, 0x68, 0xbd, 0x01, 0x4d, 0x46,
|
0xfd, 0x56, 0x81, 0xcd, 0xa7, 0xae, 0xbb, 0x82, 0xde, 0x0d, 0x68, 0x31, 0x12, 0xcd, 0x28, 0xb7,
|
||||||
0xe2, 0x29, 0xe5, 0x28, 0x65, 0x21, 0xee, 0x3e, 0x54, 0xd3, 0x84, 0xc4, 0x02, 0xb3, 0x7d, 0xd8,
|
0x52, 0x15, 0x7c, 0xee, 0x81, 0x91, 0xc4, 0x24, 0x12, 0x36, 0x3b, 0x07, 0x9d, 0x7d, 0x91, 0xaa,
|
||||||
0x3e, 0x10, 0x75, 0x3b, 0x38, 0xc3, 0x2d, 0xab, 0x03, 0x55, 0x27, 0x1e, 0x25, 0x48, 0xb4, 0x22,
|
0xfd, 0x53, 0xdc, 0x32, 0xbb, 0x60, 0xd8, 0xd1, 0x38, 0xc6, 0x18, 0x6b, 0x12, 0x0b, 0xf1, 0xcf,
|
||||||
0xb9, 0x90, 0xe0, 0x02, 0x35, 0x57, 0x0b, 0xf7, 0xd2, 0xeb, 0xd7, 0xb3, 0x2c, 0x1b, 0x2a, 0x9f,
|
0x31, 0x40, 0xb5, 0x70, 0x2e, 0x5c, 0x19, 0x9d, 0x46, 0xd9, 0x2c, 0x32, 0xd3, 0x2a, 0x31, 0xd3,
|
||||||
0xaa, 0x70, 0xc6, 0xcd, 0xd4, 0x68, 0x82, 0x8b, 0x91, 0xca, 0xa3, 0x6b, 0xed, 0x42, 0xcf, 0xf1,
|
0x2e, 0x31, 0x03, 0x82, 0x99, 0xc7, 0x60, 0x08, 0x5f, 0x68, 0x23, 0x51, 0x28, 0x7b, 0x7c, 0x31,
|
||||||
0x3c, 0xca, 0x68, 0x88, 0x2c, 0x9e, 0x53, 0x2f, 0xc1, 0xd8, 0x15, 0xcc, 0xe7, 0x08, 0xac, 0x2c,
|
0x56, 0x61, 0xf7, 0xcc, 0x5d, 0xe8, 0xdb, 0xae, 0x4b, 0x19, 0x0d, 0x10, 0xf4, 0x0b, 0xea, 0xc6,
|
||||||
0x79, 0xa5, 0xad, 0x91, 0xb3, 0x54, 0x90, 0xb3, 0x5c, 0x90, 0x53, 0xc8, 0x8b, 0x35, 0xd7, 0x55,
|
0x08, 0xb5, 0x86, 0xe1, 0x6f, 0x83, 0x99, 0x8f, 0x55, 0x51, 0xf0, 0x2a, 0x65, 0x3a, 0x4d, 0xd9,
|
||||||
0x32, 0xf5, 0x5b, 0xa4, 0xc3, 0x7b, 0xb9, 0x02, 0x97, 0x45, 0xee, 0x9b, 0x2a, 0xf7, 0x99, 0xa7,
|
0x22, 0x1e, 0xde, 0x29, 0xe4, 0xb4, 0x2a, 0x62, 0xdf, 0x54, 0xb1, 0x67, 0x9a, 0xd6, 0x10, 0x06,
|
||||||
0x3d, 0x80, 0xfe, 0x3c, 0x9a, 0x12, 0xfb, 0x21, 0xec, 0x3d, 0x25, 0x3e, 0x79, 0x53, 0x24, 0x14,
|
0xf3, 0xd6, 0x94, 0xa7, 0x47, 0x70, 0xe3, 0x19, 0xf1, 0xc8, 0x75, 0x9e, 0x90, 0x44, 0xdf, 0x9e,
|
||||||
0x31, 0x70, 0xa6, 0x44, 0xd2, 0xe5, 0x80, 0xf3, 0x4e, 0x0a, 0xf0, 0x5d, 0xd8, 0x79, 0x49, 0x13,
|
0x11, 0x99, 0x43, 0x6e, 0x70, 0x5e, 0x49, 0x19, 0x7c, 0x1b, 0x76, 0x5e, 0xd1, 0x98, 0xad, 0x34,
|
||||||
0xb6, 0x12, 0xce, 0xfe, 0x01, 0x60, 0x66, 0x60, 0xc0, 0x4d, 0x28, 0x72, 0x45, 0x99, 0x2a, 0x2c,
|
0x67, 0x7d, 0x07, 0x90, 0x09, 0xa4, 0xc6, 0x53, 0x57, 0xe4, 0x92, 0x32, 0x95, 0x58, 0x24, 0x91,
|
||||||
0x6a, 0xce, 0xdc, 0x48, 0x8d, 0xd0, 0x16, 0xb4, 0xd3, 0x80, 0x5e, 0x9d, 0x84, 0xee, 0x84, 0xb0,
|
0x39, 0xa1, 0xea, 0x9a, 0x2d, 0xe8, 0x24, 0x3e, 0xbd, 0x3c, 0x0e, 0x9c, 0x29, 0x61, 0xb1, 0xa8,
|
||||||
0x44, 0xb4, 0x9e, 0x98, 0xab, 0x64, 0x4c, 0x7c, 0x5f, 0xcc, 0x51, 0xd3, 0xfe, 0x12, 0x76, 0x8b,
|
0x5a, 0xd1, 0x4a, 0xf1, 0x84, 0x78, 0x9e, 0x28, 0xda, 0x96, 0xf5, 0x39, 0xec, 0x96, 0xfd, 0x4b,
|
||||||
0xf1, 0x55, 0x0d, 0xde, 0x87, 0xf6, 0x4c, 0xad, 0x04, 0xa3, 0x55, 0x16, 0xcb, 0xd5, 0x83, 0xce,
|
0x64, 0xe6, 0xbb, 0xd0, 0xc9, 0xd8, 0x8a, 0xd1, 0x5b, 0x6d, 0x31, 0x5d, 0x7d, 0xe8, 0x1e, 0x33,
|
||||||
0x09, 0x43, 0xb5, 0x14, 0x71, 0xfb, 0x36, 0xf4, 0xcc, 0xb0, 0x88, 0x03, 0x59, 0x2e, 0x87, 0xa5,
|
0x64, 0x4b, 0x01, 0xb7, 0xee, 0x40, 0x3f, 0x2d, 0x78, 0x71, 0x20, 0xd3, 0x6f, 0xb3, 0x24, 0x56,
|
||||||
0x89, 0x4a, 0x67, 0x02, 0x0d, 0x55, 0xf0, 0xec, 0x10, 0xfd, 0x3f, 0x7d, 0x6a, 0xfb, 0xd0, 0x32,
|
0xe1, 0x4c, 0xa1, 0xa9, 0x32, 0xa8, 0xab, 0xe8, 0xbf, 0xab, 0x53, 0xcb, 0x83, 0x76, 0x0a, 0x67,
|
||||||
0x74, 0x96, 0xd7, 0xa8, 0x70, 0x21, 0xc8, 0xa9, 0x7d, 0x07, 0x5a, 0x91, 0xe4, 0x49, 0x64, 0x9c,
|
0x79, 0x8e, 0x4a, 0x33, 0x40, 0xf6, 0xfb, 0x5b, 0xd0, 0x0e, 0x25, 0x4e, 0x22, 0xfd, 0x74, 0x0e,
|
||||||
0xf6, 0x61, 0x4f, 0x51, 0xd0, 0xfc, 0x67, 0xa9, 0xd5, 0x44, 0xb4, 0xbb, 0xd0, 0x78, 0xe5, 0xb8,
|
0xfa, 0x0a, 0x82, 0xc6, 0x9f, 0x85, 0x26, 0x66, 0x80, 0x75, 0x0f, 0x9a, 0xaf, 0x6d, 0x67, 0x82,
|
||||||
0x63, 0x0c, 0xc6, 0xf1, 0xdd, 0x48, 0xe5, 0x2c, 0xee, 0xaf, 0x29, 0x99, 0x86, 0xf1, 0xb5, 0x88,
|
0xce, 0xb8, 0x7d, 0x27, 0x54, 0x31, 0x8b, 0x91, 0x35, 0x23, 0xb3, 0x20, 0xba, 0x12, 0xfe, 0x0c,
|
||||||
0x57, 0xb5, 0xbf, 0xc7, 0x1b, 0x40, 0xaa, 0xa6, 0xe4, 0xbe, 0x83, 0xcd, 0xa9, 0x79, 0x6a, 0xb5,
|
0xeb, 0x5b, 0x9c, 0x00, 0x92, 0x35, 0x45, 0xf7, 0x5d, 0x2c, 0x4e, 0x8d, 0x53, 0xb3, 0xbd, 0xa1,
|
||||||
0x37, 0xb4, 0xda, 0x26, 0x81, 0x5b, 0xd0, 0x98, 0x4a, 0x7c, 0xd5, 0xbf, 0x9a, 0x90, 0x8a, 0x6a,
|
0xd9, 0x4e, 0x03, 0xb8, 0x0d, 0xcd, 0x99, 0xb4, 0xaf, 0xea, 0x57, 0x03, 0x52, 0x5e, 0xad, 0xa7,
|
||||||
0x3f, 0x81, 0x5d, 0x79, 0x2f, 0xae, 0xbc, 0xfe, 0xe6, 0xae, 0x18, 0x99, 0x83, 0x9c, 0xa6, 0x7d,
|
0xb0, 0x2b, 0x47, 0xe1, 0xca, 0x89, 0x37, 0x37, 0x62, 0x64, 0x0c, 0x35, 0x3d, 0xb7, 0xe6, 0x4c,
|
||||||
0xd8, 0x9b, 0x83, 0x50, 0xdd, 0xba, 0x0e, 0xdd, 0x67, 0x17, 0x04, 0xdb, 0x41, 0x17, 0xfb, 0xaf,
|
0xa8, 0x6a, 0x5d, 0x87, 0xde, 0xf3, 0x73, 0x82, 0xe5, 0xa0, 0x93, 0xfd, 0x67, 0x05, 0xea, 0x62,
|
||||||
0x12, 0xd4, 0xc4, 0x0e, 0x4f, 0x97, 0x33, 0x51, 0x01, 0x64, 0xb0, 0x45, 0xf8, 0xdd, 0x82, 0xd4,
|
0x87, 0x87, 0xcb, 0x91, 0x28, 0x07, 0xd2, 0xd9, 0x22, 0xfb, 0xbd, 0x12, 0xd5, 0x46, 0x1e, 0x50,
|
||||||
0xd5, 0x2c, 0xa1, 0x5a, 0xe1, 0xce, 0x6b, 0x08, 0x07, 0x4c, 0x5a, 0xd5, 0xa1, 0xdf, 0xcc, 0x25,
|
0xbd, 0x34, 0xf3, 0x9a, 0x42, 0x01, 0x83, 0x56, 0x79, 0x10, 0xf3, 0x65, 0x3e, 0x0b, 0x45, 0xee,
|
||||||
0xad, 0xab, 0x90, 0xd7, 0xae, 0xb5, 0x44, 0xbb, 0xfc, 0xf8, 0xc3, 0xb2, 0xf1, 0xff, 0xa3, 0x04,
|
0xda, 0x4b, 0xb8, 0x2b, 0xb6, 0x3f, 0x2c, 0x6b, 0xff, 0xdf, 0x2b, 0xd0, 0xfd, 0x9a, 0xb0, 0x8b,
|
||||||
0x9d, 0x6f, 0x09, 0xbb, 0x0c, 0xe3, 0x09, 0xaf, 0x50, 0x52, 0x98, 0x37, 0x6c, 0xd2, 0xf8, 0x6a,
|
0x20, 0x9a, 0xf2, 0x0c, 0xc5, 0xa5, 0x7e, 0xc3, 0x22, 0x8d, 0x2e, 0x47, 0x67, 0x57, 0x0c, 0x6b,
|
||||||
0x78, 0x7e, 0xcd, 0xb0, 0x27, 0x44, 0x29, 0x79, 0x3e, 0xb8, 0x73, 0xec, 0xc8, 0x29, 0xab, 0x88,
|
0x42, 0xa4, 0x92, 0xc7, 0x83, 0x3b, 0x47, 0xb6, 0xec, 0xb2, 0x9a, 0xd8, 0xdb, 0x84, 0xf6, 0x9b,
|
||||||
0xbd, 0x4d, 0x68, 0xbd, 0xbe, 0x1a, 0xe2, 0x0d, 0x15, 0xc6, 0x72, 0xf0, 0x84, 0x19, 0x6e, 0x79,
|
0xcb, 0x11, 0x4e, 0xbc, 0x20, 0x92, 0x8d, 0x27, 0xc4, 0x70, 0xcb, 0x8d, 0x82, 0x30, 0x24, 0x32,
|
||||||
0x71, 0x18, 0x45, 0x44, 0x66, 0x5a, 0xe5, 0x60, 0xa7, 0x1a, 0xac, 0xae, 0xad, 0x70, 0x27, 0x52,
|
0x52, 0x83, 0x1b, 0x3b, 0xd1, 0xc6, 0x1a, 0x5a, 0x0a, 0x77, 0x42, 0x65, 0xac, 0xa9, 0x8d, 0x9d,
|
||||||
0x60, 0x0d, 0x0d, 0x76, 0x6a, 0xc0, 0x9a, 0x19, 0x33, 0x0d, 0xd6, 0x12, 0x2d, 0x35, 0x85, 0xe6,
|
0xa4, 0xc6, 0x5a, 0x39, 0x31, 0x6d, 0xac, 0x2d, 0x4a, 0x6a, 0x06, 0xad, 0xc3, 0x30, 0x39, 0x8d,
|
||||||
0x51, 0x94, 0x9e, 0x25, 0xce, 0x88, 0xf0, 0xd1, 0x67, 0x21, 0x73, 0xfc, 0x61, 0xca, 0x97, 0x82,
|
0xed, 0x31, 0xe1, 0xad, 0xcf, 0x02, 0x66, 0x7b, 0xa3, 0x84, 0x2f, 0x05, 0x74, 0xc3, 0xdc, 0x86,
|
||||||
0x7a, 0xd5, 0xda, 0x86, 0x4e, 0x44, 0x62, 0x6c, 0x4a, 0xb5, 0x5b, 0x46, 0xa1, 0xaa, 0xd6, 0x0d,
|
0x6e, 0x48, 0x22, 0x2c, 0x4a, 0xb5, 0x5b, 0x45, 0xa2, 0x0c, 0xf3, 0x26, 0x6c, 0x89, 0xe5, 0x88,
|
||||||
0xd8, 0x12, 0xcb, 0x21, 0x0d, 0x86, 0x13, 0x12, 0x07, 0xc4, 0x9f, 0x86, 0x1e, 0x51, 0x79, 0xec,
|
0xfa, 0xa3, 0x29, 0x89, 0x7c, 0xe2, 0xcd, 0x02, 0x97, 0xa8, 0x38, 0xf6, 0x60, 0x33, 0x3d, 0xe4,
|
||||||
0xc3, 0xa6, 0x39, 0xe4, 0x93, 0x28, 0x8e, 0x44, 0x3e, 0xf6, 0x29, 0xf4, 0x4e, 0xc7, 0xf8, 0xb3,
|
0x9d, 0x28, 0x8e, 0x44, 0x3c, 0xd6, 0x09, 0xf4, 0x4f, 0x26, 0xf8, 0xa5, 0x67, 0x1e, 0xf5, 0xc7,
|
||||||
0xcf, 0x7c, 0x1a, 0x8c, 0x9e, 0x3a, 0xcc, 0xb1, 0xd6, 0xb1, 0x4e, 0x24, 0xa6, 0xa1, 0x97, 0xa8,
|
0xcf, 0x6c, 0x66, 0x9b, 0xeb, 0x98, 0x27, 0x12, 0xd1, 0xc0, 0x8d, 0x95, 0x43, 0xd4, 0x66, 0x52,
|
||||||
0x80, 0xe8, 0xcd, 0xa4, 0x09, 0xf1, 0x86, 0xfa, 0x48, 0x8a, 0x86, 0xbf, 0x07, 0xb3, 0x23, 0x46,
|
0x84, 0xb8, 0x23, 0x7d, 0x24, 0x49, 0xc3, 0x01, 0x9f, 0x1d, 0x31, 0x3a, 0x53, 0x0e, 0xad, 0xef,
|
||||||
0xa7, 0x2a, 0xa0, 0xfd, 0xa3, 0x48, 0x42, 0x0a, 0x6f, 0x43, 0x6b, 0x46, 0xb6, 0x24, 0xea, 0xb5,
|
0x45, 0x10, 0x92, 0x78, 0x0b, 0xda, 0x19, 0xd8, 0x8a, 0xc8, 0xd7, 0xba, 0xce, 0x97, 0x0e, 0x74,
|
||||||
0xae, 0xeb, 0xa5, 0x13, 0x3d, 0x80, 0x75, 0x66, 0x58, 0x0c, 0xb1, 0x6b, 0x1d, 0x35, 0x18, 0x3b,
|
0x1f, 0xd6, 0x59, 0x8a, 0x62, 0x84, 0x55, 0x6b, 0xab, 0xc6, 0xd8, 0x51, 0x92, 0x45, 0x8c, 0xd6,
|
||||||
0xca, 0x32, 0xcf, 0xd1, 0xfe, 0x02, 0xe0, 0x95, 0x98, 0x43, 0xc1, 0x18, 0x2f, 0xc3, 0xac, 0x40,
|
0x67, 0x00, 0xaf, 0x45, 0x1f, 0x0a, 0xc4, 0x38, 0x0c, 0xf3, 0x04, 0x21, 0xd1, 0x33, 0xfb, 0x32,
|
||||||
0x28, 0xf4, 0xd4, 0xb9, 0x32, 0xea, 0xf0, 0x2d, 0xcc, 0xe9, 0x27, 0x87, 0xfa, 0x6e, 0xc0, 0x14,
|
0x65, 0x87, 0x6f, 0x61, 0x4c, 0x3f, 0xd8, 0xd4, 0x73, 0xd4, 0x25, 0xc0, 0xb0, 0xfe, 0xaa, 0x40,
|
||||||
0xc1, 0xbf, 0x4b, 0xd0, 0x96, 0x08, 0x92, 0x24, 0x42, 0xb8, 0x38, 0x7b, 0x1a, 0xe2, 0xb6, 0x46,
|
0x47, 0x5a, 0x90, 0x20, 0xd1, 0x84, 0x83, 0xbd, 0xa7, 0x4d, 0xdc, 0xd1, 0x16, 0x8b, 0x9f, 0x97,
|
||||||
0xcc, 0xff, 0xbc, 0x64, 0x62, 0x62, 0x1b, 0x26, 0x97, 0x4e, 0xa4, 0xa2, 0x54, 0x96, 0x99, 0xdd,
|
0x9c, 0x4f, 0x2c, 0xc3, 0xf8, 0xc2, 0x0e, 0x95, 0x97, 0xda, 0x32, 0xb1, 0x7b, 0xd0, 0x95, 0xd9,
|
||||||
0x85, 0x8e, 0xac, 0x86, 0x32, 0xac, 0x2e, 0x33, 0xbc, 0xcf, 0x7f, 0x2b, 0x91, 0x89, 0xb8, 0xfc,
|
0x50, 0x82, 0xc6, 0x32, 0xc1, 0x07, 0xfc, 0xdb, 0x8b, 0x48, 0xc4, 0xf0, 0xeb, 0x1c, 0xdc, 0x2a,
|
||||||
0xda, 0x87, 0x37, 0x73, 0x16, 0x82, 0xe3, 0x81, 0xf8, 0xfb, 0x2c, 0x60, 0xf1, 0xf5, 0xe0, 0x3e,
|
0x48, 0x08, 0x8c, 0xfb, 0xe2, 0xf7, 0xb9, 0xcf, 0xa2, 0xab, 0xe1, 0x03, 0x80, 0x6c, 0xc5, 0xdb,
|
||||||
0xc0, 0x6c, 0xc5, 0xc7, 0x6e, 0x42, 0xae, 0x55, 0x67, 0x63, 0x26, 0x17, 0x8e, 0x9f, 0xaa, 0xcc,
|
0x6e, 0x4a, 0xae, 0x54, 0x65, 0x63, 0x24, 0xe7, 0xb6, 0x97, 0xa8, 0xc8, 0x9f, 0x54, 0x1f, 0x57,
|
||||||
0x1f, 0x97, 0x1f, 0x95, 0xec, 0x6f, 0x60, 0xfd, 0x2b, 0x7f, 0x42, 0xc3, 0x8c, 0x0b, 0x5a, 0x4d,
|
0xac, 0xaf, 0x60, 0xfd, 0x0b, 0x6f, 0x4a, 0x83, 0x9c, 0x0a, 0x4a, 0xcd, 0xec, 0x1f, 0x83, 0x48,
|
||||||
0x9d, 0x9f, 0xc3, 0x58, 0xe5, 0xcb, 0x97, 0x34, 0xc0, 0xa5, 0x94, 0x0b, 0xe7, 0x3e, 0x8c, 0xd4,
|
0xc5, 0xcb, 0x97, 0xd4, 0xc7, 0xa5, 0xa4, 0x0b, 0xfb, 0x3e, 0x08, 0xb3, 0xeb, 0x92, 0xb4, 0x27,
|
||||||
0xf5, 0x69, 0xf0, 0x64, 0xbf, 0xfc, 0x59, 0x01, 0x98, 0x81, 0x59, 0x8f, 0x61, 0x40, 0xc3, 0x21,
|
0xeb, 0xe5, 0x8f, 0x1a, 0x40, 0x66, 0xcc, 0x7c, 0x02, 0x43, 0x1a, 0x8c, 0xb0, 0xa4, 0xce, 0xa9,
|
||||||
0xb6, 0xd4, 0x05, 0x75, 0x89, 0x1c, 0x81, 0x61, 0x4c, 0xdc, 0x34, 0x4e, 0xe8, 0x05, 0x51, 0xf7,
|
0x43, 0x64, 0x0b, 0x8c, 0x22, 0xe2, 0x24, 0x51, 0x4c, 0xcf, 0x89, 0x9a, 0x7f, 0xbb, 0x2a, 0x96,
|
||||||
0xdf, 0xae, 0xca, 0xa5, 0xc8, 0xe1, 0x63, 0xd8, 0x99, 0xf9, 0x7a, 0x19, 0xb7, 0xf2, 0x4a, 0xb7,
|
0x32, 0x86, 0x0f, 0x61, 0x27, 0xd3, 0x75, 0x73, 0x6a, 0xd5, 0x95, 0x6a, 0x8f, 0x60, 0x0b, 0xd5,
|
||||||
0x87, 0xb0, 0x85, 0x6e, 0x78, 0x71, 0xa5, 0x39, 0xa7, 0xca, 0x4a, 0xa7, 0xcf, 0x60, 0x3f, 0xc3,
|
0x70, 0x70, 0x25, 0x05, 0xa5, 0xda, 0x4a, 0xa5, 0x4f, 0x60, 0x2f, 0x87, 0x93, 0x57, 0x6a, 0x4e,
|
||||||
0x93, 0x77, 0x6a, 0xc6, 0xb5, 0xba, 0xd2, 0xf5, 0x13, 0xd8, 0x45, 0xd7, 0x4b, 0x87, 0xb2, 0xa2,
|
0xd5, 0x58, 0xa9, 0xfa, 0x11, 0xec, 0xa2, 0xea, 0x85, 0x4d, 0x59, 0x59, 0xaf, 0xfe, 0x0f, 0x70,
|
||||||
0x5f, 0xed, 0x5f, 0xf0, 0x9c, 0x92, 0x78, 0x94, 0xe3, 0x59, 0x5f, 0xe9, 0xf4, 0x21, 0x6c, 0xa2,
|
0xce, 0x48, 0x34, 0x2e, 0xe0, 0x6c, 0xac, 0x54, 0x7a, 0x1f, 0x36, 0x51, 0xa9, 0xe4, 0xa7, 0x79,
|
||||||
0x53, 0x21, 0x4e, 0xe3, 0x4d, 0x2e, 0x09, 0x71, 0x19, 0xde, 0x2a, 0x19, 0x97, 0xe6, 0x2a, 0x17,
|
0x9d, 0x4a, 0x4c, 0x1c, 0x86, 0x53, 0x25, 0xa7, 0xd2, 0x5a, 0xa5, 0x82, 0x9f, 0x97, 0xee, 0xcb,
|
||||||
0xfc, 0x79, 0xe9, 0xbc, 0x48, 0x47, 0x84, 0xf9, 0xe7, 0xa6, 0xfb, 0xff, 0xeb, 0x00, 0xfd, 0x56,
|
0x64, 0x4c, 0x98, 0x77, 0x96, 0x56, 0xff, 0xbf, 0x6d, 0xa0, 0x5f, 0xaa, 0xd0, 0x39, 0x1c, 0x47,
|
||||||
0x86, 0xf6, 0xd1, 0x28, 0x0e, 0xd3, 0x28, 0x37, 0xe5, 0xb2, 0x87, 0xe7, 0xa6, 0x5c, 0xda, 0xdc,
|
0x41, 0x12, 0x16, 0xba, 0x5c, 0xd6, 0xf0, 0x5c, 0x97, 0x4b, 0x99, 0xfb, 0xd0, 0x95, 0x5f, 0x4f,
|
||||||
0x83, 0x8e, 0xfc, 0xf5, 0x54, 0x66, 0x72, 0xb8, 0xac, 0xf9, 0x56, 0xe7, 0x5f, 0x2d, 0xe7, 0x9c,
|
0x25, 0x26, 0x9b, 0xcb, 0x9c, 0x2f, 0x75, 0x7e, 0x6b, 0x39, 0xe3, 0x98, 0x95, 0x60, 0xb1, 0xbd,
|
||||||
0xb3, 0x32, 0xcc, 0x8f, 0x57, 0xa6, 0xfd, 0x3e, 0x87, 0xee, 0x58, 0x26, 0xa2, 0x2c, 0x65, 0x29,
|
0x72, 0xe5, 0xf7, 0x29, 0xf4, 0x26, 0x32, 0x10, 0x25, 0x29, 0x53, 0x79, 0x57, 0x7b, 0xce, 0x00,
|
||||||
0xef, 0xe8, 0xc8, 0x33, 0x82, 0x07, 0xd9, 0x84, 0xe5, 0x10, 0xbd, 0x80, 0xcd, 0xb9, 0xcd, 0xfc,
|
0xee, 0xe7, 0x03, 0x96, 0x4d, 0xf4, 0x12, 0x36, 0xe7, 0x36, 0x8b, 0xbd, 0x64, 0xe5, 0x7b, 0xa9,
|
||||||
0x2c, 0xd9, 0xd9, 0x59, 0x6a, 0x1f, 0x6e, 0x29, 0xd8, 0xac, 0x97, 0x18, 0xb0, 0x08, 0x6a, 0x92,
|
0x73, 0xb0, 0xa5, 0xcc, 0xe6, 0xb5, 0x44, 0x83, 0x85, 0x50, 0x97, 0x78, 0xde, 0x83, 0x9e, 0x2f,
|
||||||
0xcf, 0x07, 0xd0, 0x0d, 0xe4, 0x8f, 0x8e, 0x51, 0xa2, 0x92, 0x71, 0xcc, 0xfd, 0x20, 0xa1, 0x1a,
|
0x3f, 0x3a, 0x29, 0x13, 0xb5, 0x9c, 0x62, 0xe1, 0x83, 0x84, 0x6c, 0x38, 0x02, 0xdf, 0x42, 0x36,
|
||||||
0xae, 0xe0, 0xb7, 0x50, 0x8d, 0xac, 0xb6, 0x58, 0x0f, 0xde, 0x11, 0x68, 0x36, 0x8d, 0x94, 0xfc,
|
0xf2, 0xdc, 0x62, 0x3e, 0x78, 0x45, 0xa0, 0xd8, 0x2c, 0x54, 0xf4, 0x0f, 0xe5, 0x75, 0x6d, 0xd1,
|
||||||
0x03, 0xf9, 0xb9, 0xb6, 0xe8, 0xa1, 0x70, 0xf8, 0x7b, 0x1d, 0x2a, 0x4f, 0x8e, 0xbf, 0xb6, 0x5e,
|
0x43, 0xe1, 0xe0, 0xd7, 0x06, 0xd4, 0x9e, 0x1e, 0x7d, 0x69, 0xbe, 0x81, 0xf5, 0xd2, 0xcb, 0xc5,
|
||||||
0xc3, 0x7a, 0xe1, 0xd5, 0x63, 0xe9, 0x6b, 0x65, 0xf1, 0xdb, 0x6a, 0xf0, 0xf6, 0xb2, 0x63, 0xf5,
|
0xd4, 0x63, 0x65, 0xf1, 0x73, 0x6a, 0xf8, 0xff, 0x65, 0xc7, 0xea, 0xe2, 0xb0, 0xc6, 0x6d, 0x96,
|
||||||
0xe1, 0xb0, 0xc6, 0x31, 0x0b, 0x5f, 0x15, 0x06, 0x73, 0xf1, 0x07, 0x8b, 0xc1, 0x5c, 0xf6, 0x31,
|
0x6e, 0x15, 0xa9, 0xcd, 0xc5, 0x17, 0x96, 0xd4, 0xe6, 0xb2, 0xcb, 0xc8, 0x9a, 0xf9, 0x31, 0x34,
|
||||||
0xb2, 0x66, 0x7d, 0x0a, 0x75, 0xf9, 0x18, 0xb2, 0xb6, 0x95, 0x6d, 0xee, 0x55, 0x35, 0xd8, 0x29,
|
0xe4, 0x63, 0xc8, 0xdc, 0x56, 0xb2, 0x85, 0x57, 0xd5, 0x70, 0xa7, 0xb4, 0x9b, 0x2a, 0xbe, 0x82,
|
||||||
0xec, 0x1a, 0xc7, 0x97, 0xd0, 0xcd, 0xbd, 0x1e, 0xad, 0x1b, 0xb9, 0x58, 0xf9, 0xb7, 0xd4, 0xe0,
|
0x5e, 0xe1, 0xc1, 0x68, 0xde, 0x2c, 0xf8, 0x2a, 0xbe, 0xa5, 0x86, 0xff, 0x5b, 0x7c, 0x98, 0x5a,
|
||||||
0xad, 0xc5, 0x87, 0x06, 0xed, 0x08, 0x60, 0xf6, 0x86, 0xb1, 0xfa, 0xca, 0x7a, 0xee, 0x4d, 0x36,
|
0x3b, 0x04, 0xc8, 0x1e, 0x25, 0xe6, 0x40, 0x49, 0xcf, 0xbd, 0xc9, 0x86, 0x7b, 0x0b, 0x4e, 0x52,
|
||||||
0xd8, 0x5f, 0x70, 0x62, 0x40, 0xce, 0x60, 0xa3, 0xf8, 0xea, 0xb0, 0x0a, 0xaa, 0x16, 0xdf, 0x08,
|
0x23, 0xa7, 0xb0, 0x51, 0x7e, 0x75, 0x98, 0x25, 0x56, 0xcb, 0x6f, 0x84, 0xe1, 0xed, 0xa5, 0xe7,
|
||||||
0x83, 0x5b, 0x4b, 0xcf, 0xb3, 0xb0, 0xc5, 0xb7, 0x87, 0x81, 0x5d, 0xf2, 0x92, 0x31, 0xb0, 0x4b,
|
0x79, 0xb3, 0xe5, 0xb7, 0x47, 0x6a, 0x76, 0xc9, 0x4b, 0x26, 0x35, 0xbb, 0xf4, 0xd1, 0xb2, 0x66,
|
||||||
0x1f, 0x2d, 0x6b, 0xd6, 0x77, 0xd0, 0xcb, 0x3f, 0x1b, 0x2c, 0x2d, 0xd2, 0xc2, 0xd7, 0xcc, 0xe0,
|
0x7e, 0x03, 0xfd, 0xe2, 0xb3, 0xc1, 0xd4, 0x24, 0x2d, 0x7c, 0xcd, 0x0c, 0x6f, 0x2d, 0x39, 0x4d,
|
||||||
0xe6, 0x92, 0x53, 0x03, 0xf8, 0x91, 0x1c, 0x04, 0xfc, 0x72, 0xd1, 0x35, 0xcb, 0xbc, 0x29, 0x06,
|
0x0d, 0x7e, 0x20, 0x1b, 0x01, 0x6f, 0x2e, 0x3a, 0x67, 0xb9, 0x37, 0xc5, 0x70, 0xbb, 0xb8, 0x99,
|
||||||
0xdb, 0xf9, 0x4d, 0xe3, 0xf5, 0x00, 0xea, 0xf2, 0x7b, 0xd4, 0x34, 0x40, 0xee, 0xf3, 0x74, 0xd0,
|
0x6a, 0x3d, 0x84, 0x86, 0xbc, 0x8f, 0xa6, 0x05, 0x50, 0xb8, 0x9e, 0x0e, 0xbb, 0xf9, 0x5d, 0x6b,
|
||||||
0xc9, 0xee, 0xda, 0x6b, 0x0f, 0x4a, 0x78, 0xe7, 0x35, 0x9f, 0x13, 0x26, 0xa7, 0x23, 0x1b, 0x6a,
|
0xed, 0x61, 0x05, 0x67, 0x5e, 0xeb, 0x05, 0x61, 0xb2, 0x3b, 0xf2, 0xae, 0xe6, 0x54, 0xc4, 0x26,
|
||||||
0xce, 0x45, 0x6c, 0x72, 0x97, 0xf3, 0xba, 0xf8, 0xe7, 0xc6, 0xc3, 0x7f, 0x02, 0x00, 0x00, 0xff,
|
0x57, 0x39, 0x6b, 0x88, 0xff, 0x33, 0x1e, 0xfd, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xe9, 0x8d, 0xe9,
|
||||||
0xff, 0xb2, 0xd2, 0x28, 0x97, 0xe9, 0x10, 0x00, 0x00,
|
0x67, 0xdc, 0x10, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,14 +30,13 @@ message UpdateProcessResponse {
|
||||||
message CreateContainerRequest {
|
message CreateContainerRequest {
|
||||||
string id = 1; // ID of container
|
string id = 1; // ID of container
|
||||||
string bundlePath = 2; // path to OCI bundle
|
string bundlePath = 2; // path to OCI bundle
|
||||||
string checkpoint = 7; // checkpoint name if you want to create immediate checkpoint (optional)
|
string checkpoint = 3; // checkpoint name if you want to create immediate checkpoint (optional)
|
||||||
|
string stdin = 4; // path to the file where stdin will be read (optional)
|
||||||
|
string stdout = 5; // path to file where stdout will be written (optional)
|
||||||
|
string stderr = 6; // path to file where stderr will be written (optional)
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateContainerResponse {
|
message CreateContainerResponse {
|
||||||
uint32 pid = 1; // PID of the containers main process
|
|
||||||
string stdin = 2; // path to the file where stdin will be read (optional)
|
|
||||||
string stdout = 3; // path to file where stdout will be written (optional)
|
|
||||||
string stderr = 4; // path to file where stderr will be written (optional)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message SignalRequest {
|
message SignalRequest {
|
||||||
|
@ -57,7 +56,10 @@ message AddProcessRequest {
|
||||||
repeated string env = 5; // List of environment variables for process
|
repeated string env = 5; // List of environment variables for process
|
||||||
string cwd = 6; // Workind directory of process
|
string cwd = 6; // Workind directory of process
|
||||||
string pid = 7; // Process ID
|
string pid = 7; // Process ID
|
||||||
};
|
string stdin = 8; // path to the file where stdin will be read (optional)
|
||||||
|
string stdout = 9; // path to file where stdout will be written (optional)
|
||||||
|
string stderr = 10; // path to file where stderr will be written (optional)
|
||||||
|
}
|
||||||
|
|
||||||
message User {
|
message User {
|
||||||
uint32 uid = 1; // UID of user
|
uint32 uid = 1; // UID of user
|
||||||
|
@ -66,9 +68,6 @@ message User {
|
||||||
}
|
}
|
||||||
|
|
||||||
message AddProcessResponse {
|
message AddProcessResponse {
|
||||||
string stdin = 1; // path to the file where stdin will be read (optional)
|
|
||||||
string stdout = 2; // path to file where stdout will be written (optional)
|
|
||||||
string stderr = 3; // path to file where stderr will be written (optional)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateCheckpointRequest {
|
message CreateCheckpointRequest {
|
||||||
|
|
|
@ -41,7 +41,6 @@ func main() {
|
||||||
// or if runc exits before we hit the handler
|
// or if runc exits before we hit the handler
|
||||||
signals := make(chan os.Signal, 2048)
|
signals := make(chan os.Signal, 2048)
|
||||||
signal.Notify(signals)
|
signal.Notify(signals)
|
||||||
setupLogger()
|
|
||||||
// set the shim as the subreaper for all orphaned processes created by the container
|
// set the shim as the subreaper for all orphaned processes created by the container
|
||||||
if err := util.SetSubreaper(1); err != nil {
|
if err := util.SetSubreaper(1); err != nil {
|
||||||
logrus.WithField("error", err).Fatal("shim: set as subreaper")
|
logrus.WithField("error", err).Fatal("shim: set as subreaper")
|
||||||
|
|
|
@ -12,20 +12,19 @@ import (
|
||||||
|
|
||||||
"github.com/docker/containerd/runtime"
|
"github.com/docker/containerd/runtime"
|
||||||
"github.com/opencontainers/runc/libcontainer"
|
"github.com/opencontainers/runc/libcontainer"
|
||||||
"github.com/opencontainers/specs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type process struct {
|
type process struct {
|
||||||
id string
|
id string
|
||||||
bundle string
|
bundle string
|
||||||
stdio *stdio
|
stdio *stdio
|
||||||
s specs.Process
|
|
||||||
exec bool
|
exec bool
|
||||||
containerPid int
|
containerPid int
|
||||||
checkpoint *runtime.Checkpoint
|
checkpoint *runtime.Checkpoint
|
||||||
shimIO *IO
|
shimIO *IO
|
||||||
console libcontainer.Console
|
console libcontainer.Console
|
||||||
consolePath string
|
consolePath string
|
||||||
|
state *runtime.ProcessState
|
||||||
}
|
}
|
||||||
|
|
||||||
func newProcess(id, bundle string, exec bool, checkpoint string) (*process, error) {
|
func newProcess(id, bundle string, exec bool, checkpoint string) (*process, error) {
|
||||||
|
@ -38,7 +37,7 @@ func newProcess(id, bundle string, exec bool, checkpoint string) (*process, erro
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
p.s = *s
|
p.state = s
|
||||||
if checkpoint != "" {
|
if checkpoint != "" {
|
||||||
cpt, err := loadCheckpoint(bundle, checkpoint)
|
cpt, err := loadCheckpoint(bundle, checkpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -52,13 +51,13 @@ func newProcess(id, bundle string, exec bool, checkpoint string) (*process, erro
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadProcess() (*specs.Process, error) {
|
func loadProcess() (*runtime.ProcessState, error) {
|
||||||
f, err := os.Open("process.json")
|
f, err := os.Open("process.json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
var s specs.Process
|
var s runtime.ProcessState
|
||||||
if err := json.NewDecoder(f).Decode(&s); err != nil {
|
if err := json.NewDecoder(f).Decode(&s); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -158,20 +157,24 @@ func (p *process) delete() error {
|
||||||
// in RDWR so that they remain open if the other side stops listening
|
// in RDWR so that they remain open if the other side stops listening
|
||||||
func (p *process) openIO() error {
|
func (p *process) openIO() error {
|
||||||
p.stdio = &stdio{}
|
p.stdio = &stdio{}
|
||||||
if p.s.Terminal {
|
var (
|
||||||
|
uid = int(p.state.User.UID)
|
||||||
|
gid = int(p.state.User.GID)
|
||||||
|
)
|
||||||
|
if p.state.Terminal {
|
||||||
// FIXME: this is wrong for user namespaces and will need to be translated
|
// FIXME: this is wrong for user namespaces and will need to be translated
|
||||||
console, err := libcontainer.NewConsole(int(p.s.User.UID), int(p.s.User.GID))
|
console, err := libcontainer.NewConsole(uid, gid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.console = console
|
p.console = console
|
||||||
p.consolePath = console.Path()
|
p.consolePath = console.Path()
|
||||||
stdin, err := os.OpenFile("stdin", syscall.O_RDWR, 0)
|
stdin, err := os.OpenFile(p.state.Stdin, syscall.O_RDWR, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
go io.Copy(console, stdin)
|
go io.Copy(console, stdin)
|
||||||
stdout, err := os.OpenFile("stdout", syscall.O_RDWR, 0)
|
stdout, err := os.OpenFile(p.state.Stdout, syscall.O_RDWR, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -181,20 +184,20 @@ func (p *process) openIO() error {
|
||||||
}()
|
}()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
i, err := p.initializeIO(int(p.s.User.UID))
|
i, err := p.initializeIO(uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.shimIO = i
|
p.shimIO = i
|
||||||
// non-tty
|
// non-tty
|
||||||
for name, dest := range map[string]func(f *os.File){
|
for name, dest := range map[string]func(f *os.File){
|
||||||
"stdin": func(f *os.File) {
|
p.state.Stdin: func(f *os.File) {
|
||||||
go io.Copy(i.Stdin, f)
|
go io.Copy(i.Stdin, f)
|
||||||
},
|
},
|
||||||
"stdout": func(f *os.File) {
|
p.state.Stdout: func(f *os.File) {
|
||||||
go io.Copy(f, i.Stdout)
|
go io.Copy(f, i.Stdout)
|
||||||
},
|
},
|
||||||
"stderr": func(f *os.File) {
|
p.state.Stderr: func(f *os.File) {
|
||||||
go io.Copy(f, i.Stderr)
|
go io.Copy(f, i.Stderr)
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
|
|
|
@ -46,7 +46,7 @@ var daemonFlags = []cli.Flag{
|
||||||
},
|
},
|
||||||
cli.DurationFlag{
|
cli.DurationFlag{
|
||||||
Name: "metrics-interval",
|
Name: "metrics-interval",
|
||||||
Value: 60 * time.Second,
|
Value: 120 * time.Second,
|
||||||
Usage: "interval for flushing metrics to the store",
|
Usage: "interval for flushing metrics to the store",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
|
|
186
ctr/container.go
186
ctr/container.go
|
@ -50,7 +50,6 @@ var containersCommand = cli.Command{
|
||||||
listCommand,
|
listCommand,
|
||||||
startCommand,
|
startCommand,
|
||||||
statsCommand,
|
statsCommand,
|
||||||
attachCommand,
|
|
||||||
},
|
},
|
||||||
Action: listContainers,
|
Action: listContainers,
|
||||||
}
|
}
|
||||||
|
@ -81,77 +80,6 @@ func listContainers(context *cli.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var attachCommand = cli.Command{
|
|
||||||
Name: "attach",
|
|
||||||
Usage: "attach to a running container",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "state-dir",
|
|
||||||
Value: "/run/containerd",
|
|
||||||
Usage: "runtime state directory",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
|
||||||
Name: "pid,p",
|
|
||||||
Value: "init",
|
|
||||||
Usage: "specify the process id to attach to",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Action: func(context *cli.Context) {
|
|
||||||
var (
|
|
||||||
id = context.Args().First()
|
|
||||||
pid = context.String("pid")
|
|
||||||
)
|
|
||||||
if id == "" {
|
|
||||||
fatal("container id cannot be empty", 1)
|
|
||||||
}
|
|
||||||
c := getClient(context)
|
|
||||||
type bundleState struct {
|
|
||||||
Bundle string `json:"bundle"`
|
|
||||||
}
|
|
||||||
f, err := os.Open(filepath.Join(context.String("state-dir"), id, "state.json"))
|
|
||||||
if err != nil {
|
|
||||||
fatal(err.Error(), 1)
|
|
||||||
}
|
|
||||||
var s bundleState
|
|
||||||
err = json.NewDecoder(f).Decode(&s)
|
|
||||||
f.Close()
|
|
||||||
if err != nil {
|
|
||||||
fatal(err.Error(), 1)
|
|
||||||
}
|
|
||||||
mkterm, err := readTermSetting(s.Bundle)
|
|
||||||
if err != nil {
|
|
||||||
fatal(err.Error(), 1)
|
|
||||||
}
|
|
||||||
if mkterm {
|
|
||||||
s, err := term.SetRawTerminal(os.Stdin.Fd())
|
|
||||||
if err != nil {
|
|
||||||
fatal(err.Error(), 1)
|
|
||||||
}
|
|
||||||
state = s
|
|
||||||
}
|
|
||||||
if err := attachStdio(
|
|
||||||
filepath.Join(context.String("state-dir"), id, pid, "stdin"),
|
|
||||||
filepath.Join(context.String("state-dir"), id, pid, "stdout"),
|
|
||||||
filepath.Join(context.String("state-dir"), id, pid, "stderr"),
|
|
||||||
); err != nil {
|
|
||||||
fatal(err.Error(), 1)
|
|
||||||
}
|
|
||||||
closer := func() {
|
|
||||||
if state != nil {
|
|
||||||
term.RestoreTerminal(os.Stdin.Fd(), state)
|
|
||||||
}
|
|
||||||
stdin.Close()
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
io.Copy(stdin, os.Stdin)
|
|
||||||
closer()
|
|
||||||
}()
|
|
||||||
if err := waitForExit(c, id, "init", closer); err != nil {
|
|
||||||
fatal(err.Error(), 1)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var startCommand = cli.Command{
|
var startCommand = cli.Command{
|
||||||
Name: "start",
|
Name: "start",
|
||||||
Usage: "start a container",
|
Usage: "start a container",
|
||||||
|
@ -181,17 +109,22 @@ var startCommand = cli.Command{
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal(fmt.Sprintf("cannot get the absolute path of the bundle: %v", err), 1)
|
fatal(fmt.Sprintf("cannot get the absolute path of the bundle: %v", err), 1)
|
||||||
}
|
}
|
||||||
c := getClient(context)
|
s, err := createStdio()
|
||||||
r := &types.CreateContainerRequest{
|
|
||||||
Id: id,
|
|
||||||
BundlePath: bpath,
|
|
||||||
Checkpoint: context.String("checkpoint"),
|
|
||||||
}
|
|
||||||
resp, err := c.CreateContainer(netcontext.Background(), r)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal(err.Error(), 1)
|
fatal(err.Error(), 1)
|
||||||
}
|
}
|
||||||
var tty bool
|
var (
|
||||||
|
tty bool
|
||||||
|
c = getClient(context)
|
||||||
|
r = &types.CreateContainerRequest{
|
||||||
|
Id: id,
|
||||||
|
BundlePath: bpath,
|
||||||
|
Checkpoint: context.String("checkpoint"),
|
||||||
|
Stdin: s.stdin,
|
||||||
|
Stdout: s.stdout,
|
||||||
|
Stderr: s.stderr,
|
||||||
|
}
|
||||||
|
)
|
||||||
if context.Bool("attach") {
|
if context.Bool("attach") {
|
||||||
mkterm, err := readTermSetting(bpath)
|
mkterm, err := readTermSetting(bpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -205,10 +138,17 @@ var startCommand = cli.Command{
|
||||||
}
|
}
|
||||||
state = s
|
state = s
|
||||||
}
|
}
|
||||||
if err := attachStdio(resp.Stdin, resp.Stdout, resp.Stderr); err != nil {
|
if err := attachStdio(s); err != nil {
|
||||||
fatal(err.Error(), 1)
|
fatal(err.Error(), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
events, err := c.Events(netcontext.Background(), &types.EventsRequest{})
|
||||||
|
if err != nil {
|
||||||
|
fatal(err.Error(), 1)
|
||||||
|
}
|
||||||
|
if _, err := c.CreateContainer(netcontext.Background(), r); err != nil {
|
||||||
|
fatal(err.Error(), 1)
|
||||||
|
}
|
||||||
if context.Bool("attach") {
|
if context.Bool("attach") {
|
||||||
restoreAndCloseStdin := func() {
|
restoreAndCloseStdin := func() {
|
||||||
if state != nil {
|
if state != nil {
|
||||||
|
@ -239,7 +179,7 @@ var startCommand = cli.Command{
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
if err := waitForExit(c, id, "init", restoreAndCloseStdin); err != nil {
|
if err := waitForExit(c, events, id, "init", restoreAndCloseStdin); err != nil {
|
||||||
fatal(err.Error(), 1)
|
fatal(err.Error(), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,20 +222,19 @@ func readTermSetting(path string) (bool, error) {
|
||||||
return spec.Process.Terminal, nil
|
return spec.Process.Terminal, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func attachStdio(stdins, stdout, stderr string) error {
|
func attachStdio(s stdio) error {
|
||||||
stdinf, err := os.OpenFile(stdins, syscall.O_WRONLY, 0)
|
stdinf, err := os.OpenFile(s.stdin, syscall.O_RDWR, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// FIXME: assign to global
|
||||||
stdin = stdinf
|
stdin = stdinf
|
||||||
|
stdoutf, err := os.OpenFile(s.stdout, syscall.O_RDWR, 0)
|
||||||
stdoutf, err := os.OpenFile(stdout, syscall.O_RDWR, 0)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
go io.Copy(os.Stdout, stdoutf)
|
go io.Copy(os.Stdout, stdoutf)
|
||||||
|
stderrf, err := os.OpenFile(s.stderr, syscall.O_RDWR, 0)
|
||||||
stderrf, err := os.OpenFile(stderr, syscall.O_RDWR, 0)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -374,22 +313,24 @@ var execCommand = cli.Command{
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) {
|
Action: func(context *cli.Context) {
|
||||||
p := &types.AddProcessRequest{
|
p := &types.AddProcessRequest{
|
||||||
|
Id: context.String("id"),
|
||||||
Pid: context.String("pid"),
|
Pid: context.String("pid"),
|
||||||
Args: context.Args(),
|
Args: context.Args(),
|
||||||
Cwd: context.String("cwd"),
|
Cwd: context.String("cwd"),
|
||||||
Terminal: context.Bool("tty"),
|
Terminal: context.Bool("tty"),
|
||||||
Id: context.String("id"),
|
|
||||||
Env: context.StringSlice("env"),
|
Env: context.StringSlice("env"),
|
||||||
User: &types.User{
|
User: &types.User{
|
||||||
Uid: uint32(context.Int("uid")),
|
Uid: uint32(context.Int("uid")),
|
||||||
Gid: uint32(context.Int("gid")),
|
Gid: uint32(context.Int("gid")),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
c := getClient(context)
|
s, err := createStdio()
|
||||||
resp, err := c.AddProcess(netcontext.Background(), p)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal(err.Error(), 1)
|
fatal(err.Error(), 1)
|
||||||
}
|
}
|
||||||
|
p.Stdin = s.stdin
|
||||||
|
p.Stdout = s.stdout
|
||||||
|
p.Stderr = s.stderr
|
||||||
if context.Bool("attach") {
|
if context.Bool("attach") {
|
||||||
if context.Bool("tty") {
|
if context.Bool("tty") {
|
||||||
s, err := term.SetRawTerminal(os.Stdin.Fd())
|
s, err := term.SetRawTerminal(os.Stdin.Fd())
|
||||||
|
@ -398,10 +339,18 @@ var execCommand = cli.Command{
|
||||||
}
|
}
|
||||||
state = s
|
state = s
|
||||||
}
|
}
|
||||||
if err := attachStdio(resp.Stdin, resp.Stdout, resp.Stderr); err != nil {
|
if err := attachStdio(s); err != nil {
|
||||||
fatal(err.Error(), 1)
|
fatal(err.Error(), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
c := getClient(context)
|
||||||
|
events, err := c.Events(netcontext.Background(), &types.EventsRequest{})
|
||||||
|
if err != nil {
|
||||||
|
fatal(err.Error(), 1)
|
||||||
|
}
|
||||||
|
if _, err := c.AddProcess(netcontext.Background(), p); err != nil {
|
||||||
|
fatal(err.Error(), 1)
|
||||||
|
}
|
||||||
if context.Bool("attach") {
|
if context.Bool("attach") {
|
||||||
restoreAndCloseStdin := func() {
|
restoreAndCloseStdin := func() {
|
||||||
if state != nil {
|
if state != nil {
|
||||||
|
@ -411,9 +360,28 @@ var execCommand = cli.Command{
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
io.Copy(stdin, os.Stdin)
|
io.Copy(stdin, os.Stdin)
|
||||||
|
if _, err := c.UpdateProcess(netcontext.Background(), &types.UpdateProcessRequest{
|
||||||
|
Id: p.Id,
|
||||||
|
Pid: p.Pid,
|
||||||
|
CloseStdin: true,
|
||||||
|
}); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
restoreAndCloseStdin()
|
restoreAndCloseStdin()
|
||||||
}()
|
}()
|
||||||
if err := waitForExit(c, context.String("id"), context.String("pid"), restoreAndCloseStdin); err != nil {
|
if context.Bool("tty") {
|
||||||
|
resize(p.Id, p.Pid, c)
|
||||||
|
go func() {
|
||||||
|
s := make(chan os.Signal, 64)
|
||||||
|
signal.Notify(s, syscall.SIGWINCH)
|
||||||
|
for range s {
|
||||||
|
if err := resize(p.Id, p.Pid, c); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
if err := waitForExit(c, events, context.String("id"), context.String("pid"), restoreAndCloseStdin); err != nil {
|
||||||
fatal(err.Error(), 1)
|
fatal(err.Error(), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -442,11 +410,7 @@ var statsCommand = cli.Command{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitForExit(c types.APIClient, id, pid string, closer func()) error {
|
func waitForExit(c types.APIClient, events types.API_EventsClient, id, pid string, closer func()) error {
|
||||||
events, err := c.Events(netcontext.Background(), &types.EventsRequest{})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for {
|
for {
|
||||||
e, err := events.Recv()
|
e, err := events.Recv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -461,3 +425,29 @@ func waitForExit(c types.APIClient, id, pid string, closer func()) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type stdio struct {
|
||||||
|
stdin string
|
||||||
|
stdout string
|
||||||
|
stderr string
|
||||||
|
}
|
||||||
|
|
||||||
|
func createStdio() (s stdio, err error) {
|
||||||
|
tmp, err := ioutil.TempDir("", "ctr-")
|
||||||
|
if err != nil {
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
// create fifo's for the process
|
||||||
|
for name, fd := range map[string]*string{
|
||||||
|
"stdin": &s.stdin,
|
||||||
|
"stdout": &s.stdout,
|
||||||
|
"stderr": &s.stderr,
|
||||||
|
} {
|
||||||
|
path := filepath.Join(tmp, name)
|
||||||
|
if err := syscall.Mkfifo(path, 0755); err != nil && !os.IsExist(err) {
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
*fd = path
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
|
@ -19,9 +19,9 @@ type Container interface {
|
||||||
// Path returns the path to the bundle
|
// Path returns the path to the bundle
|
||||||
Path() string
|
Path() string
|
||||||
// Start starts the init process of the container
|
// Start starts the init process of the container
|
||||||
Start(checkpoint string) (Process, error)
|
Start(checkpoint string, s Stdio) (Process, error)
|
||||||
// Exec starts another process in an existing container
|
// Exec starts another process in an existing container
|
||||||
Exec(string, specs.Process) (Process, error)
|
Exec(string, specs.Process, Stdio) (Process, error)
|
||||||
// Delete removes the container's state and any resources
|
// Delete removes the container's state and any resources
|
||||||
Delete() error
|
Delete() error
|
||||||
// Processes returns all the containers processes that have been added
|
// Processes returns all the containers processes that have been added
|
||||||
|
@ -45,6 +45,12 @@ type Container interface {
|
||||||
// OOM() (<-chan struct{}, error)
|
// OOM() (<-chan struct{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Stdio struct {
|
||||||
|
Stdin string
|
||||||
|
Stdout string
|
||||||
|
Stderr string
|
||||||
|
}
|
||||||
|
|
||||||
// New returns a new container
|
// New returns a new container
|
||||||
func New(root, id, bundle string) (Container, error) {
|
func New(root, id, bundle string) (Container, error) {
|
||||||
c := &container{
|
c := &container{
|
||||||
|
@ -94,11 +100,11 @@ func Load(root, id string) (Container, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pid := d.Name()
|
pid := d.Name()
|
||||||
s, err := readProcessSpec(filepath.Join(root, id, pid))
|
s, err := readProcessState(filepath.Join(root, id, pid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
p, err := loadProcess(filepath.Join(root, id, pid), pid, c, *s)
|
p, err := loadProcess(filepath.Join(root, id, pid), pid, c, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithField("id", id).WithField("pid", pid).Debug("containerd: error loading process %s", err)
|
logrus.WithField("id", id).WithField("pid", pid).Debug("containerd: error loading process %s", err)
|
||||||
continue
|
continue
|
||||||
|
@ -108,13 +114,13 @@ func Load(root, id string) (Container, error) {
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readProcessSpec(dir string) (*specs.Process, error) {
|
func readProcessState(dir string) (*ProcessState, error) {
|
||||||
f, err := os.Open(filepath.Join(dir, "process.json"))
|
f, err := os.Open(filepath.Join(dir, "process.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
var s specs.Process
|
var s ProcessState
|
||||||
if err := json.NewDecoder(f).Decode(&s); err != nil {
|
if err := json.NewDecoder(f).Decode(&s); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -127,6 +133,7 @@ type container struct {
|
||||||
id string
|
id string
|
||||||
bundle string
|
bundle string
|
||||||
processes map[string]*process
|
processes map[string]*process
|
||||||
|
stdio Stdio
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) ID() string {
|
func (c *container) ID() string {
|
||||||
|
@ -137,12 +144,15 @@ func (c *container) Path() string {
|
||||||
return c.bundle
|
return c.bundle
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) Start(checkpoint string) (Process, error) {
|
func (c *container) Start(checkpoint string, s Stdio) (Process, error) {
|
||||||
processRoot := filepath.Join(c.root, c.id, InitProcessID)
|
processRoot := filepath.Join(c.root, c.id, InitProcessID)
|
||||||
if err := os.MkdirAll(processRoot, 0755); err != nil {
|
if err := os.Mkdir(processRoot, 0755); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cmd := exec.Command("containerd-shim", "-checkpoint", checkpoint, c.id, c.bundle)
|
cmd := exec.Command("containerd-shim",
|
||||||
|
"-checkpoint", checkpoint,
|
||||||
|
c.id, c.bundle,
|
||||||
|
)
|
||||||
cmd.Dir = processRoot
|
cmd.Dir = processRoot
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||||
Setpgid: true,
|
Setpgid: true,
|
||||||
|
@ -151,7 +161,7 @@ func (c *container) Start(checkpoint string) (Process, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
p, err := newProcess(processRoot, InitProcessID, c, spec.Process)
|
p, err := newProcess(processRoot, InitProcessID, c, spec.Process, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -165,17 +175,20 @@ func (c *container) Start(checkpoint string) (Process, error) {
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) Exec(pid string, spec specs.Process) (Process, error) {
|
func (c *container) Exec(pid string, spec specs.Process, s Stdio) (Process, error) {
|
||||||
processRoot := filepath.Join(c.root, c.id, pid)
|
processRoot := filepath.Join(c.root, c.id, pid)
|
||||||
if err := os.MkdirAll(processRoot, 0755); err != nil {
|
if err := os.Mkdir(processRoot, 0755); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cmd := exec.Command("containerd-shim", "-exec", c.id, c.bundle)
|
cmd := exec.Command("containerd-shim",
|
||||||
|
"-exec",
|
||||||
|
c.id, c.bundle,
|
||||||
|
)
|
||||||
cmd.Dir = processRoot
|
cmd.Dir = processRoot
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||||
Setpgid: true,
|
Setpgid: true,
|
||||||
}
|
}
|
||||||
p, err := newProcess(processRoot, pid, c, spec)
|
p, err := newProcess(processRoot, pid, c, spec, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -228,7 +241,7 @@ func (c *container) Processes() ([]Process, error) {
|
||||||
|
|
||||||
func (c *container) RemoveProcess(pid string) error {
|
func (c *container) RemoveProcess(pid string) error {
|
||||||
delete(c.processes, pid)
|
delete(c.processes, pid)
|
||||||
return nil
|
return os.RemoveAll(filepath.Join(c.root, c.id, pid))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) Checkpoints() ([]Checkpoint, error) {
|
func (c *container) Checkpoints() ([]Checkpoint, error) {
|
||||||
|
|
|
@ -21,19 +21,14 @@ type Process interface {
|
||||||
// This is either "init" when it is the container's init process or
|
// This is either "init" when it is the container's init process or
|
||||||
// it is a user provided id for the process similar to the container id
|
// it is a user provided id for the process similar to the container id
|
||||||
ID() string
|
ID() string
|
||||||
// Stdin returns the path the the processes stdin fifo
|
|
||||||
Stdin() string
|
|
||||||
CloseStdin() error
|
CloseStdin() error
|
||||||
Resize(int, int) error
|
Resize(int, int) error
|
||||||
// Stdout returns the path the the processes stdout fifo
|
|
||||||
Stdout() string
|
|
||||||
// Stderr returns the path the the processes stderr fifo
|
|
||||||
Stderr() string
|
|
||||||
// ExitFD returns the fd the provides an event when the process exits
|
// ExitFD returns the fd the provides an event when the process exits
|
||||||
ExitFD() int
|
ExitFD() int
|
||||||
// ExitStatus returns the exit status of the process or an error if it
|
// ExitStatus returns the exit status of the process or an error if it
|
||||||
// has not exited
|
// has not exited
|
||||||
ExitStatus() (int, error)
|
ExitStatus() (int, error)
|
||||||
|
// Spec returns the process spec that created the process
|
||||||
Spec() specs.Process
|
Spec() specs.Process
|
||||||
// Signal sends the provided signal to the process
|
// Signal sends the provided signal to the process
|
||||||
Signal(os.Signal) error
|
Signal(os.Signal) error
|
||||||
|
@ -41,33 +36,27 @@ type Process interface {
|
||||||
Container() Container
|
Container() Container
|
||||||
}
|
}
|
||||||
|
|
||||||
func newProcess(root, id string, c *container, s specs.Process) (*process, error) {
|
func newProcess(root, id string, c *container, s specs.Process, stdio Stdio) (*process, error) {
|
||||||
p := &process{
|
p := &process{
|
||||||
root: root,
|
root: root,
|
||||||
id: id,
|
id: id,
|
||||||
container: c,
|
container: c,
|
||||||
spec: s,
|
spec: s,
|
||||||
|
stdio: stdio,
|
||||||
}
|
}
|
||||||
f, err := os.Create(filepath.Join(root, "process.json"))
|
f, err := os.Create(filepath.Join(root, "process.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
if err := json.NewEncoder(f).Encode(s); err != nil {
|
if err := json.NewEncoder(f).Encode(ProcessState{
|
||||||
|
Process: s,
|
||||||
|
Stdin: stdio.Stdin,
|
||||||
|
Stdout: stdio.Stdout,
|
||||||
|
Stderr: stdio.Stderr,
|
||||||
|
}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// create fifo's for the process
|
|
||||||
for name, fd := range map[string]*string{
|
|
||||||
"stdin": &p.stdin,
|
|
||||||
"stdout": &p.stdout,
|
|
||||||
"stderr": &p.stderr,
|
|
||||||
} {
|
|
||||||
path := filepath.Join(root, name)
|
|
||||||
if err := syscall.Mkfifo(path, 0755); err != nil && !os.IsExist(err) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
*fd = path
|
|
||||||
}
|
|
||||||
exit, err := getExitPipe(filepath.Join(root, ExitFile))
|
exit, err := getExitPipe(filepath.Join(root, ExitFile))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -81,15 +70,17 @@ func newProcess(root, id string, c *container, s specs.Process) (*process, error
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadProcess(root, id string, c *container, s specs.Process) (*process, error) {
|
func loadProcess(root, id string, c *container, s *ProcessState) (*process, error) {
|
||||||
p := &process{
|
p := &process{
|
||||||
root: root,
|
root: root,
|
||||||
id: id,
|
id: id,
|
||||||
container: c,
|
container: c,
|
||||||
spec: s,
|
spec: s.Process,
|
||||||
stdin: filepath.Join(root, "stdin"),
|
stdio: Stdio{
|
||||||
stdout: filepath.Join(root, "stdout"),
|
Stdin: s.Stdin,
|
||||||
stderr: filepath.Join(root, "stderr"),
|
Stdout: s.Stdout,
|
||||||
|
Stderr: s.Stderr,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
if _, err := p.ExitStatus(); err != nil {
|
if _, err := p.ExitStatus(); err != nil {
|
||||||
if err == ErrProcessNotExited {
|
if err == ErrProcessNotExited {
|
||||||
|
@ -122,18 +113,14 @@ func getControlPipe(path string) (*os.File, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type process struct {
|
type process struct {
|
||||||
root string
|
root string
|
||||||
id string
|
id string
|
||||||
pid int
|
pid int
|
||||||
// stdio fifos
|
|
||||||
stdin string
|
|
||||||
stdout string
|
|
||||||
stderr string
|
|
||||||
|
|
||||||
exitPipe *os.File
|
exitPipe *os.File
|
||||||
controlPipe *os.File
|
controlPipe *os.File
|
||||||
container *container
|
container *container
|
||||||
spec specs.Process
|
spec specs.Process
|
||||||
|
stdio Stdio
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *process) ID() string {
|
func (p *process) ID() string {
|
||||||
|
@ -182,18 +169,6 @@ func (p *process) Spec() specs.Process {
|
||||||
return p.spec
|
return p.spec
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *process) Stdin() string {
|
|
||||||
return p.stdin
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *process) Stdout() string {
|
|
||||||
return p.stdout
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *process) Stderr() string {
|
|
||||||
return p.stderr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes any open files and/or resouces on the process
|
// Close closes any open files and/or resouces on the process
|
||||||
func (p *process) Close() error {
|
func (p *process) Close() error {
|
||||||
return p.exitPipe.Close()
|
return p.exitPipe.Close()
|
||||||
|
|
|
@ -3,6 +3,8 @@ package runtime
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/opencontainers/specs"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -35,6 +37,16 @@ const (
|
||||||
|
|
||||||
type state struct {
|
type state struct {
|
||||||
Bundle string `json:"bundle"`
|
Bundle string `json:"bundle"`
|
||||||
|
Stdin string `json:"stdin"`
|
||||||
|
Stdout string `json:"stdout"`
|
||||||
|
Stderr string `json:"stderr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProcessState struct {
|
||||||
|
specs.Process
|
||||||
|
Stdin string `json:"containerdStdin"`
|
||||||
|
Stdout string `json:"containerdStdout"`
|
||||||
|
Stderr string `json:"containerdStderr"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Stat struct {
|
type Stat struct {
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package supervisor
|
package supervisor
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/docker/containerd/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
type AddProcessEvent struct {
|
type AddProcessEvent struct {
|
||||||
s *Supervisor
|
s *Supervisor
|
||||||
|
@ -14,7 +18,11 @@ func (h *AddProcessEvent) Handle(e *Event) error {
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrContainerNotFound
|
return ErrContainerNotFound
|
||||||
}
|
}
|
||||||
process, err := ci.container.Exec(e.Pid, *e.ProcessSpec)
|
process, err := ci.container.Exec(e.Pid, *e.ProcessSpec, runtime.Stdio{
|
||||||
|
Stdin: e.Stdin,
|
||||||
|
Stdout: e.Stdout,
|
||||||
|
Stderr: e.Stderr,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -22,10 +30,6 @@ func (h *AddProcessEvent) Handle(e *Event) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ExecProcessTimer.UpdateSince(start)
|
ExecProcessTimer.UpdateSince(start)
|
||||||
e.StartResponse <- StartResponse{
|
e.StartResponse <- StartResponse{}
|
||||||
Stdin: process.Stdin(),
|
|
||||||
Stdout: process.Stdout(),
|
|
||||||
Stderr: process.Stderr(),
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,9 @@ func (h *StartEvent) Handle(e *Event) error {
|
||||||
Err: e.Err,
|
Err: e.Err,
|
||||||
Container: container,
|
Container: container,
|
||||||
StartResponse: e.StartResponse,
|
StartResponse: e.StartResponse,
|
||||||
|
Stdin: e.Stdin,
|
||||||
|
Stdout: e.Stdout,
|
||||||
|
Stderr: e.Stderr,
|
||||||
}
|
}
|
||||||
if e.Checkpoint != nil {
|
if e.Checkpoint != nil {
|
||||||
task.Checkpoint = e.Checkpoint.Name
|
task.Checkpoint = e.Checkpoint.Name
|
||||||
|
|
|
@ -37,9 +37,6 @@ func NewEvent(t EventType) *Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
type StartResponse struct {
|
type StartResponse struct {
|
||||||
Stdin string
|
|
||||||
Stdout string
|
|
||||||
Stderr string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Event struct {
|
type Event struct {
|
||||||
|
|
|
@ -38,7 +38,11 @@ func (w *worker) Start() {
|
||||||
defer w.wg.Done()
|
defer w.wg.Done()
|
||||||
for t := range w.s.tasks {
|
for t := range w.s.tasks {
|
||||||
started := time.Now()
|
started := time.Now()
|
||||||
process, err := t.Container.Start(t.Checkpoint)
|
process, err := t.Container.Start(t.Checkpoint, runtime.Stdio{
|
||||||
|
Stdin: t.Stdin,
|
||||||
|
Stdout: t.Stdout,
|
||||||
|
Stderr: t.Stderr,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
evt := NewEvent(DeleteEventType)
|
evt := NewEvent(DeleteEventType)
|
||||||
evt.ID = t.Container.ID()
|
evt.ID = t.Container.ID()
|
||||||
|
@ -61,10 +65,6 @@ func (w *worker) Start() {
|
||||||
}
|
}
|
||||||
ContainerStartTimer.UpdateSince(started)
|
ContainerStartTimer.UpdateSince(started)
|
||||||
t.Err <- nil
|
t.Err <- nil
|
||||||
t.StartResponse <- StartResponse{
|
t.StartResponse <- StartResponse{}
|
||||||
Stdin: process.Stdin(),
|
|
||||||
Stdout: process.Stdout(),
|
|
||||||
Stderr: process.Stderr(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue