Files
moby/builder/builder-next/executor.go
Anthony Nandaa a9ec07a005 builder-next: add buildkit executor for wcow
WCOW support on Buildkit is now coming to maturity. As part
of making this generally available, integrating it in
Docker Engine is critical for it's adoption.

This commit adds the buildkit execuitor for WCOW as the
next-builder (backend) for building Windows containers.

This will be an opt-in feature, with the end users setting
DOCKER_BUILDKIT=1 environment variable to use it.

The integration tests bit has also been handled.
https://github.com/moby/buildkit/pull/5956,
BUILDKIT_REF has been set to `master` for now, so
that the tests can run successfully. On the next
release, we will revert this back to using releases.

Signed-off-by: Anthony Nandaa <profnandaa@gmail.com>
2025-05-20 00:14:09 +03:00

120 lines
2.7 KiB
Go

package buildkit
import (
"context"
"net"
"os"
"path/filepath"
"sync"
"github.com/containerd/log"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/libnetwork"
"github.com/moby/buildkit/executor/oci"
resourcestypes "github.com/moby/buildkit/executor/resources/types"
"github.com/moby/buildkit/identity"
"github.com/moby/buildkit/util/network"
)
type bridgeProvider struct {
*libnetwork.Controller
Root string
}
type lnInterface struct {
ep *libnetwork.Endpoint
sbx *libnetwork.Sandbox
sync.Once
err error
ready chan struct{}
provider *bridgeProvider
}
func (p *bridgeProvider) New(_ context.Context, _ string) (network.Namespace, error) {
n, err := p.NetworkByName(networkName)
if err != nil {
return nil, err
}
iface := &lnInterface{ready: make(chan struct{}), provider: p}
iface.Once.Do(func() {
go iface.init(p.Controller, n)
})
return iface, nil
}
func (p *bridgeProvider) Close() error {
return nil
}
func (iface *lnInterface) init(c *libnetwork.Controller, n *libnetwork.Network) {
defer close(iface.ready)
id := identity.NewID()
ep, err := n.CreateEndpoint(context.TODO(), id, libnetwork.CreateOptionDisableResolution())
if err != nil {
iface.err = err
return
}
sbx, err := c.NewSandbox(
context.TODO(),
id,
libnetwork.OptionUseExternalKey(),
libnetwork.OptionHostsPath(filepath.Join(iface.provider.Root, id, "hosts")),
libnetwork.OptionResolvConfPath(filepath.Join(iface.provider.Root, id, "resolv.conf")),
)
if err != nil {
iface.err = err
return
}
if err := ep.Join(context.TODO(), sbx); err != nil {
iface.err = err
return
}
iface.sbx = sbx
iface.ep = ep
}
// TODO(neersighted): Unstub Sample(), and collect data from the libnetwork Endpoint.
func (iface *lnInterface) Sample() (*resourcestypes.NetworkSample, error) {
return &resourcestypes.NetworkSample{}, nil
}
func (iface *lnInterface) Close() error {
<-iface.ready
if iface.sbx != nil {
go func() {
if err := iface.sbx.Delete(context.TODO()); err != nil {
log.G(context.TODO()).WithError(err).Errorf("failed to delete builder network sandbox")
}
if err := os.RemoveAll(filepath.Join(iface.provider.Root, iface.sbx.ContainerID())); err != nil {
log.G(context.TODO()).WithError(err).Errorf("failed to delete builder sandbox directory")
}
}()
}
return iface.err
}
func getDNSConfig(cfg config.DNSConfig) *oci.DNSConfig {
if cfg.DNS != nil || cfg.DNSSearch != nil || cfg.DNSOptions != nil {
return &oci.DNSConfig{
Nameservers: ipAddresses(cfg.DNS),
SearchDomains: cfg.DNSSearch,
Options: cfg.DNSOptions,
}
}
return nil
}
func ipAddresses(ips []net.IP) []string {
var addrs []string
for _, ip := range ips {
addrs = append(addrs, ip.String())
}
return addrs
}