Move fifo creation to client
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
		| @@ -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 { | ||||||
| @@ -125,15 +116,11 @@ 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(), |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Michael Crosby
					Michael Crosby