mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-09 21:17:09 +08:00
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 <tonistiigi@gmail.com> Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
14
vendor/github.com/moby/buildkit/client/solve.go
generated
vendored
14
vendor/github.com/moby/buildkit/client/solve.go
generated
vendored
@ -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
|
||||
}
|
||||
|
5
vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go
generated
vendored
5
vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go
generated
vendored
@ -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 {
|
||||
|
109
vendor/github.com/moby/buildkit/util/entitlements/entitlements.go
generated
vendored
109
vendor/github.com/moby/buildkit/util/entitlements/entitlements.go
generated
vendored
@ -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: {},
|
||||
}
|
||||
|
||||
func Parse(s string) (Entitlement, error) {
|
||||
type EntitlementsConfig interface {
|
||||
Merge(EntitlementsConfig) 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{}
|
||||
}
|
||||
|
Reference in New Issue
Block a user