full diff: https://github.com/moby/buildkit/compare/v0.12.4...v0.12.5
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
| ... | ... |
@@ -142,8 +142,8 @@ func newSnapshotterController(ctx context.Context, rt http.RoundTripper, opt Opt |
| 142 | 142 |
return nil, err |
| 143 | 143 |
} |
| 144 | 144 |
frontends := map[string]frontend.Frontend{
|
| 145 |
- "dockerfile.v0": forwarder.NewGatewayForwarder(wc, dockerfile.Build), |
|
| 146 |
- "gateway.v0": gateway.NewGatewayFrontend(wc), |
|
| 145 |
+ "dockerfile.v0": forwarder.NewGatewayForwarder(wc.Infos(), dockerfile.Build), |
|
| 146 |
+ "gateway.v0": gateway.NewGatewayFrontend(wc.Infos()), |
|
| 147 | 147 |
} |
| 148 | 148 |
|
| 149 | 149 |
return control.NewController(control.Opt{
|
| ... | ... |
@@ -364,8 +364,8 @@ func newGraphDriverController(ctx context.Context, rt http.RoundTripper, opt Opt |
| 364 | 364 |
wc.Add(w) |
| 365 | 365 |
|
| 366 | 366 |
frontends := map[string]frontend.Frontend{
|
| 367 |
- "dockerfile.v0": forwarder.NewGatewayForwarder(wc, dockerfile.Build), |
|
| 368 |
- "gateway.v0": gateway.NewGatewayFrontend(wc), |
|
| 367 |
+ "dockerfile.v0": forwarder.NewGatewayForwarder(wc.Infos(), dockerfile.Build), |
|
| 368 |
+ "gateway.v0": gateway.NewGatewayFrontend(wc.Infos()), |
|
| 369 | 369 |
} |
| 370 | 370 |
|
| 371 | 371 |
return control.NewController(control.Opt{
|
| ... | ... |
@@ -60,7 +60,7 @@ require ( |
| 60 | 60 |
github.com/miekg/dns v1.1.43 |
| 61 | 61 |
github.com/mistifyio/go-zfs/v3 v3.0.1 |
| 62 | 62 |
github.com/mitchellh/copystructure v1.2.0 |
| 63 |
- github.com/moby/buildkit v0.12.5-0.20231208203051-3b6880d2a00f // v0.12 branch (v0.12.5-dev) |
|
| 63 |
+ github.com/moby/buildkit v0.12.5 |
|
| 64 | 64 |
github.com/moby/ipvs v1.1.0 |
| 65 | 65 |
github.com/moby/locker v1.0.1 |
| 66 | 66 |
github.com/moby/patternmatcher v0.6.0 |
| ... | ... |
@@ -902,8 +902,8 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx |
| 902 | 902 |
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= |
| 903 | 903 |
github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs= |
| 904 | 904 |
github.com/moby/buildkit v0.8.1/go.mod h1:/kyU1hKy/aYCuP39GZA9MaKioovHku57N6cqlKZIaiQ= |
| 905 |
-github.com/moby/buildkit v0.12.5-0.20231208203051-3b6880d2a00f h1:nYPkpfWrlQznHPLNrXxXIQMaTlmnsSBiiRTgnQ5hrZ0= |
|
| 906 |
-github.com/moby/buildkit v0.12.5-0.20231208203051-3b6880d2a00f/go.mod h1:XG74uz06nPWQpnxYwgCryrVidvor0+ElUxGosbZPQG4= |
|
| 905 |
+github.com/moby/buildkit v0.12.5 h1:RNHH1l3HDhYyZafr5EgstEu8aGNCwyfvMtrQDtjH9T0= |
|
| 906 |
+github.com/moby/buildkit v0.12.5/go.mod h1:YGwjA2loqyiYfZeEo8FtI7z4x5XponAaIWsWcSjWwso= |
|
| 907 | 907 |
github.com/moby/ipvs v1.1.0 h1:ONN4pGaZQgAx+1Scz5RvWV4Q7Gb+mvfRh3NsPS+1XQQ= |
| 908 | 908 |
github.com/moby/ipvs v1.1.0/go.mod h1:4VJMWuf098bsUMmZEiD4Tjk/O7mOn3l1PTD3s4OoYAs= |
| 909 | 909 |
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= |
| ... | ... |
@@ -405,6 +405,9 @@ func (c *Controller) Solve(ctx context.Context, req *controlapi.SolveRequest) (* |
| 405 | 405 |
|
| 406 | 406 |
var cacheImports []frontend.CacheOptionsEntry |
| 407 | 407 |
for _, im := range req.Cache.Imports {
|
| 408 |
+ if im == nil {
|
|
| 409 |
+ continue |
|
| 410 |
+ } |
|
| 408 | 411 |
cacheImports = append(cacheImports, frontend.CacheOptionsEntry{
|
| 409 | 412 |
Type: im.Type, |
| 410 | 413 |
Attrs: im.Attrs, |
| ... | ... |
@@ -6,8 +6,9 @@ import ( |
| 6 | 6 |
"net" |
| 7 | 7 |
"syscall" |
| 8 | 8 |
|
| 9 |
+ "github.com/containerd/containerd/mount" |
|
| 10 |
+ "github.com/docker/docker/pkg/idtools" |
|
| 9 | 11 |
resourcestypes "github.com/moby/buildkit/executor/resources/types" |
| 10 |
- "github.com/moby/buildkit/snapshot" |
|
| 11 | 12 |
"github.com/moby/buildkit/solver/pb" |
| 12 | 13 |
) |
| 13 | 14 |
|
| ... | ... |
@@ -28,8 +29,13 @@ type Meta struct {
|
| 28 | 28 |
RemoveMountStubsRecursive bool |
| 29 | 29 |
} |
| 30 | 30 |
|
| 31 |
+type MountableRef interface {
|
|
| 32 |
+ Mount() ([]mount.Mount, func() error, error) |
|
| 33 |
+ IdentityMapping() *idtools.IdentityMapping |
|
| 34 |
+} |
|
| 35 |
+ |
|
| 31 | 36 |
type Mountable interface {
|
| 32 |
- Mount(ctx context.Context, readonly bool) (snapshot.Mountable, error) |
|
| 37 |
+ Mount(ctx context.Context, readonly bool) (MountableRef, error) |
|
| 33 | 38 |
} |
| 34 | 39 |
|
| 35 | 40 |
type Mount struct {
|
| ... | ... |
@@ -12,7 +12,6 @@ import ( |
| 12 | 12 |
"github.com/containerd/containerd/namespaces" |
| 13 | 13 |
"github.com/containerd/containerd/oci" |
| 14 | 14 |
"github.com/containerd/containerd/pkg/userns" |
| 15 |
- "github.com/containerd/continuity/fs" |
|
| 16 | 15 |
"github.com/docker/docker/pkg/idtools" |
| 17 | 16 |
"github.com/mitchellh/hashstructure/v2" |
| 18 | 17 |
"github.com/moby/buildkit/executor" |
| ... | ... |
@@ -215,6 +214,7 @@ func GenerateSpec(ctx context.Context, meta executor.Meta, mounts []executor.Mou |
| 215 | 215 |
type mountRef struct {
|
| 216 | 216 |
mount mount.Mount |
| 217 | 217 |
unmount func() error |
| 218 |
+ subRefs map[string]mountRef |
|
| 218 | 219 |
} |
| 219 | 220 |
|
| 220 | 221 |
type submounts struct {
|
| ... | ... |
@@ -230,12 +230,19 @@ func (s *submounts) subMount(m mount.Mount, subPath string) (mount.Mount, error) |
| 230 | 230 |
} |
| 231 | 231 |
h, err := hashstructure.Hash(m, hashstructure.FormatV2, nil) |
| 232 | 232 |
if err != nil {
|
| 233 |
- return mount.Mount{}, nil
|
|
| 233 |
+ return mount.Mount{}, err
|
|
| 234 | 234 |
} |
| 235 | 235 |
if mr, ok := s.m[h]; ok {
|
| 236 |
- sm, err := sub(mr.mount, subPath) |
|
| 236 |
+ if sm, ok := mr.subRefs[subPath]; ok {
|
|
| 237 |
+ return sm.mount, nil |
|
| 238 |
+ } |
|
| 239 |
+ sm, unmount, err := sub(mr.mount, subPath) |
|
| 237 | 240 |
if err != nil {
|
| 238 |
- return mount.Mount{}, nil
|
|
| 241 |
+ return mount.Mount{}, err
|
|
| 242 |
+ } |
|
| 243 |
+ mr.subRefs[subPath] = mountRef{
|
|
| 244 |
+ mount: sm, |
|
| 245 |
+ unmount: unmount, |
|
| 239 | 246 |
} |
| 240 | 247 |
return sm, nil |
| 241 | 248 |
} |
| ... | ... |
@@ -261,12 +268,17 @@ func (s *submounts) subMount(m mount.Mount, subPath string) (mount.Mount, error) |
| 261 | 261 |
Options: opts, |
| 262 | 262 |
}, |
| 263 | 263 |
unmount: lm.Unmount, |
| 264 |
+ subRefs: map[string]mountRef{},
|
|
| 264 | 265 |
} |
| 265 | 266 |
|
| 266 |
- sm, err := sub(s.m[h].mount, subPath) |
|
| 267 |
+ sm, unmount, err := sub(s.m[h].mount, subPath) |
|
| 267 | 268 |
if err != nil {
|
| 268 | 269 |
return mount.Mount{}, err
|
| 269 | 270 |
} |
| 271 |
+ s.m[h].subRefs[subPath] = mountRef{
|
|
| 272 |
+ mount: sm, |
|
| 273 |
+ unmount: unmount, |
|
| 274 |
+ } |
|
| 270 | 275 |
return sm, nil |
| 271 | 276 |
} |
| 272 | 277 |
|
| ... | ... |
@@ -276,6 +288,9 @@ func (s *submounts) cleanup() {
|
| 276 | 276 |
for _, m := range s.m {
|
| 277 | 277 |
func(m mountRef) {
|
| 278 | 278 |
go func() {
|
| 279 |
+ for _, sm := range m.subRefs {
|
|
| 280 |
+ sm.unmount() |
|
| 281 |
+ } |
|
| 279 | 282 |
m.unmount() |
| 280 | 283 |
wg.Done() |
| 281 | 284 |
}() |
| ... | ... |
@@ -284,15 +299,6 @@ func (s *submounts) cleanup() {
|
| 284 | 284 |
wg.Wait() |
| 285 | 285 |
} |
| 286 | 286 |
|
| 287 |
-func sub(m mount.Mount, subPath string) (mount.Mount, error) {
|
|
| 288 |
- src, err := fs.RootPath(m.Source, subPath) |
|
| 289 |
- if err != nil {
|
|
| 290 |
- return mount.Mount{}, err
|
|
| 291 |
- } |
|
| 292 |
- m.Source = src |
|
| 293 |
- return m, nil |
|
| 294 |
-} |
|
| 295 |
- |
|
| 296 | 287 |
func specMapping(s []idtools.IDMap) []specs.LinuxIDMapping {
|
| 297 | 288 |
var ids []specs.LinuxIDMapping |
| 298 | 289 |
for _, item := range s {
|
| 299 | 290 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 0 |
+package oci |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/containerd/containerd/mount" |
|
| 4 |
+ "github.com/containerd/continuity/fs" |
|
| 5 |
+) |
|
| 6 |
+ |
|
| 7 |
+func sub(m mount.Mount, subPath string) (mount.Mount, func() error, error) {
|
|
| 8 |
+ src, err := fs.RootPath(m.Source, subPath) |
|
| 9 |
+ if err != nil {
|
|
| 10 |
+ return mount.Mount{}, nil, err
|
|
| 11 |
+ } |
|
| 12 |
+ m.Source = src |
|
| 13 |
+ return m, func() error { return nil }, nil
|
|
| 14 |
+} |
| 0 | 15 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,57 @@ |
| 0 |
+//go:build linux |
|
| 1 |
+// +build linux |
|
| 2 |
+ |
|
| 3 |
+package oci |
|
| 4 |
+ |
|
| 5 |
+import ( |
|
| 6 |
+ "os" |
|
| 7 |
+ "strconv" |
|
| 8 |
+ |
|
| 9 |
+ "github.com/containerd/containerd/mount" |
|
| 10 |
+ "github.com/containerd/continuity/fs" |
|
| 11 |
+ "github.com/moby/buildkit/snapshot" |
|
| 12 |
+ "github.com/pkg/errors" |
|
| 13 |
+ "golang.org/x/sys/unix" |
|
| 14 |
+) |
|
| 15 |
+ |
|
| 16 |
+func sub(m mount.Mount, subPath string) (mount.Mount, func() error, error) {
|
|
| 17 |
+ var retries = 10 |
|
| 18 |
+ root := m.Source |
|
| 19 |
+ for {
|
|
| 20 |
+ src, err := fs.RootPath(root, subPath) |
|
| 21 |
+ if err != nil {
|
|
| 22 |
+ return mount.Mount{}, nil, err
|
|
| 23 |
+ } |
|
| 24 |
+ // similar to runc.WithProcfd |
|
| 25 |
+ fh, err := os.OpenFile(src, unix.O_PATH|unix.O_CLOEXEC, 0) |
|
| 26 |
+ if err != nil {
|
|
| 27 |
+ return mount.Mount{}, nil, err
|
|
| 28 |
+ } |
|
| 29 |
+ |
|
| 30 |
+ fdPath := "/proc/self/fd/" + strconv.Itoa(int(fh.Fd())) |
|
| 31 |
+ if resolved, err := os.Readlink(fdPath); err != nil {
|
|
| 32 |
+ fh.Close() |
|
| 33 |
+ return mount.Mount{}, nil, err
|
|
| 34 |
+ } else if resolved != src {
|
|
| 35 |
+ retries-- |
|
| 36 |
+ if retries <= 0 {
|
|
| 37 |
+ fh.Close() |
|
| 38 |
+ return mount.Mount{}, nil, errors.Errorf("unable to safely resolve subpath %s", subPath)
|
|
| 39 |
+ } |
|
| 40 |
+ fh.Close() |
|
| 41 |
+ continue |
|
| 42 |
+ } |
|
| 43 |
+ |
|
| 44 |
+ m.Source = fdPath |
|
| 45 |
+ lm := snapshot.LocalMounterWithMounts([]mount.Mount{m}, snapshot.ForceRemount())
|
|
| 46 |
+ mp, err := lm.Mount() |
|
| 47 |
+ if err != nil {
|
|
| 48 |
+ fh.Close() |
|
| 49 |
+ return mount.Mount{}, nil, err
|
|
| 50 |
+ } |
|
| 51 |
+ m.Source = mp |
|
| 52 |
+ fh.Close() // release the fd, we don't need it anymore |
|
| 53 |
+ |
|
| 54 |
+ return m, lm.Unmount, nil |
|
| 55 |
+ } |
|
| 56 |
+} |
| ... | ... |
@@ -7,7 +7,9 @@ import ( |
| 7 | 7 |
"fmt" |
| 8 | 8 |
"path/filepath" |
| 9 | 9 |
|
| 10 |
+ "github.com/containerd/containerd/mount" |
|
| 10 | 11 |
"github.com/containerd/containerd/oci" |
| 12 |
+ "github.com/containerd/continuity/fs" |
|
| 11 | 13 |
"github.com/docker/docker/pkg/idtools" |
| 12 | 14 |
"github.com/moby/buildkit/solver/pb" |
| 13 | 15 |
specs "github.com/opencontainers/runtime-spec/specs-go" |
| ... | ... |
@@ -67,3 +69,12 @@ func getTracingSocket() string {
|
| 67 | 67 |
func cgroupV2NamespaceSupported() bool {
|
| 68 | 68 |
return false |
| 69 | 69 |
} |
| 70 |
+ |
|
| 71 |
+func sub(m mount.Mount, subPath string) (mount.Mount, func() error, error) {
|
|
| 72 |
+ src, err := fs.RootPath(m.Source, subPath) |
|
| 73 |
+ if err != nil {
|
|
| 74 |
+ return mount.Mount{}, nil, err
|
|
| 75 |
+ } |
|
| 76 |
+ m.Source = src |
|
| 77 |
+ return m, func() error { return nil }, nil
|
|
| 78 |
+} |
| ... | ... |
@@ -5,6 +5,7 @@ import ( |
| 5 | 5 |
"errors" |
| 6 | 6 |
"os" |
| 7 | 7 |
"path/filepath" |
| 8 |
+ "strings" |
|
| 8 | 9 |
"syscall" |
| 9 | 10 |
|
| 10 | 11 |
"github.com/containerd/continuity/fs" |
| ... | ... |
@@ -43,7 +44,7 @@ func MountStubsCleaner(ctx context.Context, dir string, mounts []Mount, recursiv |
| 43 | 43 |
} |
| 44 | 44 |
|
| 45 | 45 |
realPathNext := filepath.Dir(realPath) |
| 46 |
- if realPath == realPathNext {
|
|
| 46 |
+ if realPath == realPathNext || realPathNext == dir {
|
|
| 47 | 47 |
break |
| 48 | 48 |
} |
| 49 | 49 |
realPath = realPathNext |
| ... | ... |
@@ -52,6 +53,11 @@ func MountStubsCleaner(ctx context.Context, dir string, mounts []Mount, recursiv |
| 52 | 52 |
|
| 53 | 53 |
return func() {
|
| 54 | 54 |
for _, p := range paths {
|
| 55 |
+ p, err := fs.RootPath(dir, strings.TrimPrefix(p, dir)) |
|
| 56 |
+ if err != nil {
|
|
| 57 |
+ continue |
|
| 58 |
+ } |
|
| 59 |
+ |
|
| 55 | 60 |
st, err := os.Lstat(p) |
| 56 | 61 |
if err != nil {
|
| 57 | 62 |
continue |
| ... | ... |
@@ -70,8 +76,12 @@ func MountStubsCleaner(ctx context.Context, dir string, mounts []Mount, recursiv |
| 70 | 70 |
|
| 71 | 71 |
// Back up the timestamps of the dir for reproducible builds |
| 72 | 72 |
// https://github.com/moby/buildkit/issues/3148 |
| 73 |
- dir := filepath.Dir(p) |
|
| 74 |
- dirSt, err := os.Stat(dir) |
|
| 73 |
+ parent := filepath.Dir(p) |
|
| 74 |
+ if realPath, err := fs.RootPath(dir, strings.TrimPrefix(parent, dir)); err != nil || realPath != parent {
|
|
| 75 |
+ continue |
|
| 76 |
+ } |
|
| 77 |
+ |
|
| 78 |
+ dirSt, err := os.Stat(parent) |
|
| 75 | 79 |
if err != nil {
|
| 76 | 80 |
bklog.G(ctx).WithError(err).Warnf("Failed to stat %q (parent of mount stub %q)", dir, p)
|
| 77 | 81 |
continue |
| ... | ... |
@@ -88,7 +98,7 @@ func MountStubsCleaner(ctx context.Context, dir string, mounts []Mount, recursiv |
| 88 | 88 |
} |
| 89 | 89 |
|
| 90 | 90 |
// Restore the timestamps of the dir |
| 91 |
- if err := os.Chtimes(dir, atime, mtime); err != nil {
|
|
| 91 |
+ if err := os.Chtimes(parent, atime, mtime); err != nil {
|
|
| 92 | 92 |
bklog.G(ctx).WithError(err).Warnf("Failed to restore time time mount stub timestamp (os.Chtimes(%q, %v, %v))", dir, atime, mtime)
|
| 93 | 93 |
} |
| 94 | 94 |
} |
| ... | ... |
@@ -17,6 +17,18 @@ func ParsePlatforms(meta map[string][]byte) (Platforms, error) {
|
| 17 | 17 |
return Platforms{}, errors.Wrapf(err, "failed to parse platforms passed to provenance processor")
|
| 18 | 18 |
} |
| 19 | 19 |
} |
| 20 |
+ if len(ps.Platforms) == 0 {
|
|
| 21 |
+ return Platforms{}, errors.Errorf("invalid empty platforms index for exporter")
|
|
| 22 |
+ } |
|
| 23 |
+ for i, p := range ps.Platforms {
|
|
| 24 |
+ if p.ID == "" {
|
|
| 25 |
+ return Platforms{}, errors.Errorf("invalid empty platform key for exporter")
|
|
| 26 |
+ } |
|
| 27 |
+ if p.Platform.OS == "" || p.Platform.Architecture == "" {
|
|
| 28 |
+ return Platforms{}, errors.Errorf("invalid platform value %v for exporter", p.Platform)
|
|
| 29 |
+ } |
|
| 30 |
+ ps.Platforms[i].Platform = platforms.Normalize(p.Platform) |
|
| 31 |
+ } |
|
| 20 | 32 |
return ps, nil |
| 21 | 33 |
} |
| 22 | 34 |
|
| ... | ... |
@@ -36,6 +48,8 @@ func ParsePlatforms(meta map[string][]byte) (Platforms, error) {
|
| 36 | 36 |
OSFeatures: img.OSFeatures, |
| 37 | 37 |
Variant: img.Variant, |
| 38 | 38 |
} |
| 39 |
+ } else if img.OS != "" || img.Architecture != "" {
|
|
| 40 |
+ return Platforms{}, errors.Errorf("invalid image config: os and architecture must be specified together")
|
|
| 39 | 41 |
} |
| 40 | 42 |
} |
| 41 | 43 |
p = platforms.Normalize(p) |
| ... | ... |
@@ -569,11 +569,27 @@ func parseHistoryFromConfig(dt []byte) ([]ocispecs.History, error) {
|
| 569 | 569 |
} |
| 570 | 570 |
|
| 571 | 571 |
func patchImageConfig(dt []byte, descs []ocispecs.Descriptor, history []ocispecs.History, cache []byte, epoch *time.Time) ([]byte, error) {
|
| 572 |
+ var img ocispecs.Image |
|
| 573 |
+ if err := json.Unmarshal(dt, &img); err != nil {
|
|
| 574 |
+ return nil, errors.Wrap(err, "invalid image config for export") |
|
| 575 |
+ } |
|
| 576 |
+ |
|
| 572 | 577 |
m := map[string]json.RawMessage{}
|
| 573 | 578 |
if err := json.Unmarshal(dt, &m); err != nil {
|
| 574 | 579 |
return nil, errors.Wrap(err, "failed to parse image config for patch") |
| 575 | 580 |
} |
| 576 | 581 |
|
| 582 |
+ if m == nil {
|
|
| 583 |
+ return nil, errors.Errorf("invalid null image config for export")
|
|
| 584 |
+ } |
|
| 585 |
+ |
|
| 586 |
+ if img.OS == "" {
|
|
| 587 |
+ return nil, errors.Errorf("invalid image config for export: missing os")
|
|
| 588 |
+ } |
|
| 589 |
+ if img.Architecture == "" {
|
|
| 590 |
+ return nil, errors.Errorf("invalid image config for export: missing architecture")
|
|
| 591 |
+ } |
|
| 592 |
+ |
|
| 577 | 593 |
var rootFS ocispecs.RootFS |
| 578 | 594 |
rootFS.Type = "layers" |
| 579 | 595 |
for _, desc := range descs {
|
| ... | ... |
@@ -4,6 +4,7 @@ import ( |
| 4 | 4 |
"context" |
| 5 | 5 |
|
| 6 | 6 |
"github.com/moby/buildkit/client/llb" |
| 7 |
+ "github.com/moby/buildkit/executor" |
|
| 7 | 8 |
gw "github.com/moby/buildkit/frontend/gateway/client" |
| 8 | 9 |
"github.com/moby/buildkit/session" |
| 9 | 10 |
"github.com/moby/buildkit/solver" |
| ... | ... |
@@ -17,7 +18,7 @@ type Result = result.Result[solver.ResultProxy] |
| 17 | 17 |
type Attestation = result.Attestation[solver.ResultProxy] |
| 18 | 18 |
|
| 19 | 19 |
type Frontend interface {
|
| 20 |
- Solve(ctx context.Context, llb FrontendLLBBridge, opt map[string]string, inputs map[string]*pb.Definition, sid string, sm *session.Manager) (*Result, error) |
|
| 20 |
+ Solve(ctx context.Context, llb FrontendLLBBridge, exec executor.Executor, opt map[string]string, inputs map[string]*pb.Definition, sid string, sm *session.Manager) (*Result, error) |
|
| 21 | 21 |
} |
| 22 | 22 |
|
| 23 | 23 |
type FrontendLLBBridge interface {
|
| ... | ... |
@@ -30,8 +30,14 @@ func AttestationToPB[T any](a *result.Attestation[T]) (*pb.Attestation, error) {
|
| 30 | 30 |
} |
| 31 | 31 |
|
| 32 | 32 |
func AttestationFromPB[T any](a *pb.Attestation) (*result.Attestation[T], error) {
|
| 33 |
+ if a == nil {
|
|
| 34 |
+ return nil, errors.Errorf("invalid nil attestation")
|
|
| 35 |
+ } |
|
| 33 | 36 |
subjects := make([]result.InTotoSubject, len(a.InTotoSubjects)) |
| 34 | 37 |
for i, subject := range a.InTotoSubjects {
|
| 38 |
+ if subject == nil {
|
|
| 39 |
+ return nil, errors.Errorf("invalid nil attestation subject")
|
|
| 40 |
+ } |
|
| 35 | 41 |
subjects[i] = result.InTotoSubject{
|
| 36 | 42 |
Kind: subject.Kind, |
| 37 | 43 |
Name: subject.Name, |
| ... | ... |
@@ -47,7 +47,7 @@ type Mount struct {
|
| 47 | 47 |
WorkerRef *worker.WorkerRef |
| 48 | 48 |
} |
| 49 | 49 |
|
| 50 |
-func NewContainer(ctx context.Context, w worker.Worker, sm *session.Manager, g session.Group, req NewContainerRequest) (client.Container, error) {
|
|
| 50 |
+func NewContainer(ctx context.Context, cm cache.Manager, exec executor.Executor, sm *session.Manager, g session.Group, req NewContainerRequest) (client.Container, error) {
|
|
| 51 | 51 |
ctx, cancel := context.WithCancel(ctx) |
| 52 | 52 |
eg, ctx := errgroup.WithContext(ctx) |
| 53 | 53 |
platform := opspb.Platform{
|
| ... | ... |
@@ -63,7 +63,7 @@ func NewContainer(ctx context.Context, w worker.Worker, sm *session.Manager, g s |
| 63 | 63 |
hostname: req.Hostname, |
| 64 | 64 |
extraHosts: req.ExtraHosts, |
| 65 | 65 |
platform: platform, |
| 66 |
- executor: w.Executor(), |
|
| 66 |
+ executor: exec, |
|
| 67 | 67 |
sm: sm, |
| 68 | 68 |
group: g, |
| 69 | 69 |
errGroup: eg, |
| ... | ... |
@@ -86,9 +86,8 @@ func NewContainer(ctx context.Context, w worker.Worker, sm *session.Manager, g s |
| 86 | 86 |
} |
| 87 | 87 |
|
| 88 | 88 |
name := fmt.Sprintf("container %s", req.ContainerID)
|
| 89 |
- mm := mounts.NewMountManager(name, w.CacheManager(), sm) |
|
| 90 |
- p, err := PrepareMounts(ctx, mm, w.CacheManager(), g, "", mnts, refs, func(m *opspb.Mount, ref cache.ImmutableRef) (cache.MutableRef, error) {
|
|
| 91 |
- cm := w.CacheManager() |
|
| 89 |
+ mm := mounts.NewMountManager(name, cm, sm) |
|
| 90 |
+ p, err := PrepareMounts(ctx, mm, cm, g, "", mnts, refs, func(m *opspb.Mount, ref cache.ImmutableRef) (cache.MutableRef, error) {
|
|
| 92 | 91 |
if m.Input != opspb.Empty {
|
| 93 | 92 |
cm = refs[m.Input].Worker.CacheManager() |
| 94 | 93 |
} |
| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
|
| 7 | 7 |
cacheutil "github.com/moby/buildkit/cache/util" |
| 8 | 8 |
"github.com/moby/buildkit/client/llb" |
| 9 |
+ "github.com/moby/buildkit/executor" |
|
| 9 | 10 |
"github.com/moby/buildkit/frontend" |
| 10 | 11 |
"github.com/moby/buildkit/frontend/gateway/client" |
| 11 | 12 |
"github.com/moby/buildkit/frontend/gateway/container" |
| ... | ... |
@@ -26,7 +27,7 @@ import ( |
| 26 | 26 |
"golang.org/x/sync/errgroup" |
| 27 | 27 |
) |
| 28 | 28 |
|
| 29 |
-func LLBBridgeToGatewayClient(ctx context.Context, llbBridge frontend.FrontendLLBBridge, opts map[string]string, inputs map[string]*opspb.Definition, w worker.Infos, sid string, sm *session.Manager) (*BridgeClient, error) {
|
|
| 29 |
+func LLBBridgeToGatewayClient(ctx context.Context, llbBridge frontend.FrontendLLBBridge, exec executor.Executor, opts map[string]string, inputs map[string]*opspb.Definition, w worker.Infos, sid string, sm *session.Manager) (*BridgeClient, error) {
|
|
| 30 | 30 |
bc := &BridgeClient{
|
| 31 | 31 |
opts: opts, |
| 32 | 32 |
inputs: inputs, |
| ... | ... |
@@ -35,6 +36,7 @@ func LLBBridgeToGatewayClient(ctx context.Context, llbBridge frontend.FrontendLL |
| 35 | 35 |
sm: sm, |
| 36 | 36 |
workers: w, |
| 37 | 37 |
workerRefByID: make(map[string]*worker.WorkerRef), |
| 38 |
+ executor: exec, |
|
| 38 | 39 |
} |
| 39 | 40 |
bc.buildOpts = bc.loadBuildOpts() |
| 40 | 41 |
return bc, nil |
| ... | ... |
@@ -52,6 +54,7 @@ type BridgeClient struct {
|
| 52 | 52 |
workerRefByID map[string]*worker.WorkerRef |
| 53 | 53 |
buildOpts client.BuildOpts |
| 54 | 54 |
ctrs []client.Container |
| 55 |
+ executor executor.Executor |
|
| 55 | 56 |
} |
| 56 | 57 |
|
| 57 | 58 |
func (c *BridgeClient) Solve(ctx context.Context, req client.SolveRequest) (*client.Result, error) {
|
| ... | ... |
@@ -293,13 +296,13 @@ func (c *BridgeClient) NewContainer(ctx context.Context, req client.NewContainer |
| 293 | 293 |
return nil, err |
| 294 | 294 |
} |
| 295 | 295 |
|
| 296 |
- w, err := c.workers.GetDefault() |
|
| 296 |
+ cm, err := c.workers.DefaultCacheManager() |
|
| 297 | 297 |
if err != nil {
|
| 298 | 298 |
return nil, err |
| 299 | 299 |
} |
| 300 | 300 |
|
| 301 | 301 |
group := session.NewGroup(c.sid) |
| 302 |
- ctr, err := container.NewContainer(ctx, w, c.sm, group, ctrReq) |
|
| 302 |
+ ctr, err := container.NewContainer(ctx, cm, c.executor, c.sm, group, ctrReq) |
|
| 303 | 303 |
if err != nil {
|
| 304 | 304 |
return nil, err |
| 305 | 305 |
} |
| ... | ... |
@@ -3,6 +3,7 @@ package forwarder |
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 | 5 |
|
| 6 |
+ "github.com/moby/buildkit/executor" |
|
| 6 | 7 |
"github.com/moby/buildkit/frontend" |
| 7 | 8 |
"github.com/moby/buildkit/frontend/gateway/client" |
| 8 | 9 |
"github.com/moby/buildkit/session" |
| ... | ... |
@@ -22,8 +23,8 @@ type GatewayForwarder struct {
|
| 22 | 22 |
f client.BuildFunc |
| 23 | 23 |
} |
| 24 | 24 |
|
| 25 |
-func (gf *GatewayForwarder) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBridge, opts map[string]string, inputs map[string]*pb.Definition, sid string, sm *session.Manager) (retRes *frontend.Result, retErr error) {
|
|
| 26 |
- c, err := LLBBridgeToGatewayClient(ctx, llbBridge, opts, inputs, gf.workers, sid, sm) |
|
| 25 |
+func (gf *GatewayForwarder) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBridge, exec executor.Executor, opts map[string]string, inputs map[string]*pb.Definition, sid string, sm *session.Manager) (retRes *frontend.Result, retErr error) {
|
|
| 26 |
+ c, err := LLBBridgeToGatewayClient(ctx, llbBridge, exec, opts, inputs, gf.workers, sid, sm) |
|
| 27 | 27 |
if err != nil {
|
| 28 | 28 |
return nil, err |
| 29 | 29 |
} |
| ... | ... |
@@ -86,7 +86,7 @@ func filterPrefix(opts map[string]string, pfx string) map[string]string {
|
| 86 | 86 |
return m |
| 87 | 87 |
} |
| 88 | 88 |
|
| 89 |
-func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBridge, opts map[string]string, inputs map[string]*opspb.Definition, sid string, sm *session.Manager) (*frontend.Result, error) {
|
|
| 89 |
+func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBridge, exec executor.Executor, opts map[string]string, inputs map[string]*opspb.Definition, sid string, sm *session.Manager) (*frontend.Result, error) {
|
|
| 90 | 90 |
source, ok := opts[keySource] |
| 91 | 91 |
if !ok {
|
| 92 | 92 |
return nil, errors.Errorf("no source specified for gateway")
|
| ... | ... |
@@ -141,7 +141,7 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten |
| 141 | 141 |
} |
| 142 | 142 |
} |
| 143 | 143 |
} else {
|
| 144 |
- c, err := forwarder.LLBBridgeToGatewayClient(ctx, llbBridge, opts, inputs, gf.workers, sid, sm) |
|
| 144 |
+ c, err := forwarder.LLBBridgeToGatewayClient(ctx, llbBridge, exec, opts, inputs, gf.workers, sid, sm) |
|
| 145 | 145 |
if err != nil {
|
| 146 | 146 |
return nil, err |
| 147 | 147 |
} |
| ... | ... |
@@ -281,18 +281,13 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten |
| 281 | 281 |
} |
| 282 | 282 |
} |
| 283 | 283 |
|
| 284 |
- lbf, ctx, err := serveLLBBridgeForwarder(ctx, llbBridge, gf.workers, inputs, sid, sm) |
|
| 284 |
+ lbf, ctx, err := serveLLBBridgeForwarder(ctx, llbBridge, exec, gf.workers, inputs, sid, sm) |
|
| 285 | 285 |
defer lbf.conn.Close() //nolint |
| 286 | 286 |
if err != nil {
|
| 287 | 287 |
return nil, err |
| 288 | 288 |
} |
| 289 | 289 |
defer lbf.Discard() |
| 290 | 290 |
|
| 291 |
- w, err := gf.workers.GetDefault() |
|
| 292 |
- if err != nil {
|
|
| 293 |
- return nil, err |
|
| 294 |
- } |
|
| 295 |
- |
|
| 296 | 291 |
mdmnt, release, err := metadataMount(frontendDef) |
| 297 | 292 |
if err != nil {
|
| 298 | 293 |
return nil, err |
| ... | ... |
@@ -305,7 +300,7 @@ func (gf *gatewayFrontend) Solve(ctx context.Context, llbBridge frontend.Fronten |
| 305 | 305 |
mnts = append(mnts, *mdmnt) |
| 306 | 306 |
} |
| 307 | 307 |
|
| 308 |
- _, err = w.Executor().Run(ctx, "", container.MountWithSession(rootFS, session.NewGroup(sid)), mnts, executor.ProcessInfo{Meta: meta, Stdin: lbf.Stdin, Stdout: lbf.Stdout, Stderr: os.Stderr}, nil)
|
|
| 308 |
+ _, err = exec.Run(ctx, "", container.MountWithSession(rootFS, session.NewGroup(sid)), mnts, executor.ProcessInfo{Meta: meta, Stdin: lbf.Stdin, Stdout: lbf.Stdout, Stderr: os.Stderr}, nil)
|
|
| 309 | 309 |
if err != nil {
|
| 310 | 310 |
if errdefs.IsCanceled(ctx, err) && lbf.isErrServerClosed {
|
| 311 | 311 |
err = errors.Errorf("frontend grpc server closed unexpectedly")
|
| ... | ... |
@@ -434,11 +429,11 @@ func (lbf *llbBridgeForwarder) Result() (*frontend.Result, error) {
|
| 434 | 434 |
return lbf.result, nil |
| 435 | 435 |
} |
| 436 | 436 |
|
| 437 |
-func NewBridgeForwarder(ctx context.Context, llbBridge frontend.FrontendLLBBridge, workers worker.Infos, inputs map[string]*opspb.Definition, sid string, sm *session.Manager) LLBBridgeForwarder {
|
|
| 438 |
- return newBridgeForwarder(ctx, llbBridge, workers, inputs, sid, sm) |
|
| 437 |
+func NewBridgeForwarder(ctx context.Context, llbBridge frontend.FrontendLLBBridge, exec executor.Executor, workers worker.Infos, inputs map[string]*opspb.Definition, sid string, sm *session.Manager) LLBBridgeForwarder {
|
|
| 438 |
+ return newBridgeForwarder(ctx, llbBridge, exec, workers, inputs, sid, sm) |
|
| 439 | 439 |
} |
| 440 | 440 |
|
| 441 |
-func newBridgeForwarder(ctx context.Context, llbBridge frontend.FrontendLLBBridge, workers worker.Infos, inputs map[string]*opspb.Definition, sid string, sm *session.Manager) *llbBridgeForwarder {
|
|
| 441 |
+func newBridgeForwarder(ctx context.Context, llbBridge frontend.FrontendLLBBridge, exec executor.Executor, workers worker.Infos, inputs map[string]*opspb.Definition, sid string, sm *session.Manager) *llbBridgeForwarder {
|
|
| 442 | 442 |
lbf := &llbBridgeForwarder{
|
| 443 | 443 |
callCtx: ctx, |
| 444 | 444 |
llbBridge: llbBridge, |
| ... | ... |
@@ -451,13 +446,14 @@ func newBridgeForwarder(ctx context.Context, llbBridge frontend.FrontendLLBBridg |
| 451 | 451 |
sid: sid, |
| 452 | 452 |
sm: sm, |
| 453 | 453 |
ctrs: map[string]gwclient.Container{},
|
| 454 |
+ executor: exec, |
|
| 454 | 455 |
} |
| 455 | 456 |
return lbf |
| 456 | 457 |
} |
| 457 | 458 |
|
| 458 |
-func serveLLBBridgeForwarder(ctx context.Context, llbBridge frontend.FrontendLLBBridge, workers worker.Infos, inputs map[string]*opspb.Definition, sid string, sm *session.Manager) (*llbBridgeForwarder, context.Context, error) {
|
|
| 459 |
+func serveLLBBridgeForwarder(ctx context.Context, llbBridge frontend.FrontendLLBBridge, exec executor.Executor, workers worker.Infos, inputs map[string]*opspb.Definition, sid string, sm *session.Manager) (*llbBridgeForwarder, context.Context, error) {
|
|
| 459 | 460 |
ctx, cancel := context.WithCancel(ctx) |
| 460 |
- lbf := newBridgeForwarder(ctx, llbBridge, workers, inputs, sid, sm) |
|
| 461 |
+ lbf := newBridgeForwarder(ctx, llbBridge, exec, workers, inputs, sid, sm) |
|
| 461 | 462 |
server := grpc.NewServer(grpc.UnaryInterceptor(grpcerrors.UnaryServerInterceptor), grpc.StreamInterceptor(grpcerrors.StreamServerInterceptor)) |
| 462 | 463 |
grpc_health_v1.RegisterHealthServer(server, health.NewServer()) |
| 463 | 464 |
pb.RegisterLLBBridgeServer(server, lbf) |
| ... | ... |
@@ -552,6 +548,7 @@ type llbBridgeForwarder struct {
|
| 552 | 552 |
isErrServerClosed bool |
| 553 | 553 |
sid string |
| 554 | 554 |
sm *session.Manager |
| 555 |
+ executor executor.Executor |
|
| 555 | 556 |
*pipe |
| 556 | 557 |
ctrs map[string]gwclient.Container |
| 557 | 558 |
ctrsMu sync.Mutex |
| ... | ... |
@@ -646,12 +643,21 @@ func (lbf *llbBridgeForwarder) registerResultIDs(results ...solver.Result) (ids |
| 646 | 646 |
func (lbf *llbBridgeForwarder) Solve(ctx context.Context, req *pb.SolveRequest) (*pb.SolveResponse, error) {
|
| 647 | 647 |
var cacheImports []frontend.CacheOptionsEntry |
| 648 | 648 |
for _, e := range req.CacheImports {
|
| 649 |
+ if e == nil {
|
|
| 650 |
+ return nil, errors.Errorf("invalid nil cache import")
|
|
| 651 |
+ } |
|
| 649 | 652 |
cacheImports = append(cacheImports, frontend.CacheOptionsEntry{
|
| 650 | 653 |
Type: e.Type, |
| 651 | 654 |
Attrs: e.Attrs, |
| 652 | 655 |
}) |
| 653 | 656 |
} |
| 654 | 657 |
|
| 658 |
+ for _, p := range req.SourcePolicies {
|
|
| 659 |
+ if p == nil {
|
|
| 660 |
+ return nil, errors.Errorf("invalid nil source policy")
|
|
| 661 |
+ } |
|
| 662 |
+ } |
|
| 663 |
+ |
|
| 655 | 664 |
ctx = tracing.ContextWithSpanFromContext(ctx, lbf.callCtx) |
| 656 | 665 |
res, err := lbf.llbBridge.Solve(ctx, frontend.SolveRequest{
|
| 657 | 666 |
Evaluate: req.Evaluate, |
| ... | ... |
@@ -1033,7 +1039,7 @@ func (lbf *llbBridgeForwarder) NewContainer(ctx context.Context, in *pb.NewConta |
| 1033 | 1033 |
// and we want the context to live for the duration of the container. |
| 1034 | 1034 |
group := session.NewGroup(lbf.sid) |
| 1035 | 1035 |
|
| 1036 |
- w, err := lbf.workers.GetDefault() |
|
| 1036 |
+ cm, err := lbf.workers.DefaultCacheManager() |
|
| 1037 | 1037 |
if err != nil {
|
| 1038 | 1038 |
return nil, stack.Enable(err) |
| 1039 | 1039 |
} |
| ... | ... |
@@ -1043,7 +1049,7 @@ func (lbf *llbBridgeForwarder) NewContainer(ctx context.Context, in *pb.NewConta |
| 1043 | 1043 |
return nil, stack.Enable(err) |
| 1044 | 1044 |
} |
| 1045 | 1045 |
|
| 1046 |
- ctr, err := container.NewContainer(context.Background(), w, lbf.sm, group, ctrReq) |
|
| 1046 |
+ ctr, err := container.NewContainer(context.Background(), cm, lbf.executor, lbf.sm, group, ctrReq) |
|
| 1047 | 1047 |
if err != nil {
|
| 1048 | 1048 |
return nil, stack.Enable(err) |
| 1049 | 1049 |
} |
| ... | ... |
@@ -1077,6 +1083,12 @@ func (lbf *llbBridgeForwarder) ReleaseContainer(ctx context.Context, in *pb.Rele |
| 1077 | 1077 |
} |
| 1078 | 1078 |
|
| 1079 | 1079 |
func (lbf *llbBridgeForwarder) Warn(ctx context.Context, in *pb.WarnRequest) (*pb.WarnResponse, error) {
|
| 1080 |
+ // validate ranges are valid |
|
| 1081 |
+ for _, r := range in.Ranges {
|
|
| 1082 |
+ if r == nil {
|
|
| 1083 |
+ return nil, status.Errorf(codes.InvalidArgument, "invalid source range") |
|
| 1084 |
+ } |
|
| 1085 |
+ } |
|
| 1080 | 1086 |
err := lbf.llbBridge.Warn(ctx, in.Digest, string(in.Short), frontend.WarnOpts{
|
| 1081 | 1087 |
Level: int(in.Level), |
| 1082 | 1088 |
SourceInfo: in.Info, |
| ... | ... |
@@ -11,22 +11,39 @@ type Mounter interface {
|
| 11 | 11 |
Unmount() error |
| 12 | 12 |
} |
| 13 | 13 |
|
| 14 |
+type LocalMounterOpt func(*localMounter) |
|
| 15 |
+ |
|
| 14 | 16 |
// LocalMounter is a helper for mounting mountfactory to temporary path. In |
| 15 | 17 |
// addition it can mount binds without privileges |
| 16 |
-func LocalMounter(mountable Mountable) Mounter {
|
|
| 17 |
- return &localMounter{mountable: mountable}
|
|
| 18 |
+func LocalMounter(mountable Mountable, opts ...LocalMounterOpt) Mounter {
|
|
| 19 |
+ lm := &localMounter{mountable: mountable}
|
|
| 20 |
+ for _, opt := range opts {
|
|
| 21 |
+ opt(lm) |
|
| 22 |
+ } |
|
| 23 |
+ return lm |
|
| 18 | 24 |
} |
| 19 | 25 |
|
| 20 | 26 |
// LocalMounterWithMounts is a helper for mounting to temporary path. In |
| 21 | 27 |
// addition it can mount binds without privileges |
| 22 |
-func LocalMounterWithMounts(mounts []mount.Mount) Mounter {
|
|
| 23 |
- return &localMounter{mounts: mounts}
|
|
| 28 |
+func LocalMounterWithMounts(mounts []mount.Mount, opts ...LocalMounterOpt) Mounter {
|
|
| 29 |
+ lm := &localMounter{mounts: mounts}
|
|
| 30 |
+ for _, opt := range opts {
|
|
| 31 |
+ opt(lm) |
|
| 32 |
+ } |
|
| 33 |
+ return lm |
|
| 24 | 34 |
} |
| 25 | 35 |
|
| 26 | 36 |
type localMounter struct {
|
| 27 |
- mu sync.Mutex |
|
| 28 |
- mounts []mount.Mount |
|
| 29 |
- mountable Mountable |
|
| 30 |
- target string |
|
| 31 |
- release func() error |
|
| 37 |
+ mu sync.Mutex |
|
| 38 |
+ mounts []mount.Mount |
|
| 39 |
+ mountable Mountable |
|
| 40 |
+ target string |
|
| 41 |
+ release func() error |
|
| 42 |
+ forceRemount bool |
|
| 43 |
+} |
|
| 44 |
+ |
|
| 45 |
+func ForceRemount() LocalMounterOpt {
|
|
| 46 |
+ return func(lm *localMounter) {
|
|
| 47 |
+ lm.forceRemount = true |
|
| 48 |
+ } |
|
| 32 | 49 |
} |
| ... | ... |
@@ -5,6 +5,7 @@ package snapshot |
| 5 | 5 |
|
| 6 | 6 |
import ( |
| 7 | 7 |
"os" |
| 8 |
+ "path/filepath" |
|
| 8 | 9 |
"syscall" |
| 9 | 10 |
|
| 10 | 11 |
"github.com/containerd/containerd/mount" |
| ... | ... |
@@ -34,30 +35,48 @@ func (lm *localMounter) Mount() (string, error) {
|
| 34 | 34 |
} |
| 35 | 35 |
} |
| 36 | 36 |
|
| 37 |
+ var isFile bool |
|
| 37 | 38 |
if len(lm.mounts) == 1 && (lm.mounts[0].Type == "bind" || lm.mounts[0].Type == "rbind") {
|
| 38 |
- ro := false |
|
| 39 |
- for _, opt := range lm.mounts[0].Options {
|
|
| 40 |
- if opt == "ro" {
|
|
| 41 |
- ro = true |
|
| 42 |
- break |
|
| 39 |
+ if !lm.forceRemount {
|
|
| 40 |
+ ro := false |
|
| 41 |
+ for _, opt := range lm.mounts[0].Options {
|
|
| 42 |
+ if opt == "ro" {
|
|
| 43 |
+ ro = true |
|
| 44 |
+ break |
|
| 45 |
+ } |
|
| 43 | 46 |
} |
| 47 |
+ if !ro {
|
|
| 48 |
+ return lm.mounts[0].Source, nil |
|
| 49 |
+ } |
|
| 50 |
+ } |
|
| 51 |
+ fi, err := os.Stat(lm.mounts[0].Source) |
|
| 52 |
+ if err != nil {
|
|
| 53 |
+ return "", err |
|
| 44 | 54 |
} |
| 45 |
- if !ro {
|
|
| 46 |
- return lm.mounts[0].Source, nil |
|
| 55 |
+ if !fi.IsDir() {
|
|
| 56 |
+ isFile = true |
|
| 47 | 57 |
} |
| 48 | 58 |
} |
| 49 | 59 |
|
| 50 |
- dir, err := os.MkdirTemp("", "buildkit-mount")
|
|
| 60 |
+ dest, err := os.MkdirTemp("", "buildkit-mount")
|
|
| 51 | 61 |
if err != nil {
|
| 52 | 62 |
return "", errors.Wrap(err, "failed to create temp dir") |
| 53 | 63 |
} |
| 54 | 64 |
|
| 55 |
- if err := mount.All(lm.mounts, dir); err != nil {
|
|
| 56 |
- os.RemoveAll(dir) |
|
| 57 |
- return "", errors.Wrapf(err, "failed to mount %s: %+v", dir, lm.mounts) |
|
| 65 |
+ if isFile {
|
|
| 66 |
+ dest = filepath.Join(dest, "file") |
|
| 67 |
+ if err := os.WriteFile(dest, []byte{}, 0644); err != nil {
|
|
| 68 |
+ os.RemoveAll(dest) |
|
| 69 |
+ return "", errors.Wrap(err, "failed to create temp file") |
|
| 70 |
+ } |
|
| 71 |
+ } |
|
| 72 |
+ |
|
| 73 |
+ if err := mount.All(lm.mounts, dest); err != nil {
|
|
| 74 |
+ os.RemoveAll(dest) |
|
| 75 |
+ return "", errors.Wrapf(err, "failed to mount %s: %+v", dest, lm.mounts) |
|
| 58 | 76 |
} |
| 59 |
- lm.target = dir |
|
| 60 |
- return dir, nil |
|
| 77 |
+ lm.target = dest |
|
| 78 |
+ return dest, nil |
|
| 61 | 79 |
} |
| 62 | 80 |
|
| 63 | 81 |
func (lm *localMounter) Unmount() error {
|
| ... | ... |
@@ -10,14 +10,11 @@ import ( |
| 10 | 10 |
"github.com/containerd/containerd/pkg/userns" |
| 11 | 11 |
"github.com/containerd/containerd/snapshots" |
| 12 | 12 |
"github.com/docker/docker/pkg/idtools" |
| 13 |
+ "github.com/moby/buildkit/executor" |
|
| 13 | 14 |
"github.com/pkg/errors" |
| 14 | 15 |
) |
| 15 | 16 |
|
| 16 |
-type Mountable interface {
|
|
| 17 |
- // ID() string |
|
| 18 |
- Mount() ([]mount.Mount, func() error, error) |
|
| 19 |
- IdentityMapping() *idtools.IdentityMapping |
|
| 20 |
-} |
|
| 17 |
+type Mountable = executor.MountableRef |
|
| 21 | 18 |
|
| 22 | 19 |
// Snapshotter defines interface that any snapshot implementation should satisfy |
| 23 | 20 |
type Snapshotter interface {
|
| ... | ... |
@@ -11,6 +11,8 @@ import ( |
| 11 | 11 |
"github.com/moby/buildkit/cache/remotecache" |
| 12 | 12 |
"github.com/moby/buildkit/client" |
| 13 | 13 |
"github.com/moby/buildkit/client/llb" |
| 14 |
+ "github.com/moby/buildkit/executor" |
|
| 15 |
+ resourcestypes "github.com/moby/buildkit/executor/resources/types" |
|
| 14 | 16 |
"github.com/moby/buildkit/frontend" |
| 15 | 17 |
gw "github.com/moby/buildkit/frontend/gateway/client" |
| 16 | 18 |
"github.com/moby/buildkit/identity" |
| ... | ... |
@@ -23,6 +25,7 @@ import ( |
| 23 | 23 |
"github.com/moby/buildkit/sourcepolicy" |
| 24 | 24 |
spb "github.com/moby/buildkit/sourcepolicy/pb" |
| 25 | 25 |
"github.com/moby/buildkit/util/bklog" |
| 26 |
+ "github.com/moby/buildkit/util/entitlements" |
|
| 26 | 27 |
"github.com/moby/buildkit/util/flightcontrol" |
| 27 | 28 |
"github.com/moby/buildkit/util/progress" |
| 28 | 29 |
"github.com/moby/buildkit/worker" |
| ... | ... |
@@ -39,6 +42,10 @@ type llbBridge struct {
|
| 39 | 39 |
cms map[string]solver.CacheManager |
| 40 | 40 |
cmsMu sync.Mutex |
| 41 | 41 |
sm *session.Manager |
| 42 |
+ |
|
| 43 |
+ executorOnce sync.Once |
|
| 44 |
+ executorErr error |
|
| 45 |
+ executor executor.Executor |
|
| 42 | 46 |
} |
| 43 | 47 |
|
| 44 | 48 |
func (b *llbBridge) Warn(ctx context.Context, dgst digest.Digest, msg string, opts frontend.WarnOpts) error {
|
| ... | ... |
@@ -79,6 +86,14 @@ func (b *llbBridge) loadResult(ctx context.Context, def *pb.Definition, cacheImp |
| 79 | 79 |
} |
| 80 | 80 |
var polEngine SourcePolicyEvaluator |
| 81 | 81 |
if srcPol != nil || len(pol) > 0 {
|
| 82 |
+ for _, p := range pol {
|
|
| 83 |
+ if p == nil {
|
|
| 84 |
+ return nil, errors.Errorf("invalid nil policy")
|
|
| 85 |
+ } |
|
| 86 |
+ if err := validateSourcePolicy(*p); err != nil {
|
|
| 87 |
+ return nil, err |
|
| 88 |
+ } |
|
| 89 |
+ } |
|
| 82 | 90 |
if srcPol != nil {
|
| 83 | 91 |
pol = append([]*spb.Policy{srcPol}, pol...)
|
| 84 | 92 |
} |
| ... | ... |
@@ -151,6 +166,52 @@ func (b *llbBridge) loadResult(ctx context.Context, def *pb.Definition, cacheImp |
| 151 | 151 |
return res, nil |
| 152 | 152 |
} |
| 153 | 153 |
|
| 154 |
+func (b *llbBridge) validateEntitlements(p executor.ProcessInfo) error {
|
|
| 155 |
+ ent, err := loadEntitlements(b.builder) |
|
| 156 |
+ if err != nil {
|
|
| 157 |
+ return err |
|
| 158 |
+ } |
|
| 159 |
+ v := entitlements.Values{
|
|
| 160 |
+ NetworkHost: p.Meta.NetMode == pb.NetMode_HOST, |
|
| 161 |
+ SecurityInsecure: p.Meta.SecurityMode == pb.SecurityMode_INSECURE, |
|
| 162 |
+ } |
|
| 163 |
+ return ent.Check(v) |
|
| 164 |
+} |
|
| 165 |
+ |
|
| 166 |
+func (b *llbBridge) Run(ctx context.Context, id string, rootfs executor.Mount, mounts []executor.Mount, process executor.ProcessInfo, started chan<- struct{}) (resourcestypes.Recorder, error) {
|
|
| 167 |
+ if err := b.validateEntitlements(process); err != nil {
|
|
| 168 |
+ return nil, err |
|
| 169 |
+ } |
|
| 170 |
+ |
|
| 171 |
+ if err := b.loadExecutor(); err != nil {
|
|
| 172 |
+ return nil, err |
|
| 173 |
+ } |
|
| 174 |
+ return b.executor.Run(ctx, id, rootfs, mounts, process, started) |
|
| 175 |
+} |
|
| 176 |
+ |
|
| 177 |
+func (b *llbBridge) Exec(ctx context.Context, id string, process executor.ProcessInfo) error {
|
|
| 178 |
+ if err := b.validateEntitlements(process); err != nil {
|
|
| 179 |
+ return err |
|
| 180 |
+ } |
|
| 181 |
+ |
|
| 182 |
+ if err := b.loadExecutor(); err != nil {
|
|
| 183 |
+ return err |
|
| 184 |
+ } |
|
| 185 |
+ return b.executor.Exec(ctx, id, process) |
|
| 186 |
+} |
|
| 187 |
+ |
|
| 188 |
+func (b *llbBridge) loadExecutor() error {
|
|
| 189 |
+ b.executorOnce.Do(func() {
|
|
| 190 |
+ w, err := b.resolveWorker() |
|
| 191 |
+ if err != nil {
|
|
| 192 |
+ b.executorErr = err |
|
| 193 |
+ return |
|
| 194 |
+ } |
|
| 195 |
+ b.executor = w.Executor() |
|
| 196 |
+ }) |
|
| 197 |
+ return b.executorErr |
|
| 198 |
+} |
|
| 199 |
+ |
|
| 154 | 200 |
type resultProxy struct {
|
| 155 | 201 |
id string |
| 156 | 202 |
b *provenanceBridge |
| ... | ... |
@@ -165,7 +165,7 @@ func (b *provenanceBridge) Solve(ctx context.Context, req frontend.SolveRequest, |
| 165 | 165 |
return nil, errors.Errorf("invalid frontend: %s", req.Frontend)
|
| 166 | 166 |
} |
| 167 | 167 |
wb := &provenanceBridge{llbBridge: b.llbBridge, req: &req}
|
| 168 |
- res, err = f.Solve(ctx, wb, req.FrontendOpt, req.FrontendInputs, sid, b.llbBridge.sm) |
|
| 168 |
+ res, err = f.Solve(ctx, wb, b.llbBridge, req.FrontendOpt, req.FrontendInputs, sid, b.llbBridge.sm) |
|
| 169 | 169 |
if err != nil {
|
| 170 | 170 |
return nil, err |
| 171 | 171 |
} |
| ... | ... |
@@ -447,6 +447,9 @@ func (s *Solver) Solve(ctx context.Context, id string, sessionID string, req fro |
| 447 | 447 |
j.SetValue(keyEntitlements, set) |
| 448 | 448 |
|
| 449 | 449 |
if srcPol != nil {
|
| 450 |
+ if err := validateSourcePolicy(*srcPol); err != nil {
|
|
| 451 |
+ return nil, err |
|
| 452 |
+ } |
|
| 450 | 453 |
j.SetValue(keySourcePolicy, *srcPol) |
| 451 | 454 |
} |
| 452 | 455 |
|
| ... | ... |
@@ -455,7 +458,7 @@ func (s *Solver) Solve(ctx context.Context, id string, sessionID string, req fro |
| 455 | 455 |
br := s.bridge(j) |
| 456 | 456 |
var fwd gateway.LLBBridgeForwarder |
| 457 | 457 |
if s.gatewayForwarder != nil && req.Definition == nil && req.Frontend == "" {
|
| 458 |
- fwd = gateway.NewBridgeForwarder(ctx, br, s.workerController, req.FrontendInputs, sessionID, s.sm) |
|
| 458 |
+ fwd = gateway.NewBridgeForwarder(ctx, br, br, s.workerController.Infos(), req.FrontendInputs, sessionID, s.sm) |
|
| 459 | 459 |
defer fwd.Discard() |
| 460 | 460 |
// Register build before calling s.recordBuildHistory, because |
| 461 | 461 |
// s.recordBuildHistory can block for several seconds on |
| ... | ... |
@@ -595,6 +598,23 @@ func (s *Solver) Solve(ctx context.Context, id string, sessionID string, req fro |
| 595 | 595 |
}, nil |
| 596 | 596 |
} |
| 597 | 597 |
|
| 598 |
+func validateSourcePolicy(pol spb.Policy) error {
|
|
| 599 |
+ for _, r := range pol.Rules {
|
|
| 600 |
+ if r == nil {
|
|
| 601 |
+ return errors.New("invalid nil rule in policy")
|
|
| 602 |
+ } |
|
| 603 |
+ if r.Selector == nil {
|
|
| 604 |
+ return errors.New("invalid nil selector in policy")
|
|
| 605 |
+ } |
|
| 606 |
+ for _, c := range r.Selector.Constraints {
|
|
| 607 |
+ if c == nil {
|
|
| 608 |
+ return errors.New("invalid nil constraint in policy")
|
|
| 609 |
+ } |
|
| 610 |
+ } |
|
| 611 |
+ } |
|
| 612 |
+ return nil |
|
| 613 |
+} |
|
| 614 |
+ |
|
| 598 | 615 |
func runCacheExporters(ctx context.Context, exporters []RemoteCacheExporter, j *solver.Job, cached *result.Result[solver.CachedResult], inp *result.Result[cache.ImmutableRef]) (map[string]string, error) {
|
| 599 | 616 |
eg, ctx := errgroup.WithContext(ctx) |
| 600 | 617 |
g := session.NewGroup(j.SessionID) |
| ... | ... |
@@ -991,6 +1011,9 @@ func loadSourcePolicy(b solver.Builder) (*spb.Policy, error) {
|
| 991 | 991 |
return errors.Errorf("invalid source policy %T", v)
|
| 992 | 992 |
} |
| 993 | 993 |
for _, f := range x.Rules {
|
| 994 |
+ if f == nil {
|
|
| 995 |
+ return errors.Errorf("invalid nil policy rule")
|
|
| 996 |
+ } |
|
| 994 | 997 |
r := *f |
| 995 | 998 |
srcPol.Rules = append(srcPol.Rules, &r) |
| 996 | 999 |
} |
| ... | ... |
@@ -101,16 +101,12 @@ func ValidateEntitlements(ent entitlements.Set) LoadOpt {
|
| 101 | 101 |
return func(op *pb.Op, _ *pb.OpMetadata, opt *solver.VertexOptions) error {
|
| 102 | 102 |
switch op := op.Op.(type) {
|
| 103 | 103 |
case *pb.Op_Exec: |
| 104 |
- if op.Exec.Network == pb.NetMode_HOST {
|
|
| 105 |
- if !ent.Allowed(entitlements.EntitlementNetworkHost) {
|
|
| 106 |
- return errors.Errorf("%s is not allowed", entitlements.EntitlementNetworkHost)
|
|
| 107 |
- } |
|
| 104 |
+ v := entitlements.Values{
|
|
| 105 |
+ NetworkHost: op.Exec.Network == pb.NetMode_HOST, |
|
| 106 |
+ SecurityInsecure: op.Exec.Security == pb.SecurityMode_INSECURE, |
|
| 108 | 107 |
} |
| 109 |
- |
|
| 110 |
- if op.Exec.Security == pb.SecurityMode_INSECURE {
|
|
| 111 |
- if !ent.Allowed(entitlements.EntitlementSecurityInsecure) {
|
|
| 112 |
- return errors.Errorf("%s is not allowed", entitlements.EntitlementSecurityInsecure)
|
|
| 113 |
- } |
|
| 108 |
+ if err := ent.Check(v); err != nil {
|
|
| 109 |
+ return err |
|
| 114 | 110 |
} |
| 115 | 111 |
} |
| 116 | 112 |
return nil |
| ... | ... |
@@ -10,6 +10,9 @@ import ( |
| 10 | 10 |
|
| 11 | 11 |
func match(ctx context.Context, src *selectorCache, ref string, attrs map[string]string) (bool, error) {
|
| 12 | 12 |
for _, c := range src.Constraints {
|
| 13 |
+ if c == nil {
|
|
| 14 |
+ return false, errors.Errorf("invalid nil constraint for %v", src)
|
|
| 15 |
+ } |
|
| 13 | 16 |
switch c.Condition {
|
| 14 | 17 |
case spb.AttrMatch_EQUAL: |
| 15 | 18 |
if attrs[c.Key] != c.Value {
|
| ... | ... |
@@ -58,3 +58,23 @@ func (s Set) Allowed(e Entitlement) bool {
|
| 58 | 58 |
_, ok := s[e] |
| 59 | 59 |
return ok |
| 60 | 60 |
} |
| 61 |
+ |
|
| 62 |
+func (s Set) Check(v Values) error {
|
|
| 63 |
+ if v.NetworkHost {
|
|
| 64 |
+ if !s.Allowed(EntitlementNetworkHost) {
|
|
| 65 |
+ return errors.Errorf("%s is not allowed", EntitlementNetworkHost)
|
|
| 66 |
+ } |
|
| 67 |
+ } |
|
| 68 |
+ |
|
| 69 |
+ if v.SecurityInsecure {
|
|
| 70 |
+ if !s.Allowed(EntitlementSecurityInsecure) {
|
|
| 71 |
+ return errors.Errorf("%s is not allowed", EntitlementSecurityInsecure)
|
|
| 72 |
+ } |
|
| 73 |
+ } |
|
| 74 |
+ return nil |
|
| 75 |
+} |
|
| 76 |
+ |
|
| 77 |
+type Values struct {
|
|
| 78 |
+ NetworkHost bool |
|
| 79 |
+ SecurityInsecure bool |
|
| 80 |
+} |
| ... | ... |
@@ -13,6 +13,9 @@ func Attributes(attrs []*commonpb.KeyValue) []attribute.KeyValue {
|
| 13 | 13 |
|
| 14 | 14 |
out := make([]attribute.KeyValue, 0, len(attrs)) |
| 15 | 15 |
for _, a := range attrs {
|
| 16 |
+ if a == nil {
|
|
| 17 |
+ continue |
|
| 18 |
+ } |
|
| 16 | 19 |
kv := attribute.KeyValue{
|
| 17 | 20 |
Key: attribute.Key(a.Key), |
| 18 | 21 |
Value: toValue(a.Value), |
| ... | ... |
@@ -42,7 +45,9 @@ func toValue(v *commonpb.AnyValue) attribute.Value {
|
| 42 | 42 |
func boolArray(kv []*commonpb.AnyValue) attribute.Value {
|
| 43 | 43 |
arr := make([]bool, len(kv)) |
| 44 | 44 |
for i, v := range kv {
|
| 45 |
- arr[i] = v.GetBoolValue() |
|
| 45 |
+ if v != nil {
|
|
| 46 |
+ arr[i] = v.GetBoolValue() |
|
| 47 |
+ } |
|
| 46 | 48 |
} |
| 47 | 49 |
return attribute.BoolSliceValue(arr) |
| 48 | 50 |
} |
| ... | ... |
@@ -50,7 +55,9 @@ func boolArray(kv []*commonpb.AnyValue) attribute.Value {
|
| 50 | 50 |
func intArray(kv []*commonpb.AnyValue) attribute.Value {
|
| 51 | 51 |
arr := make([]int64, len(kv)) |
| 52 | 52 |
for i, v := range kv {
|
| 53 |
- arr[i] = v.GetIntValue() |
|
| 53 |
+ if v != nil {
|
|
| 54 |
+ arr[i] = v.GetIntValue() |
|
| 55 |
+ } |
|
| 54 | 56 |
} |
| 55 | 57 |
return attribute.Int64SliceValue(arr) |
| 56 | 58 |
} |
| ... | ... |
@@ -58,7 +65,9 @@ func intArray(kv []*commonpb.AnyValue) attribute.Value {
|
| 58 | 58 |
func doubleArray(kv []*commonpb.AnyValue) attribute.Value {
|
| 59 | 59 |
arr := make([]float64, len(kv)) |
| 60 | 60 |
for i, v := range kv {
|
| 61 |
- arr[i] = v.GetDoubleValue() |
|
| 61 |
+ if v != nil {
|
|
| 62 |
+ arr[i] = v.GetDoubleValue() |
|
| 63 |
+ } |
|
| 62 | 64 |
} |
| 63 | 65 |
return attribute.Float64SliceValue(arr) |
| 64 | 66 |
} |
| ... | ... |
@@ -66,13 +75,15 @@ func doubleArray(kv []*commonpb.AnyValue) attribute.Value {
|
| 66 | 66 |
func stringArray(kv []*commonpb.AnyValue) attribute.Value {
|
| 67 | 67 |
arr := make([]string, len(kv)) |
| 68 | 68 |
for i, v := range kv {
|
| 69 |
- arr[i] = v.GetStringValue() |
|
| 69 |
+ if v != nil {
|
|
| 70 |
+ arr[i] = v.GetStringValue() |
|
| 71 |
+ } |
|
| 70 | 72 |
} |
| 71 | 73 |
return attribute.StringSliceValue(arr) |
| 72 | 74 |
} |
| 73 | 75 |
|
| 74 | 76 |
func arrayValues(kv []*commonpb.AnyValue) attribute.Value {
|
| 75 |
- if len(kv) == 0 {
|
|
| 77 |
+ if len(kv) == 0 || kv[0] == nil {
|
|
| 76 | 78 |
return attribute.StringSliceValue([]string{})
|
| 77 | 79 |
} |
| 78 | 80 |
|
| ... | ... |
@@ -32,14 +32,20 @@ func Spans(sdl []*tracepb.ResourceSpans) []tracesdk.ReadOnlySpan {
|
| 32 | 32 |
} |
| 33 | 33 |
|
| 34 | 34 |
for _, sdi := range sd.ScopeSpans {
|
| 35 |
- sda := make([]tracesdk.ReadOnlySpan, len(sdi.Spans)) |
|
| 36 |
- for i, s := range sdi.Spans {
|
|
| 37 |
- sda[i] = &readOnlySpan{
|
|
| 35 |
+ if sdi == nil {
|
|
| 36 |
+ continue |
|
| 37 |
+ } |
|
| 38 |
+ sda := make([]tracesdk.ReadOnlySpan, 0, len(sdi.Spans)) |
|
| 39 |
+ for _, s := range sdi.Spans {
|
|
| 40 |
+ if s == nil {
|
|
| 41 |
+ continue |
|
| 42 |
+ } |
|
| 43 |
+ sda = append(sda, &readOnlySpan{
|
|
| 38 | 44 |
pb: s, |
| 39 | 45 |
is: sdi.Scope, |
| 40 | 46 |
resource: sd.Resource, |
| 41 | 47 |
schemaURL: sd.SchemaUrl, |
| 42 |
- } |
|
| 48 |
+ }) |
|
| 43 | 49 |
} |
| 44 | 50 |
out = append(out, sda...) |
| 45 | 51 |
} |
| ... | ... |
@@ -170,6 +176,9 @@ var _ tracesdk.ReadOnlySpan = &readOnlySpan{}
|
| 170 | 170 |
|
| 171 | 171 |
// status transform a OTLP span status into span code. |
| 172 | 172 |
func statusCode(st *tracepb.Status) codes.Code {
|
| 173 |
+ if st == nil {
|
|
| 174 |
+ return codes.Unset |
|
| 175 |
+ } |
|
| 173 | 176 |
switch st.Code {
|
| 174 | 177 |
case tracepb.Status_STATUS_CODE_ERROR: |
| 175 | 178 |
return codes.Error |
| ... | ... |
@@ -186,6 +195,9 @@ func links(links []*tracepb.Span_Link) []tracesdk.Link {
|
| 186 | 186 |
|
| 187 | 187 |
sl := make([]tracesdk.Link, 0, len(links)) |
| 188 | 188 |
for _, otLink := range links {
|
| 189 |
+ if otLink == nil {
|
|
| 190 |
+ continue |
|
| 191 |
+ } |
|
| 189 | 192 |
// This redefinition is necessary to prevent otLink.*ID[:] copies |
| 190 | 193 |
// being reused -- in short we need a new otLink per iteration. |
| 191 | 194 |
otLink := otLink |
| ... | ... |
@@ -226,6 +238,9 @@ func spanEvents(es []*tracepb.Span_Event) []tracesdk.Event {
|
| 226 | 226 |
if messageEvents >= maxMessageEventsPerSpan {
|
| 227 | 227 |
break |
| 228 | 228 |
} |
| 229 |
+ if e == nil {
|
|
| 230 |
+ continue |
|
| 231 |
+ } |
|
| 229 | 232 |
messageEvents++ |
| 230 | 233 |
events = append(events, |
| 231 | 234 |
tracesdk.Event{
|
| ... | ... |
@@ -3,6 +3,7 @@ package worker |
| 3 | 3 |
import ( |
| 4 | 4 |
"github.com/containerd/containerd/filters" |
| 5 | 5 |
"github.com/hashicorp/go-multierror" |
| 6 |
+ "github.com/moby/buildkit/cache" |
|
| 6 | 7 |
"github.com/moby/buildkit/client" |
| 7 | 8 |
"github.com/pkg/errors" |
| 8 | 9 |
) |
| ... | ... |
@@ -81,3 +82,25 @@ func (c *Controller) WorkerInfos() []client.WorkerInfo {
|
| 81 | 81 |
} |
| 82 | 82 |
return out |
| 83 | 83 |
} |
| 84 |
+ |
|
| 85 |
+func (c *Controller) Infos() Infos {
|
|
| 86 |
+ return &infosController{c: c}
|
|
| 87 |
+} |
|
| 88 |
+ |
|
| 89 |
+type infosController struct {
|
|
| 90 |
+ c *Controller |
|
| 91 |
+} |
|
| 92 |
+ |
|
| 93 |
+var _ Infos = &infosController{}
|
|
| 94 |
+ |
|
| 95 |
+func (c *infosController) DefaultCacheManager() (cache.Manager, error) {
|
|
| 96 |
+ w, err := c.c.GetDefault() |
|
| 97 |
+ if err != nil {
|
|
| 98 |
+ return nil, err |
|
| 99 |
+ } |
|
| 100 |
+ return w.CacheManager(), nil |
|
| 101 |
+} |
|
| 102 |
+ |
|
| 103 |
+func (c *infosController) WorkerInfos() []client.WorkerInfo {
|
|
| 104 |
+ return c.c.WorkerInfos() |
|
| 105 |
+} |
| ... | ... |
@@ -682,7 +682,7 @@ github.com/mitchellh/hashstructure/v2 |
| 682 | 682 |
# github.com/mitchellh/reflectwalk v1.0.2 |
| 683 | 683 |
## explicit |
| 684 | 684 |
github.com/mitchellh/reflectwalk |
| 685 |
-# github.com/moby/buildkit v0.12.5-0.20231208203051-3b6880d2a00f |
|
| 685 |
+# github.com/moby/buildkit v0.12.5 |
|
| 686 | 686 |
## explicit; go 1.20 |
| 687 | 687 |
github.com/moby/buildkit/api/services/control |
| 688 | 688 |
github.com/moby/buildkit/api/types |