github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/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/demonoid81/moby/daemon/config" 12 "github.com/demonoid81/moby/pkg/idtools" 13 "github.com/demonoid81/moby/pkg/stringid" 14 "github.com/demonoid81/libnetwork" 15 "github.com/moby/buildkit/executor" 16 "github.com/moby/buildkit/executor/oci" 17 "github.com/moby/buildkit/executor/runcexecutor" 18 "github.com/moby/buildkit/identity" 19 "github.com/moby/buildkit/solver/pb" 20 "github.com/moby/buildkit/util/network" 21 specs "github.com/opencontainers/runtime-spec/specs-go" 22 "github.com/sirupsen/logrus" 23 ) 24 25 const networkName = "bridge" 26 27 func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, dnsConfig *oci.DNSConfig, rootless bool, idmap *idtools.IdentityMapping) (executor.Executor, error) { 28 networkProviders := map[pb.NetMode]network.Provider{ 29 pb.NetMode_UNSET: &bridgeProvider{NetworkController: net, Root: filepath.Join(root, "net")}, 30 pb.NetMode_HOST: network.NewHostProvider(), 31 pb.NetMode_NONE: network.NewNoneProvider(), 32 } 33 return runcexecutor.New(runcexecutor.Opt{ 34 Root: filepath.Join(root, "executor"), 35 CommandCandidates: []string{"runc"}, 36 DefaultCgroupParent: cgroupParent, 37 Rootless: rootless, 38 NoPivot: os.Getenv("DOCKER_RAMDISK") != "", 39 IdentityMapping: idmap, 40 DNS: dnsConfig, 41 }, networkProviders) 42 } 43 44 type bridgeProvider struct { 45 libnetwork.NetworkController 46 Root string 47 } 48 49 func (p *bridgeProvider) New() (network.Namespace, error) { 50 n, err := p.NetworkByName(networkName) 51 if err != nil { 52 return nil, err 53 } 54 55 iface := &lnInterface{ready: make(chan struct{}), provider: p} 56 iface.Once.Do(func() { 57 go iface.init(p.NetworkController, n) 58 }) 59 60 return iface, nil 61 } 62 63 type lnInterface struct { 64 ep libnetwork.Endpoint 65 sbx libnetwork.Sandbox 66 sync.Once 67 err error 68 ready chan struct{} 69 provider *bridgeProvider 70 } 71 72 func (iface *lnInterface) init(c libnetwork.NetworkController, n libnetwork.Network) { 73 defer close(iface.ready) 74 id := identity.NewID() 75 76 ep, err := n.CreateEndpoint(id, libnetwork.CreateOptionDisableResolution()) 77 if err != nil { 78 iface.err = err 79 return 80 } 81 82 sbx, err := c.NewSandbox(id, libnetwork.OptionUseExternalKey(), libnetwork.OptionHostsPath(filepath.Join(iface.provider.Root, id, "hosts")), 83 libnetwork.OptionResolvConfPath(filepath.Join(iface.provider.Root, id, "resolv.conf"))) 84 if err != nil { 85 iface.err = err 86 return 87 } 88 89 if err := ep.Join(sbx); err != nil { 90 iface.err = err 91 return 92 } 93 94 iface.sbx = sbx 95 iface.ep = ep 96 } 97 98 func (iface *lnInterface) Set(s *specs.Spec) { 99 <-iface.ready 100 if iface.err != nil { 101 logrus.WithError(iface.err).Error("failed to set networking spec") 102 return 103 } 104 shortNetCtlrID := stringid.TruncateID(iface.provider.NetworkController.ID()) 105 // attach netns to bridge within the container namespace, using reexec in a prestart hook 106 s.Hooks = &specs.Hooks{ 107 Prestart: []specs.Hook{{ 108 Path: filepath.Join("/proc", strconv.Itoa(os.Getpid()), "exe"), 109 Args: []string{"libnetwork-setkey", "-exec-root=" + iface.provider.Config().Daemon.ExecRoot, iface.sbx.ContainerID(), shortNetCtlrID}, 110 }}, 111 } 112 } 113 114 func (iface *lnInterface) Close() error { 115 <-iface.ready 116 if iface.sbx != nil { 117 go func() { 118 if err := iface.sbx.Delete(); err != nil { 119 logrus.Errorf("failed to delete builder network sandbox: %v", err) 120 } 121 }() 122 } 123 return iface.err 124 } 125 126 func getDNSConfig(cfg config.DNSConfig) *oci.DNSConfig { 127 if cfg.DNS != nil || cfg.DNSSearch != nil || cfg.DNSOptions != nil { 128 return &oci.DNSConfig{ 129 Nameservers: cfg.DNS, 130 SearchDomains: cfg.DNSSearch, 131 Options: cfg.DNSOptions, 132 } 133 } 134 return nil 135 }