func (s *statsHandler) Handle(key string, initialMessage string, incomingMessages <-chan string, response chan<- common.Message) { defer backend.SignalHandlerClosed(key, response) data := fmt.Sprintf("%d", s.i) wrap := common.Message{ Key: key, Type: common.Body, Body: data, } response <- wrap return }
func (e *oneAndDoneHandler) Handle(key string, initialMessage string, incomingMessages <-chan string, response chan<- common.Message) { defer backend.SignalHandlerClosed(key, response) m := <-incomingMessages if m != "" { data := fmt.Sprintf("%s-response", m) wrap := common.Message{ Key: key, Type: common.Body, Body: data, } response <- wrap } }
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 (s *StatsHandler) 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, "message": initialMessage}).Error("Couldn't parse url from message.") return } id := "" parts := pathParts(requestUrl.Path) if len(parts) == 3 { id = parts[2] } container, err := resolveContainer(id) if err != nil { log.WithFields(log.Fields{"id": id, "error": err}).Error("Couldn't find container for id.") return } c, err := client.NewClient(config.Config.CAdvisorUrl) if err != nil { log.WithFields(log.Fields{"error": err}).Error("Couldn't get CAdvisor client.") return } reader, writer := io.Pipe() go func(w *io.PipeWriter) { for { _, ok := <-incomingMessages if !ok { w.Close() return } } }(writer) go func(r *io.PipeReader) { scanner := bufio.NewScanner(r) 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 stat scanner.") } }(reader) count := config.Config.NumStats for { machineInfo, err := c.MachineInfo() if err != nil { log.WithFields(log.Fields{"error": err}).Error("Error getting machine info.") return } memLimit := machineInfo.MemoryCapacity info, err := c.ContainerInfo(container, &info.ContainerInfoRequest{ NumStats: count, }) if err != nil { return } err = writeStats(info, memLimit, writer) if err != nil { return } time.Sleep(1 * time.Second) count = 1 } return }
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) }
func (s *ContainerStatsHandler) 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, "message": initialMessage}).Error("Couldn't parse url from message.") return } tokenString := requestUrl.Query().Get("token") containerIds := map[string]string{} token, err := parseRequestToken(tokenString, config.Config.ParsedPublicKey) if err == nil { containerIdsInterface, found := token.Claims["containerIds"] if found { containerIdsVal, ok := containerIdsInterface.(map[string]interface{}) if ok { for key, val := range containerIdsVal { if containerIdsValString, ok := val.(string); ok { containerIds[key] = containerIdsValString } } } } } id := "" parts := pathParts(requestUrl.Path) if len(parts) == 3 { id = parts[2] } container, err := resolveContainer(id) if err != nil { log.WithFields(log.Fields{"id": id, "error": err}).Error("Couldn't find container for id.") return } c, err := client.NewClient(config.Config.CAdvisorUrl) if err != nil { log.WithFields(log.Fields{"error": err}).Error("Couldn't get CAdvisor client.") return } reader, writer := io.Pipe() go func(w *io.PipeWriter) { for { _, ok := <-incomingMessages if !ok { w.Close() return } } }(writer) go func(r *io.PipeReader) { scanner := bufio.NewScanner(r) 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 stat scanner.") } }(reader) count := config.Config.NumStats for { machineInfo, err := c.MachineInfo() if err != nil { log.WithFields(log.Fields{"error": err}).Error("Error getting machine info.") return } memLimit := machineInfo.MemoryCapacity infos := []info.ContainerInfo{} if container != "" { cInfo, err := c.ContainerInfo(container, &info.ContainerInfoRequest{ NumStats: count, }) if err != nil { return } infos = append(infos, *cInfo) } else { cInfos, err := c.AllDockerContainers(&info.ContainerInfoRequest{ NumStats: count, }) if err != nil { return } infos = append(infos, cInfos...) } err = writeAggregatedStats(id, containerIds, "container", infos, uint64(memLimit), writer) if err != nil { return } time.Sleep(1 * time.Second) count = 1 } return }
func (s *Handler) 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") _, valid := auth.GetAndCheckToken(tokenString) if !valid { return } conn, err := net.Dial("unix", "/var/run/docker.sock") if err != nil { log.WithFields(log.Fields{"error": err}).Error("Couldn't dial docker socket.") return } closed := false go func() { defer func() { closed = true conn.Close() }() for { msg, ok := <-incomingMessages if !ok { return } data, err := base64.StdEncoding.DecodeString(msg) if err != nil { log.WithFields(log.Fields{"error": err}).Error("Error decoding message.") return } if _, err := conn.Write(data); err != nil { log.WithFields(log.Fields{"error": err}).Error("Error write message.") return } } }() for { buff := make([]byte, 1024) n, err := conn.Read(buff) if n > 0 && err == nil { text := base64.StdEncoding.EncodeToString(buff[:n]) message := common.Message{ Key: key, Type: common.Body, Body: text, } response <- message } if err != nil { if err != io.EOF && !closed { log.WithFields(log.Fields{"error": err}).Errorf("Error reading response.") } return } } }
func (s *HostStatsHandler) Handle(key string, initialMessage string, incomingMessages <-chan string, response chan<- common.Message) { defer backend.SignalHandlerClosed(key, response) c, err := client.NewClient(config.Config.CAdvisorUrl) if err != nil { log.WithFields(log.Fields{"error": err}).Error("Couldn't get CAdvisor client.") return } requestUrl, err := url.Parse(initialMessage) if err != nil { log.WithFields(log.Fields{"error": err, "message": initialMessage}).Error("Couldn't parse url from message.") return } tokenString := requestUrl.Query().Get("token") resourceId := "" token, err := parseRequestToken(tokenString, config.Config.ParsedPublicKey) if err == nil { resourceIdInterface, found := token.Claims["resourceId"] if found { resourceIdVal, ok := resourceIdInterface.(string) if ok { resourceId = resourceIdVal } } } reader, writer := io.Pipe() go func(w *io.PipeWriter) { for { _, ok := <-incomingMessages if !ok { w.Close() return } } }(writer) go func(r *io.PipeReader) { scanner := bufio.NewScanner(r) 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 stat scanner.") } }(reader) count := config.Config.NumStats for { machineInfo, err := c.MachineInfo() if err != nil { log.WithFields(log.Fields{"error": err}).Error("Error getting machine info.") return } memLimit := machineInfo.MemoryCapacity infos := []info.ContainerInfo{} cInfo, err := c.ContainerInfo("", &info.ContainerInfoRequest{ NumStats: count, }) if err != nil { return } infos = append(infos, *cInfo) err = writeAggregatedStats(resourceId, nil, "host", infos, uint64(memLimit), writer) if err != nil { return } time.Sleep(1 * time.Second) count = 1 } return }