Add update rpc for resource updates

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2016-03-07 15:23:52 -08:00
parent 44d6a60e7e
commit 0dd075a47b
7 changed files with 298 additions and 122 deletions

View file

@ -174,6 +174,40 @@ func (s *apiServer) UpdateContainer(ctx context.Context, r *types.UpdateContaine
e := &supervisor.UpdateTask{} e := &supervisor.UpdateTask{}
e.ID = r.Id e.ID = r.Id
e.State = runtime.State(r.Status) e.State = runtime.State(r.Status)
if r.Resources != nil {
rs := r.Resources
e.Resources = &runtime.Resource{}
if rs.CpuShares != 0 {
e.Resources.CPUShares = int64(rs.CpuShares)
}
if rs.BlkioWeight != 0 {
e.Resources.BlkioWeight = uint16(rs.BlkioWeight)
}
if rs.CpuPeriod != 0 {
e.Resources.CPUPeriod = int64(rs.CpuPeriod)
}
if rs.CpuQuota != 0 {
e.Resources.CPUQuota = int64(rs.CpuQuota)
}
if rs.CpusetCpus != "" {
e.Resources.CpusetCpus = rs.CpusetCpus
}
if rs.CpusetMems != "" {
e.Resources.CpusetMems = rs.CpusetMems
}
if rs.KernelMemoryLimit != 0 {
e.Resources.KernelMemory = int64(rs.KernelMemoryLimit)
}
if rs.MemoryLimit != 0 {
e.Resources.Memory = int64(rs.MemoryLimit)
}
if rs.MemoryReservation != 0 {
e.Resources.MemoryReservation = int64(rs.MemoryReservation)
}
if rs.MemorySwap != 0 {
e.Resources.MemorySwap = int64(rs.MemorySwap)
}
}
s.sv.SendTask(e) s.sv.SendTask(e)
if err := <-e.ErrorCh(); err != nil { if err := <-e.ErrorCh(); err != nil {
return nil, err return nil, err

View file

@ -32,6 +32,7 @@ It has these top-level messages:
Machine Machine
StateResponse StateResponse
UpdateContainerRequest UpdateContainerRequest
UpdateResource
UpdateContainerResponse UpdateContainerResponse
EventsRequest EventsRequest
Event Event
@ -373,6 +374,7 @@ type UpdateContainerRequest struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
Pid string `protobuf:"bytes,2,opt,name=pid" json:"pid,omitempty"` Pid string `protobuf:"bytes,2,opt,name=pid" json:"pid,omitempty"`
Status string `protobuf:"bytes,3,opt,name=status" json:"status,omitempty"` Status string `protobuf:"bytes,3,opt,name=status" json:"status,omitempty"`
Resources *UpdateResource `protobuf:"bytes,4,opt,name=resources" json:"resources,omitempty"`
} }
func (m *UpdateContainerRequest) Reset() { *m = UpdateContainerRequest{} } func (m *UpdateContainerRequest) Reset() { *m = UpdateContainerRequest{} }
@ -380,13 +382,38 @@ func (m *UpdateContainerRequest) String() string { return proto.Compa
func (*UpdateContainerRequest) ProtoMessage() {} func (*UpdateContainerRequest) ProtoMessage() {}
func (*UpdateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } func (*UpdateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} }
func (m *UpdateContainerRequest) GetResources() *UpdateResource {
if m != nil {
return m.Resources
}
return nil
}
type UpdateResource struct {
BlkioWeight uint32 `protobuf:"varint,1,opt,name=blkioWeight" json:"blkioWeight,omitempty"`
CpuShares uint32 `protobuf:"varint,2,opt,name=cpuShares" json:"cpuShares,omitempty"`
CpuPeriod uint32 `protobuf:"varint,3,opt,name=cpuPeriod" json:"cpuPeriod,omitempty"`
CpuQuota uint32 `protobuf:"varint,4,opt,name=cpuQuota" json:"cpuQuota,omitempty"`
CpusetCpus string `protobuf:"bytes,5,opt,name=cpusetCpus" json:"cpusetCpus,omitempty"`
CpusetMems string `protobuf:"bytes,6,opt,name=cpusetMems" json:"cpusetMems,omitempty"`
MemoryLimit uint32 `protobuf:"varint,7,opt,name=memoryLimit" json:"memoryLimit,omitempty"`
MemorySwap uint32 `protobuf:"varint,8,opt,name=memorySwap" json:"memorySwap,omitempty"`
MemoryReservation uint32 `protobuf:"varint,9,opt,name=memoryReservation" json:"memoryReservation,omitempty"`
KernelMemoryLimit uint32 `protobuf:"varint,10,opt,name=kernelMemoryLimit" json:"kernelMemoryLimit,omitempty"`
}
func (m *UpdateResource) Reset() { *m = UpdateResource{} }
func (m *UpdateResource) String() string { return proto.CompactTextString(m) }
func (*UpdateResource) ProtoMessage() {}
func (*UpdateResource) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} }
type UpdateContainerResponse struct { type UpdateContainerResponse struct {
} }
func (m *UpdateContainerResponse) Reset() { *m = UpdateContainerResponse{} } func (m *UpdateContainerResponse) Reset() { *m = UpdateContainerResponse{} }
func (m *UpdateContainerResponse) String() string { return proto.CompactTextString(m) } func (m *UpdateContainerResponse) String() string { return proto.CompactTextString(m) }
func (*UpdateContainerResponse) ProtoMessage() {} func (*UpdateContainerResponse) ProtoMessage() {}
func (*UpdateContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } func (*UpdateContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} }
type EventsRequest struct { type EventsRequest struct {
Timestamp uint64 `protobuf:"varint,1,opt,name=timestamp" json:"timestamp,omitempty"` Timestamp uint64 `protobuf:"varint,1,opt,name=timestamp" json:"timestamp,omitempty"`
@ -395,7 +422,7 @@ type EventsRequest struct {
func (m *EventsRequest) Reset() { *m = EventsRequest{} } func (m *EventsRequest) Reset() { *m = EventsRequest{} }
func (m *EventsRequest) String() string { return proto.CompactTextString(m) } func (m *EventsRequest) String() string { return proto.CompactTextString(m) }
func (*EventsRequest) ProtoMessage() {} func (*EventsRequest) ProtoMessage() {}
func (*EventsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } func (*EventsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} }
type Event struct { type Event struct {
Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"`
@ -408,7 +435,7 @@ type Event struct {
func (m *Event) Reset() { *m = Event{} } func (m *Event) Reset() { *m = Event{} }
func (m *Event) String() string { return proto.CompactTextString(m) } func (m *Event) String() string { return proto.CompactTextString(m) }
func (*Event) ProtoMessage() {} func (*Event) ProtoMessage() {}
func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} }
type NetworkStats struct { type NetworkStats struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
@ -425,7 +452,7 @@ type NetworkStats struct {
func (m *NetworkStats) Reset() { *m = NetworkStats{} } func (m *NetworkStats) Reset() { *m = NetworkStats{} }
func (m *NetworkStats) String() string { return proto.CompactTextString(m) } func (m *NetworkStats) String() string { return proto.CompactTextString(m) }
func (*NetworkStats) ProtoMessage() {} func (*NetworkStats) ProtoMessage() {}
func (*NetworkStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } func (*NetworkStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} }
type CpuUsage struct { type CpuUsage struct {
TotalUsage uint64 `protobuf:"varint,1,opt,name=total_usage" json:"total_usage,omitempty"` TotalUsage uint64 `protobuf:"varint,1,opt,name=total_usage" json:"total_usage,omitempty"`
@ -437,7 +464,7 @@ type CpuUsage struct {
func (m *CpuUsage) Reset() { *m = CpuUsage{} } func (m *CpuUsage) Reset() { *m = CpuUsage{} }
func (m *CpuUsage) String() string { return proto.CompactTextString(m) } func (m *CpuUsage) String() string { return proto.CompactTextString(m) }
func (*CpuUsage) ProtoMessage() {} func (*CpuUsage) ProtoMessage() {}
func (*CpuUsage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } func (*CpuUsage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} }
type ThrottlingData struct { type ThrottlingData struct {
Periods uint64 `protobuf:"varint,1,opt,name=periods" json:"periods,omitempty"` Periods uint64 `protobuf:"varint,1,opt,name=periods" json:"periods,omitempty"`
@ -448,7 +475,7 @@ type ThrottlingData struct {
func (m *ThrottlingData) Reset() { *m = ThrottlingData{} } func (m *ThrottlingData) Reset() { *m = ThrottlingData{} }
func (m *ThrottlingData) String() string { return proto.CompactTextString(m) } func (m *ThrottlingData) String() string { return proto.CompactTextString(m) }
func (*ThrottlingData) ProtoMessage() {} func (*ThrottlingData) ProtoMessage() {}
func (*ThrottlingData) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } func (*ThrottlingData) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} }
type CpuStats struct { type CpuStats struct {
CpuUsage *CpuUsage `protobuf:"bytes,1,opt,name=cpu_usage" json:"cpu_usage,omitempty"` CpuUsage *CpuUsage `protobuf:"bytes,1,opt,name=cpu_usage" json:"cpu_usage,omitempty"`
@ -459,7 +486,7 @@ type CpuStats struct {
func (m *CpuStats) Reset() { *m = CpuStats{} } func (m *CpuStats) Reset() { *m = CpuStats{} }
func (m *CpuStats) String() string { return proto.CompactTextString(m) } func (m *CpuStats) String() string { return proto.CompactTextString(m) }
func (*CpuStats) ProtoMessage() {} func (*CpuStats) ProtoMessage() {}
func (*CpuStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } func (*CpuStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} }
func (m *CpuStats) GetCpuUsage() *CpuUsage { func (m *CpuStats) GetCpuUsage() *CpuUsage {
if m != nil { if m != nil {
@ -485,7 +512,7 @@ type MemoryData struct {
func (m *MemoryData) Reset() { *m = MemoryData{} } func (m *MemoryData) Reset() { *m = MemoryData{} }
func (m *MemoryData) String() string { return proto.CompactTextString(m) } func (m *MemoryData) String() string { return proto.CompactTextString(m) }
func (*MemoryData) ProtoMessage() {} func (*MemoryData) ProtoMessage() {}
func (*MemoryData) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } func (*MemoryData) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} }
type MemoryStats struct { type MemoryStats struct {
Cache uint64 `protobuf:"varint,1,opt,name=cache" json:"cache,omitempty"` Cache uint64 `protobuf:"varint,1,opt,name=cache" json:"cache,omitempty"`
@ -498,7 +525,7 @@ type MemoryStats struct {
func (m *MemoryStats) Reset() { *m = MemoryStats{} } func (m *MemoryStats) Reset() { *m = MemoryStats{} }
func (m *MemoryStats) String() string { return proto.CompactTextString(m) } func (m *MemoryStats) String() string { return proto.CompactTextString(m) }
func (*MemoryStats) ProtoMessage() {} func (*MemoryStats) ProtoMessage() {}
func (*MemoryStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} } func (*MemoryStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} }
func (m *MemoryStats) GetUsage() *MemoryData { func (m *MemoryStats) GetUsage() *MemoryData {
if m != nil { if m != nil {
@ -538,7 +565,7 @@ type BlkioStatsEntry struct {
func (m *BlkioStatsEntry) Reset() { *m = BlkioStatsEntry{} } func (m *BlkioStatsEntry) Reset() { *m = BlkioStatsEntry{} }
func (m *BlkioStatsEntry) String() string { return proto.CompactTextString(m) } func (m *BlkioStatsEntry) String() string { return proto.CompactTextString(m) }
func (*BlkioStatsEntry) ProtoMessage() {} func (*BlkioStatsEntry) ProtoMessage() {}
func (*BlkioStatsEntry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} } func (*BlkioStatsEntry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} }
type BlkioStats struct { type BlkioStats struct {
IoServiceBytesRecursive []*BlkioStatsEntry `protobuf:"bytes,1,rep,name=io_service_bytes_recursive" json:"io_service_bytes_recursive,omitempty"` IoServiceBytesRecursive []*BlkioStatsEntry `protobuf:"bytes,1,rep,name=io_service_bytes_recursive" json:"io_service_bytes_recursive,omitempty"`
@ -554,7 +581,7 @@ type BlkioStats struct {
func (m *BlkioStats) Reset() { *m = BlkioStats{} } func (m *BlkioStats) Reset() { *m = BlkioStats{} }
func (m *BlkioStats) String() string { return proto.CompactTextString(m) } func (m *BlkioStats) String() string { return proto.CompactTextString(m) }
func (*BlkioStats) ProtoMessage() {} func (*BlkioStats) ProtoMessage() {}
func (*BlkioStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } func (*BlkioStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} }
func (m *BlkioStats) GetIoServiceBytesRecursive() []*BlkioStatsEntry { func (m *BlkioStats) GetIoServiceBytesRecursive() []*BlkioStatsEntry {
if m != nil { if m != nil {
@ -622,7 +649,7 @@ type HugetlbStats struct {
func (m *HugetlbStats) Reset() { *m = HugetlbStats{} } func (m *HugetlbStats) Reset() { *m = HugetlbStats{} }
func (m *HugetlbStats) String() string { return proto.CompactTextString(m) } func (m *HugetlbStats) String() string { return proto.CompactTextString(m) }
func (*HugetlbStats) ProtoMessage() {} func (*HugetlbStats) ProtoMessage() {}
func (*HugetlbStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } func (*HugetlbStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} }
type CgroupStats struct { type CgroupStats struct {
CpuStats *CpuStats `protobuf:"bytes,1,opt,name=cpu_stats" json:"cpu_stats,omitempty"` CpuStats *CpuStats `protobuf:"bytes,1,opt,name=cpu_stats" json:"cpu_stats,omitempty"`
@ -634,7 +661,7 @@ type CgroupStats struct {
func (m *CgroupStats) Reset() { *m = CgroupStats{} } func (m *CgroupStats) Reset() { *m = CgroupStats{} }
func (m *CgroupStats) String() string { return proto.CompactTextString(m) } func (m *CgroupStats) String() string { return proto.CompactTextString(m) }
func (*CgroupStats) ProtoMessage() {} func (*CgroupStats) ProtoMessage() {}
func (*CgroupStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } func (*CgroupStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} }
func (m *CgroupStats) GetCpuStats() *CpuStats { func (m *CgroupStats) GetCpuStats() *CpuStats {
if m != nil { if m != nil {
@ -673,7 +700,7 @@ type StatsResponse struct {
func (m *StatsResponse) Reset() { *m = StatsResponse{} } func (m *StatsResponse) Reset() { *m = StatsResponse{} }
func (m *StatsResponse) String() string { return proto.CompactTextString(m) } func (m *StatsResponse) String() string { return proto.CompactTextString(m) }
func (*StatsResponse) ProtoMessage() {} func (*StatsResponse) ProtoMessage() {}
func (*StatsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } func (*StatsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} }
func (m *StatsResponse) GetNetworkStats() []*NetworkStats { func (m *StatsResponse) GetNetworkStats() []*NetworkStats {
if m != nil { if m != nil {
@ -696,7 +723,7 @@ type StatsRequest struct {
func (m *StatsRequest) Reset() { *m = StatsRequest{} } func (m *StatsRequest) Reset() { *m = StatsRequest{} }
func (m *StatsRequest) String() string { return proto.CompactTextString(m) } func (m *StatsRequest) String() string { return proto.CompactTextString(m) }
func (*StatsRequest) ProtoMessage() {} func (*StatsRequest) ProtoMessage() {}
func (*StatsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } func (*StatsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} }
func init() { func init() {
proto.RegisterType((*UpdateProcessRequest)(nil), "types.UpdateProcessRequest") proto.RegisterType((*UpdateProcessRequest)(nil), "types.UpdateProcessRequest")
@ -722,6 +749,7 @@ func init() {
proto.RegisterType((*Machine)(nil), "types.Machine") proto.RegisterType((*Machine)(nil), "types.Machine")
proto.RegisterType((*StateResponse)(nil), "types.StateResponse") proto.RegisterType((*StateResponse)(nil), "types.StateResponse")
proto.RegisterType((*UpdateContainerRequest)(nil), "types.UpdateContainerRequest") proto.RegisterType((*UpdateContainerRequest)(nil), "types.UpdateContainerRequest")
proto.RegisterType((*UpdateResource)(nil), "types.UpdateResource")
proto.RegisterType((*UpdateContainerResponse)(nil), "types.UpdateContainerResponse") proto.RegisterType((*UpdateContainerResponse)(nil), "types.UpdateContainerResponse")
proto.RegisterType((*EventsRequest)(nil), "types.EventsRequest") proto.RegisterType((*EventsRequest)(nil), "types.EventsRequest")
proto.RegisterType((*Event)(nil), "types.Event") proto.RegisterType((*Event)(nil), "types.Event")
@ -1105,106 +1133,113 @@ var _API_serviceDesc = grpc.ServiceDesc{
} }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 1605 bytes of a gzipped FileDescriptorProto // 1723 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x58, 0xeb, 0x6e, 0xdb, 0xc6, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x58, 0xd9, 0x6e, 0xdb, 0x46,
0x12, 0xb6, 0x2e, 0x96, 0xac, 0xd1, 0xc5, 0x36, 0x7d, 0x93, 0x95, 0x93, 0x13, 0x1f, 0x26, 0xe7, 0x17, 0xb6, 0x76, 0xeb, 0x68, 0xb1, 0x4d, 0x6f, 0xb2, 0xf2, 0xe7, 0x8f, 0x7f, 0x26, 0x7f, 0x63,
0x24, 0x38, 0x08, 0x8c, 0xd4, 0xe9, 0x25, 0x4d, 0x81, 0xa2, 0xa9, 0x13, 0x34, 0x2d, 0x9c, 0xd4, 0x14, 0x81, 0x91, 0x3a, 0x5d, 0xd2, 0x14, 0x28, 0x9a, 0x3a, 0x41, 0xd3, 0xc2, 0x49, 0x15, 0x2f,
0x8d, 0xed, 0x02, 0xfd, 0x25, 0x50, 0xe4, 0x46, 0xda, 0x9a, 0x22, 0x59, 0xee, 0xd2, 0x97, 0x57, 0x2d, 0x7a, 0x25, 0x50, 0xe4, 0x44, 0x62, 0x4d, 0x91, 0x2c, 0x67, 0xe8, 0xe5, 0x15, 0x1a, 0xb4,
0x68, 0xd0, 0xfe, 0xec, 0xa3, 0xf4, 0x01, 0xfa, 0x38, 0x7d, 0x8a, 0xce, 0xde, 0x28, 0x92, 0xba, 0x97, 0x7d, 0x94, 0x3e, 0x40, 0x9f, 0xa5, 0x57, 0x7d, 0x8a, 0x9e, 0xd9, 0x28, 0x92, 0x5a, 0x5c,
0xb8, 0x40, 0x51, 0xa0, 0x7f, 0x04, 0xec, 0xee, 0xcc, 0x37, 0xdf, 0x7e, 0x3b, 0x33, 0xdc, 0x15, 0xa0, 0x28, 0xd0, 0x1b, 0x01, 0x33, 0x73, 0xd6, 0xef, 0x9c, 0xef, 0x0c, 0x47, 0x50, 0xb7, 0x42,
0x34, 0x9c, 0x88, 0xee, 0x47, 0x71, 0xc8, 0x43, 0x6b, 0x99, 0x5f, 0x47, 0x84, 0xd9, 0x03, 0xd8, 0x77, 0x3f, 0x8c, 0x02, 0x16, 0x18, 0x15, 0x76, 0x1d, 0x12, 0x6a, 0x0e, 0x60, 0xe3, 0x2c, 0x74,
0x3c, 0x8b, 0x3c, 0x87, 0x93, 0xe3, 0x38, 0x74, 0x09, 0x63, 0x6f, 0xc8, 0x0f, 0x09, 0x61, 0xdc, 0x2c, 0x46, 0x7a, 0x51, 0x60, 0x13, 0x4a, 0x8f, 0xc9, 0x0f, 0x31, 0xa1, 0xcc, 0x00, 0x28, 0xba,
0x02, 0x28, 0x53, 0xaf, 0x5b, 0xda, 0x2b, 0x3d, 0x68, 0x58, 0x4d, 0xa8, 0x44, 0x38, 0x28, 0xcb, 0x4e, 0xa7, 0xb0, 0x5b, 0xd8, 0xab, 0x1b, 0x0d, 0x28, 0x85, 0xb8, 0x28, 0x8a, 0x05, 0x9e, 0xd8,
0x01, 0xae, 0xb8, 0x7e, 0xc8, 0xc8, 0x09, 0xf7, 0x68, 0xd0, 0xad, 0xe0, 0xdc, 0x8a, 0xd5, 0x86, 0x5e, 0x40, 0xc9, 0x09, 0x73, 0x5c, 0xbf, 0x53, 0xc2, 0xbd, 0x65, 0xa3, 0x05, 0x95, 0x4b, 0xd7,
0xe5, 0x4b, 0xea, 0xf1, 0x51, 0xb7, 0x8a, 0xc3, 0xb6, 0xd5, 0x81, 0xda, 0x88, 0xd0, 0xe1, 0x88, 0x61, 0xa3, 0x4e, 0x19, 0x97, 0x2d, 0xa3, 0x0d, 0xd5, 0x11, 0x71, 0x87, 0x23, 0xd6, 0xa9, 0xf0,
0x77, 0x97, 0xc5, 0xd8, 0xde, 0x81, 0xad, 0x42, 0x0c, 0x16, 0x85, 0x01, 0x23, 0xf6, 0xbb, 0x12, 0xb5, 0xb9, 0x0d, 0x9b, 0x39, 0x1f, 0x34, 0x0c, 0x7c, 0x4a, 0xcc, 0xb7, 0x05, 0xd8, 0x3a, 0x8c,
0x6c, 0x1f, 0xc6, 0x04, 0x57, 0x0e, 0xc3, 0x80, 0x3b, 0x34, 0x20, 0xf1, 0xac, 0xf8, 0x38, 0x18, 0x08, 0x9e, 0x1c, 0x06, 0x3e, 0xb3, 0x5c, 0x9f, 0x44, 0xb3, 0xfc, 0xe3, 0x62, 0x10, 0xfb, 0x8e,
0x24, 0x81, 0xe7, 0x93, 0x63, 0x07, 0x63, 0x4c, 0x68, 0x8c, 0x88, 0x7b, 0x1e, 0x85, 0x34, 0xe0, 0x47, 0x7a, 0x16, 0xfa, 0x98, 0x84, 0x31, 0x22, 0xf6, 0x79, 0x18, 0xb8, 0x3e, 0x13, 0x61, 0xd4,
0x92, 0x46, 0x43, 0xd0, 0x60, 0x92, 0x55, 0x55, 0x0e, 0x91, 0x06, 0x0e, 0xc3, 0x44, 0xd1, 0x30, 0x79, 0x18, 0x54, 0x44, 0x55, 0x16, 0x4b, 0x0c, 0x03, 0x97, 0x41, 0x2c, 0xc3, 0xd0, 0x6b, 0x12,
0x63, 0x12, 0xc7, 0xdd, 0x9a, 0x19, 0xfb, 0xce, 0x80, 0xf8, 0xac, 0x5b, 0xdf, 0xab, 0x3c, 0x68, 0x45, 0x9d, 0xaa, 0x5e, 0x7b, 0xd6, 0x80, 0x78, 0xb4, 0x53, 0xdb, 0x2d, 0xed, 0xd5, 0xcd, 0x4f,
0xd8, 0x9f, 0xc2, 0xce, 0x14, 0x19, 0x45, 0xd4, 0xba, 0x0b, 0x0d, 0xd7, 0x4c, 0x4a, 0x52, 0xcd, 0x61, 0x7b, 0x2a, 0x18, 0x19, 0xa8, 0x71, 0x17, 0xea, 0xb6, 0xde, 0x14, 0x41, 0x35, 0x0e, 0x56,
0x83, 0xb5, 0x7d, 0x29, 0xe0, 0x7e, 0x6a, 0x6c, 0x3f, 0x81, 0xf6, 0x09, 0x1d, 0x06, 0x8e, 0x7f, 0xf7, 0x05, 0x80, 0xfb, 0x89, 0xb0, 0xf9, 0x18, 0x5a, 0x27, 0xee, 0xd0, 0xb7, 0xbc, 0x1b, 0x31,
0xa3, 0x86, 0x82, 0x89, 0xb4, 0x94, 0xc4, 0xdb, 0xf6, 0x1a, 0x74, 0x8c, 0xa7, 0x56, 0xe6, 0xe7, 0xe4, 0x91, 0x08, 0x49, 0x11, 0x78, 0xcb, 0x5c, 0x85, 0xb6, 0xd6, 0x54, 0xc8, 0xfc, 0x5c, 0x84,
0x32, 0xac, 0x3f, 0xf3, 0xbc, 0x05, 0x87, 0xb2, 0x06, 0x2b, 0x9c, 0xc4, 0x63, 0x2a, 0x50, 0xca, 0xb5, 0xa7, 0x8e, 0xb3, 0xa0, 0x28, 0xab, 0xb0, 0xcc, 0x48, 0x34, 0x76, 0xb9, 0x95, 0xa2, 0xa8,
0xf2, 0x14, 0x76, 0xa1, 0x9a, 0x30, 0xe4, 0x57, 0x91, 0xfc, 0x9a, 0x9a, 0xdf, 0x19, 0x4e, 0x59, 0xc2, 0x0e, 0x94, 0x63, 0x8a, 0xf1, 0x95, 0x44, 0x7c, 0x0d, 0x15, 0xdf, 0x19, 0x6e, 0x19, 0x4d,
0x2d, 0xa8, 0x3a, 0xf1, 0x90, 0xa1, 0x30, 0x15, 0xc5, 0x85, 0x04, 0x17, 0xa8, 0x8a, 0x1e, 0xb8, 0x28, 0x5b, 0xd1, 0x90, 0x22, 0x30, 0x25, 0x19, 0x0b, 0xf1, 0x2f, 0x10, 0x15, 0xb5, 0xb0, 0x2f,
0x97, 0x9e, 0x96, 0x44, 0xb3, 0xac, 0xe7, 0xe5, 0x5c, 0x29, 0xc8, 0xd9, 0x28, 0xc8, 0x09, 0x72, 0x1d, 0x05, 0x89, 0x8a, 0xb2, 0x96, 0x85, 0x73, 0x39, 0x07, 0x67, 0x3d, 0x07, 0x27, 0x88, 0xf5,
0xbc, 0x09, 0x2d, 0xd7, 0x89, 0x9c, 0x01, 0xf5, 0x29, 0xa7, 0x84, 0x75, 0x9b, 0x12, 0x7e, 0x07, 0x06, 0x34, 0x6d, 0x2b, 0xb4, 0x06, 0xae, 0xe7, 0x32, 0x97, 0xd0, 0x4e, 0x43, 0x98, 0xdf, 0x86,
0x56, 0x9d, 0x28, 0x72, 0xe2, 0x71, 0x18, 0xe3, 0x66, 0xde, 0x52, 0x9f, 0x74, 0x5b, 0xc6, 0x9c, 0x15, 0x2b, 0x0c, 0xad, 0x68, 0x1c, 0x44, 0x98, 0xcc, 0x1b, 0xd7, 0x23, 0x9d, 0xa6, 0x16, 0xa7,
0x11, 0x9f, 0x06, 0xc9, 0xd5, 0x91, 0x38, 0x84, 0x6e, 0x5b, 0xce, 0xa2, 0x79, 0x10, 0xbe, 0x26, 0xc4, 0x73, 0xfd, 0xf8, 0xea, 0x88, 0x17, 0xa1, 0xd3, 0x12, 0xbb, 0x28, 0xee, 0x07, 0xaf, 0xc8,
0x97, 0xc7, 0x31, 0xbd, 0x40, 0xdb, 0x21, 0xe2, 0x74, 0xc4, 0xe6, 0x50, 0xdc, 0xaa, 0xdc, 0x09, 0x65, 0x2f, 0x72, 0x2f, 0x50, 0x76, 0x88, 0x76, 0xda, 0x3c, 0x39, 0x04, 0xb7, 0x2c, 0x32, 0xc1,
0x32, 0x4c, 0xb4, 0x06, 0x6d, 0x31, 0x18, 0x6a, 0x51, 0xdb, 0xd6, 0x36, 0x74, 0x1c, 0xcf, 0xc3, 0x08, 0x63, 0x85, 0x41, 0x8b, 0x2f, 0x86, 0x0a, 0xd4, 0x96, 0xb1, 0x05, 0x6d, 0xcb, 0x71, 0xd0,
0xd8, 0x21, 0x4a, 0xf2, 0x05, 0xf5, 0x18, 0x0a, 0x51, 0x41, 0x71, 0x37, 0xc1, 0xca, 0x2a, 0xa9, 0x77, 0x80, 0x90, 0x7c, 0xe1, 0x3a, 0x14, 0x81, 0x28, 0x21, 0xb8, 0x1b, 0x60, 0xa4, 0x91, 0x54,
0x05, 0x3e, 0x4a, 0x0f, 0x3b, 0xcd, 0xa2, 0x59, 0x2a, 0xff, 0x37, 0x97, 0x66, 0x65, 0xa9, 0xec, 0x00, 0x1f, 0x25, 0xc5, 0x4e, 0xba, 0x68, 0x16, 0xca, 0xff, 0xcf, 0xb4, 0x59, 0x51, 0x20, 0xbb,
0xba, 0x39, 0xf9, 0x74, 0xc1, 0xee, 0x41, 0x77, 0x1a, 0x4d, 0x47, 0x7a, 0x0c, 0x3b, 0xcf, 0x89, 0xa6, 0x2b, 0x9f, 0x1c, 0x98, 0x5d, 0xe8, 0x4c, 0x5b, 0x53, 0x9e, 0x1e, 0xc1, 0xf6, 0x33, 0xe2,
0x4f, 0x6e, 0x8a, 0x84, 0x47, 0x14, 0x38, 0x63, 0xa2, 0x32, 0x44, 0x00, 0x4e, 0x3b, 0x69, 0xc0, 0x91, 0x9b, 0x3c, 0x61, 0x89, 0x7c, 0x6b, 0x4c, 0x64, 0x87, 0x70, 0x83, 0xd3, 0x4a, 0xca, 0xe0,
0xbb, 0xb0, 0x75, 0x44, 0x19, 0x5f, 0x08, 0x67, 0x7f, 0x07, 0x30, 0x31, 0x48, 0xc1, 0xd3, 0x50, 0x5d, 0xd8, 0x3c, 0x72, 0x29, 0x5b, 0x68, 0xce, 0xfc, 0x0e, 0x60, 0x22, 0x90, 0x18, 0x4f, 0x5c,
0xe4, 0x8a, 0x72, 0x9d, 0x36, 0x28, 0x22, 0x77, 0x23, 0x5d, 0xc9, 0x1b, 0xd0, 0x4c, 0x02, 0x7a, 0x91, 0x2b, 0x97, 0xa9, 0xb6, 0x41, 0x10, 0x99, 0x1d, 0x2a, 0x26, 0xaf, 0x43, 0x23, 0xf6, 0xdd,
0x75, 0x12, 0xba, 0xe7, 0x84, 0x33, 0x59, 0x48, 0xb2, 0xbc, 0xd9, 0x88, 0xf8, 0xbe, 0xac, 0xa3, 0xab, 0x93, 0xc0, 0x3e, 0x27, 0x8c, 0x0a, 0x22, 0x09, 0x7a, 0xd3, 0x11, 0xf1, 0x3c, 0xc1, 0xa3,
0x15, 0xfb, 0x33, 0xd8, 0x2e, 0xc6, 0xd7, 0x65, 0xf2, 0x3f, 0x68, 0x4e, 0xd4, 0x62, 0x18, 0xad, 0x65, 0xf3, 0x33, 0xd8, 0xca, 0xfb, 0x57, 0x34, 0x79, 0x07, 0x1a, 0x13, 0xb4, 0x28, 0x7a, 0x2b,
0x32, 0x4f, 0xae, 0xd6, 0x09, 0x47, 0xb5, 0x66, 0x11, 0xdf, 0x83, 0x4e, 0x5a, 0x52, 0xd2, 0x48, 0xcd, 0x83, 0xab, 0x79, 0xc2, 0x10, 0xad, 0x59, 0x81, 0xef, 0x42, 0x3b, 0xa1, 0x94, 0x10, 0x92,
0x25, 0x9a, 0xc3, 0x13, 0xa6, 0x2d, 0xde, 0x95, 0xa1, 0xae, 0x8f, 0xd3, 0x24, 0xec, 0xdf, 0x58, 0x8d, 0x66, 0xb1, 0x98, 0x2a, 0x89, 0xb7, 0x45, 0xa8, 0xa9, 0x72, 0xea, 0x86, 0xfd, 0x07, 0x29,
0x12, 0xeb, 0xd0, 0x60, 0xd7, 0x8c, 0x93, 0xf1, 0xb1, 0x2e, 0x8c, 0xf6, 0x3f, 0xab, 0x30, 0x7e, 0xb1, 0x06, 0x75, 0x7a, 0x4d, 0x19, 0x19, 0xf7, 0x14, 0x31, 0x5a, 0xff, 0x2e, 0x62, 0xfc, 0x54,
0x2a, 0x41, 0x23, 0x15, 0xec, 0xc6, 0xb6, 0xf9, 0x1f, 0x68, 0x44, 0x4a, 0x3a, 0xa2, 0xea, 0xa3, 0x80, 0x7a, 0x02, 0xd8, 0x8d, 0x63, 0xf3, 0x7f, 0x50, 0x0f, 0x25, 0x74, 0x44, 0xf2, 0xa3, 0x71,
0x79, 0xd0, 0xd1, 0xaa, 0x18, 0x49, 0x27, 0x72, 0x57, 0x0b, 0x6d, 0x52, 0xa9, 0x83, 0xc2, 0x45, 0xd0, 0x56, 0xa8, 0x68, 0x48, 0x27, 0x70, 0x97, 0x73, 0x63, 0x52, 0xa2, 0x83, 0xc0, 0x85, 0x9c,
0xa2, 0xba, 0x6a, 0xa2, 0xba, 0xac, 0x55, 0xa8, 0xc7, 0x49, 0xc0, 0x29, 0x26, 0x97, 0xec, 0x1a, 0x5d, 0x55, 0xce, 0x2e, 0x63, 0x05, 0x6a, 0x51, 0xec, 0x33, 0x17, 0x9b, 0x4b, 0x4c, 0x0d, 0xf3,
0xf6, 0x7d, 0xa8, 0xbf, 0x72, 0xdc, 0x11, 0xb2, 0x11, 0x96, 0x6e, 0xa4, 0x8f, 0x4d, 0x7e, 0x15, 0x3e, 0xd4, 0x5e, 0x5a, 0xf6, 0x08, 0xa3, 0xe1, 0x92, 0x76, 0xa8, 0xca, 0x26, 0x6e, 0x85, 0x31,
0xc6, 0x04, 0x77, 0x7b, 0x2d, 0xa9, 0x54, 0xed, 0x6f, 0xb1, 0x5d, 0xaa, 0x24, 0xd0, 0xd9, 0x73, 0xc1, 0x6c, 0xaf, 0x45, 0x28, 0x65, 0xf3, 0x1b, 0x1c, 0x97, 0xb2, 0x09, 0x54, 0xf7, 0xdc, 0x43,
0x0f, 0x6b, 0xcd, 0x6c, 0xc4, 0x24, 0xcf, 0x54, 0x97, 0xb5, 0xee, 0x40, 0x7d, 0xac, 0xf0, 0x75, 0xae, 0xe9, 0x44, 0x74, 0xf3, 0x4c, 0x4d, 0x59, 0xe3, 0x0e, 0xd4, 0xc6, 0xd2, 0xbe, 0xa2, 0xa3,
0x39, 0x1a, 0xfe, 0x3a, 0xaa, 0xfd, 0x0c, 0xb6, 0xd5, 0xd7, 0x66, 0xe1, 0x37, 0x65, 0xaa, 0x1f, 0x8e, 0x5f, 0x79, 0x35, 0xcf, 0x61, 0x4b, 0xde, 0x36, 0x0b, 0xef, 0x94, 0xa9, 0x79, 0x2c, 0x53,
0xab, 0x2d, 0xcb, 0x0f, 0x89, 0xbd, 0x0b, 0x3b, 0x53, 0x10, 0xba, 0xf8, 0x6c, 0x68, 0xbf, 0xb8, 0x96, 0x17, 0xc9, 0x1e, 0xd4, 0x23, 0x42, 0x83, 0x38, 0x42, 0x40, 0x04, 0x0a, 0x8d, 0x83, 0x4d,
0x20, 0x98, 0xdd, 0x06, 0x14, 0xf3, 0x43, 0xec, 0x1e, 0xfd, 0xc7, 0x91, 0xc4, 0xae, 0xda, 0xdf, 0xdd, 0x3b, 0xc2, 0xf4, 0xb1, 0x3a, 0x35, 0x7f, 0x2f, 0x40, 0x3b, 0xbb, 0xc5, 0x29, 0x34, 0xf0,
0xc0, 0xb2, 0xb4, 0x11, 0x02, 0x08, 0x6e, 0x3a, 0xa4, 0x0a, 0x3f, 0x2b, 0x62, 0xdb, 0xd0, 0xa9, 0xce, 0xdd, 0xe0, 0x5b, 0x79, 0x05, 0xca, 0xe4, 0xb1, 0x8b, 0x10, 0x8a, 0x93, 0x91, 0x85, 0x76,
0x9a, 0x94, 0x9b, 0x40, 0x2e, 0x4b, 0xc8, 0x5f, 0x4b, 0xd0, 0x7a, 0x4d, 0xf8, 0x65, 0x18, 0x9f, 0xd5, 0xbc, 0x92, 0x5b, 0x3d, 0x12, 0xb9, 0x81, 0x23, 0xef, 0x01, 0xde, 0xc0, 0xb8, 0xf5, 0x3a,
0x0b, 0xd1, 0x58, 0xa1, 0xa2, 0x31, 0xf3, 0xe3, 0xab, 0xfe, 0xe0, 0x9a, 0xe3, 0xa9, 0x4a, 0x75, 0x0e, 0x98, 0xa5, 0xae, 0x52, 0x7e, 0xcd, 0x21, 0x84, 0x84, 0x1d, 0x72, 0x20, 0x2b, 0xc9, 0xd5,
0xc5, 0xe1, 0xe3, 0xcc, 0xb1, 0xa3, 0xea, 0xb8, 0x22, 0xe7, 0x10, 0xf7, 0xcd, 0x55, 0x1f, 0x13, 0x27, 0xf6, 0x5e, 0x92, 0x31, 0x55, 0x5d, 0x8a, 0x4e, 0x25, 0xb8, 0x47, 0xee, 0x18, 0x99, 0x5d,
0x33, 0x8c, 0xd5, 0xe1, 0x4a, 0x33, 0x9c, 0xf2, 0xe2, 0x30, 0x8a, 0x88, 0xa7, 0x62, 0x09, 0xb0, 0xd3, 0xca, 0x72, 0xf3, 0xe4, 0xd2, 0x0a, 0x45, 0xb3, 0xb6, 0x90, 0x11, 0x6b, 0x72, 0x0f, 0xe3,
0x53, 0x03, 0x56, 0x33, 0x56, 0x38, 0x13, 0x69, 0xb0, 0xba, 0x01, 0x3b, 0x4d, 0xc1, 0x56, 0x32, 0x25, 0xd1, 0x85, 0xc5, 0xc7, 0xa5, 0xe8, 0x5b, 0x71, 0x74, 0x4e, 0x22, 0x9f, 0x78, 0x2f, 0x53,
0x66, 0x06, 0xac, 0x21, 0x89, 0x8f, 0x61, 0xe5, 0x30, 0x4a, 0xce, 0x98, 0x33, 0x24, 0xa2, 0xb9, 0x96, 0x40, 0x5c, 0x50, 0x3b, 0xb0, 0x3d, 0x85, 0xa9, 0x9a, 0x46, 0x26, 0xb4, 0x9e, 0x5f, 0x10,
0xf0, 0x90, 0x3b, 0x7e, 0x3f, 0x11, 0x43, 0x25, 0x96, 0x48, 0xf7, 0x88, 0xc4, 0x98, 0x27, 0x7a, 0xa4, 0xbb, 0x46, 0x19, 0xf3, 0xe2, 0xed, 0x80, 0x80, 0x8e, 0x43, 0x91, 0x7d, 0xd9, 0x7c, 0x0d,
0xb6, 0x8c, 0xe7, 0x5e, 0xb5, 0x6e, 0xc1, 0x86, 0x1c, 0xf6, 0x69, 0xd0, 0x3f, 0x27, 0x71, 0x40, 0x15, 0x21, 0xc3, 0x3b, 0x82, 0xc3, 0xa8, 0x6a, 0x20, 0xeb, 0x31, 0xab, 0x04, 0x2d, 0x5d, 0x9f,
0xfc, 0x71, 0xe8, 0x11, 0xbd, 0x8f, 0x5d, 0x58, 0x4f, 0x17, 0x45, 0x79, 0xcb, 0x25, 0xb9, 0x1f, 0xb2, 0xe6, 0xe0, 0xc4, 0x64, 0x45, 0x98, 0xfc, 0xb5, 0x00, 0xcd, 0x57, 0x84, 0x5d, 0x06, 0xd1,
0xfb, 0x14, 0x3a, 0xa7, 0x23, 0xbc, 0xdf, 0x70, 0x2c, 0xa0, 0xe1, 0x73, 0x87, 0x3b, 0x22, 0x41, 0x39, 0xef, 0x22, 0x9a, 0x1b, 0x71, 0x88, 0x64, 0x74, 0xd5, 0x1f, 0x5c, 0x33, 0x05, 0x77, 0x99,
0x11, 0x9f, 0x86, 0x1e, 0xd3, 0x01, 0xd1, 0x9b, 0x2b, 0x13, 0xe2, 0xf5, 0xcd, 0x92, 0x12, 0x0d, 0x83, 0x81, 0x3b, 0x3d, 0x4b, 0x0e, 0xb6, 0x92, 0xd8, 0x43, 0xbb, 0xc7, 0x57, 0x7d, 0x64, 0x6a,
0x3f, 0x21, 0x93, 0x25, 0x99, 0xd3, 0x32, 0xa0, 0xcd, 0xe5, 0x26, 0x94, 0xf0, 0x36, 0x5e, 0x05, 0x10, 0xc9, 0x3a, 0x0b, 0x31, 0xdc, 0x72, 0xa2, 0x20, 0x0c, 0x89, 0x23, 0x7d, 0x71, 0x63, 0xa7,
0x52, 0xb2, 0xea, 0x2a, 0xb0, 0x6a, 0x92, 0xd4, 0x6c, 0x74, 0x1f, 0x56, 0x79, 0xca, 0xa2, 0x8f, 0xda, 0x58, 0x55, 0x4b, 0xe1, 0x4e, 0xa8, 0x8c, 0xd5, 0xb4, 0xb1, 0xd3, 0xc4, 0xd8, 0x72, 0x4a,
0x89, 0xe4, 0xe8, 0x5c, 0xdd, 0xd2, 0x96, 0x05, 0x8e, 0xa2, 0xe4, 0x65, 0x8f, 0xd1, 0xb0, 0x2a, 0x4c, 0x1b, 0xab, 0x8b, 0xc0, 0xc7, 0xb0, 0x8c, 0xb5, 0x3c, 0xa3, 0xd6, 0x50, 0xb4, 0x0a, 0xc3,
0xea, 0x6b, 0x80, 0x57, 0xb2, 0x60, 0xa4, 0x0d, 0x36, 0x9d, 0xac, 0x6c, 0x28, 0xff, 0xd8, 0xb9, 0x5a, 0x7b, 0xfd, 0x98, 0x2f, 0x25, 0x58, 0x9c, 0xff, 0x21, 0x89, 0xb0, 0xc2, 0x6a, 0xb7, 0x88,
0x4a, 0x35, 0x13, 0x53, 0xb8, 0xd3, 0xb7, 0x0e, 0xf5, 0x5d, 0x7d, 0x1f, 0xaa, 0x0a, 0x17, 0x9f, 0x44, 0x28, 0x1b, 0xb7, 0x60, 0x5d, 0x2c, 0xfb, 0xae, 0xdf, 0x97, 0x55, 0x1a, 0x07, 0x0e, 0x51,
0x8e, 0xb1, 0xd1, 0x2b, 0x6d, 0x7e, 0x2f, 0x41, 0x53, 0x01, 0xaa, 0x9d, 0xe0, 0xb2, 0x8b, 0x35, 0x79, 0x60, 0xe5, 0x92, 0x43, 0x3e, 0xef, 0xc4, 0x91, 0xc8, 0xc7, 0x3c, 0x85, 0xf6, 0xe9, 0x08,
0x63, 0x10, 0xf7, 0x4c, 0x80, 0xfc, 0x57, 0x2e, 0x43, 0x01, 0x3f, 0x86, 0xec, 0xd2, 0x89, 0x32, 0x3f, 0xf8, 0x18, 0x4e, 0x94, 0xe1, 0x33, 0x8b, 0x59, 0x9c, 0xb1, 0xa1, 0x68, 0x3a, 0xaa, 0x1c,
0x24, 0x67, 0x9a, 0xdd, 0x87, 0x96, 0x3a, 0x32, 0x6d, 0x58, 0x9d, 0x67, 0xf8, 0x50, 0xf4, 0x51, 0xa2, 0x36, 0x93, 0x22, 0xc4, 0xe9, 0xeb, 0x23, 0x09, 0x1a, 0xde, 0xa9, 0x93, 0x23, 0x41, 0x72,
0x64, 0x22, 0x1b, 0x4b, 0xf3, 0xe0, 0x76, 0xce, 0x42, 0x72, 0xdc, 0x97, 0xbf, 0x2f, 0x02, 0x1e, 0xe1, 0xd0, 0x64, 0x22, 0x09, 0x09, 0xbc, 0x29, 0xfa, 0x38, 0x95, 0x42, 0xe3, 0x60, 0x45, 0xb3,
0x5f, 0xf7, 0x1e, 0x02, 0x4c, 0x46, 0xa2, 0x60, 0xce, 0xc9, 0xb5, 0x4e, 0x7f, 0xdc, 0xc9, 0x85, 0x56, 0x27, 0xba, 0x0f, 0x2b, 0x2c, 0x89, 0xa2, 0x8f, 0x8d, 0x64, 0x29, 0xf2, 0x6a, 0x5a, 0xe5,
0xe3, 0x27, 0x5a, 0x88, 0xa7, 0xe5, 0x27, 0x25, 0xfb, 0x2b, 0x58, 0xfd, 0xdc, 0x3f, 0xa7, 0x61, 0x62, 0xe4, 0x33, 0x50, 0x0c, 0x5d, 0x65, 0x56, 0x7a, 0x7d, 0x05, 0x20, 0x5b, 0x53, 0xc8, 0xe0,
0xc6, 0x05, 0xad, 0xc6, 0xce, 0xf7, 0x61, 0xac, 0xf7, 0x2b, 0x86, 0x34, 0xc0, 0xa1, 0x52, 0x0f, 0x14, 0x4e, 0xc3, 0x86, 0xf0, 0x8f, 0xad, 0xab, 0x04, 0x33, 0xbe, 0x85, 0x99, 0xbe, 0xb1, 0x5c,
0xab, 0x33, 0x8c, 0x26, 0x17, 0x49, 0x85, 0xa7, 0x84, 0xfb, 0xad, 0x02, 0x30, 0x01, 0xb3, 0x9e, 0xcf, 0x56, 0x1f, 0x88, 0x65, 0xae, 0xe2, 0x89, 0xae, 0x96, 0xd8, 0xfc, 0x51, 0x80, 0x86, 0x34,
0x42, 0x8f, 0x86, 0x7d, 0xcc, 0xbb, 0x0b, 0xea, 0x12, 0x55, 0x27, 0xfd, 0x98, 0xb8, 0x49, 0xcc, 0x28, 0x33, 0xc1, 0x63, 0x1b, 0x87, 0x88, 0xb6, 0xb8, 0xab, 0x1d, 0x64, 0xaf, 0xfd, 0x54, 0x08,
0xe8, 0x05, 0xd1, 0x7d, 0x6b, 0x5b, 0xef, 0xa5, 0xc8, 0xe1, 0x03, 0xd8, 0x9a, 0xf8, 0x7a, 0x19, 0xf8, 0x75, 0x40, 0x91, 0x5a, 0xa9, 0x20, 0x67, 0x8a, 0xdd, 0x87, 0xa6, 0x2c, 0x99, 0x12, 0x2c,
0xb7, 0xf2, 0x42, 0xb7, 0xc7, 0xb0, 0x81, 0x6e, 0xd8, 0x70, 0x92, 0x9c, 0x53, 0x65, 0xa1, 0xd3, 0xcf, 0x13, 0x7c, 0xc0, 0x2f, 0x16, 0x8c, 0x44, 0x4c, 0xda, 0xc6, 0xc1, 0xed, 0x8c, 0x84, 0x88,
0xc7, 0xb0, 0x9b, 0xe1, 0x29, 0xd2, 0x39, 0xe3, 0x5a, 0x5d, 0xe8, 0xfa, 0x21, 0x6c, 0xa3, 0xeb, 0x71, 0x5f, 0xfc, 0x3e, 0xf7, 0x59, 0x74, 0xdd, 0x7d, 0x00, 0x30, 0x59, 0x71, 0xc2, 0x9c, 0x93,
0xa5, 0x43, 0x79, 0xd1, 0x6f, 0xf9, 0x4f, 0xf0, 0x1c, 0x93, 0x78, 0x98, 0xe3, 0x59, 0x5b, 0xe8, 0x6b, 0xd5, 0xfe, 0x98, 0xc9, 0x85, 0xe5, 0xc5, 0x0a, 0x88, 0x27, 0xc5, 0xc7, 0x05, 0xf3, 0x2b,
0xf4, 0x1e, 0xac, 0xa3, 0x53, 0x21, 0x4e, 0xfd, 0x26, 0x17, 0x46, 0x5c, 0x8e, 0xad, 0x27, 0xe3, 0x58, 0xf9, 0x9c, 0x8f, 0xa5, 0x94, 0x0a, 0x4a, 0x8d, 0xad, 0xef, 0x83, 0x48, 0xe5, 0xcb, 0x97,
0xb2, 0xb2, 0xc8, 0xc5, 0x3e, 0x86, 0xd6, 0xcb, 0x64, 0x48, 0xb8, 0x3f, 0x48, 0xb3, 0xff, 0x2f, 0xae, 0x8f, 0x4b, 0x89, 0x1e, 0xb2, 0x33, 0x08, 0x27, 0x5f, 0xd6, 0xd2, 0x9e, 0x04, 0xee, 0xb7,
0xd6, 0xd3, 0x8f, 0x65, 0x68, 0x1e, 0x0e, 0xe3, 0x30, 0x89, 0x72, 0x9d, 0x41, 0xa5, 0xf4, 0x54, 0x12, 0xc0, 0xc4, 0x98, 0xf1, 0x04, 0xba, 0x6e, 0xd0, 0xe7, 0xe3, 0xc4, 0xb5, 0x89, 0xe4, 0x49,
0x67, 0x50, 0x36, 0x0f, 0xa0, 0xa5, 0x3e, 0x82, 0xda, 0x4c, 0xd5, 0x9a, 0x35, 0x9d, 0xf9, 0xe2, 0x3f, 0x22, 0x76, 0x1c, 0x51, 0xf7, 0x82, 0xa8, 0x41, 0xbe, 0xa5, 0x72, 0xc9, 0xc7, 0xf0, 0x01,
0x2e, 0x35, 0x10, 0x5b, 0xd0, 0x86, 0xf9, 0x6a, 0xcb, 0x64, 0xe3, 0x27, 0xd0, 0x1e, 0xa9, 0x7d, 0x6c, 0x4e, 0x74, 0x9d, 0x94, 0x5a, 0x71, 0xa1, 0xda, 0x23, 0x58, 0x47, 0x35, 0x1c, 0x38, 0x71,
0x69, 0x4b, 0x75, 0xb2, 0xf7, 0x4c, 0xe4, 0x09, 0xc1, 0xfd, 0xec, 0xfe, 0x55, 0x4d, 0xbd, 0x84, 0x46, 0xa9, 0xb4, 0x50, 0xe9, 0x63, 0xd8, 0x49, 0xc5, 0xc9, 0xdb, 0x39, 0xa5, 0x5a, 0x5e, 0xa8,
0xf5, 0xa9, 0xc9, 0x7c, 0x69, 0xd9, 0xd9, 0xd2, 0x6a, 0x1e, 0x6c, 0x68, 0xd8, 0xac, 0x97, 0xac, 0xfa, 0x21, 0x6c, 0xa1, 0xea, 0xa5, 0xe5, 0xb2, 0xbc, 0x5e, 0xe5, 0x2f, 0xc4, 0x39, 0x26, 0xd1,
0xb7, 0x2b, 0xf5, 0x35, 0x4f, 0x2f, 0xd8, 0xd6, 0xff, 0xa1, 0x1d, 0xa8, 0x0f, 0x56, 0xaa, 0x48, 0x30, 0x13, 0x67, 0x75, 0xa1, 0xd2, 0x7b, 0xb0, 0x86, 0x4a, 0x39, 0x3f, 0xb5, 0x9b, 0x54, 0x28,
0x25, 0x03, 0x90, 0xfb, 0x98, 0xa1, 0x2a, 0xae, 0xe4, 0x39, 0x53, 0x95, 0xac, 0xc6, 0xb9, 0x4f, 0xb1, 0x19, 0x8e, 0x9e, 0x94, 0xca, 0xf2, 0x22, 0x15, 0xb3, 0x07, 0xcd, 0x17, 0xf1, 0x90, 0x30,
0xa3, 0x6a, 0x93, 0xfa, 0x32, 0x39, 0xeb, 0x91, 0x74, 0xf0, 0x4b, 0x0d, 0x2a, 0xcf, 0x8e, 0xbf, 0x6f, 0x90, 0x74, 0xff, 0xdf, 0xe4, 0xd3, 0x8f, 0x45, 0x68, 0x1c, 0x0e, 0xa3, 0x20, 0x0e, 0x33,
0xb4, 0xde, 0xc0, 0x6a, 0xe1, 0x69, 0x67, 0x99, 0x6e, 0x33, 0xfb, 0xfd, 0xd9, 0xfb, 0xf7, 0xbc, 0x93, 0x41, 0xb6, 0xf4, 0xd4, 0x64, 0x90, 0x32, 0x7b, 0xd0, 0x94, 0xf7, 0x91, 0x12, 0x93, 0x5c,
0x65, 0x7d, 0x0f, 0x58, 0x12, 0x98, 0x85, 0x4b, 0x42, 0x8a, 0x39, 0xfb, 0xfe, 0x91, 0x62, 0xce, 0x33, 0xa6, 0x3b, 0x9f, 0x7f, 0x5c, 0x8a, 0x7b, 0x55, 0x09, 0x66, 0xd9, 0x96, 0xea, 0xc6, 0x4f,
0xbb, 0x5b, 0x2c, 0x59, 0x1f, 0x41, 0x4d, 0x3d, 0x04, 0xad, 0x4d, 0x6d, 0x9b, 0x7b, 0x51, 0xf6, 0xa0, 0x35, 0x92, 0x79, 0x29, 0x49, 0x59, 0xd9, 0x7b, 0xda, 0xf3, 0x24, 0xc0, 0xfd, 0x74, 0xfe,
0xb6, 0x0a, 0xb3, 0xa9, 0xe3, 0x11, 0xb4, 0x73, 0x4f, 0x6c, 0xeb, 0x56, 0x2e, 0x56, 0xfe, 0x1d, 0x92, 0x53, 0x2f, 0x60, 0x6d, 0x6a, 0x33, 0x4b, 0x2d, 0x33, 0x4d, 0xad, 0xc6, 0xc1, 0xba, 0x32,
0xd9, 0xfb, 0xd7, 0xec, 0xc5, 0x14, 0xed, 0x10, 0x60, 0xf2, 0x64, 0xb2, 0xba, 0xda, 0x7a, 0xea, 0x9b, 0xd6, 0x12, 0x7c, 0xbb, 0x92, 0x9f, 0x37, 0xc9, 0x8b, 0xc3, 0x78, 0x17, 0x5a, 0xbe, 0xbc,
0x3d, 0xda, 0xdb, 0x9d, 0xb1, 0x92, 0x82, 0x9c, 0xc1, 0x5a, 0xf1, 0x4d, 0x64, 0x15, 0x54, 0x2d, 0xb0, 0x12, 0x44, 0x4a, 0x29, 0x03, 0x99, 0xcb, 0x0c, 0x51, 0xb1, 0x45, 0x9c, 0x33, 0x51, 0x49,
0xbe, 0x60, 0x7a, 0x77, 0xe6, 0xae, 0x67, 0x61, 0x8b, 0x2f, 0xa3, 0x14, 0x76, 0xce, 0x3b, 0x2b, 0x63, 0x9c, 0xb9, 0x1a, 0xe5, 0x98, 0x54, 0x5f, 0xd7, 0xb3, 0x5e, 0x8d, 0x07, 0xbf, 0x54, 0xa1,
0x85, 0x9d, 0xfb, 0xa4, 0x5a, 0xb2, 0xbe, 0x86, 0x4e, 0xfe, 0x51, 0x63, 0x19, 0x91, 0x66, 0xbe, 0xf4, 0xb4, 0xf7, 0xa5, 0x71, 0x0c, 0x2b, 0xb9, 0xb7, 0xae, 0xa1, 0xa7, 0xcd, 0xec, 0x07, 0x79,
0xb5, 0x7a, 0xb7, 0xe7, 0xac, 0xa6, 0x80, 0xef, 0xc3, 0xb2, 0x7a, 0xbe, 0x98, 0x8c, 0xcf, 0xbe, 0xf7, 0xbf, 0xf3, 0x8e, 0xd5, 0x77, 0xc0, 0x12, 0xb7, 0x99, 0xfb, 0x48, 0x48, 0x6c, 0xce, 0xfe,
0x78, 0x7a, 0x9b, 0xf9, 0xc9, 0xd4, 0xeb, 0x11, 0xd4, 0xd4, 0xf5, 0x32, 0x4d, 0x80, 0xdc, 0x6d, 0x20, 0x4b, 0x6c, 0xce, 0xfb, 0xb6, 0x58, 0x32, 0x3e, 0x82, 0xaa, 0x7c, 0x19, 0x1b, 0x1b, 0x4a,
0xb3, 0xd7, 0xca, 0xce, 0xda, 0x4b, 0x8f, 0x4a, 0x26, 0x0e, 0xcb, 0xc5, 0x61, 0xb3, 0xe2, 0x64, 0x36, 0xf3, 0xc4, 0xee, 0x6e, 0xe6, 0x76, 0x13, 0xc5, 0x23, 0x68, 0x65, 0xfe, 0x73, 0x30, 0x6e,
0x0e, 0x67, 0x50, 0x93, 0x7f, 0x02, 0x3d, 0xfe, 0x23, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x2d, 0x77, 0x65, 0x7c, 0x65, 0x1f, 0xd6, 0xdd, 0xff, 0xcc, 0x3e, 0x4c, 0xac, 0x1d, 0x02, 0x4c, 0xde, 0x90,
0x4b, 0x11, 0x12, 0x00, 0x00, 0x46, 0x47, 0x49, 0x4f, 0x3d, 0xd0, 0xbb, 0x3b, 0x33, 0x4e, 0x12, 0x23, 0x67, 0xb0, 0x9a, 0x7f,
0x24, 0x1a, 0x39, 0x54, 0xf3, 0x4f, 0xba, 0xee, 0x9d, 0xb9, 0xe7, 0x69, 0xb3, 0xf9, 0xa7, 0x62,
0x62, 0x76, 0xce, 0xc3, 0x33, 0x31, 0x3b, 0xf7, 0x8d, 0xb9, 0x64, 0x7c, 0x0d, 0xed, 0xec, 0x2b,
0xcf, 0xd0, 0x20, 0xcd, 0x7c, 0x7c, 0x76, 0x6f, 0xcf, 0x39, 0x4d, 0x0c, 0xbe, 0x0f, 0x15, 0xf9,
0x9e, 0xd3, 0x1d, 0x9f, 0x7e, 0x02, 0x76, 0x37, 0xb2, 0x9b, 0x89, 0xd6, 0x43, 0xa8, 0xca, 0xcf,
0xcb, 0xa4, 0x01, 0x32, 0x5f, 0x9b, 0xdd, 0x66, 0x7a, 0xd7, 0x5c, 0x7a, 0x58, 0xd0, 0x7e, 0x68,
0xc6, 0x0f, 0x9d, 0xe5, 0x27, 0x55, 0x9c, 0x41, 0x55, 0xfc, 0x2b, 0xf6, 0xe8, 0xcf, 0x00, 0x00,
0x00, 0xff, 0xff, 0x96, 0xc1, 0x71, 0xd3, 0x22, 0x13, 0x00, 0x00,
} }

View file

@ -159,6 +159,20 @@ message UpdateContainerRequest {
string id = 1; // ID of container string id = 1; // ID of container
string pid = 2; string pid = 2;
string status = 3; // Status to whcih containerd will try to change string status = 3; // Status to whcih containerd will try to change
UpdateResource resources =4;
}
message UpdateResource {
uint32 blkioWeight =1;
uint32 cpuShares = 2;
uint32 cpuPeriod = 3;
uint32 cpuQuota = 4;
string cpusetCpus = 5;
string cpusetMems = 6;
uint32 memoryLimit = 7;
uint32 memorySwap = 8;
uint32 memoryReservation = 9;
uint32 kernelMemoryLimit = 10;
} }
message UpdateContainerResponse { message UpdateContainerResponse {

View file

@ -53,6 +53,7 @@ var containersCommand = cli.Command{
startCommand, startCommand,
statsCommand, statsCommand,
watchCommand, watchCommand,
updateCommand,
}, },
Action: listContainers, Action: listContainers,
} }
@ -517,6 +518,59 @@ var statsCommand = cli.Command{
}, },
} }
var updateCommand = cli.Command{
Name: "update",
Usage: "update a containers resources",
Flags: []cli.Flag{
cli.IntFlag{
Name: "memory-limit",
},
cli.IntFlag{
Name: "memory-reservation",
},
cli.IntFlag{
Name: "memory-swap",
},
cli.IntFlag{
Name: "cpu-quota",
},
cli.IntFlag{
Name: "cpu-period",
},
cli.IntFlag{
Name: "kernel-limit",
},
cli.IntFlag{
Name: "blkio-weight",
},
cli.StringFlag{
Name: "cpuset-cpus",
},
cli.StringFlag{
Name: "cpuset-mems",
},
},
Action: func(context *cli.Context) {
req := &types.UpdateContainerRequest{
Id: context.Args().First(),
}
req.Resources = &types.UpdateResource{}
req.Resources.MemoryLimit = uint32(context.Int("memory-limit"))
req.Resources.MemoryReservation = uint32(context.Int("memory-reservation"))
req.Resources.MemorySwap = uint32(context.Int("memory-swap"))
req.Resources.BlkioWeight = uint32(context.Int("blkio-weight"))
req.Resources.CpuPeriod = uint32(context.Int("cpu-period"))
req.Resources.CpuQuota = uint32(context.Int("cpu-quota"))
req.Resources.CpuShares = uint32(context.Int("cpu-shares"))
req.Resources.CpusetCpus = context.String("cpuset-cpus")
req.Resources.CpusetMems = context.String("cpuset-mems")
c := getClient(context)
if _, err := c.UpdateContainer(netcontext.Background(), req); err != nil {
fatal(err.Error(), 1)
}
},
}
func waitForExit(c types.APIClient, events types.API_EventsClient, id, pid string, closer func()) error { func waitForExit(c types.APIClient, events types.API_EventsClient, id, pid string, closer func()) error {
for { for {
e, err := events.Recv() e, err := events.Recv()

View file

@ -48,6 +48,8 @@ type Container interface {
Runtime() string Runtime() string
// OOM signals the channel if the container received an OOM notification // OOM signals the channel if the container received an OOM notification
OOM() (OOM, error) OOM() (OOM, error)
// UpdateResource updates the containers resources to new values
UpdateResources(*Resource) error
} }
type OOM interface { type OOM interface {
@ -213,3 +215,22 @@ func (c *container) RemoveProcess(pid string) error {
delete(c.processes, pid) delete(c.processes, pid)
return os.RemoveAll(filepath.Join(c.root, c.id, pid)) return os.RemoveAll(filepath.Join(c.root, c.id, pid))
} }
func (c *container) UpdateResources(r *Resource) error {
container, err := c.getLibctContainer()
if err != nil {
return err
}
config := container.Config()
config.Cgroups.Resources.CpuShares = r.CPUShares
config.Cgroups.Resources.BlkioWeight = r.BlkioWeight
config.Cgroups.Resources.CpuPeriod = r.CPUPeriod
config.Cgroups.Resources.CpuQuota = r.CPUQuota
config.Cgroups.Resources.CpusetCpus = r.CpusetCpus
config.Cgroups.Resources.CpusetMems = r.CpusetMems
config.Cgroups.Resources.KernelMemory = r.KernelMemory
config.Cgroups.Resources.Memory = r.Memory
config.Cgroups.Resources.MemoryReservation = r.MemoryReservation
config.Cgroups.Resources.MemorySwap = r.MemorySwap
return container.Set(config)
}

View file

@ -32,6 +32,19 @@ const (
type State string type State string
type Resource struct {
CPUShares int64
BlkioWeight uint16
CPUPeriod int64
CPUQuota int64
CpusetCpus string
CpusetMems string
KernelMemory int64
Memory int64
MemoryReservation int64
MemorySwap int64
}
const ( const (
Paused = State("paused") Paused = State("paused")
Stopped = State("stopped") Stopped = State("stopped")

View file

@ -10,6 +10,7 @@ type UpdateTask struct {
baseTask baseTask
ID string ID string
State runtime.State State runtime.State
Resources *runtime.Resource
} }
func (s *Supervisor) updateContainer(t *UpdateTask) error { func (s *Supervisor) updateContainer(t *UpdateTask) error {
@ -41,6 +42,10 @@ func (s *Supervisor) updateContainer(t *UpdateTask) error {
default: default:
return ErrUnknownContainerStatus return ErrUnknownContainerStatus
} }
return nil
}
if t.Resources != nil {
return container.UpdateResources(t.Resources)
} }
return nil return nil
} }