mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
daemon/server/backend: move build options to buildbackend
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 == "":
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user