Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bake: add network mode support to HCL and docs for network and entitlements #2671

Merged
merged 3 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions bake/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ func (c Config) newOverrides(v []string) (map[string]map[string]Override, error)
o := t[kk[1]]

switch keys[1] {
case "output", "cache-to", "cache-from", "tags", "platform", "secrets", "ssh", "attest", "entitlements":
case "output", "cache-to", "cache-from", "tags", "platform", "secrets", "ssh", "attest", "entitlements", "network":
if len(parts) == 2 {
o.ArrValue = append(o.ArrValue, parts[1])
}
Expand Down Expand Up @@ -704,7 +704,7 @@ type Target struct {
Outputs []string `json:"output,omitempty" hcl:"output,optional" cty:"output"`
Pull *bool `json:"pull,omitempty" hcl:"pull,optional" cty:"pull"`
NoCache *bool `json:"no-cache,omitempty" hcl:"no-cache,optional" cty:"no-cache"`
NetworkMode *string `json:"-" hcl:"-" cty:"-"`
NetworkMode *string `json:"network" hcl:"network" cty:"network"`
NoCacheFilter []string `json:"no-cache-filter,omitempty" hcl:"no-cache-filter,optional" cty:"no-cache-filter"`
ShmSize *string `json:"shm-size,omitempty" hcl:"shm-size,optional"`
Ulimits []string `json:"ulimits,omitempty" hcl:"ulimits,optional"`
Expand Down Expand Up @@ -914,6 +914,8 @@ func (t *Target) AddOverrides(overrides map[string]Override) error {
t.ShmSize = &value
case "ulimits":
t.Ulimits = o.ArrValue
case "network":
t.NetworkMode = &value
case "pull":
pull, err := strconv.ParseBool(value)
if err != nil {
Expand Down
64 changes: 63 additions & 1 deletion bake/bake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1757,7 +1757,7 @@ func TestHCLEntitlements(t *testing.T) {
require.Equal(t, entitlements.EntitlementNetworkHost, bo["app"].Allow[1])
}

func TestEntitlementsForNetHost(t *testing.T) {
func TestEntitlementsForNetHostCompose(t *testing.T) {
fp := File{
Name: "docker-bake.hcl",
Data: []byte(
Expand Down Expand Up @@ -1790,7 +1790,69 @@ func TestEntitlementsForNetHost(t *testing.T) {
require.Contains(t, m, "app")
require.Len(t, m["app"].Entitlements, 1)
require.Equal(t, "network.host", m["app"].Entitlements[0])
require.Equal(t, "host", *m["app"].NetworkMode)

require.Len(t, bo["app"].Allow, 1)
require.Equal(t, entitlements.EntitlementNetworkHost, bo["app"].Allow[0])
require.Equal(t, "host", bo["app"].NetworkMode)
}

func TestEntitlementsForNetHost(t *testing.T) {
fp := File{
Name: "docker-bake.hcl",
Data: []byte(
`target "app" {
dockerfile = "app.Dockerfile"
network = "host"
}`),
}

ctx := context.TODO()
m, g, err := ReadTargets(ctx, []File{fp}, []string{"app"}, nil, nil)
require.NoError(t, err)

bo, err := TargetsToBuildOpt(m, &Input{})
require.NoError(t, err)

require.Equal(t, 1, len(g))
require.Equal(t, []string{"app"}, g["default"].Targets)

require.Equal(t, 1, len(m))
require.Contains(t, m, "app")
require.Len(t, m["app"].Entitlements, 1)
require.Equal(t, "network.host", m["app"].Entitlements[0])
require.Equal(t, "host", *m["app"].NetworkMode)

require.Len(t, bo["app"].Allow, 1)
require.Equal(t, entitlements.EntitlementNetworkHost, bo["app"].Allow[0])
require.Equal(t, "host", bo["app"].NetworkMode)
}

func TestNetNone(t *testing.T) {
fp := File{
Name: "docker-bake.hcl",
Data: []byte(
`target "app" {
dockerfile = "app.Dockerfile"
network = "none"
}`),
}

ctx := context.TODO()
m, g, err := ReadTargets(ctx, []File{fp}, []string{"app"}, nil, nil)
require.NoError(t, err)

bo, err := TargetsToBuildOpt(m, &Input{})
require.NoError(t, err)

require.Equal(t, 1, len(g))
require.Equal(t, []string{"app"}, g["default"].Targets)

require.Equal(t, 1, len(m))
require.Contains(t, m, "app")
require.Len(t, m["app"].Entitlements, 0)
require.Equal(t, "none", *m["app"].NetworkMode)

require.Len(t, bo["app"].Allow, 0)
require.Equal(t, "none", bo["app"].NetworkMode)
}
40 changes: 40 additions & 0 deletions docs/bake-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,25 @@ $ docker buildx bake --print -f - <<< 'target "default" {}'
}
```

### `target.entitlements`

Entitlements are permissions that the build process requires to run.

Currently supported entitlements are:

- `network.host`: Allows the build to use commands that access the host network. In Dockerfile, use [`RUN --network=host`](https://docs.docker.com/reference/dockerfile/#run---networkhost) to run a command with host network enabled.

- `security.insecure`: Allows the build to run commands in privileged containers that are not limited by the default security sandbox. Such container may potentially access and modify system resources. In Dockerfile, use [`RUN --security=insecure`](https://docs.docker.com/reference/dockerfile/#run---security) to run a command in a privileged container.

```hcl
target "integration-tests" {
# this target requires privileged containers to run nested containers
entitlements = ["security.insecure"]
}
```

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.inherits`

A target can inherit attributes from other targets.
Expand Down Expand Up @@ -749,6 +768,27 @@ target "app" {
}
```

### `target.network`

Specify the network mode for the whole build request. This will override the default network mode
for all the `RUN` instructions in the Dockerfile. Accepted values are `default`, `host`, and `none`.

Usually, a better approach to set the network mode for your build steps is to instead use `RUN --network=<value>`
in your Dockerfile. This way, you can set the network mode for individual build steps and everyone building
the Dockerfile gets consistent behavior without needing to pass additional flags to the build command.

If you set network mode to `host` in your Bake file, you must also grant `network.host` entitlement when
invoking the `bake` command. This is because `host` network mode requires elevated privileges and can be a security risk.
You can pass `--allow=network.host` to the `docker buildx bake` command to grant the entitlement, or you can
confirm the entitlement when prompted if you are using an interactive terminal.

```hcl
target "app" {
# make sure this build does not access internet
network = "none"
}
```

### `target.no-cache-filter`

Don't use build cache for the specified stages.
Expand Down