From 6b9f5324cab1f1683677019ad132f0d3a1c04cf1 Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Wed, 5 Aug 2026 12:29:45 +0200 Subject: [PATCH] avoid policy dependency from builder loading Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- builder/builder.go | 3 ++- builder/node.go | 34 ++++++++++++---------------------- commands/bake.go | 4 +++- commands/build.go | 7 +++++-- commands/create.go | 3 +++ commands/dial_stdio.go | 5 ++++- commands/history/utils.go | 7 +++++-- commands/inspect.go | 7 +++++-- driver/image.go | 4 ++-- driver/image_test.go | 6 +++--- driver/manager.go | 4 ++-- policy/default.go | 24 ++++++++++++++++++++++++ 12 files changed, 70 insertions(+), 38 deletions(-) diff --git a/builder/builder.go b/builder/builder.go index fabd53f24507..b3daa323f859 100644 --- a/builder/builder.go +++ b/builder/builder.go @@ -347,6 +347,7 @@ type CreateOpts struct { Endpoint string Append bool Timeout time.Duration + ImageVerifier driver.ImageVerifier } func Create(ctx context.Context, txn *store.Txn, dockerCli command.Cli, opts CreateOpts) (*Builder, error) { @@ -532,7 +533,7 @@ func Create(ctx context.Context, txn *store.Txn, dockerCli command.Cli, opts Cre } defer func() { cancel(errors.WithStack(context.Canceled)) }() - nodes, err := b.LoadNodes(timeoutCtx, WithData()) + nodes, err := b.LoadNodes(timeoutCtx, WithData(), WithImageVerifier(opts.ImageVerifier)) if err != nil { return nil, err } diff --git a/builder/node.go b/builder/node.go index 95e56e3b03d7..9825903d6287 100644 --- a/builder/node.go +++ b/builder/node.go @@ -8,19 +8,15 @@ import ( "github.com/containerd/platforms" "github.com/docker/buildx/driver" - "github.com/docker/buildx/policy" "github.com/docker/buildx/store" "github.com/docker/buildx/store/storeutil" - "github.com/docker/buildx/util/confutil" "github.com/docker/buildx/util/dockerutil" "github.com/docker/buildx/util/imagetools" "github.com/docker/buildx/util/platformutil" "github.com/moby/buildkit/client" "github.com/moby/buildkit/util/grpcerrors" - digest "github.com/opencontainers/go-digest" ocispecs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" - "github.com/sirupsen/logrus" "golang.org/x/sync/errgroup" "google.golang.org/grpc/codes" ) @@ -51,10 +47,11 @@ func (b *Builder) Nodes() []Node { type LoadNodesOption func(*loadNodesOptions) type loadNodesOptions struct { - data bool - skipImageOpt bool - dialMeta map[string][]string - clientOpt []client.ClientOpt + data bool + skipImageOpt bool + dialMeta map[string][]string + clientOpt []client.ClientOpt + imageVerifier driver.ImageVerifier } func WithData() LoadNodesOption { @@ -81,6 +78,12 @@ func WithClientOpt(clientOpt ...client.ClientOpt) LoadNodesOption { } } +func WithImageVerifier(imageVerifier driver.ImageVerifier) LoadNodesOption { + return func(o *loadNodesOptions) { + o.imageVerifier = imageVerifier + } +} + // LoadNodes loads and returns nodes for this builder. // TODO: this should be a method on a Node object and lazy load data for each driver. func (b *Builder) LoadNodes(ctx context.Context, opts ...LoadNodesOption) (_ []Node, err error) { @@ -113,19 +116,6 @@ func (b *Builder) LoadNodes(ctx context.Context, opts ...LoadNodesOption) (_ []N } } - var imageVerifier driver.ImageVerifier - if policy.DefaultPolicyEnabled() { - pol := policy.DefaultPolicy(policy.Opt{ - Log: func(_ logrus.Level, msg string) { - logrus.Debug(msg) - }, - VerifierProvider: policy.SignatureVerifier(confutil.NewConfig(b.opts.dockerCli)), - }) - imageVerifier = func(ctx context.Context, ref string, platform *ocispecs.Platform, resolver policy.SourceMetadataResolver) (digest.Digest, error) { - return pol.CheckSource(ctx, ref, platform, resolver) - } - } - for i, n := range b.NodeGroup.Nodes { func(i int, n store.Node) { eg.Go(func() error { @@ -154,7 +144,7 @@ func (b *Builder) LoadNodes(ctx context.Context, opts ...LoadNodesOption) (_ []N Files: n.Files, DriverOpts: n.DriverOpts, Auth: imageopt.Auth, - ImageVerifier: imageVerifier, + ImageVerifier: lno.imageVerifier, Platforms: n.Platforms, ContextPathHash: b.opts.contextPathHash, DialMeta: lno.dialMeta, diff --git a/commands/bake.go b/commands/bake.go index 6fcde330d1fd..2924177f24d0 100644 --- a/commands/bake.go +++ b/commands/bake.go @@ -25,6 +25,7 @@ import ( "github.com/docker/buildx/build" "github.com/docker/buildx/builder" "github.com/docker/buildx/localstate" + "github.com/docker/buildx/policy" "github.com/docker/buildx/util/buildflags" "github.com/docker/buildx/util/cobrautil" "github.com/docker/buildx/util/cobrautil/completion" @@ -168,7 +169,8 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba if err = updateLastActivity(dockerCli, b.NodeGroup); err != nil { return errors.Wrapf(err, "failed to update builder last activity time") } - nodes, err = b.LoadNodes(ctx) + imageVerifier := policy.DefaultImageVerifier(confutil.NewConfig(dockerCli)) + nodes, err = b.LoadNodes(ctx, builder.WithImageVerifier(imageVerifier)) if err != nil { return err } diff --git a/commands/build.go b/commands/build.go index 04d20bea6e41..5f267704052a 100644 --- a/commands/build.go +++ b/commands/build.go @@ -21,6 +21,7 @@ import ( "github.com/containerd/containerd/v2/pkg/epoch" "github.com/docker/buildx/build" "github.com/docker/buildx/builder" + "github.com/docker/buildx/policy" "github.com/docker/buildx/store" "github.com/docker/buildx/store/storeutil" "github.com/docker/buildx/util/buildflags" @@ -356,7 +357,8 @@ func runBuild(ctx context.Context, dockerCli command.Cli, debugOpts debuggerOpti if err != nil { return err } - _, err = b.LoadNodes(ctx) + imageVerifier := policy.DefaultImageVerifier(confutil.NewConfig(dockerCli)) + _, err = b.LoadNodes(ctx, builder.WithImageVerifier(imageVerifier)) if err != nil { return err } @@ -1193,7 +1195,8 @@ func RunBuild(ctx context.Context, dockerCli command.Cli, in *BuildOptions, inSt if err = updateLastActivity(dockerCli, b.NodeGroup); err != nil { return nil, nil, errors.Wrapf(err, "failed to update builder last activity time") } - nodes, err := b.LoadNodes(ctx) + imageVerifier := policy.DefaultImageVerifier(confutil.NewConfig(dockerCli)) + nodes, err := b.LoadNodes(ctx, builder.WithImageVerifier(imageVerifier)) if err != nil { return nil, nil, err } diff --git a/commands/create.go b/commands/create.go index 025a3750ff25..0c8523549ea5 100644 --- a/commands/create.go +++ b/commands/create.go @@ -8,9 +8,11 @@ import ( "github.com/docker/buildx/builder" "github.com/docker/buildx/driver" + "github.com/docker/buildx/policy" "github.com/docker/buildx/store/storeutil" "github.com/docker/buildx/util/cobrautil" "github.com/docker/buildx/util/cobrautil/completion" + "github.com/docker/buildx/util/confutil" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/spf13/cobra" @@ -64,6 +66,7 @@ func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, arg Endpoint: ep, Append: in.actionAppend, Timeout: in.timeout, + ImageVerifier: policy.DefaultImageVerifier(confutil.NewConfig(dockerCli)), }) if err != nil { return err diff --git a/commands/dial_stdio.go b/commands/dial_stdio.go index 0c77f8532c1a..afbfeed91378 100644 --- a/commands/dial_stdio.go +++ b/commands/dial_stdio.go @@ -9,6 +9,8 @@ import ( "github.com/containerd/platforms" "github.com/docker/buildx/build" "github.com/docker/buildx/builder" + "github.com/docker/buildx/policy" + "github.com/docker/buildx/util/confutil" "github.com/docker/buildx/util/progress" "github.com/docker/cli/cli/command" "github.com/moby/buildkit/util/appcontext" @@ -39,7 +41,8 @@ func runDialStdio(dockerCli command.Cli, opts stdioOptions) error { if err = updateLastActivity(dockerCli, b.NodeGroup); err != nil { return errors.Wrapf(err, "failed to update builder last activity time") } - nodes, err := b.LoadNodes(ctx) + imageVerifier := policy.DefaultImageVerifier(confutil.NewConfig(dockerCli)) + nodes, err := b.LoadNodes(ctx, builder.WithImageVerifier(imageVerifier)) if err != nil { return err } diff --git a/commands/history/utils.go b/commands/history/utils.go index a05c9e9c1dd5..43b2b593f3c0 100644 --- a/commands/history/utils.go +++ b/commands/history/utils.go @@ -13,6 +13,8 @@ import ( "time" "github.com/docker/buildx/builder" + "github.com/docker/buildx/policy" + "github.com/docker/buildx/util/confutil" "github.com/docker/cli/cli/command" "github.com/docker/go-units" controlapi "github.com/moby/buildkit/api/services/control" @@ -356,14 +358,15 @@ func loadNodes(ctx context.Context, dockerCli command.Cli, builderName string) ( if err != nil { return nil, err } - nodes, err := b.LoadNodes(ctx, builder.WithData()) + imageVerifier := policy.DefaultImageVerifier(confutil.NewConfig(dockerCli)) + nodes, err := b.LoadNodes(ctx, builder.WithData(), builder.WithImageVerifier(imageVerifier)) if err != nil { return nil, err } if ok, err := b.Boot(ctx); err != nil { return nil, err } else if ok { - nodes, err = b.LoadNodes(ctx, builder.WithData()) + nodes, err = b.LoadNodes(ctx, builder.WithData(), builder.WithImageVerifier(imageVerifier)) if err != nil { return nil, err } diff --git a/commands/inspect.go b/commands/inspect.go index 9e891217aeb5..72d74c9a06eb 100644 --- a/commands/inspect.go +++ b/commands/inspect.go @@ -11,7 +11,9 @@ import ( "github.com/docker/buildx/builder" "github.com/docker/buildx/driver" + "github.com/docker/buildx/policy" "github.com/docker/buildx/util/cobrautil/completion" + "github.com/docker/buildx/util/confutil" "github.com/docker/buildx/util/platformutil" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -42,7 +44,8 @@ func runInspect(ctx context.Context, dockerCli command.Cli, in inspectOptions) e } defer func() { cancel(errors.WithStack(context.Canceled)) }() - nodes, err := b.LoadNodes(timeoutCtx, builder.WithData()) + imageVerifier := policy.DefaultImageVerifier(confutil.NewConfig(dockerCli)) + nodes, err := b.LoadNodes(timeoutCtx, builder.WithData(), builder.WithImageVerifier(imageVerifier)) if in.bootstrap { var ok bool ok, err = b.Boot(ctx) @@ -50,7 +53,7 @@ func runInspect(ctx context.Context, dockerCli command.Cli, in inspectOptions) e return err } if ok { - nodes, err = b.LoadNodes(timeoutCtx, builder.WithData()) + nodes, err = b.LoadNodes(timeoutCtx, builder.WithData(), builder.WithImageVerifier(imageVerifier)) } } diff --git a/driver/image.go b/driver/image.go index d44f121884dc..86d9cb5654d3 100644 --- a/driver/image.go +++ b/driver/image.go @@ -5,8 +5,8 @@ import ( "github.com/distribution/reference" "github.com/docker/buildx/driver/bkimage" - "github.com/docker/buildx/policy" "github.com/docker/buildx/util/progress" + "github.com/docker/buildx/util/sourcemeta" digest "github.com/opencontainers/go-digest" ocispecs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" @@ -20,7 +20,7 @@ import ( // moby/buildkit repository (unmanaged images pass through the default policy // unchanged). A tagged canonical reference is still verified because its tag // carries the release identity checked by the policy. -func VerifyImageRef(ctx context.Context, l progress.SubLogger, ref string, platform *ocispecs.Platform, resolver policy.SourceMetadataResolver, verify ImageVerifier) (string, bool, error) { +func VerifyImageRef(ctx context.Context, l progress.SubLogger, ref string, platform *ocispecs.Platform, resolver *sourcemeta.Resolver, verify ImageVerifier) (string, bool, error) { if verify == nil { return ref, false, nil } diff --git a/driver/image_test.go b/driver/image_test.go index a40b2261af4a..43c092abc756 100644 --- a/driver/image_test.go +++ b/driver/image_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - "github.com/docker/buildx/policy" + "github.com/docker/buildx/util/sourcemeta" "github.com/moby/buildkit/client" digest "github.com/opencontainers/go-digest" ocispecs "github.com/opencontainers/image-spec/specs-go/v1" @@ -22,7 +22,7 @@ func TestVerifyImageRefTaggedCanonical(t *testing.T) { ref := "moby/buildkit:v0.31.2@" + dgst.String() var verifiedRef string - pinned, applied, err := VerifyImageRef(context.Background(), nopSubLogger{}, ref, nil, nil, func(_ context.Context, ref string, _ *ocispecs.Platform, _ policy.SourceMetadataResolver) (digest.Digest, error) { + pinned, applied, err := VerifyImageRef(context.Background(), nopSubLogger{}, ref, nil, nil, func(_ context.Context, ref string, _ *ocispecs.Platform, _ *sourcemeta.Resolver) (digest.Digest, error) { verifiedRef = ref return dgst, nil }) @@ -36,7 +36,7 @@ func TestVerifyImageRefDigestOnly(t *testing.T) { dgst := digest.FromString("buildkit") called := false - pinned, applied, err := VerifyImageRef(context.Background(), nopSubLogger{}, "moby/buildkit@"+dgst.String(), nil, nil, func(_ context.Context, _ string, _ *ocispecs.Platform, _ policy.SourceMetadataResolver) (digest.Digest, error) { + pinned, applied, err := VerifyImageRef(context.Background(), nopSubLogger{}, "moby/buildkit@"+dgst.String(), nil, nil, func(_ context.Context, _ string, _ *ocispecs.Platform, _ *sourcemeta.Resolver) (digest.Digest, error) { called = true return dgst, nil }) diff --git a/driver/manager.go b/driver/manager.go index b9ef2c275af5..546043f1cebe 100644 --- a/driver/manager.go +++ b/driver/manager.go @@ -5,7 +5,7 @@ import ( "sort" "sync" - "github.com/docker/buildx/policy" + "github.com/docker/buildx/util/sourcemeta" "github.com/docker/cli/cli/context/store" "github.com/moby/buildkit/client" "github.com/moby/buildkit/session/auth/authprovider" @@ -36,7 +36,7 @@ type BuildkitConfig struct { // Source metadata is resolved through the given resolver, which drivers back // with a BuildKit instance they have access to so that registry access // happens where the image is pulled from. -type ImageVerifier func(ctx context.Context, ref string, platform *ocispecs.Platform, resolver policy.SourceMetadataResolver) (digest.Digest, error) +type ImageVerifier func(ctx context.Context, ref string, platform *ocispecs.Platform, resolver *sourcemeta.Resolver) (digest.Digest, error) type InitConfig struct { Name string diff --git a/policy/default.go b/policy/default.go index 9161f083584b..b5b7a5a65824 100644 --- a/policy/default.go +++ b/policy/default.go @@ -1,10 +1,17 @@ package policy import ( + "context" _ "embed" "os" "strconv" "sync" + + "github.com/docker/buildx/util/confutil" + "github.com/docker/buildx/util/sourcemeta" + digest "github.com/opencontainers/go-digest" + ocispecs "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/sirupsen/logrus" ) // DefaultPolicyFilename is the synthetic filename used for the embedded @@ -43,3 +50,20 @@ var DefaultPolicyEnabled = sync.OnceValue(func() bool { } return false }) + +// DefaultImageVerifier returns an image verifier backed by the builtin default +// policy, or nil when the default policy is disabled. +func DefaultImageVerifier(cfg *confutil.Config) func(context.Context, string, *ocispecs.Platform, *sourcemeta.Resolver) (digest.Digest, error) { + if !DefaultPolicyEnabled() { + return nil + } + pol := DefaultPolicy(Opt{ + Log: func(_ logrus.Level, msg string) { + logrus.Debug(msg) + }, + VerifierProvider: SignatureVerifier(cfg), + }) + return func(ctx context.Context, ref string, platform *ocispecs.Platform, resolver *sourcemeta.Resolver) (digest.Digest, error) { + return pol.CheckSource(ctx, ref, platform, resolver) + } +}