Skip to content

Commit 0dda89d

Browse files
committed
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 <[email protected]>
1 parent ef73c64 commit 0dda89d

File tree

13 files changed

+199
-49
lines changed

13 files changed

+199
-49
lines changed

bake/bake.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727
"github.com/moby/buildkit/client"
2828
"github.com/moby/buildkit/client/llb"
2929
"github.com/moby/buildkit/session/auth/authprovider"
30-
"github.com/moby/buildkit/util/entitlements"
3130
"github.com/pkg/errors"
3231
"github.com/zclconf/go-cty/cty"
3332
"github.com/zclconf/go-cty/cty/convert"
@@ -1434,9 +1433,7 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
14341433
}
14351434
bo.Ulimits = ulimits
14361435

1437-
for _, ent := range t.Entitlements {
1438-
bo.Allow = append(bo.Allow, entitlements.Entitlement(ent))
1439-
}
1436+
bo.Allow = append(bo.Allow, t.Entitlements...)
14401437

14411438
return bo, nil
14421439
}

bake/entitlements.go

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@ import (
2020
"github.com/moby/buildkit/util/entitlements"
2121
"github.com/pkg/errors"
2222
"github.com/sirupsen/logrus"
23+
"github.com/tonistiigi/go-csvvalue"
2324
)
2425

2526
type EntitlementKey string
2627

