// ListPodSandbox returns a list of Sandbox. func (ds *dockerService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter) ([]*runtimeApi.PodSandbox, error) { // By default, list all containers whether they are running or not. opts := dockertypes.ContainerListOptions{All: true} filterOutReadySandboxes := false opts.Filter = dockerfilters.NewArgs() f := newDockerFilter(&opts.Filter) // Add filter to select only sandbox containers. f.AddLabel(containerTypeLabelKey, containerTypeLabelSandbox) if filter != nil { if filter.Id != nil { f.Add("id", filter.GetId()) } if filter.State != nil { if filter.GetState() == runtimeApi.PodSandBoxState_READY { // Only list running containers. opts.All = false } else { // runtimeApi.PodSandBoxState_NOTREADY can mean the // container is in any of the non-running state (e.g., created, // exited). We can't tell docker to filter out running // containers directly, so we'll need to filter them out // ourselves after getting the results. filterOutReadySandboxes = true } } if filter.LabelSelector != nil { for k, v := range filter.LabelSelector { f.AddLabel(k, v) } } } containers, err := ds.client.ListContainers(opts) if err != nil { return nil, err } // Convert docker containers to runtime api sandboxes. result := []*runtimeApi.PodSandbox{} for i := range containers { c := containers[i] converted, err := toRuntimeAPISandbox(&c) if err != nil { glog.V(5).Infof("Unable to convert docker to runtime API sandbox: %v", err) continue } if filterOutReadySandboxes && converted.GetState() == runtimeApi.PodSandBoxState_READY { continue } result = append(result, converted) } return result, nil }
// foldFilter generates the container filter based on the user's filtering options. func (daemon *Daemon) foldFilter(config *types.ContainerListOptions) (*listContext, error) { psFilters := config.Filter var filtExited []int err := psFilters.WalkValues("exited", func(value string) error { code, err := strconv.Atoi(value) if err != nil { return err } filtExited = append(filtExited, code) return nil }) if err != nil { return nil, err } err = psFilters.WalkValues("status", func(value string) error { if !container.IsValidStateString(value) { return fmt.Errorf("Unrecognised filter value for status: %s", value) } config.All = true return nil }) if err != nil { return nil, err } var beforeContFilter, sinceContFilter *container.Container err = psFilters.WalkValues("before", func(value string) error { beforeContFilter, err = daemon.GetContainer(value) return err }) if err != nil { return nil, err } err = psFilters.WalkValues("since", func(value string) error { sinceContFilter, err = daemon.GetContainer(value) return err }) if err != nil { return nil, err } imagesFilter := map[image.ID]bool{} var ancestorFilter bool if psFilters.Include("ancestor") { ancestorFilter = true psFilters.WalkValues("ancestor", func(ancestor string) error { id, err := daemon.GetImageID(ancestor) if err != nil { logrus.Warnf("Error while looking up for image %v", ancestor) return nil } if imagesFilter[id] { // Already seen this ancestor, skip it return nil } // Then walk down the graph and put the imageIds in imagesFilter populateImageFilterByParents(imagesFilter, id, daemon.imageStore.Children) return nil }) } if config.Before != "" && beforeContFilter == nil { beforeContFilter, err = daemon.GetContainer(config.Before) if err != nil { return nil, err } } if config.Since != "" && sinceContFilter == nil { sinceContFilter, err = daemon.GetContainer(config.Since) if err != nil { return nil, err } } return &listContext{ filters: psFilters, ancestorFilter: ancestorFilter, images: imagesFilter, exitAllowed: filtExited, beforeFilter: beforeContFilter, sinceFilter: sinceContFilter, ContainerListOptions: config, names: daemon.nameIndex.GetAll(), }, nil }