func (s *ProxyTestSuite) SetUpSuite(c *check.C) { cli, err := events.NewDockerClient() if err != nil { c.Fatalf("Could not connect to docker, err: [%v]", err) } s.client = cli s.setupWebsocketProxy() }
func (l *LogsHandler) Handle(key string, initialMessage string, incomingMessages <-chan string, response chan<- common.Message) { defer backend.SignalHandlerClosed(key, response) requestUrl, err := url.Parse(initialMessage) if err != nil { log.WithFields(log.Fields{"error": err, "url": initialMessage}).Error("Couldn't parse url.") return } tokenString := requestUrl.Query().Get("token") token, valid := auth.GetAndCheckToken(tokenString) if !valid { return } logs := token.Claims["logs"].(map[string]interface{}) container := logs["Container"].(string) follow, found := logs["Follow"].(bool) if !found { follow = true } tailTemp, found := logs["Lines"].(int) var tail string if found { tail = strconv.Itoa(int(tailTemp)) } else { tail = "100" } client, err := events.NewDockerClient() if err != nil { log.WithFields(log.Fields{"error": err}).Error("Couldn't get docker client.") return } reader, writer := io.Pipe() containerRef, err := client.InspectContainer(container) if err != nil { return } logopts := dockerClient.LogsOptions{ Container: container, Follow: follow, Stdout: true, Stderr: true, Timestamps: true, Tail: tail, } if containerRef.Config.Tty { logopts.OutputStream = stdbothWriter{writer} logopts.RawTerminal = true } else { logopts.OutputStream = stdoutWriter{writer} logopts.ErrorStream = stderrorWriter{writer} logopts.RawTerminal = false } go func(w *io.PipeWriter) { for { _, ok := <-incomingMessages if !ok { w.Close() return } } }(writer) go func(r *io.PipeReader) { scanner := bufio.NewScanner(r) scanner.Split(customSplit) for scanner.Scan() { text := scanner.Text() message := common.Message{ Key: key, Type: common.Body, Body: text, } response <- message } if err := scanner.Err(); err != nil { log.WithFields(log.Fields{"error": err}).Error("Error with the container log scanner.") } }(reader) // Returns an error, but ignoring it because it will always return an error when a streaming call is made. client.Logs(logopts) }
func (h *ExecHandler) Handle(key string, initialMessage string, incomingMessages <-chan string, response chan<- common.Message) { defer backend.SignalHandlerClosed(key, response) requestUrl, err := url.Parse(initialMessage) if err != nil { log.WithFields(log.Fields{"error": err, "url": initialMessage}).Error("Couldn't parse url.") return } tokenString := requestUrl.Query().Get("token") token, valid := auth.GetAndCheckToken(tokenString) if !valid { return } execMap := token.Claims["exec"].(map[string]interface{}) execConfig := convert(execMap) client, err := events.NewDockerClient() if err != nil { log.WithFields(log.Fields{"error": err}).Error("Couldn't get docker client.") return } outputReader, outputWriter := io.Pipe() inputReader, inputWriter := io.Pipe() execObj, err := client.CreateExec(execConfig) if err != nil { return } go func(w *io.PipeWriter) { for { msg, ok := <-incomingMessages if !ok { w.Close() return } data, err := base64.StdEncoding.DecodeString(msg) if err != nil { log.WithFields(log.Fields{"error": err}).Error("Error decoding message.") continue } inputWriter.Write([]byte(data)) } }(outputWriter) go func(r *io.PipeReader) { scanner := bufio.NewScanner(r) scanner.Split(bufio.ScanRunes) for scanner.Scan() { data := scanner.Bytes() text := base64.StdEncoding.EncodeToString(data) message := common.Message{ Key: key, Type: common.Body, Body: text, } response <- message } if err := scanner.Err(); err != nil { log.WithFields(log.Fields{"error": err}).Error("Error with the exec scanner.") } }(outputReader) startConfig := dockerClient.StartExecOptions{ Detach: false, Tty: true, RawTerminal: true, InputStream: inputReader, OutputStream: outputWriter, } client.StartExec(execObj.ID, startConfig) }