func (self *version2_0) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error { switch requestType { case summaryApi: containerName := getContainerName(request) glog.V(2).Infof("Api - Summary(%v)", containerName) stats, err := m.GetContainerDerivedStats(containerName) if err != nil { return err } return writeResult(stats, w) case statsApi: name := getContainerName(request) sr, err := getStatsRequest(name, r) if err != nil { return err } glog.V(2).Infof("Api - Stats: Looking for stats for container %q, options %+v", name, sr) query := info.ContainerInfoRequest{ NumStats: sr.Count, } cont, err := m.GetContainerInfo(name, &query) if err != nil { return fmt.Errorf("failed to get container %q: %v", name, err) } contStats := convertStats(cont) return writeResult(contStats, w) case specApi: containerName := getContainerName(request) glog.V(2).Infof("Api - Spec(%v)", containerName) spec, err := m.GetContainerSpec(containerName) if err != nil { return err } specV2 := convertSpec(spec) return writeResult(specV2, w) case storageApi: var err error fi := []v2.FsInfo{} label := r.URL.Query().Get("label") if len(label) == 0 { // Get all global filesystems info. fi, err = m.GetFsInfo("") if err != nil { return err } } else { // Get a specific label. fi, err = m.GetFsInfo(label) if err != nil { return err } } return writeResult(fi, w) default: return self.baseVersion.HandleRequest(requestType, request, m, w, r) } }
func HandleRequest(m manager.Manager, w http.ResponseWriter, u *url.URL) error { start := time.Now() // Get API request type. requestType := u.Path[len(ApiResource):] i := strings.Index(requestType, "/") requestArgs := "" if i != -1 { requestArgs = requestType[i:] requestType = requestType[:i] } if requestType == MachineApi { log.Printf("Api - Machine") // Get the MachineInfo machineInfo, err := m.GetMachineInfo() if err != nil { return err } out, err := json.Marshal(machineInfo) if err != nil { fmt.Fprintf(w, "Failed to marshall MachineInfo with error: %s", err) } w.Write(out) } else if requestType == ContainersApi { // The container name is the path after the requestType containerName := requestArgs log.Printf("Api - Container(%s)", containerName) // Get the container. cont, err := m.GetContainerInfo(containerName) if err != nil { fmt.Fprintf(w, "Failed to get container \"%s\" with error: %s", containerName, err) return err } // Only output the container as JSON. out, err := json.Marshal(cont) if err != nil { fmt.Fprintf(w, "Failed to marshall container %q with error: %s", containerName, err) } w.Write(out) } else { return fmt.Errorf("unknown API request type %q", requestType) } log.Printf("Request took %s", time.Since(start)) return nil }
func ServerContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) error { start := time.Now() // The container name is the path after the handler containerName := u.Path[len(ContainersPage)-1:] // Get the container. cont, err := m.GetContainerInfo(containerName) if err != nil { return fmt.Errorf("Failed to get container \"%s\" with error: %s", containerName, err) } // Get the MachineInfo machineInfo, err := m.GetMachineInfo() if err != nil { return err } // Make a list of the parent containers and their links var parentContainers []string parentContainers = append(parentContainers, string("root")) parentName := "" for _, part := range strings.Split(string(cont.Name), "/") { if part == "" { continue } parentName += "/" + part parentContainers = append(parentContainers, string(parentName)) } data := &pageData{ ContainerName: cont.Name, ParentContainers: parentContainers, Subcontainers: cont.Subcontainers, Spec: cont.Spec, Stats: cont.Stats, MachineInfo: machineInfo, ResourcesAvailable: cont.Spec.Cpu != nil || cont.Spec.Memory != nil, CpuAvailable: cont.Spec.Cpu != nil, MemoryAvailable: cont.Spec.Memory != nil, } err = pageTemplate.Execute(w, data) if err != nil { log.Printf("Failed to apply template: %s", err) } log.Printf("Request took %s", time.Since(start)) return nil }
func (self *version1_0) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error { switch requestType { case machineApi: glog.V(4).Infof("Api - Machine") // Get the MachineInfo machineInfo, err := m.GetMachineInfo() if err != nil { return err } err = writeResult(machineInfo, w) if err != nil { return err } case containersApi: containerName := getContainerName(request) glog.V(4).Infof("Api - Container(%s)", containerName) // Get the query request. query, err := getContainerInfoRequest(r.Body) if err != nil { return err } // Get the container. cont, err := m.GetContainerInfo(containerName, query) if err != nil { return fmt.Errorf("failed to get container %q with error: %s", containerName, err) } // Only output the container as JSON. err = writeResult(cont, w) if err != nil { return err } default: return fmt.Errorf("unknown request type %q", requestType) } return nil }
func ServerContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) error { start := time.Now() // The container name is the path after the handler containerName := u.Path[len(ContainersPage)-1:] // Get the container. reqParams := info.ContainerInfoRequest{ NumStats: 60, NumSamples: 60, } cont, err := m.GetContainerInfo(containerName, &reqParams) if err != nil { return fmt.Errorf("Failed to get container \"%s\" with error: %s", containerName, err) } // Get the MachineInfo machineInfo, err := m.GetMachineInfo() if err != nil { return err } // Make a list of the parent containers and their links var parentContainers []info.ContainerReference parentContainers = append(parentContainers, info.ContainerReference{Name: "root"}) parentName := "" for _, part := range strings.Split(string(cont.Name), "/") { if part == "" { continue } parentName += "/" + part parentContainers = append(parentContainers, info.ContainerReference{Name: parentName}) } // Pick the shortest name of the container as the display name. displayName := cont.Name for _, alias := range cont.Aliases { if len(displayName) >= len(alias) { displayName = alias } } // Replace the last part of the parent containers with the displayName. if displayName != cont.Name { parentContainers[len(parentContainers)-1] = info.ContainerReference{ Name: fmt.Sprintf("%s (%s)", displayName, path.Base(cont.Name)), } } data := &pageData{ ContainerName: displayName, // TODO(vmarmol): Only use strings for this. ParentContainers: parentContainers, Subcontainers: cont.Subcontainers, Spec: cont.Spec, Stats: cont.Stats, MachineInfo: machineInfo, ResourcesAvailable: cont.Spec.Cpu != nil || cont.Spec.Memory != nil, CpuAvailable: cont.Spec.Cpu != nil, MemoryAvailable: cont.Spec.Memory != nil, } err = pageTemplate.Execute(w, data) if err != nil { log.Printf("Failed to apply template: %s", err) } log.Printf("Request took %s", time.Since(start)) return nil }
func serveContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) error { start := time.Now() // The container name is the path after the handler containerName := u.Path[len(ContainersPage)-1:] // Get the container. reqParams := info.ContainerInfoRequest{ NumStats: 60, } cont, err := m.GetContainerInfo(containerName, &reqParams) if err != nil { return fmt.Errorf("failed to get container %q with error: %v", containerName, err) } displayName := getContainerDisplayName(cont.ContainerReference) // Get the MachineInfo machineInfo, err := m.GetMachineInfo() if err != nil { return err } // Make a list of the parent containers and their links pathParts := strings.Split(string(cont.Name), "/") parentContainers := make([]link, 0, len(pathParts)) parentContainers = append(parentContainers, link{ Text: "root", Link: ContainersPage, }) for i := 1; i < len(pathParts); i++ { // Skip empty parts. if pathParts[i] == "" { continue } parentContainers = append(parentContainers, link{ Text: pathParts[i], Link: path.Join(ContainersPage, path.Join(pathParts[1:i+1]...)), }) } // Build the links for the subcontainers. subcontainerLinks := make([]link, 0, len(cont.Subcontainers)) for _, sub := range cont.Subcontainers { subcontainerLinks = append(subcontainerLinks, link{ Text: getContainerDisplayName(sub), Link: path.Join(ContainersPage, sub.Name), }) } data := &pageData{ DisplayName: displayName, ContainerName: cont.Name, ParentContainers: parentContainers, Subcontainers: subcontainerLinks, Spec: cont.Spec, Stats: cont.Stats, MachineInfo: machineInfo, IsRoot: cont.Name == "/", ResourcesAvailable: cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork || cont.Spec.HasFilesystem, CpuAvailable: cont.Spec.HasCpu, MemoryAvailable: cont.Spec.HasMemory, NetworkAvailable: cont.Spec.HasNetwork, FsAvailable: cont.Spec.HasFilesystem, } err = pageTemplate.Execute(w, data) if err != nil { glog.Errorf("Failed to apply template: %s", err) } glog.V(1).Infof("Request took %s", time.Since(start)) return nil }
func handleRequest(m manager.Manager, w http.ResponseWriter, r *http.Request) error { start := time.Now() request := r.URL.Path requestElements := strings.Split(r.URL.Path, "/") // Verify that we have all the elements we expect: // <empty>/api/<version>/<request type>[/<args...>] // [0] [1] [2] [3] [4...] if len(requestElements) < 4 { return fmt.Errorf("incomplete API request %q", request) } // Get all the element parts. emptyElement := requestElements[0] apiElement := requestElements[1] version := requestElements[2] requestType := requestElements[3] requestArgs := []string{} if len(requestElements) > 4 { requestArgs = requestElements[4:] } // The container name is the path after the requestType. containerName := path.Join("/", strings.Join(requestArgs, "/")) // Check elements. if len(emptyElement) != 0 { return fmt.Errorf("unexpected API request format %q", request) } if apiElement != "api" { return fmt.Errorf("invalid API request format %q", request) } if _, ok := supportedApiVersions[version]; !ok { return fmt.Errorf("unsupported API version %q", version) } switch { case requestType == machineApi: glog.V(2).Infof("Api - Machine") // Get the MachineInfo machineInfo, err := m.GetMachineInfo() if err != nil { return err } err = writeResult(machineInfo, w) if err != nil { return err } case requestType == containersApi: glog.V(2).Infof("Api - Container(%s)", containerName) // Get the query request. query, err := getContainerInfoRequest(r.Body) if err != nil { return err } // Get the container. cont, err := m.GetContainerInfo(containerName, query) if err != nil { return fmt.Errorf("failed to get container %q with error: %s", containerName, err) } // Only output the container as JSON. err = writeResult(cont, w) if err != nil { return err } case requestType == subcontainersApi: if version == version1_0 { return fmt.Errorf("request type of %q not supported in API version %q", requestType, version) } glog.V(2).Infof("Api - Subcontainers(%s)", containerName) // Get the query request. query, err := getContainerInfoRequest(r.Body) if err != nil { return err } // Get the subcontainers. containers, err := m.SubcontainersInfo(containerName, query) if err != nil { return fmt.Errorf("failed to get subcontainers for container %q with error: %s", containerName, err) } // Only output the containers as JSON. err = writeResult(containers, w) if err != nil { return err } case requestType == dockerApi: if version == version1_0 || version == version1_1 { return fmt.Errorf("request type of %q not supported in API version %q", requestType, version) } glog.V(2).Infof("Api - Docker(%s)", containerName) // Get the query request. query, err := getContainerInfoRequest(r.Body) if err != nil { return err } // Get the Docker containers. containers, err := m.DockerContainersInfo(containerName, query) if err != nil { return fmt.Errorf("failed to get docker containers for %q with error: %s", containerName, err) } // Only output the containers as JSON. err = writeResult(containers, w) if err != nil { return err } default: return fmt.Errorf("unknown API request type %q", requestType) } glog.V(2).Infof("Request took %s", time.Since(start)) return nil }
func HandleRequest(m manager.Manager, w http.ResponseWriter, r *http.Request) error { start := time.Now() u := r.URL // Get API request type. requestType := u.Path[len(ApiResource):] i := strings.Index(requestType, "/") requestArgs := "" if i != -1 { requestArgs = requestType[i:] requestType = requestType[:i] } switch { case requestType == MachineApi: log.Printf("Api - Machine") // Get the MachineInfo machineInfo, err := m.GetMachineInfo() if err != nil { return err } out, err := json.Marshal(machineInfo) if err != nil { fmt.Fprintf(w, "Failed to marshall MachineInfo with error: %s", err) } w.Write(out) case requestType == ContainersApi: // The container name is the path after the requestType containerName := requestArgs log.Printf("Api - Container(%s)", containerName) var query info.ContainerInfoRequest // If a user does not specify number of stats/samples he wants, // it's 64 by default query.NumStats = 64 query.NumSamples = 64 decoder := json.NewDecoder(r.Body) err := decoder.Decode(&query) if err != nil && err != io.EOF { return fmt.Errorf("unable to decode the json value: ", err) } // Get the container. cont, err := m.GetContainerInfo(containerName, &query) if err != nil { fmt.Fprintf(w, "Failed to get container \"%s\" with error: %s", containerName, err) return err } // Only output the container as JSON. out, err := json.Marshal(cont) if err != nil { fmt.Fprintf(w, "Failed to marshall container %q with error: %s", containerName, err) } w.Write(out) default: return fmt.Errorf("unknown API request type %q", requestType) } log.Printf("Request took %s", time.Since(start)) return nil }