github.com/jwhonce/docker@v0.6.7-0.20190327063223-da823cf3a5a3/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, rootless bool) (executor.Executor, error) { 24 networkProviders := map[pb.NetMode]network.Provider{ 25 pb.NetMode_UNSET: &bridgeProvider{NetworkController: net, Root: filepath.Join(root, "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 Rootless: rootless, 34 }, networkProviders) 35 } 36 37 type bridgeProvider struct { 38 libnetwork.NetworkController 39 Root string 40 } 41 42 func (p *bridgeProvider) New() (network.Namespace, error) { 43 n, err := p.NetworkByName(networkName) 44 if err != nil { 45 return nil, err 46 } 47 48 iface := &lnInterface{ready: make(chan struct{}), provider: p} 49 iface.Once.Do(func() { 50 go iface.init(p.NetworkController, n) 51 }) 52 53 return iface, nil 54 } 55 56 type lnInterface struct { 57 ep libnetwork.Endpoint 58 sbx libnetwork.Sandbox 59 sync.Once 60 err error 61 ready chan struct{} 62 provider *bridgeProvider 63 } 64 65 func (iface *lnInterface) init(c libnetwork.NetworkController, n libnetwork.Network) { 66 defer close(iface.ready) 67 id := identity.NewID() 68 69 ep, err := n.CreateEndpoint(id, libnetwork.CreateOptionDisableResolution()) 70 if err != nil { 71 iface.err = err 72 return 73 } 74 75 sbx, err := c.NewSandbox(id, libnetwork.OptionUseExternalKey(), libnetwork.OptionHostsPath(filepath.Join(iface.provider.Root, id, "hosts")), 76 libnetwork.OptionResolvConfPath(filepath.Join(iface.provider.Root, id, "resolv.conf"))) 77 if err != nil { 78 iface.err = err 79 return 80 } 81 82 if err := ep.Join(sbx); err != nil { 83 iface.err = err 84 return 85 } 86 87 iface.sbx = sbx 88 iface.ep = ep 89 } 90 91 func (iface *lnInterface) Set(s *specs.Spec) { 92 <-iface.ready 93 if iface.err != nil { 94 logrus.WithError(iface.err).Error("failed to set networking spec") 95 return 96 } 97 // attach netns to bridge within the container namespace, using reexec in a prestart hook 98 s.Hooks = &specs.Hooks{ 99 Prestart: []specs.Hook{{ 100 Path: filepath.Join("/proc", strconv.Itoa(os.Getpid()), "exe"), 101 Args: []string{"libnetwork-setkey", "-exec-root=" + iface.provider.Config().Daemon.ExecRoot, iface.sbx.ContainerID(), iface.provider.NetworkController.ID()}, 102 }}, 103 } 104 } 105 106 func (iface *lnInterface) Close() error { 107 <-iface.ready 108 if iface.sbx != nil { 109 go func() { 110 if err := iface.sbx.Delete(); err != nil { 111 logrus.Errorf("failed to delete builder network sandbox: %v", err) 112 } 113 }() 114 } 115 return iface.err 116 }