github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/builder/builder-next/executor_unix.go (about) 1 // +build !windows 2 3 package buildkit 4 5 import ( 6 "os" 7 "path/filepath" 8 "strconv" 9 "sync" 10 11 "github.com/docker/libnetwork" 12 "github.com/moby/buildkit/executor" 13 "github.com/moby/buildkit/executor/runcexecutor" 14 "github.com/moby/buildkit/identity" 15 "github.com/moby/buildkit/solver/pb" 16 "github.com/moby/buildkit/util/network" 17 specs "github.com/opencontainers/runtime-spec/specs-go" 18 "github.com/sirupsen/logrus" 19 ) 20 21 const networkName = "bridge" 22 23 func newExecutor(root, cgroupParent string, net libnetwork.NetworkController) (executor.Executor, error) { 24 networkProviders := map[pb.NetMode]network.Provider{ 25 pb.NetMode_UNSET: &bridgeProvider{NetworkController: net}, 26 pb.NetMode_HOST: network.NewHostProvider(), 27 pb.NetMode_NONE: network.NewNoneProvider(), 28 } 29 return runcexecutor.New(runcexecutor.Opt{ 30 Root: filepath.Join(root, "executor"), 31 CommandCandidates: []string{"runc"}, 32 DefaultCgroupParent: cgroupParent, 33 }, networkProviders) 34 } 35 36 type bridgeProvider struct { 37 libnetwork.NetworkController 38 } 39 40 func (p *bridgeProvider) New() (network.Namespace, error) { 41 n, err := p.NetworkByName(networkName) 42 if err != nil { 43 return nil, err 44 } 45 46 iface := &lnInterface{ready: make(chan struct{}), provider: p} 47 iface.Once.Do(func() { 48 go iface.init(p.NetworkController, n) 49 }) 50 51 return iface, nil 52 } 53 54 type lnInterface struct { 55 ep libnetwork.Endpoint 56 sbx libnetwork.Sandbox 57 sync.Once 58 err error 59 ready chan struct{} 60 provider *bridgeProvider 61 } 62 63 func (iface *lnInterface) init(c libnetwork.NetworkController, n libnetwork.Network) { 64 defer close(iface.ready) 65 id := identity.NewID() 66 67 ep, err := n.CreateEndpoint(id, libnetwork.CreateOptionDisableResolution()) 68 if err != nil { 69 iface.err = err 70 return 71 } 72 73 sbx, err := c.NewSandbox(id, libnetwork.OptionUseExternalKey()) 74 if err != nil { 75 iface.err = err 76 return 77 } 78 79 if err := ep.Join(sbx); err != nil { 80 iface.err = err 81 return 82 } 83 84 iface.sbx = sbx 85 iface.ep = ep 86 } 87 88 func (iface *lnInterface) Set(s *specs.Spec) { 89 <-iface.ready 90 if iface.err != nil { 91 return 92 } 93 // attach netns to bridge within the container namespace, using reexec in a prestart hook 94 s.Hooks = &specs.Hooks{ 95 Prestart: []specs.Hook{{ 96 Path: filepath.Join("/proc", strconv.Itoa(os.Getpid()), "exe"), 97 Args: []string{"libnetwork-setkey", iface.sbx.ContainerID(), iface.provider.NetworkController.ID()}, 98 }}, 99 } 100 } 101 102 func (iface *lnInterface) Close() error { 103 <-iface.ready 104 go func() { 105 if err := iface.sbx.Delete(); err != nil { 106 logrus.Errorf("failed to delete builder network sandbox: %v", err) 107 } 108 }() 109 return iface.err 110 }