diff --git a/build/build.go b/build/build.go index 21b502a07fad..d451117261dd 100644 --- a/build/build.go +++ b/build/build.go @@ -641,8 +641,14 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op return nil, nil, errors.Errorf("network mode %q not supported by buildkit - you can define a custom network for your builder using the network driver-opt in buildx create", opt.NetworkMode) } + // retrieve host gateway IP from node driver + hostGatewayIP, err := nodeDriver.HostGatewayIP(ctx) + if err != nil { + return nil, nil, err + } + // setup extrahosts - extraHosts, err := toBuildkitExtraHosts(opt.ExtraHosts, nodeDriver.IsMobyDriver()) + extraHosts, err := toBuildkitExtraHosts(opt.ExtraHosts, hostGatewayIP) if err != nil { return nil, nil, err } diff --git a/build/utils.go b/build/utils.go index 03a85ca4b4a0..b617259b9969 100644 --- a/build/utils.go +++ b/build/utils.go @@ -57,7 +57,7 @@ func isArchive(header []byte) bool { } // toBuildkitExtraHosts converts hosts from docker key:value format to buildkit's csv format -func toBuildkitExtraHosts(inp []string, mobyDriver bool) (string, error) { +func toBuildkitExtraHosts(inp []string, hgip net.IP) (string, error) { if len(inp) == 0 { return "", nil } @@ -67,11 +67,16 @@ func toBuildkitExtraHosts(inp []string, mobyDriver bool) (string, error) { if !ok || host == "" || ip == "" { return "", errors.Errorf("invalid host %s", h) } - // Skip IP address validation for "host-gateway" string with moby driver - if !mobyDriver || ip != mobyHostGatewayName { - if net.ParseIP(ip) == nil { - return "", errors.Errorf("invalid host %s", h) + // If the IP Address is a "host-gateway", replace this value with the + // IP address provided by the worker's label. + if ip == mobyHostGatewayName { + if hgip == nil { + return "", errors.Errorf("unable to derive the IP value for host-gateway") } + ip = hgip.String() + } + if net.ParseIP(ip) == nil { + return "", errors.Errorf("invalid host %s", h) } hosts = append(hosts, host+"="+ip) } diff --git a/driver/manager.go b/driver/manager.go index 657e5094db3d..44b548d7e94d 100644 --- a/driver/manager.go +++ b/driver/manager.go @@ -2,17 +2,17 @@ package driver import ( "context" + "net" "os" "sort" "strings" "sync" - "k8s.io/client-go/rest" - dockerclient "github.com/docker/docker/client" "github.com/moby/buildkit/client" specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" + "k8s.io/client-go/rest" ) type Factory interface { @@ -154,6 +154,9 @@ type DriverHandle struct { features map[Feature]bool historyAPISupportedOnce sync.Once historyAPISupported bool + hostGatewayIPOnce sync.Once + hostGatewayIP net.IP + hostGatewayIPErr error } func (d *DriverHandle) Client(ctx context.Context) (*client.Client, error) { @@ -178,3 +181,34 @@ func (d *DriverHandle) HistoryAPISupported(ctx context.Context) bool { }) return d.historyAPISupported } + +func (d *DriverHandle) HostGatewayIP(ctx context.Context) (net.IP, error) { + d.hostGatewayIPOnce.Do(func() { + if !d.Driver.IsMobyDriver() { + return + } + c, err := d.Client(ctx) + if err != nil { + d.hostGatewayIPErr = err + return + } + workers, err := c.ListWorkers(ctx) + if err != nil { + d.hostGatewayIPErr = err + return + } + if len(workers) == 0 { + return + } + // TODO: Use HostGatewayIP const from github.com/docker/docker/builder/builder-next/worker/label pkg + if v, ok := workers[0].Labels["org.mobyproject.buildkit.worker.hostgatewayip"]; ok && v != "" { + ip := net.ParseIP(v) + if ip == nil { + d.hostGatewayIPErr = errors.Wrapf(err, "failed to parse host gateway IP: %s", v) + return + } + d.hostGatewayIP = ip + } + }) + return d.hostGatewayIP, d.hostGatewayIPErr +}