build: remove --stream

--stream was always experimental and this patch removes the functionality.

Users should enable BuildKit with DOCKER_BUILDKIT=1

Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
Tibor Vass 2019-09-24 21:24:46 +00:00
parent 47fd8986ea
commit c3990f3ba6
3 changed files with 5 additions and 154 deletions

View File

@ -10,7 +10,6 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net"
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
@ -33,7 +32,6 @@ import (
"github.com/docker/docker/pkg/urlutil" "github.com/docker/docker/pkg/urlutil"
units "github.com/docker/go-units" units "github.com/docker/go-units"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -165,9 +163,7 @@ func NewBuildCommand(dockerCli command.Cli) *cobra.Command {
flags.SetAnnotation("squash", "version", []string{"1.25"}) flags.SetAnnotation("squash", "version", []string{"1.25"})
flags.BoolVar(&options.stream, "stream", false, "Stream attaches to server to negotiate build context") flags.BoolVar(&options.stream, "stream", false, "Stream attaches to server to negotiate build context")
flags.SetAnnotation("stream", "experimental", nil) flags.MarkHidden("stream")
flags.SetAnnotation("stream", "version", []string{"1.31"})
flags.SetAnnotation("stream", "no-buildkit", nil)
flags.StringVar(&options.progress, "progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output") flags.StringVar(&options.progress, "progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output")
flags.SetAnnotation("progress", "buildkit", nil) flags.SetAnnotation("progress", "buildkit", nil)
@ -224,8 +220,8 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
remote string remote string
) )
if options.compress && options.stream { if options.stream {
return errors.New("--compress conflicts with --stream options") return errors.New("Experimental flag --stream was removed, enable BuildKit instead with DOCKER_BUILDKIT=1")
} }
if options.dockerfileFromStdin() { if options.dockerfileFromStdin() {
@ -284,7 +280,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
} }
// read from a directory into tar archive // read from a directory into tar archive
if buildCtx == nil && !options.stream { if buildCtx == nil {
excludes, err := build.ReadDockerignore(contextDir) excludes, err := build.ReadDockerignore(contextDir)
if err != nil { if err != nil {
return err return err
@ -315,16 +311,6 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
} }
} }
// if streaming and Dockerfile was not from stdin then read from file
// to the same reader that is usually stdin
if options.stream && dockerfileCtx == nil {
dockerfileCtx, err = os.Open(relDockerfile)
if err != nil {
return errors.Wrapf(err, "failed to open %s", relDockerfile)
}
defer dockerfileCtx.Close()
}
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
@ -367,38 +353,11 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
buildCtx = dockerfileCtx buildCtx = dockerfileCtx
} }
s, err := trySession(dockerCli, contextDir, true)
if err != nil {
return err
}
var body io.Reader var body io.Reader
if buildCtx != nil && !options.stream { if buildCtx != nil {
body = progress.NewProgressReader(buildCtx, progressOutput, 0, "", "Sending build context to Docker daemon") body = progress.NewProgressReader(buildCtx, progressOutput, 0, "", "Sending build context to Docker daemon")
} }
// add context stream to the session
if options.stream && s != nil {
syncDone := make(chan error) // used to signal first progress reporting completed.
// progress would also send errors but don't need it here as errors
// are handled by session.Run() and ImageBuild()
if err := addDirToSession(s, contextDir, progressOutput, syncDone); err != nil {
return err
}
buf := newBufferedWriter(syncDone, buildBuff)
defer func() {
select {
case <-buf.flushed:
case <-ctx.Done():
}
}()
buildBuff = buf
remote = clientSessionRemote
body = buildCtx
}
configFile := dockerCli.ConfigFile() configFile := dockerCli.ConfigFile()
creds, _ := configFile.GetAllCredentials() creds, _ := configFile.GetAllCredentials()
authConfigs := make(map[string]types.AuthConfig, len(creds)) authConfigs := make(map[string]types.AuthConfig, len(creds))
@ -411,20 +370,6 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
buildOptions.AuthConfigs = authConfigs buildOptions.AuthConfigs = authConfigs
buildOptions.RemoteContext = remote buildOptions.RemoteContext = remote
if s != nil {
go func() {
logrus.Debugf("running session: %v", s.ID())
dialSession := func(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error) {
return dockerCli.Client().DialHijack(ctx, "/session", proto, meta)
}
if err := s.Run(ctx, dialSession); err != nil {
logrus.Error(err)
cancel() // cancel progress context
}
}()
buildOptions.SessionID = s.ID()
}
response, err := dockerCli.Client().ImageBuild(ctx, body, buildOptions) response, err := dockerCli.Client().ImageBuild(ctx, body, buildOptions)
if err != nil { if err != nil {
if options.quiet { if options.quiet {

View File

@ -1,28 +1,20 @@
package image package image
import ( import (
"bytes"
"context" "context"
"crypto/rand" "crypto/rand"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"sync"
"time"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/image/build"
cliconfig "github.com/docker/cli/cli/config" cliconfig "github.com/docker/cli/cli/config"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
"github.com/docker/docker/pkg/progress"
"github.com/moby/buildkit/session" "github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/filesync"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/time/rate"
) )
const clientSessionRemote = "client-session" const clientSessionRemote = "client-session"
@ -49,87 +41,6 @@ func trySession(dockerCli command.Cli, contextDir string, forStream bool) (*sess
return s, nil return s, nil
} }
func addDirToSession(session *session.Session, contextDir string, progressOutput progress.Output, done chan error) error {
excludes, err := build.ReadDockerignore(contextDir)
if err != nil {
return err
}
p := &sizeProgress{out: progressOutput, action: "Streaming build context to Docker daemon"}
workdirProvider := filesync.NewFSSyncProvider([]filesync.SyncedDir{
{Dir: contextDir, Excludes: excludes},
})
session.Allow(workdirProvider)
// this will be replaced on parallel build jobs. keep the current
// progressbar for now
if snpc, ok := workdirProvider.(interface {
SetNextProgressCallback(func(int, bool), chan error)
}); ok {
snpc.SetNextProgressCallback(p.update, done)
}
return nil
}
type sizeProgress struct {
out progress.Output
action string
limiter *rate.Limiter
}
func (sp *sizeProgress) update(size int, last bool) {
if sp.limiter == nil {
sp.limiter = rate.NewLimiter(rate.Every(100*time.Millisecond), 1)
}
if last || sp.limiter.Allow() {
sp.out.WriteProgress(progress.Progress{Action: sp.action, Current: int64(size), LastUpdate: last})
}
}
type bufferedWriter struct {
done chan error
io.Writer
buf *bytes.Buffer
flushed chan struct{}
mu sync.Mutex
}
func newBufferedWriter(done chan error, w io.Writer) *bufferedWriter {
bw := &bufferedWriter{done: done, Writer: w, buf: new(bytes.Buffer), flushed: make(chan struct{})}
go func() {
<-done
bw.flushBuffer()
}()
return bw
}
func (bw *bufferedWriter) Write(dt []byte) (int, error) {
select {
case <-bw.done:
bw.flushBuffer()
return bw.Writer.Write(dt)
default:
return bw.buf.Write(dt)
}
}
func (bw *bufferedWriter) flushBuffer() {
bw.mu.Lock()
select {
case <-bw.flushed:
default:
bw.Writer.Write(bw.buf.Bytes())
close(bw.flushed)
}
bw.mu.Unlock()
}
func (bw *bufferedWriter) String() string {
return fmt.Sprintf("%s", bw.Writer)
}
func getBuildSharedKey(dir string) (string, error) { func getBuildSharedKey(dir string) (string, error) {
// build session is hash of build dir with node based randomness // build session is hash of build dir with node based randomness
s := sha256.Sum256([]byte(fmt.Sprintf("%s:%s", tryNodeIdentifier(), dir))) s := sha256.Sum256([]byte(fmt.Sprintf("%s:%s", tryNodeIdentifier(), dir)))

View File

@ -2873,11 +2873,6 @@ _docker_image_build() {
boolean_options+=" boolean_options+="
--compress --compress
" "
if __docker_server_is_experimental ; then
boolean_options+="
--stream
"
fi
fi fi
local all_options="$options_with_args $boolean_options" local all_options="$options_with_args $boolean_options"