summaryrefslogtreecommitdiff
path: root/libpod/runtime_img.go
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2018-02-19 08:40:43 -0600
committerAtomic Bot <atomic-devel@projectatomic.io>2018-02-20 21:54:32 +0000
commit4929e37507b530cb1d0e92cfcd252b0abefb4f2f (patch)
treeafb9e0ea7fb8e8ed09b77630bbb19260c3545188 /libpod/runtime_img.go
parentdf7bf04dc629686fc6741d0231bd28247fc47ee8 (diff)
downloadpodman-4929e37507b530cb1d0e92cfcd252b0abefb4f2f.tar.gz
podman-4929e37507b530cb1d0e92cfcd252b0abefb4f2f.tar.bz2
podman-4929e37507b530cb1d0e92cfcd252b0abefb4f2f.zip
Performance enhancement for podman images
Previous code was using slow routines to collect some of the information needed to output images. Specifically size was being calculated instead of using the cached, already known size already available. Also, straight- lined several of the code paths. Overall assessment is that these improvements cut the time for images in half. Signed-off-by: baude <bbaude@redhat.com> Closes: #365 Approved by: mheon
Diffstat (limited to 'libpod/runtime_img.go')
-rw-r--r--libpod/runtime_img.go178
1 files changed, 178 insertions, 0 deletions
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index 76687351d..cc6275494 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -108,6 +108,9 @@ type imageDecomposeStruct struct {
transport string
}
+// ImageResultFilter is a mock function for image filtering
+type ImageResultFilter func(inspect.ImageResult) bool
+
func (k *Image) assembleFqName() string {
return fmt.Sprintf("%s/%s:%s", k.Registry, k.ImageName, k.Tag)
}
@@ -1262,3 +1265,178 @@ func getPolicyContext(ctx *types.SystemContext) (*signature.PolicyContext, error
}
return policyContext, nil
}
+
+// sizer knows its size.
+type sizer interface {
+ Size() (int64, error)
+}
+
+func imageSize(img types.ImageSource) *uint64 {
+ if s, ok := img.(sizer); ok {
+ if sum, err := s.Size(); err == nil {
+ usum := uint64(sum)
+ return &usum
+ }
+ }
+ return nil
+}
+
+func reposToMap(repotags []string) map[string]string {
+ // map format is repo -> tag
+ repos := make(map[string]string)
+ for _, repo := range repotags {
+ var repository, tag string
+ if len(repo) > 0 {
+ li := strings.LastIndex(repo, ":")
+ repository = repo[0:li]
+ tag = repo[li+1:]
+ }
+ repos[repository] = tag
+ }
+ if len(repos) == 0 {
+ repos["<none>"] = "<none"
+ }
+ return repos
+}
+
+// GetImageResults gets the images for podman images and returns them as
+// an array of ImageResults
+func (r *Runtime) GetImageResults() ([]inspect.ImageResult, error) {
+ var results []inspect.ImageResult
+
+ images, err := r.store.Images()
+ if err != nil {
+ return nil, err
+ }
+ for _, image := range images {
+ storeRef, err := is.Transport.ParseStoreReference(r.store, image.ID)
+ if err != nil {
+ return nil, err
+ }
+ systemContext := &types.SystemContext{}
+ img, err := storeRef.NewImageSource(systemContext)
+ if err != nil {
+ return nil, err
+ }
+ ic, err := storeRef.NewImage(&types.SystemContext{})
+ if err != nil {
+ return nil, err
+ }
+ imgInspect, err := ic.Inspect()
+ if err != nil {
+ return nil, err
+ }
+ dangling := false
+ if len(image.Names) == 0 {
+ dangling = true
+ }
+
+ for repo, tag := range reposToMap(image.Names) {
+ results = append(results, inspect.ImageResult{
+ ID: image.ID,
+ Repository: repo,
+ RepoTags: image.Names,
+ Tag: tag,
+ Size: imageSize(img),
+ Digest: image.Digest,
+ Created: image.Created,
+ Labels: imgInspect.Labels,
+ Dangling: dangling,
+ })
+ }
+
+ }
+ return results, nil
+}
+
+// ImageCreatedBefore allows you to filter on images created before
+// the given time.Time
+func ImageCreatedBefore(createTime time.Time) ImageResultFilter {
+ return func(i inspect.ImageResult) bool {
+ if i.Created.Before(createTime) {
+ return true
+ }
+ return false
+ }
+}
+
+// ImageCreatedAfter allows you to filter on images created after
+// the given time.Time
+func ImageCreatedAfter(createTime time.Time) ImageResultFilter {
+ return func(i inspect.ImageResult) bool {
+ if i.Created.After(createTime) {
+ return true
+ }
+ return false
+ }
+}
+
+// ImageDangling allows you to filter images for dangling images
+func ImageDangling() ImageResultFilter {
+ return func(i inspect.ImageResult) bool {
+ if i.Dangling {
+ return true
+ }
+ return false
+ }
+}
+
+// ImageLabel allows you to filter by images labels key and/or value
+func ImageLabel(labelfilter string) ImageResultFilter {
+ // We need to handle both label=key and label=key=value
+ return func(i inspect.ImageResult) bool {
+ var value string
+ splitFilter := strings.Split(labelfilter, "=")
+ key := splitFilter[0]
+ if len(splitFilter) > 1 {
+ value = splitFilter[1]
+ }
+ for labelKey, labelValue := range i.Labels {
+ // handles label=key
+ if key == labelKey && len(strings.TrimSpace(value)) == 0 {
+ return true
+ }
+ //handles label=key=value
+ if key == labelKey && value == labelValue {
+ return true
+ }
+ }
+ return false
+ }
+}
+
+// OutputImageFilter allows you to filter by an a specific image name
+func OutputImageFilter(name string) ImageResultFilter {
+ return func(i inspect.ImageResult) bool {
+ li := strings.LastIndex(name, ":")
+ var repository, tag string
+ if li < 0 {
+ repository = name
+ } else {
+ repository = name[0:li]
+ tag = name[li+1:]
+ }
+ if repository == i.Repository && len(strings.TrimSpace(tag)) == 0 {
+ return true
+ }
+ if repository == i.Repository && tag == i.Tag {
+ return true
+ }
+ return false
+ }
+}
+
+// FilterImages filters images using a set of predefined fitler funcs
+func FilterImages(images []inspect.ImageResult, filters []ImageResultFilter) []inspect.ImageResult {
+ var filteredImages []inspect.ImageResult
+ for _, image := range images {
+ include := true
+ for _, filter := range filters {
+ include = include && filter(image)
+ }
+ if include {
+ filteredImages = append(filteredImages, image)
+ }
+ }
+ return filteredImages
+}