From d52485c2f901e62e9a26445e230ec3f6662fa276 Mon Sep 17 00:00:00 2001 From: Anda Xu Date: Tue, 14 Aug 2018 18:40:28 -0700 Subject: [PATCH 1/3] propagate the dockerd cgroup-parent config to buildkitd Signed-off-by: Anda Xu --- builder/builder-next/builder.go | 9 +++++---- builder/builder-next/controller.go | 2 +- builder/builder-next/executor_unix.go | 7 ++++--- cmd/dockerd/daemon.go | 20 ++++++++++++++++---- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/builder/builder-next/builder.go b/builder/builder-next/builder.go index 0016d9e8ea..7bd93c05fc 100644 --- a/builder/builder-next/builder.go +++ b/builder/builder-next/builder.go @@ -50,10 +50,11 @@ func init() { // Opt is option struct required for creating the builder type Opt struct { - SessionManager *session.Manager - Root string - Dist images.DistributionServices - NetworkController libnetwork.NetworkController + SessionManager *session.Manager + Root string + Dist images.DistributionServices + NetworkController libnetwork.NetworkController + DefaultCgroupParent string } // Builder can build using BuildKit backend diff --git a/builder/builder-next/controller.go b/builder/builder-next/controller.go index f50dea315a..808b0b884f 100644 --- a/builder/builder-next/controller.go +++ b/builder/builder-next/controller.go @@ -102,7 +102,7 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) { return nil, err } - exec, err := newExecutor(root, opt.NetworkController) + exec, err := newExecutor(root, opt.DefaultCgroupParent, opt.NetworkController) if err != nil { return nil, err } diff --git a/builder/builder-next/executor_unix.go b/builder/builder-next/executor_unix.go index 808889a0af..94d8bb7660 100644 --- a/builder/builder-next/executor_unix.go +++ b/builder/builder-next/executor_unix.go @@ -19,15 +19,16 @@ import ( const networkName = "bridge" -func newExecutor(root string, net libnetwork.NetworkController) (executor.Executor, error) { +func newExecutor(root, cgroupParent string, net libnetwork.NetworkController) (executor.Executor, error) { networkProviders := map[pb.NetMode]network.Provider{ pb.NetMode_UNSET: &bridgeProvider{NetworkController: net}, pb.NetMode_HOST: network.NewHostProvider(), pb.NetMode_NONE: network.NewNoneProvider(), } return runcexecutor.New(runcexecutor.Opt{ - Root: filepath.Join(root, "executor"), - CommandCandidates: []string{"docker-runc", "runc"}, + Root: filepath.Join(root, "executor"), + CommandCandidates: []string{"docker-runc", "runc"}, + DefaultCgroupParent: cgroupParent, }, networkProviders) } diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index b46ee08121..678d849963 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -284,11 +284,23 @@ func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptio if err != nil { return opts, err } + cgroupParent := "docker" + useSystemd := daemon.UsingSystemd(config) + if useSystemd { + cgroupParent = "system.slice" + } + if config.CgroupParent != "" { + cgroupParent = config.CgroupParent + } + if useSystemd { + cgroupParent = cgroupParent + ":" + "docker" + ":" + } bk, err := buildkit.New(buildkit.Opt{ - SessionManager: sm, - Root: filepath.Join(config.Root, "buildkit"), - Dist: daemon.DistributionServices(), - NetworkController: daemon.NetworkController(), + SessionManager: sm, + Root: filepath.Join(config.Root, "buildkit"), + Dist: daemon.DistributionServices(), + NetworkController: daemon.NetworkController(), + DefaultCgroupParent: cgroupParent, }) if err != nil { return opts, err From 54b3af4c7d7d625b9cff6d5d7b8730ec99f38977 Mon Sep 17 00:00:00 2001 From: Anda Xu Date: Thu, 6 Sep 2018 11:50:41 -0700 Subject: [PATCH 2/3] update vendor Signed-off-by: Anda Xu --- builder/builder-next/executor_windows.go | 2 +- builder/builder-next/worker/worker.go | 10 +- cmd/dockerd/daemon.go | 14 +- vendor.conf | 2 +- .../moby/buildkit/api/types/worker.pb.go | 353 +++++++++++++++++- .../moby/buildkit/api/types/worker.proto | 8 + .../github.com/moby/buildkit/cache/manager.go | 13 +- .../moby/buildkit/client/llb/state.go | 2 +- .../moby/buildkit/client/workers.go | 17 + .../moby/buildkit/control/control.go | 71 ++++ .../executor/runcexecutor/executor.go | 15 + .../dockerfile/dockerfile2llb/convert.go | 2 +- .../frontend/gateway/forwarder/forward.go | 6 +- .../moby/buildkit/util/throttle/throttle.go | 58 +++ .../github.com/moby/buildkit/worker/worker.go | 3 +- 15 files changed, 540 insertions(+), 36 deletions(-) create mode 100644 vendor/github.com/moby/buildkit/util/throttle/throttle.go diff --git a/builder/builder-next/executor_windows.go b/builder/builder-next/executor_windows.go index e3b5aba829..f19bf18655 100644 --- a/builder/builder-next/executor_windows.go +++ b/builder/builder-next/executor_windows.go @@ -10,7 +10,7 @@ import ( "github.com/moby/buildkit/executor" ) -func newExecutor(_ string, _ libnetwork.NetworkController) (executor.Executor, error) { +func newExecutor(_, _ string, _ libnetwork.NetworkController) (executor.Executor, error) { return &winExecutor{}, nil } diff --git a/builder/builder-next/worker/worker.go b/builder/builder-next/worker/worker.go index f288466e47..e2aae3a63f 100644 --- a/builder/builder-next/worker/worker.go +++ b/builder/builder-next/worker/worker.go @@ -46,6 +46,7 @@ import ( type Opt struct { ID string Labels map[string]string + GCPolicy []client.PruneInfo SessionManager *session.Manager MetadataStore *metadata.Store Executor executor.Executor @@ -130,6 +131,11 @@ func (w *Worker) Platforms() []ocispec.Platform { return []ocispec.Platform{platforms.DefaultSpec()} } +// GCPolicy returns automatic GC Policy +func (w *Worker) GCPolicy() []client.PruneInfo { + return w.Opt.GCPolicy +} + // LoadRef loads a reference by ID func (w *Worker) LoadRef(id string) (cache.ImmutableRef, error) { return w.CacheManager.Get(context.TODO(), id) @@ -176,8 +182,8 @@ func (w *Worker) DiskUsage(ctx context.Context, opt client.DiskUsageInfo) ([]*cl } // Prune deletes reclaimable build cache -func (w *Worker) Prune(ctx context.Context, ch chan client.UsageInfo, info client.PruneInfo) error { - return w.CacheManager.Prune(ctx, ch, info) +func (w *Worker) Prune(ctx context.Context, ch chan client.UsageInfo, info ...client.PruneInfo) error { + return w.CacheManager.Prune(ctx, ch, info...) } // Exporter returns exporter by name diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index 678d849963..2cdd5bf47c 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -259,7 +259,7 @@ type routerOptions struct { cluster *cluster.Cluster } -func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptions, error) { +func newRouterOptions(config *config.Config, d *daemon.Daemon) (routerOptions, error) { opts := routerOptions{} sm, err := session.NewManager() if err != nil { @@ -280,7 +280,7 @@ func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptio return opts, errors.Wrap(err, "failed to create fscache") } - manager, err := dockerfile.NewBuildManager(daemon.BuilderBackend(), sm, buildCache, daemon.IdentityMapping()) + manager, err := dockerfile.NewBuildManager(d.BuilderBackend(), sm, buildCache, d.IdentityMapping()) if err != nil { return opts, err } @@ -298,15 +298,15 @@ func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptio bk, err := buildkit.New(buildkit.Opt{ SessionManager: sm, Root: filepath.Join(config.Root, "buildkit"), - Dist: daemon.DistributionServices(), - NetworkController: daemon.NetworkController(), + Dist: d.DistributionServices(), + NetworkController: d.NetworkController(), DefaultCgroupParent: cgroupParent, }) if err != nil { return opts, err } - bb, err := buildbackend.NewBackend(daemon.ImageService(), manager, buildCache, bk) + bb, err := buildbackend.NewBackend(d.ImageService(), manager, buildCache, bk) if err != nil { return opts, errors.Wrap(err, "failed to create buildmanager") } @@ -315,8 +315,8 @@ func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptio buildBackend: bb, buildCache: buildCache, buildkit: bk, - features: daemon.Features(), - daemon: daemon, + features: d.Features(), + daemon: d, }, nil } diff --git a/vendor.conf b/vendor.conf index cc9b664e34..5246435f29 100644 --- a/vendor.conf +++ b/vendor.conf @@ -26,7 +26,7 @@ github.com/imdario/mergo v0.3.6 golang.org/x/sync 1d60e4601c6fd243af51cc01ddf169918a5407ca # buildkit -github.com/moby/buildkit 6812dac65e0440bb75affce1fb2175e640edc15d +github.com/moby/buildkit a9fe50acf16dd05d1f9877b27068884543ad7a1f github.com/tonistiigi/fsutil b19464cd1b6a00773b4f2eb7acf9c30426f9df42 github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746 github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7 diff --git a/vendor/github.com/moby/buildkit/api/types/worker.pb.go b/vendor/github.com/moby/buildkit/api/types/worker.pb.go index 46c8538f8e..0344d523e7 100644 --- a/vendor/github.com/moby/buildkit/api/types/worker.pb.go +++ b/vendor/github.com/moby/buildkit/api/types/worker.pb.go @@ -9,6 +9,7 @@ It has these top-level messages: WorkerRecord + GCPolicy */ package moby_buildkit_v1_types @@ -35,6 +36,7 @@ type WorkerRecord struct { ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` Labels map[string]string `protobuf:"bytes,2,rep,name=Labels" json:"Labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Platforms []pb.Platform `protobuf:"bytes,3,rep,name=platforms" json:"platforms"` + GCPolicy []*GCPolicy `protobuf:"bytes,4,rep,name=GCPolicy" json:"GCPolicy,omitempty"` } func (m *WorkerRecord) Reset() { *m = WorkerRecord{} } @@ -63,8 +65,56 @@ func (m *WorkerRecord) GetPlatforms() []pb.Platform { return nil } +func (m *WorkerRecord) GetGCPolicy() []*GCPolicy { + if m != nil { + return m.GCPolicy + } + return nil +} + +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" json:"filters,omitempty"` +} + +func (m *GCPolicy) Reset() { *m = GCPolicy{} } +func (m *GCPolicy) String() string { return proto.CompactTextString(m) } +func (*GCPolicy) ProtoMessage() {} +func (*GCPolicy) Descriptor() ([]byte, []int) { return fileDescriptorWorker, []int{1} } + +func (m *GCPolicy) GetAll() bool { + if m != nil { + return m.All + } + return false +} + +func (m *GCPolicy) GetKeepDuration() int64 { + if m != nil { + return m.KeepDuration + } + return 0 +} + +func (m *GCPolicy) GetKeepBytes() int64 { + if m != nil { + return m.KeepBytes + } + return 0 +} + +func (m *GCPolicy) GetFilters() []string { + if m != nil { + return m.Filters + } + return nil +} + func init() { proto.RegisterType((*WorkerRecord)(nil), "moby.buildkit.v1.types.WorkerRecord") + proto.RegisterType((*GCPolicy)(nil), "moby.buildkit.v1.types.GCPolicy") } func (m *WorkerRecord) Marshal() (dAtA []byte, err error) { size := m.Size() @@ -116,6 +166,71 @@ func (m *WorkerRecord) MarshalTo(dAtA []byte) (int, error) { i += n } } + if len(m.GCPolicy) > 0 { + for _, msg := range m.GCPolicy { + dAtA[i] = 0x22 + i++ + i = encodeVarintWorker(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *GCPolicy) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GCPolicy) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.All { + dAtA[i] = 0x8 + i++ + if m.All { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + if m.KeepDuration != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintWorker(dAtA, i, uint64(m.KeepDuration)) + } + if m.KeepBytes != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintWorker(dAtA, i, uint64(m.KeepBytes)) + } + if len(m.Filters) > 0 { + for _, s := range m.Filters { + dAtA[i] = 0x22 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } return i, nil } @@ -149,6 +264,33 @@ func (m *WorkerRecord) Size() (n int) { n += 1 + l + sovWorker(uint64(l)) } } + if len(m.GCPolicy) > 0 { + for _, e := range m.GCPolicy { + l = e.Size() + n += 1 + l + sovWorker(uint64(l)) + } + } + return n +} + +func (m *GCPolicy) Size() (n int) { + var l int + _ = l + if m.All { + n += 2 + } + if m.KeepDuration != 0 { + n += 1 + sovWorker(uint64(m.KeepDuration)) + } + if m.KeepBytes != 0 { + n += 1 + sovWorker(uint64(m.KeepBytes)) + } + if len(m.Filters) > 0 { + for _, s := range m.Filters { + l = len(s) + n += 1 + l + sovWorker(uint64(l)) + } + } return n } @@ -372,6 +514,174 @@ func (m *WorkerRecord) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GCPolicy", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWorker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWorker + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GCPolicy = append(m.GCPolicy, &GCPolicy{}) + if err := m.GCPolicy[len(m.GCPolicy)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipWorker(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthWorker + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GCPolicy) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWorker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GCPolicy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GCPolicy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field All", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWorker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.All = bool(v != 0) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field KeepDuration", wireType) + } + m.KeepDuration = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWorker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.KeepDuration |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field KeepBytes", wireType) + } + m.KeepBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWorker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.KeepBytes |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Filters", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWorker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthWorker + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Filters = append(m.Filters, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipWorker(dAtA[iNdEx:]) @@ -501,23 +811,28 @@ var ( func init() { proto.RegisterFile("worker.proto", fileDescriptorWorker) } var fileDescriptorWorker = []byte{ - // 273 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x8f, 0x41, 0x4b, 0xf3, 0x40, - 0x10, 0x86, 0xbf, 0x4d, 0x3e, 0x0b, 0xdd, 0x06, 0x91, 0x45, 0x24, 0xe4, 0x10, 0x8b, 0xa7, 0x1e, - 0x74, 0xb6, 0xea, 0x45, 0x3d, 0x96, 0x0a, 0x16, 0x3c, 0x48, 0x2e, 0x9e, 0xb3, 0xed, 0x36, 0x86, - 0x24, 0xce, 0xb2, 0xd9, 0x44, 0xf2, 0x0f, 0x7b, 0xf4, 0xe2, 0x55, 0x24, 0xbf, 0x44, 0xba, 0x89, - 0x98, 0x83, 0xb7, 0x79, 0x87, 0x67, 0x1e, 0xde, 0xa1, 0xde, 0x1b, 0xea, 0x4c, 0x6a, 0x50, 0x1a, - 0x0d, 0xb2, 0x93, 0x02, 0x45, 0x03, 0xa2, 0x4a, 0xf3, 0x4d, 0x96, 0x1a, 0xa8, 0x2f, 0xc1, 0x34, - 0x4a, 0x96, 0xc1, 0x45, 0x92, 0x9a, 0x97, 0x4a, 0xc0, 0x1a, 0x0b, 0x9e, 0x60, 0x82, 0xdc, 0xe2, - 0xa2, 0xda, 0xda, 0x64, 0x83, 0x9d, 0x3a, 0x4d, 0x70, 0x3e, 0xc0, 0xf7, 0x46, 0xfe, 0x63, 0xe4, - 0x25, 0xe6, 0xb5, 0xd4, 0x5c, 0x09, 0x8e, 0xaa, 0xec, 0xe8, 0xb3, 0x0f, 0x42, 0xbd, 0x67, 0xdb, - 0x22, 0x92, 0x6b, 0xd4, 0x1b, 0x76, 0x48, 0x9d, 0xd5, 0xd2, 0x27, 0x53, 0x32, 0x1b, 0x47, 0xce, - 0x6a, 0xc9, 0x1e, 0xe8, 0xe8, 0x31, 0x16, 0x32, 0x2f, 0x7d, 0x67, 0xea, 0xce, 0x26, 0x57, 0x73, - 0xf8, 0xbb, 0x26, 0x0c, 0x2d, 0xd0, 0x9d, 0xdc, 0xbf, 0x1a, 0xdd, 0x44, 0xfd, 0x3d, 0x9b, 0xd3, - 0xb1, 0xca, 0x63, 0xb3, 0x45, 0x5d, 0x94, 0xbe, 0x6b, 0x65, 0x1e, 0x28, 0x01, 0x4f, 0xfd, 0x72, - 0xf1, 0x7f, 0xf7, 0x79, 0xfa, 0x2f, 0xfa, 0x85, 0x82, 0x5b, 0x3a, 0x19, 0x88, 0xd8, 0x11, 0x75, - 0x33, 0xd9, 0xf4, 0xdd, 0xf6, 0x23, 0x3b, 0xa6, 0x07, 0x75, 0x9c, 0x57, 0xd2, 0x77, 0xec, 0xae, - 0x0b, 0x77, 0xce, 0x0d, 0x59, 0x78, 0xbb, 0x36, 0x24, 0xef, 0x6d, 0x48, 0xbe, 0xda, 0x90, 0x88, - 0x91, 0x7d, 0xf6, 0xfa, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xa9, 0x5c, 0x8f, 0x26, 0x71, 0x01, 0x00, - 0x00, + // 355 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xc1, 0x4e, 0xea, 0x40, + 0x14, 0x86, 0x6f, 0x5b, 0x2e, 0x97, 0x0e, 0xcd, 0x8d, 0x99, 0x18, 0xd3, 0x10, 0x83, 0x84, 0x15, + 0x0b, 0x9d, 0xa2, 0x6e, 0xd4, 0xb8, 0x42, 0x8c, 0x92, 0xb8, 0x20, 0xb3, 0x71, 0xdd, 0x81, 0x01, + 0x9b, 0x0e, 0x9c, 0xc9, 0x74, 0x8a, 0xf6, 0x39, 0x7c, 0x29, 0x96, 0x3e, 0x81, 0x31, 0x3c, 0x89, + 0x99, 0x29, 0x08, 0x26, 0xba, 0x3b, 0xff, 0x9f, 0xff, 0xfb, 0xe7, 0x9c, 0x0c, 0x0a, 0x9e, 0x41, + 0xa5, 0x5c, 0x11, 0xa9, 0x40, 0x03, 0x3e, 0x98, 0x01, 0x2b, 0x08, 0xcb, 0x13, 0x31, 0x4e, 0x13, + 0x4d, 0x16, 0xa7, 0x44, 0x17, 0x92, 0x67, 0x8d, 0x93, 0x69, 0xa2, 0x9f, 0x72, 0x46, 0x46, 0x30, + 0x8b, 0xa6, 0x30, 0x85, 0xc8, 0xc6, 0x59, 0x3e, 0xb1, 0xca, 0x0a, 0x3b, 0x95, 0x35, 0x8d, 0xe3, + 0x9d, 0xb8, 0x69, 0x8c, 0x36, 0x8d, 0x51, 0x06, 0x62, 0xc1, 0x55, 0x24, 0x59, 0x04, 0x32, 0x2b, + 0xd3, 0xed, 0x57, 0x17, 0x05, 0x8f, 0x76, 0x0b, 0xca, 0x47, 0xa0, 0xc6, 0xf8, 0x3f, 0x72, 0x07, + 0xfd, 0xd0, 0x69, 0x39, 0x1d, 0x9f, 0xba, 0x83, 0x3e, 0xbe, 0x47, 0xd5, 0x87, 0x98, 0x71, 0x91, + 0x85, 0x6e, 0xcb, 0xeb, 0xd4, 0xcf, 0xba, 0xe4, 0xe7, 0x35, 0xc9, 0x6e, 0x0b, 0x29, 0x91, 0xdb, + 0xb9, 0x56, 0x05, 0x5d, 0xf3, 0xb8, 0x8b, 0x7c, 0x29, 0x62, 0x3d, 0x01, 0x35, 0xcb, 0x42, 0xcf, + 0x96, 0x05, 0x44, 0x32, 0x32, 0x5c, 0x9b, 0xbd, 0xca, 0xf2, 0xfd, 0xe8, 0x0f, 0xdd, 0x86, 0xf0, + 0x35, 0xaa, 0xdd, 0xdd, 0x0c, 0x41, 0x24, 0xa3, 0x22, 0xac, 0x58, 0xa0, 0xf5, 0xdb, 0xeb, 0x9b, + 0x1c, 0xfd, 0x22, 0x1a, 0x97, 0xa8, 0xbe, 0xb3, 0x06, 0xde, 0x43, 0x5e, 0xca, 0x8b, 0xf5, 0x65, + 0x66, 0xc4, 0xfb, 0xe8, 0xef, 0x22, 0x16, 0x39, 0x0f, 0x5d, 0xeb, 0x95, 0xe2, 0xca, 0xbd, 0x70, + 0xda, 0x2f, 0xdb, 0x87, 0x0d, 0x17, 0x0b, 0x61, 0xb9, 0x1a, 0x35, 0x23, 0x6e, 0xa3, 0x20, 0xe5, + 0x5c, 0xf6, 0x73, 0x15, 0xeb, 0x04, 0xe6, 0x16, 0xf7, 0xe8, 0x37, 0x0f, 0x1f, 0x22, 0xdf, 0xe8, + 0x5e, 0xa1, 0xb9, 0x39, 0xd6, 0x04, 0xb6, 0x06, 0x0e, 0xd1, 0xbf, 0x49, 0x22, 0x34, 0x57, 0x99, + 0xbd, 0xcb, 0xa7, 0x1b, 0xd9, 0x0b, 0x96, 0xab, 0xa6, 0xf3, 0xb6, 0x6a, 0x3a, 0x1f, 0xab, 0xa6, + 0xc3, 0xaa, 0xf6, 0x93, 0xce, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x79, 0x52, 0x6a, 0x29, + 0x02, 0x00, 0x00, } diff --git a/vendor/github.com/moby/buildkit/api/types/worker.proto b/vendor/github.com/moby/buildkit/api/types/worker.proto index b1376b7431..82dd7ad651 100644 --- a/vendor/github.com/moby/buildkit/api/types/worker.proto +++ b/vendor/github.com/moby/buildkit/api/types/worker.proto @@ -13,4 +13,12 @@ message WorkerRecord { string ID = 1; map Labels = 2; repeated pb.Platform platforms = 3 [(gogoproto.nullable) = false]; + repeated GCPolicy GCPolicy = 4; +} + +message GCPolicy { + bool all = 1; + int64 keepDuration = 2; + int64 keepBytes = 3; + repeated string filters = 4; } diff --git a/vendor/github.com/moby/buildkit/cache/manager.go b/vendor/github.com/moby/buildkit/cache/manager.go index 7939cce12f..e73de71f3a 100644 --- a/vendor/github.com/moby/buildkit/cache/manager.go +++ b/vendor/github.com/moby/buildkit/cache/manager.go @@ -39,7 +39,7 @@ type Accessor interface { type Controller interface { DiskUsage(ctx context.Context, info client.DiskUsageInfo) ([]*client.UsageInfo, error) - Prune(ctx context.Context, ch chan client.UsageInfo, info client.PruneInfo) error + Prune(ctx context.Context, ch chan client.UsageInfo, info ...client.PruneInfo) error GC(ctx context.Context) error } @@ -304,10 +304,19 @@ func (cm *cacheManager) GetMutable(ctx context.Context, id string) (MutableRef, return rec.mref(), nil } -func (cm *cacheManager) Prune(ctx context.Context, ch chan client.UsageInfo, opt client.PruneInfo) error { +func (cm *cacheManager) Prune(ctx context.Context, ch chan client.UsageInfo, opts ...client.PruneInfo) error { cm.muPrune.Lock() defer cm.muPrune.Unlock() + for _, opt := range opts { + if err := cm.pruneOnce(ctx, ch, opt); err != nil { + return err + } + } + return nil +} + +func (cm *cacheManager) pruneOnce(ctx context.Context, ch chan client.UsageInfo, opt client.PruneInfo) error { filter, err := filters.ParseAll(opt.Filter...) if err != nil { return err diff --git a/vendor/github.com/moby/buildkit/client/llb/state.go b/vendor/github.com/moby/buildkit/client/llb/state.go index 6812ad36e8..e8972dfdba 100644 --- a/vendor/github.com/moby/buildkit/client/llb/state.go +++ b/vendor/github.com/moby/buildkit/client/llb/state.go @@ -67,7 +67,7 @@ func (s State) Value(k interface{}) interface{} { return s.ctx.Value(k) } -func (s State) SetMarhalDefaults(co ...ConstraintsOpt) State { +func (s State) SetMarshalDefaults(co ...ConstraintsOpt) State { s.opts = co return s } diff --git a/vendor/github.com/moby/buildkit/client/workers.go b/vendor/github.com/moby/buildkit/client/workers.go index a868292556..50654897ed 100644 --- a/vendor/github.com/moby/buildkit/client/workers.go +++ b/vendor/github.com/moby/buildkit/client/workers.go @@ -2,8 +2,10 @@ package client import ( "context" + "time" controlapi "github.com/moby/buildkit/api/services/control" + apitypes "github.com/moby/buildkit/api/types" "github.com/moby/buildkit/solver/pb" specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" @@ -13,6 +15,7 @@ type WorkerInfo struct { ID string Labels map[string]string Platforms []specs.Platform + GCPolicy []PruneInfo } func (c *Client) ListWorkers(ctx context.Context, opts ...ListWorkersOption) ([]*WorkerInfo, error) { @@ -34,6 +37,7 @@ func (c *Client) ListWorkers(ctx context.Context, opts ...ListWorkersOption) ([] ID: w.ID, Labels: w.Labels, Platforms: pb.ToSpecPlatforms(w.Platforms), + GCPolicy: fromAPIGCPolicy(w.GCPolicy), }) } @@ -47,3 +51,16 @@ type ListWorkersOption interface { type ListWorkersInfo struct { Filter []string } + +func fromAPIGCPolicy(in []*apitypes.GCPolicy) []PruneInfo { + out := make([]PruneInfo, 0, len(in)) + for _, p := range in { + out = append(out, PruneInfo{ + All: p.All, + Filter: p.Filters, + KeepDuration: time.Duration(p.KeepDuration), + KeepBytes: p.KeepBytes, + }) + } + return out +} diff --git a/vendor/github.com/moby/buildkit/control/control.go b/vendor/github.com/moby/buildkit/control/control.go index 0e6904dc8f..8b3b7bd8ac 100644 --- a/vendor/github.com/moby/buildkit/control/control.go +++ b/vendor/github.com/moby/buildkit/control/control.go @@ -2,6 +2,7 @@ package control import ( "context" + "sync" "time" "github.com/docker/distribution/reference" @@ -17,6 +18,7 @@ import ( "github.com/moby/buildkit/solver" "github.com/moby/buildkit/solver/llbsolver" "github.com/moby/buildkit/solver/pb" + "github.com/moby/buildkit/util/throttle" "github.com/moby/buildkit/worker" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -40,6 +42,8 @@ type Controller struct { // TODO: ControlService solver *llbsolver.Solver cache solver.CacheManager gatewayForwarder *controlgateway.GatewayForwarder + throttledGC func() + gcmu sync.Mutex } func NewController(opt Opt) (*Controller, error) { @@ -58,6 +62,12 @@ func NewController(opt Opt) (*Controller, error) { cache: cache, gatewayForwarder: gatewayForwarder, } + c.throttledGC = throttle.ThrottleAfter(time.Minute, c.gc) + + defer func() { + time.AfterFunc(time.Second, c.throttledGC) + }() + return c, nil } @@ -172,6 +182,10 @@ func (c *Controller) Prune(req *controlapi.PruneRequest, stream controlapi.Contr func (c *Controller) Solve(ctx context.Context, req *controlapi.SolveRequest) (*controlapi.SolveResponse, error) { ctx = session.NewContext(ctx, req.Session) + defer func() { + time.AfterFunc(time.Second, c.throttledGC) + }() + var expi exporter.ExporterInstance // TODO: multiworker // This is actually tricky, as the exporter should come from the worker that has the returned reference. We may need to delay this so that the solver loads this. @@ -313,11 +327,55 @@ func (c *Controller) ListWorkers(ctx context.Context, r *controlapi.ListWorkersR ID: w.ID(), Labels: w.Labels(), Platforms: pb.PlatformsFromSpec(w.Platforms()), + GCPolicy: toPBGCPolicy(w.GCPolicy()), }) } return resp, nil } +func (c *Controller) gc() { + c.gcmu.Lock() + defer c.gcmu.Unlock() + + workers, err := c.opt.WorkerController.List() + if err != nil { + return + } + + eg, ctx := errgroup.WithContext(context.TODO()) + + var size int64 + ch := make(chan client.UsageInfo) + done := make(chan struct{}) + go func() { + for ui := range ch { + size += ui.Size + } + close(done) + }() + + for _, w := range workers { + func(w worker.Worker) { + eg.Go(func() error { + if policy := w.GCPolicy(); len(policy) > 0 { + return w.Prune(ctx, ch, policy...) + } + return nil + }) + }(w) + } + + err = eg.Wait() + close(ch) + if err != nil { + logrus.Errorf("gc error: %+v", err) + } + <-done + if size > 0 { + logrus.Debugf("gc cleaned up %d bytes", size) + } +} + func parseCacheExporterOpt(opt map[string]string) solver.CacheExportMode { for k, v := range opt { switch k { @@ -336,3 +394,16 @@ func parseCacheExporterOpt(opt map[string]string) solver.CacheExportMode { } return solver.CacheExportModeMin } + +func toPBGCPolicy(in []client.PruneInfo) []*apitypes.GCPolicy { + policy := make([]*apitypes.GCPolicy, 0, len(in)) + for _, p := range in { + policy = append(policy, &apitypes.GCPolicy{ + All: p.All, + KeepBytes: p.KeepBytes, + KeepDuration: int64(p.KeepDuration), + Filters: p.Filter, + }) + } + return policy +} diff --git a/vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go b/vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go index 4458a992a3..cdb0d28ab3 100644 --- a/vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go +++ b/vendor/github.com/moby/buildkit/executor/runcexecutor/executor.go @@ -36,6 +36,8 @@ type Opt struct { CommandCandidates []string // without root privileges (has nothing to do with Opt.Root directory) Rootless bool + // DefaultCgroupParent is the cgroup-parent name for executor + DefaultCgroupParent string } var defaultCommandCandidates = []string{"buildkit-runc", "runc"} @@ -44,6 +46,7 @@ type runcExecutor struct { runc *runc.Runc root string cmd string + cgroupParent string rootless bool networkProviders map[pb.NetMode]network.Provider } @@ -94,6 +97,7 @@ func New(opt Opt, networkProviders map[pb.NetMode]network.Provider) (executor.Ex w := &runcExecutor{ runc: runtime, root: root, + cgroupParent: opt.DefaultCgroupParent, rootless: opt.Rootless, networkProviders: networkProviders, } @@ -173,6 +177,17 @@ func (w *runcExecutor) Exec(ctx context.Context, meta executor.Meta, root cache. if meta.ReadonlyRootFS { opts = append(opts, containerdoci.WithRootFSReadonly()) } + + if w.cgroupParent != "" { + var cgroupsPath string + lastSeparator := w.cgroupParent[len(w.cgroupParent)-1:] + if strings.Contains(w.cgroupParent, ".slice") && lastSeparator == ":" { + cgroupsPath = w.cgroupParent + id + } else { + cgroupsPath = filepath.Join("/", w.cgroupParent, "buildkit", id) + } + opts = append(opts, containerdoci.WithCgroup(cgroupsPath)) + } spec, cleanup, err := oci.GenerateSpec(ctx, meta, mounts, id, resolvConf, hostsFile, namespace, opts...) if err != nil { return err diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go index e69efc22ab..19d017dabc 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert.go @@ -347,7 +347,7 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State, } buildContext.Output = bc.Output() - st := target.state.SetMarhalDefaults(llb.Platform(platformOpt.targetPlatform)) + st := target.state.SetMarshalDefaults(llb.Platform(platformOpt.targetPlatform)) if !platformOpt.implicitTarget { target.image.OS = platformOpt.targetPlatform.OS diff --git a/vendor/github.com/moby/buildkit/frontend/gateway/forwarder/forward.go b/vendor/github.com/moby/buildkit/frontend/gateway/forwarder/forward.go index 65597e5eb8..a95f7bbaa2 100644 --- a/vendor/github.com/moby/buildkit/frontend/gateway/forwarder/forward.go +++ b/vendor/github.com/moby/buildkit/frontend/gateway/forwarder/forward.go @@ -67,7 +67,11 @@ func (c *bridgeClient) Solve(ctx context.Context, req client.SolveRequest) (*cli func (c *bridgeClient) BuildOpts() client.BuildOpts { workers := make([]client.WorkerInfo, 0, len(c.workerInfos)) for _, w := range c.workerInfos { - workers = append(workers, client.WorkerInfo(w)) + workers = append(workers, client.WorkerInfo{ + ID: w.ID, + Labels: w.Labels, + Platforms: w.Platforms, + }) } return client.BuildOpts{ diff --git a/vendor/github.com/moby/buildkit/util/throttle/throttle.go b/vendor/github.com/moby/buildkit/util/throttle/throttle.go new file mode 100644 index 0000000000..490ccd9c3d --- /dev/null +++ b/vendor/github.com/moby/buildkit/util/throttle/throttle.go @@ -0,0 +1,58 @@ +package throttle + +import ( + "sync" + "time" +) + +// Throttle wraps a function so that internal function does not get called +// more frequently than the specified duration. +func Throttle(d time.Duration, f func()) func() { + return throttle(d, f, true) +} + +// ThrottleAfter wraps a function so that internal function does not get called +// more frequently than the specified duration. The delay is added after function +// has been called. +func ThrottleAfter(d time.Duration, f func()) func() { + return throttle(d, f, false) +} + +func throttle(d time.Duration, f func(), wait bool) func() { + var next, running bool + var mu sync.Mutex + return func() { + mu.Lock() + defer mu.Unlock() + + next = true + if !running { + running = true + go func() { + for { + mu.Lock() + if next == false { + running = false + mu.Unlock() + return + } + if !wait { + next = false + } + mu.Unlock() + + if wait { + time.Sleep(d) + mu.Lock() + next = false + mu.Unlock() + f() + } else { + f() + time.Sleep(d) + } + } + }() + } + } +} diff --git a/vendor/github.com/moby/buildkit/worker/worker.go b/vendor/github.com/moby/buildkit/worker/worker.go index 4172cdf8a3..97abfbfbb2 100644 --- a/vendor/github.com/moby/buildkit/worker/worker.go +++ b/vendor/github.com/moby/buildkit/worker/worker.go @@ -20,6 +20,7 @@ type Worker interface { ID() string Labels() map[string]string Platforms() []specs.Platform + GCPolicy() []client.PruneInfo LoadRef(id string) (cache.ImmutableRef, error) // ResolveOp resolves Vertex.Sys() to Op implementation. ResolveOp(v solver.Vertex, s frontend.FrontendLLBBridge) (solver.Op, error) @@ -28,7 +29,7 @@ type Worker interface { Exec(ctx context.Context, meta executor.Meta, rootFS cache.ImmutableRef, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error DiskUsage(ctx context.Context, opt client.DiskUsageInfo) ([]*client.UsageInfo, error) Exporter(name string) (exporter.Exporter, error) - Prune(ctx context.Context, ch chan client.UsageInfo, opt client.PruneInfo) error + Prune(ctx context.Context, ch chan client.UsageInfo, opt ...client.PruneInfo) error GetRemote(ctx context.Context, ref cache.ImmutableRef, createIfNeeded bool) (*solver.Remote, error) FromRemote(ctx context.Context, remote *solver.Remote) (cache.ImmutableRef, error) } From 66ac92cdc65be350ec53f1de51052374846dfe24 Mon Sep 17 00:00:00 2001 From: Anda Xu Date: Fri, 7 Sep 2018 13:43:21 -0700 Subject: [PATCH 3/3] create newBuildKit function separately in daemon_unix.go and daemon_windows.go for cross platform build Signed-off-by: Anda Xu --- cmd/dockerd/daemon.go | 12 +----------- cmd/dockerd/daemon_unix.go | 16 ++++++++++++++++ cmd/dockerd/daemon_windows.go | 5 +++++ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index 2cdd5bf47c..c894d2a95f 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -284,17 +284,7 @@ func newRouterOptions(config *config.Config, d *daemon.Daemon) (routerOptions, e if err != nil { return opts, err } - cgroupParent := "docker" - useSystemd := daemon.UsingSystemd(config) - if useSystemd { - cgroupParent = "system.slice" - } - if config.CgroupParent != "" { - cgroupParent = config.CgroupParent - } - if useSystemd { - cgroupParent = cgroupParent + ":" + "docker" + ":" - } + cgroupParent := newCgroupParent(config) bk, err := buildkit.New(buildkit.Opt{ SessionManager: sm, Root: filepath.Join(config.Root, "buildkit"), diff --git a/cmd/dockerd/daemon_unix.go b/cmd/dockerd/daemon_unix.go index df51c3ef4b..7b03e28594 100644 --- a/cmd/dockerd/daemon_unix.go +++ b/cmd/dockerd/daemon_unix.go @@ -13,6 +13,7 @@ import ( "github.com/containerd/containerd/runtime/v1/linux" "github.com/docker/docker/cmd/dockerd/hack" "github.com/docker/docker/daemon" + "github.com/docker/docker/daemon/config" "github.com/docker/docker/libcontainerd/supervisor" "github.com/docker/libnetwork/portallocator" "golang.org/x/sys/unix" @@ -107,3 +108,18 @@ func wrapListeners(proto string, ls []net.Listener) []net.Listener { } return ls } + +func newCgroupParent(config *config.Config) string { + cgroupParent := "docker" + useSystemd := daemon.UsingSystemd(config) + if useSystemd { + cgroupParent = "system.slice" + } + if config.CgroupParent != "" { + cgroupParent = config.CgroupParent + } + if useSystemd { + cgroupParent = cgroupParent + ":" + "docker" + ":" + } + return cgroupParent +} diff --git a/cmd/dockerd/daemon_windows.go b/cmd/dockerd/daemon_windows.go index 11ff7da871..3b9ed9551f 100644 --- a/cmd/dockerd/daemon_windows.go +++ b/cmd/dockerd/daemon_windows.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" + "github.com/docker/docker/daemon/config" "github.com/docker/docker/libcontainerd/supervisor" "github.com/sirupsen/logrus" "golang.org/x/sys/windows" @@ -83,3 +84,7 @@ func allocateDaemonPort(addr string) error { func wrapListeners(proto string, ls []net.Listener) []net.Listener { return ls } + +func newCgroupParent(config *config.Config) string { + return "" +}