Ver Fonte

Fix race on ContainerAttachRaw

Signed-off-by: Jim Minter <jminter@redhat.com>
Jim Minter há 8 anos atrás
pai
commit
32ca1214fa

+ 1 - 1
builder/builder.go

@@ -114,7 +114,7 @@ type Backend interface {
 	// PullOnBuild tells Docker to pull image referenced by `name`.
 	// PullOnBuild tells Docker to pull image referenced by `name`.
 	PullOnBuild(ctx context.Context, name string, authConfigs map[string]types.AuthConfig, output io.Writer) (Image, error)
 	PullOnBuild(ctx context.Context, name string, authConfigs map[string]types.AuthConfig, output io.Writer) (Image, error)
 	// ContainerAttachRaw attaches to container.
 	// ContainerAttachRaw attaches to container.
-	ContainerAttachRaw(cID string, stdin io.ReadCloser, stdout, stderr io.Writer, stream bool) error
+	ContainerAttachRaw(cID string, stdin io.ReadCloser, stdout, stderr io.Writer, stream bool, attached chan struct{}) error
 	// ContainerCreate creates a new Docker container and returns potential warnings
 	// ContainerCreate creates a new Docker container and returns potential warnings
 	ContainerCreate(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error)
 	ContainerCreate(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error)
 	// ContainerRm removes a container specified by `id`.
 	// ContainerRm removes a container specified by `id`.

+ 8 - 1
builder/dockerfile/internals.go

@@ -573,11 +573,18 @@ func (b *Builder) create() (string, error) {
 var errCancelled = errors.New("build cancelled")
 var errCancelled = errors.New("build cancelled")
 
 
 func (b *Builder) run(cID string) (err error) {
 func (b *Builder) run(cID string) (err error) {
+	attached := make(chan struct{})
 	errCh := make(chan error)
 	errCh := make(chan error)
 	go func() {
 	go func() {
-		errCh <- b.docker.ContainerAttachRaw(cID, nil, b.Stdout, b.Stderr, true)
+		errCh <- b.docker.ContainerAttachRaw(cID, nil, b.Stdout, b.Stderr, true, attached)
 	}()
 	}()
 
 
+	select {
+	case err := <-errCh:
+		return err
+	case <-attached:
+	}
+
 	finished := make(chan struct{})
 	finished := make(chan struct{})
 	cancelErrCh := make(chan error, 1)
 	cancelErrCh := make(chan error, 1)
 	go func() {
 	go func() {

+ 1 - 1
builder/dockerfile/mockbackend_test.go

@@ -33,7 +33,7 @@ func (m *MockBackend) PullOnBuild(ctx context.Context, name string, authConfigs
 	return nil, nil
 	return nil, nil
 }
 }
 
 
-func (m *MockBackend) ContainerAttachRaw(cID string, stdin io.ReadCloser, stdout, stderr io.Writer, stream bool) error {
+func (m *MockBackend) ContainerAttachRaw(cID string, stdin io.ReadCloser, stdout, stderr io.Writer, stream bool, attached chan struct{}) error {
 	return nil
 	return nil
 }
 }
 
 

+ 2 - 1
daemon/attach.go

@@ -73,7 +73,7 @@ func (daemon *Daemon) ContainerAttach(prefixOrName string, c *backend.ContainerA
 }
 }
 
 
 // ContainerAttachRaw attaches the provided streams to the container's stdio
 // ContainerAttachRaw attaches the provided streams to the container's stdio
-func (daemon *Daemon) ContainerAttachRaw(prefixOrName string, stdin io.ReadCloser, stdout, stderr io.Writer, doStream bool) error {
+func (daemon *Daemon) ContainerAttachRaw(prefixOrName string, stdin io.ReadCloser, stdout, stderr io.Writer, doStream bool, attached chan struct{}) error {
 	container, err := daemon.GetContainer(prefixOrName)
 	container, err := daemon.GetContainer(prefixOrName)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -86,6 +86,7 @@ func (daemon *Daemon) ContainerAttachRaw(prefixOrName string, stdin io.ReadClose
 		CloseStdin: container.Config.StdinOnce,
 		CloseStdin: container.Config.StdinOnce,
 	}
 	}
 	container.StreamConfig.AttachStreams(&cfg)
 	container.StreamConfig.AttachStreams(&cfg)
+	close(attached)
 	if cfg.UseStdin {
 	if cfg.UseStdin {
 		cfg.Stdin = stdin
 		cfg.Stdin = stdin
 	}
 	}