diff --git a/api/types/build/build.go b/api/types/build/build.go index a798802357..db98397734 100644 --- a/api/types/build/build.go +++ b/api/types/build/build.go @@ -1,12 +1,5 @@ package build -import ( - "io" - - "github.com/moby/moby/api/types/container" - "github.com/moby/moby/api/types/registry" -) - // BuilderVersion sets the version of underlying builder to use type BuilderVersion string @@ -21,71 +14,3 @@ const ( type Result struct { ID string } - -// ImageBuildOptions holds the information -// necessary to build images. -type ImageBuildOptions struct { - Tags []string - SuppressOutput bool - RemoteContext string - NoCache bool - Remove bool - ForceRemove bool - PullParent bool - Isolation container.Isolation - CPUSetCPUs string - CPUSetMems string - CPUShares int64 - CPUQuota int64 - CPUPeriod int64 - Memory int64 - MemorySwap int64 - CgroupParent string - NetworkMode string - ShmSize int64 - Dockerfile string - Ulimits []*container.Ulimit - // BuildArgs needs to be a *string instead of just a string so that - // we can tell the difference between "" (empty string) and no value - // at all (nil). See the parsing of buildArgs in - // api/server/router/build/build_routes.go for even more info. - BuildArgs map[string]*string - AuthConfigs map[string]registry.AuthConfig - Context io.Reader - Labels map[string]string - // squash the resulting image's layers to the parent - // preserves the original image and creates a new one from the parent with all - // the changes applied to a single layer - Squash bool - // CacheFrom specifies images that are used for matching cache. Images - // specified here do not need to have a valid parent chain to match cache. - CacheFrom []string - SecurityOpt []string - ExtraHosts []string // List of extra hosts - Target string - SessionID string - Platform string - // Version specifies the version of the underlying builder to use - Version BuilderVersion - // BuildID is an optional identifier that can be passed together with the - // build request. The same identifier can be used to gracefully cancel the - // build with the cancel request. - BuildID string - // Outputs defines configurations for exporting build results. Only supported - // in BuildKit mode - Outputs []ImageBuildOutput -} - -// ImageBuildOutput defines configuration for exporting a build result -type ImageBuildOutput struct { - Type string - Attrs map[string]string -} - -// ImageBuildResponse holds information -// returned by a server after building -// an image. -type ImageBuildResponse struct { - Body io.ReadCloser - OSType string -} diff --git a/client/client_interfaces.go b/client/client_interfaces.go index f75f8f79a2..448ecd9f71 100644 --- a/client/client_interfaces.go +++ b/client/client_interfaces.go @@ -106,7 +106,7 @@ type DistributionAPIClient interface { // ImageAPIClient defines API client methods for the images type ImageAPIClient interface { - ImageBuild(ctx context.Context, context io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error) + ImageBuild(ctx context.Context, context io.Reader, options ImageBuildOptions) (ImageBuildResponse, error) BuildCachePrune(ctx context.Context, opts BuildCachePruneOptions) (*build.CachePruneReport, error) BuildCancel(ctx context.Context, id string) error ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (io.ReadCloser, error) diff --git a/client/image_build.go b/client/image_build.go index 94ec6c3a42..5c1634d08b 100644 --- a/client/image_build.go +++ b/client/image_build.go @@ -10,7 +10,6 @@ import ( "strconv" "strings" - "github.com/moby/moby/api/types/build" "github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/network" ) @@ -18,15 +17,15 @@ import ( // ImageBuild sends a request to the daemon to build images. // The Body in the response implements an [io.ReadCloser] and it's up to the caller to // close it. -func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error) { +func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, options ImageBuildOptions) (ImageBuildResponse, error) { query, err := cli.imageBuildOptionsToQuery(ctx, options) if err != nil { - return build.ImageBuildResponse{}, err + return ImageBuildResponse{}, err } buf, err := json.Marshal(options.AuthConfigs) if err != nil { - return build.ImageBuildResponse{}, err + return ImageBuildResponse{}, err } headers := http.Header{} @@ -35,16 +34,16 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio resp, err := cli.postRaw(ctx, "/build", query, buildContext, headers) if err != nil { - return build.ImageBuildResponse{}, err + return ImageBuildResponse{}, err } - return build.ImageBuildResponse{ + return ImageBuildResponse{ Body: resp.Body, OSType: resp.Header.Get("Ostype"), }, nil } -func (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options build.ImageBuildOptions) (url.Values, error) { +func (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options ImageBuildOptions) (url.Values, error) { query := url.Values{} if len(options.Tags) > 0 { query["t"] = options.Tags diff --git a/client/image_build_opts.go b/client/image_build_opts.go new file mode 100644 index 0000000000..df51db09eb --- /dev/null +++ b/client/image_build_opts.go @@ -0,0 +1,77 @@ +package client + +import ( + "io" + + "github.com/moby/moby/api/types/build" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/registry" +) + +// ImageBuildOptions holds the information +// necessary to build images. +type ImageBuildOptions struct { + Tags []string + SuppressOutput bool + RemoteContext string + NoCache bool + Remove bool + ForceRemove bool + PullParent bool + Isolation container.Isolation + CPUSetCPUs string + CPUSetMems string + CPUShares int64 + CPUQuota int64 + CPUPeriod int64 + Memory int64 + MemorySwap int64 + CgroupParent string + NetworkMode string + ShmSize int64 + Dockerfile string + Ulimits []*container.Ulimit + // BuildArgs needs to be a *string instead of just a string so that + // we can tell the difference between "" (empty string) and no value + // at all (nil). See the parsing of buildArgs in + // api/server/router/build/build_routes.go for even more info. + BuildArgs map[string]*string + AuthConfigs map[string]registry.AuthConfig + Context io.Reader + Labels map[string]string + // squash the resulting image's layers to the parent + // preserves the original image and creates a new one from the parent with all + // the changes applied to a single layer + Squash bool + // CacheFrom specifies images that are used for matching cache. Images + // specified here do not need to have a valid parent chain to match cache. + CacheFrom []string + SecurityOpt []string + ExtraHosts []string // List of extra hosts + Target string + SessionID string + Platform string + // Version specifies the version of the underlying builder to use + Version build.BuilderVersion + // BuildID is an optional identifier that can be passed together with the + // build request. The same identifier can be used to gracefully cancel the + // build with the cancel request. + BuildID string + // Outputs defines configurations for exporting build results. Only supported + // in BuildKit mode + Outputs []ImageBuildOutput +} + +// ImageBuildOutput defines configuration for exporting a build result +type ImageBuildOutput struct { + Type string + Attrs map[string]string +} + +// ImageBuildResponse holds information +// returned by a server after building +// an image. +type ImageBuildResponse struct { + Body io.ReadCloser + OSType string +} diff --git a/client/image_build_test.go b/client/image_build_test.go index 235cc8addd..481ac13f86 100644 --- a/client/image_build_test.go +++ b/client/image_build_test.go @@ -11,7 +11,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/build" "github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/registry" "gotest.tools/v3/assert" @@ -21,7 +20,7 @@ import ( func TestImageBuildError(t *testing.T) { client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error"))) assert.NilError(t, err) - _, err = client.ImageBuild(context.Background(), nil, build.ImageBuildOptions{}) + _, err = client.ImageBuild(context.Background(), nil, ImageBuildOptions{}) assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal)) } @@ -30,13 +29,13 @@ func TestImageBuild(t *testing.T) { v2 := "value2" emptyRegistryConfig := "bnVsbA==" buildCases := []struct { - buildOptions build.ImageBuildOptions + buildOptions ImageBuildOptions expectedQueryParams map[string]string expectedTags []string expectedRegistryConfig string }{ { - buildOptions: build.ImageBuildOptions{ + buildOptions: ImageBuildOptions{ SuppressOutput: true, NoCache: true, Remove: true, @@ -53,7 +52,7 @@ func TestImageBuild(t *testing.T) { expectedRegistryConfig: emptyRegistryConfig, }, { - buildOptions: build.ImageBuildOptions{ + buildOptions: ImageBuildOptions{ SuppressOutput: false, NoCache: false, Remove: false, @@ -71,7 +70,7 @@ func TestImageBuild(t *testing.T) { expectedRegistryConfig: emptyRegistryConfig, }, { - buildOptions: build.ImageBuildOptions{ + buildOptions: ImageBuildOptions{ RemoteContext: "remoteContext", Isolation: container.Isolation("isolation"), CPUSetCPUs: "2", @@ -104,7 +103,7 @@ func TestImageBuild(t *testing.T) { expectedRegistryConfig: emptyRegistryConfig, }, { - buildOptions: build.ImageBuildOptions{ + buildOptions: ImageBuildOptions{ BuildArgs: map[string]*string{ "ARG1": &v1, "ARG2": &v2, @@ -119,7 +118,7 @@ func TestImageBuild(t *testing.T) { expectedRegistryConfig: emptyRegistryConfig, }, { - buildOptions: build.ImageBuildOptions{ + buildOptions: ImageBuildOptions{ Ulimits: []*container.Ulimit{ { Name: "nproc", @@ -141,7 +140,7 @@ func TestImageBuild(t *testing.T) { expectedRegistryConfig: emptyRegistryConfig, }, { - buildOptions: build.ImageBuildOptions{ + buildOptions: ImageBuildOptions{ AuthConfigs: map[string]registry.AuthConfig{ "https://index.docker.io/v1/": { Auth: "dG90bwo=", 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..4b90b564da 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 @@ -98,9 +98,9 @@ func (bm *BuildManager) Build(ctx context.Context, config backend.BuildConfig) ( // builderOptions are the dependencies required by the builder type builderOptions struct { - Options *build.ImageBuildOptions + Options *buildbackend.BuildOptions Backend builder.Backend - ProgressWriter backend.ProgressWriter + ProgressWriter buildbackend.ProgressWriter PathCache pathCache IDMapping user.IdentityMapping } @@ -108,11 +108,11 @@ type builderOptions struct { // Builder is a Dockerfile builder // It implements the builder.Backend interface. type Builder struct { - options *build.ImageBuildOptions + options *buildbackend.BuildOptions Stdout io.Writer Stderr io.Writer - Aux backend.AuxEmitter + Aux buildbackend.AuxEmitter Output io.Writer docker builder.Backend @@ -130,7 +130,7 @@ type Builder struct { func newBuilder(ctx context.Context, options builderOptions) (*Builder, error) { config := options.Options if config == nil { - config = new(build.ImageBuildOptions) + config = &buildbackend.BuildOptions{} } imgProber, err := newImageProber(ctx, options.Backend, config.CacheFrom, config.NoCache) @@ -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 } @@ -343,7 +343,7 @@ func BuildFromConfig(ctx context.Context, config *container.Config, changes []st } b, err := newBuilder(ctx, builderOptions{ - Options: &build.ImageBuildOptions{NoCache: true}, + Options: &buildbackend.BuildOptions{NoCache: true}, }) if err != nil { return nil, err diff --git a/daemon/builder/dockerfile/dispatchers_test.go b/daemon/builder/dockerfile/dispatchers_test.go index 1d4762bd7b..da7e964bcb 100644 --- a/daemon/builder/dockerfile/dispatchers_test.go +++ b/daemon/builder/dockerfile/dispatchers_test.go @@ -11,12 +11,12 @@ import ( "github.com/moby/buildkit/frontend/dockerfile/instructions" "github.com/moby/buildkit/frontend/dockerfile/parser" "github.com/moby/buildkit/frontend/dockerfile/shell" - "github.com/moby/moby/api/types/build" "github.com/moby/moby/api/types/container" "github.com/moby/moby/v2/daemon/builder" "github.com/moby/moby/v2/daemon/internal/image" "github.com/moby/moby/v2/daemon/pkg/oci" "github.com/moby/moby/v2/daemon/server/backend" + "github.com/moby/moby/v2/daemon/server/buildbackend" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -24,19 +24,18 @@ import ( func newBuilderWithMockBackend(t *testing.T) *Builder { t.Helper() mockBackend := &MockBackend{} - opts := &build.ImageBuildOptions{} ctx := context.Background() imageProber, err := newImageProber(ctx, mockBackend, nil, false) assert.NilError(t, err, "Could not create image prober") b := &Builder{ - options: opts, + options: &buildbackend.BuildOptions{}, docker: mockBackend, Stdout: new(bytes.Buffer), disableCommit: true, imageSources: newImageSources(builderOptions{ - Options: opts, + Options: &buildbackend.BuildOptions{}, Backend: mockBackend, }), imageProber: imageProber, 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.go b/daemon/builder/dockerfile/internals.go index 96935761fc..d2d0626e79 100644 --- a/daemon/builder/dockerfile/internals.go +++ b/daemon/builder/dockerfile/internals.go @@ -16,7 +16,6 @@ import ( "github.com/containerd/platforms" "github.com/moby/go-archive" "github.com/moby/go-archive/chrootarchive" - "github.com/moby/moby/api/types/build" "github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/network" "github.com/moby/moby/v2/daemon/builder" @@ -24,6 +23,7 @@ import ( "github.com/moby/moby/v2/daemon/internal/stringid" networkSettings "github.com/moby/moby/v2/daemon/network" "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" ) @@ -340,7 +340,7 @@ func (b *Builder) create(ctx context.Context, runConfig *container.Config) (stri return ctr.ID, nil } -func hostConfigFromOptions(options *build.ImageBuildOptions) *container.HostConfig { +func hostConfigFromOptions(options *buildbackend.BuildOptions) *container.HostConfig { resources := container.Resources{ CgroupParent: options.CgroupParent, CPUShares: options.CPUShares, diff --git a/daemon/builder/dockerfile/internals_linux_test.go b/daemon/builder/dockerfile/internals_linux_test.go index 07fba0cf96..0c8ec3775f 100644 --- a/daemon/builder/dockerfile/internals_linux_test.go +++ b/daemon/builder/dockerfile/internals_linux_test.go @@ -6,7 +6,7 @@ import ( "path/filepath" "testing" - "github.com/moby/moby/api/types/build" + "github.com/moby/moby/v2/daemon/server/buildbackend" "github.com/moby/sys/user" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -58,7 +58,7 @@ othergrp:x:6666: expected identity }{ { - builder: &Builder{options: &build.ImageBuildOptions{Platform: "linux"}}, + builder: &Builder{options: &buildbackend.BuildOptions{Platform: "linux"}}, name: "UIDNoMap", chownStr: "1", idMapping: unmapped, @@ -66,7 +66,7 @@ othergrp:x:6666: expected: identity{UID: 1, GID: 1}, }, { - builder: &Builder{options: &build.ImageBuildOptions{Platform: "linux"}}, + builder: &Builder{options: &buildbackend.BuildOptions{Platform: "linux"}}, name: "UIDGIDNoMap", chownStr: "0:1", idMapping: unmapped, @@ -74,7 +74,7 @@ othergrp:x:6666: expected: identity{UID: 0, GID: 1}, }, { - builder: &Builder{options: &build.ImageBuildOptions{Platform: "linux"}}, + builder: &Builder{options: &buildbackend.BuildOptions{Platform: "linux"}}, name: "UIDWithMap", chownStr: "0", idMapping: remapped, @@ -82,7 +82,7 @@ othergrp:x:6666: expected: identity{UID: 100000, GID: 100000}, }, { - builder: &Builder{options: &build.ImageBuildOptions{Platform: "linux"}}, + builder: &Builder{options: &buildbackend.BuildOptions{Platform: "linux"}}, name: "UIDGIDWithMap", chownStr: "1:33", idMapping: remapped, @@ -90,7 +90,7 @@ othergrp:x:6666: expected: identity{UID: 100001, GID: 100033}, }, { - builder: &Builder{options: &build.ImageBuildOptions{Platform: "linux"}}, + builder: &Builder{options: &buildbackend.BuildOptions{Platform: "linux"}}, name: "UserNoMap", chownStr: "bin:5555", idMapping: unmapped, @@ -98,7 +98,7 @@ othergrp:x:6666: expected: identity{UID: 1, GID: 5555}, }, { - builder: &Builder{options: &build.ImageBuildOptions{Platform: "linux"}}, + builder: &Builder{options: &buildbackend.BuildOptions{Platform: "linux"}}, name: "GroupWithMap", chownStr: "0:unicorn", idMapping: remapped, @@ -106,7 +106,7 @@ othergrp:x:6666: expected: identity{UID: 100000, GID: 101002}, }, { - builder: &Builder{options: &build.ImageBuildOptions{Platform: "linux"}}, + builder: &Builder{options: &buildbackend.BuildOptions{Platform: "linux"}}, name: "UserOnlyWithMap", chownStr: "unicorn", idMapping: remapped, @@ -131,7 +131,7 @@ othergrp:x:6666: descr string }{ { - builder: &Builder{options: &build.ImageBuildOptions{Platform: "linux"}}, + builder: &Builder{options: &buildbackend.BuildOptions{Platform: "linux"}}, name: "BadChownFlagFormat", chownStr: "bob:1:555", idMapping: unmapped, @@ -139,7 +139,7 @@ othergrp:x:6666: descr: "invalid chown string format: bob:1:555", }, { - builder: &Builder{options: &build.ImageBuildOptions{Platform: "linux"}}, + builder: &Builder{options: &buildbackend.BuildOptions{Platform: "linux"}}, name: "UserNoExist", chownStr: "bob", idMapping: unmapped, @@ -147,7 +147,7 @@ othergrp:x:6666: descr: "can't find uid for user bob: no such user: bob", }, { - builder: &Builder{options: &build.ImageBuildOptions{Platform: "linux"}}, + builder: &Builder{options: &buildbackend.BuildOptions{Platform: "linux"}}, name: "GroupNoExist", chownStr: "root:bob", idMapping: unmapped, diff --git a/daemon/builder/dockerfile/internals_test.go b/daemon/builder/dockerfile/internals_test.go index 24c87de0eb..b7516137da 100644 --- a/daemon/builder/dockerfile/internals_test.go +++ b/daemon/builder/dockerfile/internals_test.go @@ -8,13 +8,12 @@ import ( "testing" "github.com/moby/go-archive" - "github.com/moby/moby/api/types/build" "github.com/moby/moby/api/types/container" "github.com/moby/moby/v2/daemon/builder" "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,8 +74,8 @@ func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath, dockerfilePath = builder.DefaultDockerfileName } - config := backend.BuildConfig{ - Options: &build.ImageBuildOptions{Dockerfile: dockerfilePath}, + config := buildbackend.BuildConfig{ + Options: &buildbackend.BuildOptions{Dockerfile: dockerfilePath}, Source: tarStream, } _, _, err = remotecontext.Detect(config) 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..798894bc90 100644 --- a/daemon/server/buildbackend/build.go +++ b/daemon/server/buildbackend/build.go @@ -1,6 +1,15 @@ 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/container" + "github.com/moby/moby/api/types/filters" + "github.com/moby/moby/api/types/registry" +) type CachePruneOptions struct { All bool @@ -9,3 +18,104 @@ 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 *BuildOptions +} + +// BuildOptions holds the information +// necessary to build images. +type BuildOptions struct { + Tags []string + SuppressOutput bool + RemoteContext string + NoCache bool + Remove bool + ForceRemove bool + PullParent bool + Isolation container.Isolation + CPUSetCPUs string + CPUSetMems string + CPUShares int64 + CPUQuota int64 + CPUPeriod int64 + Memory int64 + MemorySwap int64 + CgroupParent string + NetworkMode string + ShmSize int64 + Dockerfile string + Ulimits []*container.Ulimit + // BuildArgs needs to be a *string instead of just a string so that + // we can tell the difference between "" (empty string) and no value + // at all (nil). See the parsing of buildArgs in + // api/server/router/build/build_routes.go for even more info. + BuildArgs map[string]*string + AuthConfigs map[string]registry.AuthConfig + Context io.Reader + Labels map[string]string + // squash the resulting image's layers to the parent + // preserves the original image and creates a new one from the parent with all + // the changes applied to a single layer + Squash bool + // CacheFrom specifies images that are used for matching cache. Images + // specified here do not need to have a valid parent chain to match cache. + CacheFrom []string + SecurityOpt []string + ExtraHosts []string // List of extra hosts + Target string + SessionID string + Platform string + // Version specifies the version of the underlying builder to use + Version build.BuilderVersion + // BuildID is an optional identifier that can be passed together with the + // build request. The same identifier can be used to gracefully cancel the + // build with the cancel request. + BuildID string + // Outputs defines configurations for exporting build results. Only supported + // in BuildKit mode + Outputs []BuildOutput +} + +// BuildOutput defines configuration for exporting a build result +type BuildOutput struct { + Type string + Attrs map[string]string +} + +// 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..a90074bfd7 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" @@ -36,8 +35,8 @@ type invalidParam struct { func (e invalidParam) InvalidParameter() {} -func newImageBuildOptions(ctx context.Context, r *http.Request) (*build.ImageBuildOptions, error) { - options := &build.ImageBuildOptions{ +func newImageBuildOptions(ctx context.Context, r *http.Request) (*buildbackend.BuildOptions, error) { + options := &buildbackend.BuildOptions{ Version: build.BuilderV1, // Builder V1 is the default, but can be overridden Dockerfile: r.FormValue("dockerfile"), SuppressOutput: httputils.BoolValue(r, "q"), @@ -82,7 +81,7 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*build.ImageBui if versions.GreaterThanOrEqualTo(version, "1.40") { outputsJSON := r.FormValue("outputs") if outputsJSON != "" { - var outputs []build.ImageBuildOutput + var outputs []buildbackend.BuildOutput if err := json.Unmarshal([]byte(outputsJSON), &outputs); err != nil { return nil, invalidParam{errors.Wrap(err, "invalid outputs specified")} } @@ -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), diff --git a/integration/build/build_cgroupns_linux_test.go b/integration/build/build_cgroupns_linux_test.go index 1923628714..f4bf3cbf39 100644 --- a/integration/build/build_cgroupns_linux_test.go +++ b/integration/build/build_cgroupns_linux_test.go @@ -7,7 +7,7 @@ import ( "strings" "testing" - "github.com/moby/moby/api/types/build" + "github.com/moby/moby/client" "github.com/moby/moby/client/pkg/jsonmessage" "github.com/moby/moby/v2/integration/internal/requirement" "github.com/moby/moby/v2/testutil" @@ -51,14 +51,12 @@ func testBuildWithCgroupNs(ctx context.Context, t *testing.T, daemonNsMode strin source := fakecontext.New(t, "", fakecontext.WithDockerfile(dockerfile)) defer source.Close() - client := d.NewClientT(t) - resp, err := client.ImageBuild(ctx, - source.AsTarReader(t), - build.ImageBuildOptions{ - Remove: true, - ForceRemove: true, - Tags: []string{"buildcgroupns"}, - }) + apiClient := d.NewClientT(t) + resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + Tags: []string{"buildcgroupns"}, + }) assert.NilError(t, err) defer resp.Body.Close() diff --git a/integration/build/build_squash_test.go b/integration/build/build_squash_test.go index d9e4629460..3c1c4b8471 100644 --- a/integration/build/build_squash_test.go +++ b/integration/build/build_squash_test.go @@ -7,7 +7,6 @@ import ( "testing" "github.com/moby/moby/api/pkg/stdcopy" - "github.com/moby/moby/api/types/build" "github.com/moby/moby/client" "github.com/moby/moby/v2/integration/internal/container" "github.com/moby/moby/v2/testutil" @@ -51,13 +50,11 @@ func TestBuildSquashParent(t *testing.T) { defer source.Close() name := strings.ToLower(t.Name()) - resp, err := apiClient.ImageBuild(ctx, - source.AsTarReader(t), - build.ImageBuildOptions{ - Remove: true, - ForceRemove: true, - Tags: []string{name}, - }) + resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + Tags: []string{name}, + }) assert.NilError(t, err) _, err = io.Copy(io.Discard, resp.Body) resp.Body.Close() @@ -70,7 +67,7 @@ func TestBuildSquashParent(t *testing.T) { // build with squash resp, err = apiClient.ImageBuild(ctx, source.AsTarReader(t), - build.ImageBuildOptions{ + client.ImageBuildOptions{ Remove: true, ForceRemove: true, Squash: true, diff --git a/integration/build/build_test.go b/integration/build/build_test.go index 4c3648b230..9f2ae882f0 100644 --- a/integration/build/build_test.go +++ b/integration/build/build_test.go @@ -110,7 +110,7 @@ func TestBuildWithRemoveAndForceRemove(t *testing.T) { _, err := tw.Write(dockerfile) assert.NilError(t, err) assert.NilError(t, tw.Close()) - resp, err := apiClient.ImageBuild(ctx, buff, build.ImageBuildOptions{Remove: tc.rm, ForceRemove: tc.forceRm, NoCache: true}) + resp, err := apiClient.ImageBuild(ctx, buff, client.ImageBuildOptions{Remove: tc.rm, ForceRemove: tc.forceRm, NoCache: true}) assert.NilError(t, err) defer resp.Body.Close() filter, err := buildContainerIdsFilter(resp.Body) @@ -163,16 +163,12 @@ func TestBuildMultiStageCopy(t *testing.T) { t.Run(target, func(t *testing.T) { imgName := strings.ToLower(t.Name()) - resp, err := apiclient.ImageBuild( - ctx, - source.AsTarReader(t), - build.ImageBuildOptions{ - Remove: true, - ForceRemove: true, - Target: target, - Tags: []string{imgName}, - }, - ) + resp, err := apiclient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + Target: target, + Tags: []string{imgName}, + }) assert.NilError(t, err) out := bytes.NewBuffer(nil) @@ -213,13 +209,11 @@ func TestBuildMultiStageParentConfig(t *testing.T) { apiclient := testEnv.APIClient() imgName := strings.ToLower(t.Name()) - resp, err := apiclient.ImageBuild(ctx, - source.AsTarReader(t), - build.ImageBuildOptions{ - Remove: true, - ForceRemove: true, - Tags: []string{imgName}, - }) + resp, err := apiclient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + Tags: []string{imgName}, + }) assert.NilError(t, err) _, err = io.Copy(io.Discard, resp.Body) assert.Check(t, resp.Body.Close()) @@ -260,15 +254,13 @@ func TestBuildLabelWithTargets(t *testing.T) { apiclient := testEnv.APIClient() // For `target-a` build - resp, err := apiclient.ImageBuild(ctx, - source.AsTarReader(t), - build.ImageBuildOptions{ - Remove: true, - ForceRemove: true, - Tags: []string{imgName}, - Labels: testLabels, - Target: "target-a", - }) + resp, err := apiclient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + Tags: []string{imgName}, + Labels: testLabels, + Target: "target-a", + }) assert.NilError(t, err) _, err = io.Copy(io.Discard, resp.Body) assert.Check(t, resp.Body.Close()) @@ -289,7 +281,7 @@ func TestBuildLabelWithTargets(t *testing.T) { delete(testLabels, "label-a") resp, err = apiclient.ImageBuild(ctx, source.AsTarReader(t), - build.ImageBuildOptions{ + client.ImageBuildOptions{ Remove: true, ForceRemove: true, Tags: []string{imgName}, @@ -328,12 +320,10 @@ COPY 3/ /target/ defer source.Close() apiclient := testEnv.APIClient() - resp, err := apiclient.ImageBuild(ctx, - source.AsTarReader(t), - build.ImageBuildOptions{ - Remove: true, - ForceRemove: true, - }) + resp, err := apiclient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + }) assert.NilError(t, err) _, err = io.Copy(io.Discard, resp.Body) assert.Check(t, resp.Body.Close()) @@ -364,12 +354,10 @@ RUN cat somefile` defer source.Close() apiclient := testEnv.APIClient() - resp, err := apiclient.ImageBuild(ctx, - source.AsTarReader(t), - build.ImageBuildOptions{ - Remove: true, - ForceRemove: true, - }) + resp, err := apiclient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + }) out := bytes.NewBuffer(nil) assert.NilError(t, err) @@ -410,12 +398,10 @@ COPY bar / assert.NilError(t, err) apiclient := testEnv.APIClient() - resp, err := apiclient.ImageBuild(ctx, - buf, - build.ImageBuildOptions{ - Remove: true, - ForceRemove: true, - }) + resp, err := apiclient.ImageBuild(ctx, buf, client.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + }) out := bytes.NewBuffer(nil) assert.NilError(t, err) @@ -435,7 +421,7 @@ COPY bar / resp, err = apiclient.ImageBuild(ctx, buf, - build.ImageBuildOptions{ + client.ImageBuildOptions{ Remove: true, ForceRemove: true, }) @@ -472,12 +458,10 @@ RUN [ ! -f foo ] defer source.Close() apiClient := testEnv.APIClient() - resp, err := apiClient.ImageBuild(ctx, - source.AsTarReader(t), - build.ImageBuildOptions{ - Remove: true, - ForceRemove: true, - }) + resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + }) out := bytes.NewBuffer(nil) assert.NilError(t, err) @@ -518,12 +502,10 @@ RUN for g in $(seq 0 8); do dd if=/dev/urandom of=rnd bs=1K count=1 seek=$((1024 assert.NilError(t, err) apiClient := testEnv.APIClient() - resp, err := apiClient.ImageBuild(ctx, - buf, - build.ImageBuildOptions{ - Remove: true, - ForceRemove: true, - }) + resp, err := apiClient.ImageBuild(ctx, buf, client.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + }) out := bytes.NewBuffer(nil) assert.NilError(t, err) @@ -559,12 +541,10 @@ COPY --from=intermediate C:\\stuff C:\\stuff assert.NilError(t, err) apiClient := testEnv.APIClient() - resp, err := apiClient.ImageBuild(ctx, - buf, - build.ImageBuildOptions{ - Remove: true, - ForceRemove: true, - }) + resp, err := apiClient.ImageBuild(ctx, buf, client.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + }) out := bytes.NewBuffer(nil) assert.NilError(t, err) @@ -626,7 +606,7 @@ func TestBuildWithEmptyDockerfile(t *testing.T) { _, err = apiClient.ImageBuild(ctx, buf, - build.ImageBuildOptions{ + client.ImageBuildOptions{ Remove: true, ForceRemove: true, }) @@ -653,15 +633,11 @@ func TestBuildPreserveOwnership(t *testing.T) { t.Run(target, func(t *testing.T) { ctx := testutil.StartSpan(ctx, t) - resp, err := apiClient.ImageBuild( - ctx, - source.AsTarReader(t), - build.ImageBuildOptions{ - Remove: true, - ForceRemove: true, - Target: target, - }, - ) + resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + Target: target, + }) assert.NilError(t, err) out := bytes.NewBuffer(nil) @@ -684,7 +660,7 @@ func TestBuildPlatformInvalid(t *testing.T) { err := w.Close() assert.NilError(t, err) - _, err = testEnv.APIClient().ImageBuild(ctx, buf, build.ImageBuildOptions{ + _, err = testEnv.APIClient().ImageBuild(ctx, buf, client.ImageBuildOptions{ Remove: true, ForceRemove: true, Platform: "foobar", @@ -713,7 +689,7 @@ func TestBuildWorkdirNoCacheMiss(t *testing.T) { apiClient := testEnv.APIClient() buildAndGetID := func() string { - resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), build.ImageBuildOptions{ + resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ Version: build.BuilderV1, }) assert.NilError(t, err) @@ -752,7 +728,7 @@ func TestBuildEmitsImageCreateEvent(t *testing.T) { since := time.Now() - resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), build.ImageBuildOptions{ + resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ Version: builderVersion, NoCache: true, }) @@ -807,7 +783,7 @@ func TestBuildHistoryDoesNotPreventRemoval(t *testing.T) { apiClient := testEnv.APIClient() buildImage := func(imgName string) error { - resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), build.ImageBuildOptions{ + resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ Remove: true, ForceRemove: true, Tags: []string{imgName}, diff --git a/integration/build/build_userns_linux_test.go b/integration/build/build_userns_linux_test.go index 6b574f0b80..9437f729e1 100644 --- a/integration/build/build_userns_linux_test.go +++ b/integration/build/build_userns_linux_test.go @@ -10,7 +10,6 @@ import ( "testing" "github.com/moby/moby/api/pkg/stdcopy" - "github.com/moby/moby/api/types/build" "github.com/moby/moby/client" "github.com/moby/moby/client/pkg/jsonmessage" "github.com/moby/moby/v2/integration/internal/container" @@ -64,11 +63,9 @@ func TestBuildUserNamespaceValidateCapabilitiesAreV2(t *testing.T) { source := fakecontext.New(t, "", fakecontext.WithDockerfile(dockerfile)) defer source.Close() - resp, err := clientUserRemap.ImageBuild(ctx, - source.AsTarReader(t), - build.ImageBuildOptions{ - Tags: []string{imageTag}, - }) + resp, err := clientUserRemap.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ + Tags: []string{imageTag}, + }) assert.NilError(t, err) defer resp.Body.Close() diff --git a/integration/capabilities/capabilities_linux_test.go b/integration/capabilities/capabilities_linux_test.go index 50c38feb3f..bd6f0c670b 100644 --- a/integration/capabilities/capabilities_linux_test.go +++ b/integration/capabilities/capabilities_linux_test.go @@ -7,9 +7,8 @@ import ( "testing" "github.com/moby/moby/api/pkg/stdcopy" - "github.com/moby/moby/api/types/build" containertypes "github.com/moby/moby/api/types/container" - client2 "github.com/moby/moby/client" + "github.com/moby/moby/client" "github.com/moby/moby/v2/integration/internal/container" "github.com/moby/moby/v2/testutil" "github.com/moby/moby/v2/testutil/fakecontext" @@ -32,14 +31,12 @@ func TestNoNewPrivileges(t *testing.T) { source := fakecontext.New(t, "", fakecontext.WithDockerfile(withFileCapability)) defer source.Close() - client := testEnv.APIClient() + apiClient := testEnv.APIClient() // Build image - resp, err := client.ImageBuild(ctx, - source.AsTarReader(t), - build.ImageBuildOptions{ - Tags: []string{imageTag}, - }) + resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ + Tags: []string{imageTag}, + }) assert.NilError(t, err) _, err = io.Copy(io.Discard, resp.Body) assert.NilError(t, err) @@ -78,11 +75,11 @@ func TestNoNewPrivileges(t *testing.T) { container.WithCmd("/bin/cat", "/txt"), container.WithSecurityOpt("no-new-privileges=true"), ) - cid := container.Run(ctx, t, client, opts...) - poll.WaitOn(t, container.IsInState(ctx, client, cid, containertypes.StateExited)) + cid := container.Run(ctx, t, apiClient, opts...) + poll.WaitOn(t, container.IsInState(ctx, apiClient, cid, containertypes.StateExited)) // Assert on outputs - logReader, err := client.ContainerLogs(ctx, cid, client2.ContainerLogsOptions{ + logReader, err := apiClient.ContainerLogs(ctx, cid, client.ContainerLogsOptions{ ShowStdout: true, ShowStderr: true, }) diff --git a/integration/container/copy_test.go b/integration/container/copy_test.go index 6ddb9a79f8..8b344a30f9 100644 --- a/integration/container/copy_test.go +++ b/integration/container/copy_test.go @@ -213,7 +213,7 @@ func makeTestImage(ctx context.Context, t *testing.T) (imageID string) { `)) defer buildCtx.Close() - resp, err := apiClient.ImageBuild(ctx, buildCtx.AsTarReader(t), build.ImageBuildOptions{}) + resp, err := apiClient.ImageBuild(ctx, buildCtx.AsTarReader(t), client.ImageBuildOptions{}) assert.NilError(t, err) defer resp.Body.Close() @@ -287,7 +287,7 @@ func TestCopyFromContainer(t *testing.T) { `)) defer buildCtx.Close() - resp, err := apiClient.ImageBuild(ctx, buildCtx.AsTarReader(t), build.ImageBuildOptions{}) + resp, err := apiClient.ImageBuild(ctx, buildCtx.AsTarReader(t), client.ImageBuildOptions{}) assert.NilError(t, err) defer resp.Body.Close() diff --git a/integration/image/history_test.go b/integration/image/history_test.go index 180c4891bf..de2d2f6187 100644 --- a/integration/image/history_test.go +++ b/integration/image/history_test.go @@ -68,7 +68,7 @@ func TestAPIImageHistoryCrossPlatform(t *testing.T) { defer buildCtx.Close() // Build the image for a non-native platform - resp, err := apiClient.ImageBuild(ctx, buildCtx.AsTarReader(t), buildtypes.ImageBuildOptions{ + resp, err := apiClient.ImageBuild(ctx, buildCtx.AsTarReader(t), client.ImageBuildOptions{ Version: buildtypes.BuilderBuildKit, Tags: []string{"cross-platform-test"}, Platform: platforms.FormatAll(nonNativePlatform), diff --git a/integration/internal/build/build.go b/integration/internal/build/build.go index 1f79ce0415..40ae23bb91 100644 --- a/integration/internal/build/build.go +++ b/integration/internal/build/build.go @@ -18,7 +18,7 @@ import ( // Do builds an image from the given context and returns the image ID. func Do(ctx context.Context, t *testing.T, apiClient client.APIClient, buildCtx *fakecontext.Fake) string { - resp, err := apiClient.ImageBuild(ctx, buildCtx.AsTarReader(t), build.ImageBuildOptions{}) + resp, err := apiClient.ImageBuild(ctx, buildCtx.AsTarReader(t), client.ImageBuildOptions{}) if resp.Body != nil { defer resp.Body.Close() } diff --git a/integration/volume/mount_test.go b/integration/volume/mount_test.go index a220777aea..6e3b0f0690 100644 --- a/integration/volume/mount_test.go +++ b/integration/volume/mount_test.go @@ -9,7 +9,6 @@ import ( "strings" "testing" - "github.com/moby/moby/api/types/build" containertypes "github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/mount" "github.com/moby/moby/api/types/network" @@ -320,13 +319,11 @@ func setupTestImage(t *testing.T, ctx context.Context, apiClient client.APIClien ) defer source.Close() - resp, err := apiClient.ImageBuild(ctx, - source.AsTarReader(t), - build.ImageBuildOptions{ - Remove: false, - ForceRemove: false, - Tags: []string{imgName}, - }) + resp, err := apiClient.ImageBuild(ctx, source.AsTarReader(t), client.ImageBuildOptions{ + Remove: false, + ForceRemove: false, + Tags: []string{imgName}, + }) assert.NilError(t, err) out := bytes.NewBuffer(nil) diff --git a/testutil/fakestorage/fixtures.go b/testutil/fakestorage/fixtures.go index ca0f2b3820..9e55ea8663 100644 --- a/testutil/fakestorage/fixtures.go +++ b/testutil/fakestorage/fixtures.go @@ -10,7 +10,7 @@ import ( "testing" "github.com/moby/go-archive" - "github.com/moby/moby/api/types/build" + "github.com/moby/moby/client" "gotest.tools/v3/assert" ) @@ -76,7 +76,7 @@ CMD ["./httpserver"] assert.NilError(t, err) apiClient := testEnv.APIClient() - resp, err := apiClient.ImageBuild(context.Background(), reader, build.ImageBuildOptions{ + resp, err := apiClient.ImageBuild(context.Background(), reader, client.ImageBuildOptions{ Remove: true, ForceRemove: true, Tags: []string{"httpserver"}, diff --git a/testutil/fakestorage/storage.go b/testutil/fakestorage/storage.go index a716e8b535..f8d5e3b3c7 100644 --- a/testutil/fakestorage/storage.go +++ b/testutil/fakestorage/storage.go @@ -11,7 +11,6 @@ import ( "strings" "testing" - "github.com/moby/moby/api/types/build" containertypes "github.com/moby/moby/api/types/container" "github.com/moby/moby/client" "github.com/moby/moby/v2/testutil" @@ -145,7 +144,7 @@ func newRemoteFileServer(t testing.TB, ctx *fakecontext.Fake, c client.APIClient COPY . /static`); err != nil { t.Fatal(err) } - resp, err := c.ImageBuild(context.Background(), ctx.AsTarReader(t), build.ImageBuildOptions{ + resp, err := c.ImageBuild(context.Background(), ctx.AsTarReader(t), client.ImageBuildOptions{ NoCache: true, Tags: []string{imgName}, }) diff --git a/vendor/github.com/moby/moby/api/types/build/build.go b/vendor/github.com/moby/moby/api/types/build/build.go index a798802357..db98397734 100644 --- a/vendor/github.com/moby/moby/api/types/build/build.go +++ b/vendor/github.com/moby/moby/api/types/build/build.go @@ -1,12 +1,5 @@ package build -import ( - "io" - - "github.com/moby/moby/api/types/container" - "github.com/moby/moby/api/types/registry" -) - // BuilderVersion sets the version of underlying builder to use type BuilderVersion string @@ -21,71 +14,3 @@ const ( type Result struct { ID string } - -// ImageBuildOptions holds the information -// necessary to build images. -type ImageBuildOptions struct { - Tags []string - SuppressOutput bool - RemoteContext string - NoCache bool - Remove bool - ForceRemove bool - PullParent bool - Isolation container.Isolation - CPUSetCPUs string - CPUSetMems string - CPUShares int64 - CPUQuota int64 - CPUPeriod int64 - Memory int64 - MemorySwap int64 - CgroupParent string - NetworkMode string - ShmSize int64 - Dockerfile string - Ulimits []*container.Ulimit - // BuildArgs needs to be a *string instead of just a string so that - // we can tell the difference between "" (empty string) and no value - // at all (nil). See the parsing of buildArgs in - // api/server/router/build/build_routes.go for even more info. - BuildArgs map[string]*string - AuthConfigs map[string]registry.AuthConfig - Context io.Reader - Labels map[string]string - // squash the resulting image's layers to the parent - // preserves the original image and creates a new one from the parent with all - // the changes applied to a single layer - Squash bool - // CacheFrom specifies images that are used for matching cache. Images - // specified here do not need to have a valid parent chain to match cache. - CacheFrom []string - SecurityOpt []string - ExtraHosts []string // List of extra hosts - Target string - SessionID string - Platform string - // Version specifies the version of the underlying builder to use - Version BuilderVersion - // BuildID is an optional identifier that can be passed together with the - // build request. The same identifier can be used to gracefully cancel the - // build with the cancel request. - BuildID string - // Outputs defines configurations for exporting build results. Only supported - // in BuildKit mode - Outputs []ImageBuildOutput -} - -// ImageBuildOutput defines configuration for exporting a build result -type ImageBuildOutput struct { - Type string - Attrs map[string]string -} - -// ImageBuildResponse holds information -// returned by a server after building -// an image. -type ImageBuildResponse struct { - Body io.ReadCloser - OSType string -} diff --git a/vendor/github.com/moby/moby/client/client_interfaces.go b/vendor/github.com/moby/moby/client/client_interfaces.go index f75f8f79a2..448ecd9f71 100644 --- a/vendor/github.com/moby/moby/client/client_interfaces.go +++ b/vendor/github.com/moby/moby/client/client_interfaces.go @@ -106,7 +106,7 @@ type DistributionAPIClient interface { // ImageAPIClient defines API client methods for the images type ImageAPIClient interface { - ImageBuild(ctx context.Context, context io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error) + ImageBuild(ctx context.Context, context io.Reader, options ImageBuildOptions) (ImageBuildResponse, error) BuildCachePrune(ctx context.Context, opts BuildCachePruneOptions) (*build.CachePruneReport, error) BuildCancel(ctx context.Context, id string) error ImageCreate(ctx context.Context, parentReference string, options ImageCreateOptions) (io.ReadCloser, error) diff --git a/vendor/github.com/moby/moby/client/image_build.go b/vendor/github.com/moby/moby/client/image_build.go index 94ec6c3a42..5c1634d08b 100644 --- a/vendor/github.com/moby/moby/client/image_build.go +++ b/vendor/github.com/moby/moby/client/image_build.go @@ -10,7 +10,6 @@ import ( "strconv" "strings" - "github.com/moby/moby/api/types/build" "github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/network" ) @@ -18,15 +17,15 @@ import ( // ImageBuild sends a request to the daemon to build images. // The Body in the response implements an [io.ReadCloser] and it's up to the caller to // close it. -func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error) { +func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, options ImageBuildOptions) (ImageBuildResponse, error) { query, err := cli.imageBuildOptionsToQuery(ctx, options) if err != nil { - return build.ImageBuildResponse{}, err + return ImageBuildResponse{}, err } buf, err := json.Marshal(options.AuthConfigs) if err != nil { - return build.ImageBuildResponse{}, err + return ImageBuildResponse{}, err } headers := http.Header{} @@ -35,16 +34,16 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio resp, err := cli.postRaw(ctx, "/build", query, buildContext, headers) if err != nil { - return build.ImageBuildResponse{}, err + return ImageBuildResponse{}, err } - return build.ImageBuildResponse{ + return ImageBuildResponse{ Body: resp.Body, OSType: resp.Header.Get("Ostype"), }, nil } -func (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options build.ImageBuildOptions) (url.Values, error) { +func (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options ImageBuildOptions) (url.Values, error) { query := url.Values{} if len(options.Tags) > 0 { query["t"] = options.Tags diff --git a/vendor/github.com/moby/moby/client/image_build_opts.go b/vendor/github.com/moby/moby/client/image_build_opts.go new file mode 100644 index 0000000000..df51db09eb --- /dev/null +++ b/vendor/github.com/moby/moby/client/image_build_opts.go @@ -0,0 +1,77 @@ +package client + +import ( + "io" + + "github.com/moby/moby/api/types/build" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/registry" +) + +// ImageBuildOptions holds the information +// necessary to build images. +type ImageBuildOptions struct { + Tags []string + SuppressOutput bool + RemoteContext string + NoCache bool + Remove bool + ForceRemove bool + PullParent bool + Isolation container.Isolation + CPUSetCPUs string + CPUSetMems string + CPUShares int64 + CPUQuota int64 + CPUPeriod int64 + Memory int64 + MemorySwap int64 + CgroupParent string + NetworkMode string + ShmSize int64 + Dockerfile string + Ulimits []*container.Ulimit + // BuildArgs needs to be a *string instead of just a string so that + // we can tell the difference between "" (empty string) and no value + // at all (nil). See the parsing of buildArgs in + // api/server/router/build/build_routes.go for even more info. + BuildArgs map[string]*string + AuthConfigs map[string]registry.AuthConfig + Context io.Reader + Labels map[string]string + // squash the resulting image's layers to the parent + // preserves the original image and creates a new one from the parent with all + // the changes applied to a single layer + Squash bool + // CacheFrom specifies images that are used for matching cache. Images + // specified here do not need to have a valid parent chain to match cache. + CacheFrom []string + SecurityOpt []string + ExtraHosts []string // List of extra hosts + Target string + SessionID string + Platform string + // Version specifies the version of the underlying builder to use + Version build.BuilderVersion + // BuildID is an optional identifier that can be passed together with the + // build request. The same identifier can be used to gracefully cancel the + // build with the cancel request. + BuildID string + // Outputs defines configurations for exporting build results. Only supported + // in BuildKit mode + Outputs []ImageBuildOutput +} + +// ImageBuildOutput defines configuration for exporting a build result +type ImageBuildOutput struct { + Type string + Attrs map[string]string +} + +// ImageBuildResponse holds information +// returned by a server after building +// an image. +type ImageBuildResponse struct { + Body io.ReadCloser + OSType string +}