github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/engine/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/pkg/idtools" 14 "github.com/docker/docker/pkg/stringid" 15 "github.com/docker/libnetwork" 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 return runcexecutor.New(runcexecutor.Opt{ 48 Root: filepath.Join(root, "executor"), 49 CommandCandidates: []string{"runc"}, 50 DefaultCgroupParent: cgroupParent, 51 Rootless: rootless, 52 NoPivot: os.Getenv("DOCKER_RAMDISK") != "", 53 IdentityMapping: idmap, 54 DNS: dnsConfig, 55 ApparmorProfile: apparmorProfile, 56 }, networkProviders) 57 } 58 59 type bridgeProvider struct { 60 libnetwork.NetworkController 61 Root string 62 } 63 64 func (p *bridgeProvider) New() (network.Namespace, error) { 65 n, err := p.NetworkByName(networkName) 66 if err != nil { 67 return nil, err 68 } 69 70 iface := &lnInterface{ready: make(chan struct{}), provider: p} 71 iface.Once.Do(func() { 72 go iface.init(p.NetworkController, n) 73 }) 74 75 return iface, nil 76 } 77 78 type lnInterface struct { 79 ep libnetwork.Endpoint 80 sbx libnetwork.Sandbox 81 sync.Once 82 err error 83 ready chan struct{} 84 provider *bridgeProvider 85 } 86 87 func (iface *lnInterface) init(c libnetwork.NetworkController, n libnetwork.Network) { 88 defer close(iface.ready) 89 id := identity.NewID() 90 91 ep, err := n.CreateEndpoint(id, libnetwork.CreateOptionDisableResolution()) 92 if err != nil { 93 iface.err = err 94 return 95 } 96 97 sbx, err := c.NewSandbox(id, libnetwork.OptionUseExternalKey(), libnetwork.OptionHostsPath(filepath.Join(iface.provider.Root, id, "hosts")), 98 libnetwork.OptionResolvConfPath(filepath.Join(iface.provider.Root, id, "resolv.conf"))) 99 if err != nil { 100 iface.err = err 101 return 102 } 103 104 if err := ep.Join(sbx); err != nil { 105 iface.err = err 106 return 107 } 108 109 iface.sbx = sbx 110 iface.ep = ep 111 } 112 113 func (iface *lnInterface) Set(s *specs.Spec) error { 114 <-iface.ready 115 if iface.err != nil { 116 logrus.WithError(iface.err).Error("failed to set networking spec") 117 return iface.err 118 } 119 shortNetCtlrID := stringid.TruncateID(iface.provider.NetworkController.ID()) 120 // attach netns to bridge within the container namespace, using reexec in a prestart hook 121 s.Hooks = &specs.Hooks{ 122 Prestart: []specs.Hook{{ 123 Path: filepath.Join("/proc", strconv.Itoa(os.Getpid()), "exe"), 124 Args: []string{"libnetwork-setkey", "-exec-root=" + iface.provider.Config().Daemon.ExecRoot, iface.sbx.ContainerID(), shortNetCtlrID}, 125 }}, 126 } 127 return nil 128 } 129 130 func (iface *lnInterface) Close() error { 131 <-iface.ready 132 if iface.sbx != nil { 133 go func() { 134 if err := iface.sbx.Delete(); err != nil { 135 logrus.WithError(err).Errorf("failed to delete builder network sandbox") 136 } 137 if err := os.RemoveAll(filepath.Join(iface.provider.Root, iface.sbx.ContainerID())); err != nil { 138 logrus.WithError(err).Errorf("failed to delete builder sandbox directory") 139 } 140 }() 141 } 142 return iface.err 143 } 144 145 func getDNSConfig(cfg config.DNSConfig) *oci.DNSConfig { 146 if cfg.DNS != nil || cfg.DNSSearch != nil || cfg.DNSOptions != nil { 147 return &oci.DNSConfig{ 148 Nameservers: cfg.DNS, 149 SearchDomains: cfg.DNSSearch, 150 Options: cfg.DNSOptions, 151 } 152 } 153 return nil 154 }