// Use the Portlayer's support for docker ps to get the container count // return order: running, paused, stopped counts func (s *SystemProxy) ContainerCount() (int, int, int, error) { defer trace.End(trace.Begin("ContainerCount")) var running, paused, stopped int plClient := PortLayerClient() if plClient == nil { return 0, 0, 0, derr.NewErrorWithStatusCode(fmt.Errorf("ContainerCount failed to create a portlayer client"), http.StatusInternalServerError) } all := true containList, err := plClient.Containers.GetContainerList(containers.NewGetContainerListParamsWithContext(ctx).WithAll(&all)) if err != nil { return 0, 0, 0, derr.NewErrorWithStatusCode(fmt.Errorf("Failed to get container list: %s", err), http.StatusInternalServerError) } for _, t := range containList.Payload { if *t.ContainerConfig.State == "Running" { running++ } else if *t.ContainerConfig.State == "Stopped" || *t.ContainerConfig.State == "Created" { stopped++ } } return running, paused, stopped, nil }
// syncContainerCache runs once at startup to populate the container cache func syncContainerCache() error { log.Debugf("Updating container cache") backend := NewContainerBackend() client := backend.containerProxy.Client() reqParams := containers.NewGetContainerListParamsWithContext(ctx).WithAll(swag.Bool(true)) containme, err := client.Containers.GetContainerList(reqParams) if err != nil { return errors.Errorf("Failed to retrieve container list from portlayer: %s", err) } log.Debugf("Found %d containers", len(containme.Payload)) cc := cache.ContainerCache() var errs []string for _, info := range containme.Payload { container := ContainerInfoToVicContainer(*info) cc.AddContainer(container) if err = setPortMapping(info, backend, container); err != nil { errs = append(errs, err.Error()) } } if len(errs) > 0 { return errors.Errorf("Failed to set port mapping: %s", strings.Join(errs, "\n")) } return nil }
// Containers returns the list of containers to show given the user's filtering. func (c *Container) Containers(config *types.ContainerListOptions) ([]*types.Container, error) { // Get an API client to the portlayer client := c.containerProxy.Client() containme, err := client.Containers.GetContainerList(containers.NewGetContainerListParamsWithContext(ctx).WithAll(&config.All)) if err != nil { switch err := err.(type) { case *containers.GetContainerListInternalServerError: return nil, fmt.Errorf("Error invoking GetContainerList: %s", err.Payload.Message) default: return nil, fmt.Errorf("Error invoking GetContainerList: %s", err.Error()) } } // TODO: move to conversion function containers := make([]*types.Container, 0, len(containme.Payload)) for _, t := range containme.Payload { cmd := strings.Join(t.ProcessConfig.ExecArgs, " ") // the docker client expects the friendly name to be prefixed // with a forward slash -- create a new slice and add here names := make([]string, 0, len(t.ContainerConfig.Names)) for i := range t.ContainerConfig.Names { names = append(names, clientFriendlyContainerName(t.ContainerConfig.Names[i])) } var started time.Time var stopped time.Time if t.ProcessConfig.StartTime != nil && *t.ProcessConfig.StartTime > 0 { started = time.Unix(*t.ProcessConfig.StartTime, 0) } if t.ProcessConfig.StopTime != nil && *t.ProcessConfig.StopTime > 0 { stopped = time.Unix(*t.ProcessConfig.StopTime, 0) } // get the docker friendly status _, status := dockerStatus(int(*t.ProcessConfig.ExitCode), *t.ProcessConfig.Status, *t.ContainerConfig.State, started, stopped) ips, err := externalIPv4Addrs() var ports []types.Port if err != nil { log.Errorf("Could not get IP information for reporting port bindings.") } else { ports = portInformation(t, ips) } // verify that the repo:tag exists for the container -- if it doesn't then we should present the // truncated imageID -- if we have a failure determining then we'll show the data we have repo := *t.ContainerConfig.RepoName ref, _ := reference.ParseNamed(*t.ContainerConfig.RepoName) if ref != nil { imageID, err := cache.RepositoryCache().Get(ref) if err != nil && err == cache.ErrDoesNotExist { // the tag has been removed, so we need to show the truncated imageID imageID = cache.RepositoryCache().GetImageID(*t.ContainerConfig.LayerID) if imageID != "" { id := uid.Parse(imageID) repo = id.Truncate().String() } } } c := &types.Container{ ID: *t.ContainerConfig.ContainerID, Image: repo, Created: *t.ContainerConfig.CreateTime, Status: status, Names: names, Command: cmd, SizeRw: *t.ContainerConfig.StorageSize, Ports: ports, } containers = append(containers, c) } // sort on creation time sort.Sort(sort.Reverse(containerByCreated(containers))) return containers, nil }