Merge pull request #102 from keloyang/attach-block

Recheck the container's state to avoid attach block.
This commit is contained in:
Sebastiaan van Stijn 2017-05-24 12:09:38 +01:00 committed by GitHub
commit 61c0b9f78d
1 changed files with 29 additions and 9 deletions

View File

@ -8,6 +8,7 @@ import (
"github.com/docker/cli/cli" "github.com/docker/cli/cli"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/signal"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -22,6 +23,20 @@ type attachOptions struct {
container string container string
} }
func inspectContainerAndCheckState(ctx context.Context, cli client.APIClient, args string) (*types.ContainerJSON, error) {
c, err := cli.ContainerInspect(ctx, args)
if err != nil {
return nil, err
}
if !c.State.Running {
return nil, errors.New("You cannot attach to a stopped container, start it first")
}
if c.State.Paused {
return nil, errors.New("You cannot attach to a paused container, unpause it first")
}
return &c, nil
}
// NewAttachCommand creates a new cobra.Command for `docker attach` // NewAttachCommand creates a new cobra.Command for `docker attach`
func NewAttachCommand(dockerCli *command.DockerCli) *cobra.Command { func NewAttachCommand(dockerCli *command.DockerCli) *cobra.Command {
var opts attachOptions var opts attachOptions
@ -47,19 +62,11 @@ func runAttach(dockerCli *command.DockerCli, opts *attachOptions) error {
ctx := context.Background() ctx := context.Background()
client := dockerCli.Client() client := dockerCli.Client()
c, err := client.ContainerInspect(ctx, opts.container) c, err := inspectContainerAndCheckState(ctx, client, opts.container)
if err != nil { if err != nil {
return err return err
} }
if !c.State.Running {
return errors.New("You cannot attach to a stopped container, start it first")
}
if c.State.Paused {
return errors.New("You cannot attach to a paused container, unpause it first")
}
if err := dockerCli.In().CheckTty(!opts.noStdin, c.Config.Tty); err != nil { if err := dockerCli.In().CheckTty(!opts.noStdin, c.Config.Tty); err != nil {
return err return err
} }
@ -95,6 +102,19 @@ func runAttach(dockerCli *command.DockerCli, opts *attachOptions) error {
} }
defer resp.Close() defer resp.Close()
// If use docker attach command to attach to a stop container, it will return
// "You cannot attach to a stopped container" error, it's ok, but when
// attach to a running container, it(docker attach) use inspect to check
// the container's state, if it pass the state check on the client side,
// and then the container is stopped, docker attach command still attach to
// the container and not exit.
//
// Recheck the container's state to avoid attach block.
_, err = inspectContainerAndCheckState(ctx, client, opts.container)
if err != nil {
return err
}
if c.Config.Tty && dockerCli.Out().IsTerminal() { if c.Config.Tty && dockerCli.Out().IsTerminal() {
height, width := dockerCli.Out().GetTtySize() height, width := dockerCli.Out().GetTtySize()
// To handle the case where a user repeatedly attaches/detaches without resizing their // To handle the case where a user repeatedly attaches/detaches without resizing their