github.com/darciopacifico/docker@v1.9.0-rc1/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 112 if len(imageFilters["label"]) > 0 { 113 if image.Config == nil { 114 // Very old image that do not have image.Config (or even labels) 115 continue 116 } 117 // We are now sure image.Config is not nil 118 if !imageFilters.MatchKVList("label", image.Config.Labels) { 119 continue 120 } 121 } 122 if filtTagged { 123 newImage := newImage(image, s.graph.GetParentsSize(image)) 124 125 if utils.DigestReference(ref) { 126 newImage.RepoTags = []string{} 127 newImage.RepoDigests = []string{imgRef} 128 } else { 129 newImage.RepoTags = []string{imgRef} 130 newImage.RepoDigests = []string{} 131 } 132 133 lookup[id] = newImage 134 } 135 } 136 137 } 138 } 139 s.Unlock() 140 141 images := []*types.Image{} 142 for _, value := range lookup { 143 images = append(images, value) 144 } 145 146 // Display images which aren't part of a repository/tag 147 if filter == "" || filtLabel { 148 for _, image := range allImages { 149 if len(imageFilters["label"]) > 0 { 150 if image.Config == nil { 151 // Very old image that do not have image.Config (or even labels) 152 continue 153 } 154 // We are now sure image.Config is not nil 155 if !imageFilters.MatchKVList("label", image.Config.Labels) { 156 continue 157 } 158 } 159 newImage := newImage(image, s.graph.GetParentsSize(image)) 160 newImage.RepoTags = []string{"<none>:<none>"} 161 newImage.RepoDigests = []string{"<none>@<none>"} 162 163 images = append(images, newImage) 164 } 165 } 166 167 sort.Sort(sort.Reverse(byCreated(images))) 168 169 return images, nil 170 } 171 172 func newImage(image *image.Image, parentSize int64) *types.Image { 173 newImage := new(types.Image) 174 newImage.ParentID = image.Parent 175 newImage.ID = image.ID 176 newImage.Created = image.Created.Unix() 177 newImage.Size = image.Size 178 newImage.VirtualSize = parentSize + image.Size 179 if image.Config != nil { 180 newImage.Labels = image.Config.Labels 181 } 182 return newImage 183 }