From 83d5c0c61bbb4b9fd68a9495c30c7a7167fadb93 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 3 Sep 2024 18:18:59 -0700 Subject: [PATCH 1/3] bake: allow setting networkmode in HCL/JSON Signed-off-by: Tonis Tiigi --- bake/bake.go | 6 +++-- bake/bake_test.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/bake/bake.go b/bake/bake.go index fc707131d81..9ed1dfd8e15 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -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]) } @@ -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"` @@ -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 { diff --git a/bake/bake_test.go b/bake/bake_test.go index 185b528556d..bb95499a76a 100644 --- a/bake/bake_test.go +++ b/bake/bake_test.go @@ -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( @@ -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) } From fa1d19bb1efad6bf66771ca71fd21348521e8a24 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 3 Sep 2024 18:19:35 -0700 Subject: [PATCH 2/3] docs: add docs for bake entitlements config Signed-off-by: Tonis Tiigi --- docs/bake-reference.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/bake-reference.md b/docs/bake-reference.md index 9a76e04d465..7e2a0ddf1d3 100644 --- a/docs/bake-reference.md +++ b/docs/bake-reference.md @@ -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. From f0f8876902d2c3c81418291799ed2f80db0dd575 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 3 Sep 2024 18:20:11 -0700 Subject: [PATCH 3/3] docs: add docs for bake network mode config Signed-off-by: Tonis Tiigi --- docs/bake-reference.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/bake-reference.md b/docs/bake-reference.md index 7e2a0ddf1d3..542c50a589c 100644 --- a/docs/bake-reference.md +++ b/docs/bake-reference.md @@ -768,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=` +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.