mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
d942c59b69
When we use the engine/env object we can run into a situation where a string is passed in as the value but later on when we json serialize the name/value pairs, because the string is made up of just numbers it appears as an integer and not a string - meaning no quotes. This can cause parsing issues for clients. I tried to find all spots where we call env.Set() and the type of the name being set might end up having a value that could look like an int (like author). In those cases I switched it to use env.SetJson() instead because that will wrap it in quotes. One interesting thing to note about the testcase that I modified is that the escaped quotes should have been there all along and we were incorrectly letting it thru. If you look at the metadata stored for that resource you can see the quotes were escaped and we lost them during the serialization steps because of the env.Set() stuff. The use of env is probably not the best way to do all of this. Closes: #9602 Signed-off-by: Doug Davis <dug@us.ibm.com>
103 lines
2.5 KiB
Go
103 lines
2.5 KiB
Go
package graph
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/docker/docker/engine"
|
|
"github.com/docker/docker/image"
|
|
"github.com/docker/docker/pkg/parsers/filters"
|
|
)
|
|
|
|
func (s *TagStore) CmdImages(job *engine.Job) engine.Status {
|
|
var (
|
|
allImages map[string]*image.Image
|
|
err error
|
|
filt_tagged = true
|
|
)
|
|
|
|
imageFilters, err := filters.FromParam(job.Getenv("filters"))
|
|
if err != nil {
|
|
return job.Error(err)
|
|
}
|
|
if i, ok := imageFilters["dangling"]; ok {
|
|
for _, value := range i {
|
|
if strings.ToLower(value) == "true" {
|
|
filt_tagged = false
|
|
}
|
|
}
|
|
}
|
|
|
|
if job.GetenvBool("all") && filt_tagged {
|
|
allImages, err = s.graph.Map()
|
|
} else {
|
|
allImages, err = s.graph.Heads()
|
|
}
|
|
if err != nil {
|
|
return job.Error(err)
|
|
}
|
|
lookup := make(map[string]*engine.Env)
|
|
s.Lock()
|
|
for name, repository := range s.Repositories {
|
|
if job.Getenv("filter") != "" {
|
|
if match, _ := path.Match(job.Getenv("filter"), name); !match {
|
|
continue
|
|
}
|
|
}
|
|
for tag, id := range repository {
|
|
image, err := s.graph.Get(id)
|
|
if err != nil {
|
|
log.Printf("Warning: couldn't load %s from %s/%s: %s", id, name, tag, err)
|
|
continue
|
|
}
|
|
|
|
if out, exists := lookup[id]; exists {
|
|
if filt_tagged {
|
|
out.SetList("RepoTags", append(out.GetList("RepoTags"), fmt.Sprintf("%s:%s", name, tag)))
|
|
}
|
|
} else {
|
|
// get the boolean list for if only the untagged images are requested
|
|
delete(allImages, id)
|
|
if filt_tagged {
|
|
out := &engine.Env{}
|
|
out.SetJson("ParentId", image.Parent)
|
|
out.SetList("RepoTags", []string{fmt.Sprintf("%s:%s", name, tag)})
|
|
out.SetJson("Id", image.ID)
|
|
out.SetInt64("Created", image.Created.Unix())
|
|
out.SetInt64("Size", image.Size)
|
|
out.SetInt64("VirtualSize", image.GetParentsSize(0)+image.Size)
|
|
lookup[id] = out
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
s.Unlock()
|
|
|
|
outs := engine.NewTable("Created", len(lookup))
|
|
for _, value := range lookup {
|
|
outs.Add(value)
|
|
}
|
|
|
|
// Display images which aren't part of a repository/tag
|
|
if job.Getenv("filter") == "" {
|
|
for _, image := range allImages {
|
|
out := &engine.Env{}
|
|
out.SetJson("ParentId", image.Parent)
|
|
out.SetList("RepoTags", []string{"<none>:<none>"})
|
|
out.SetJson("Id", image.ID)
|
|
out.SetInt64("Created", image.Created.Unix())
|
|
out.SetInt64("Size", image.Size)
|
|
out.SetInt64("VirtualSize", image.GetParentsSize(0)+image.Size)
|
|
outs.Add(out)
|
|
}
|
|
}
|
|
|
|
outs.ReverseSort()
|
|
if _, err := outs.WriteListTo(job.Stdout); err != nil {
|
|
return job.Error(err)
|
|
}
|
|
return engine.StatusOK
|
|
}
|