2728
const (
2829
EntitlementKeyNetworkHost EntitlementKey = "network.host"
2930
EntitlementKeySecurityInsecure EntitlementKey = "security.insecure"
31+
EntitlementKeyDevice EntitlementKey = "device"
3032
EntitlementKeyFSRead EntitlementKey = "fs.read"
3133
EntitlementKeyFSWrite EntitlementKey = "fs.write"
3234
EntitlementKeyFS EntitlementKey = "fs"
@@ -39,13 +41,19 @@ const (
3941
type EntitlementConf struct {
4042
NetworkHost bool
4143
SecurityInsecure bool
44+
Devices *EntitlementsDevicesConf
4245
FSRead []string
4346
FSWrite []string
4447
ImagePush []string
4548
ImageLoad []string
4649
SSH bool
4750
}
4851

52+
type EntitlementsDevicesConf struct {
53+
All bool
54+
Devices map[string]struct{}
55+
}
56+
4957
func ParseEntitlements(in []string) (EntitlementConf, error) {
5058
var conf EntitlementConf
5159
for _, e := range in {
@@ -59,6 +67,22 @@ func ParseEntitlements(in []string) (EntitlementConf, error) {
5967
default:
6068
k, v, _ := strings.Cut(e, "=")
6169
switch k {
70+
case string(EntitlementKeyDevice):
71+
if v == "" {
72+
conf.Devices = &EntitlementsDevicesConf{All: true}
73+
continue
74+
}
75+
fields, err := csvvalue.Fields(v, nil)
76+
if err != nil {
77+
return EntitlementConf{}, errors.Wrapf(err, "failed to parse device entitlement %q", v)
78+
}
79+
if conf.Devices == nil {
80+
conf.Devices = &EntitlementsDevicesConf{}
81+
}
82+
if conf.Devices.Devices == nil {
83+
conf.Devices.Devices = make(map[string]struct{}, 0)
84+
}
85+
conf.Devices.Devices[fields[0]] = struct{}{}
6286
case string(EntitlementKeyFSRead):
6387
conf.FSRead = append(conf.FSRead, v)
6488
case string(EntitlementKeyFSWrite):
@@ -95,12 +119,34 @@ func (c EntitlementConf) Validate(m map[string]build.Options) (EntitlementConf,
95119

96120
func (c EntitlementConf) check(bo build.Options, expected *EntitlementConf) error {
97121
for _, e := range bo.Allow {
122+
k, rest, _ := strings.Cut(e, "=")
123+
switch k {
124+
case entitlements.EntitlementDevice.String():
125+
if rest == "" {
126+
if c.Devices == nil || !c.Devices.All {
127+
expected.Devices = &EntitlementsDevicesConf{All: true}
128+
}
129+
continue
130+
}
131+
fields, err := csvvalue.Fields(rest, nil)
132+
if err != nil {
133+
return errors.Wrapf(err, "failed to parse device entitlement %q", rest)
134+
}
135+
if expected.Devices == nil {
136+
expected.Devices = &EntitlementsDevicesConf{}
137+
}
138+
if expected.Devices.Devices == nil {
139+
expected.Devices.Devices = make(map[string]struct{}, 0)
140+
}
141+
expected.Devices.Devices[fields[0]] = struct{}{}
142+
}
143+
98144
switch e {
99-
case entitlements.EntitlementNetworkHost:
145+
case entitlements.EntitlementNetworkHost.String():
100146
if !c.NetworkHost {
101147
expected.NetworkHost = true
102148
}
103-
case entitlements.EntitlementSecurityInsecure:
149+
case entitlements.EntitlementSecurityInsecure.String():
104150
if !c.SecurityInsecure {
105151
expected.SecurityInsecure = true
106152
}
@@ -187,6 +233,18 @@ func (c EntitlementConf) Prompt(ctx context.Context, isRemote bool, out io.Write
187233
flags = append(flags, string(EntitlementKeySecurityInsecure))
188234
}
189235

236+
if c.Devices != nil {
237+
if c.Devices.All {
238+
msgs = append(msgs, " - Access to CDI devices")
239+
flags = append(flags, string(EntitlementKeyDevice))
240+
} else {
241+
for d := range c.Devices.Devices {
242+
msgs = append(msgs, fmt.Sprintf(" - Access to device %s", d))
243+
flags = append(flags, string(EntitlementKeyDevice)+"="+d)
244+
}
245+
}
246+
}
247+
190248
if c.SSH {
191249
msgsFS = append(msgsFS, " - Forwarding default SSH agent socket")
192250
flagsFS = append(flagsFS, string(EntitlementKeySSH))

bake/entitlements_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,8 @@ func TestValidateEntitlements(t *testing.T) {
208208
{
209209
name: "NetworkHostMissing",
210210
opt: build.Options{
211-
Allow: []entitlements.Entitlement{
212-
entitlements.EntitlementNetworkHost,
211+
Allow: []string{
212+
entitlements.EntitlementNetworkHost.String(),
213213
},
214214
},
215215
expected: EntitlementConf{
@@ -223,8 +223,8 @@ func TestValidateEntitlements(t *testing.T) {
223223
NetworkHost: true,
224224
},
225225
opt: build.Options{
226-
Allow: []entitlements.Entitlement{
227-
entitlements.EntitlementNetworkHost,
226+
Allow: []string{
227+
entitlements.EntitlementNetworkHost.String(),
228228
},
229229
},
230230
expected: EntitlementConf{
@@ -234,9 +234,9 @@ func TestValidateEntitlements(t *testing.T) {
234234
{
235235
name: "SecurityAndNetworkHostMissing",
236236
opt: build.Options{
237-
Allow: []entitlements.Entitlement{
238-
entitlements.EntitlementNetworkHost,
239-
entitlements.EntitlementSecurityInsecure,
237+
Allow: []string{
238+
entitlements.EntitlementNetworkHost.String(),
239+
entitlements.EntitlementSecurityInsecure.String(),
240240
},
241241
},
242242
expected: EntitlementConf{
@@ -251,9 +251,9 @@ func TestValidateEntitlements(t *testing.T) {
251251
NetworkHost: true,
252252
},
253253
opt: build.Options{
254-
Allow: []entitlements.Entitlement{
255-
entitlements.EntitlementNetworkHost,
256-
entitlements.EntitlementSecurityInsecure,
254+
Allow: []string{
255+
entitlements.EntitlementNetworkHost.String(),
256+
entitlements.EntitlementSecurityInsecure.String(),
257257
},
258258
},
259259
expected: EntitlementConf{

build/build.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import (
4040
"github.com/moby/buildkit/solver/errdefs"
4141
"github.com/moby/buildkit/solver/pb"
4242
spb "github.com/moby/buildkit/sourcepolicy/pb"
43-
"github.com/moby/buildkit/util/entitlements"
4443
"github.com/moby/buildkit/util/progress/progresswriter"
4544
"github.com/moby/buildkit/util/tracing"
4645
"github.com/opencontainers/go-digest"
@@ -63,7 +62,7 @@ type Options struct {
6362
Inputs Inputs
6463

6564
Ref string
66-
Allow []entitlements.Entitlement
65+
Allow []string
6766
Attests map[string]*string
6867
BuildArgs map[string]string
6968
CacheFrom []client.CacheOptionsEntry

build/opt.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt *O
318318
switch opt.NetworkMode {
319319
case "host":
320320
so.FrontendAttrs["force-network-mode"] = opt.NetworkMode
321-
so.AllowedEntitlements = append(so.AllowedEntitlements, entitlements.EntitlementNetworkHost)
321+
so.AllowedEntitlements = append(so.AllowedEntitlements, entitlements.EntitlementNetworkHost.String())
322322
case "none":
323323
so.FrontendAttrs["force-network-mode"] = opt.NetworkMode
324324
case "", "default":

commands/build.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions, debugConfig *debug.D
593593

594594
flags.StringSliceVar(&options.extraHosts, "add-host", []string{}, `Add a custom host-to-IP mapping (format: "host:ip")`)
595595

596-
flags.StringSliceVar(&options.allow, "allow", []string{}, `Allow extra privileged entitlement (e.g., "network.host", "security.insecure")`)
596+
flags.StringArrayVar(&options.allow, "allow", []string{}, `Allow extra privileged entitlement (e.g., "network.host", "security.insecure")`)
597597

598598
flags.StringArrayVarP(&options.annotations, "annotation", "", []string{}, "Add annotation to the image")
599599

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,5 @@ exclude (
194194
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
195195
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
196196
)
197+
198+
replace github.com/moby/buildkit => github.com/tonistiigi/buildkit v0.10.0-rc2.0.20250214043642-c9e788c50beb

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,6 @@ github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/z
297297
github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
298298
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
299299
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
300-
github.com/moby/buildkit v0.20.0-rc2 h1:QjACghvG0pSAp7dk9aQMYWioDEOljDWyyoUjyg35qfg=
301-
github.com/moby/buildkit v0.20.0-rc2/go.mod h1:kMXf90l/f3zygRK8bYbyetfyzoJYntb6Bpi2VsLfXgQ=
302300
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
303301
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
304302
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
441439
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
442440
github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c=
443441
github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
442+
github.com/tonistiigi/buildkit v0.10.0-rc2.0.20250214043642-c9e788c50beb h1:uk0jspTfKpsaTGWqWO/MHWGQy4atLlOeJ6zjL7V1OeI=
443+
github.com/tonistiigi/buildkit v0.10.0-rc2.0.20250214043642-c9e788c50beb/go.mod h1:kMXf90l/f3zygRK8bYbyetfyzoJYntb6Bpi2VsLfXgQ=
444444
github.com/tonistiigi/dchapes-mode v0.0.0-20241001053921-ca0759fec205 h1:eUk79E1w8yMtXeHSzjKorxuC8qJOnyXQnLaJehxpJaI=
445445
github.com/tonistiigi/dchapes-mode v0.0.0-20241001053921-ca0759fec205/go.mod h1:3Iuxbr0P7D3zUzBMAZB+ois3h/et0shEz0qApgHYGpY=
446446
github.com/tonistiigi/fsutil v0.0.0-20250113203817-b14e27f4135a h1:EfGw4G0x/8qXWgtcZ6KVaPS+wpWOQMaypczzP8ojkMY=

util/buildflags/entitlements.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
package buildflags
22

3-
import "github.com/moby/buildkit/util/entitlements"
3+
import (
4+
"log"
45

5-
func ParseEntitlements(in []string) ([]entitlements.Entitlement, error) {
6-
out := make([]entitlements.Entitlement, 0, len(in))
6+
"github.com/moby/buildkit/util/entitlements"
7+
)
8+
9+
func ParseEntitlements(in []string) ([]string, error) {
10+
out := make([]string, 0, len(in))
11+
log.Printf("in: %#v", in)
712
for _, v := range in {
813
if v == "" {
914
continue
1015
}
1116

12-
e, err := entitlements.Parse(v)
13-
if err != nil {
17+
if _, _, err := entitlements.Parse(v); err != nil {
1418
return nil, err
1519
}
16-
out = append(out, e)
20+
out = append(out, v)
1721
}
22+
log.Printf("Parsed entitlements: %v", out)
1823
return out, nil
1924
}

vendor/github.com/moby/buildkit/client/solve.go

Lines changed: 3 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)