Skip to content

Commit b514ed4

Browse files
committed
bake: extra-hosts support
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
1 parent 52b5d08 commit b514ed4

7 files changed

Lines changed: 99 additions & 0 deletions

File tree

bake/bake.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding"
66
"encoding/json"
7+
"fmt"
78
"io"
89
"maps"
910
"os"
@@ -726,6 +727,7 @@ type Target struct {
726727
Ulimits []string `json:"ulimits,omitempty" hcl:"ulimits,optional" cty:"ulimits"`
727728
Call *string `json:"call,omitempty" hcl:"call,optional" cty:"call"`
728729
Entitlements []string `json:"entitlements,omitempty" hcl:"entitlements,optional" cty:"entitlements"`
730+
ExtraHosts map[string]*string `json:"extra-hosts,omitempty" hcl:"extra-hosts,optional" cty:"extra-hosts"`
729731
// IMPORTANT: if you add more fields here, do not forget to update newOverrides/AddOverrides and docs/bake-reference.md.
730732

731733
// linked is a private field to mark a target used as a linked one
@@ -764,6 +766,14 @@ func (t *Target) MarshalJSON() ([]byte, error) {
764766
}
765767
}
766768

769+
tgt.ExtraHosts = maps.Clone(t.ExtraHosts)
770+
for k, v := range t.ExtraHosts {
771+
if v != nil {
772+
escaped := esc(*v)
773+
tgt.ExtraHosts[k] = &escaped
774+
}
775+
}
776+
767777
return json.Marshal(tgt)
768778
}
769779

@@ -894,6 +904,15 @@ func (t *Target) Merge(t2 *Target) {
894904
if t2.Entitlements != nil { // merge
895905
t.Entitlements = append(t.Entitlements, t2.Entitlements...)
896906
}
907+
for k, v := range t2.ExtraHosts {
908+
if v == nil {
909+
continue
910+
}
911+
if t.ExtraHosts == nil {
912+
t.ExtraHosts = map[string]*string{}
913+
}
914+
t.ExtraHosts[k] = v
915+
}
897916
t.Inherits = append(t.Inherits, t2.Inherits...)
898917
}
899918

@@ -1082,6 +1101,14 @@ func (t *Target) AddOverrides(overrides map[string]Override, ent *EntitlementCon
10821101
return errors.Errorf("invalid value %s for boolean key load", value)
10831102
}
10841103
t.Outputs = setLoadOverride(t.Outputs, load)
1104+
case "extra-hosts":
1105+
if len(keys) != 2 {
1106+
return errors.Errorf("invalid format for extra-hosts, expecting extra-hosts.<hostname>=<ip>")
1107+
}
1108+
if t.ExtraHosts == nil {
1109+
t.ExtraHosts = map[string]*string{}
1110+
}
1111+
t.ExtraHosts[keys[1]] = &value
10851112
default:
10861113
return errors.Errorf("unknown key: %s", keys[0])
10871114
}
@@ -1404,6 +1431,14 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
14041431
}
14051432
}
14061433

1434+
var extraHosts []string
1435+
for k, v := range t.ExtraHosts {
1436+
if v == nil {
1437+
continue
1438+
}
1439+
extraHosts = append(extraHosts, fmt.Sprintf("%s=%s", k, *v))
1440+
}
1441+
14071442
bo := &build.Options{
14081443
Inputs: bi,
14091444
Tags: t.Tags,
@@ -1415,6 +1450,7 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
14151450
NetworkMode: networkMode,
14161451
Linked: t.linked,
14171452
ShmSize: *shmSize,
1453+
ExtraHosts: extraHosts,
14181454
}
14191455

14201456
platforms, err := platformutil.Parse(t.Platforms)

