From 6382cf9e808b10ff7695294437dc1b7129dc7e68 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Mon, 24 Jun 2024 15:52:18 +0100 Subject: [PATCH 1/2] config: allow configuring free gc policies Signed-off-by: Justin Chadwell --- api/services/control/control.pb.go | 385 ++++++++++++++--------- api/services/control/control.proto | 5 +- api/types/worker.pb.go | 157 ++++++--- api/types/worker.proto | 6 +- cache/manager.go | 51 ++- cache/manager_test.go | 129 ++++++++ client/prune.go | 17 +- client/workers.go | 4 +- cmd/buildctl/debug/workers.go | 10 +- cmd/buildctl/prune.go | 15 +- cmd/buildkitd/config/config.go | 27 +- cmd/buildkitd/config/gcpolicy.go | 15 +- cmd/buildkitd/config/gcpolicy_openbsd.go | 19 -- cmd/buildkitd/config/gcpolicy_unix.go | 17 +- cmd/buildkitd/config/gcpolicy_windows.go | 23 -- cmd/buildkitd/config/load_test.go | 25 +- cmd/buildkitd/main.go | 14 +- control/control.go | 12 +- util/disk/disk.go | 7 + util/disk/disk_openbsd.go | 21 ++ util/disk/disk_unix.go | 21 ++ util/disk/disk_windows.go | 33 ++ 22 files changed, 714 insertions(+), 299 deletions(-) delete mode 100644 cmd/buildkitd/config/gcpolicy_openbsd.go create mode 100644 util/disk/disk.go create mode 100644 util/disk/disk_openbsd.go create mode 100644 util/disk/disk_unix.go create mode 100644 util/disk/disk_windows.go diff --git a/api/services/control/control.pb.go b/api/services/control/control.pb.go index acc90314bb68..a1a830363869 100644 --- a/api/services/control/control.pb.go +++ b/api/services/control/control.pb.go @@ -69,7 +69,9 @@ type PruneRequest struct { Filter []string `protobuf:"bytes,1,rep,name=filter,proto3" json:"filter,omitempty"` All bool `protobuf:"varint,2,opt,name=all,proto3" json:"all,omitempty"` KeepDuration int64 `protobuf:"varint,3,opt,name=keepDuration,proto3" json:"keepDuration,omitempty"` - KeepBytes int64 `protobuf:"varint,4,opt,name=keepBytes,proto3" json:"keepBytes,omitempty"` + MinStorage int64 `protobuf:"varint,5,opt,name=minStorage,proto3" json:"minStorage,omitempty"` + MaxStorage int64 `protobuf:"varint,4,opt,name=maxStorage,proto3" json:"maxStorage,omitempty"` + Free int64 `protobuf:"varint,6,opt,name=free,proto3" json:"free,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -129,9 +131,23 @@ func (m *PruneRequest) GetKeepDuration() int64 { return 0 } -func (m *PruneRequest) GetKeepBytes() int64 { +func (m *PruneRequest) GetMinStorage() int64 { if m != nil { - return m.KeepBytes + return m.MinStorage + } + return 0 +} + +func (m *PruneRequest) GetMaxStorage() int64 { + if m != nil { + return m.MaxStorage + } + return 0 +} + +func (m *PruneRequest) GetFree() int64 { + if m != nil { + return m.Free } return 0 } @@ -2033,155 +2049,156 @@ func init() { func init() { proto.RegisterFile("control.proto", fileDescriptor_0c5120591600887d) } var fileDescriptor_0c5120591600887d = []byte{ - // 2354 bytes of a gzipped FileDescriptorProto + // 2374 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x19, 0x4d, 0x73, 0x1b, 0x59, 0x31, 0x23, 0xc9, 0xb2, 0xd4, 0x92, 0x1c, 0xf9, 0x25, 0x1b, 0x86, 0x21, 0x6b, 0x3b, 0xb3, 0x09, - 0xb8, 0x42, 0x32, 0xf2, 0x0a, 0x42, 0xb2, 0x0e, 0x84, 0x58, 0x96, 0xd8, 0x38, 0xc4, 0x15, 0xef, - 0xb3, 0xb3, 0xa1, 0xb6, 0x6a, 0xa1, 0xc6, 0xd2, 0xb3, 0x32, 0xe5, 0xd1, 0xcc, 0xf0, 0xde, 0x93, - 0x37, 0xe2, 0xc4, 0x89, 0x2a, 0x2e, 0x14, 0x17, 0x8a, 0x0b, 0x77, 0x4e, 0x9c, 0x39, 0x73, 0xa0, - 0x2a, 0x47, 0xce, 0x7b, 0xc8, 0x52, 0xf9, 0x01, 0x14, 0x47, 0x8e, 0xd4, 0xfb, 0x18, 0x69, 0x24, - 0x8d, 0x6c, 0x39, 0xc9, 0x49, 0xaf, 0xdf, 0xeb, 0xee, 0xe9, 0xee, 0xd7, 0xdd, 0xaf, 0xbb, 0x05, - 0x95, 0x76, 0x18, 0x70, 0x1a, 0xfa, 0x4e, 0x44, 0x43, 0x1e, 0xa2, 0x6a, 0x2f, 0x3c, 0x1c, 0x38, - 0x87, 0x7d, 0xcf, 0xef, 0x1c, 0x7b, 0xdc, 0x39, 0xf9, 0xd8, 0xaa, 0x77, 0x3d, 0xfe, 0xa2, 0x7f, - 0xe8, 0xb4, 0xc3, 0x5e, 0xad, 0x1b, 0x76, 0xc3, 0x5a, 0x37, 0x0c, 0xbb, 0x3e, 0x71, 0x23, 0x8f, - 0xe9, 0x65, 0x8d, 0x46, 0xed, 0x1a, 0xe3, 0x2e, 0xef, 0x33, 0xc5, 0xc5, 0xba, 0x3d, 0x49, 0x23, - 0xb7, 0x0f, 0xfb, 0x47, 0x12, 0x92, 0x80, 0x5c, 0x69, 0xf4, 0x5a, 0x02, 0x5d, 0x7c, 0xbf, 0x16, - 0x7f, 0xbf, 0xe6, 0x46, 0x5e, 0x8d, 0x0f, 0x22, 0xc2, 0x6a, 0x5f, 0x85, 0xf4, 0x98, 0x50, 0x4d, - 0x70, 0x6b, 0x26, 0x01, 0x0b, 0xfd, 0x13, 0x42, 0x6b, 0xd1, 0x61, 0x2d, 0x8c, 0x62, 0x69, 0xee, - 0x9c, 0x82, 0xdd, 0xa7, 0x6d, 0x12, 0x85, 0xbe, 0xd7, 0x1e, 0x08, 0x1a, 0xb5, 0xd2, 0x64, 0xab, - 0x5a, 0xbb, 0xa1, 0xec, 0xdc, 0xeb, 0x11, 0xc6, 0xdd, 0x5e, 0xa4, 0x10, 0xec, 0xdf, 0x19, 0x50, - 0xde, 0xa3, 0xfd, 0x80, 0x60, 0xf2, 0xeb, 0x3e, 0x61, 0x1c, 0x5d, 0x81, 0xfc, 0x91, 0xe7, 0x73, - 0x42, 0x4d, 0x63, 0x2d, 0xbb, 0x5e, 0xc4, 0x1a, 0x42, 0x55, 0xc8, 0xba, 0xbe, 0x6f, 0x66, 0xd6, - 0x8c, 0xf5, 0x02, 0x16, 0x4b, 0xb4, 0x0e, 0xe5, 0x63, 0x42, 0xa2, 0x66, 0x9f, 0xba, 0xdc, 0x0b, - 0x03, 0x33, 0xbb, 0x66, 0xac, 0x67, 0x1b, 0xb9, 0x57, 0xaf, 0x57, 0x0d, 0x3c, 0x76, 0x82, 0x6c, - 0x28, 0x0a, 0xb8, 0x31, 0xe0, 0x84, 0x99, 0xb9, 0x04, 0xda, 0x68, 0xdb, 0xbe, 0x09, 0xd5, 0xa6, - 0xc7, 0x8e, 0x9f, 0x31, 0xb7, 0x7b, 0x96, 0x2c, 0xf6, 0x63, 0x58, 0x4e, 0xe0, 0xb2, 0x28, 0x0c, - 0x18, 0x41, 0x77, 0x20, 0x4f, 0x49, 0x3b, 0xa4, 0x1d, 0x89, 0x5c, 0xaa, 0x7f, 0xe8, 0x4c, 0xba, - 0x81, 0xa3, 0x09, 0x04, 0x12, 0xd6, 0xc8, 0xf6, 0x9f, 0xb3, 0x50, 0x4a, 0xec, 0xa3, 0x25, 0xc8, - 0xec, 0x34, 0x4d, 0x63, 0xcd, 0x58, 0x2f, 0xe2, 0xcc, 0x4e, 0x13, 0x99, 0xb0, 0xb8, 0xdb, 0xe7, - 0xee, 0xa1, 0x4f, 0xb4, 0xee, 0x31, 0x88, 0x2e, 0xc3, 0xc2, 0x4e, 0xf0, 0x8c, 0x11, 0xa9, 0x78, - 0x01, 0x2b, 0x00, 0x21, 0xc8, 0xed, 0x7b, 0xbf, 0x21, 0x4a, 0x4d, 0x2c, 0xd7, 0xc8, 0x82, 0xfc, - 0x9e, 0x4b, 0x49, 0xc0, 0xcd, 0x05, 0xc1, 0xb7, 0x91, 0x31, 0x0d, 0xac, 0x77, 0x50, 0x03, 0x8a, - 0xdb, 0x94, 0xb8, 0x9c, 0x74, 0xb6, 0xb8, 0x99, 0x5f, 0x33, 0xd6, 0x4b, 0x75, 0xcb, 0x51, 0xb7, - 0xe6, 0xc4, 0xb7, 0xe6, 0x1c, 0xc4, 0xb7, 0xd6, 0x28, 0xbc, 0x7a, 0xbd, 0x7a, 0xe1, 0x8f, 0xdf, - 0x08, 0xdb, 0x0d, 0xc9, 0xd0, 0x43, 0x80, 0x27, 0x2e, 0xe3, 0xcf, 0x98, 0x64, 0xb2, 0x78, 0x26, - 0x93, 0x9c, 0x64, 0x90, 0xa0, 0x41, 0x2b, 0x00, 0xd2, 0x08, 0xdb, 0x61, 0x3f, 0xe0, 0x66, 0x41, - 0xca, 0x9e, 0xd8, 0x41, 0x6b, 0x50, 0x6a, 0x12, 0xd6, 0xa6, 0x5e, 0x24, 0xaf, 0xba, 0x28, 0xcd, - 0x93, 0xdc, 0x12, 0x1c, 0x94, 0x05, 0x0f, 0x06, 0x11, 0x31, 0x41, 0x22, 0x24, 0x76, 0xc4, 0x5d, - 0xee, 0xbf, 0x70, 0x29, 0xe9, 0x98, 0x25, 0x69, 0x2e, 0x0d, 0x09, 0xfb, 0x2a, 0x4b, 0x30, 0xb3, - 0x2c, 0x2f, 0x39, 0x06, 0xed, 0xdf, 0x16, 0xa0, 0xbc, 0x2f, 0x42, 0x21, 0x76, 0x87, 0x2a, 0x64, - 0x31, 0x39, 0xd2, 0x77, 0x23, 0x96, 0xc8, 0x01, 0x68, 0x92, 0x23, 0x2f, 0xf0, 0xa4, 0x54, 0x19, - 0xa9, 0xf8, 0x92, 0x13, 0x1d, 0x3a, 0xa3, 0x5d, 0x9c, 0xc0, 0x40, 0x0e, 0xa0, 0xd6, 0xcb, 0x28, - 0xa4, 0x9c, 0xd0, 0x26, 0x89, 0x28, 0x69, 0x0b, 0x03, 0xca, 0xfb, 0x2b, 0xe2, 0x94, 0x13, 0xd4, - 0x87, 0x6f, 0xc5, 0xbb, 0x5b, 0x9c, 0x53, 0x96, 0x20, 0xca, 0x49, 0x27, 0xbb, 0x3f, 0xed, 0x64, - 0x49, 0x91, 0x9d, 0x19, 0xd4, 0xad, 0x80, 0xd3, 0x01, 0x9e, 0xc5, 0x5b, 0xd8, 0x64, 0x9f, 0x30, - 0x26, 0x74, 0x92, 0x0e, 0x83, 0x63, 0x10, 0x59, 0x50, 0xf8, 0x19, 0x0d, 0x03, 0x4e, 0x82, 0x8e, - 0x74, 0x96, 0x22, 0x1e, 0xc2, 0xe8, 0x39, 0x54, 0xe2, 0xb5, 0x64, 0x68, 0x2e, 0x4a, 0x11, 0x3f, - 0x3e, 0x43, 0xc4, 0x31, 0x1a, 0x25, 0xd8, 0x38, 0x1f, 0xb4, 0x09, 0x0b, 0xdb, 0x6e, 0xfb, 0x05, - 0x91, 0x7e, 0x51, 0xaa, 0xaf, 0x4c, 0x33, 0x94, 0xc7, 0x4f, 0xa5, 0x23, 0x30, 0x19, 0xda, 0x17, - 0xb0, 0x22, 0x41, 0xbf, 0x84, 0x72, 0x2b, 0xe0, 0x1e, 0xf7, 0x49, 0x4f, 0xde, 0x71, 0x51, 0xdc, - 0x71, 0x63, 0xf3, 0xeb, 0xd7, 0xab, 0x3f, 0x9a, 0x99, 0xd1, 0xfa, 0xdc, 0xf3, 0x6b, 0x24, 0x41, - 0xe5, 0x24, 0x58, 0xe0, 0x31, 0x7e, 0xe8, 0x0b, 0x58, 0x8a, 0x85, 0xdd, 0x09, 0xa2, 0x3e, 0x67, - 0x26, 0x48, 0xad, 0xeb, 0x73, 0x6a, 0xad, 0x88, 0x94, 0xda, 0x13, 0x9c, 0x84, 0xb1, 0x77, 0x02, - 0x4e, 0x68, 0xe0, 0xfa, 0xda, 0x69, 0x87, 0x30, 0xda, 0x11, 0xbe, 0x29, 0x12, 0xef, 0x9e, 0x4c, - 0xb7, 0x66, 0x59, 0x9a, 0xe6, 0xc6, 0xf4, 0x57, 0x93, 0xe9, 0xd9, 0x51, 0xc8, 0x78, 0x8c, 0x14, - 0xdd, 0x83, 0x62, 0xec, 0x08, 0xcc, 0xac, 0x48, 0xe9, 0xad, 0x69, 0x3e, 0x31, 0x0a, 0x1e, 0x21, - 0x5b, 0x8f, 0xe1, 0xea, 0x69, 0x0e, 0x26, 0x02, 0xe6, 0x98, 0x0c, 0xe2, 0x80, 0x39, 0x26, 0x03, - 0x91, 0xb3, 0x4e, 0x5c, 0xbf, 0xaf, 0x72, 0x59, 0x11, 0x2b, 0x60, 0x33, 0x73, 0xcf, 0xb0, 0x1e, - 0x02, 0x9a, 0xf6, 0x84, 0x73, 0x71, 0xf8, 0x0c, 0x2e, 0xa5, 0x58, 0x35, 0x85, 0xc5, 0xf5, 0x24, - 0x8b, 0xe9, 0x80, 0x1d, 0xb1, 0xb4, 0xff, 0x96, 0x85, 0x72, 0xd2, 0xb7, 0xd0, 0x06, 0x5c, 0x52, - 0x1a, 0x63, 0x72, 0x94, 0x08, 0x46, 0xc5, 0x3c, 0xed, 0x08, 0xd5, 0xe1, 0xf2, 0x4e, 0x4f, 0x6f, - 0x27, 0xe3, 0x37, 0x23, 0x93, 0x4d, 0xea, 0x19, 0x0a, 0xe1, 0x03, 0xc5, 0x6a, 0x32, 0xe8, 0xb3, - 0xf2, 0x76, 0x3e, 0x39, 0x3d, 0x00, 0x9c, 0x54, 0x5a, 0xe5, 0x62, 0xe9, 0x7c, 0xd1, 0x4f, 0x60, - 0x51, 0x1d, 0x30, 0x9d, 0x57, 0x3e, 0x3a, 0xfd, 0x13, 0x8a, 0x59, 0x4c, 0x23, 0xc8, 0x95, 0x1e, - 0xcc, 0x5c, 0x38, 0x07, 0xb9, 0xa6, 0xb1, 0x1e, 0x81, 0x35, 0x5b, 0xe4, 0xf3, 0xb8, 0x80, 0xfd, - 0x57, 0x03, 0x96, 0xa7, 0x3e, 0x24, 0x9e, 0x44, 0xf9, 0x28, 0x28, 0x16, 0x72, 0x8d, 0x9a, 0xb0, - 0xa0, 0x92, 0x54, 0x46, 0x0a, 0xec, 0xcc, 0x21, 0xb0, 0x93, 0xc8, 0x50, 0x8a, 0xd8, 0xba, 0x07, - 0xf0, 0x76, 0xce, 0x6a, 0xff, 0xdd, 0x80, 0x8a, 0x4e, 0x08, 0xba, 0x7e, 0x70, 0xa1, 0x3a, 0x8c, - 0x31, 0xbd, 0xa7, 0x2b, 0x89, 0x3b, 0x33, 0x73, 0x89, 0x42, 0x73, 0x26, 0xe9, 0x94, 0x8c, 0x53, - 0xec, 0xac, 0xed, 0xd8, 0xaf, 0x26, 0x50, 0xcf, 0x25, 0xf9, 0x35, 0xa8, 0xec, 0xcb, 0x3a, 0x75, - 0xe6, 0xb3, 0x68, 0xff, 0xd7, 0x80, 0xa5, 0x18, 0x47, 0x6b, 0xf7, 0x43, 0x28, 0x9c, 0x10, 0xca, - 0xc9, 0x4b, 0xc2, 0xb4, 0x56, 0xe6, 0xb4, 0x56, 0x9f, 0x4b, 0x0c, 0x3c, 0xc4, 0x44, 0x9b, 0x50, - 0x50, 0x35, 0x31, 0x89, 0x2f, 0x6a, 0x65, 0x16, 0x95, 0xfe, 0xde, 0x10, 0x1f, 0xd5, 0x20, 0xe7, - 0x87, 0x5d, 0xa6, 0x63, 0xe6, 0x3b, 0xb3, 0xe8, 0x9e, 0x84, 0x5d, 0x2c, 0x11, 0xd1, 0x7d, 0x28, - 0x7c, 0xe5, 0xd2, 0xc0, 0x0b, 0xba, 0x71, 0x14, 0xac, 0xce, 0x22, 0x7a, 0xae, 0xf0, 0xf0, 0x90, - 0x40, 0x94, 0x71, 0x79, 0x75, 0x86, 0x1e, 0x43, 0xbe, 0xe3, 0x75, 0x09, 0xe3, 0xca, 0x24, 0x8d, - 0xba, 0x78, 0x8f, 0xbe, 0x7e, 0xbd, 0x7a, 0x33, 0xf1, 0xe0, 0x84, 0x11, 0x09, 0x44, 0xd3, 0xe0, - 0x7a, 0x01, 0xa1, 0xa2, 0x07, 0xb8, 0xad, 0x48, 0x9c, 0xa6, 0xfc, 0xc1, 0x9a, 0x83, 0xe0, 0xe5, - 0xa9, 0x67, 0x45, 0xe6, 0x8b, 0xb7, 0xe3, 0xa5, 0x38, 0x88, 0x30, 0x08, 0xdc, 0x1e, 0xd1, 0xe5, - 0x86, 0x5c, 0x8b, 0xaa, 0xa8, 0x2d, 0xfc, 0xbc, 0x23, 0xeb, 0xc5, 0x02, 0xd6, 0x10, 0xda, 0x84, - 0x45, 0xc6, 0x5d, 0x2a, 0x72, 0xce, 0xc2, 0x9c, 0xe5, 0x5c, 0x4c, 0x80, 0x1e, 0x40, 0xb1, 0x1d, - 0xf6, 0x22, 0x9f, 0x08, 0xea, 0xfc, 0x9c, 0xd4, 0x23, 0x12, 0xe1, 0x7a, 0x84, 0xd2, 0x90, 0xca, - 0x42, 0xb2, 0x88, 0x15, 0x80, 0xee, 0x42, 0x25, 0xa2, 0x61, 0x97, 0x12, 0xc6, 0x3e, 0xa5, 0x61, - 0x3f, 0xd2, 0xc5, 0xc0, 0xb2, 0x48, 0xde, 0x7b, 0xc9, 0x03, 0x3c, 0x8e, 0x67, 0xff, 0x27, 0x03, - 0xe5, 0xa4, 0x8b, 0x4c, 0x55, 0xd8, 0x8f, 0x21, 0xaf, 0x1c, 0x4e, 0xf9, 0xfa, 0xdb, 0xd9, 0x58, - 0x71, 0x48, 0xb5, 0xb1, 0x09, 0x8b, 0xed, 0x3e, 0x95, 0xe5, 0xb7, 0x2a, 0xca, 0x63, 0x50, 0x68, - 0xca, 0x43, 0xee, 0xfa, 0xd2, 0xc6, 0x59, 0xac, 0x00, 0x51, 0x91, 0x0f, 0xbb, 0xa4, 0xf3, 0x55, - 0xe4, 0x43, 0xb2, 0xe4, 0xfd, 0x2d, 0xbe, 0xd3, 0xfd, 0x15, 0xce, 0x7d, 0x7f, 0xf6, 0x3f, 0x0d, - 0x28, 0x0e, 0x63, 0x2b, 0x61, 0x5d, 0xe3, 0x9d, 0xad, 0x3b, 0x66, 0x99, 0xcc, 0xdb, 0x59, 0xe6, - 0x0a, 0xe4, 0x19, 0xa7, 0xc4, 0xed, 0xa9, 0x7e, 0x11, 0x6b, 0x48, 0x64, 0xb1, 0x1e, 0xeb, 0xca, - 0x1b, 0x2a, 0x63, 0xb1, 0xb4, 0xff, 0x67, 0x40, 0x65, 0x2c, 0xdc, 0xdf, 0xab, 0x2e, 0x97, 0x61, - 0xc1, 0x27, 0x27, 0x44, 0x75, 0xb4, 0x59, 0xac, 0x00, 0xb1, 0xcb, 0x5e, 0x84, 0x94, 0x4b, 0xe1, - 0xca, 0x58, 0x01, 0x42, 0xe6, 0x0e, 0xe1, 0xae, 0xe7, 0xcb, 0xbc, 0x54, 0xc6, 0x1a, 0x12, 0x32, - 0xf7, 0xa9, 0xaf, 0x6b, 0x74, 0xb1, 0x44, 0x36, 0xe4, 0xbc, 0xe0, 0x28, 0xd4, 0x6e, 0x23, 0x2b, - 0x1b, 0x55, 0xeb, 0xed, 0x04, 0x47, 0x21, 0x96, 0x67, 0xe8, 0x1a, 0xe4, 0xa9, 0x1b, 0x74, 0x49, - 0x5c, 0xa0, 0x17, 0x05, 0x16, 0x16, 0x3b, 0x58, 0x1f, 0xd8, 0x36, 0x94, 0x65, 0x57, 0xbc, 0x4b, - 0x98, 0xe8, 0xc1, 0x84, 0x5b, 0x77, 0x5c, 0xee, 0x4a, 0xb5, 0xcb, 0x58, 0xae, 0xed, 0x5b, 0x80, - 0x9e, 0x78, 0x8c, 0x3f, 0x97, 0x33, 0x05, 0x76, 0x56, 0xcb, 0xbc, 0x0f, 0x97, 0xc6, 0xb0, 0xf5, - 0xb3, 0xf0, 0xe3, 0x89, 0xa6, 0xf9, 0xfa, 0x74, 0xc6, 0x95, 0xa3, 0x0b, 0x47, 0x11, 0x4e, 0xf4, - 0xce, 0x15, 0x28, 0x49, 0xbd, 0xd4, 0xb7, 0x6d, 0x17, 0xca, 0x0a, 0xd4, 0xcc, 0x3f, 0x83, 0x8b, - 0x31, 0xa3, 0xcf, 0x09, 0x95, 0xed, 0x8c, 0x21, 0xed, 0xf2, 0xbd, 0x59, 0x5f, 0x69, 0x8c, 0xa3, - 0xe3, 0x49, 0x7a, 0x9b, 0xc0, 0x25, 0x89, 0xf3, 0xc8, 0x63, 0x3c, 0xa4, 0x83, 0x58, 0xeb, 0x15, - 0x80, 0xad, 0x36, 0xf7, 0x4e, 0xc8, 0xd3, 0xc0, 0x57, 0xcf, 0x68, 0x01, 0x27, 0x76, 0xe2, 0x27, - 0x32, 0x33, 0xea, 0x1c, 0xaf, 0x42, 0xb1, 0xe5, 0x52, 0x7f, 0xd0, 0x7a, 0xe9, 0x71, 0xdd, 0xc0, - 0x8f, 0x36, 0xec, 0x3f, 0x18, 0xb0, 0x9c, 0xfc, 0x4e, 0xeb, 0x44, 0xa4, 0x8b, 0xfb, 0x90, 0xe3, - 0x71, 0x1d, 0xb3, 0x94, 0xa6, 0xc4, 0x14, 0x89, 0x28, 0x75, 0xb0, 0x24, 0x4a, 0x58, 0x5a, 0x05, - 0xce, 0xf5, 0xd3, 0xc9, 0x27, 0x2c, 0xfd, 0x4d, 0x11, 0xd0, 0xf4, 0x71, 0x4a, 0x47, 0x9c, 0x6c, - 0x10, 0x33, 0x13, 0x0d, 0xe2, 0x97, 0x93, 0x0d, 0xa2, 0x7a, 0x9a, 0xef, 0xce, 0x23, 0xc9, 0x1c, - 0x6d, 0xe2, 0x58, 0x1f, 0x93, 0x3b, 0x47, 0x1f, 0x83, 0xd6, 0xe3, 0x17, 0x47, 0xbd, 0x75, 0x28, - 0xce, 0x29, 0x34, 0x6a, 0x3b, 0xba, 0xae, 0xd0, 0xaf, 0xd0, 0x83, 0xf3, 0x4d, 0x4b, 0x72, 0x93, - 0x93, 0x92, 0x06, 0x94, 0xb6, 0xe3, 0x44, 0x79, 0x8e, 0x51, 0x49, 0x92, 0x08, 0x6d, 0xe8, 0xc2, - 0x46, 0xa5, 0xe6, 0xab, 0xd3, 0x2a, 0xc6, 0x63, 0x91, 0x90, 0xea, 0xca, 0xe6, 0x28, 0xa5, 0xb4, - 0x2c, 0x4a, 0x03, 0x6d, 0xce, 0x65, 0xfb, 0x39, 0xeb, 0x4b, 0xf4, 0x09, 0xe4, 0x31, 0x61, 0x7d, - 0x9f, 0xcb, 0xf9, 0x4b, 0xa9, 0x7e, 0x6d, 0x06, 0x77, 0x85, 0x24, 0x63, 0x55, 0x13, 0xa0, 0x9f, - 0xc3, 0xa2, 0x5a, 0x31, 0xb3, 0x34, 0x6b, 0x6c, 0x90, 0x22, 0x99, 0xa6, 0xd1, 0x0d, 0x85, 0x86, - 0x44, 0x38, 0x7e, 0x4a, 0x02, 0xa2, 0xe7, 0x82, 0xa2, 0x35, 0x5e, 0xc0, 0x89, 0x1d, 0x54, 0x87, - 0x05, 0x4e, 0xdd, 0x36, 0x31, 0x2b, 0x73, 0x98, 0x50, 0xa1, 0x8a, 0xc4, 0x16, 0x79, 0x41, 0x40, - 0x3a, 0xe6, 0x92, 0xaa, 0x94, 0x14, 0x84, 0xbe, 0x0b, 0x4b, 0x41, 0xbf, 0x27, 0x9b, 0x85, 0xce, - 0x3e, 0x27, 0x11, 0x33, 0x2f, 0xca, 0xef, 0x4d, 0xec, 0xa2, 0xeb, 0x50, 0x09, 0xfa, 0xbd, 0x03, - 0xf1, 0xc2, 0x2b, 0xb4, 0xaa, 0x44, 0x1b, 0xdf, 0x44, 0xb7, 0x60, 0x59, 0xd0, 0xc5, 0xb7, 0xad, - 0x30, 0x97, 0x25, 0xe6, 0xf4, 0x01, 0x6a, 0x40, 0x85, 0xbc, 0x54, 0x03, 0x81, 0x96, 0xf4, 0x5f, - 0x34, 0x87, 0x3e, 0xe3, 0x24, 0x68, 0x0d, 0x4a, 0x41, 0xbf, 0xf7, 0x3c, 0x2e, 0x7c, 0x2f, 0xc9, - 0x6f, 0x25, 0xb7, 0xde, 0x43, 0x67, 0xfe, 0x3e, 0xfa, 0x0e, 0xeb, 0x4b, 0x28, 0x27, 0x6f, 0x3b, - 0x85, 0xf6, 0xee, 0x78, 0x5f, 0x3f, 0x87, 0xf7, 0x25, 0xda, 0x9a, 0x01, 0x7c, 0xfb, 0x59, 0xd4, - 0x71, 0x39, 0x49, 0xcb, 0xef, 0xd3, 0x79, 0xee, 0x0a, 0xe4, 0xf7, 0x94, 0x3b, 0xa8, 0xa9, 0xac, - 0x86, 0xc4, 0x7e, 0x93, 0x88, 0x2b, 0xd2, 0x49, 0x5d, 0x43, 0x32, 0x2f, 0x7a, 0x81, 0xeb, 0xc7, - 0xa3, 0xd9, 0x02, 0x1e, 0xc2, 0xf6, 0x55, 0xb0, 0xd2, 0x3e, 0xad, 0x0c, 0x65, 0xff, 0x25, 0x03, - 0x30, 0xba, 0x3e, 0xf4, 0x21, 0x40, 0x8f, 0x74, 0x3c, 0xf7, 0x57, 0x7c, 0xd4, 0xd2, 0x16, 0xe5, - 0x8e, 0xec, 0x6b, 0x47, 0xcd, 0x47, 0xe6, 0x9d, 0x9b, 0x0f, 0x04, 0x39, 0x26, 0xe4, 0x55, 0x85, - 0x92, 0x5c, 0xa3, 0xa7, 0x50, 0x72, 0x83, 0x20, 0xe4, 0x32, 0x90, 0xe2, 0x76, 0xff, 0xf6, 0x69, - 0x0e, 0xe7, 0x6c, 0x8d, 0xf0, 0x55, 0x9c, 0x26, 0x39, 0x58, 0x0f, 0xa0, 0x3a, 0x89, 0x70, 0xae, - 0x76, 0xf4, 0x1f, 0x19, 0xb8, 0x38, 0x71, 0xad, 0xe8, 0x11, 0x54, 0x15, 0x34, 0x31, 0xa2, 0x39, - 0x2b, 0x34, 0xa6, 0xa8, 0xd0, 0x43, 0x28, 0x6f, 0x71, 0x2e, 0x72, 0xb1, 0xd2, 0x57, 0x35, 0xa1, - 0xa7, 0x73, 0x19, 0xa3, 0x40, 0x8f, 0x46, 0x89, 0x2d, 0x3b, 0x6b, 0xd4, 0x30, 0x21, 0x7f, 0x7a, - 0x56, 0xb3, 0x7e, 0x31, 0x3b, 0x00, 0xb2, 0xca, 0x4a, 0xf5, 0xf1, 0x00, 0x38, 0x23, 0xaf, 0x8d, - 0x6c, 0xf8, 0x27, 0x03, 0x0a, 0x71, 0x80, 0xa6, 0x4e, 0x4b, 0xee, 0x8f, 0x4f, 0x4b, 0x6e, 0xcc, - 0x7e, 0x56, 0xdf, 0xe7, 0x90, 0xe4, 0xe6, 0x4f, 0xe1, 0x83, 0xd4, 0x92, 0x06, 0x95, 0x60, 0x71, - 0xff, 0x60, 0x0b, 0x1f, 0xb4, 0x9a, 0xd5, 0x0b, 0xa8, 0x0c, 0x85, 0xed, 0xa7, 0xbb, 0x7b, 0x4f, - 0x5a, 0x07, 0xad, 0xaa, 0x21, 0x8e, 0x9a, 0x2d, 0xb1, 0x6e, 0x56, 0x33, 0xf5, 0xdf, 0xe7, 0x61, - 0x71, 0x5b, 0xfd, 0x37, 0x87, 0x0e, 0xa0, 0x38, 0xfc, 0xd3, 0x06, 0xd9, 0x29, 0xa6, 0x99, 0xf8, - 0xf7, 0xc7, 0xfa, 0xe8, 0x54, 0x1c, 0xfd, 0xe4, 0x3d, 0x82, 0x05, 0xf9, 0xf7, 0x15, 0x4a, 0x19, - 0x4c, 0x24, 0xff, 0xd7, 0xb2, 0x4e, 0xff, 0x3b, 0x68, 0xc3, 0x10, 0x9c, 0xe4, 0x54, 0x27, 0x8d, - 0x53, 0x72, 0x74, 0x6c, 0xad, 0x9e, 0x31, 0x0e, 0x42, 0xbb, 0x90, 0xd7, 0xad, 0x6e, 0x1a, 0x6a, - 0x72, 0x76, 0x63, 0xad, 0xcd, 0x46, 0x50, 0xcc, 0x36, 0x0c, 0xb4, 0x3b, 0xfc, 0x37, 0x20, 0x4d, - 0xb4, 0x64, 0x9f, 0x60, 0x9d, 0x71, 0xbe, 0x6e, 0x6c, 0x18, 0xe8, 0x0b, 0x28, 0x25, 0x3a, 0x01, - 0x94, 0x52, 0x87, 0x4e, 0xb7, 0x15, 0xd6, 0x8d, 0x33, 0xb0, 0xb4, 0xe6, 0x2d, 0xc8, 0xc9, 0x04, - 0x90, 0x62, 0xec, 0x44, 0xa3, 0x90, 0x26, 0xe6, 0x58, 0xe3, 0x70, 0xa8, 0x5a, 0x1b, 0x12, 0x24, - 0xbd, 0x0f, 0xdd, 0x38, 0xab, 0x22, 0x99, 0xe9, 0x36, 0x53, 0x4e, 0xbc, 0x61, 0xa0, 0x10, 0xd0, - 0x74, 0xd2, 0x47, 0xdf, 0x4f, 0xf1, 0x92, 0x59, 0xaf, 0x92, 0x75, 0x6b, 0x3e, 0x64, 0xa5, 0x54, - 0xa3, 0xfc, 0xea, 0xcd, 0x8a, 0xf1, 0xaf, 0x37, 0x2b, 0xc6, 0xbf, 0xdf, 0xac, 0x18, 0x87, 0x79, - 0x59, 0x6b, 0xfe, 0xe0, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xaa, 0x06, 0xac, 0x18, 0xbb, 0x1e, - 0x00, 0x00, + 0xb8, 0x42, 0x32, 0xf2, 0x0a, 0x42, 0xb2, 0x0e, 0x84, 0x58, 0x96, 0xd8, 0x38, 0x24, 0x15, 0xef, + 0xb3, 0xb3, 0xa1, 0xb6, 0x6a, 0xa1, 0xc6, 0xd2, 0xb3, 0x32, 0xe5, 0xd1, 0xcc, 0xf0, 0xe6, 0xc9, + 0x6b, 0x71, 0xe2, 0xca, 0x85, 0xe2, 0x42, 0x71, 0xe1, 0xce, 0x89, 0x33, 0x67, 0x0e, 0x54, 0xe5, + 0xc8, 0x79, 0x0f, 0x59, 0x2a, 0x3f, 0x80, 0xe2, 0xc8, 0x71, 0xeb, 0x7d, 0x8c, 0xf4, 0x24, 0x8d, + 0x6c, 0x39, 0xc9, 0x49, 0xaf, 0xfb, 0x75, 0xf7, 0x74, 0xf7, 0xeb, 0xee, 0xd7, 0xfd, 0x04, 0x95, + 0x76, 0x18, 0x30, 0x1a, 0xfa, 0x4e, 0x44, 0x43, 0x16, 0xa2, 0x6a, 0x2f, 0x3c, 0x18, 0x38, 0x07, + 0x7d, 0xcf, 0xef, 0x1c, 0x79, 0xcc, 0x39, 0xfe, 0xd8, 0xaa, 0x77, 0x3d, 0xf6, 0xb2, 0x7f, 0xe0, + 0xb4, 0xc3, 0x5e, 0xad, 0x1b, 0x76, 0xc3, 0x5a, 0x37, 0x0c, 0xbb, 0x3e, 0x71, 0x23, 0x2f, 0x56, + 0xcb, 0x1a, 0x8d, 0xda, 0xb5, 0x98, 0xb9, 0xac, 0x1f, 0x4b, 0x29, 0xd6, 0xed, 0x49, 0x1e, 0x81, + 0x3e, 0xe8, 0x1f, 0x0a, 0x48, 0x00, 0x62, 0xa5, 0xc8, 0x6b, 0x1a, 0x39, 0xff, 0x7e, 0x2d, 0xf9, + 0x7e, 0xcd, 0x8d, 0xbc, 0x1a, 0x1b, 0x44, 0x24, 0xae, 0x7d, 0x15, 0xd2, 0x23, 0x42, 0x15, 0xc3, + 0xad, 0x99, 0x0c, 0x71, 0xe8, 0x1f, 0x13, 0x5a, 0x8b, 0x0e, 0x6a, 0x61, 0x94, 0x68, 0x73, 0xe7, + 0x14, 0xea, 0x3e, 0x6d, 0x93, 0x28, 0xf4, 0xbd, 0xf6, 0x80, 0xf3, 0xc8, 0x95, 0x62, 0x5b, 0x55, + 0xd6, 0x0d, 0x75, 0x67, 0x5e, 0x8f, 0xc4, 0xcc, 0xed, 0x45, 0x92, 0xc0, 0x7e, 0x65, 0x40, 0x79, + 0x97, 0xf6, 0x03, 0x82, 0xc9, 0x6f, 0xfb, 0x24, 0x66, 0xe8, 0x0a, 0xe4, 0x0f, 0x3d, 0x9f, 0x11, + 0x6a, 0x1a, 0x6b, 0xd9, 0xf5, 0x22, 0x56, 0x10, 0xaa, 0x42, 0xd6, 0xf5, 0x7d, 0x33, 0xb3, 0x66, + 0xac, 0x17, 0x30, 0x5f, 0xa2, 0x75, 0x28, 0x1f, 0x11, 0x12, 0x35, 0xfb, 0xd4, 0x65, 0x5e, 0x18, + 0x98, 0xd9, 0x35, 0x63, 0x3d, 0xdb, 0xc8, 0xbd, 0x7a, 0xbd, 0x6a, 0xe0, 0xb1, 0x1d, 0x74, 0x1d, + 0xa0, 0xe7, 0x05, 0x7b, 0x2c, 0xa4, 0x6e, 0x97, 0x98, 0x0b, 0x1a, 0x9d, 0x86, 0x17, 0x54, 0xee, + 0x49, 0x42, 0x95, 0x1b, 0xa3, 0x1a, 0xe2, 0x91, 0x09, 0xb9, 0x43, 0x4a, 0x88, 0x99, 0xd7, 0xf6, + 0x05, 0xc6, 0xbe, 0x09, 0xd5, 0xa6, 0x17, 0x1f, 0x3d, 0x8f, 0xdd, 0xee, 0x59, 0xd6, 0xd8, 0x8f, + 0x61, 0x59, 0xa3, 0x8d, 0xa3, 0x30, 0x88, 0x09, 0xba, 0x03, 0x79, 0x4a, 0xda, 0x21, 0xed, 0x08, + 0xe2, 0x52, 0xfd, 0x43, 0x67, 0x32, 0x90, 0x1c, 0xc5, 0xc0, 0x89, 0xb0, 0x22, 0xb6, 0xff, 0x92, + 0x85, 0x92, 0x86, 0x47, 0x4b, 0x90, 0xd9, 0x69, 0x9a, 0xc6, 0x9a, 0xb1, 0x5e, 0xc4, 0x99, 0x9d, + 0x26, 0x32, 0x61, 0xf1, 0x69, 0x9f, 0xb9, 0x07, 0x3e, 0x51, 0xde, 0x4b, 0x40, 0x74, 0x19, 0x16, + 0x76, 0x82, 0xe7, 0x31, 0x11, 0xae, 0x2b, 0x60, 0x09, 0x20, 0x04, 0xb9, 0x3d, 0xef, 0x77, 0xca, + 0x03, 0x58, 0xac, 0x91, 0x05, 0xf9, 0x5d, 0x97, 0x92, 0x80, 0x09, 0xef, 0x15, 0x1b, 0x19, 0xd3, + 0xc0, 0x0a, 0x83, 0x1a, 0x50, 0xdc, 0xa6, 0xc4, 0x65, 0xa4, 0xb3, 0xc5, 0x84, 0x5b, 0x4a, 0x75, + 0xcb, 0x91, 0xe7, 0xee, 0x24, 0xe7, 0xee, 0xec, 0x27, 0xe7, 0xde, 0x28, 0xbc, 0x7a, 0xbd, 0x7a, + 0xe1, 0x4f, 0xdf, 0xac, 0x1a, 0x78, 0xc4, 0x86, 0x1e, 0x02, 0x3c, 0x71, 0x63, 0xf6, 0x3c, 0x16, + 0x42, 0x16, 0xcf, 0x14, 0x92, 0x13, 0x02, 0x34, 0x1e, 0xb4, 0x02, 0x20, 0x9c, 0xb0, 0x1d, 0xf6, + 0x03, 0x66, 0x16, 0x84, 0xee, 0x1a, 0x06, 0xad, 0x41, 0xa9, 0x49, 0xe2, 0x36, 0xf5, 0x22, 0x11, + 0x2c, 0x45, 0xe1, 0x1e, 0x1d, 0xc5, 0x25, 0x48, 0x0f, 0xee, 0x0f, 0x22, 0x62, 0x82, 0x20, 0xd0, + 0x30, 0xfc, 0x2c, 0xf7, 0x5e, 0xba, 0x94, 0x74, 0xcc, 0x92, 0x70, 0x97, 0x82, 0xb8, 0x7f, 0xa5, + 0x27, 0x62, 0xb3, 0x2c, 0x0e, 0x39, 0x01, 0xed, 0xdf, 0x17, 0xa0, 0xbc, 0xc7, 0x93, 0x29, 0x09, + 0x87, 0x2a, 0x64, 0x31, 0x39, 0x54, 0x67, 0xc3, 0x97, 0xc8, 0x01, 0x68, 0x92, 0x43, 0x2f, 0xf0, + 0x84, 0x56, 0x19, 0x61, 0xf8, 0x92, 0x13, 0x1d, 0x38, 0x23, 0x2c, 0xd6, 0x28, 0x90, 0x03, 0xa8, + 0x75, 0x12, 0x85, 0x94, 0x11, 0xda, 0x24, 0x11, 0x25, 0x6d, 0xee, 0x40, 0x71, 0x7e, 0x45, 0x9c, + 0xb2, 0x83, 0xfa, 0xf0, 0x9d, 0x04, 0xbb, 0xc5, 0x18, 0x8d, 0x35, 0xa6, 0x9c, 0x08, 0xb2, 0xfb, + 0xd3, 0x41, 0xa6, 0xab, 0xec, 0xcc, 0xe0, 0x6e, 0x05, 0x8c, 0x0e, 0xf0, 0x2c, 0xd9, 0xdc, 0x27, + 0x7b, 0x24, 0x8e, 0xb9, 0x4d, 0x22, 0x60, 0x70, 0x02, 0x22, 0x0b, 0x0a, 0xbf, 0xa0, 0x61, 0xc0, + 0x48, 0xd0, 0x11, 0xc1, 0x52, 0xc4, 0x43, 0x18, 0xbd, 0x80, 0x4a, 0xb2, 0x16, 0x02, 0xcd, 0x45, + 0xa1, 0xe2, 0xc7, 0x67, 0xa8, 0x38, 0xc6, 0x23, 0x15, 0x1b, 0x97, 0x83, 0x36, 0x61, 0x61, 0xdb, + 0x6d, 0xbf, 0x24, 0x22, 0x2e, 0x4a, 0xf5, 0x95, 0x69, 0x81, 0x62, 0xfb, 0x99, 0x08, 0x84, 0x58, + 0x64, 0xf5, 0x05, 0x2c, 0x59, 0xd0, 0xaf, 0xa1, 0xdc, 0x0a, 0x98, 0xc7, 0x7c, 0xd2, 0x13, 0x67, + 0x5c, 0xe4, 0x67, 0xdc, 0xd8, 0xfc, 0xfa, 0xf5, 0xea, 0x4f, 0x66, 0xd6, 0xc4, 0x3e, 0xf3, 0xfc, + 0x1a, 0xd1, 0xb8, 0x1c, 0x4d, 0x04, 0x1e, 0x93, 0x87, 0xbe, 0x80, 0xa5, 0x44, 0xd9, 0x9d, 0x20, + 0xea, 0xb3, 0xd8, 0x04, 0x61, 0x75, 0x7d, 0x4e, 0xab, 0x25, 0x93, 0x34, 0x7b, 0x42, 0x12, 0x77, + 0xf6, 0x4e, 0xc0, 0x08, 0x0d, 0x5c, 0x5f, 0x05, 0xed, 0x10, 0x46, 0x3b, 0x3c, 0x36, 0x79, 0xe9, + 0xde, 0x15, 0x05, 0xdb, 0x2c, 0x0b, 0xd7, 0xdc, 0x98, 0xfe, 0xaa, 0x5e, 0xe0, 0x1d, 0x49, 0x8c, + 0xc7, 0x58, 0xd1, 0x3d, 0x28, 0x26, 0x81, 0x10, 0x9b, 0x15, 0xa1, 0xbd, 0x35, 0x2d, 0x27, 0x21, + 0xc1, 0x23, 0x62, 0xeb, 0x31, 0x5c, 0x3d, 0x2d, 0xc0, 0x78, 0xc2, 0x1c, 0x91, 0x41, 0x92, 0x30, + 0x47, 0x64, 0xc0, 0x6b, 0xd6, 0xb1, 0xeb, 0xf7, 0x65, 0x2d, 0x2b, 0x62, 0x09, 0x6c, 0x66, 0xee, + 0x19, 0xd6, 0x43, 0x40, 0xd3, 0x91, 0x70, 0x2e, 0x09, 0x9f, 0xc1, 0xa5, 0x14, 0xaf, 0xa6, 0x88, + 0xb8, 0xae, 0x8b, 0x98, 0x4e, 0xd8, 0x91, 0x48, 0xfb, 0xef, 0x59, 0x28, 0xeb, 0xb1, 0x85, 0x36, + 0xe0, 0x92, 0xb4, 0x18, 0x93, 0x43, 0x2d, 0x19, 0xa5, 0xf0, 0xb4, 0x2d, 0x54, 0x87, 0xcb, 0x3b, + 0x3d, 0x85, 0xd6, 0xf3, 0x37, 0x23, 0x8a, 0x4d, 0xea, 0x1e, 0x0a, 0xe1, 0x03, 0x29, 0x6a, 0x32, + 0xe9, 0xb3, 0xe2, 0x74, 0x3e, 0x39, 0x3d, 0x01, 0x9c, 0x54, 0x5e, 0x19, 0x62, 0xe9, 0x72, 0xd1, + 0xcf, 0x60, 0x51, 0x6e, 0xc4, 0xaa, 0xae, 0x7c, 0x74, 0xfa, 0x27, 0xa4, 0xb0, 0x84, 0x87, 0xb3, + 0x4b, 0x3b, 0x62, 0x73, 0xe1, 0x1c, 0xec, 0x8a, 0xc7, 0x7a, 0x04, 0xd6, 0x6c, 0x95, 0xcf, 0x13, + 0x02, 0xf6, 0xdf, 0x0c, 0x58, 0x9e, 0xfa, 0x10, 0xbf, 0x12, 0xc5, 0xa5, 0x20, 0x45, 0x88, 0x35, + 0x6a, 0xc2, 0x82, 0x2c, 0x52, 0x19, 0xa1, 0xb0, 0x33, 0x87, 0xc2, 0x8e, 0x56, 0xa1, 0x24, 0xb3, + 0x75, 0x0f, 0xe0, 0xed, 0x82, 0xd5, 0xfe, 0x87, 0x01, 0x15, 0x55, 0x10, 0x54, 0xff, 0xe0, 0x42, + 0x75, 0x98, 0x63, 0x0a, 0xa7, 0x3a, 0x89, 0x3b, 0x33, 0x6b, 0x89, 0x24, 0x73, 0x26, 0xf9, 0xa4, + 0x8e, 0x53, 0xe2, 0xac, 0xed, 0x24, 0xae, 0x26, 0x48, 0xcf, 0xa5, 0xf9, 0x35, 0xa8, 0xec, 0x89, + 0x4e, 0x77, 0xe6, 0xb5, 0x68, 0xff, 0xcf, 0x80, 0xa5, 0x84, 0x46, 0x59, 0xf7, 0x63, 0x28, 0x1c, + 0x13, 0xca, 0xc8, 0x09, 0x89, 0x95, 0x55, 0xe6, 0xb4, 0x55, 0x9f, 0x0b, 0x0a, 0x3c, 0xa4, 0x44, + 0x9b, 0x50, 0x90, 0x5d, 0x35, 0x49, 0x0e, 0x6a, 0x65, 0x16, 0x97, 0xfa, 0xde, 0x90, 0x1e, 0xd5, + 0x20, 0xe7, 0x87, 0xdd, 0x58, 0xe5, 0xcc, 0xf7, 0x66, 0xf1, 0x3d, 0x09, 0xbb, 0x58, 0x10, 0xa2, + 0xfb, 0x50, 0xf8, 0xca, 0xa5, 0x81, 0x17, 0x74, 0x93, 0x2c, 0x58, 0x9d, 0xc5, 0xf4, 0x42, 0xd2, + 0xe1, 0x21, 0x03, 0x6f, 0xe3, 0xf2, 0x72, 0x0f, 0x3d, 0x86, 0x7c, 0xc7, 0xeb, 0x92, 0x98, 0x49, + 0x97, 0x34, 0xea, 0xfc, 0x3e, 0xfa, 0xfa, 0xf5, 0xea, 0x4d, 0xed, 0xc2, 0x09, 0x23, 0x12, 0xf0, + 0xb1, 0xc3, 0xf5, 0x02, 0x42, 0xf9, 0x14, 0x71, 0x5b, 0xb2, 0x38, 0x4d, 0xf1, 0x83, 0x95, 0x04, + 0x2e, 0xcb, 0x93, 0xd7, 0x8a, 0xa8, 0x17, 0x6f, 0x27, 0x4b, 0x4a, 0xe0, 0x69, 0x10, 0xb8, 0x3d, + 0xa2, 0xda, 0x0d, 0xb1, 0xe6, 0x5d, 0x51, 0x9b, 0xc7, 0x79, 0x47, 0xf4, 0x8b, 0x05, 0xac, 0x20, + 0xb4, 0x09, 0x8b, 0x31, 0x73, 0x29, 0xaf, 0x39, 0x0b, 0x73, 0xb6, 0x73, 0x09, 0x03, 0x7a, 0x00, + 0xc5, 0x76, 0xd8, 0x8b, 0x7c, 0xc2, 0xb9, 0xf3, 0x73, 0x72, 0x8f, 0x58, 0x78, 0xe8, 0x11, 0x4a, + 0x43, 0x2a, 0x1a, 0xc9, 0x22, 0x96, 0x00, 0xba, 0x0b, 0x95, 0x88, 0x86, 0x5d, 0x4a, 0xe2, 0xf8, + 0x53, 0x1a, 0xf6, 0x23, 0xd5, 0x0c, 0x2c, 0xf3, 0xe2, 0xbd, 0xab, 0x6f, 0xe0, 0x71, 0x3a, 0xfb, + 0xbf, 0x19, 0x28, 0xeb, 0x21, 0x32, 0xd5, 0x61, 0x3f, 0x86, 0xbc, 0x0c, 0x38, 0x19, 0xeb, 0x6f, + 0xe7, 0x63, 0x29, 0x21, 0xd5, 0xc7, 0x26, 0x2c, 0xb6, 0xfb, 0x54, 0xb4, 0xdf, 0xb2, 0x29, 0x4f, + 0x40, 0x6e, 0x29, 0x0b, 0x99, 0xeb, 0xcb, 0xa1, 0x06, 0x4b, 0x80, 0x77, 0xe4, 0xc3, 0x39, 0xeb, + 0x7c, 0x1d, 0xf9, 0x90, 0x4d, 0x3f, 0xbf, 0xc5, 0x77, 0x3a, 0xbf, 0xc2, 0xb9, 0xcf, 0xcf, 0xfe, + 0x97, 0x01, 0xc5, 0x61, 0x6e, 0x69, 0xde, 0x35, 0xde, 0xd9, 0xbb, 0x63, 0x9e, 0xc9, 0xbc, 0x9d, + 0x67, 0xae, 0x40, 0x3e, 0x66, 0x94, 0xb8, 0x3d, 0x39, 0x71, 0x62, 0x05, 0xf1, 0x2a, 0xd6, 0x8b, + 0xbb, 0xe2, 0x84, 0xca, 0x98, 0x2f, 0xed, 0xff, 0x1b, 0x50, 0x19, 0x4b, 0xf7, 0xf7, 0x6a, 0xcb, + 0x65, 0x58, 0xf0, 0xc9, 0x31, 0x91, 0x33, 0x71, 0x16, 0x4b, 0x80, 0x63, 0xe3, 0x97, 0x21, 0x65, + 0x42, 0xb9, 0x32, 0x96, 0x00, 0xd7, 0xb9, 0x43, 0x98, 0xeb, 0xf9, 0xa2, 0x2e, 0x95, 0xb1, 0x82, + 0xb8, 0xce, 0x7d, 0xea, 0xab, 0x1e, 0x9d, 0x2f, 0x91, 0x0d, 0x39, 0x2f, 0x38, 0x0c, 0x55, 0xd8, + 0x88, 0xce, 0x46, 0xf6, 0x7a, 0x3b, 0xc1, 0x61, 0x88, 0xc5, 0x1e, 0xba, 0x06, 0x79, 0xea, 0x06, + 0x5d, 0x92, 0x34, 0xe8, 0x45, 0x4e, 0x85, 0x39, 0x06, 0xab, 0x0d, 0xdb, 0x86, 0x72, 0x63, 0xc0, + 0x48, 0xfc, 0x94, 0xc4, 0x7c, 0x06, 0xe3, 0x61, 0xdd, 0x71, 0x99, 0x2b, 0xcc, 0x2e, 0x63, 0xb1, + 0xb6, 0x6f, 0x01, 0x7a, 0xe2, 0xc5, 0xec, 0x85, 0x78, 0x95, 0x88, 0xcf, 0x1a, 0x99, 0xf7, 0xe0, + 0xd2, 0x18, 0xb5, 0xba, 0x16, 0x7e, 0x3a, 0x31, 0x34, 0x5f, 0x9f, 0xae, 0xb8, 0xe2, 0xf1, 0xc3, + 0x91, 0x8c, 0x13, 0xb3, 0x73, 0x05, 0x4a, 0xc2, 0x2e, 0xf9, 0x6d, 0xdb, 0x85, 0xb2, 0x04, 0x95, + 0xf0, 0xcf, 0xe0, 0x62, 0x22, 0xe8, 0x73, 0x42, 0xc5, 0x38, 0x63, 0x08, 0xbf, 0xfc, 0x60, 0xd6, + 0x57, 0x1a, 0xe3, 0xe4, 0x78, 0x92, 0xdf, 0x26, 0x70, 0x49, 0xd0, 0x3c, 0xf2, 0x62, 0x16, 0xd2, + 0x41, 0x62, 0xf5, 0x0a, 0xc0, 0x56, 0x9b, 0x79, 0xc7, 0xe4, 0x59, 0xe0, 0xcb, 0x6b, 0xb4, 0x80, + 0x35, 0x4c, 0x72, 0x45, 0x66, 0x46, 0x93, 0xe3, 0x55, 0x28, 0xb6, 0x5c, 0xea, 0x0f, 0x5a, 0x27, + 0x1e, 0x53, 0x03, 0xfc, 0x08, 0x61, 0xff, 0xd1, 0x80, 0x65, 0xfd, 0x3b, 0xad, 0x63, 0x5e, 0x2e, + 0xee, 0x43, 0x8e, 0x25, 0x7d, 0xcc, 0x52, 0x9a, 0x11, 0x53, 0x2c, 0xbc, 0xd5, 0xc1, 0x82, 0x49, + 0xf3, 0xb4, 0x4c, 0x9c, 0xeb, 0xa7, 0xb3, 0x4f, 0x78, 0xfa, 0x9b, 0x22, 0xa0, 0xe9, 0xed, 0x94, + 0x89, 0x58, 0x1f, 0x10, 0x33, 0x13, 0x03, 0xe2, 0x97, 0x93, 0x03, 0xa2, 0xbc, 0x9a, 0xef, 0xce, + 0xa3, 0xc9, 0x1c, 0x63, 0xe2, 0xd8, 0x1c, 0x93, 0x3b, 0xc7, 0x1c, 0x83, 0xd6, 0x93, 0x1b, 0x47, + 0xde, 0x75, 0x28, 0xa9, 0x29, 0x34, 0x6a, 0x3b, 0xaa, 0xaf, 0x50, 0xb7, 0xd0, 0x83, 0xf3, 0xbd, + 0x96, 0xe4, 0x26, 0x5f, 0x4a, 0x1a, 0x50, 0xda, 0x4e, 0x0a, 0xe5, 0x39, 0x9e, 0x4a, 0x74, 0x26, + 0xb4, 0xa1, 0x1a, 0x1b, 0x59, 0x9a, 0xaf, 0x4e, 0x9b, 0x98, 0x3c, 0x8b, 0x84, 0x54, 0x75, 0x36, + 0x87, 0x29, 0xad, 0x65, 0x51, 0x38, 0x68, 0x73, 0x2e, 0xdf, 0xcf, 0xd9, 0x5f, 0xa2, 0x4f, 0x20, + 0x8f, 0x49, 0xdc, 0xf7, 0x99, 0x78, 0x7f, 0x29, 0xd5, 0xaf, 0xcd, 0x90, 0x2e, 0x89, 0x44, 0xae, + 0x2a, 0x06, 0xf4, 0x4b, 0x58, 0x94, 0xab, 0xd8, 0x2c, 0xcd, 0x7a, 0x36, 0x48, 0xd1, 0x4c, 0xf1, + 0xa8, 0x81, 0x42, 0x41, 0x3c, 0x1d, 0x3f, 0x25, 0x01, 0x51, 0x2f, 0x8b, 0x7c, 0x34, 0x5e, 0xc0, + 0x1a, 0x06, 0xd5, 0x61, 0x81, 0x51, 0xb7, 0x4d, 0xcc, 0xca, 0x1c, 0x2e, 0x94, 0xa4, 0xbc, 0xb0, + 0x45, 0x5e, 0x10, 0x90, 0x8e, 0xb9, 0x24, 0x3b, 0x25, 0x09, 0xa1, 0xef, 0xc3, 0x52, 0xd0, 0xef, + 0x89, 0x61, 0xa1, 0xb3, 0xc7, 0x48, 0x14, 0x9b, 0x17, 0xc5, 0xf7, 0x26, 0xb0, 0xe8, 0x3a, 0x54, + 0x82, 0x7e, 0x6f, 0x9f, 0xdf, 0xf0, 0x92, 0xac, 0x2a, 0xc8, 0xc6, 0x91, 0xe8, 0x16, 0x2c, 0x73, + 0xbe, 0xe4, 0xb4, 0x25, 0xe5, 0xb2, 0xa0, 0x9c, 0xde, 0x40, 0x0d, 0xa8, 0x90, 0x13, 0xf9, 0x20, + 0xd0, 0x12, 0xf1, 0x8b, 0xe6, 0xb0, 0x67, 0x9c, 0x05, 0xad, 0x41, 0x29, 0xe8, 0xf7, 0x5e, 0x24, + 0x8d, 0xef, 0x25, 0xf1, 0x2d, 0x1d, 0xf5, 0x1e, 0x26, 0xf3, 0xf7, 0x31, 0x77, 0x58, 0x5f, 0x42, + 0x59, 0x3f, 0xed, 0x14, 0xde, 0xbb, 0xe3, 0x73, 0xfd, 0x1c, 0xd1, 0xa7, 0x8d, 0x35, 0x03, 0xf8, + 0xee, 0xf3, 0xa8, 0xe3, 0x32, 0x92, 0x56, 0xdf, 0xa7, 0xeb, 0xdc, 0x15, 0xc8, 0xef, 0xca, 0x70, + 0x90, 0xaf, 0xb2, 0x0a, 0xe2, 0xf8, 0x26, 0xe1, 0x47, 0xa4, 0x8a, 0xba, 0x82, 0x44, 0x5d, 0xf4, + 0x02, 0xd7, 0x4f, 0x9e, 0x66, 0x0b, 0x78, 0x08, 0xdb, 0x57, 0xc1, 0x4a, 0xfb, 0xb4, 0x74, 0x94, + 0xfd, 0xd7, 0x0c, 0xc0, 0xe8, 0xf8, 0xd0, 0x87, 0x00, 0x3d, 0xd2, 0xf1, 0xdc, 0xdf, 0xb0, 0xd1, + 0x48, 0x5b, 0x14, 0x18, 0x31, 0xd7, 0x8e, 0x86, 0x8f, 0xcc, 0x3b, 0x0f, 0x1f, 0x08, 0x72, 0x31, + 0xd7, 0x57, 0x36, 0x4a, 0x62, 0x8d, 0x9e, 0x41, 0xc9, 0x0d, 0x82, 0x90, 0x89, 0x44, 0x4a, 0xc6, + 0xfd, 0xdb, 0xa7, 0x05, 0x9c, 0xb3, 0x35, 0xa2, 0x97, 0x79, 0xaa, 0x4b, 0xb0, 0x1e, 0x40, 0x75, + 0x92, 0xe0, 0x5c, 0xe3, 0xe8, 0x3f, 0x33, 0x70, 0x71, 0xe2, 0x58, 0xd1, 0x23, 0xa8, 0x4a, 0x68, + 0xe2, 0x89, 0xe6, 0xac, 0xd4, 0x98, 0xe2, 0x42, 0x0f, 0xa1, 0xbc, 0xc5, 0x18, 0xaf, 0xc5, 0xd2, + 0x5e, 0x39, 0x84, 0x9e, 0x2e, 0x65, 0x8c, 0x03, 0x3d, 0x1a, 0x15, 0xb6, 0xec, 0xac, 0xa7, 0x86, + 0x09, 0xfd, 0xd3, 0xab, 0x9a, 0xf5, 0xab, 0xd9, 0x09, 0x90, 0x95, 0x5e, 0xaa, 0x8f, 0x27, 0xc0, + 0x19, 0x75, 0x6d, 0xe4, 0xc3, 0x3f, 0x1b, 0x50, 0x48, 0x12, 0x34, 0xf5, 0xb5, 0xe4, 0xfe, 0xf8, + 0x6b, 0xc9, 0x8d, 0xd9, 0xd7, 0xea, 0xfb, 0x7c, 0x24, 0xb9, 0xf9, 0x73, 0xf8, 0x20, 0xb5, 0xa5, + 0x41, 0x25, 0x58, 0xdc, 0xdb, 0xdf, 0xc2, 0xfb, 0xad, 0x66, 0xf5, 0x02, 0x2a, 0x43, 0x61, 0xfb, + 0xd9, 0xd3, 0xdd, 0x27, 0xad, 0xfd, 0x56, 0xd5, 0xe0, 0x5b, 0xcd, 0x16, 0x5f, 0x37, 0xab, 0x99, + 0xfa, 0x1f, 0xf2, 0xb0, 0xb8, 0x2d, 0xff, 0xdd, 0x43, 0xfb, 0x50, 0x1c, 0xfe, 0x69, 0x83, 0xec, + 0x14, 0xd7, 0x4c, 0xfc, 0xfb, 0x63, 0x7d, 0x74, 0x2a, 0x8d, 0xba, 0xf2, 0x1e, 0xc1, 0x82, 0xf8, + 0x03, 0x0c, 0xa5, 0x3c, 0x4c, 0xe8, 0xff, 0x8c, 0x59, 0xa7, 0xff, 0x1d, 0xb4, 0x61, 0x70, 0x49, + 0xe2, 0x55, 0x27, 0x4d, 0x92, 0xfe, 0x74, 0x6c, 0xad, 0x9e, 0xf1, 0x1c, 0x84, 0x9e, 0x42, 0x5e, + 0x8d, 0xba, 0x69, 0xa4, 0xfa, 0xdb, 0x8d, 0xb5, 0x36, 0x9b, 0x40, 0x0a, 0xdb, 0x30, 0xd0, 0xd3, + 0xe1, 0xbf, 0x01, 0x69, 0xaa, 0xe9, 0x73, 0x82, 0x75, 0xc6, 0xfe, 0xba, 0xb1, 0x61, 0xa0, 0x2f, + 0xa0, 0xa4, 0x4d, 0x02, 0x28, 0xa5, 0x0f, 0x9d, 0x1e, 0x2b, 0xac, 0x1b, 0x67, 0x50, 0x29, 0xcb, + 0x5b, 0x90, 0x13, 0x05, 0x20, 0xc5, 0xd9, 0xda, 0xa0, 0x90, 0xa6, 0xe6, 0xd8, 0xe0, 0x70, 0x20, + 0x47, 0x1b, 0x12, 0xe8, 0xd1, 0x87, 0x6e, 0x9c, 0xd5, 0x91, 0xcc, 0x0c, 0x9b, 0xa9, 0x20, 0xde, + 0x30, 0x50, 0x08, 0x68, 0xba, 0xe8, 0xa3, 0x1f, 0xa6, 0x44, 0xc9, 0xac, 0x5b, 0xc9, 0xba, 0x35, + 0x1f, 0xb1, 0x34, 0xaa, 0x51, 0x7e, 0xf5, 0x66, 0xc5, 0xf8, 0xf7, 0x9b, 0x15, 0xe3, 0x3f, 0x6f, + 0x56, 0x8c, 0x83, 0xbc, 0xe8, 0x35, 0x7f, 0xf4, 0x6d, 0x00, 0x00, 0x00, 0xff, 0xff, 0x40, 0x05, + 0x0e, 0x94, 0xfd, 0x1e, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2690,8 +2707,18 @@ func (m *PruneRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - if m.KeepBytes != 0 { - i = encodeVarintControl(dAtA, i, uint64(m.KeepBytes)) + if m.Free != 0 { + i = encodeVarintControl(dAtA, i, uint64(m.Free)) + i-- + dAtA[i] = 0x30 + } + if m.MinStorage != 0 { + i = encodeVarintControl(dAtA, i, uint64(m.MinStorage)) + i-- + dAtA[i] = 0x28 + } + if m.MaxStorage != 0 { + i = encodeVarintControl(dAtA, i, uint64(m.MaxStorage)) i-- dAtA[i] = 0x20 } @@ -4572,8 +4599,14 @@ func (m *PruneRequest) Size() (n int) { if m.KeepDuration != 0 { n += 1 + sovControl(uint64(m.KeepDuration)) } - if m.KeepBytes != 0 { - n += 1 + sovControl(uint64(m.KeepBytes)) + if m.MaxStorage != 0 { + n += 1 + sovControl(uint64(m.MaxStorage)) + } + if m.MinStorage != 0 { + n += 1 + sovControl(uint64(m.MinStorage)) + } + if m.Free != 0 { + n += 1 + sovControl(uint64(m.Free)) } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) @@ -5502,9 +5535,47 @@ func (m *PruneRequest) Unmarshal(dAtA []byte) error { } case 4: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field KeepBytes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MaxStorage", wireType) + } + m.MaxStorage = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowControl + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxStorage |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinStorage", wireType) + } + m.MinStorage = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowControl + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinStorage |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Free", wireType) } - m.KeepBytes = 0 + m.Free = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowControl @@ -5514,7 +5585,7 @@ func (m *PruneRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.KeepBytes |= int64(b&0x7F) << shift + m.Free |= int64(b&0x7F) << shift if b < 0x80 { break } diff --git a/api/services/control/control.proto b/api/services/control/control.proto index 60a4aabc3ea3..d148b768ed69 100644 --- a/api/services/control/control.proto +++ b/api/services/control/control.proto @@ -31,7 +31,10 @@ message PruneRequest { repeated string filter = 1; bool all = 2; int64 keepDuration = 3 [(gogoproto.nullable) = true]; - int64 keepBytes = 4 [(gogoproto.nullable) = true]; + + int64 minStorage = 5 [(gogoproto.nullable) = true]; + int64 maxStorage = 4 [(gogoproto.nullable) = true]; + int64 free = 6 [(gogoproto.nullable) = true]; } message DiskUsageRequest { diff --git a/api/types/worker.pb.go b/api/types/worker.pb.go index e1b3928cba52..2ad6f16d436f 100644 --- a/api/types/worker.pb.go +++ b/api/types/worker.pb.go @@ -104,10 +104,13 @@ func (m *WorkerRecord) GetBuildkitVersion() *BuildkitVersion { } type GCPolicy struct { - All bool `protobuf:"varint,1,opt,name=all,proto3" json:"all,omitempty"` - KeepDuration int64 `protobuf:"varint,2,opt,name=keepDuration,proto3" json:"keepDuration,omitempty"` - KeepBytes int64 `protobuf:"varint,3,opt,name=keepBytes,proto3" json:"keepBytes,omitempty"` - Filters []string `protobuf:"bytes,4,rep,name=filters,proto3" json:"filters,omitempty"` + All bool `protobuf:"varint,1,opt,name=all,proto3" json:"all,omitempty"` + KeepDuration int64 `protobuf:"varint,2,opt,name=keepDuration,proto3" json:"keepDuration,omitempty"` + Filters []string `protobuf:"bytes,4,rep,name=filters,proto3" json:"filters,omitempty"` + MinStorage int64 `protobuf:"varint,5,opt,name=minStorage,proto3" json:"minStorage,omitempty"` + // maxStorage was renamed from freeBytes + MaxStorage int64 `protobuf:"varint,3,opt,name=maxStorage,proto3" json:"maxStorage,omitempty"` + Free int64 `protobuf:"varint,6,opt,name=free,proto3" json:"free,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -160,18 +163,32 @@ func (m *GCPolicy) GetKeepDuration() int64 { return 0 } -func (m *GCPolicy) GetKeepBytes() int64 { +func (m *GCPolicy) GetFilters() []string { + if m != nil { + return m.Filters + } + return nil +} + +func (m *GCPolicy) GetMinStorage() int64 { if m != nil { - return m.KeepBytes + return m.MinStorage } return 0 } -func (m *GCPolicy) GetFilters() []string { +func (m *GCPolicy) GetMaxStorage() int64 { if m != nil { - return m.Filters + return m.MaxStorage } - return nil + return 0 +} + +func (m *GCPolicy) GetFree() int64 { + if m != nil { + return m.Free + } + return 0 } type BuildkitVersion struct { @@ -247,33 +264,35 @@ func init() { func init() { proto.RegisterFile("worker.proto", fileDescriptor_e4ff6184b07e587a) } var fileDescriptor_e4ff6184b07e587a = []byte{ - // 416 bytes of a gzipped FileDescriptorProto + // 443 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0xc1, 0x8e, 0xd3, 0x30, - 0x10, 0x25, 0xc9, 0xee, 0xd2, 0xb8, 0x11, 0x20, 0x0b, 0xa1, 0x28, 0x42, 0x25, 0xca, 0x85, 0x1e, - 0xc0, 0x59, 0x96, 0x0b, 0x20, 0x4e, 0xa1, 0x08, 0x56, 0xe2, 0xb0, 0xf8, 0x00, 0x67, 0x3b, 0xeb, - 0x86, 0x28, 0xee, 0xda, 0x72, 0x9c, 0x40, 0xfe, 0xb0, 0x47, 0xbe, 0x00, 0xa1, 0x1e, 0xf8, 0x0e, - 0x64, 0x27, 0x69, 0x4b, 0xd9, 0xde, 0xe6, 0xcd, 0xbc, 0xf7, 0x3c, 0xf3, 0x64, 0x10, 0x7c, 0x17, - 0xaa, 0x62, 0x0a, 0x49, 0x25, 0xb4, 0x80, 0x8f, 0x56, 0x82, 0x76, 0x88, 0x36, 0x25, 0xbf, 0xae, - 0x4a, 0x8d, 0xda, 0x17, 0x48, 0x77, 0x92, 0xd5, 0xd1, 0xf3, 0xa2, 0xd4, 0xdf, 0x1a, 0x8a, 0x72, - 0xb1, 0x4a, 0x0b, 0x51, 0x88, 0xd4, 0xd2, 0x69, 0xb3, 0xb4, 0xc8, 0x02, 0x5b, 0xf5, 0x36, 0xd1, - 0xb3, 0x3d, 0xba, 0x71, 0x4c, 0x47, 0xc7, 0xb4, 0x16, 0xbc, 0x65, 0x2a, 0x95, 0x34, 0x15, 0xb2, - 0xee, 0xd9, 0xc9, 0x1f, 0x17, 0x04, 0x5f, 0xed, 0x16, 0x98, 0xe5, 0x42, 0x5d, 0xc3, 0x7b, 0xc0, - 0xbd, 0x5c, 0x84, 0x4e, 0xec, 0xcc, 0x7d, 0xec, 0x5e, 0x2e, 0xe0, 0x47, 0x70, 0xf6, 0x89, 0x50, - 0xc6, 0xeb, 0xd0, 0x8d, 0xbd, 0xf9, 0xf4, 0xe2, 0x1c, 0xdd, 0xbe, 0x26, 0xda, 0x77, 0x41, 0xbd, - 0xe4, 0xfd, 0x8d, 0x56, 0x1d, 0x1e, 0xf4, 0xf0, 0x1c, 0xf8, 0x92, 0x13, 0xbd, 0x14, 0x6a, 0x55, - 0x87, 0x9e, 0x35, 0x0b, 0x90, 0xa4, 0xe8, 0x6a, 0x68, 0x66, 0x27, 0xeb, 0x5f, 0x4f, 0xee, 0xe0, - 0x1d, 0x09, 0xbe, 0x05, 0x93, 0x0f, 0xef, 0xae, 0x04, 0x2f, 0xf3, 0x2e, 0x3c, 0xb1, 0x82, 0xf8, - 0xd8, 0xeb, 0x23, 0x0f, 0x6f, 0x15, 0xf0, 0x33, 0xb8, 0x9f, 0x0d, 0xbc, 0x2f, 0x4c, 0xd5, 0xa5, - 0xb8, 0x09, 0x4f, 0x63, 0x67, 0x3e, 0xbd, 0x78, 0x7a, 0xcc, 0xe4, 0x80, 0x8e, 0x0f, 0xf5, 0xd1, - 0x6b, 0x30, 0xdd, 0xbb, 0x0c, 0x3e, 0x00, 0x5e, 0xc5, 0xba, 0x21, 0x2c, 0x53, 0xc2, 0x87, 0xe0, - 0xb4, 0x25, 0xbc, 0x61, 0xa1, 0x6b, 0x7b, 0x3d, 0x78, 0xe3, 0xbe, 0x72, 0x92, 0x1f, 0xbb, 0x5b, - 0x8c, 0x8e, 0x70, 0x6e, 0x75, 0x13, 0x6c, 0x4a, 0x98, 0x80, 0xa0, 0x62, 0x4c, 0x2e, 0x1a, 0x45, - 0xb4, 0x59, 0xd4, 0xc8, 0x3d, 0xfc, 0x4f, 0x0f, 0x3e, 0x06, 0xbe, 0xc1, 0x59, 0xa7, 0x99, 0xc9, - 0xcf, 0x10, 0x76, 0x0d, 0x18, 0x82, 0xbb, 0xcb, 0x92, 0x6b, 0xa6, 0x6a, 0x1b, 0x95, 0x8f, 0x47, - 0x98, 0x90, 0xff, 0x72, 0x30, 0x64, 0x49, 0xf2, 0x8a, 0x14, 0x6c, 0x58, 0x7e, 0x84, 0x66, 0xd2, - 0x0e, 0x61, 0xf5, 0x27, 0x8c, 0x10, 0x46, 0x60, 0xa2, 0x58, 0x5b, 0xda, 0x91, 0x67, 0x47, 0x5b, - 0x9c, 0x05, 0xeb, 0xcd, 0xcc, 0xf9, 0xb9, 0x99, 0x39, 0xbf, 0x37, 0x33, 0x87, 0x9e, 0xd9, 0xaf, - 0xf5, 0xf2, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x19, 0xcf, 0xd5, 0xdf, 0x02, 0x00, 0x00, + 0x14, 0xc4, 0x49, 0xb7, 0xb4, 0x6e, 0x04, 0xc8, 0x42, 0xc8, 0xea, 0xa1, 0x54, 0x15, 0x12, 0x3d, + 0x80, 0xb3, 0x2c, 0x17, 0x40, 0x9c, 0x4a, 0x11, 0xac, 0xc4, 0x61, 0x31, 0x12, 0x9c, 0x9d, 0xae, + 0x5b, 0xa2, 0xb8, 0xb5, 0xe5, 0x38, 0x81, 0xfc, 0x1d, 0xc7, 0x3d, 0xf2, 0x05, 0x08, 0xf5, 0xc0, + 0x77, 0x20, 0xbf, 0x24, 0xdd, 0xec, 0xc2, 0xde, 0x3c, 0xf3, 0x66, 0x26, 0xef, 0x8d, 0x82, 0xa3, + 0x6f, 0xda, 0x66, 0xd2, 0x32, 0x63, 0xb5, 0xd3, 0xe4, 0xc1, 0x56, 0x27, 0x15, 0x4b, 0x8a, 0x54, + 0x9d, 0x67, 0xa9, 0x63, 0xe5, 0x33, 0xe6, 0x2a, 0x23, 0xf3, 0xf1, 0xd3, 0x4d, 0xea, 0xbe, 0x16, + 0x09, 0x5b, 0xe9, 0x6d, 0xbc, 0xd1, 0x1b, 0x1d, 0x83, 0x3c, 0x29, 0xd6, 0x80, 0x00, 0xc0, 0xab, + 0x8e, 0x19, 0x3f, 0xe9, 0xc8, 0x7d, 0x62, 0xdc, 0x26, 0xc6, 0xb9, 0x56, 0xa5, 0xb4, 0xb1, 0x49, + 0x62, 0x6d, 0xf2, 0x5a, 0x3d, 0xfb, 0x13, 0xe0, 0xe8, 0x0b, 0x6c, 0xc1, 0xe5, 0x4a, 0xdb, 0x73, + 0x72, 0x07, 0x07, 0xa7, 0x4b, 0x8a, 0xa6, 0x68, 0x3e, 0xe4, 0xc1, 0xe9, 0x92, 0xbc, 0xc7, 0xfd, + 0x0f, 0x22, 0x91, 0x2a, 0xa7, 0xc1, 0x34, 0x9c, 0x8f, 0x4e, 0x8e, 0xd9, 0xff, 0xd7, 0x64, 0xdd, + 0x14, 0x56, 0x5b, 0xde, 0xee, 0x9c, 0xad, 0x78, 0xe3, 0x27, 0xc7, 0x78, 0x68, 0x94, 0x70, 0x6b, + 0x6d, 0xb7, 0x39, 0x0d, 0x21, 0x2c, 0x62, 0x26, 0x61, 0x67, 0x0d, 0xb9, 0xe8, 0x5d, 0xfc, 0x7a, + 0x78, 0x8b, 0x5f, 0x8a, 0xc8, 0x6b, 0x3c, 0x78, 0xf7, 0xe6, 0x4c, 0xab, 0x74, 0x55, 0xd1, 0x1e, + 0x18, 0xa6, 0x37, 0x7d, 0xbd, 0xd5, 0xf1, 0x83, 0x83, 0x7c, 0xc4, 0x77, 0x17, 0x8d, 0xee, 0xb3, + 0xb4, 0x79, 0xaa, 0x77, 0xf4, 0x68, 0x8a, 0xe6, 0xa3, 0x93, 0xc7, 0x37, 0x85, 0x5c, 0x93, 0xf3, + 0xeb, 0xfe, 0xf1, 0x4b, 0x3c, 0xea, 0x5c, 0x46, 0xee, 0xe1, 0x30, 0x93, 0x55, 0x53, 0x96, 0x7f, + 0x92, 0xfb, 0xf8, 0xa8, 0x14, 0xaa, 0x90, 0x34, 0x00, 0xae, 0x06, 0xaf, 0x82, 0x17, 0x68, 0xf6, + 0x03, 0x5d, 0x1e, 0xe3, 0x8d, 0x42, 0x29, 0x30, 0x0e, 0xb8, 0x7f, 0x92, 0x19, 0x8e, 0x32, 0x29, + 0xcd, 0xb2, 0xb0, 0xc2, 0xf9, 0x4d, 0xbd, 0x3f, 0xe4, 0x57, 0x38, 0x42, 0xf1, 0xed, 0x75, 0xaa, + 0x9c, 0xb4, 0x39, 0xb4, 0x31, 0xe4, 0x2d, 0x24, 0x8f, 0x30, 0xde, 0xa6, 0xbb, 0x4f, 0x4e, 0x5b, + 0xb1, 0x91, 0x70, 0x65, 0x08, 0x6d, 0x22, 0xde, 0xe1, 0x41, 0x25, 0xbe, 0xb7, 0xaa, 0xf0, 0x8a, + 0xea, 0xc0, 0x13, 0x8a, 0x7b, 0x6b, 0x2b, 0x25, 0xed, 0x77, 0xe6, 0xc0, 0xcc, 0xc4, 0x3f, 0x85, + 0xfa, 0x95, 0x8c, 0x58, 0x65, 0x3e, 0xaf, 0x6e, 0xa1, 0x85, 0x7e, 0x52, 0x36, 0xad, 0xd7, 0x5d, + 0xb4, 0x90, 0x8c, 0xf1, 0xc0, 0xca, 0x32, 0x85, 0x51, 0x08, 0xa3, 0x03, 0x5e, 0x44, 0x17, 0xfb, + 0x09, 0xfa, 0xb9, 0x9f, 0xa0, 0xdf, 0xfb, 0x09, 0x4a, 0xfa, 0xf0, 0x8f, 0x3e, 0xff, 0x1b, 0x00, + 0x00, 0xff, 0xff, 0xc0, 0xdf, 0xd3, 0xae, 0x28, 0x03, 0x00, 0x00, } func (m *WorkerRecord) Marshal() (dAtA []byte, err error) { @@ -393,6 +412,16 @@ func (m *GCPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.Free != 0 { + i = encodeVarintWorker(dAtA, i, uint64(m.Free)) + i-- + dAtA[i] = 0x30 + } + if m.MinStorage != 0 { + i = encodeVarintWorker(dAtA, i, uint64(m.MinStorage)) + i-- + dAtA[i] = 0x28 + } if len(m.Filters) > 0 { for iNdEx := len(m.Filters) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Filters[iNdEx]) @@ -402,8 +431,8 @@ func (m *GCPolicy) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x22 } } - if m.KeepBytes != 0 { - i = encodeVarintWorker(dAtA, i, uint64(m.KeepBytes)) + if m.MaxStorage != 0 { + i = encodeVarintWorker(dAtA, i, uint64(m.MaxStorage)) i-- dAtA[i] = 0x18 } @@ -536,8 +565,8 @@ func (m *GCPolicy) Size() (n int) { if m.KeepDuration != 0 { n += 1 + sovWorker(uint64(m.KeepDuration)) } - if m.KeepBytes != 0 { - n += 1 + sovWorker(uint64(m.KeepBytes)) + if m.MaxStorage != 0 { + n += 1 + sovWorker(uint64(m.MaxStorage)) } if len(m.Filters) > 0 { for _, s := range m.Filters { @@ -545,6 +574,12 @@ func (m *GCPolicy) Size() (n int) { n += 1 + l + sovWorker(uint64(l)) } } + if m.MinStorage != 0 { + n += 1 + sovWorker(uint64(m.MinStorage)) + } + if m.Free != 0 { + n += 1 + sovWorker(uint64(m.Free)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -965,9 +1000,9 @@ func (m *GCPolicy) Unmarshal(dAtA []byte) error { } case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field KeepBytes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MaxStorage", wireType) } - m.KeepBytes = 0 + m.MaxStorage = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowWorker @@ -977,7 +1012,7 @@ func (m *GCPolicy) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.KeepBytes |= int64(b&0x7F) << shift + m.MaxStorage |= int64(b&0x7F) << shift if b < 0x80 { break } @@ -1014,6 +1049,44 @@ func (m *GCPolicy) Unmarshal(dAtA []byte) error { } m.Filters = append(m.Filters, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinStorage", wireType) + } + m.MinStorage = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWorker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinStorage |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Free", wireType) + } + m.Free = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWorker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Free |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipWorker(dAtA[iNdEx:]) diff --git a/api/types/worker.proto b/api/types/worker.proto index 476fcc62e104..d277dde84908 100644 --- a/api/types/worker.proto +++ b/api/types/worker.proto @@ -20,8 +20,12 @@ message WorkerRecord { message GCPolicy { bool all = 1; int64 keepDuration = 2; - int64 keepBytes = 3; repeated string filters = 4; + + int64 minStorage = 5 [(gogoproto.nullable) = true]; + // maxStorage was renamed from freeBytes + int64 maxStorage = 3 [(gogoproto.nullable) = true]; + int64 free = 6 [(gogoproto.nullable) = true]; } message BuildkitVersion { diff --git a/cache/manager.go b/cache/manager.go index 1c35de8a04d4..266b4eddd753 100644 --- a/cache/manager.go +++ b/cache/manager.go @@ -22,6 +22,7 @@ import ( "github.com/moby/buildkit/session" "github.com/moby/buildkit/snapshot" "github.com/moby/buildkit/util/bklog" + "github.com/moby/buildkit/util/disk" "github.com/moby/buildkit/util/flightcontrol" "github.com/moby/buildkit/util/progress" digest "github.com/opencontainers/go-digest" @@ -1040,7 +1041,7 @@ func (cm *cacheManager) pruneOnce(ctx context.Context, ch chan client.UsageInfo, } totalSize := int64(0) - if opt.KeepBytes != 0 { + if opt.MaxStorage != 0 { du, err := cm.DiskUsage(ctx, client.DiskUsageInfo{}) if err != nil { return err @@ -1053,27 +1054,62 @@ func (cm *cacheManager) pruneOnce(ctx context.Context, ch chan client.UsageInfo, } } + // TODO: pick a better path here + dstat, err := disk.GetDiskStat(cm.mountPool.tmpdirRoot) + if err != nil { + if opt.Free != 0 { + // if we are pruning based on disk space, failing to get info on it + // is fatal + return err + } + bklog.L.Warnf("failed to get disk size: %v", err) + } + return cm.prune(ctx, ch, pruneOpt{ filter: filter, all: opt.All, checkShared: check, keepDuration: opt.KeepDuration, - keepBytes: opt.KeepBytes, + keepBytes: calculateKeepBytes(totalSize, dstat, opt), totalSize: totalSize, }) } -func (cm *cacheManager) prune(ctx context.Context, ch chan client.UsageInfo, opt pruneOpt) (err error) { - var toDelete []*deleteRecord +func calculateKeepBytes(totalSize int64, dstat disk.DiskStat, opt client.PruneInfo) int64 { + // 0 values are special, and means we have no keep cap + if opt.MaxStorage == 0 && opt.MinStorage == 0 && opt.Free == 0 { + return 0 + } + + // try and keep as many bytes as we can + keepBytes := opt.MaxStorage + + // if we need to free up space, then decrease to that + if excess := opt.Free - dstat.Free; excess > 0 { + if keepBytes == 0 { + keepBytes = totalSize - excess + } else { + keepBytes = min(keepBytes, totalSize-excess) + } + } + + // but make sure we don't take the total below the minimum + keepBytes = max(keepBytes, opt.MinStorage) + return keepBytes +} + +func (cm *cacheManager) prune(ctx context.Context, ch chan client.UsageInfo, opt pruneOpt) (err error) { if opt.keepBytes != 0 && opt.totalSize < opt.keepBytes { return nil } + var toDelete []*deleteRecord + cm.mu.Lock() - gcMode := opt.keepBytes != 0 cutOff := time.Now().Add(-opt.keepDuration) + gcMode := opt.keepBytes != 0 locked := map[*sync.Mutex]struct{}{} @@ -1610,8 +1646,9 @@ type pruneOpt struct { all bool checkShared ExternalRefChecker keepDuration time.Duration - keepBytes int64 - totalSize int64 + + keepBytes int64 + totalSize int64 } type deleteRecord struct { diff --git a/cache/manager_test.go b/cache/manager_test.go index b6b851ff3446..2a9ee9877935 100644 --- a/cache/manager_test.go +++ b/cache/manager_test.go @@ -45,6 +45,7 @@ import ( "github.com/moby/buildkit/util/compression" "github.com/moby/buildkit/util/contentutil" "github.com/moby/buildkit/util/converter" + "github.com/moby/buildkit/util/disk" "github.com/moby/buildkit/util/iohelper" "github.com/moby/buildkit/util/leaseutil" "github.com/moby/buildkit/util/overlay" @@ -2452,6 +2453,134 @@ func TestLoadBrokenParents(t *testing.T) { require.Len(t, refA.(*immutableRef).refs, 1) } +func TestCalculateKeepBytes(t *testing.T) { + ts := []struct { + name string + totalSize int64 + stat disk.DiskStat + opt client.PruneInfo + result int64 + }{ + { + name: "empty", + totalSize: 1000, + stat: disk.DiskStat{ + Total: 10000, + Free: 9000, + }, + opt: client.PruneInfo{}, + result: 0, + }, + { + name: "only buildkit max", + totalSize: 1000, + stat: disk.DiskStat{ + Total: 10000, + Free: 9000, + }, + opt: client.PruneInfo{ + MaxStorage: 2000, // 20% of the disk + }, + result: 2000, + }, + { + name: "only buildkit free", + totalSize: 7000, + stat: disk.DiskStat{ + Total: 10000, + Free: 3000, + }, + opt: client.PruneInfo{ + Free: 5000, // 50% of the disk + }, + result: 5000, + }, + { + name: "only buildkit free with min", + totalSize: 7000, + stat: disk.DiskStat{ + Total: 10000, + Free: 3000, + }, + opt: client.PruneInfo{ + Free: 5000, // 50% of the disk + MinStorage: 6000, // 60% of the disk, + }, + result: 6000, + }, + { + name: "only buildkit free all", + totalSize: 7000, + stat: disk.DiskStat{ + Total: 10000, + Free: 3000, + }, + opt: client.PruneInfo{ + Free: 5000, // 50% of the disk + MinStorage: 2000, // 20% of the disk + MaxStorage: 4000, // 40% of the disk + }, + result: 4000, + }, + { + name: "mixed max", + totalSize: 4000, + stat: disk.DiskStat{ + Total: 10000, + Free: 2000, // something else is using 4000 + }, + opt: client.PruneInfo{ + MaxStorage: 2000, // 20% of the disk + }, + result: 2000, + }, + { + name: "mixed free", + totalSize: 4000, + stat: disk.DiskStat{ + Total: 10000, + Free: 2000, // something else is using 4000 + }, + opt: client.PruneInfo{ + Free: 5000, // 50% of the disk + }, + result: 1000, + }, + { + name: "mixed free with min", + totalSize: 4000, + stat: disk.DiskStat{ + Total: 10000, + Free: 2000, // something else is using 4000 + }, + opt: client.PruneInfo{ + Free: 5000, // 50% of the disk + MinStorage: 2000, // 20% of the disk + }, + result: 2000, + }, + { + name: "mixed free all", + totalSize: 4000, + stat: disk.DiskStat{ + Total: 10000, + Free: 2000, // something else is using 4000 + }, + opt: client.PruneInfo{ + Free: 5000, // 50% of the disk + MinStorage: 2000, // 20% of the disk + MaxStorage: 4000, // 40% of the disk + }, + result: 2000, + }, + } + for _, tc := range ts { + t.Run(tc.name, func(t *testing.T) { + require.Equal(t, tc.result, calculateKeepBytes(tc.totalSize, tc.stat, tc.opt)) + }) + } +} + func checkDiskUsage(ctx context.Context, t *testing.T, cm Manager, inuse, unused int) { du, err := cm.DiskUsage(ctx, client.DiskUsageInfo{}) require.NoError(t, err) diff --git a/client/prune.go b/client/prune.go index af8491385558..eb547c72c397 100644 --- a/client/prune.go +++ b/client/prune.go @@ -18,7 +18,9 @@ func (c *Client) Prune(ctx context.Context, ch chan UsageInfo, opts ...PruneOpti req := &controlapi.PruneRequest{ Filter: info.Filter, KeepDuration: int64(info.KeepDuration), - KeepBytes: int64(info.KeepBytes), + MinStorage: int64(info.MinStorage), + MaxStorage: int64(info.MaxStorage), + Free: int64(info.Free), } if info.All { req.All = true @@ -59,10 +61,13 @@ type PruneOption interface { } type PruneInfo struct { - Filter []string `json:"filter"` All bool `json:"all"` + Filter []string `json:"filter"` KeepDuration time.Duration `json:"keepDuration"` - KeepBytes int64 `json:"keepBytes"` + + MinStorage int64 `json:"minStorage"` + MaxStorage int64 `json:"maxStorage"` + Free int64 `json:"free"` } type pruneOptionFunc func(*PruneInfo) @@ -75,9 +80,11 @@ var PruneAll = pruneOptionFunc(func(pi *PruneInfo) { pi.All = true }) -func WithKeepOpt(duration time.Duration, bytes int64) PruneOption { +func WithKeepOpt(duration time.Duration, minStorage int64, maxStorage int64, free int64) PruneOption { return pruneOptionFunc(func(pi *PruneInfo) { pi.KeepDuration = duration - pi.KeepBytes = bytes + pi.MinStorage = minStorage + pi.MaxStorage = maxStorage + pi.Free = free }) } diff --git a/client/workers.go b/client/workers.go index b7f6f6725d90..13d68925704b 100644 --- a/client/workers.go +++ b/client/workers.go @@ -65,7 +65,9 @@ func fromAPIGCPolicy(in []*apitypes.GCPolicy) []PruneInfo { All: p.All, Filter: p.Filters, KeepDuration: time.Duration(p.KeepDuration), - KeepBytes: p.KeepBytes, + MinStorage: p.MinStorage, + MaxStorage: p.MaxStorage, + Free: p.Free, }) } return out diff --git a/cmd/buildctl/debug/workers.go b/cmd/buildctl/debug/workers.go index e6be6cee3115..6e88f4522b35 100644 --- a/cmd/buildctl/debug/workers.go +++ b/cmd/buildctl/debug/workers.go @@ -91,8 +91,14 @@ func printWorkersVerbose(tw *tabwriter.Writer, winfo []*client.WorkerInfo) { if rule.KeepDuration > 0 { fmt.Fprintf(tw, "\tKeep Duration:\t%v\n", rule.KeepDuration.String()) } - if rule.KeepBytes > 0 { - fmt.Fprintf(tw, "\tKeep Bytes:\t%g\n", units.Bytes(rule.KeepBytes)) + if rule.MaxStorage > 0 { + fmt.Fprintf(tw, "\tKeep Bytes:\t%g\n", units.Bytes(rule.MaxStorage)) + } + if rule.MinStorage > 0 { + fmt.Fprintf(tw, "\tKeep Bytes (min):\t%g\n", units.Bytes(rule.MinStorage)) + } + if rule.Free > 0 { + fmt.Fprintf(tw, "\tFree Bytes:\t%g\n", units.Bytes(rule.MinStorage)) } } fmt.Fprintf(tw, "\n") diff --git a/cmd/buildctl/prune.go b/cmd/buildctl/prune.go index 25aa27c55c7f..bdbfd1c5c8e3 100644 --- a/cmd/buildctl/prune.go +++ b/cmd/buildctl/prune.go @@ -25,6 +25,14 @@ var pruneCommand = cli.Command{ Name: "keep-storage", Usage: "Keep data below this limit (in MB)", }, + cli.Float64Flag{ + Name: "keep-storage-min", + Usage: "Always allow data above this limit (in MB)", + }, + cli.Float64Flag{ + Name: "free-storage", + Usage: "Keep free data below this limit (in MB)", + }, cli.StringSliceFlag{ Name: "filter, f", Usage: "Filter records", @@ -56,7 +64,12 @@ func prune(clicontext *cli.Context) error { opts := []client.PruneOption{ client.WithFilter(clicontext.StringSlice("filter")), - client.WithKeepOpt(clicontext.Duration("keep-duration"), int64(clicontext.Float64("keep-storage")*1e6)), + client.WithKeepOpt( + clicontext.Duration("keep-duration"), + int64(clicontext.Float64("keep-storage-min")*1e6), + int64(clicontext.Float64("keep-storage")*1e6), + int64(clicontext.Float64("free-storage")*1e6), + ), } if clicontext.Bool("all") { diff --git a/cmd/buildkitd/config/config.go b/cmd/buildkitd/config/config.go index 32eaa7bd615b..76bc9a4207c0 100644 --- a/cmd/buildkitd/config/config.go +++ b/cmd/buildkitd/config/config.go @@ -154,10 +154,29 @@ type ContainerdRuntime struct { } type GCPolicy struct { - All bool `toml:"all"` - KeepBytes DiskSpace `toml:"keepBytes"` - KeepDuration Duration `toml:"keepDuration"` - Filters []string `toml:"filters"` + All bool `toml:"all"` + Filters []string `toml:"filters"` + + KeepDuration Duration `toml:"keepDuration"` + + // KeepBytes is the maximum amount of storage this policy is ever allowed + // to consume. Any storage above this mark can be cleared during a gc + // sweep. + // + // Deprecated: use MaxStorage instead + KeepBytes DiskSpace `toml:"keepBytes"` + + // MinStorage is the minimum amount of storage this policy is always + // allowed to consume. Any amount of storage below this mark will not be + // cleared by this policy. + MinStorage DiskSpace `toml:"minStorage"` + // MaxStorage is the maximum amount of storage this policy is ever allowed + // to consume. Any storage above this mark can be cleared during a gc + // sweep. + MaxStorage DiskSpace `toml:"maxStorage"` + // Free is the amount of storage the gc will attempt to leave free on the + // disk. However, it will never attempt to bring it below MinStorage. + Free DiskSpace `toml:"free"` } type DNSConfig struct { diff --git a/cmd/buildkitd/config/gcpolicy.go b/cmd/buildkitd/config/gcpolicy.go index 5e9ac6ac5c02..b9c34c7b0ca4 100644 --- a/cmd/buildkitd/config/gcpolicy.go +++ b/cmd/buildkitd/config/gcpolicy.go @@ -8,6 +8,7 @@ import ( "github.com/docker/go-units" "github.com/moby/buildkit/util/bklog" + "github.com/moby/buildkit/util/disk" "github.com/pkg/errors" ) @@ -77,21 +78,21 @@ func DefaultGCPolicy(keep DiskSpace) []GCPolicy { { Filters: []string{"type==source.local,type==exec.cachemount,type==source.git.checkout"}, KeepDuration: Duration{Duration: time.Duration(48) * time.Hour}, // 48h - KeepBytes: DiskSpace{Bytes: 512 * 1e6}, // 512MB + MaxStorage: DiskSpace{Bytes: 512 * 1e6}, // 512MB }, // remove any data not used for 60 days { KeepDuration: Duration{Duration: time.Duration(60) * 24 * time.Hour}, // 60d - KeepBytes: keep, + MaxStorage: keep, }, // keep the unshared build cache under cap { - KeepBytes: keep, + MaxStorage: keep, }, // if previous policies were insufficient start deleting internal data to keep build cache under cap { - All: true, - KeepBytes: keep, + All: true, + MaxStorage: keep, }, } } @@ -118,12 +119,12 @@ func (d DiskSpace) AsBytes(root string) int64 { return 0 } - diskSize, err := getDiskSize(root) + dstat, err := disk.GetDiskStat(root) if err != nil { bklog.L.Warnf("failed to get disk size: %v", err) return defaultCap } - avail := diskSize * d.Percentage / 100 + avail := dstat.Total * d.Percentage / 100 rounded := (avail/(1<<30) + 1) * 1e9 // round up return rounded } diff --git a/cmd/buildkitd/config/gcpolicy_openbsd.go b/cmd/buildkitd/config/gcpolicy_openbsd.go deleted file mode 100644 index 341ac2cd7c88..000000000000 --- a/cmd/buildkitd/config/gcpolicy_openbsd.go +++ /dev/null @@ -1,19 +0,0 @@ -//go:build openbsd -// +build openbsd - -package config - -import ( - "syscall" -) - -var DiskSpacePercentage int64 = 10 - -func getDiskSize(root string) (int64, error) { - var st syscall.Statfs_t - if err := syscall.Statfs(root, &st); err != nil { - return 0, err - } - diskSize := int64(st.F_bsize) * int64(st.F_blocks) - return diskSize, nil -} diff --git a/cmd/buildkitd/config/gcpolicy_unix.go b/cmd/buildkitd/config/gcpolicy_unix.go index b88e2172fff1..f033e65be927 100644 --- a/cmd/buildkitd/config/gcpolicy_unix.go +++ b/cmd/buildkitd/config/gcpolicy_unix.go @@ -1,19 +1,6 @@ -//go:build !windows && !openbsd -// +build !windows,!openbsd +//go:build !windows +// +build !windows package config -import ( - "syscall" -) - var DiskSpacePercentage int64 = 10 - -func getDiskSize(root string) (int64, error) { - var st syscall.Statfs_t - if err := syscall.Statfs(root, &st); err != nil { - return 0, err - } - diskSize := int64(st.Bsize) * int64(st.Blocks) - return diskSize, nil -} diff --git a/cmd/buildkitd/config/gcpolicy_windows.go b/cmd/buildkitd/config/gcpolicy_windows.go index 77c7099de5f8..ec5900e48522 100644 --- a/cmd/buildkitd/config/gcpolicy_windows.go +++ b/cmd/buildkitd/config/gcpolicy_windows.go @@ -3,29 +3,6 @@ package config -import ( - "golang.org/x/sys/windows" -) - // set as double that for Linux since // Windows images are generally larger. var DiskSpacePercentage int64 = 20 - -func getDiskSize(root string) (int64, error) { - rootUTF16, err := windows.UTF16FromString(root) - if err != nil { - return 0, err - } - var freeAvailableBytes uint64 - var totalBytes uint64 - var totalFreeBytes uint64 - - if err := windows.GetDiskFreeSpaceEx( - &rootUTF16[0], - &freeAvailableBytes, - &totalBytes, - &totalFreeBytes); err != nil { - return 0, err - } - return int64(totalBytes), nil -} diff --git a/cmd/buildkitd/config/load_test.go b/cmd/buildkitd/config/load_test.go index 4b446510c8c6..5ae1ea10c4fd 100644 --- a/cmd/buildkitd/config/load_test.go +++ b/cmd/buildkitd/config/load_test.go @@ -57,6 +57,10 @@ keepDuration=7200 [[worker.containerd.gcpolicy]] keepBytes="20%" keepDuration="24h" +[[worker.containerd.gcpolicy]] +minStorage="10GB" +maxStorage="80%" +free="10%" [registry."docker.io"] mirrors=["hub.docker.io"] @@ -110,21 +114,28 @@ searchDomains=["example.com"] require.Equal(t, "exotic", cfg.Workers.Containerd.Runtime.Name) require.Equal(t, "/usr/bin/exotic", cfg.Workers.Containerd.Runtime.Path) require.Equal(t, "bar", cfg.Workers.Containerd.Runtime.Options["foo"]) - require.Equal(t, 3, len(cfg.Workers.Containerd.GCPolicy)) + require.Equal(t, 4, len(cfg.Workers.Containerd.GCPolicy)) require.Nil(t, cfg.Workers.Containerd.GC) require.Equal(t, true, cfg.Workers.Containerd.GCPolicy[0].All) - require.Equal(t, false, cfg.Workers.Containerd.GCPolicy[1].All) - require.Equal(t, false, cfg.Workers.Containerd.GCPolicy[2].All) + require.Equal(t, 1, len(cfg.Workers.Containerd.GCPolicy[0].Filters)) require.Equal(t, int64(20), cfg.Workers.Containerd.GCPolicy[0].KeepBytes.Bytes) - require.Equal(t, int64(40*1024*1024), cfg.Workers.Containerd.GCPolicy[1].KeepBytes.Bytes) - require.Equal(t, int64(20), cfg.Workers.Containerd.GCPolicy[2].KeepBytes.Percentage) require.Equal(t, time.Duration(3600), cfg.Workers.Containerd.GCPolicy[0].KeepDuration.Duration/time.Second) + + require.Equal(t, false, cfg.Workers.Containerd.GCPolicy[1].All) + require.Equal(t, int64(40*1024*1024), cfg.Workers.Containerd.GCPolicy[1].KeepBytes.Bytes) require.Equal(t, time.Duration(7200), cfg.Workers.Containerd.GCPolicy[1].KeepDuration.Duration/time.Second) - require.Equal(t, time.Duration(86400), cfg.Workers.Containerd.GCPolicy[2].KeepDuration.Duration/time.Second) - require.Equal(t, 1, len(cfg.Workers.Containerd.GCPolicy[0].Filters)) require.Equal(t, 0, len(cfg.Workers.Containerd.GCPolicy[1].Filters)) + require.Equal(t, false, cfg.Workers.Containerd.GCPolicy[2].All) + require.Equal(t, int64(20), cfg.Workers.Containerd.GCPolicy[2].KeepBytes.Percentage) + require.Equal(t, time.Duration(86400), cfg.Workers.Containerd.GCPolicy[2].KeepDuration.Duration/time.Second) + + require.Equal(t, false, cfg.Workers.Containerd.GCPolicy[3].All) + require.Equal(t, int64(10*1024*1024*1024), cfg.Workers.Containerd.GCPolicy[3].MinStorage.Bytes) + require.Equal(t, int64(80), cfg.Workers.Containerd.GCPolicy[3].MaxStorage.Percentage) + require.Equal(t, int64(10), cfg.Workers.Containerd.GCPolicy[3].Free.Percentage) + require.Equal(t, true, *cfg.Registries["docker.io"].PlainHTTP) require.Equal(t, true, *cfg.Registries["docker.io"].Insecure) require.Equal(t, "hub.docker.io", cfg.Registries["docker.io"].Mirrors[0]) diff --git a/cmd/buildkitd/main.go b/cmd/buildkitd/main.go index fcd823fbe682..7c90021f98d3 100644 --- a/cmd/buildkitd/main.go +++ b/cmd/buildkitd/main.go @@ -542,8 +542,10 @@ func setDefaultConfig(cfg *config.Config) { } } -var isRootlessConfigOnce sync.Once -var isRootlessConfigValue bool +var ( + isRootlessConfigOnce sync.Once + isRootlessConfigValue bool +) // isRootlessConfig is true if we should be using the rootless config // defaults instead of the normal defaults. @@ -923,11 +925,17 @@ func getGCPolicy(cfg config.GCConfig, root string) []client.PruneInfo { } out := make([]client.PruneInfo, 0, len(cfg.GCPolicy)) for _, rule := range cfg.GCPolicy { + //nolint:staticcheck + if rule.KeepBytes != (config.DiskSpace{}) { + rule.MaxStorage = rule.KeepBytes + } out = append(out, client.PruneInfo{ Filter: rule.Filters, All: rule.All, - KeepBytes: rule.KeepBytes.AsBytes(root), KeepDuration: rule.KeepDuration.Duration, + MinStorage: rule.MinStorage.AsBytes(root), + MaxStorage: rule.MaxStorage.AsBytes(root), + Free: rule.Free.AsBytes(root), }) } return out diff --git a/control/control.go b/control/control.go index dfc0b6c9d9b2..7557b2ea6333 100644 --- a/control/control.go +++ b/control/control.go @@ -216,7 +216,9 @@ func (c *Controller) Prune(req *controlapi.PruneRequest, stream controlapi.Contr Filter: req.Filter, All: req.All, KeepDuration: time.Duration(req.KeepDuration), - KeepBytes: req.KeepBytes, + MinStorage: req.MinStorage, + MaxStorage: req.MaxStorage, + Free: req.Free, }) }) }(w) @@ -635,9 +637,11 @@ func toPBGCPolicy(in []client.PruneInfo) []*apitypes.GCPolicy { for _, p := range in { policy = append(policy, &apitypes.GCPolicy{ All: p.All, - KeepBytes: p.KeepBytes, - KeepDuration: int64(p.KeepDuration), Filters: p.Filter, + KeepDuration: int64(p.KeepDuration), + MinStorage: p.MinStorage, + MaxStorage: p.MaxStorage, + Free: p.Free, }) } return policy @@ -676,7 +680,7 @@ func cacheOptKey(opt controlapi.CacheOptionsEntry) (string, error) { if opt.Type == "registry" && opt.Attrs["ref"] != "" { return opt.Attrs["ref"], nil } - var rawOpt = struct { + rawOpt := struct { Type string Attrs map[string]string }{ diff --git a/util/disk/disk.go b/util/disk/disk.go new file mode 100644 index 000000000000..511616c50130 --- /dev/null +++ b/util/disk/disk.go @@ -0,0 +1,7 @@ +package disk + +type DiskStat struct { + Total int64 + Free int64 + Available int64 +} diff --git a/util/disk/disk_openbsd.go b/util/disk/disk_openbsd.go new file mode 100644 index 000000000000..729b071e9e5c --- /dev/null +++ b/util/disk/disk_openbsd.go @@ -0,0 +1,21 @@ +//go:build openbsd +// +build openbsd + +package disk + +import ( + "syscall" +) + +func GetDiskStat(root string) (DiskStat, error) { + var st syscall.Statfs_t + if err := syscall.Statfs(root, &st); err != nil { + return DiskStat{}, err + } + + return DiskStat{ + Total: int64(st.F_bsize) * int64(st.F_blocks), + Free: int64(st.F_bsize) * int64(st.F_bfree), + Available: int64(st.F_bsize) * int64(st.F_bavail), + }, nil +} diff --git a/util/disk/disk_unix.go b/util/disk/disk_unix.go new file mode 100644 index 000000000000..37cfeabc1358 --- /dev/null +++ b/util/disk/disk_unix.go @@ -0,0 +1,21 @@ +//go:build !windows && !openbsd +// +build !windows,!openbsd + +package disk + +import ( + "syscall" +) + +func GetDiskStat(root string) (DiskStat, error) { + var st syscall.Statfs_t + if err := syscall.Statfs(root, &st); err != nil { + return DiskStat{}, err + } + + return DiskStat{ + Total: int64(st.Bsize) * int64(st.Blocks), + Free: int64(st.Bsize) * int64(st.Bfree), + Available: int64(st.Bsize) * int64(st.Bavail), + }, nil +} diff --git a/util/disk/disk_windows.go b/util/disk/disk_windows.go new file mode 100644 index 000000000000..d19df26282ba --- /dev/null +++ b/util/disk/disk_windows.go @@ -0,0 +1,33 @@ +//go:build windows +// +build windows + +package disk + +import ( + "golang.org/x/sys/windows" +) + +func GetDiskStat(root string) (DiskStat, error) { + rootUTF16, err := windows.UTF16FromString(root) + if err != nil { + return DiskStat{}, err + } + var ( + totalBytes uint64 + totalFreeBytes uint64 + freeAvailableBytes uint64 + ) + if err := windows.GetDiskFreeSpaceEx( + &rootUTF16[0], + &freeAvailableBytes, + &totalBytes, + &totalFreeBytes); err != nil { + return DiskStat{}, err + } + + return DiskStat{ + Total: int64(totalBytes), + Free: int64(totalFreeBytes), + Available: int64(freeAvailableBytes), + }, nil +} From ac7caa8f3b354fba7622d9da29a1171b5b709734 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Wed, 25 Sep 2024 10:49:50 +0100 Subject: [PATCH 2/2] chore: use a better root for computing free disk space We shouldn't use the cachemount root, we should actually properly use the worker's specified root which is propagated from the config. Signed-off-by: Justin Chadwell --- cache/manager.go | 7 +++++-- cache/manager_test.go | 1 + solver/llbsolver/mounts/mount_test.go | 1 + source/git/source_test.go | 1 + source/http/source_test.go | 1 + worker/base/worker.go | 2 ++ worker/containerd/containerd.go | 1 + worker/runc/runc.go | 1 + 8 files changed, 13 insertions(+), 2 deletions(-) diff --git a/cache/manager.go b/cache/manager.go index 266b4eddd753..c4e2e84f12fc 100644 --- a/cache/manager.go +++ b/cache/manager.go @@ -49,6 +49,7 @@ type ManagerOpt struct { Applier diff.Applier Differ diff.Comparer MetadataStore *metadata.Store + Root string MountPoolRoot string } @@ -94,6 +95,8 @@ type cacheManager struct { Differ diff.Comparer MetadataStore *metadata.Store + root string + mountPool sharableMountPool muPrune sync.Mutex // make sure parallel prune is not allowed so there will not be inconsistent results @@ -110,6 +113,7 @@ func NewManager(opt ManagerOpt) (Manager, error) { Applier: opt.Applier, Differ: opt.Differ, MetadataStore: opt.MetadataStore, + root: opt.Root, records: make(map[string]*cacheRecord), } @@ -1054,8 +1058,7 @@ func (cm *cacheManager) pruneOnce(ctx context.Context, ch chan client.UsageInfo, } } - // TODO: pick a better path here - dstat, err := disk.GetDiskStat(cm.mountPool.tmpdirRoot) + dstat, err := disk.GetDiskStat(cm.root) if err != nil { if opt.Free != 0 { // if we are pruning based on disk space, failing to get info on it diff --git a/cache/manager_test.go b/cache/manager_test.go index 2a9ee9877935..1aef32987104 100644 --- a/cache/manager_test.go +++ b/cache/manager_test.go @@ -152,6 +152,7 @@ func newCacheManager(ctx context.Context, t *testing.T, opt cmOpt) (co *cmOut, c GarbageCollect: mdb.GarbageCollect, Applier: applier, Differ: differ, + Root: tmpdir, MountPoolRoot: filepath.Join(tmpdir, "cachemounts"), }) if err != nil { diff --git a/solver/llbsolver/mounts/mount_test.go b/solver/llbsolver/mounts/mount_test.go index 44536d795dc2..180f40607b75 100644 --- a/solver/llbsolver/mounts/mount_test.go +++ b/solver/llbsolver/mounts/mount_test.go @@ -109,6 +109,7 @@ func newCacheManager(ctx context.Context, t *testing.T, opt cmOpt) (co *cmOut, e Differ: differ, LeaseManager: lm, GarbageCollect: mdb.GarbageCollect, + Root: tmpdir, MountPoolRoot: filepath.Join(tmpdir, "cachemounts"), }) if err != nil { diff --git a/source/git/source_test.go b/source/git/source_test.go index 104263934a7c..59a0fdd83e4f 100644 --- a/source/git/source_test.go +++ b/source/git/source_test.go @@ -649,6 +649,7 @@ func setupGitSource(t *testing.T, tmpdir string) source.Source { Applier: applier, Differ: differ, GarbageCollect: mdb.GarbageCollect, + Root: tmpdir, MountPoolRoot: filepath.Join(tmpdir, "cachemounts"), }) require.NoError(t, err) diff --git a/source/http/source_test.go b/source/http/source_test.go index 980ec2117b2e..8f091dd7008c 100644 --- a/source/http/source_test.go +++ b/source/http/source_test.go @@ -355,6 +355,7 @@ func newHTTPSource(t *testing.T) (source.Source, error) { Applier: applier, Differ: differ, GarbageCollect: mdb.GarbageCollect, + Root: tmpdir, MountPoolRoot: filepath.Join(tmpdir, "cachemounts"), }) if err != nil { diff --git a/worker/base/worker.go b/worker/base/worker.go index d57cf457618f..0a1743929a91 100644 --- a/worker/base/worker.go +++ b/worker/base/worker.go @@ -62,6 +62,7 @@ const labelCreatedAt = "buildkit/createdat" // See also CommonOpt. type WorkerOpt struct { ID string + Root string Labels map[string]string Platforms []ocispecs.Platform GCPolicy []client.PruneInfo @@ -110,6 +111,7 @@ func NewWorker(ctx context.Context, opt WorkerOpt) (*Worker, error) { ContentStore: opt.ContentStore, Differ: opt.Differ, MetadataStore: opt.MetadataStore, + Root: opt.Root, MountPoolRoot: opt.MountPoolRoot, }) if err != nil { diff --git a/worker/containerd/containerd.go b/worker/containerd/containerd.go index d3ec2e4d632b..c00b951bb3f7 100644 --- a/worker/containerd/containerd.go +++ b/worker/containerd/containerd.go @@ -184,6 +184,7 @@ func newContainerd(client *containerd.Client, workerOpts WorkerOptions) (base.Wo opt := base.WorkerOpt{ ID: id, + Root: root, Labels: xlabels, MetadataStore: md, NetworkProviders: np, diff --git a/worker/runc/runc.go b/worker/runc/runc.go index 937e96017b56..ce756ce3754e 100644 --- a/worker/runc/runc.go +++ b/worker/runc/runc.go @@ -150,6 +150,7 @@ func NewWorkerOpt(root string, snFactory SnapshotterFactory, rootless bool, proc opt = base.WorkerOpt{ ID: id, + Root: root, Labels: xlabels, MetadataStore: md, NetworkProviders: np,