func (self *version1_2) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error { switch requestType { case dockerApi: glog.V(4).Infof("Api - Docker(%v)", request) // Get the query request. query, err := getContainerInfoRequest(r.Body) if err != nil { return err } var containers map[string]info.ContainerInfo // map requests for "docker/" to "docker" if len(request) == 1 && len(request[0]) == 0 { request = request[:0] } switch len(request) { case 0: // Get all Docker containers. containers, err = m.AllDockerContainers(query) if err != nil { return fmt.Errorf("failed to get all Docker containers with error: %v", err) } case 1: // Get one Docker container. var cont info.ContainerInfo cont, err = m.DockerContainer(request[0], query) if err != nil { return fmt.Errorf("failed to get Docker container %q with error: %v", request[0], err) } containers = map[string]info.ContainerInfo{ cont.Name: cont, } default: return fmt.Errorf("unknown request for Docker container %v", request) } // Only output the containers as JSON. err = writeResult(containers, w) if err != nil { return err } return nil default: return self.baseVersion.HandleRequest(requestType, request, m, w, r) } }
func serveDockerPage(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(DockerPage):] rootDir := getRootDir(u.Path) var data *pageData if containerName == "" { // Get the containers. reqParams := info.ContainerInfoRequest{ NumStats: 0, } conts, err := m.AllDockerContainers(&reqParams) if err != nil { return fmt.Errorf("failed to get container %q with error: %v", containerName, err) } subcontainers := make([]link, 0, len(conts)) for _, cont := range conts { subcontainers = append(subcontainers, link{ Text: getContainerDisplayName(cont.ContainerReference), Link: path.Join("/docker", docker.ContainerNameToDockerId(cont.ContainerReference.Name)), }) } // Get Docker status status, err := m.DockerInfo() if err != nil { return err } dockerStatus, driverStatus := toStatusKV(status) // Get Docker Images images, err := m.DockerImages() if err != nil { return err } dockerContainersText := "Docker Containers" data = &pageData{ DisplayName: dockerContainersText, ParentContainers: []link{ { Text: dockerContainersText, Link: DockerPage, }}, Subcontainers: subcontainers, Root: rootDir, DockerStatus: dockerStatus, DockerDriverStatus: driverStatus, DockerImages: images, } } else { // Get the container. reqParams := info.ContainerInfoRequest{ NumStats: 60, } cont, err := m.DockerContainer(containerName, &reqParams) if err != nil { return fmt.Errorf("failed to get container %q with error: %v", containerName, err) } displayName := getContainerDisplayName(cont.ContainerReference) // Make a list of the parent containers and their links var parentContainers []link parentContainers = append(parentContainers, link{ Text: "Docker containers", Link: DockerPage, }) parentContainers = append(parentContainers, link{ Text: displayName, Link: path.Join(DockerPage, docker.ContainerNameToDockerId(cont.Name)), }) // Get the MachineInfo machineInfo, err := m.GetMachineInfo() if err != nil { return err } data = &pageData{ DisplayName: displayName, ContainerName: cont.Name, ParentContainers: parentContainers, Spec: cont.Spec, Stats: cont.Stats, MachineInfo: machineInfo, ResourcesAvailable: cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork, CpuAvailable: cont.Spec.HasCpu, MemoryAvailable: cont.Spec.HasMemory, NetworkAvailable: cont.Spec.HasNetwork, FsAvailable: cont.Spec.HasFilesystem, Root: rootDir, } } err := pageTemplate.Execute(w, data) if err != nil { glog.Errorf("Failed to apply template: %s", err) } glog.V(5).Infof("Request took %s", time.Since(start)) return nil }
func handleRequest(m manager.Manager, w http.ResponseWriter, r *http.Request) error { start := time.Now() defer glog.V(2).Infof("Request took %s", time.Since(start)) 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) } containerName = strings.TrimLeft(containerName, "/") glog.V(2).Infof("Api - Docker(%s)", containerName) // Get the query request. query, err := getContainerInfoRequest(r.Body) if err != nil { return err } var containers map[string]info.ContainerInfo if containerName == "" { // Get all Docker containers. containers, err = m.AllDockerContainers(query) if err != nil { return fmt.Errorf("failed to get all Docker containers with error: %v", err) } } else { // Get one Docker container. var cont info.ContainerInfo cont, err = m.DockerContainer(containerName, query) if err != nil { return fmt.Errorf("failed to get Docker container %q with error: %v", containerName, err) } containers = map[string]info.ContainerInfo{ cont.Name: cont, } } // 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) } return nil }