bake/bake_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ target "webDEP" {
2727
no-cache = true
2828
shm-size = "128m"
2929
ulimits = ["nofile=1024:1024"]
30+
extra-hosts = {
31+
my_hostname = "8.8.8.8"
32+
}
3033
}
3134
3235
target "webapp" {
@@ -64,6 +67,7 @@ target "webapp" {
6467
require.Equal(t, true, *m["webapp"].NoCache)
6568
require.Equal(t, "128m", *m["webapp"].ShmSize)
6669
require.Equal(t, []string{"nofile=1024:1024"}, m["webapp"].Ulimits)
70+
require.Equal(t, map[string]*string{"my_hostname": ptrstr("8.8.8.8")}, m["webapp"].ExtraHosts)
6771
require.Nil(t, m["webapp"].Pull)
6872

6973
require.Equal(t, 1, len(g))

bake/compose.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,16 @@ func ParseCompose(cfgs []composetypes.ConfigFile, envs map[string]string) (*Conf
122122
}
123123
}
124124

125+
extraHosts := map[string]*string{}
126+
if s.Build.ExtraHosts != nil {
127+
for k, v := range s.Build.ExtraHosts {
128+
for _, ip := range v {
129+
vv := ip
130+
extraHosts[k] = &vv
131+
}
132+
}
133+
}
134+
125135
var ssh []*buildflags.SSH
126136
for _, bkey := range s.Build.SSH {
127137
sshkey := composeToBuildkitSSH(bkey)
@@ -180,6 +190,7 @@ func ParseCompose(cfgs []composetypes.ConfigFile, envs map[string]string) (*Conf
180190
Secrets: secrets,
181191
ShmSize: shmSize,
182192
Ulimits: ulimits,
193+
ExtraHosts: extraHosts,
183194
}
184195
if err = t.composeExtTarget(s.Build.Extensions); err != nil {
185196
return nil, err

bake/compose_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ services:
3232
- type=local,src=path/to/cache
3333
cache_to:
3434
- type=local,dest=path/to/cache
35+
extra_hosts:
36+
- "somehost:162.242.195.82"
37+
- "myhostv6:::1"
3538
ssh:
3639
- key=/path/to/key
3740
- default
@@ -76,6 +79,7 @@ secrets:
7679
require.Equal(t, ptrstr("123"), c.Targets[1].Args["buildno"])
7780
require.Equal(t, []string{"type=local,src=path/to/cache"}, stringify(c.Targets[1].CacheFrom))
7881
require.Equal(t, []string{"type=local,dest=path/to/cache"}, stringify(c.Targets[1].CacheTo))
82+
require.Equal(t, map[string]*string{"myhostv6": ptrstr("::1"), "somehost": ptrstr("162.242.195.82")}, c.Targets[1].ExtraHosts)
7983
require.Equal(t, "none", *c.Targets[1].NetworkMode)
8084
require.Equal(t, []string{"default", "key=/path/to/key"}, stringify(c.Targets[1].SSH))
8185
require.Equal(t, []string{

docs/bake-reference.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ The following table shows the complete list of attributes that you can assign to
227227
| [`description`](#targetdescription) | String | Description of a target |
228228
| [`dockerfile-inline`](#targetdockerfile-inline) | String | Inline Dockerfile string |
229229
| [`dockerfile`](#targetdockerfile) | String | Dockerfile location |
230+
| [`entitlements`](#targetentitlements) | List | Permissions that the build process requires to run |
231+
| [`extra-hosts`](#targetextra-hosts) | List | Customs host-to-IP mapping |
230232
| [`inherits`](#targetinherits) | List | Inherit attributes from other targets |
231233
| [`labels`](#targetlabels) | Map | Metadata for images |
232234
| [`matrix`](#targetmatrix) | Map | Define a set of variables that forks a target into multiple targets. |
@@ -583,6 +585,20 @@ target "integration-tests" {
583585

584586
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.
585587

588+
### `target.extra-hosts`
589+
590+
Use the `extra-hosts` attribute to define customs host-to-IP mapping for the
591+
target. This has the same effect as passing a [`--add-host`][add-host] flag to
592+
the build command.
593+
594+
```hcl
595+
target "default" {
596+
extra-hosts = {
597+
my_hostname = "8.8.8.8"
598+
}
599+
}
600+
```
601+
586602
### `target.inherits`
587603

588604
A target can inherit attributes from other targets.
@@ -1422,6 +1438,7 @@ target "webapp-dev" {
14221438
14231439
<!-- external links -->
14241440

1441+
[add-host]: https://docs.docker.com/reference/cli/docker/buildx/build/#add-host
14251442
[attestations]: https://docs.docker.com/build/attestations/
14261443
[bake_stdlib]: https://github.com/docker/buildx/blob/master/bake/hclparser/stdlib.go
14271444
[build-arg]: https://docs.docker.com/reference/cli/docker/image/build/#build-arg

docs/reference/buildx_bake.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ You can override the following fields:
366366
* `context`
367367
* `dockerfile`
368368
* `entitlements`
369+
* `extra-hosts`
369370
* `labels`
370371
* `load`
371372
* `no-cache`

tests/bake.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ var bakeTests = []func(t *testing.T, sb integration.Sandbox){
8080
testBakeCallMetadata,
8181
testBakeMultiPlatform,
8282
testBakeCheckCallOutput,
83+
testBakeExtraHosts,
8384
}
8485

8586
func testBakePrint(t *testing.T, sb integration.Sandbox) {
@@ -2162,6 +2163,31 @@ target "third" {
21622163
})
21632164
}
21642165

2166+
func testBakeExtraHosts(t *testing.T, sb integration.Sandbox) {
2167+
dockerfile := []byte(`
2168+
FROM busybox
2169+
RUN cat /etc/hosts | grep myhost | grep 1.2.3.4
2170+
`)
2171+
bakefile := []byte(`
2172+
target "default" {
2173+
extra-hosts = {
2174+
myhost = "1.2.3.4"
2175+
}
2176+
}
2177+
`)
2178+
dir := tmpdir(
2179+
t,
2180+
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
2181+
fstest.CreateFile("Dockerfile", dockerfile, 0600),
2182+
)
2183+
2184+
out, err := bakeCmd(
2185+
sb,
2186+
withDir(dir),
2187+
)
2188+
require.NoError(t, err, out)
2189+
}
2190+
21652191
func writeTempPrivateKey(fp string) error {
21662192
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
21672193
if err != nil {

0 commit comments

Comments
 (0)