in daemon/images.go [38:149]
func (daemon *Daemon) Images(filterArgs, filter string, all bool) ([]*types.Image, error) {
var (
allImages map[image.ID]*image.Image
err error
danglingOnly = false
)
imageFilters, err := filters.FromParam(filterArgs)
if err != nil {
return nil, err
}
if err := imageFilters.Validate(acceptedImageFilterTags); err != nil {
return nil, err
}
if imageFilters.Include("dangling") {
if imageFilters.ExactMatch("dangling", "true") {
danglingOnly = true
} else if !imageFilters.ExactMatch("dangling", "false") {
return nil, fmt.Errorf("Invalid filter 'dangling=%s'", imageFilters.Get("dangling"))
}
}
if danglingOnly {
allImages = daemon.imageStore.Heads()
} else {
allImages = daemon.imageStore.Map()
}
images := []*types.Image{}
var filterTagged bool
if filter != "" {
filterRef, err := reference.ParseNamed(filter)
if err == nil { // parse error means wildcard repo
if _, ok := filterRef.(reference.NamedTagged); ok {
filterTagged = true
}
}
}
for id, img := range allImages {
if imageFilters.Include("label") {
// Very old image that do not have image.Config (or even labels)
if img.Config == nil {
continue
}
// We are now sure image.Config is not nil
if !imageFilters.MatchKVList("label", img.Config.Labels) {
continue
}
}
layerID := img.RootFS.ChainID()
var size int64
if layerID != "" {
l, err := daemon.layerStore.Get(layerID)
if err != nil {
return nil, err
}
size, err = l.Size()
layer.ReleaseAndLog(daemon.layerStore, l)
if err != nil {
return nil, err
}
}
newImage := newImage(img, size)
for _, ref := range daemon.referenceStore.References(id) {
if filter != "" { // filter by tag/repo name
if filterTagged { // filter by tag, require full ref match
if ref.String() != filter {
continue
}
} else if matched, err := path.Match(filter, ref.Name()); !matched || err != nil { // name only match, FIXME: docs say exact
continue
}
}
if _, ok := ref.(reference.Canonical); ok {
newImage.RepoDigests = append(newImage.RepoDigests, ref.String())
}
if _, ok := ref.(reference.NamedTagged); ok {
newImage.RepoTags = append(newImage.RepoTags, ref.String())
}
}
if newImage.RepoDigests == nil && newImage.RepoTags == nil {
if all || len(daemon.imageStore.Children(id)) == 0 {
if imageFilters.Include("dangling") && !danglingOnly {
//dangling=false case, so dangling image is not needed
continue
}
if filter != "" { // skip images with no references if filtering by tag
continue
}
newImage.RepoDigests = []string{"<none>@<none>"}
newImage.RepoTags = []string{"<none>:<none>"}
} else {
continue
}
} else if danglingOnly {
continue
}
images = append(images, newImage)
}
sort.Sort(sort.Reverse(byCreated(images)))
return images, nil
}