From 5232d82c1b0d1da10fa7b9c9a787f807da2068a8 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 5 Sep 2025 14:39:55 +0200 Subject: [PATCH] daemon/server/backend: move build options to buildbackend Signed-off-by: Sebastiaan van Stijn --- daemon/builder/backend/backend.go | 5 +- daemon/builder/builder.go | 3 +- daemon/builder/dockerfile/builder.go | 10 ++-- daemon/builder/dockerfile/imagecontext.go | 10 ++-- daemon/builder/dockerfile/internals_test.go | 4 +- daemon/builder/dockerfile/mockbackend_test.go | 3 +- daemon/builder/remotecontext/detect.go | 4 +- daemon/containerd/image_builder.go | 7 +-- daemon/image_service.go | 3 +- daemon/images/image_builder.go | 7 +-- daemon/internal/builder-next/builder.go | 3 +- daemon/server/backend/build.go | 50 ------------------ daemon/server/buildbackend/build.go | 51 ++++++++++++++++++- daemon/server/router/build/backend.go | 3 +- daemon/server/router/build/build_routes.go | 7 ++- 15 files changed, 85 insertions(+), 85 deletions(-) delete mode 100644 daemon/server/backend/build.go diff --git a/daemon/builder/backend/backend.go b/daemon/builder/backend/backend.go index f975f3074b..a23d148122 100644 --- a/daemon/builder/backend/backend.go +++ b/daemon/builder/backend/backend.go @@ -13,7 +13,6 @@ import ( buildkit "github.com/moby/moby/v2/daemon/internal/builder-next" "github.com/moby/moby/v2/daemon/internal/image" "github.com/moby/moby/v2/daemon/internal/stringid" - "github.com/moby/moby/v2/daemon/server/backend" "github.com/moby/moby/v2/daemon/server/buildbackend" "github.com/pkg/errors" "google.golang.org/grpc" @@ -27,7 +26,7 @@ type ImageComponent interface { // Builder defines interface for running a build type Builder interface { - Build(context.Context, backend.BuildConfig) (*builder.Result, error) + Build(context.Context, buildbackend.BuildConfig) (*builder.Result, error) } // Backend provides build functionality to the API router @@ -51,7 +50,7 @@ func (b *Backend) RegisterGRPC(s *grpc.Server) { } // Build builds an image from a Source -func (b *Backend) Build(ctx context.Context, config backend.BuildConfig) (string, error) { +func (b *Backend) Build(ctx context.Context, config buildbackend.BuildConfig) (string, error) { options := config.Options useBuildKit := options.Version == build.BuilderBuildKit diff --git a/daemon/builder/builder.go b/daemon/builder/builder.go index fdeb3528bd..ba42e43645 100644 --- a/daemon/builder/builder.go +++ b/daemon/builder/builder.go @@ -13,6 +13,7 @@ import ( "github.com/moby/moby/v2/daemon/internal/image" "github.com/moby/moby/v2/daemon/internal/layer" "github.com/moby/moby/v2/daemon/server/backend" + "github.com/moby/moby/v2/daemon/server/buildbackend" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -52,7 +53,7 @@ type Backend interface { // ImageBackend are the interface methods required from an image component type ImageBackend interface { - GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts backend.GetImageAndLayerOptions) (Image, ROLayer, error) + GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts buildbackend.GetImageAndLayerOptions) (Image, ROLayer, error) } // ExecBackend contains the interface methods required for executing containers diff --git a/daemon/builder/dockerfile/builder.go b/daemon/builder/dockerfile/builder.go index 3cc4a8c486..f887bc7fd6 100644 --- a/daemon/builder/dockerfile/builder.go +++ b/daemon/builder/dockerfile/builder.go @@ -18,7 +18,7 @@ import ( "github.com/moby/moby/v2/daemon/builder" "github.com/moby/moby/v2/daemon/builder/remotecontext" "github.com/moby/moby/v2/daemon/internal/stringid" - "github.com/moby/moby/v2/daemon/server/backend" + "github.com/moby/moby/v2/daemon/server/buildbackend" "github.com/moby/moby/v2/errdefs" "github.com/moby/sys/user" ocispec "github.com/opencontainers/image-spec/specs-go/v1" @@ -62,7 +62,7 @@ func NewBuildManager(b builder.Backend, identityMapping user.IdentityMapping) (* } // Build starts a new build from a BuildConfig -func (bm *BuildManager) Build(ctx context.Context, config backend.BuildConfig) (*builder.Result, error) { +func (bm *BuildManager) Build(ctx context.Context, config buildbackend.BuildConfig) (*builder.Result, error) { buildsTriggered.Inc() if config.Options.Dockerfile == "" { config.Options.Dockerfile = builder.DefaultDockerfileName @@ -100,7 +100,7 @@ func (bm *BuildManager) Build(ctx context.Context, config backend.BuildConfig) ( type builderOptions struct { Options *build.ImageBuildOptions Backend builder.Backend - ProgressWriter backend.ProgressWriter + ProgressWriter buildbackend.ProgressWriter PathCache pathCache IDMapping user.IdentityMapping } @@ -112,7 +112,7 @@ type Builder struct { Stdout io.Writer Stderr io.Writer - Aux backend.AuxEmitter + Aux buildbackend.AuxEmitter Output io.Writer docker builder.Backend @@ -217,7 +217,7 @@ func (b *Builder) build(ctx context.Context, source builder.Source, dockerfile * return &builder.Result{ImageID: state.imageID, FromImage: state.baseImage}, nil } -func emitImageID(aux backend.AuxEmitter, state *dispatchState) error { +func emitImageID(aux buildbackend.AuxEmitter, state *dispatchState) error { if aux == nil || state.imageID == "" { return nil } diff --git a/daemon/builder/dockerfile/imagecontext.go b/daemon/builder/dockerfile/imagecontext.go index ae44878f4d..1f08a27948 100644 --- a/daemon/builder/dockerfile/imagecontext.go +++ b/daemon/builder/dockerfile/imagecontext.go @@ -8,7 +8,7 @@ import ( "github.com/containerd/platforms" "github.com/moby/moby/v2/daemon/builder" dockerimage "github.com/moby/moby/v2/daemon/internal/image" - "github.com/moby/moby/v2/daemon/server/backend" + "github.com/moby/moby/v2/daemon/server/buildbackend" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" ) @@ -25,15 +25,15 @@ type imageSources struct { func newImageSources(options builderOptions) *imageSources { getAndMount := func(ctx context.Context, idOrRef string, localOnly bool, platform *ocispec.Platform) (builder.Image, builder.ROLayer, error) { - pullOption := backend.PullOptionNoPull + pullOption := buildbackend.PullOptionNoPull if !localOnly { if options.Options.PullParent { - pullOption = backend.PullOptionForcePull + pullOption = buildbackend.PullOptionForcePull } else { - pullOption = backend.PullOptionPreferLocal + pullOption = buildbackend.PullOptionPreferLocal } } - return options.Backend.GetImageAndReleasableLayer(ctx, idOrRef, backend.GetImageAndLayerOptions{ + return options.Backend.GetImageAndReleasableLayer(ctx, idOrRef, buildbackend.GetImageAndLayerOptions{ PullOption: pullOption, AuthConfig: options.Options.AuthConfigs, Output: options.ProgressWriter.Output, diff --git a/daemon/builder/dockerfile/internals_test.go b/daemon/builder/dockerfile/internals_test.go index 24c87de0eb..dbced9ed65 100644 --- a/daemon/builder/dockerfile/internals_test.go +++ b/daemon/builder/dockerfile/internals_test.go @@ -14,7 +14,7 @@ import ( "github.com/moby/moby/v2/daemon/builder/remotecontext" "github.com/moby/moby/v2/daemon/internal/image" "github.com/moby/moby/v2/daemon/internal/layer" - "github.com/moby/moby/v2/daemon/server/backend" + "github.com/moby/moby/v2/daemon/server/buildbackend" "github.com/opencontainers/go-digest" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -75,7 +75,7 @@ func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath, dockerfilePath = builder.DefaultDockerfileName } - config := backend.BuildConfig{ + config := buildbackend.BuildConfig{ Options: &build.ImageBuildOptions{Dockerfile: dockerfilePath}, Source: tarStream, } diff --git a/daemon/builder/dockerfile/mockbackend_test.go b/daemon/builder/dockerfile/mockbackend_test.go index d44d1a01f8..5f42b3924f 100644 --- a/daemon/builder/dockerfile/mockbackend_test.go +++ b/daemon/builder/dockerfile/mockbackend_test.go @@ -12,6 +12,7 @@ import ( "github.com/moby/moby/v2/daemon/internal/image" "github.com/moby/moby/v2/daemon/internal/layer" "github.com/moby/moby/v2/daemon/server/backend" + "github.com/moby/moby/v2/daemon/server/buildbackend" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -62,7 +63,7 @@ func (m *MockBackend) CopyOnBuild(containerID string, destPath string, srcRoot s return nil } -func (m *MockBackend) GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts backend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error) { +func (m *MockBackend) GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts buildbackend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error) { if m.getImageFunc != nil { return m.getImageFunc(refOrID) } diff --git a/daemon/builder/remotecontext/detect.go b/daemon/builder/remotecontext/detect.go index ae81c808ef..8cc23b604c 100644 --- a/daemon/builder/remotecontext/detect.go +++ b/daemon/builder/remotecontext/detect.go @@ -15,7 +15,7 @@ import ( "github.com/moby/buildkit/frontend/dockerfile/parser" "github.com/moby/moby/v2/daemon/builder" "github.com/moby/moby/v2/daemon/builder/remotecontext/urlutil" - "github.com/moby/moby/v2/daemon/server/backend" + "github.com/moby/moby/v2/daemon/server/buildbackend" "github.com/moby/moby/v2/errdefs" "github.com/moby/patternmatcher" "github.com/moby/patternmatcher/ignorefile" @@ -28,7 +28,7 @@ const ClientSessionRemote = "client-session" // Detect returns a context and dockerfile from remote location or local // archive. -func Detect(config backend.BuildConfig) (remote builder.Source, dockerfile *parser.Result, _ error) { +func Detect(config buildbackend.BuildConfig) (remote builder.Source, dockerfile *parser.Result, _ error) { remoteURL := config.Options.RemoteContext switch { case remoteURL == "": diff --git a/daemon/containerd/image_builder.go b/daemon/containerd/image_builder.go index df3696e582..8d2b4eb88f 100644 --- a/daemon/containerd/image_builder.go +++ b/daemon/containerd/image_builder.go @@ -33,6 +33,7 @@ import ( "github.com/moby/moby/v2/daemon/internal/layer" "github.com/moby/moby/v2/daemon/internal/stringid" "github.com/moby/moby/v2/daemon/server/backend" + "github.com/moby/moby/v2/daemon/server/buildbackend" "github.com/moby/moby/v2/errdefs" "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/identity" @@ -64,7 +65,7 @@ const ( // GetImageAndReleasableLayer returns an image and releaseable layer for a // reference or ID. Every call to GetImageAndReleasableLayer MUST call // releasableLayer.Release() to prevent leaking of layers. -func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts backend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error) { +func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts buildbackend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error) { if refOrID == "" { // FROM scratch if runtime.GOOS == "windows" { return nil, nil, errors.New(`"FROM scratch" is not supported on Windows`) @@ -80,10 +81,10 @@ func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID s }, nil } - if opts.PullOption != backend.PullOptionForcePull { + if opts.PullOption != buildbackend.PullOptionForcePull { // TODO(laurazard): same as below img, err := i.GetImage(ctx, refOrID, backend.GetImageOpts{Platform: opts.Platform}) - if err != nil && opts.PullOption == backend.PullOptionNoPull { + if err != nil && opts.PullOption == buildbackend.PullOptionNoPull { return nil, nil, err } imgDesc, err := i.resolveDescriptor(ctx, refOrID) diff --git a/daemon/image_service.go b/daemon/image_service.go index 4683035874..b4a4365fd8 100644 --- a/daemon/image_service.go +++ b/daemon/image_service.go @@ -16,6 +16,7 @@ import ( "github.com/moby/moby/v2/daemon/internal/image" "github.com/moby/moby/v2/daemon/internal/layer" "github.com/moby/moby/v2/daemon/server/backend" + "github.com/moby/moby/v2/daemon/server/buildbackend" "github.com/moby/moby/v2/daemon/server/imagebackend" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" @@ -48,7 +49,7 @@ type ImageService interface { // Layers - GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts backend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error) + GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts buildbackend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error) CreateLayer(container *container.Container, initFunc layer.MountInit) (container.RWLayer, error) CreateLayerFromImage(img *image.Image, layerName string, rwLayerOpts *layer.CreateRWLayerOpts) (container.RWLayer, error) GetLayerByID(cid string) (container.RWLayer, error) diff --git a/daemon/images/image_builder.go b/daemon/images/image_builder.go index 5f209cefaa..bcf8e6517f 100644 --- a/daemon/images/image_builder.go +++ b/daemon/images/image_builder.go @@ -17,6 +17,7 @@ import ( "github.com/moby/moby/v2/daemon/internal/layer" "github.com/moby/moby/v2/daemon/internal/stringid" "github.com/moby/moby/v2/daemon/server/backend" + "github.com/moby/moby/v2/daemon/server/buildbackend" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" @@ -195,7 +196,7 @@ Please notify the image author to correct the configuration.`, // GetImageAndReleasableLayer returns an image and releaseable layer for a reference or ID. // Every call to GetImageAndReleasableLayer MUST call releasableLayer.Release() to prevent // leaking of layers. -func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts backend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error) { +func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID string, opts buildbackend.GetImageAndLayerOptions) (builder.Image, builder.ROLayer, error) { if refOrID == "" { // FROM scratch if runtime.GOOS == "windows" { return nil, nil, errors.New(`"FROM scratch" is not supported on Windows`) @@ -209,9 +210,9 @@ func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID s return nil, lyr, err } - if opts.PullOption != backend.PullOptionForcePull { + if opts.PullOption != buildbackend.PullOptionForcePull { img, err := i.GetImage(ctx, refOrID, backend.GetImageOpts{Platform: opts.Platform}) - if err != nil && opts.PullOption == backend.PullOptionNoPull { + if err != nil && opts.PullOption == buildbackend.PullOptionNoPull { return nil, nil, err } if err != nil && !cerrdefs.IsNotFound(err) { diff --git a/daemon/internal/builder-next/builder.go b/daemon/internal/builder-next/builder.go index 5838f62ee7..81e7c013ab 100644 --- a/daemon/internal/builder-next/builder.go +++ b/daemon/internal/builder-next/builder.go @@ -32,7 +32,6 @@ import ( "github.com/moby/moby/v2/daemon/internal/timestamp" "github.com/moby/moby/v2/daemon/libnetwork" "github.com/moby/moby/v2/daemon/pkg/opts" - "github.com/moby/moby/v2/daemon/server/backend" "github.com/moby/moby/v2/daemon/server/buildbackend" "github.com/moby/moby/v2/errdefs" "github.com/moby/sys/user" @@ -243,7 +242,7 @@ func (b *Builder) Prune(ctx context.Context, opts buildbackend.CachePruneOptions } // Build executes a build request -func (b *Builder) Build(ctx context.Context, opt backend.BuildConfig) (*builder.Result, error) { +func (b *Builder) Build(ctx context.Context, opt buildbackend.BuildConfig) (*builder.Result, error) { if len(opt.Options.Outputs) > 1 { return nil, errors.Errorf("multiple outputs not supported") } diff --git a/daemon/server/backend/build.go b/daemon/server/backend/build.go deleted file mode 100644 index ba5f247138..0000000000 --- a/daemon/server/backend/build.go +++ /dev/null @@ -1,50 +0,0 @@ -package backend - -import ( - "io" - - "github.com/moby/moby/api/types/build" - "github.com/moby/moby/api/types/registry" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" -) - -// PullOption defines different modes for accessing images -type PullOption int - -const ( - // PullOptionNoPull only returns local images - PullOptionNoPull PullOption = iota - // PullOptionForcePull always tries to pull a ref from the registry first - PullOptionForcePull - // PullOptionPreferLocal uses local image if it exists, otherwise pulls - PullOptionPreferLocal -) - -// ProgressWriter is a data object to transport progress streams to the client -type ProgressWriter struct { - Output io.Writer - StdoutFormatter io.Writer - StderrFormatter io.Writer - AuxFormatter AuxEmitter - ProgressReaderFunc func(io.ReadCloser) io.ReadCloser -} - -// AuxEmitter is an interface for emitting aux messages during build progress -type AuxEmitter interface { - Emit(string, any) error -} - -// BuildConfig is the configuration used by a BuildManager to start a build -type BuildConfig struct { - Source io.ReadCloser - ProgressWriter ProgressWriter - Options *build.ImageBuildOptions -} - -// GetImageAndLayerOptions are the options supported by GetImageAndReleasableLayer -type GetImageAndLayerOptions struct { - PullOption PullOption - AuthConfig map[string]registry.AuthConfig - Output io.Writer - Platform *ocispec.Platform -} diff --git a/daemon/server/buildbackend/build.go b/daemon/server/buildbackend/build.go index bcab277079..fa027b8140 100644 --- a/daemon/server/buildbackend/build.go +++ b/daemon/server/buildbackend/build.go @@ -1,6 +1,14 @@ package buildbackend -import "github.com/moby/moby/api/types/filters" +import ( + "io" + + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + + "github.com/moby/moby/api/types/build" + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/registry" +) type CachePruneOptions struct { All bool @@ -9,3 +17,44 @@ type CachePruneOptions struct { MinFreeSpace int64 Filters filters.Args } + +// PullOption defines different modes for accessing images +type PullOption int + +const ( + // PullOptionNoPull only returns local images + PullOptionNoPull PullOption = iota + // PullOptionForcePull always tries to pull a ref from the registry first + PullOptionForcePull + // PullOptionPreferLocal uses local image if it exists, otherwise pulls + PullOptionPreferLocal +) + +// ProgressWriter is a data object to transport progress streams to the client +type ProgressWriter struct { + Output io.Writer + StdoutFormatter io.Writer + StderrFormatter io.Writer + AuxFormatter AuxEmitter + ProgressReaderFunc func(io.ReadCloser) io.ReadCloser +} + +// AuxEmitter is an interface for emitting aux messages during build progress +type AuxEmitter interface { + Emit(string, any) error +} + +// BuildConfig is the configuration used by a BuildManager to start a build +type BuildConfig struct { + Source io.ReadCloser + ProgressWriter ProgressWriter + Options *build.ImageBuildOptions +} + +// GetImageAndLayerOptions are the options supported by GetImageAndReleasableLayer +type GetImageAndLayerOptions struct { + PullOption PullOption + AuthConfig map[string]registry.AuthConfig + Output io.Writer + Platform *ocispec.Platform +} diff --git a/daemon/server/router/build/backend.go b/daemon/server/router/build/backend.go index ee45a1357e..6841cb4cb3 100644 --- a/daemon/server/router/build/backend.go +++ b/daemon/server/router/build/backend.go @@ -4,7 +4,6 @@ import ( "context" "github.com/moby/moby/api/types/build" - "github.com/moby/moby/v2/daemon/server/backend" "github.com/moby/moby/v2/daemon/server/buildbackend" ) @@ -12,7 +11,7 @@ import ( type Backend interface { // Build a Docker image returning the id of the image // TODO: make this return a reference instead of string - Build(context.Context, backend.BuildConfig) (string, error) + Build(context.Context, buildbackend.BuildConfig) (string, error) // PruneCache prunes the build cache. PruneCache(context.Context, buildbackend.CachePruneOptions) (*build.CachePruneReport, error) diff --git a/daemon/server/router/build/build_routes.go b/daemon/server/router/build/build_routes.go index 06d8305455..15551dea21 100644 --- a/daemon/server/router/build/build_routes.go +++ b/daemon/server/router/build/build_routes.go @@ -23,7 +23,6 @@ import ( "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/registry" "github.com/moby/moby/api/types/versions" - "github.com/moby/moby/v2/daemon/server/backend" "github.com/moby/moby/v2/daemon/server/buildbackend" "github.com/moby/moby/v2/daemon/server/httputils" "github.com/moby/moby/v2/pkg/ioutils" @@ -314,7 +313,7 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r * wantAux := versions.GreaterThanOrEqualTo(version, "1.30") - imgID, err := br.backend.Build(ctx, backend.BuildConfig{ + imgID, err := br.backend.Build(ctx, buildbackend.BuildConfig{ Source: body, Options: buildOptions, ProgressWriter: buildProgressWriter(out, wantAux, createProgressReader), @@ -360,7 +359,7 @@ func (s *syncWriter) Write(b []byte) (int, error) { return s.w.Write(b) } -func buildProgressWriter(out io.Writer, wantAux bool, createProgressReader func(io.ReadCloser) io.ReadCloser) backend.ProgressWriter { +func buildProgressWriter(out io.Writer, wantAux bool, createProgressReader func(io.ReadCloser) io.ReadCloser) buildbackend.ProgressWriter { // see https://github.com/moby/moby/pull/21406 out = &syncWriter{w: out} @@ -369,7 +368,7 @@ func buildProgressWriter(out io.Writer, wantAux bool, createProgressReader func( aux = &streamformatter.AuxFormatter{Writer: out} } - return backend.ProgressWriter{ + return buildbackend.ProgressWriter{ Output: out, StdoutFormatter: streamformatter.NewStdoutWriter(out), StderrFormatter: streamformatter.NewStderrWriter(out),