github.com/rsampaio/docker@v0.7.2-0.20150827203920-fdc73cc3fc31/api/server/exec.go (about) 1 package server 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "net/http" 8 "strconv" 9 10 "github.com/Sirupsen/logrus" 11 "github.com/docker/docker/api/types" 12 "github.com/docker/docker/pkg/stdcopy" 13 "github.com/docker/docker/pkg/version" 14 "github.com/docker/docker/runconfig" 15 ) 16 17 func (s *Server) getExecByID(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 18 if vars == nil { 19 return fmt.Errorf("Missing parameter 'id'") 20 } 21 22 eConfig, err := s.daemon.ContainerExecInspect(vars["id"]) 23 if err != nil { 24 return err 25 } 26 27 return writeJSON(w, http.StatusOK, eConfig) 28 } 29 30 func (s *Server) postContainerExecCreate(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 31 if err := parseForm(r); err != nil { 32 return err 33 } 34 if err := checkForJSON(r); err != nil { 35 return err 36 } 37 name := vars["name"] 38 39 execConfig := &runconfig.ExecConfig{} 40 if err := json.NewDecoder(r.Body).Decode(execConfig); err != nil { 41 return err 42 } 43 execConfig.Container = name 44 45 if len(execConfig.Cmd) == 0 { 46 return fmt.Errorf("No exec command specified") 47 } 48 49 // Register an instance of Exec in container. 50 id, err := s.daemon.ContainerExecCreate(execConfig) 51 if err != nil { 52 logrus.Errorf("Error setting up exec command in container %s: %s", name, err) 53 return err 54 } 55 56 return writeJSON(w, http.StatusCreated, &types.ContainerExecCreateResponse{ 57 ID: id, 58 }) 59 } 60 61 // TODO(vishh): Refactor the code to avoid having to specify stream config as part of both create and start. 62 func (s *Server) postContainerExecStart(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 63 if err := parseForm(r); err != nil { 64 return err 65 } 66 var ( 67 execName = vars["name"] 68 stdin, inStream io.ReadCloser 69 stdout, stderr, outStream io.Writer 70 ) 71 72 execStartCheck := &types.ExecStartCheck{} 73 if err := json.NewDecoder(r.Body).Decode(execStartCheck); err != nil { 74 return err 75 } 76 77 if !execStartCheck.Detach { 78 var err error 79 // Setting up the streaming http interface. 80 inStream, outStream, err = hijackServer(w) 81 if err != nil { 82 return err 83 } 84 defer closeStreams(inStream, outStream) 85 86 if _, ok := r.Header["Upgrade"]; ok { 87 fmt.Fprintf(outStream, "HTTP/1.1 101 UPGRADED\r\nContent-Type: application/vnd.docker.raw-stream\r\nConnection: Upgrade\r\nUpgrade: tcp\r\n\r\n") 88 } else { 89 fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n") 90 } 91 92 stdin = inStream 93 stdout = outStream 94 if !execStartCheck.Tty { 95 stderr = stdcopy.NewStdWriter(outStream, stdcopy.Stderr) 96 stdout = stdcopy.NewStdWriter(outStream, stdcopy.Stdout) 97 } 98 } else { 99 outStream = w 100 } 101 102 // Now run the user process in container. 103 if err := s.daemon.ContainerExecStart(execName, stdin, stdout, stderr); err != nil { 104 fmt.Fprintf(outStream, "Error running exec in container: %v\n", err) 105 } 106 return nil 107 } 108 109 func (s *Server) postContainerExecResize(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 110 if err := parseForm(r); err != nil { 111 return err 112 } 113 if vars == nil { 114 return fmt.Errorf("Missing parameter") 115 } 116 117 height, err := strconv.Atoi(r.Form.Get("h")) 118 if err != nil { 119 return err 120 } 121 width, err := strconv.Atoi(r.Form.Get("w")) 122 if err != nil { 123 return err 124 } 125 126 return s.daemon.ContainerExecResize(vars["name"], height, width) 127 }