bake: extra-hosts support
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -366,6 +366,7 @@ You can override the following fields:
|
||||
* `context`
|
||||
* `dockerfile`
|
||||
* `entitlements`
|
||||
* `extra-hosts`
|
||||
* `labels`
|
||||
* `load`
|
||||
* `no-cache`
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user