github.com/mheon/docker@v0.11.2-0.20150922122814-44f47903a831/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 // byCreated is a temporary type used to sort a list of images by creation 22 // time. 23 type byCreated []*types.Image 24 25 func (r byCreated) Len() int { return len(r) } 26 func (r byCreated) Swap(i, j int) { r[i], r[j] = r[j], r[i] } 27 func (r byCreated) Less(i, j int) bool { return r[i].Created < r[j].Created } 28 29 // Images returns a filtered list of images. filterArgs is a JSON-encoded set 30 // of filter arguments which will be interpreted by pkg/parsers/filters. 31 // filter is a shell glob string applied to repository names. The argument 32 // named all controls whether all images in the graph are filtered, or just 33 // the heads. 34 func (s *TagStore) Images(filterArgs, filter string, all bool) ([]*types.Image, error) { 35 var ( 36 allImages map[string]*image.Image 37 err error 38 filtTagged = true 39 filtLabel = false 40 ) 41 42 imageFilters, err := filters.FromParam(filterArgs) 43 if err != nil { 44 return nil, err 45 } 46 for name := range imageFilters { 47 if _, ok := acceptedImageFilterTags[name]; !ok { 48 return nil, fmt.Errorf("Invalid filter '%s'", name) 49 } 50 } 51 52 if i, ok := imageFilters["dangling"]; ok { 53 for _, value := range i { 54 if strings.ToLower(value) == "true" { 55 filtTagged = false 56 } 57 } 58 } 59 60 _, filtLabel = imageFilters["label"] 61 62 if all && filtTagged { 63 allImages = s.graph.Map() 64 } else { 65 allImages = s.graph.Heads() 66 } 67 68 lookup := make(map[string]*types.Image) 69 s.Lock() 70 for repoName, repository := range s.Repositories { 71 filterTagName := "" 72 if filter != "" { 73 filterName := filter 74 // Test if the tag was in there, if yes, get the name 75 if strings.Contains(filterName, ":") { 76 filterWithTag := strings.Split(filter, ":") 77 filterName = filterWithTag[0] 78 filterTagName = filterWithTag[1] 79 } 80 if match, _ := path.Match(filterName, repoName); !match { 81 continue 82 } 83 if filterTagName != "" { 84 if _, ok := repository[filterTagName]; !ok { 85 continue 86 } 87 } 88 } 89 for ref, id := range repository { 90 imgRef := utils.ImageReference(repoName, ref) 91 if !strings.Contains(imgRef, filterTagName) { 92 continue 93 } 94 image, err := s.graph.Get(id) 95 if err != nil { 96 logrus.Warnf("couldn't load %s from %s: %s", id, imgRef, err) 97 continue 98 } 99 100 if lImage, exists := lookup[id]; exists { 101 if filtTagged { 102 if utils.DigestReference(ref) { 103 lImage.RepoDigests = append(lImage.RepoDigests, imgRef) 104 } else { // Tag Ref. 105 lImage.RepoTags = append(lImage.RepoTags, imgRef) 106 } 107 } 108 } else { 109 // get the boolean list for if only the untagged images are requested 110 delete(allImages, id) 111 if !imageFilters.MatchKVList("label", image.ContainerConfig.Labels) { 112 continue 113 } 114 if filtTagged { 115 newImage := new(types.Image) 116 newImage.ParentID = image.Parent 117 newImage.ID = image.ID 118 newImage.Created = image.Created.Unix() 119 newImage.Size = image.Size 120 newImage.VirtualSize = s.graph.GetParentsSize(image) + image.Size 121 newImage.Labels = image.ContainerConfig.Labels 122 123 if utils.DigestReference(ref) { 124 newImage.RepoTags = []string{} 125 newImage.RepoDigests = []string{imgRef} 126 } else { 127 newImage.RepoTags = []string{imgRef} 128 newImage.RepoDigests = []string{} 129 } 130 131 lookup[id] = newImage 132 } 133 } 134 135 } 136 } 137 s.Unlock() 138 139 images := []*types.Image{} 140 for _, value := range lookup { 141 images = append(images, value) 142 } 143 144 // Display images which aren't part of a repository/tag 145 if filter == "" || filtLabel { 146 for _, image := range allImages { 147 if !imageFilters.MatchKVList("label", image.ContainerConfig.Labels) { 148 continue 149 } 150 newImage := new(types.Image) 151 newImage.ParentID = image.Parent 152 newImage.RepoTags = []string{"<none>:<none>"} 153 newImage.RepoDigests = []string{"<none>@<none>"} 154 newImage.ID = image.ID 155 newImage.Created = image.Created.Unix() 156 newImage.Size = image.Size 157 newImage.VirtualSize = s.graph.GetParentsSize(image) + image.Size 158 newImage.Labels = image.ContainerConfig.Labels 159 160 images = append(images, newImage) 161 } 162 } 163 164 sort.Sort(sort.Reverse(byCreated(images))) 165 166 return images, nil 167 }