From 0c296fe85784944c57b5c2b51937132205453550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B5nis=20Tiigi?= Date: Fri, 14 Feb 2025 11:31:51 +0100 Subject: [PATCH] support for device entitlement in build and bake Allow access to CDI Devices in Buildkit v0.20.0+ for devices that are not automatically allowed to be used by everyone in BuildKit configuration. Signed-off-by: Tonis Tiigi Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- bake/bake.go | 5 +- bake/bake_test.go | 8 +- bake/entitlements.go | 62 +++++++++- bake/entitlements_test.go | 20 ++-- build/build.go | 3 +- build/opt.go | 2 +- commands/build.go | 2 +- docs/reference/buildx_build.md | 2 +- docs/reference/buildx_debug_build.md | 2 +- go.mod | 2 + go.sum | 4 +- util/buildflags/entitlements.go | 17 ++- .../github.com/moby/buildkit/client/solve.go | 14 +-- .../buildkit/cmd/buildkitd/config/config.go | 5 +- .../util/entitlements/entitlements.go | 109 ++++++++++++++++-- vendor/modules.txt | 3 +- 16 files changed, 205 insertions(+), 55 deletions(-) diff --git a/bake/bake.go b/bake/bake.go index 41e1ec5c3b1e..cde0e3cd0279 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -27,7 +27,6 @@ import ( "github.com/moby/buildkit/client" "github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/session/auth/authprovider" - "github.com/moby/buildkit/util/entitlements" "github.com/pkg/errors" "github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty/convert" @@ -1434,9 +1433,7 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) { } bo.Ulimits = ulimits - for _, ent := range t.Entitlements { - bo.Allow = append(bo.Allow, entitlements.Entitlement(ent)) - } + bo.Allow = append(bo.Allow, t.Entitlements...) return bo, nil } diff --git a/bake/bake_test.go b/bake/bake_test.go index f1f0a9f28a74..afd5c99ee40b 100644 --- a/bake/bake_test.go +++ b/bake/bake_test.go @@ -1806,8 +1806,8 @@ func TestHCLEntitlements(t *testing.T) { require.Equal(t, "network.host", m["app"].Entitlements[1]) require.Len(t, bo["app"].Allow, 2) - require.Equal(t, entitlements.EntitlementSecurityInsecure, bo["app"].Allow[0]) - require.Equal(t, entitlements.EntitlementNetworkHost, bo["app"].Allow[1]) + require.Equal(t, entitlements.EntitlementSecurityInsecure.String(), bo["app"].Allow[0]) + require.Equal(t, entitlements.EntitlementNetworkHost.String(), bo["app"].Allow[1]) } func TestEntitlementsForNetHostCompose(t *testing.T) { @@ -1846,7 +1846,7 @@ func TestEntitlementsForNetHostCompose(t *testing.T) { 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, entitlements.EntitlementNetworkHost.String(), bo["app"].Allow[0]) require.Equal(t, "host", bo["app"].NetworkMode) } @@ -1877,7 +1877,7 @@ func TestEntitlementsForNetHost(t *testing.T) { 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, entitlements.EntitlementNetworkHost.String(), bo["app"].Allow[0]) require.Equal(t, "host", bo["app"].NetworkMode) } diff --git a/bake/entitlements.go b/bake/entitlements.go index 4a1d0b03711d..389d0dd9772f 100644 --- a/bake/entitlements.go +++ b/bake/entitlements.go @@ -20,6 +20,7 @@ import ( "github.com/moby/buildkit/util/entitlements" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "github.com/tonistiigi/go-csvvalue" ) type EntitlementKey string @@ -27,6 +28,7 @@ type EntitlementKey string const ( EntitlementKeyNetworkHost EntitlementKey = "network.host" EntitlementKeySecurityInsecure EntitlementKey = "security.insecure" + EntitlementKeyDevice EntitlementKey = "device" EntitlementKeyFSRead EntitlementKey = "fs.read" EntitlementKeyFSWrite EntitlementKey = "fs.write" EntitlementKeyFS EntitlementKey = "fs" @@ -39,6 +41,7 @@ const ( type EntitlementConf struct { NetworkHost bool SecurityInsecure bool + Devices *EntitlementsDevicesConf FSRead []string FSWrite []string ImagePush []string @@ -46,6 +49,11 @@ type EntitlementConf struct { SSH bool } +type EntitlementsDevicesConf struct { + All bool + Devices map[string]struct{} +} + func ParseEntitlements(in []string) (EntitlementConf, error) { var conf EntitlementConf for _, e := range in { @@ -59,6 +67,22 @@ func ParseEntitlements(in []string) (EntitlementConf, error) { default: k, v, _ := strings.Cut(e, "=") switch k { + case string(EntitlementKeyDevice): + if v == "" { + conf.Devices = &EntitlementsDevicesConf{All: true} + continue + } + fields, err := csvvalue.Fields(v, nil) + if err != nil { + return EntitlementConf{}, errors.Wrapf(err, "failed to parse device entitlement %q", v) + } + if conf.Devices == nil { + conf.Devices = &EntitlementsDevicesConf{} + } + if conf.Devices.Devices == nil { + conf.Devices.Devices = make(map[string]struct{}, 0) + } + conf.Devices.Devices[fields[0]] = struct{}{} case string(EntitlementKeyFSRead): conf.FSRead = append(conf.FSRead, v) case string(EntitlementKeyFSWrite): @@ -95,12 +119,34 @@ func (c EntitlementConf) Validate(m map[string]build.Options) (EntitlementConf, func (c EntitlementConf) check(bo build.Options, expected *EntitlementConf) error { for _, e := range bo.Allow { + k, rest, _ := strings.Cut(e, "=") + switch k { + case entitlements.EntitlementDevice.String(): + if rest == "" { + if c.Devices == nil || !c.Devices.All { + expected.Devices = &EntitlementsDevicesConf{All: true} + } + continue + } + fields, err := csvvalue.Fields(rest, nil) + if err != nil { + return errors.Wrapf(err, "failed to parse device entitlement %q", rest) + } + if expected.Devices == nil { + expected.Devices = &EntitlementsDevicesConf{} + } + if expected.Devices.Devices == nil { + expected.Devices.Devices = make(map[string]struct{}, 0) + } + expected.Devices.Devices[fields[0]] = struct{}{} + } + switch e { - case entitlements.EntitlementNetworkHost: + case entitlements.EntitlementNetworkHost.String(): if !c.NetworkHost { expected.NetworkHost = true } - case entitlements.EntitlementSecurityInsecure: + case entitlements.EntitlementSecurityInsecure.String(): if !c.SecurityInsecure { expected.SecurityInsecure = true } @@ -187,6 +233,18 @@ func (c EntitlementConf) Prompt(ctx context.Context, isRemote bool, out io.Write flags = append(flags, string(EntitlementKeySecurityInsecure)) } + if c.Devices != nil { + if c.Devices.All { + msgs = append(msgs, " - Access to CDI devices") + flags = append(flags, string(EntitlementKeyDevice)) + } else { + for d := range c.Devices.Devices { + msgs = append(msgs, fmt.Sprintf(" - Access to device %s", d)) + flags = append(flags, string(EntitlementKeyDevice)+"="+d) + } + } + } + if c.SSH { msgsFS = append(msgsFS, " - Forwarding default SSH agent socket") flagsFS = append(flagsFS, string(EntitlementKeySSH)) diff --git a/bake/entitlements_test.go b/bake/entitlements_test.go index df9c5f347a07..2bd2a5ba87c6 100644 --- a/bake/entitlements_test.go +++ b/bake/entitlements_test.go @@ -208,8 +208,8 @@ func TestValidateEntitlements(t *testing.T) { { name: "NetworkHostMissing", opt: build.Options{ - Allow: []entitlements.Entitlement{ - entitlements.EntitlementNetworkHost, + Allow: []string{ + entitlements.EntitlementNetworkHost.String(), }, }, expected: EntitlementConf{ @@ -223,8 +223,8 @@ func TestValidateEntitlements(t *testing.T) { NetworkHost: true, }, opt: build.Options{ - Allow: []entitlements.Entitlement{ - entitlements.EntitlementNetworkHost, + Allow: []string{ + entitlements.EntitlementNetworkHost.String(), }, }, expected: EntitlementConf{ @@ -234,9 +234,9 @@ func TestValidateEntitlements(t *testing.T) { { name: "SecurityAndNetworkHostMissing", opt: build.Options{ - Allow: []entitlements.Entitlement{ - entitlements.EntitlementNetworkHost, - entitlements.EntitlementSecurityInsecure, + Allow: []string{ + entitlements.EntitlementNetworkHost.String(), + entitlements.EntitlementSecurityInsecure.String(), }, }, expected: EntitlementConf{ @@ -251,9 +251,9 @@ func TestValidateEntitlements(t *testing.T) { NetworkHost: true, }, opt: build.Options{ - Allow: []entitlements.Entitlement{ - entitlements.EntitlementNetworkHost, - entitlements.EntitlementSecurityInsecure, + Allow: []string{ + entitlements.EntitlementNetworkHost.String(), + entitlements.EntitlementSecurityInsecure.String(), }, }, expected: EntitlementConf{ diff --git a/build/build.go b/build/build.go index a51e925a0940..f0c24fc8f412 100644 --- a/build/build.go +++ b/build/build.go @@ -40,7 +40,6 @@ import ( "github.com/moby/buildkit/solver/errdefs" "github.com/moby/buildkit/solver/pb" spb "github.com/moby/buildkit/sourcepolicy/pb" - "github.com/moby/buildkit/util/entitlements" "github.com/moby/buildkit/util/progress/progresswriter" "github.com/moby/buildkit/util/tracing" "github.com/opencontainers/go-digest" @@ -63,7 +62,7 @@ type Options struct { Inputs Inputs Ref string - Allow []entitlements.Entitlement + Allow []string Attests map[string]*string BuildArgs map[string]string CacheFrom []client.CacheOptionsEntry diff --git a/build/opt.go b/build/opt.go index 931c586ca5d9..af4986e09ca3 100644 --- a/build/opt.go +++ b/build/opt.go @@ -318,7 +318,7 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt *O switch opt.NetworkMode { case "host": so.FrontendAttrs["force-network-mode"] = opt.NetworkMode - so.AllowedEntitlements = append(so.AllowedEntitlements, entitlements.EntitlementNetworkHost) + so.AllowedEntitlements = append(so.AllowedEntitlements, entitlements.EntitlementNetworkHost.String()) case "none": so.FrontendAttrs["force-network-mode"] = opt.NetworkMode case "", "default": diff --git a/commands/build.go b/commands/build.go index f0bd44b791b9..5d90afd05f8a 100644 --- a/commands/build.go +++ b/commands/build.go @@ -593,7 +593,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions, debugConfig *debug.D flags.StringSliceVar(&options.extraHosts, "add-host", []string{}, `Add a custom host-to-IP mapping (format: "host:ip")`) - flags.StringSliceVar(&options.allow, "allow", []string{}, `Allow extra privileged entitlement (e.g., "network.host", "security.insecure")`) + flags.StringArrayVar(&options.allow, "allow", []string{}, `Allow extra privileged entitlement (e.g., "network.host", "security.insecure")`) flags.StringArrayVarP(&options.annotations, "annotation", "", []string{}, "Add annotation to the image") diff --git a/docs/reference/buildx_build.md b/docs/reference/buildx_build.md index 215eff9aace4..3765dddcc6a2 100644 --- a/docs/reference/buildx_build.md +++ b/docs/reference/buildx_build.md @@ -16,7 +16,7 @@ Start a build | Name | Type | Default | Description | |:----------------------------------------|:--------------|:----------|:-------------------------------------------------------------------------------------------------------------| | [`--add-host`](#add-host) | `stringSlice` | | Add a custom host-to-IP mapping (format: `host:ip`) | -| [`--allow`](#allow) | `stringSlice` | | Allow extra privileged entitlement (e.g., `network.host`, `security.insecure`) | +| [`--allow`](#allow) | `stringArray` | | Allow extra privileged entitlement (e.g., `network.host`, `security.insecure`) | | [`--annotation`](#annotation) | `stringArray` | | Add annotation to the image | | [`--attest`](#attest) | `stringArray` | | Attestation parameters (format: `type=sbom,generator=image`) | | [`--build-arg`](#build-arg) | `stringArray` | | Set build-time variables | diff --git a/docs/reference/buildx_debug_build.md b/docs/reference/buildx_debug_build.md index 66340169509f..609ca1503bfc 100644 --- a/docs/reference/buildx_debug_build.md +++ b/docs/reference/buildx_debug_build.md @@ -12,7 +12,7 @@ Start a build | Name | Type | Default | Description | |:--------------------|:--------------|:----------|:-------------------------------------------------------------------------------------------------------------| | `--add-host` | `stringSlice` | | Add a custom host-to-IP mapping (format: `host:ip`) | -| `--allow` | `stringSlice` | | Allow extra privileged entitlement (e.g., `network.host`, `security.insecure`) | +| `--allow` | `stringArray` | | Allow extra privileged entitlement (e.g., `network.host`, `security.insecure`) | | `--annotation` | `stringArray` | | Add annotation to the image | | `--attest` | `stringArray` | | Attestation parameters (format: `type=sbom,generator=image`) | | `--build-arg` | `stringArray` | | Set build-time variables | diff --git a/go.mod b/go.mod index abf8975590b9..0c460dfb2e5d 100644 --- a/go.mod +++ b/go.mod @@ -194,3 +194,5 @@ exclude ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 ) + +replace github.com/moby/buildkit => github.com/tonistiigi/buildkit v0.10.0-rc2.0.20250214043642-c9e788c50beb diff --git a/go.sum b/go.sum index 09764e31bc05..8ab18dbfc7b8 100644 --- a/go.sum +++ b/go.sum @@ -297,8 +297,6 @@ github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/z github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/buildkit v0.20.0-rc2 h1:QjACghvG0pSAp7dk9aQMYWioDEOljDWyyoUjyg35qfg= -github.com/moby/buildkit v0.20.0-rc2/go.mod h1:kMXf90l/f3zygRK8bYbyetfyzoJYntb6Bpi2VsLfXgQ= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= @@ -441,6 +439,8 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtse github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c= github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= +github.com/tonistiigi/buildkit v0.10.0-rc2.0.20250214043642-c9e788c50beb h1:uk0jspTfKpsaTGWqWO/MHWGQy4atLlOeJ6zjL7V1OeI= +github.com/tonistiigi/buildkit v0.10.0-rc2.0.20250214043642-c9e788c50beb/go.mod h1:kMXf90l/f3zygRK8bYbyetfyzoJYntb6Bpi2VsLfXgQ= github.com/tonistiigi/dchapes-mode v0.0.0-20241001053921-ca0759fec205 h1:eUk79E1w8yMtXeHSzjKorxuC8qJOnyXQnLaJehxpJaI= github.com/tonistiigi/dchapes-mode v0.0.0-20241001053921-ca0759fec205/go.mod h1:3Iuxbr0P7D3zUzBMAZB+ois3h/et0shEz0qApgHYGpY= github.com/tonistiigi/fsutil v0.0.0-20250113203817-b14e27f4135a h1:EfGw4G0x/8qXWgtcZ6KVaPS+wpWOQMaypczzP8ojkMY= diff --git a/util/buildflags/entitlements.go b/util/buildflags/entitlements.go index 970739bc45df..0f655295c6cf 100644 --- a/util/buildflags/entitlements.go +++ b/util/buildflags/entitlements.go @@ -1,19 +1,24 @@ package buildflags -import "github.com/moby/buildkit/util/entitlements" +import ( + "log" -func ParseEntitlements(in []string) ([]entitlements.Entitlement, error) { - out := make([]entitlements.Entitlement, 0, len(in)) + "github.com/moby/buildkit/util/entitlements" +) + +func ParseEntitlements(in []string) ([]string, error) { + out := make([]string, 0, len(in)) + log.Printf("in: %#v", in) for _, v := range in { if v == "" { continue } - e, err := entitlements.Parse(v) - if err != nil { + if _, _, err := entitlements.Parse(v); err != nil { return nil, err } - out = append(out, e) + out = append(out, v) } + log.Printf("Parsed entitlements: %v", out) return out, nil } diff --git a/vendor/github.com/moby/buildkit/client/solve.go b/vendor/github.com/moby/buildkit/client/solve.go index efdf9fa9f105..57ee82d05669 100644 --- a/vendor/github.com/moby/buildkit/client/solve.go +++ b/vendor/github.com/moby/buildkit/client/solve.go @@ -7,6 +7,7 @@ import ( "io" "maps" "os" + "slices" "strings" "time" @@ -24,7 +25,6 @@ import ( "github.com/moby/buildkit/solver/pb" spb "github.com/moby/buildkit/sourcepolicy/pb" "github.com/moby/buildkit/util/bklog" - "github.com/moby/buildkit/util/entitlements" ocispecs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/tonistiigi/fsutil" @@ -45,7 +45,7 @@ type SolveOpt struct { CacheExports []CacheOptionsEntry CacheImports []CacheOptionsEntry Session []session.Attachable - AllowedEntitlements []entitlements.Entitlement + AllowedEntitlements []string SharedSession *session.Session // TODO: refactor to better session syncing SessionPreInitialized bool // TODO: refactor to better session syncing Internal bool @@ -277,7 +277,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG FrontendAttrs: frontendAttrs, FrontendInputs: frontendInputs, Cache: &cacheOpt.options, - Entitlements: entitlementsToPB(opt.AllowedEntitlements), + Entitlements: slices.Clone(opt.AllowedEntitlements), Internal: opt.Internal, SourcePolicy: opt.SourcePolicy, }) @@ -553,11 +553,3 @@ func prepareMounts(opt *SolveOpt) (map[string]fsutil.FS, error) { } return mounts, nil } - -func entitlementsToPB(entitlements []entitlements.Entitlement) []string { - clone := make([]string, len(entitlements)) - for i, e := range entitlements { - clone[i] = string(e) - } - return clone -} diff --git a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go index 381effcdc9b7..3222406a42da 100644 --- a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go +++ b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go @@ -77,8 +77,9 @@ type OTELConfig struct { } type CDIConfig struct { - Disabled *bool `toml:"disabled"` - SpecDirs []string `toml:"specDirs"` + Disabled *bool `toml:"disabled"` + SpecDirs []string `toml:"specDirs"` + AutoAllowed []string `toml:"autoAllowed"` } type GCConfig struct { diff --git a/vendor/github.com/moby/buildkit/util/entitlements/entitlements.go b/vendor/github.com/moby/buildkit/util/entitlements/entitlements.go index 328580c326df..106f492ceee2 100644 --- a/vendor/github.com/moby/buildkit/util/entitlements/entitlements.go +++ b/vendor/github.com/moby/buildkit/util/entitlements/entitlements.go @@ -1,31 +1,119 @@ package entitlements import ( + "strings" + "github.com/pkg/errors" + "github.com/tonistiigi/go-csvvalue" ) type Entitlement string +func (e Entitlement) String() string { + return string(e) +} + const ( EntitlementSecurityInsecure Entitlement = "security.insecure" EntitlementNetworkHost Entitlement = "network.host" + EntitlementDevice Entitlement = "device" ) var all = map[Entitlement]struct{}{ EntitlementSecurityInsecure: {}, EntitlementNetworkHost: {}, + EntitlementDevice: {}, +} + +type EntitlementsConfig interface { + Merge(EntitlementsConfig) error } -func Parse(s string) (Entitlement, error) { +type DevicesConfig struct { + Devices map[string]string + All bool +} + +var _ EntitlementsConfig = &DevicesConfig{} + +func ParseDevicesConfig(s string) (*DevicesConfig, error) { + if s == "" { + return &DevicesConfig{All: true}, nil + } + + fields, err := csvvalue.Fields(s, nil) + if err != nil { + return nil, err + } + deviceName := fields[0] + var deviceAlias string + + for _, field := range fields[1:] { + k, v, ok := strings.Cut(field, "=") + if !ok { + return nil, errors.Errorf("invalid device config %q", field) + } + switch k { + case "alias": + deviceAlias = v + default: + return nil, errors.Errorf("unknown device config key %q", k) + } + } + + cfg := &DevicesConfig{Devices: map[string]string{}} + + if deviceAlias != "" { + cfg.Devices[deviceAlias] = deviceName + } else { + cfg.Devices[deviceName] = "" + } + return cfg, nil +} + +func (c *DevicesConfig) Merge(in EntitlementsConfig) error { + c2, ok := in.(*DevicesConfig) + if !ok { + return errors.Errorf("cannot merge %T into %T", in, c) + } + + if c2.All { + c.All = true + return nil + } + + for k, v := range c2.Devices { + if c.Devices == nil { + c.Devices = map[string]string{} + } + c.Devices[k] = v + } + return nil +} + +func Parse(s string) (Entitlement, EntitlementsConfig, error) { + var cfg EntitlementsConfig + key, rest, _ := strings.Cut(s, "=") + switch Entitlement(key) { + case EntitlementDevice: + s = key + var err error + cfg, err = ParseDevicesConfig(rest) + if err != nil { + return "", nil, err + } + default: + } + _, ok := all[Entitlement(s)] if !ok { - return "", errors.Errorf("unknown entitlement %s", s) + return "", nil, errors.Errorf("unknown entitlement %s", s) } - return Entitlement(s), nil + return Entitlement(s), cfg, nil } func WhiteList(allowed, supported []Entitlement) (Set, error) { - m := map[Entitlement]struct{}{} + m := map[Entitlement]EntitlementsConfig{} var supm Set if supported != nil { @@ -37,7 +125,7 @@ func WhiteList(allowed, supported []Entitlement) (Set, error) { } for _, e := range allowed { - e, err := Parse(string(e)) + e, cfg, err := Parse(string(e)) if err != nil { return nil, err } @@ -46,13 +134,19 @@ func WhiteList(allowed, supported []Entitlement) (Set, error) { return nil, errors.Errorf("granting entitlement %s is not allowed by build daemon configuration", e) } } - m[e] = struct{}{} + if prev, ok := m[e]; ok && prev != nil { + if err := prev.Merge(cfg); err != nil { + return nil, err + } + } else { + m[e] = cfg + } } return Set(m), nil } -type Set map[Entitlement]struct{} +type Set map[Entitlement]EntitlementsConfig func (s Set) Allowed(e Entitlement) bool { _, ok := s[e] @@ -77,4 +171,5 @@ func (s Set) Check(v Values) error { type Values struct { NetworkHost bool SecurityInsecure bool + Devices map[string]struct{} } diff --git a/vendor/modules.txt b/vendor/modules.txt index 86f2d90f2ad3..0d9cf5236cae 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -493,7 +493,7 @@ github.com/mitchellh/go-wordwrap github.com/mitchellh/hashstructure/v2 # github.com/mitchellh/mapstructure v1.5.0 ## explicit; go 1.14 -# github.com/moby/buildkit v0.20.0-rc2 +# github.com/moby/buildkit v0.20.0-rc2 => github.com/tonistiigi/buildkit v0.10.0-rc2.0.20250214043642-c9e788c50beb ## explicit; go 1.22.0 github.com/moby/buildkit/api/services/control github.com/moby/buildkit/api/types @@ -1387,3 +1387,4 @@ sigs.k8s.io/structured-merge-diff/v4/value ## explicit; go 1.12 sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 +# github.com/moby/buildkit => github.com/tonistiigi/buildkit v0.10.0-rc2.0.20250214043642-c9e788c50beb