Merge pull request #3234 from crazy-max/bake-add-host

bake: extra-hosts support
This commit is contained in:
Tõnis Tiigi
2025-06-11 12:50:34 -07:00
committed by GitHub
7 changed files with 99 additions and 0 deletions
+36
View File
@@ -4,6 +4,7 @@ import (
"context"
"encoding"
"encoding/json"
"fmt"
"io"
"maps"
"os"
@@ -726,6 +727,7 @@ type Target struct {
Ulimits []string `json:"ulimits,omitempty" hcl:"ulimits,optional" cty:"ulimits"`
Call *string `json:"call,omitempty" hcl:"call,optional" cty:"call"`
Entitlements []string `json:"entitlements,omitempty" hcl:"entitlements,optional" cty:"entitlements"`
ExtraHosts map[string]*string `json:"extra-hosts,omitempty" hcl:"extra-hosts,optional" cty:"extra-hosts"`
// IMPORTANT: if you add more fields here, do not forget to update newOverrides/AddOverrides and docs/bake-reference.md.
// linked is a private field to mark a target used as a linked one
@@ -764,6 +766,14 @@ func (t *Target) MarshalJSON() ([]byte, error) {
}
}
tgt.ExtraHosts = maps.Clone(t.ExtraHosts)
for k, v := range t.ExtraHosts {
if v != nil {
escaped := esc(*v)
tgt.ExtraHosts[k] = &escaped
}
}
return json.Marshal(tgt)
}
@@ -894,6 +904,15 @@ func (t *Target) Merge(t2 *Target) {
if t2.Entitlements != nil { // merge
t.Entitlements = append(t.Entitlements, t2.Entitlements...)
}
for k, v := range t2.ExtraHosts {
if v == nil {
continue
}
if t.ExtraHosts == nil {
t.ExtraHosts = map[string]*string{}
}
t.ExtraHosts[k] = v
}
t.Inherits = append(t.Inherits, t2.Inherits...)
}
@@ -1082,6 +1101,14 @@ func (t *Target) AddOverrides(overrides map[string]Override, ent *EntitlementCon
return errors.Errorf("invalid value %s for boolean key load", value)
}
t.Outputs = setLoadOverride(t.Outputs, load)
case "extra-hosts":
if len(keys) != 2 {
return errors.Errorf("invalid format for extra-hosts, expecting extra-hosts.<hostname>=<ip>")
}
if t.ExtraHosts == nil {
t.ExtraHosts = map[string]*string{}
}
t.ExtraHosts[keys[1]] = &value
default:
return errors.Errorf("unknown key: %s", keys[0])
}
@@ -1404,6 +1431,14 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
}
}
var extraHosts []string
for k, v := range t.ExtraHosts {
if v == nil {
continue
}
extraHosts = append(extraHosts, fmt.Sprintf("%s=%s", k, *v))
}
bo := &build.Options{
Inputs: bi,
Tags: t.Tags,
@@ -1415,6 +1450,7 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
NetworkMode: networkMode,
Linked: t.linked,
ShmSize: *shmSize,
ExtraHosts: extraHosts,
}
platforms, err := platformutil.Parse(t.Platforms)
+4
View File
@@ -27,6 +27,9 @@ target "webDEP" {
no-cache = true
shm-size = "128m"
ulimits = ["nofile=1024:1024"]
extra-hosts = {
my_hostname = "8.8.8.8"
}
}
target "webapp" {
@@ -64,6 +67,7 @@ target "webapp" {
require.Equal(t, true, *m["webapp"].NoCache)
require.Equal(t, "128m", *m["webapp"].ShmSize)
require.Equal(t, []string{"nofile=1024:1024"}, m["webapp"].Ulimits)
require.Equal(t, map[string]*string{"my_hostname": ptrstr("8.8.8.8")}, m["webapp"].ExtraHosts)
require.Nil(t, m["webapp"].Pull)
require.Equal(t, 1, len(g))
+11
View File
@@ -122,6 +122,16 @@ func ParseCompose(cfgs []composetypes.ConfigFile, envs map[string]string) (*Conf
}
}
extraHosts := map[string]*string{}
if s.Build.ExtraHosts != nil {
for k, v := range s.Build.ExtraHosts {
for _, ip := range v {
vv := ip
extraHosts[k] = &vv
}
}
}
var ssh []*buildflags.SSH
for _, bkey := range s.Build.SSH {
sshkey := composeToBuildkitSSH(bkey)
@@ -180,6 +190,7 @@ func ParseCompose(cfgs []composetypes.ConfigFile, envs map[string]string) (*Conf
Secrets: secrets,
ShmSize: shmSize,
Ulimits: ulimits,
ExtraHosts: extraHosts,
}
if err = t.composeExtTarget(s.Build.Extensions); err != nil {
return nil, err
+4
View File
@@ -32,6 +32,9 @@ services:
- type=local,src=path/to/cache
cache_to:
- type=local,dest=path/to/cache
extra_hosts:
- "somehost:162.242.195.82"
- "myhostv6:::1"
ssh:
- key=/path/to/key
- default
@@ -76,6 +79,7 @@ secrets:
require.Equal(t, ptrstr("123"), c.Targets[1].Args["buildno"])
require.Equal(t, []string{"type=local,src=path/to/cache"}, stringify(c.Targets[1].CacheFrom))
require.Equal(t, []string{"type=local,dest=path/to/cache"}, stringify(c.Targets[1].CacheTo))
require.Equal(t, map[string]*string{"myhostv6": ptrstr("::1"), "somehost": ptrstr("162.242.195.82")}, c.Targets[1].ExtraHosts)
require.Equal(t, "none", *c.Targets[1].NetworkMode)
require.Equal(t, []string{"default", "key=/path/to/key"}, stringify(c.Targets[1].SSH))
require.Equal(t, []string{
+17
View File
@@ -227,6 +227,8 @@ The following table shows the complete list of attributes that you can assign to
| [`description`](#targetdescription) | String | Description of a target |
| [`dockerfile-inline`](#targetdockerfile-inline) | String | Inline Dockerfile string |
| [`dockerfile`](#targetdockerfile) | String | Dockerfile location |
| [`entitlements`](#targetentitlements) | List | Permissions that the build process requires to run |
| [`extra-hosts`](#targetextra-hosts) | List | Customs host-to-IP mapping |
| [`inherits`](#targetinherits) | List | Inherit attributes from other targets |
| [`labels`](#targetlabels) | Map | Metadata for images |
| [`matrix`](#targetmatrix) | Map | Define a set of variables that forks a target into multiple targets. |
@@ -583,6 +585,20 @@ target "integration-tests" {
Entitlements are enabled with a two-step process. First, a target must declare the entitlements it requires. Secondly, when invoking the `bake` command, the user must grant the entitlements by passing the `--allow` flag or confirming the entitlements when prompted in an interactive terminal. This is to ensure that the user is aware of the possibly insecure permissions they are granting to the build process.
### `target.extra-hosts`
Use the `extra-hosts` attribute to define customs host-to-IP mapping for the
target. This has the same effect as passing a [`--add-host`][add-host] flag to
the build command.
```hcl
target "default" {
extra-hosts = {
my_hostname = "8.8.8.8"
}
}
```
### `target.inherits`
A target can inherit attributes from other targets.
@@ -1422,6 +1438,7 @@ target "webapp-dev" {
<!-- external links -->
[add-host]: https://docs.docker.com/reference/cli/docker/buildx/build/#add-host
[attestations]: https://docs.docker.com/build/attestations/
[bake_stdlib]: https://github.com/docker/buildx/blob/master/bake/hclparser/stdlib.go
[build-arg]: https://docs.docker.com/reference/cli/docker/image/build/#build-arg
+1
View File
@@ -366,6 +366,7 @@ You can override the following fields:
* `context`
* `dockerfile`
* `entitlements`
* `extra-hosts`
* `labels`
* `load`
* `no-cache`
+26
View File
@@ -80,6 +80,7 @@ var bakeTests = []func(t *testing.T, sb integration.Sandbox){
testBakeCallMetadata,
testBakeMultiPlatform,
testBakeCheckCallOutput,
testBakeExtraHosts,
}
func testBakePrint(t *testing.T, sb integration.Sandbox) {
@@ -2162,6 +2163,31 @@ target "third" {
})
}
func testBakeExtraHosts(t *testing.T, sb integration.Sandbox) {
dockerfile := []byte(`
FROM busybox
RUN cat /etc/hosts | grep myhost | grep 1.2.3.4
`)
bakefile := []byte(`
target "default" {
extra-hosts = {
myhost = "1.2.3.4"
}
}
`)
dir := tmpdir(
t,
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
fstest.CreateFile("Dockerfile", dockerfile, 0600),
)
out, err := bakeCmd(
sb,
withDir(dir),
)
require.NoError(t, err, out)
}
func writeTempPrivateKey(fp string) error {
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {