github.com/ncdc/docker@v0.10.1-0.20160129113957-6c6729ef5b74/api/client/attach.go (about) 1 package client 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/Sirupsen/logrus" 8 Cli "github.com/docker/docker/cli" 9 flag "github.com/docker/docker/pkg/mflag" 10 "github.com/docker/docker/pkg/signal" 11 "github.com/docker/engine-api/types" 12 ) 13 14 // CmdAttach attaches to a running container. 15 // 16 // Usage: docker attach [OPTIONS] CONTAINER 17 func (cli *DockerCli) CmdAttach(args ...string) error { 18 cmd := Cli.Subcmd("attach", []string{"CONTAINER"}, Cli.DockerCommands["attach"].Description, true) 19 noStdin := cmd.Bool([]string{"-no-stdin"}, false, "Do not attach STDIN") 20 proxy := cmd.Bool([]string{"-sig-proxy"}, true, "Proxy all received signals to the process") 21 detachKeys := cmd.String([]string{"-detach-keys"}, "", "Override the key sequence for detaching a container") 22 23 cmd.Require(flag.Exact, 1) 24 25 cmd.ParseFlags(args, true) 26 27 c, err := cli.client.ContainerInspect(cmd.Arg(0)) 28 if err != nil { 29 return err 30 } 31 32 if !c.State.Running { 33 return fmt.Errorf("You cannot attach to a stopped container, start it first") 34 } 35 36 if c.State.Paused { 37 return fmt.Errorf("You cannot attach to a paused container, unpause it first") 38 } 39 40 if err := cli.CheckTtyInput(!*noStdin, c.Config.Tty); err != nil { 41 return err 42 } 43 44 if c.Config.Tty && cli.isTerminalOut { 45 if err := cli.monitorTtySize(cmd.Arg(0), false); err != nil { 46 logrus.Debugf("Error monitoring TTY size: %s", err) 47 } 48 } 49 50 if *detachKeys != "" { 51 cli.configFile.DetachKeys = *detachKeys 52 } 53 54 options := types.ContainerAttachOptions{ 55 ContainerID: cmd.Arg(0), 56 Stream: true, 57 Stdin: !*noStdin && c.Config.OpenStdin, 58 Stdout: true, 59 Stderr: true, 60 DetachKeys: cli.configFile.DetachKeys, 61 } 62 63 var in io.ReadCloser 64 if options.Stdin { 65 in = cli.in 66 } 67 68 if *proxy && !c.Config.Tty { 69 sigc := cli.forwardAllSignals(options.ContainerID) 70 defer signal.StopCatch(sigc) 71 } 72 73 resp, err := cli.client.ContainerAttach(options) 74 if err != nil { 75 return err 76 } 77 defer resp.Close() 78 if in != nil && c.Config.Tty { 79 if err := cli.setRawTerminal(); err != nil { 80 return err 81 } 82 defer cli.restoreTerminal(in) 83 } 84 85 if err := cli.holdHijackedConnection(c.Config.Tty, in, cli.out, cli.err, resp); err != nil { 86 return err 87 } 88 89 _, status, err := getExitCode(cli, options.ContainerID) 90 if err != nil { 91 return err 92 } 93 if status != 0 { 94 return Cli.StatusError{StatusCode: status} 95 } 96 97 return nil 98 }