mirror of https://github.com/docker/cli.git
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:
parent
47fd8986ea
commit
c3990f3ba6
|
@ -10,7 +10,6 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
@ -33,7 +32,6 @@ import (
|
|||
"github.com/docker/docker/pkg/urlutil"
|
||||
units "github.com/docker/go-units"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -165,9 +163,7 @@ func NewBuildCommand(dockerCli command.Cli) *cobra.Command {
|
|||
flags.SetAnnotation("squash", "version", []string{"1.25"})
|
||||
|
||||
flags.BoolVar(&options.stream, "stream", false, "Stream attaches to server to negotiate build context")
|
||||
flags.SetAnnotation("stream", "experimental", nil)
|
||||
flags.SetAnnotation("stream", "version", []string{"1.31"})
|
||||
flags.SetAnnotation("stream", "no-buildkit", nil)
|
||||
flags.MarkHidden("stream")
|
||||
|
||||
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)
|
||||
|
@ -224,8 +220,8 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
|
|||
remote string
|
||||
)
|
||||
|
||||
if options.compress && options.stream {
|
||||
return errors.New("--compress conflicts with --stream options")
|
||||
if options.stream {
|
||||
return errors.New("Experimental flag --stream was removed, enable BuildKit instead with DOCKER_BUILDKIT=1")
|
||||
}
|
||||
|
||||
if options.dockerfileFromStdin() {
|
||||
|
@ -284,7 +280,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
|
|||
}
|
||||
|
||||
// read from a directory into tar archive
|
||||
if buildCtx == nil && !options.stream {
|
||||
if buildCtx == nil {
|
||||
excludes, err := build.ReadDockerignore(contextDir)
|
||||
if err != nil {
|
||||
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())
|
||||
defer cancel()
|
||||
|
||||
|
@ -367,38 +353,11 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
|
|||
buildCtx = dockerfileCtx
|
||||
}
|
||||
|
||||
s, err := trySession(dockerCli, contextDir, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var body io.Reader
|
||||
if buildCtx != nil && !options.stream {
|
||||
if buildCtx != nil {
|
||||
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()
|
||||
creds, _ := configFile.GetAllCredentials()
|
||||
authConfigs := make(map[string]types.AuthConfig, len(creds))
|
||||
|
@ -411,20 +370,6 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
|
|||
buildOptions.AuthConfigs = authConfigs
|
||||
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)
|
||||
if err != nil {
|
||||
if options.quiet {
|
||||
|
|
|
@ -1,28 +1,20 @@
|
|||
package image
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/image/build"
|
||||
cliconfig "github.com/docker/cli/cli/config"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/docker/pkg/progress"
|
||||
"github.com/moby/buildkit/session"
|
||||
"github.com/moby/buildkit/session/filesync"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
const clientSessionRemote = "client-session"
|
||||
|
@ -49,87 +41,6 @@ func trySession(dockerCli command.Cli, contextDir string, forStream bool) (*sess
|
|||
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) {
|
||||
// build session is hash of build dir with node based randomness
|
||||
s := sha256.Sum256([]byte(fmt.Sprintf("%s:%s", tryNodeIdentifier(), dir)))
|
||||
|
|
|
@ -2873,11 +2873,6 @@ _docker_image_build() {
|
|||
boolean_options+="
|
||||
--compress
|
||||
"
|
||||
if __docker_server_is_experimental ; then
|
||||
boolean_options+="
|
||||
--stream
|
||||
"
|
||||
fi
|
||||
fi
|
||||
|
||||
local all_options="$options_with_args $boolean_options"
|
||||
|
|
Loading…
Reference in New Issue