Rename Events to task in supervisor

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2016-02-11 17:26:24 -08:00
parent d2bf71043f
commit 3dc59d565a
18 changed files with 274 additions and 281 deletions

View file

@ -32,7 +32,7 @@ func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContaine
if c.BundlePath == "" {
return nil, errors.New("empty bundle path")
}
e := supervisor.NewEvent(supervisor.StartContainerEventType)
e := supervisor.NewTask(supervisor.StartContainerTaskType)
e.ID = c.Id
e.BundlePath = c.BundlePath
e.Stdin = c.Stdin
@ -45,7 +45,7 @@ func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContaine
Name: c.Checkpoint,
}
}
s.sv.SendEvent(e)
s.sv.SendTask(e)
if err := <-e.Err; err != nil {
return nil, err
}
@ -60,11 +60,11 @@ func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContaine
}
func (s *apiServer) Signal(ctx context.Context, r *types.SignalRequest) (*types.SignalResponse, error) {
e := supervisor.NewEvent(supervisor.SignalEventType)
e := supervisor.NewTask(supervisor.SignalTaskType)
e.ID = r.Id
e.Pid = r.Pid
e.Signal = syscall.Signal(int(r.Signal))
s.sv.SendEvent(e)
s.sv.SendTask(e)
if err := <-e.Err; err != nil {
return nil, err
}
@ -89,7 +89,7 @@ func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest)
if r.Pid == "" {
return nil, fmt.Errorf("process id cannot be empty")
}
e := supervisor.NewEvent(supervisor.AddProcessEventType)
e := supervisor.NewTask(supervisor.AddProcessTaskType)
e.ID = r.Id
e.Pid = r.Pid
e.ProcessSpec = process
@ -97,7 +97,7 @@ func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest)
e.Stdout = r.Stdout
e.Stderr = r.Stderr
e.StartResponse = make(chan supervisor.StartResponse, 1)
s.sv.SendEvent(e)
s.sv.SendTask(e)
if err := <-e.Err; err != nil {
return nil, err
}
@ -106,7 +106,7 @@ func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest)
}
func (s *apiServer) CreateCheckpoint(ctx context.Context, r *types.CreateCheckpointRequest) (*types.CreateCheckpointResponse, error) {
e := supervisor.NewEvent(supervisor.CreateCheckpointEventType)
e := supervisor.NewTask(supervisor.CreateCheckpointTaskType)
e.ID = r.Id
e.Checkpoint = &runtime.Checkpoint{
Name: r.Checkpoint.Name,
@ -115,7 +115,7 @@ func (s *apiServer) CreateCheckpoint(ctx context.Context, r *types.CreateCheckpo
UnixSockets: r.Checkpoint.UnixSockets,
Shell: r.Checkpoint.Shell,
}
s.sv.SendEvent(e)
s.sv.SendTask(e)
if err := <-e.Err; err != nil {
return nil, err
}
@ -126,12 +126,12 @@ func (s *apiServer) DeleteCheckpoint(ctx context.Context, r *types.DeleteCheckpo
if r.Name == "" {
return nil, errors.New("checkpoint name cannot be empty")
}
e := supervisor.NewEvent(supervisor.DeleteCheckpointEventType)
e := supervisor.NewTask(supervisor.DeleteCheckpointTaskType)
e.ID = r.Id
e.Checkpoint = &runtime.Checkpoint{
Name: r.Name,
}
s.sv.SendEvent(e)
s.sv.SendTask(e)
if err := <-e.Err; err != nil {
return nil, err
}
@ -139,8 +139,8 @@ func (s *apiServer) DeleteCheckpoint(ctx context.Context, r *types.DeleteCheckpo
}
func (s *apiServer) ListCheckpoint(ctx context.Context, r *types.ListCheckpointRequest) (*types.ListCheckpointResponse, error) {
e := supervisor.NewEvent(supervisor.GetContainerEventType)
s.sv.SendEvent(e)
e := supervisor.NewTask(supervisor.GetContainerTaskType)
s.sv.SendTask(e)
if err := <-e.Err; err != nil {
return nil, err
}
@ -173,9 +173,9 @@ func (s *apiServer) ListCheckpoint(ctx context.Context, r *types.ListCheckpointR
}
func (s *apiServer) State(ctx context.Context, r *types.StateRequest) (*types.StateResponse, error) {
e := supervisor.NewEvent(supervisor.GetContainerEventType)
e := supervisor.NewTask(supervisor.GetContainerTaskType)
e.ID = r.Id
s.sv.SendEvent(e)
s.sv.SendTask(e)
if err := <-e.Err; err != nil {
return nil, err
}
@ -245,10 +245,10 @@ func toUint32(its []int) []uint32 {
}
func (s *apiServer) UpdateContainer(ctx context.Context, r *types.UpdateContainerRequest) (*types.UpdateContainerResponse, error) {
e := supervisor.NewEvent(supervisor.UpdateContainerEventType)
e := supervisor.NewTask(supervisor.UpdateContainerTaskType)
e.ID = r.Id
e.State = runtime.State(r.Status)
s.sv.SendEvent(e)
s.sv.SendTask(e)
if err := <-e.Err; err != nil {
return nil, err
}
@ -256,13 +256,13 @@ func (s *apiServer) UpdateContainer(ctx context.Context, r *types.UpdateContaine
}
func (s *apiServer) UpdateProcess(ctx context.Context, r *types.UpdateProcessRequest) (*types.UpdateProcessResponse, error) {
e := supervisor.NewEvent(supervisor.UpdateProcessEventType)
e := supervisor.NewTask(supervisor.UpdateProcessTaskType)
e.ID = r.Id
e.Pid = r.Pid
e.Height = int(r.Height)
e.Width = int(r.Width)
e.CloseStdin = r.CloseStdin
s.sv.SendEvent(e)
s.sv.SendTask(e)
if err := <-e.Err; err != nil {
return nil, err
}
@ -272,37 +272,25 @@ func (s *apiServer) UpdateProcess(ctx context.Context, r *types.UpdateProcessReq
func (s *apiServer) Events(r *types.EventsRequest, stream types.API_EventsServer) error {
events := s.sv.Events()
defer s.sv.Unsubscribe(events)
for evt := range events {
var ev *types.Event
switch evt.Type {
case supervisor.ExitEventType, supervisor.ExecExitEventType:
ev = &types.Event{
Type: "exit",
Id: evt.ID,
Pid: evt.Pid,
Status: uint32(evt.Status),
}
case supervisor.OOMEventType:
ev = &types.Event{
Type: "oom",
Id: evt.ID,
}
}
if ev != nil {
if err := stream.Send(ev); err != nil {
for e := range events {
if err := stream.Send(&types.Event{
Id: e.ID,
Type: e.Type,
Timestamp: uint64(e.Timestamp.Unix()),
Pid: e.Pid,
Status: uint32(e.Status),
}); err != nil {
return err
}
}
}
return nil
}
func (s *apiServer) Stats(ctx context.Context, r *types.StatsRequest) (*types.StatsResponse, error) {
e := supervisor.NewEvent(supervisor.StatsEventType)
e := supervisor.NewTask(supervisor.StatsTaskType)
e.ID = r.Id
e.Stat = make(chan *runtime.Stat, 1)
s.sv.SendEvent(e)
s.sv.SendTask(e)
if err := <-e.Err; err != nil {
return nil, err
}

View file

@ -392,12 +392,8 @@ type Event struct {
Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"`
Id string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"`
Status uint32 `protobuf:"varint,3,opt,name=status" json:"status,omitempty"`
BundlePath string `protobuf:"bytes,4,opt,name=bundlePath" json:"bundlePath,omitempty"`
Pid string `protobuf:"bytes,5,opt,name=pid" json:"pid,omitempty"`
Signal uint32 `protobuf:"varint,7,opt,name=signal" json:"signal,omitempty"`
Process *Process `protobuf:"bytes,8,opt,name=process" json:"process,omitempty"`
Containers []*Container `protobuf:"bytes,9,rep,name=containers" json:"containers,omitempty"`
Checkpoint *Checkpoint `protobuf:"bytes,10,opt,name=checkpoint" json:"checkpoint,omitempty"`
Pid string `protobuf:"bytes,4,opt,name=pid" json:"pid,omitempty"`
Timestamp uint64 `protobuf:"varint,5,opt,name=timestamp" json:"timestamp,omitempty"`
}
func (m *Event) Reset() { *m = Event{} }
@ -405,27 +401,6 @@ func (m *Event) String() string { return proto.CompactTextString(m) }
func (*Event) ProtoMessage() {}
func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} }
func (m *Event) GetProcess() *Process {
if m != nil {
return m.Process
}
return nil
}
func (m *Event) GetContainers() []*Container {
if m != nil {
return m.Containers
}
return nil
}
func (m *Event) GetCheckpoint() *Checkpoint {
if m != nil {
return m.Checkpoint
}
return nil
}
type NetworkStats struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
RxBytes uint64 `protobuf:"varint,2,opt,name=rx_bytes" json:"rx_bytes,omitempty"`
@ -1118,102 +1093,100 @@ var _API_serviceDesc = grpc.ServiceDesc{
}
var fileDescriptor0 = []byte{
// 1542 bytes of a gzipped FileDescriptorProto
// 1517 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x58, 0xd9, 0x6e, 0x1c, 0x45,
0x17, 0xf6, 0xec, 0x33, 0x67, 0x16, 0xdb, 0xed, 0x6d, 0x3c, 0xf9, 0xf3, 0xc7, 0x74, 0x02, 0x89,
0x50, 0x64, 0x05, 0x87, 0x25, 0x04, 0x09, 0x08, 0x4e, 0x44, 0x40, 0x09, 0x58, 0xb1, 0x8d, 0xc4,
0x0d, 0xa3, 0x9e, 0xee, 0x62, 0xa6, 0x71, 0x6f, 0x74, 0x55, 0x7b, 0x79, 0x85, 0x70, 0xcf, 0x5b,
0x20, 0x71, 0xc5, 0x03, 0xf0, 0x04, 0x3c, 0x07, 0x4f, 0xc1, 0xa9, 0xa5, 0x6b, 0xba, 0x7b, 0x16,
0x93, 0x0b, 0x6e, 0x46, 0xaa, 0xaa, 0xb3, 0x7c, 0xe7, 0x3b, 0x4b, 0x57, 0x0d, 0xb4, 0xac, 0xc8,
0xdd, 0x8f, 0xe2, 0x90, 0x85, 0x46, 0x8d, 0x5d, 0x45, 0x84, 0x9a, 0x23, 0xd8, 0x3c, 0x8d, 0x1c,
0x8b, 0x91, 0xa3, 0x38, 0xb4, 0x09, 0xa5, 0xaf, 0xc8, 0xcf, 0x09, 0xa1, 0xcc, 0x00, 0x28, 0xbb,
0x4e, 0xbf, 0xb4, 0x57, 0xba, 0xd7, 0x32, 0xda, 0x50, 0x89, 0x70, 0x51, 0x16, 0x0b, 0x3c, 0xb1,
0xbd, 0x90, 0x92, 0x63, 0xe6, 0xb8, 0x41, 0xbf, 0x82, 0x7b, 0x4d, 0xa3, 0x0b, 0xb5, 0x0b, 0xd7,
0x61, 0x93, 0x7e, 0x15, 0x97, 0x5d, 0xa3, 0x07, 0xf5, 0x09, 0x71, 0xc7, 0x13, 0xd6, 0xaf, 0xf1,
0xb5, 0xb9, 0x03, 0x5b, 0x05, 0x1f, 0x34, 0x0a, 0x03, 0x4a, 0xcc, 0x5f, 0x4a, 0xb0, 0x7d, 0x18,
0x13, 0x3c, 0x39, 0x0c, 0x03, 0x66, 0xb9, 0x01, 0x89, 0xe7, 0xf9, 0xc7, 0xc5, 0x28, 0x09, 0x1c,
0x8f, 0x1c, 0x59, 0xe8, 0x63, 0x0a, 0x63, 0x42, 0xec, 0xb3, 0x28, 0x74, 0x03, 0x26, 0x60, 0xb4,
0x38, 0x0c, 0x2a, 0x50, 0x55, 0xc5, 0x12, 0x61, 0xe0, 0x32, 0x4c, 0x24, 0x8c, 0x74, 0x4d, 0xe2,
0xb8, 0x5f, 0x4f, 0xd7, 0x9e, 0x35, 0x22, 0x1e, 0xed, 0x37, 0xf6, 0x2a, 0xf7, 0x5a, 0xe6, 0xa7,
0xb0, 0x33, 0x03, 0x46, 0x02, 0x35, 0x6e, 0x43, 0xcb, 0x4e, 0x37, 0x05, 0xa8, 0xf6, 0xc1, 0xda,
0xbe, 0x20, 0x70, 0x5f, 0x0b, 0x9b, 0x8f, 0xa0, 0x7b, 0xec, 0x8e, 0x03, 0xcb, 0xbb, 0x96, 0x43,
0x8e, 0x44, 0x48, 0x0a, 0xe0, 0x5d, 0x73, 0x0d, 0x7a, 0xa9, 0xa6, 0x62, 0xe6, 0xf7, 0x12, 0xac,
0x3f, 0x71, 0x9c, 0x25, 0x49, 0x59, 0x83, 0x26, 0x23, 0xb1, 0xef, 0x72, 0x2b, 0x65, 0x91, 0x85,
0x5d, 0xa8, 0x26, 0x14, 0xf1, 0x55, 0x04, 0xbe, 0xb6, 0xc2, 0x77, 0x8a, 0x5b, 0x46, 0x07, 0xaa,
0x56, 0x3c, 0xa6, 0x48, 0x4c, 0x45, 0x62, 0x21, 0xc1, 0x39, 0xb2, 0xa2, 0x16, 0xf6, 0x85, 0xa3,
0x28, 0x51, 0x28, 0x1b, 0x79, 0x3a, 0x9b, 0x05, 0x3a, 0x5b, 0x05, 0x3a, 0x81, 0xaf, 0x31, 0xfc,
0xaa, 0xf0, 0x85, 0x36, 0x12, 0x85, 0xb2, 0xcb, 0x17, 0x63, 0x15, 0x76, 0xd7, 0xd8, 0x86, 0x9e,
0xe5, 0x38, 0x2e, 0x73, 0x43, 0x04, 0xfd, 0xa5, 0xeb, 0x50, 0x84, 0x5a, 0xc1, 0xf0, 0x37, 0xc1,
0xc8, 0xc6, 0xaa, 0x28, 0x78, 0xa1, 0xd3, 0xa1, 0xf3, 0x3c, 0x8f, 0x87, 0xb7, 0x73, 0x85, 0x50,
0x16, 0xb1, 0xaf, 0xa7, 0xb9, 0xd1, 0x07, 0xe6, 0x00, 0xfa, 0xb3, 0xd6, 0x94, 0xa7, 0x87, 0xb0,
0xf3, 0x94, 0x78, 0xe4, 0x3a, 0x4f, 0x48, 0x62, 0x60, 0xf9, 0x44, 0xe6, 0x90, 0x1b, 0x9c, 0x55,
0x52, 0x06, 0x6f, 0xc3, 0xd6, 0x0b, 0x97, 0xb2, 0xa5, 0xe6, 0xcc, 0xef, 0x01, 0xa6, 0x02, 0xda,
0xb8, 0x76, 0x45, 0x2e, 0x5d, 0xa6, 0x12, 0x8b, 0x24, 0x32, 0x3b, 0x52, 0xbd, 0xb6, 0x01, 0xed,
0x24, 0x70, 0x2f, 0x8f, 0x43, 0xfb, 0x8c, 0x30, 0x2a, 0x4a, 0x5d, 0x34, 0x20, 0x9d, 0x10, 0xcf,
0x13, 0x95, 0xde, 0x34, 0x3f, 0x87, 0xed, 0xa2, 0x7f, 0x55, 0xc8, 0xef, 0x40, 0x7b, 0xca, 0x16,
0x45, 0x6f, 0x95, 0x45, 0x74, 0x75, 0x8e, 0x19, 0xb2, 0x35, 0x0f, 0xf8, 0x1e, 0xf4, 0x74, 0xd1,
0x0b, 0x21, 0x59, 0x0a, 0x16, 0x4b, 0xa8, 0x92, 0xf8, 0xad, 0x04, 0x0d, 0x95, 0xce, 0xb4, 0xa4,
0xfe, 0xc3, 0xa2, 0x5d, 0x87, 0x16, 0xbd, 0xa2, 0x8c, 0xf8, 0x47, 0xaa, 0x74, 0xbb, 0x6f, 0x5a,
0xba, 0xaf, 0x4b, 0xd0, 0xd2, 0x21, 0x2d, 0xce, 0x79, 0x61, 0x10, 0xc9, 0xa1, 0xf3, 0x16, 0xb4,
0x22, 0x19, 0x2a, 0x91, 0x50, 0xdb, 0x07, 0x3d, 0x15, 0x45, 0x4a, 0xc1, 0x94, 0x9e, 0x5a, 0x61,
0xf0, 0xd4, 0x45, 0x34, 0xe8, 0x24, 0xe2, 0xdd, 0xd0, 0x10, 0xdd, 0x70, 0x17, 0x1a, 0x2f, 0x2d,
0x7b, 0x82, 0x50, 0xf8, 0x81, 0x1d, 0x29, 0x56, 0xc5, 0x58, 0xf5, 0x89, 0x1f, 0xc6, 0x57, 0x02,
0x4d, 0xd5, 0xfc, 0x0e, 0xe7, 0x8d, 0xcc, 0x91, 0x4a, 0xee, 0x1d, 0x6c, 0x85, 0x34, 0x8a, 0x34,
0xb7, 0x33, 0x63, 0xca, 0xb8, 0x05, 0x0d, 0x5f, 0xda, 0x57, 0xdd, 0x92, 0xc2, 0x55, 0x5e, 0xcd,
0x27, 0xb0, 0x2d, 0xc7, 0xf5, 0xd2, 0xa1, 0x3c, 0x33, 0xd0, 0x64, 0x84, 0x82, 0x14, 0x73, 0x17,
0x76, 0x66, 0x4c, 0xa8, 0xde, 0x58, 0x85, 0xee, 0xb3, 0x73, 0x82, 0xc5, 0xa7, 0x8c, 0x9a, 0x7f,
0x95, 0xa0, 0x26, 0x76, 0x78, 0xb8, 0x1c, 0x89, 0x72, 0x20, 0x9d, 0xcd, 0xb3, 0xdf, 0x2d, 0x24,
0xa2, 0x9a, 0x05, 0x54, 0x2b, 0x4c, 0x58, 0x59, 0x10, 0x18, 0xb4, 0xca, 0x92, 0x28, 0x89, 0xd9,
0x1c, 0xe5, 0xb9, 0x6b, 0x2d, 0xe0, 0x2e, 0x3f, 0x6c, 0x60, 0xd1, 0xb0, 0xf9, 0xa3, 0x04, 0x9d,
0x6f, 0x08, 0xbb, 0x08, 0xe3, 0x33, 0x9e, 0x21, 0x5a, 0xe8, 0x6e, 0xec, 0x82, 0xf8, 0x72, 0x38,
0xba, 0x62, 0x58, 0x31, 0x22, 0x95, 0x3c, 0x1e, 0xdc, 0x39, 0xb2, 0x64, 0x4f, 0x57, 0xc4, 0x1e,
0x96, 0xf5, 0xab, 0xcb, 0x21, 0x16, 0x69, 0x18, 0xcb, 0x36, 0x17, 0x62, 0xb8, 0xe5, 0xc4, 0x61,
0x14, 0x11, 0x19, 0x69, 0x95, 0x1b, 0x3b, 0x49, 0x8d, 0xd5, 0x53, 0x29, 0xdc, 0x89, 0x94, 0xb1,
0x46, 0x6a, 0xec, 0x44, 0x1b, 0x6b, 0x66, 0xc4, 0x52, 0x63, 0x2d, 0x51, 0x52, 0x3e, 0x34, 0x0f,
0xa3, 0xe4, 0x94, 0x5a, 0x63, 0xc2, 0x07, 0x0d, 0x0b, 0x99, 0xe5, 0x0d, 0x13, 0xbe, 0x14, 0xd0,
0xab, 0xc6, 0x26, 0x74, 0x22, 0x12, 0x63, 0x51, 0xaa, 0xdd, 0x32, 0x12, 0x55, 0x35, 0x6e, 0xc0,
0x86, 0x58, 0x0e, 0xdd, 0x60, 0x78, 0x46, 0xe2, 0x80, 0x78, 0x7e, 0xe8, 0x10, 0x15, 0xc7, 0x2e,
0xac, 0xeb, 0x43, 0xde, 0xea, 0xe2, 0x48, 0xc4, 0x63, 0x9e, 0x40, 0xef, 0x64, 0x82, 0xb7, 0x11,
0xe6, 0xb9, 0xc1, 0xf8, 0xa9, 0xc5, 0x2c, 0x63, 0x15, 0xf3, 0x44, 0x62, 0x37, 0x74, 0xa8, 0x72,
0x88, 0xda, 0x4c, 0x8a, 0x10, 0x67, 0x98, 0x1e, 0x49, 0xd2, 0xf0, 0x73, 0x32, 0x3d, 0x62, 0xae,
0xaf, 0x1c, 0x9a, 0x3f, 0x88, 0x20, 0x24, 0xf1, 0x26, 0x7e, 0xb8, 0x35, 0x58, 0xf9, 0xe1, 0x5e,
0x4d, 0xf3, 0x95, 0x06, 0xba, 0x0f, 0xab, 0x4c, 0xa3, 0x18, 0x62, 0xd5, 0x5a, 0xaa, 0x31, 0xb6,
0x94, 0x64, 0x1e, 0xa3, 0xf9, 0x19, 0xc0, 0x4b, 0xd1, 0x87, 0x02, 0x31, 0x8e, 0x9a, 0x2c, 0x41,
0x48, 0xb4, 0x6f, 0x5d, 0x6a, 0x76, 0xf8, 0x16, 0xc6, 0xf4, 0xa3, 0xe5, 0x7a, 0xb6, 0xba, 0xa7,
0x54, 0xcd, 0xbf, 0x4b, 0xd0, 0x96, 0x16, 0x24, 0x48, 0x34, 0x61, 0x63, 0xef, 0xa5, 0x26, 0xf6,
0x52, 0x8b, 0xf9, 0x8f, 0x59, 0xc6, 0x27, 0x96, 0x21, 0xbd, 0xb0, 0x22, 0xe5, 0xa5, 0xb2, 0x48,
0xec, 0x2e, 0x74, 0x64, 0x36, 0x94, 0x60, 0x75, 0x91, 0xe0, 0x7d, 0x3e, 0x2e, 0x11, 0x89, 0x98,
0xae, 0xed, 0x83, 0x9b, 0x39, 0x09, 0x81, 0x71, 0x5f, 0xfc, 0x3e, 0x0b, 0x58, 0x7c, 0x35, 0xb8,
0x0f, 0x30, 0x5d, 0xf1, 0xb6, 0x3b, 0x23, 0x57, 0xaa, 0xb2, 0x31, 0x92, 0x73, 0xcb, 0x4b, 0x54,
0xe4, 0x8f, 0xcb, 0x8f, 0x4a, 0xe6, 0xd7, 0xb0, 0xfa, 0x85, 0x77, 0xe6, 0x86, 0x19, 0x15, 0x94,
0xf2, 0xad, 0x9f, 0xc2, 0x58, 0xc5, 0xcb, 0x97, 0x6e, 0x80, 0x4b, 0x49, 0x17, 0xf6, 0x7d, 0x18,
0x4d, 0x6f, 0x74, 0xd2, 0x9e, 0xac, 0x97, 0x3f, 0x2b, 0x00, 0x53, 0x63, 0xc6, 0x63, 0x18, 0xb8,
0xe1, 0x10, 0x4b, 0xea, 0xdc, 0xb5, 0x89, 0x6c, 0x81, 0x61, 0x4c, 0xec, 0x24, 0xa6, 0xee, 0x39,
0x51, 0xf3, 0x6f, 0x5b, 0xc5, 0x52, 0xc4, 0xf0, 0x01, 0x6c, 0x4d, 0x75, 0x9d, 0x8c, 0x5a, 0x79,
0xa9, 0xda, 0x43, 0xd8, 0x40, 0x35, 0x1c, 0x5c, 0x49, 0x4e, 0xa9, 0xb2, 0x54, 0xe9, 0x63, 0xd8,
0xcd, 0xe0, 0xe4, 0x95, 0x9a, 0x51, 0xad, 0x2e, 0x55, 0xfd, 0x10, 0xb6, 0x51, 0xf5, 0xc2, 0x72,
0x59, 0x51, 0xaf, 0xf6, 0x2f, 0x70, 0xfa, 0x24, 0x1e, 0xe7, 0x70, 0xd6, 0x97, 0x2a, 0xbd, 0x07,
0xeb, 0xa8, 0x54, 0xf0, 0xd3, 0xb8, 0x4e, 0x85, 0x12, 0x9b, 0xe1, 0x54, 0xc9, 0xa8, 0x34, 0x97,
0xa9, 0xe0, 0xe7, 0xa5, 0xf3, 0x3c, 0x19, 0x13, 0xe6, 0x8d, 0x74, 0xf5, 0xbf, 0x69, 0x03, 0xbd,
0x2e, 0x43, 0xfb, 0x70, 0x1c, 0x87, 0x49, 0x94, 0xeb, 0x72, 0x59, 0xc3, 0x33, 0x5d, 0x2e, 0x65,
0xee, 0x41, 0x47, 0x7e, 0x3d, 0x95, 0x98, 0x6c, 0x2e, 0x63, 0xb6, 0xd4, 0xf9, 0x1d, 0x69, 0xc4,
0x31, 0x2b, 0xc1, 0x7c, 0x7b, 0x65, 0xca, 0xef, 0x13, 0xe8, 0x4e, 0x64, 0x20, 0x4a, 0x52, 0xa6,
0xf2, 0x4e, 0xea, 0x79, 0x0a, 0x70, 0x3f, 0x1b, 0xb0, 0x6c, 0xa2, 0xe7, 0xb0, 0x3e, 0xb3, 0x99,
0xef, 0x25, 0x33, 0xdb, 0x4b, 0xed, 0x83, 0x0d, 0x65, 0x36, 0xab, 0x25, 0x1a, 0xec, 0x52, 0x5e,
0x03, 0xf4, 0xc5, 0xd9, 0x78, 0x17, 0xba, 0x81, 0xfc, 0xf8, 0x68, 0x46, 0x2a, 0x19, 0x03, 0xb9,
0x0f, 0x13, 0xb2, 0x62, 0x0b, 0x9c, 0x73, 0x59, 0xc9, 0x72, 0x8c, 0x79, 0xe1, 0x95, 0x81, 0x62,
0x7e, 0xa4, 0xd2, 0xa0, 0x2e, 0x89, 0xf3, 0x9e, 0x27, 0x07, 0xbf, 0xd6, 0xa1, 0xf2, 0xe4, 0xe8,
0x2b, 0xe3, 0x15, 0xac, 0x16, 0x1e, 0x55, 0x46, 0x3a, 0x5e, 0xe6, 0xbf, 0xfc, 0x06, 0xff, 0x5f,
0x74, 0xac, 0x2e, 0x10, 0x2b, 0xdc, 0x66, 0xe1, 0x76, 0xa1, 0x6d, 0xce, 0xbf, 0xb8, 0x68, 0x9b,
0x8b, 0x2e, 0x25, 0x2b, 0xc6, 0x47, 0x50, 0x97, 0x4f, 0x30, 0x63, 0x53, 0xc9, 0xe6, 0xde, 0x72,
0x83, 0xad, 0xc2, 0xae, 0x56, 0x7c, 0x01, 0xdd, 0xdc, 0xe3, 0xd6, 0xb8, 0x91, 0xf3, 0x95, 0x7f,
0xc1, 0x0d, 0xfe, 0x37, 0xff, 0x50, 0x5b, 0x3b, 0x04, 0x98, 0x3e, 0x85, 0x8c, 0xbe, 0x92, 0x9e,
0x79, 0x09, 0x0e, 0x76, 0xe7, 0x9c, 0x68, 0x23, 0xa7, 0xb0, 0x56, 0x7c, 0xeb, 0x18, 0x05, 0x56,
0x8b, 0x2f, 0x93, 0xc1, 0xad, 0x85, 0xe7, 0x59, 0xb3, 0xc5, 0x17, 0x8f, 0x36, 0xbb, 0xe0, 0xfd,
0xa4, 0xcd, 0x2e, 0x7c, 0x2a, 0xad, 0x18, 0xdf, 0x42, 0x2f, 0xff, 0x58, 0x31, 0x52, 0x92, 0xe6,
0xbe, 0xa1, 0x06, 0x37, 0x17, 0x9c, 0x6a, 0x83, 0xef, 0x43, 0x4d, 0x3e, 0x4b, 0xd2, 0x8a, 0xcf,
0xbe, 0x64, 0x06, 0x9b, 0xf9, 0x4d, 0xad, 0xf5, 0x00, 0xea, 0xf2, 0x5e, 0xaa, 0x0b, 0x20, 0x77,
0x4d, 0x1d, 0x74, 0xb2, 0xbb, 0xe6, 0xca, 0x83, 0x52, 0xea, 0x87, 0xe6, 0xfc, 0xd0, 0x79, 0x7e,
0x32, 0xc9, 0x19, 0xd5, 0xc5, 0xdf, 0x2f, 0x0f, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x37,
0x3f, 0x0d, 0x8b, 0x11, 0x00, 0x00,
0x50, 0x64, 0x05, 0x87, 0x25, 0x04, 0x09, 0x08, 0x4e, 0x44, 0x40, 0x09, 0x98, 0xd8, 0x46, 0xe2,
0x86, 0x51, 0x4f, 0x77, 0x31, 0xd3, 0xb8, 0x37, 0xba, 0xaa, 0xbd, 0xbc, 0x42, 0xb8, 0xe7, 0x2d,
0x90, 0xb8, 0xe2, 0x01, 0x78, 0x1c, 0x9e, 0x82, 0xd3, 0xb5, 0x4d, 0x77, 0xcf, 0x62, 0x72, 0xc1,
0xcd, 0x48, 0x55, 0x75, 0xce, 0x77, 0xbe, 0xb3, 0x55, 0xf5, 0x19, 0x68, 0x59, 0x91, 0xbb, 0x1f,
0xc5, 0x21, 0x0b, 0x8d, 0x1a, 0xbb, 0x8a, 0x08, 0x35, 0x47, 0xb0, 0x79, 0x1a, 0x39, 0x16, 0x23,
0x47, 0x71, 0x68, 0x13, 0x4a, 0x5f, 0x91, 0x5f, 0x12, 0x42, 0x99, 0x01, 0x50, 0x76, 0x9d, 0x7e,
0x69, 0xaf, 0x74, 0xaf, 0x65, 0xb4, 0xa1, 0x12, 0xe1, 0xa2, 0xcc, 0x17, 0x78, 0x62, 0x7b, 0x21,
0x25, 0xc7, 0xcc, 0x71, 0x83, 0x7e, 0x05, 0xf7, 0x9a, 0x46, 0x17, 0x6a, 0x17, 0xae, 0xc3, 0x26,
0xfd, 0x2a, 0x2e, 0xbb, 0x46, 0x0f, 0xea, 0x13, 0xe2, 0x8e, 0x27, 0xac, 0x5f, 0x4b, 0xd7, 0xe6,
0x0e, 0x6c, 0x15, 0x6c, 0xd0, 0x28, 0x0c, 0x28, 0x31, 0x7f, 0x2d, 0xc1, 0xf6, 0x61, 0x4c, 0xf0,
0xe4, 0x30, 0x0c, 0x98, 0xe5, 0x06, 0x24, 0x9e, 0x67, 0x1f, 0x17, 0xa3, 0x24, 0x70, 0x3c, 0x72,
0x64, 0xa1, 0x8d, 0x29, 0x8d, 0x09, 0xb1, 0xcf, 0xa2, 0xd0, 0x0d, 0x18, 0xa7, 0xd1, 0x4a, 0x69,
0x50, 0xce, 0xaa, 0xca, 0x97, 0x48, 0x03, 0x97, 0x61, 0x22, 0x68, 0xa8, 0x35, 0x89, 0xe3, 0x7e,
0x5d, 0xad, 0x3d, 0x6b, 0x44, 0x3c, 0xda, 0x6f, 0xec, 0x55, 0xee, 0xb5, 0xcc, 0x4f, 0x61, 0x67,
0x86, 0x8c, 0x20, 0x6a, 0xdc, 0x86, 0x96, 0xad, 0x36, 0x39, 0xa9, 0xf6, 0xc1, 0xda, 0x3e, 0x0f,
0xe0, 0xbe, 0x16, 0x36, 0x1f, 0x41, 0xf7, 0xd8, 0x1d, 0x07, 0x96, 0x77, 0x6d, 0x0c, 0x53, 0x26,
0x5c, 0x92, 0x13, 0xef, 0x9a, 0x6b, 0xd0, 0x53, 0x9a, 0x32, 0x32, 0x7f, 0x94, 0x60, 0xfd, 0x89,
0xe3, 0x2c, 0x49, 0xca, 0x1a, 0x34, 0x19, 0x89, 0x7d, 0x37, 0x45, 0x29, 0xf3, 0x2c, 0xec, 0x42,
0x35, 0xa1, 0xc8, 0xaf, 0xc2, 0xf9, 0xb5, 0x25, 0xbf, 0x53, 0xdc, 0x32, 0x3a, 0x50, 0xb5, 0xe2,
0x31, 0xc5, 0xc0, 0x54, 0x04, 0x17, 0x12, 0x9c, 0x63, 0x54, 0xe4, 0xc2, 0xbe, 0x70, 0x64, 0x48,
0x24, 0xcb, 0x46, 0x3e, 0x9c, 0xcd, 0x42, 0x38, 0x5b, 0x85, 0x70, 0x42, 0xba, 0x46, 0xf7, 0xab,
0xdc, 0x16, 0x62, 0x24, 0x92, 0x65, 0x37, 0x5d, 0x8c, 0xa5, 0xdb, 0x5d, 0x63, 0x1b, 0x7a, 0x96,
0xe3, 0xb8, 0xcc, 0x0d, 0x91, 0xf4, 0x97, 0xae, 0x43, 0x91, 0x6a, 0x05, 0xdd, 0xdf, 0x04, 0x23,
0xeb, 0xab, 0x0c, 0xc1, 0x0b, 0x9d, 0x0e, 0x9d, 0xe7, 0x79, 0x71, 0x78, 0x3b, 0x57, 0x08, 0x65,
0xee, 0xfb, 0xba, 0xca, 0x8d, 0x3e, 0x30, 0x07, 0xd0, 0x9f, 0x45, 0x93, 0x96, 0x1e, 0xc2, 0xce,
0x53, 0xe2, 0x91, 0xeb, 0x2c, 0x61, 0x10, 0x03, 0xcb, 0x27, 0x22, 0x87, 0x29, 0xe0, 0xac, 0x92,
0x04, 0xbc, 0x0d, 0x5b, 0x2f, 0x5c, 0xca, 0x96, 0xc2, 0x99, 0x3f, 0x00, 0x4c, 0x05, 0x34, 0xb8,
0x36, 0x45, 0x2e, 0x5d, 0x26, 0x13, 0x8b, 0x41, 0x64, 0x76, 0x24, 0x7b, 0x6d, 0x03, 0xda, 0x49,
0xe0, 0x5e, 0x1e, 0x87, 0xf6, 0x19, 0x61, 0x94, 0x97, 0x3a, 0x6f, 0x40, 0x3a, 0x21, 0x9e, 0xc7,
0x2b, 0xbd, 0x69, 0x7e, 0x0e, 0xdb, 0x45, 0xfb, 0xb2, 0x90, 0xdf, 0x81, 0xf6, 0x34, 0x5a, 0x14,
0xad, 0x55, 0x16, 0x85, 0xab, 0x73, 0xcc, 0x30, 0x5a, 0xf3, 0x88, 0xef, 0x41, 0x4f, 0x17, 0x3d,
0x17, 0x12, 0xa5, 0x60, 0xb1, 0x84, 0x4a, 0x89, 0xdf, 0x4b, 0xd0, 0x90, 0xe9, 0x54, 0x25, 0xf5,
0x1f, 0x16, 0xed, 0x3a, 0xb4, 0xe8, 0x15, 0x65, 0xc4, 0x3f, 0x92, 0xa5, 0xdb, 0x7d, 0xd3, 0xd2,
0x7d, 0x5d, 0x82, 0x96, 0x76, 0x69, 0x71, 0xce, 0x0b, 0x17, 0x91, 0xb8, 0x74, 0xde, 0x82, 0x56,
0x24, 0x5c, 0x25, 0x82, 0x6a, 0xfb, 0xa0, 0x27, 0xbd, 0x50, 0x21, 0x98, 0x86, 0xa7, 0x56, 0xb8,
0x78, 0xea, 0xdc, 0x1b, 0x34, 0x12, 0xa5, 0xdd, 0xd0, 0xe0, 0xdd, 0x70, 0x17, 0x1a, 0x2f, 0x2d,
0x7b, 0x82, 0x54, 0xd2, 0x03, 0x3b, 0x92, 0x51, 0xe5, 0xd7, 0xaa, 0x4f, 0xfc, 0x30, 0xbe, 0xe2,
0x6c, 0xaa, 0xe6, 0xf7, 0x78, 0xdf, 0x88, 0x1c, 0xc9, 0xe4, 0xde, 0xc1, 0x56, 0x50, 0x5e, 0xa8,
0xdc, 0xce, 0x5c, 0x53, 0xc6, 0x2d, 0x68, 0xf8, 0x02, 0x5f, 0x76, 0x8b, 0xa2, 0x2b, 0xad, 0x9a,
0x4f, 0x60, 0x5b, 0x5c, 0xd7, 0x4b, 0x2f, 0xe5, 0x99, 0x0b, 0x4d, 0x78, 0xc8, 0x83, 0x62, 0xee,
0xc2, 0xce, 0x0c, 0x84, 0xec, 0x8d, 0x55, 0xe8, 0x3e, 0x3b, 0x27, 0x58, 0x7c, 0x12, 0xd4, 0xfc,
0x0e, 0x6a, 0x7c, 0x23, 0xf5, 0x36, 0x25, 0x22, 0xf1, 0x85, 0xad, 0x79, 0xf0, 0x5d, 0x65, 0xbb,
0xaa, 0xd2, 0xcf, 0x5c, 0x1f, 0x91, 0x2c, 0x3f, 0xe2, 0x01, 0xae, 0x9a, 0x7f, 0x96, 0xa0, 0xf3,
0x0d, 0x61, 0x17, 0x61, 0x7c, 0x96, 0x46, 0x88, 0x16, 0xba, 0x0b, 0xab, 0x30, 0xbe, 0x1c, 0x8e,
0xae, 0x18, 0x66, 0x8c, 0x87, 0x32, 0x4d, 0x2c, 0xee, 0x1c, 0x59, 0xa2, 0xa7, 0x2a, 0x7c, 0x0f,
0x71, 0x5f, 0x5d, 0x0e, 0xb1, 0x48, 0xc2, 0x58, 0xb4, 0x19, 0x17, 0xc3, 0x2d, 0x27, 0x0e, 0xa3,
0x88, 0x38, 0xc2, 0x56, 0x0a, 0x76, 0xa2, 0xc0, 0xea, 0x4a, 0x0a, 0x77, 0x22, 0x09, 0xd6, 0x50,
0x60, 0x27, 0x1a, 0xac, 0x99, 0x11, 0x53, 0x60, 0x2d, 0x4e, 0xdc, 0x87, 0xe6, 0x61, 0x94, 0x9c,
0x52, 0x6b, 0x4c, 0xd2, 0x46, 0x67, 0x21, 0xb3, 0xbc, 0x61, 0x92, 0x2e, 0x39, 0xf5, 0xaa, 0xb1,
0x09, 0x9d, 0x88, 0xc4, 0x58, 0x14, 0x72, 0xb7, 0x8c, 0x49, 0xae, 0x1a, 0x37, 0x60, 0x83, 0x2f,
0x87, 0x6e, 0x30, 0x3c, 0x23, 0x71, 0x40, 0x3c, 0x3f, 0x74, 0x88, 0xf4, 0x63, 0x17, 0xd6, 0xf5,
0x61, 0xda, 0x6a, 0xfc, 0x88, 0xfb, 0x63, 0x9e, 0x40, 0xef, 0x64, 0x82, 0x5f, 0x03, 0xcc, 0x73,
0x83, 0xf1, 0x53, 0x8b, 0x59, 0xc6, 0x2a, 0x34, 0x10, 0xdf, 0x0d, 0x1d, 0x2a, 0x0d, 0xa2, 0x36,
0x13, 0x22, 0xc4, 0x19, 0xaa, 0x23, 0x11, 0x34, 0xbc, 0xce, 0xa7, 0x47, 0x69, 0x0a, 0x84, 0x41,
0xf3, 0x47, 0xee, 0x84, 0x08, 0xbc, 0x89, 0x0f, 0xa7, 0x26, 0x2b, 0x1e, 0xce, 0x55, 0x55, 0x91,
0xca, 0xd1, 0x7d, 0x58, 0x65, 0x9a, 0xc5, 0x10, 0xab, 0xc6, 0x92, 0x85, 0xb9, 0x25, 0x25, 0xf3,
0x1c, 0xcd, 0xcf, 0x00, 0x5e, 0xf2, 0x3e, 0xe0, 0x8c, 0xb1, 0xd5, 0xb3, 0x01, 0xc2, 0x40, 0xfb,
0xd6, 0xa5, 0x8e, 0x4e, 0xba, 0x85, 0x3e, 0xfd, 0x64, 0xb9, 0x9e, 0x2d, 0xbf, 0x13, 0xaa, 0xe6,
0xdf, 0x25, 0x68, 0x0b, 0x04, 0x41, 0x12, 0x21, 0x6c, 0xac, 0x7d, 0x05, 0xb1, 0xa7, 0x10, 0xf3,
0x8f, 0x49, 0xc6, 0x26, 0xbe, 0x39, 0xf4, 0xc2, 0x8a, 0xa4, 0x95, 0xca, 0x22, 0xb1, 0xbb, 0xd0,
0x11, 0xd9, 0x90, 0x82, 0xd5, 0x45, 0x82, 0xf7, 0xd3, 0xeb, 0x0a, 0x99, 0xf0, 0xdb, 0xad, 0x7d,
0x70, 0x33, 0x27, 0xc1, 0x39, 0xee, 0xf3, 0xdf, 0x67, 0x01, 0x8b, 0xaf, 0x06, 0xf7, 0x01, 0xa6,
0xab, 0xb4, 0x17, 0xce, 0xc8, 0x95, 0xac, 0x6c, 0xf4, 0xe4, 0xdc, 0xf2, 0x12, 0xe9, 0xf9, 0xe3,
0xf2, 0xa3, 0x92, 0xf9, 0x35, 0xac, 0x7e, 0xe1, 0x9d, 0xb9, 0x61, 0x46, 0x05, 0xa5, 0x7c, 0xeb,
0xe7, 0x30, 0x96, 0xfe, 0xa6, 0x4b, 0x37, 0xc0, 0xa5, 0x08, 0x17, 0x36, 0x5e, 0x18, 0x4d, 0xbf,
0xa8, 0x04, 0x9e, 0xa8, 0x97, 0xbf, 0x2a, 0x00, 0x53, 0x30, 0xe3, 0x31, 0x0c, 0xdc, 0x70, 0x88,
0x25, 0x75, 0xee, 0xda, 0x44, 0xb4, 0xc0, 0x30, 0x26, 0x76, 0x12, 0x53, 0xf7, 0x9c, 0xc8, 0xfb,
0x67, 0x5b, 0xfa, 0x52, 0xe4, 0xf0, 0x01, 0x6c, 0x4d, 0x75, 0x9d, 0x8c, 0x5a, 0x79, 0xa9, 0xda,
0x43, 0xd8, 0x40, 0x35, 0xbc, 0x38, 0x92, 0x9c, 0x52, 0x65, 0xa9, 0xd2, 0xc7, 0xb0, 0x9b, 0xe1,
0x99, 0x56, 0x6a, 0x46, 0xb5, 0xba, 0x54, 0xf5, 0x43, 0xd8, 0x46, 0xd5, 0x0b, 0xcb, 0x65, 0x45,
0xbd, 0xda, 0xbf, 0xe0, 0xe9, 0x93, 0x78, 0x9c, 0xe3, 0x59, 0x5f, 0xaa, 0xf4, 0x1e, 0xac, 0xa3,
0x52, 0xc1, 0x4e, 0xe3, 0x3a, 0x15, 0x4a, 0x6c, 0x86, 0xb7, 0x4a, 0x46, 0xa5, 0xb9, 0x4c, 0x05,
0xaf, 0xf7, 0xce, 0xf3, 0x64, 0x4c, 0x98, 0x37, 0xd2, 0xd5, 0xff, 0xa6, 0x0d, 0xf4, 0xba, 0x0c,
0xed, 0xc3, 0x71, 0x1c, 0x26, 0x51, 0xae, 0xcb, 0x45, 0x0d, 0xcf, 0x74, 0xb9, 0x90, 0xb9, 0x07,
0x1d, 0xf1, 0x7a, 0x49, 0x31, 0xd1, 0x5c, 0xc6, 0x6c, 0xa9, 0xa7, 0xdf, 0x28, 0xa3, 0x94, 0xb3,
0x14, 0xcc, 0xb7, 0x57, 0xa6, 0xfc, 0x3e, 0x81, 0xee, 0x44, 0x38, 0x22, 0x25, 0x45, 0x2a, 0xef,
0x28, 0xcb, 0x53, 0x82, 0xfb, 0x59, 0x87, 0x45, 0x13, 0x3d, 0x87, 0xf5, 0x99, 0xcd, 0x7c, 0x2f,
0x99, 0xd9, 0x5e, 0x6a, 0x1f, 0x6c, 0x48, 0xd8, 0xac, 0x16, 0x6f, 0xb0, 0x4b, 0xf1, 0x0c, 0xeb,
0x0f, 0x57, 0xe3, 0x5d, 0xe8, 0x06, 0xe2, 0xf1, 0xd1, 0x11, 0xa9, 0x64, 0x00, 0x72, 0x0f, 0x13,
0x46, 0xc5, 0xe6, 0x3c, 0xe7, 0x46, 0x25, 0x1b, 0xe3, 0xdc, 0x33, 0x27, 0xd2, 0x20, 0x3f, 0xd2,
0xe6, 0x8d, 0x07, 0x07, 0xbf, 0xd5, 0xa1, 0xf2, 0xe4, 0xe8, 0x2b, 0xe3, 0x15, 0xac, 0x16, 0x86,
0x1a, 0x43, 0x5d, 0x2f, 0xf3, 0x27, 0xaf, 0xc1, 0xff, 0x17, 0x1d, 0xcb, 0x07, 0x7c, 0x25, 0xc5,
0x2c, 0xbc, 0xee, 0x1a, 0x73, 0xfe, 0x87, 0x83, 0xc6, 0x5c, 0xf4, 0x51, 0xb0, 0x62, 0x7c, 0x04,
0x75, 0x31, 0x02, 0x19, 0x9b, 0x52, 0x36, 0x37, 0x4b, 0x0d, 0xb6, 0x0a, 0xbb, 0x5a, 0xf1, 0x05,
0x74, 0x73, 0xc3, 0xa5, 0x71, 0x23, 0x67, 0x2b, 0x3f, 0x41, 0x0d, 0xfe, 0x37, 0xff, 0x50, 0xa3,
0x1d, 0x02, 0x4c, 0x47, 0x11, 0xa3, 0x2f, 0xa5, 0x67, 0x26, 0xb1, 0xc1, 0xee, 0x9c, 0x13, 0x0d,
0x72, 0x0a, 0x6b, 0xc5, 0x59, 0xc3, 0x28, 0x44, 0xb5, 0x38, 0x19, 0x0c, 0x6e, 0x2d, 0x3c, 0xcf,
0xc2, 0x16, 0x27, 0x0e, 0x0d, 0xbb, 0x60, 0x7e, 0xd1, 0xb0, 0x0b, 0x47, 0x95, 0x15, 0xe3, 0x5b,
0xe8, 0xe5, 0x87, 0x05, 0x43, 0x05, 0x69, 0xee, 0x0c, 0x33, 0xb8, 0xb9, 0xe0, 0x54, 0x03, 0xbe,
0x0f, 0x35, 0x31, 0x16, 0xa8, 0x8a, 0xcf, 0x4e, 0x12, 0x83, 0xcd, 0xfc, 0xa6, 0xd6, 0x7a, 0x00,
0x75, 0xf1, 0x5d, 0xa8, 0x0b, 0x20, 0xf7, 0x99, 0x38, 0xe8, 0x64, 0x77, 0xcd, 0x95, 0x07, 0x25,
0x65, 0x87, 0xe6, 0xec, 0xd0, 0x79, 0x76, 0x32, 0xc9, 0x19, 0xd5, 0xf9, 0xdf, 0x1f, 0x0f, 0xff,
0x09, 0x00, 0x00, 0xff, 0xff, 0x25, 0xa3, 0x4c, 0x3f, 0x0b, 0x11, 0x00, 0x00,
}

View file

@ -163,12 +163,8 @@ message Event {
string type = 1;
string id = 2;
uint32 status = 3;
string bundlePath = 4;
string pid = 5;
uint32 signal = 7;
Process process = 8;
repeated Container containers = 9;
Checkpoint checkpoint = 10;
string pid = 4;
uint64 timestamp = 5;
}
message NetworkStats {

View file

@ -39,11 +39,6 @@ var daemonFlags = []cli.Flag{
Value: "/run/containerd",
Usage: "runtime state directory",
},
cli.IntFlag{
Name: "c,concurrency",
Value: 10,
Usage: "set the concurrency level for tasks",
},
cli.DurationFlag{
Name: "metrics-interval",
Value: 120 * time.Second,
@ -86,7 +81,7 @@ func main() {
if err := daemon(
context.String("listen"),
context.String("state-dir"),
context.Int("concurrency"),
10,
context.Bool("oom-notify"),
); err != nil {
logrus.Fatal(err)
@ -171,8 +166,7 @@ func daemon(address, stateDir string, concurrency int, oom bool) error {
// setup a standard reaper so that we don't leave any zombies if we are still alive
// this is just good practice because we are spawning new processes
go reapProcesses()
tasks := make(chan *supervisor.StartTask, concurrency*100)
sv, err := supervisor.New(stateDir, tasks, oom)
sv, err := supervisor.New(stateDir, oom)
if err != nil {
return err
}

View file

@ -6,13 +6,13 @@ import (
"github.com/docker/containerd/runtime"
)
type AddProcessEvent struct {
type AddProcessTask struct {
s *Supervisor
}
// TODO: add this to worker for concurrent starts??? maybe not because of races where the container
// could be stopped and removed...
func (h *AddProcessEvent) Handle(e *Event) error {
func (h *AddProcessTask) Handle(e *Task) error {
start := time.Now()
ci, ok := h.s.containers[e.ID]
if !ok {
@ -27,5 +27,11 @@ func (h *AddProcessEvent) Handle(e *Event) error {
}
ExecProcessTimer.UpdateSince(start)
e.StartResponse <- StartResponse{}
h.s.notifySubscribers(Event{
Timestamp: time.Now(),
Type: "start-process",
Pid: e.Pid,
ID: e.ID,
})
return nil
}

View file

@ -1,10 +1,10 @@
package supervisor
type CreateCheckpointEvent struct {
type CreateCheckpointTask struct {
s *Supervisor
}
func (h *CreateCheckpointEvent) Handle(e *Event) error {
func (h *CreateCheckpointTask) Handle(e *Task) error {
i, ok := h.s.containers[e.ID]
if !ok {
return ErrContainerNotFound
@ -12,11 +12,11 @@ func (h *CreateCheckpointEvent) Handle(e *Event) error {
return i.container.Checkpoint(*e.Checkpoint)
}
type DeleteCheckpointEvent struct {
type DeleteCheckpointTask struct {
s *Supervisor
}
func (h *DeleteCheckpointEvent) Handle(e *Event) error {
func (h *DeleteCheckpointTask) Handle(e *Task) error {
i, ok := h.s.containers[e.ID]
if !ok {
return ErrContainerNotFound

View file

@ -6,11 +6,11 @@ import (
"github.com/docker/containerd/runtime"
)
type StartEvent struct {
type StartTask struct {
s *Supervisor
}
func (h *StartEvent) Handle(e *Event) error {
func (h *StartTask) Handle(e *Task) error {
start := time.Now()
container, err := runtime.New(h.s.stateDir, e.ID, e.BundlePath, e.Labels)
if err != nil {
@ -20,7 +20,7 @@ func (h *StartEvent) Handle(e *Event) error {
container: container,
}
ContainersCounter.Inc(1)
task := &StartTask{
task := &startTask{
Err: e.Err,
Container: container,
StartResponse: e.StartResponse,

View file

@ -7,18 +7,19 @@ import (
"github.com/docker/containerd/runtime"
)
type DeleteEvent struct {
type DeleteTask struct {
s *Supervisor
}
func (h *DeleteEvent) Handle(e *Event) error {
func (h *DeleteTask) Handle(e *Task) error {
if i, ok := h.s.containers[e.ID]; ok {
start := time.Now()
if err := h.deleteContainer(i.container); err != nil {
logrus.WithField("error", err).Error("containerd: deleting container")
}
h.s.notifySubscribers(&Event{
Type: ExitEventType,
h.s.notifySubscribers(Event{
Type: "exit",
Timestamp: time.Now(),
ID: e.ID,
Status: e.Status,
Pid: e.Pid,
@ -29,7 +30,7 @@ func (h *DeleteEvent) Handle(e *Event) error {
return nil
}
func (h *DeleteEvent) deleteContainer(container runtime.Container) error {
func (h *DeleteTask) deleteContainer(container runtime.Container) error {
delete(h.s.containers, container.ID())
return container.Delete()
}

View file

@ -4,13 +4,13 @@ import "errors"
var (
// External errors
ErrEventChanNil = errors.New("containerd: event channel is nil")
ErrTaskChanNil = errors.New("containerd: task channel is nil")
ErrBundleNotFound = errors.New("containerd: bundle not found")
ErrContainerNotFound = errors.New("containerd: container not found")
ErrContainerExists = errors.New("containerd: container already exists")
ErrProcessNotFound = errors.New("containerd: processs not found for container")
ErrUnknownContainerStatus = errors.New("containerd: unknown container status ")
ErrUnknownEvent = errors.New("containerd: unknown event type")
ErrUnknownTask = errors.New("containerd: unknown task type")
// Internal errors
errShutdown = errors.New("containerd: supervisor is shutdown")

View file

@ -7,11 +7,11 @@ import (
"github.com/docker/containerd/runtime"
)
type ExitEvent struct {
type ExitTask struct {
s *Supervisor
}
func (h *ExitEvent) Handle(e *Event) error {
func (h *ExitTask) Handle(e *Task) error {
start := time.Now()
proc := e.Process
status, err := proc.ExitStatus()
@ -23,37 +23,43 @@ func (h *ExitEvent) Handle(e *Event) error {
// if the process is the the init process of the container then
// fire a separate event for this process
if proc.ID() != runtime.InitProcessID {
ne := NewEvent(ExecExitEventType)
ne := NewTask(ExecExitTaskType)
ne.ID = proc.Container().ID()
ne.Pid = proc.ID()
ne.Status = status
ne.Process = proc
h.s.SendEvent(ne)
h.s.SendTask(ne)
return nil
}
container := proc.Container()
ne := NewEvent(DeleteEventType)
ne := NewTask(DeleteTaskType)
ne.ID = container.ID()
ne.Status = status
ne.Pid = proc.ID()
h.s.SendEvent(ne)
h.s.SendTask(ne)
ExitProcessTimer.UpdateSince(start)
return nil
}
type ExecExitEvent struct {
type ExecExitTask struct {
s *Supervisor
}
func (h *ExecExitEvent) Handle(e *Event) error {
func (h *ExecExitTask) Handle(e *Task) error {
container := e.Process.Container()
// exec process: we remove this process without notifying the main event loop
if err := container.RemoveProcess(e.Pid); err != nil {
logrus.WithField("error", err).Error("containerd: find container for pid")
}
h.s.notifySubscribers(e)
h.s.notifySubscribers(Event{
Timestamp: time.Now(),
ID: e.ID,
Type: "exit",
Pid: e.Pid,
Status: e.Status,
})
return nil
}

View file

@ -1,10 +1,10 @@
package supervisor
type GetContainersEvent struct {
type GetContainersTask struct {
s *Supervisor
}
func (h *GetContainersEvent) Handle(e *Event) error {
func (h *GetContainersTask) Handle(e *Task) error {
if e.ID != "" {
ci := h.s.containers[e.ID]
if ci == nil {

View file

@ -9,7 +9,7 @@ var (
ContainerStatsTimer = metrics.NewTimer()
ContainersCounter = metrics.NewCounter()
EventSubscriberCounter = metrics.NewCounter()
EventsCounter = metrics.NewCounter()
TasksCounter = metrics.NewCounter()
ExecProcessTimer = metrics.NewTimer()
ExitProcessTimer = metrics.NewTimer()
EpollFdCounter = metrics.NewCounter()
@ -23,7 +23,7 @@ func Metrics() map[string]interface{} {
"container-stats-time": ContainerStatsTimer,
"containers": ContainersCounter,
"event-subscribers": EventSubscriberCounter,
"events": EventsCounter,
"tasks": TasksCounter,
"exec-process-time": ExecProcessTimer,
"exit-process-time": ExitProcessTimer,
"epoll-fds": EpollFdCounter,

View file

@ -1,10 +1,10 @@
package supervisor
type SignalEvent struct {
type SignalTask struct {
s *Supervisor
}
func (h *SignalEvent) Handle(e *Event) error {
func (h *SignalTask) Handle(e *Task) error {
i, ok := h.s.containers[e.ID]
if !ok {
return ErrContainerNotFound

View file

@ -2,11 +2,11 @@ package supervisor
import "time"
type StatsEvent struct {
type StatsTask struct {
s *Supervisor
}
func (h *StatsEvent) Handle(e *Event) error {
func (h *StatsTask) Handle(e *Task) error {
start := time.Now()
i, ok := h.s.containers[e.ID]
if !ok {

View file

@ -5,6 +5,7 @@ import (
"os"
"sort"
"sync"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/containerd/chanotify"
@ -17,7 +18,8 @@ const (
)
// New returns an initialized Process supervisor.
func New(stateDir string, tasks chan *StartTask, oom bool) (*Supervisor, error) {
func New(stateDir string, oom bool) (*Supervisor, error) {
tasks := make(chan *startTask, 10)
if err := os.MkdirAll(stateDir, 0755); err != nil {
return nil, err
}
@ -34,7 +36,7 @@ func New(stateDir string, tasks chan *StartTask, oom bool) (*Supervisor, error)
containers: make(map[string]*containerInfo),
tasks: tasks,
machine: machine,
subscribers: make(map[chan *Event]struct{}),
subscribers: make(map[chan Event]struct{}),
el: eventloop.NewChanLoop(defaultBufferSize),
monitor: monitor,
}
@ -42,26 +44,26 @@ func New(stateDir string, tasks chan *StartTask, oom bool) (*Supervisor, error)
s.notifier = chanotify.New()
go func() {
for id := range s.notifier.Chan() {
e := NewEvent(OOMEventType)
e := NewTask(OOMTaskType)
e.ID = id.(string)
s.SendEvent(e)
s.SendTask(e)
}
}()
}
// register default event handlers
s.handlers = map[EventType]Handler{
ExecExitEventType: &ExecExitEvent{s},
ExitEventType: &ExitEvent{s},
StartContainerEventType: &StartEvent{s},
DeleteEventType: &DeleteEvent{s},
GetContainerEventType: &GetContainersEvent{s},
SignalEventType: &SignalEvent{s},
AddProcessEventType: &AddProcessEvent{s},
UpdateContainerEventType: &UpdateEvent{s},
CreateCheckpointEventType: &CreateCheckpointEvent{s},
DeleteCheckpointEventType: &DeleteCheckpointEvent{s},
StatsEventType: &StatsEvent{s},
UpdateProcessEventType: &UpdateProcessEvent{s},
s.handlers = map[TaskType]Handler{
ExecExitTaskType: &ExecExitTask{s},
ExitTaskType: &ExitTask{s},
StartContainerTaskType: &StartTask{s},
DeleteTaskType: &DeleteTask{s},
GetContainerTaskType: &GetContainersTask{s},
SignalTaskType: &SignalTask{s},
AddProcessTaskType: &AddProcessTask{s},
UpdateContainerTaskType: &UpdateTask{s},
CreateCheckpointTaskType: &CreateCheckpointTask{s},
DeleteCheckpointTaskType: &DeleteCheckpointTask{s},
StatsTaskType: &StatsTask{s},
UpdateProcessTaskType: &UpdateProcessTask{s},
}
go s.exitHandler()
if err := s.restore(); err != nil {
@ -78,13 +80,13 @@ type Supervisor struct {
// stateDir is the directory on the system to store container runtime state information.
stateDir string
containers map[string]*containerInfo
handlers map[EventType]Handler
events chan *Event
tasks chan *StartTask
handlers map[TaskType]Handler
events chan *Task
tasks chan *startTask
// we need a lock around the subscribers map only because additions and deletions from
// the map are via the API so we cannot really control the concurrency
subscriberLock sync.RWMutex
subscribers map[chan *Event]struct{}
subscribers map[chan Event]struct{}
machine Machine
notifier *chanotify.Notifier
el eventloop.EventLoop
@ -105,19 +107,27 @@ func (s *Supervisor) Close() error {
return nil
}
type Event struct {
ID string `json:"id"`
Type string `json:"type"`
Timestamp time.Time `json:"timestamp"`
Pid string `json:"pid,omitempty"`
Status int `json:"status,omitempty"`
}
// Events returns an event channel that external consumers can use to receive updates
// on container events
func (s *Supervisor) Events() chan *Event {
func (s *Supervisor) Events() chan Event {
s.subscriberLock.Lock()
defer s.subscriberLock.Unlock()
c := make(chan *Event, defaultBufferSize)
c := make(chan Event, defaultBufferSize)
EventSubscriberCounter.Inc(1)
s.subscribers[c] = struct{}{}
return c
}
// Unsubscribe removes the provided channel from receiving any more events
func (s *Supervisor) Unsubscribe(sub chan *Event) {
func (s *Supervisor) Unsubscribe(sub chan Event) {
s.subscriberLock.Lock()
defer s.subscriberLock.Unlock()
delete(s.subscribers, sub)
@ -127,7 +137,7 @@ func (s *Supervisor) Unsubscribe(sub chan *Event) {
// notifySubscribers will send the provided event to the external subscribers
// of the events channel
func (s *Supervisor) notifySubscribers(e *Event) {
func (s *Supervisor) notifySubscribers(e Event) {
s.subscriberLock.RLock()
defer s.subscriberLock.RUnlock()
for sub := range s.subscribers {
@ -159,17 +169,17 @@ func (s *Supervisor) Machine() Machine {
return s.machine
}
// SendEvent sends the provided event the the supervisors main event loop
func (s *Supervisor) SendEvent(evt *Event) {
EventsCounter.Inc(1)
s.el.Send(&commonEvent{data: evt, sv: s})
// SendTask sends the provided event the the supervisors main event loop
func (s *Supervisor) SendTask(evt *Task) {
TasksCounter.Inc(1)
s.el.Send(&commonTask{data: evt, sv: s})
}
func (s *Supervisor) exitHandler() {
for p := range s.monitor.Exits() {
e := NewEvent(ExitEventType)
e := NewTask(ExitTaskType)
e.Process = p
s.SendEvent(e)
s.SendTask(e)
}
}
@ -215,9 +225,9 @@ func (s *Supervisor) restore() error {
// exit events
sort.Sort(&processSorter{exitedProcesses})
for _, p := range exitedProcesses {
e := NewEvent(ExitEventType)
e := NewTask(ExitTaskType)
e.Process = p
s.SendEvent(e)
s.SendTask(e)
}
}
}

View file

@ -8,26 +8,26 @@ import (
"github.com/opencontainers/specs"
)
type EventType string
type TaskType string
const (
ExecExitEventType EventType = "execExit"
ExitEventType EventType = "exit"
StartContainerEventType EventType = "startContainer"
DeleteEventType EventType = "deleteContainerEvent"
GetContainerEventType EventType = "getContainer"
SignalEventType EventType = "signal"
AddProcessEventType EventType = "addProcess"
UpdateContainerEventType EventType = "updateContainer"
UpdateProcessEventType EventType = "updateProcess"
CreateCheckpointEventType EventType = "createCheckpoint"
DeleteCheckpointEventType EventType = "deleteCheckpoint"
StatsEventType EventType = "events"
OOMEventType EventType = "oom"
ExecExitTaskType TaskType = "execExit"
ExitTaskType TaskType = "exit"
StartContainerTaskType TaskType = "startContainer"
DeleteTaskType TaskType = "deleteContainerEvent"
GetContainerTaskType TaskType = "getContainer"
SignalTaskType TaskType = "signal"
AddProcessTaskType TaskType = "addProcess"
UpdateContainerTaskType TaskType = "updateContainer"
UpdateProcessTaskType TaskType = "updateProcess"
CreateCheckpointTaskType TaskType = "createCheckpoint"
DeleteCheckpointTaskType TaskType = "deleteCheckpoint"
StatsTaskType TaskType = "events"
OOMTaskType TaskType = "oom"
)
func NewEvent(t EventType) *Event {
return &Event{
func NewTask(t TaskType) *Task {
return &Task{
Type: t,
Timestamp: time.Now(),
Err: make(chan error, 1),
@ -38,8 +38,8 @@ type StartResponse struct {
Container runtime.Container
}
type Event struct {
Type EventType
type Task struct {
Type TaskType
Timestamp time.Time
ID string
BundlePath string
@ -66,18 +66,18 @@ type Event struct {
}
type Handler interface {
Handle(*Event) error
Handle(*Task) error
}
type commonEvent struct {
data *Event
type commonTask struct {
data *Task
sv *Supervisor
}
func (e *commonEvent) Handle() {
func (e *commonTask) Handle() {
h, ok := e.sv.handlers[e.data.Type]
if !ok {
e.data.Err <- ErrUnknownEvent
e.data.Err <- ErrUnknownTask
return
}
err := h.Handle(e.data)

View file

@ -1,12 +1,16 @@
package supervisor
import "github.com/docker/containerd/runtime"
import (
"time"
type UpdateEvent struct {
"github.com/docker/containerd/runtime"
)
type UpdateTask struct {
s *Supervisor
}
func (h *UpdateEvent) Handle(e *Event) error {
func (h *UpdateTask) Handle(e *Task) error {
i, ok := h.s.containers[e.ID]
if !ok {
return ErrContainerNotFound
@ -18,10 +22,20 @@ func (h *UpdateEvent) Handle(e *Event) error {
if err := container.Resume(); err != nil {
return ErrUnknownContainerStatus
}
h.s.notifySubscribers(Event{
ID: e.ID,
Type: "resume",
Timestamp: time.Now(),
})
case runtime.Paused:
if err := container.Pause(); err != nil {
return ErrUnknownContainerStatus
}
h.s.notifySubscribers(Event{
ID: e.ID,
Type: "pause",
Timestamp: time.Now(),
})
default:
return ErrUnknownContainerStatus
}
@ -29,11 +43,11 @@ func (h *UpdateEvent) Handle(e *Event) error {
return nil
}
type UpdateProcessEvent struct {
type UpdateProcessTask struct {
s *Supervisor
}
func (h *UpdateProcessEvent) Handle(e *Event) error {
func (h *UpdateProcessTask) Handle(e *Task) error {
i, ok := h.s.containers[e.ID]
if !ok {
return ErrContainerNotFound

View file

@ -12,7 +12,7 @@ type Worker interface {
Start()
}
type StartTask struct {
type startTask struct {
Container runtime.Container
Checkpoint string
Stdin string
@ -40,9 +40,9 @@ func (w *worker) Start() {
started := time.Now()
process, err := t.Container.Start(t.Checkpoint, runtime.NewStdio(t.Stdin, t.Stdout, t.Stderr))
if err != nil {
evt := NewEvent(DeleteEventType)
evt := NewTask(DeleteTaskType)
evt.ID = t.Container.ID()
w.s.SendEvent(evt)
w.s.SendTask(evt)
t.Err <- err
continue
}
@ -64,5 +64,10 @@ func (w *worker) Start() {
t.StartResponse <- StartResponse{
Container: t.Container,
}
w.s.notifySubscribers(Event{
Timestamp: time.Now(),
ID: t.Container.ID(),
Type: "start-container",
})
}
}