github.com/willmtemple/docker@v1.7.0-rc2/graph/list.go (about)

     1  package graph
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"path"
     7  	"sort"
     8  	"strings"
     9  
    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, err = s.graph.Map()
    63  	} else {
    64  		allImages, err = s.graph.Heads()
    65  	}
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	lookup := make(map[string]*types.Image)
    71  	s.Lock()
    72  	for repoName, repository := range s.Repositories {
    73  		if config.Filter != "" {
    74  			if match, _ := path.Match(config.Filter, repoName); !match {
    75  				continue
    76  			}
    77  		}
    78  		for ref, id := range repository {
    79  			imgRef := utils.ImageReference(repoName, ref)
    80  			image, err := s.graph.Get(id)
    81  			if err != nil {
    82  				log.Printf("Warning: couldn't load %s from %s: %s", id, imgRef, err)
    83  				continue
    84  			}
    85  
    86  			if lImage, exists := lookup[id]; exists {
    87  				if filtTagged {
    88  					if utils.DigestReference(ref) {
    89  						lImage.RepoDigests = append(lImage.RepoDigests, imgRef)
    90  					} else { // Tag Ref.
    91  						lImage.RepoTags = append(lImage.RepoTags, imgRef)
    92  					}
    93  				}
    94  			} else {
    95  				// get the boolean list for if only the untagged images are requested
    96  				delete(allImages, id)
    97  				if !imageFilters.MatchKVList("label", image.ContainerConfig.Labels) {
    98  					continue
    99  				}
   100  				if filtTagged {
   101  					newImage := new(types.Image)
   102  					newImage.ParentId = image.Parent
   103  					newImage.ID = image.ID
   104  					newImage.Created = int(image.Created.Unix())
   105  					newImage.Size = int(image.Size)
   106  					newImage.VirtualSize = int(image.GetParentsSize(0) + image.Size)
   107  					newImage.Labels = image.ContainerConfig.Labels
   108  
   109  					if utils.DigestReference(ref) {
   110  						newImage.RepoTags = []string{}
   111  						newImage.RepoDigests = []string{imgRef}
   112  					} else {
   113  						newImage.RepoTags = []string{imgRef}
   114  						newImage.RepoDigests = []string{}
   115  					}
   116  
   117  					lookup[id] = newImage
   118  				}
   119  			}
   120  
   121  		}
   122  	}
   123  	s.Unlock()
   124  
   125  	images := []*types.Image{}
   126  	for _, value := range lookup {
   127  		images = append(images, value)
   128  	}
   129  
   130  	// Display images which aren't part of a repository/tag
   131  	if config.Filter == "" || filtLabel {
   132  		for _, image := range allImages {
   133  			if !imageFilters.MatchKVList("label", image.ContainerConfig.Labels) {
   134  				continue
   135  			}
   136  			newImage := new(types.Image)
   137  			newImage.ParentId = image.Parent
   138  			newImage.RepoTags = []string{"<none>:<none>"}
   139  			newImage.RepoDigests = []string{"<none>@<none>"}
   140  			newImage.ID = image.ID
   141  			newImage.Created = int(image.Created.Unix())
   142  			newImage.Size = int(image.Size)
   143  			newImage.VirtualSize = int(image.GetParentsSize(0) + image.Size)
   144  			newImage.Labels = image.ContainerConfig.Labels
   145  
   146  			images = append(images, newImage)
   147  		}
   148  	}
   149  
   150  	sort.Sort(sort.Reverse(ByCreated(images)))
   151  
   152  	return images, nil
   153  }