func (s *TagStore) Images(config *ImagesConfig) ([]*types.Image, error) { var ( allImages map[string]*image.Image err error filtTagged = true filtLabel = false ) imageFilters, err := filters.FromParam(config.Filters) if err != nil { return nil, err } for name := range imageFilters { if _, ok := acceptedImageFilterTags[name]; !ok { return nil, fmt.Errorf("Invalid filter '%s'", name) } } if i, ok := imageFilters["dangling"]; ok { for _, value := range i { if strings.ToLower(value) == "true" { filtTagged = false } } } _, filtLabel = imageFilters["label"] if config.All && filtTagged { allImages, err = s.graph.Map() } else { allImages, err = s.graph.Heads() } if err != nil { return nil, err } lookup := make(map[string]*types.Image) s.Lock() for repoName, repository := range s.Repositories { if config.Filter != "" { if match, _ := path.Match(config.Filter, repoName); !match { continue } } for ref, id := range repository { imgRef := utils.ImageReference(repoName, ref) image, err := s.graph.Get(id) if err != nil { log.Printf("Warning: couldn't load %s from %s: %s", id, imgRef, err) continue } if lImage, exists := lookup[id]; exists { if filtTagged { if utils.DigestReference(ref) { lImage.RepoDigests = append(lImage.RepoDigests, imgRef) } else { // Tag Ref. lImage.RepoTags = append(lImage.RepoTags, imgRef) } } } else { // get the boolean list for if only the untagged images are requested delete(allImages, id) if !imageFilters.MatchKVList("label", image.ContainerConfig.Labels) { continue } if filtTagged { newImage := new(types.Image) newImage.ParentId = image.Parent newImage.ID = image.ID newImage.Created = int(image.Created.Unix()) newImage.Size = int(image.Size) newImage.VirtualSize = int(image.GetParentsSize(0) + image.Size) newImage.Labels = image.ContainerConfig.Labels if utils.DigestReference(ref) { newImage.RepoTags = []string{} newImage.RepoDigests = []string{imgRef} } else { newImage.RepoTags = []string{imgRef} newImage.RepoDigests = []string{} } lookup[id] = newImage } } } } s.Unlock() images := []*types.Image{} for _, value := range lookup { images = append(images, value) } // Display images which aren't part of a repository/tag if config.Filter == "" || filtLabel { for _, image := range allImages { if !imageFilters.MatchKVList("label", image.ContainerConfig.Labels) { continue } newImage := new(types.Image) newImage.ParentId = image.Parent newImage.RepoTags = []string{"<none>:<none>"} newImage.RepoDigests = []string{"<none>@<none>"} newImage.ID = image.ID newImage.Created = int(image.Created.Unix()) newImage.Size = int(image.Size) newImage.VirtualSize = int(image.GetParentsSize(0) + image.Size) newImage.Labels = image.ContainerConfig.Labels images = append(images, newImage) } } sort.Sort(sort.Reverse(ByCreated(images))) return images, nil }
func (daemon *Daemon) Containers(config *ContainersConfig) ([]*types.Container, error) { var ( foundBefore bool displayed int all = config.All n = config.Limit psFilters filters.Args filtExited []int ) containers := []*types.Container{} psFilters, err := filters.FromParam(config.Filters) if err != nil { return nil, err } if i, ok := psFilters["exited"]; ok { for _, value := range i { code, err := strconv.Atoi(value) if err != nil { return nil, err } filtExited = append(filtExited, code) } } if i, ok := psFilters["status"]; ok { for _, value := range i { if value == "exited" || value == "created" { all = true } } } names := map[string][]string{} daemon.ContainerGraph().Walk("/", func(p string, e *graphdb.Entity) error { names[e.ID()] = append(names[e.ID()], p) return nil }, 1) var beforeCont, sinceCont *Container if config.Before != "" { beforeCont, err = daemon.Get(config.Before) if err != nil { return nil, err } } if config.Since != "" { sinceCont, err = daemon.Get(config.Since) if err != nil { return nil, err } } errLast := errors.New("last container") writeCont := func(container *Container) error { container.Lock() defer container.Unlock() if !container.Running && !all && n <= 0 && config.Since == "" && config.Before == "" { return nil } if !psFilters.Match("name", container.Name) { return nil } if !psFilters.Match("id", container.ID) { return nil } if !psFilters.MatchKVList("label", container.Config.Labels) { return nil } if config.Before != "" && !foundBefore { if container.ID == beforeCont.ID { foundBefore = true } return nil } if n > 0 && displayed == n { return errLast } if config.Since != "" { if container.ID == sinceCont.ID { return errLast } } if len(filtExited) > 0 { shouldSkip := true for _, code := range filtExited { if code == container.ExitCode && !container.Running { shouldSkip = false break } } if shouldSkip { return nil } } if !psFilters.Match("status", container.State.StateString()) { return nil } displayed++ newC := &types.Container{ ID: container.ID, Names: names[container.ID], } newC.Image = container.Config.Image if len(container.Args) > 0 { args := []string{} for _, arg := range container.Args { if strings.Contains(arg, " ") { args = append(args, fmt.Sprintf("'%s'", arg)) } else { args = append(args, arg) } } argsAsString := strings.Join(args, " ") newC.Command = fmt.Sprintf("%s %s", container.Path, argsAsString) } else { newC.Command = fmt.Sprintf("%s", container.Path) } newC.Created = int(container.Created.Unix()) newC.Status = container.State.String() newC.Ports = []types.Port{} for port, bindings := range container.NetworkSettings.Ports { p, _ := nat.ParsePort(port.Port()) if len(bindings) == 0 { newC.Ports = append(newC.Ports, types.Port{ PrivatePort: p, Type: port.Proto(), }) continue } for _, binding := range bindings { h, _ := nat.ParsePort(binding.HostPort) newC.Ports = append(newC.Ports, types.Port{ PrivatePort: p, PublicPort: h, Type: port.Proto(), IP: binding.HostIp, }) } } if config.Size { sizeRw, sizeRootFs := container.GetSize() newC.SizeRw = int(sizeRw) newC.SizeRootFs = int(sizeRootFs) } newC.Labels = container.Config.Labels containers = append(containers, newC) return nil } for _, container := range daemon.List() { if err := writeCont(container); err != nil { if err != errLast { return nil, err } break } } return containers, nil }