github.com/crquan/docker@v1.8.1/graph/list.go (about)

     1  package graph
     2  
     3  import (
     4  	"fmt"
     5  	"path"
     6  	"sort"
     7  	"strings"
     8  
     9  	"github.com/Sirupsen/logrus"
    10  	"github.com/docker/docker/api/types"
    11  	"github.com/docker/docker/image"
    12  	"github.com/docker/docker/pkg/parsers/filters"
    13  	"github.com/docker/docker/utils"
    14  )
    15  
    16  var acceptedImageFilterTags = map[string]struct{}{
    17  	"dangling": {},
    18  	"label":    {},
    19  }
    20  
    21  type ImagesConfig struct {
    22  	Filters string
    23  	Filter  string
    24  	All     bool
    25  }
    26  
    27  type ByCreated []*types.Image
    28  
    29  func (r ByCreated) Len() int           { return len(r) }
    30  func (r ByCreated) Swap(i, j int)      { r[i], r[j] = r[j], r[i] }
    31  func (r ByCreated) Less(i, j int) bool { return r[i].Created < r[j].Created }
    32  
    33  func (s *TagStore) Images(config *ImagesConfig) ([]*types.Image, error) {
    34  	var (
    35  		allImages  map[string]*image.Image
    36  		err        error
    37  		filtTagged = true
    38  		filtLabel  = false
    39  	)
    40  
    41  	imageFilters, err := filters.FromParam(config.Filters)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	for name := range imageFilters {
    46  		if _, ok := acceptedImageFilterTags[name]; !ok {
    47  			return nil, fmt.Errorf("Invalid filter '%s'", name)
    48  		}
    49  	}
    50  
    51  	if i, ok := imageFilters["dangling"]; ok {
    52  		for _, value := range i {
    53  			if strings.ToLower(value) == "true" {
    54  				filtTagged = false
    55  			}
    56  		}
    57  	}
    58  
    59  	_, filtLabel = imageFilters["label"]
    60  
    61  	if config.All && filtTagged {
    62  		allImages = s.graph.Map()
    63  	} else {
    64  		allImages = s.graph.Heads()
    65  	}
    66  
    67  	lookup := make(map[string]*types.Image)
    68  	s.Lock()
    69  	for repoName, repository := range s.Repositories {
    70  		if config.Filter != "" {
    71  			if match, _ := path.Match(config.Filter, repoName); !match {
    72  				continue
    73  			}
    74  		}
    75  		for ref, id := range repository {
    76  			imgRef := utils.ImageReference(repoName, ref)
    77  			image, err := s.graph.Get(id)
    78  			if err != nil {
    79  				logrus.Warnf("couldn't load %s from %s: %s", id, imgRef, err)
    80  				continue
    81  			}
    82  
    83  			if lImage, exists := lookup[id]; exists {
    84  				if filtTagged {
    85  					if utils.DigestReference(ref) {
    86  						lImage.RepoDigests = append(lImage.RepoDigests, imgRef)
    87  					} else { // Tag Ref.
    88  						lImage.RepoTags = append(lImage.RepoTags, imgRef)
    89  					}
    90  				}
    91  			} else {
    92  				// get the boolean list for if only the untagged images are requested
    93  				delete(allImages, id)
    94  				if !imageFilters.MatchKVList("label", image.ContainerConfig.Labels) {
    95  					continue
    96  				}
    97  				if filtTagged {
    98  					newImage := new(types.Image)
    99  					newImage.ParentId = image.Parent
   100  					newImage.ID = image.ID
   101  					newImage.Created = int(image.Created.Unix())
   102  					newImage.Size = int(image.Size)
   103  					newImage.VirtualSize = int(s.graph.GetParentsSize(image, 0) + image.Size)
   104  					newImage.Labels = image.ContainerConfig.Labels
   105  
   106  					if utils.DigestReference(ref) {
   107  						newImage.RepoTags = []string{}
   108  						newImage.RepoDigests = []string{imgRef}
   109  					} else {
   110  						newImage.RepoTags = []string{imgRef}
   111  						newImage.RepoDigests = []string{}
   112  					}
   113  
   114  					lookup[id] = newImage
   115  				}
   116  			}
   117  
   118  		}
   119  	}
   120  	s.Unlock()
   121  
   122  	images := []*types.Image{}
   123  	for _, value := range lookup {
   124  		images = append(images, value)
   125  	}
   126  
   127  	// Display images which aren't part of a repository/tag
   128  	if config.Filter == "" || filtLabel {
   129  		for _, image := range allImages {
   130  			if !imageFilters.MatchKVList("label", image.ContainerConfig.Labels) {
   131  				continue
   132  			}
   133  			newImage := new(types.Image)
   134  			newImage.ParentId = image.Parent
   135  			newImage.RepoTags = []string{"<none>:<none>"}
   136  			newImage.RepoDigests = []string{"<none>@<none>"}
   137  			newImage.ID = image.ID
   138  			newImage.Created = int(image.Created.Unix())
   139  			newImage.Size = int(image.Size)
   140  			newImage.VirtualSize = int(s.graph.GetParentsSize(image, 0) + image.Size)
   141  			newImage.Labels = image.ContainerConfig.Labels
   142  
   143  			images = append(images, newImage)
   144  		}
   145  	}
   146  
   147  	sort.Sort(sort.Reverse(ByCreated(images)))
   148  
   149  	return images, nil
   150  }