github.com/squaremo/docker@v1.3.2-0.20150516120342-42cfc9554972/api/client/attach.go (about) 1 package client 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "net/url" 8 9 "github.com/Sirupsen/logrus" 10 "github.com/docker/docker/api/types" 11 flag "github.com/docker/docker/pkg/mflag" 12 "github.com/docker/docker/pkg/signal" 13 ) 14 15 // CmdAttach attaches to a running container. 16 // 17 // Usage: docker attach [OPTIONS] CONTAINER 18 func (cli *DockerCli) CmdAttach(args ...string) error { 19 var ( 20 cmd = cli.Subcmd("attach", "CONTAINER", "Attach to a running container", true) 21 noStdin = cmd.Bool([]string{"#nostdin", "-no-stdin"}, false, "Do not attach STDIN") 22 proxy = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxy all received signals to the process") 23 ) 24 cmd.Require(flag.Exact, 1) 25 26 cmd.ParseFlags(args, true) 27 name := cmd.Arg(0) 28 29 stream, _, err := cli.call("GET", "/containers/"+name+"/json", nil, nil) 30 if err != nil { 31 return err 32 } 33 34 var c types.ContainerJSON 35 if err := json.NewDecoder(stream).Decode(&c); err != nil { 36 return err 37 } 38 39 if !c.State.Running { 40 return fmt.Errorf("You cannot attach to a stopped container, start it first") 41 } 42 43 if err := cli.CheckTtyInput(!*noStdin, c.Config.Tty); err != nil { 44 return err 45 } 46 47 if c.Config.Tty && cli.isTerminalOut { 48 if err := cli.monitorTtySize(cmd.Arg(0), false); err != nil { 49 logrus.Debugf("Error monitoring TTY size: %s", err) 50 } 51 } 52 53 var in io.ReadCloser 54 55 v := url.Values{} 56 v.Set("stream", "1") 57 if !*noStdin && c.Config.OpenStdin { 58 v.Set("stdin", "1") 59 in = cli.in 60 } 61 62 v.Set("stdout", "1") 63 v.Set("stderr", "1") 64 65 if *proxy && !c.Config.Tty { 66 sigc := cli.forwardAllSignals(cmd.Arg(0)) 67 defer signal.StopCatch(sigc) 68 } 69 70 if err := cli.hijack("POST", "/containers/"+cmd.Arg(0)+"/attach?"+v.Encode(), c.Config.Tty, in, cli.out, cli.err, nil, nil); err != nil { 71 return err 72 } 73 74 _, status, err := getExitCode(cli, cmd.Arg(0)) 75 if err != nil { 76 return err 77 } 78 if status != 0 { 79 return StatusError{StatusCode: status} 80 } 81 82 return nil 83 }