diff --git a/api/server/router/build/backend.go b/api/server/router/build/backend.go index 46b8a59ff0..18ba1b2769 100644 --- a/api/server/router/build/backend.go +++ b/api/server/router/build/backend.go @@ -3,7 +3,7 @@ package build import ( "io" - "github.com/docker/docker/builder" + "github.com/docker/docker/api/types/backend" "github.com/docker/engine-api/types" "golang.org/x/net/context" ) @@ -16,5 +16,5 @@ type Backend interface { // by the caller. // // TODO: make this return a reference instead of string - Build(clientCtx context.Context, config *types.ImageBuildOptions, context builder.Context, stdout io.Writer, stderr io.Writer, out io.Writer) (string, error) + BuildFromContext(ctx context.Context, src io.ReadCloser, remote string, buildOptions *types.ImageBuildOptions, pg backend.ProgressWriter) (string, error) } diff --git a/api/server/router/build/build_routes.go b/api/server/router/build/build_routes.go index 9d0380d0a7..84610126ac 100644 --- a/api/server/router/build/build_routes.go +++ b/api/server/router/build/build_routes.go @@ -13,7 +13,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/docker/api/server/httputils" - "github.com/docker/docker/builder" + "github.com/docker/docker/api/types/backend" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/streamformatter" @@ -148,6 +148,7 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r * if err != nil { return errf(err) } + buildOptions.AuthConfigs = authConfigs remoteURL := r.FormValue("remote") @@ -161,21 +162,6 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r * return progress.NewProgressReader(in, progressOutput, r.ContentLength, "Downloading context", remoteURL) } - buildContext, dockerfileName, err := builder.DetectContextFromRemoteURL(r.Body, remoteURL, createProgressReader) - if err != nil { - return errf(err) - } - defer func() { - if err := buildContext.Close(); err != nil { - logrus.Debugf("[BUILDER] failed to remove temporary context: %v", err) - } - }() - if len(dockerfileName) > 0 { - buildOptions.Dockerfile = dockerfileName - } - - buildOptions.AuthConfigs = authConfigs - var out io.Writer = output if buildOptions.SuppressOutput { out = notVerboseBuffer @@ -184,9 +170,14 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r * stdout := &streamformatter.StdoutFormatter{Writer: out, StreamFormatter: sf} stderr := &streamformatter.StderrFormatter{Writer: out, StreamFormatter: sf} - imgID, err := br.backend.Build(ctx, buildOptions, - builder.DockerIgnoreContext{ModifiableContext: buildContext}, - stdout, stderr, out) + pg := backend.ProgressWriter{ + Output: out, + StdoutFormatter: stdout, + StderrFormatter: stderr, + ProgressReaderFunc: createProgressReader, + } + + imgID, err := br.backend.BuildFromContext(ctx, r.Body, remoteURL, buildOptions, pg) if err != nil { return errf(err) } diff --git a/api/types/backend/backend.go b/api/types/backend/backend.go index e3d981d7a9..f93f99ed5e 100644 --- a/api/types/backend/backend.go +++ b/api/types/backend/backend.go @@ -6,6 +6,7 @@ package backend import ( "io" + "github.com/docker/docker/pkg/streamformatter" "github.com/docker/engine-api/types" ) @@ -73,3 +74,12 @@ type ContainerCommitConfig struct { types.ContainerCommitConfig Changes []string } + +// ProgressWriter is an interface +// to transport progress streams. +type ProgressWriter struct { + Output io.Writer + StdoutFormatter *streamformatter.StdoutFormatter + StderrFormatter *streamformatter.StderrFormatter + ProgressReaderFunc func(io.ReadCloser) io.ReadCloser +} diff --git a/daemon/builder.go b/daemon/builder.go new file mode 100644 index 0000000000..074b48b86e --- /dev/null +++ b/daemon/builder.go @@ -0,0 +1,33 @@ +package daemon + +import ( + "io" + + "github.com/Sirupsen/logrus" + "github.com/docker/docker/api/types/backend" + "github.com/docker/docker/builder" + "github.com/docker/docker/builder/dockerfile" + "github.com/docker/engine-api/types" + "golang.org/x/net/context" +) + +// BuildFromContext builds a new image from a given context. +func (daemon *Daemon) BuildFromContext(ctx context.Context, src io.ReadCloser, remote string, buildOptions *types.ImageBuildOptions, pg backend.ProgressWriter) (string, error) { + buildContext, dockerfileName, err := builder.DetectContextFromRemoteURL(src, remote, pg.ProgressReaderFunc) + if err != nil { + return "", err + } + defer func() { + if err := buildContext.Close(); err != nil { + logrus.Debugf("[BUILDER] failed to remove temporary context: %v", err) + } + }() + if len(dockerfileName) > 0 { + buildOptions.Dockerfile = dockerfileName + } + + m := dockerfile.NewBuildManager(daemon) + return m.Build(ctx, buildOptions, + builder.DockerIgnoreContext{ModifiableContext: buildContext}, + pg.StdoutFormatter, pg.StderrFormatter, pg.Output) +} diff --git a/docker/daemon.go b/docker/daemon.go index 7afe8e4249..ae804cde69 100644 --- a/docker/daemon.go +++ b/docker/daemon.go @@ -22,7 +22,6 @@ import ( "github.com/docker/docker/api/server/router/network" systemrouter "github.com/docker/docker/api/server/router/system" "github.com/docker/docker/api/server/router/volume" - "github.com/docker/docker/builder/dockerfile" "github.com/docker/docker/cli" "github.com/docker/docker/cliconfig" "github.com/docker/docker/daemon" @@ -413,7 +412,7 @@ func initRouter(s *apiserver.Server, d *daemon.Daemon) { image.NewRouter(d, decoder), systemrouter.NewRouter(d), volume.NewRouter(d), - build.NewRouter(dockerfile.NewBuildManager(d)), + build.NewRouter(d), } if d.NetworkControllerEnabled() { routers = append(routers, network.NewRouter(d))