github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/builder/builder-next/executor_unix.go (about) 1 //go:build !windows 2 // +build !windows 3 4 package buildkit 5 6 import ( 7 "os" 8 "path/filepath" 9 "strconv" 10 "sync" 11 12 "github.com/docker/docker/daemon/config" 13 "github.com/docker/docker/libnetwork" 14 "github.com/docker/docker/pkg/idtools" 15 "github.com/docker/docker/pkg/stringid" 16 "github.com/moby/buildkit/executor" 17 "github.com/moby/buildkit/executor/oci" 18 "github.com/moby/buildkit/executor/runcexecutor" 19 "github.com/moby/buildkit/identity" 20 "github.com/moby/buildkit/solver/pb" 21 "github.com/moby/buildkit/util/network" 22 specs "github.com/opencontainers/runtime-spec/specs-go" 23 "github.com/sirupsen/logrus" 24 ) 25 26 const networkName = "bridge" 27 28 func newExecutor(root, cgroupParent string, net libnetwork.NetworkController, dnsConfig *oci.DNSConfig, rootless bool, idmap idtools.IdentityMapping, apparmorProfile string) (executor.Executor, error) { 29 netRoot := filepath.Join(root, "net") 30 networkProviders := map[pb.NetMode]network.Provider{ 31 pb.NetMode_UNSET: &bridgeProvider{NetworkController: net, Root: netRoot}, 32 pb.NetMode_HOST: network.NewHostProvider(), 33 pb.NetMode_NONE: network.NewNoneProvider(), 34 } 35 36 // make sure net state directory is cleared from previous state 37 fis, err := os.ReadDir(netRoot) 38 if err == nil { 39 for _, fi := range fis { 40 fp := filepath.Join(netRoot, fi.Name()) 41 if err := os.RemoveAll(fp); err != nil { 42 logrus.WithError(err).Errorf("failed to delete old network state: %v", fp) 43 } 44 } 45 } 46 47 // Returning a non-nil but empty *IdentityMapping breaks BuildKit: 48 // https://github.com/moby/moby/pull/39444 49 pidmap := &idmap 50 if idmap.Empty() { 51 pidmap = nil 52 } 53 54 return runcexecutor.New(runcexecutor.Opt{ 55 Root: filepath.Join(root, "executor"), 56 CommandCandidates: []string{"runc"}, 57 DefaultCgroupParent: cgroupParent, 58 Rootless: rootless, 59 NoPivot: os.Getenv("DOCKER_RAMDISK") != "", 60 IdentityMapping: pidmap, 61 DNS: dnsConfig, 62 ApparmorProfile: apparmorProfile, 63 }, networkProviders) 64 } 65 66 type bridgeProvider struct { 67 libnetwork.NetworkController 68 Root string 69 } 70 71 func (p *bridgeProvider) New() (network.Namespace, error) { 72 n, err := p.NetworkByName(networkName) 73 if err != nil { 74 return nil, err 75 } 76 77 iface := &lnInterface{ready: make(chan struct{}), provider: p} 78 iface.Once.Do(func() { 79 go iface.init(p.NetworkController, n) 80 }) 81 82 return iface, nil 83 } 84 85 type lnInterface struct { 86 ep libnetwork.Endpoint 87 sbx libnetwork.Sandbox 88 sync.Once 89 err error 90 ready chan struct{} 91 provider *bridgeProvider 92 } 93 94 func (iface *lnInterface) init(c libnetwork.NetworkController, n libnetwork.Network) { 95 defer close(iface.ready) 96 id := identity.NewID() 97 98 ep, err := n.CreateEndpoint(id, libnetwork.CreateOptionDisableResolution()) 99 if err != nil { 100 iface.err = err 101 return 102 } 103 104 sbx, err := c.NewSandbox(id, libnetwork.OptionUseExternalKey(), libnetwork.OptionHostsPath(filepath.Join(iface.provider.Root, id, "hosts")), 105 libnetwork.OptionResolvConfPath(filepath.Join(iface.provider.Root, id, "resolv.conf"))) 106 if err != nil { 107 iface.err = err 108 return 109 } 110 111 if err := ep.Join(sbx); err != nil { 112 iface.err = err 113 return 114 } 115 116 iface.sbx = sbx 117 iface.ep = ep 118 } 119 120 func (iface *lnInterface) Set(s *specs.Spec) error { 121 <-iface.ready 122 if iface.err != nil { 123 logrus.WithError(iface.err).Error("failed to set networking spec") 124 return iface.err 125 } 126 shortNetCtlrID := stringid.TruncateID(iface.provider.NetworkController.ID()) 127 // attach netns to bridge within the container namespace, using reexec in a prestart hook 128 s.Hooks = &specs.Hooks{ 129 Prestart: []specs.Hook{{ 130 Path: filepath.Join("/proc", strconv.Itoa(os.Getpid()), "exe"), 131 Args: []string{"libnetwork-setkey", "-exec-root=" + iface.provider.Config().ExecRoot, iface.sbx.ContainerID(), shortNetCtlrID}, 132 }}, 133 } 134 return nil 135 } 136 137 func (iface *lnInterface) Close() error { 138 <-iface.ready 139 if iface.sbx != nil { 140 go func() { 141 if err := iface.sbx.Delete(); err != nil { 142 logrus.WithError(err).Errorf("failed to delete builder network sandbox") 143 } 144 if err := os.RemoveAll(filepath.Join(iface.provider.Root, iface.sbx.ContainerID())); err != nil { 145 logrus.WithError(err).Errorf("failed to delete builder sandbox directory") 146 } 147 }() 148 } 149 return iface.err 150 } 151 152 func getDNSConfig(cfg config.DNSConfig) *oci.DNSConfig { 153 if cfg.DNS != nil || cfg.DNSSearch != nil || cfg.DNSOptions != nil { 154 return &oci.DNSConfig{ 155 Nameservers: cfg.DNS, 156 SearchDomains: cfg.DNSSearch, 157 Options: cfg.DNSOptions, 158 } 159 } 160 return nil 161 }