Merge pull request #12184 from duglin/RemoveJobImages
Remove Job from `docker images`
This commit is contained in:
commit
6ba7bf440e
13 changed files with 112 additions and 468 deletions
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/docker/docker/daemon"
|
||||
"github.com/docker/docker/daemon/networkdriver/bridge"
|
||||
"github.com/docker/docker/engine"
|
||||
"github.com/docker/docker/graph"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/docker/docker/pkg/parsers"
|
||||
"github.com/docker/docker/pkg/parsers/filters"
|
||||
|
@ -253,48 +254,40 @@ func getImagesJSON(eng *engine.Engine, version version.Version, w http.ResponseW
|
|||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
outs *engine.Table
|
||||
job = eng.Job("images")
|
||||
)
|
||||
imagesConfig := graph.ImagesConfig{
|
||||
Filters: r.Form.Get("filters"),
|
||||
// FIXME this parameter could just be a match filter
|
||||
Filter: r.Form.Get("filter"),
|
||||
All: toBool(r.Form.Get("all")),
|
||||
}
|
||||
|
||||
job.Setenv("filters", r.Form.Get("filters"))
|
||||
// FIXME this parameter could just be a match filter
|
||||
job.Setenv("filter", r.Form.Get("filter"))
|
||||
job.Setenv("all", r.Form.Get("all"))
|
||||
images, err := getDaemon(eng).Repositories().Images(&imagesConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if version.GreaterThanOrEqualTo("1.7") {
|
||||
streamJSON(job, w, false)
|
||||
} else if outs, err = job.Stdout.AddListTable(); err != nil {
|
||||
return err
|
||||
return writeJSON(w, http.StatusOK, images)
|
||||
}
|
||||
|
||||
if err := job.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
legacyImages := []types.LegacyImage{}
|
||||
|
||||
if version.LessThan("1.7") && outs != nil { // Convert to legacy format
|
||||
outsLegacy := engine.NewTable("Created", 0)
|
||||
for _, out := range outs.Data {
|
||||
for _, repoTag := range out.GetList("RepoTags") {
|
||||
repo, tag := parsers.ParseRepositoryTag(repoTag)
|
||||
outLegacy := &engine.Env{}
|
||||
outLegacy.Set("Repository", repo)
|
||||
outLegacy.SetJson("Tag", tag)
|
||||
outLegacy.Set("Id", out.Get("Id"))
|
||||
outLegacy.SetInt64("Created", out.GetInt64("Created"))
|
||||
outLegacy.SetInt64("Size", out.GetInt64("Size"))
|
||||
outLegacy.SetInt64("VirtualSize", out.GetInt64("VirtualSize"))
|
||||
outsLegacy.Add(outLegacy)
|
||||
for _, image := range images {
|
||||
for _, repoTag := range image.RepoTags {
|
||||
repo, tag := parsers.ParseRepositoryTag(repoTag)
|
||||
legacyImage := types.LegacyImage{
|
||||
Repository: repo,
|
||||
Tag: tag,
|
||||
ID: image.ID,
|
||||
Created: image.Created,
|
||||
Size: image.Size,
|
||||
VirtualSize: image.VirtualSize,
|
||||
}
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
if _, err := outsLegacy.WriteListTo(w); err != nil {
|
||||
return err
|
||||
legacyImages = append(legacyImages, legacyImage)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
return writeJSON(w, http.StatusOK, legacyImages)
|
||||
}
|
||||
|
||||
func getImagesViz(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
|
@ -477,8 +470,8 @@ func getContainersJSON(eng *engine.Engine, version version.Version, w http.Respo
|
|||
}
|
||||
|
||||
config := &daemon.ContainersConfig{
|
||||
All: r.Form.Get("all") == "1",
|
||||
Size: r.Form.Get("size") == "1",
|
||||
All: toBool(r.Form.Get("all")),
|
||||
Size: toBool(r.Form.Get("size")),
|
||||
Since: r.Form.Get("since"),
|
||||
Before: r.Form.Get("before"),
|
||||
Filters: r.Form.Get("filters"),
|
||||
|
@ -1129,14 +1122,14 @@ func postBuild(eng *engine.Engine, version version.Version, w http.ResponseWrite
|
|||
job.Stdout.Add(utils.NewWriteFlusher(w))
|
||||
}
|
||||
|
||||
if r.FormValue("forcerm") == "1" && version.GreaterThanOrEqualTo("1.12") {
|
||||
if toBool(r.FormValue("forcerm")) && version.GreaterThanOrEqualTo("1.12") {
|
||||
job.Setenv("rm", "1")
|
||||
} else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") {
|
||||
job.Setenv("rm", "1")
|
||||
} else {
|
||||
job.Setenv("rm", r.FormValue("rm"))
|
||||
}
|
||||
if r.FormValue("pull") == "1" && version.GreaterThanOrEqualTo("1.16") {
|
||||
if toBool(r.FormValue("pull")) && version.GreaterThanOrEqualTo("1.16") {
|
||||
job.Setenv("pull", "1")
|
||||
}
|
||||
job.Stdin.Add(r.Body)
|
||||
|
@ -1546,3 +1539,8 @@ func ServeApi(job *engine.Job) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func toBool(s string) bool {
|
||||
s = strings.ToLower(strings.TrimSpace(s))
|
||||
return !(s == "" || s == "0" || s == "no" || s == "false" || s == "none")
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
@ -92,106 +91,6 @@ func TestGetInfo(t *testing.T) {
|
|||
assertContentType(r, "application/json", t)
|
||||
}
|
||||
|
||||
func TestGetImagesJSON(t *testing.T) {
|
||||
eng := engine.New()
|
||||
var called bool
|
||||
eng.Register("images", func(job *engine.Job) error {
|
||||
called = true
|
||||
v := createEnvFromGetImagesJSONStruct(sampleImage)
|
||||
if err := json.NewEncoder(job.Stdout).Encode(v); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
r := serveRequest("GET", "/images/json", nil, eng, t)
|
||||
if !called {
|
||||
t.Fatal("handler was not called")
|
||||
}
|
||||
assertHttpNotError(r, t)
|
||||
assertContentType(r, "application/json", t)
|
||||
var observed getImagesJSONStruct
|
||||
if err := json.Unmarshal(r.Body.Bytes(), &observed); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(observed, sampleImage) {
|
||||
t.Errorf("Expected %#v but got %#v", sampleImage, observed)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetImagesJSONFilter(t *testing.T) {
|
||||
eng := engine.New()
|
||||
filter := "nothing"
|
||||
eng.Register("images", func(job *engine.Job) error {
|
||||
filter = job.Getenv("filter")
|
||||
return nil
|
||||
})
|
||||
serveRequest("GET", "/images/json?filter=aaaa", nil, eng, t)
|
||||
if filter != "aaaa" {
|
||||
t.Errorf("%#v", filter)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetImagesJSONFilters(t *testing.T) {
|
||||
eng := engine.New()
|
||||
filter := "nothing"
|
||||
eng.Register("images", func(job *engine.Job) error {
|
||||
filter = job.Getenv("filters")
|
||||
return nil
|
||||
})
|
||||
serveRequest("GET", "/images/json?filters=nnnn", nil, eng, t)
|
||||
if filter != "nnnn" {
|
||||
t.Errorf("%#v", filter)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetImagesJSONAll(t *testing.T) {
|
||||
eng := engine.New()
|
||||
allFilter := "-1"
|
||||
eng.Register("images", func(job *engine.Job) error {
|
||||
allFilter = job.Getenv("all")
|
||||
return nil
|
||||
})
|
||||
serveRequest("GET", "/images/json?all=1", nil, eng, t)
|
||||
if allFilter != "1" {
|
||||
t.Errorf("%#v", allFilter)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetImagesJSONLegacyFormat(t *testing.T) {
|
||||
eng := engine.New()
|
||||
var called bool
|
||||
eng.Register("images", func(job *engine.Job) error {
|
||||
called = true
|
||||
images := []types.Image{
|
||||
createEnvFromGetImagesJSONStruct(sampleImage),
|
||||
}
|
||||
if err := json.NewEncoder(job.Stdout).Encode(images); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
r := serveRequestUsingVersion("GET", "/images/json", "1.6", nil, eng, t)
|
||||
if !called {
|
||||
t.Fatal("handler was not called")
|
||||
}
|
||||
assertHttpNotError(r, t)
|
||||
assertContentType(r, "application/json", t)
|
||||
images := engine.NewTable("Created", 0)
|
||||
if _, err := images.ReadListFrom(r.Body.Bytes()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if images.Len() != 1 {
|
||||
t.Fatalf("Expected 1 image, %d found", images.Len())
|
||||
}
|
||||
image := images.Data[0]
|
||||
if image.Get("Tag") != "test-tag" {
|
||||
t.Errorf("Expected tag 'test-tag', found '%s'", image.Get("Tag"))
|
||||
}
|
||||
if image.Get("Repository") != "test-name" {
|
||||
t.Errorf("Expected repository 'test-name', found '%s'", image.Get("Repository"))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetContainersByName(t *testing.T) {
|
||||
eng := engine.New()
|
||||
name := "container_name"
|
||||
|
|
|
@ -69,6 +69,15 @@ type Image struct {
|
|||
Labels map[string]string
|
||||
}
|
||||
|
||||
type LegacyImage struct {
|
||||
ID string `json:"Id"`
|
||||
Repository string
|
||||
Tag string
|
||||
Created int
|
||||
Size int
|
||||
VirtualSize int
|
||||
}
|
||||
|
||||
// GET "/containers/json"
|
||||
type Port struct {
|
||||
IP string
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
|
@ -187,39 +186,3 @@ func (o *Output) AddEnv() (dst *Env, err error) {
|
|||
}()
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
func (o *Output) AddListTable() (dst *Table, err error) {
|
||||
src, err := o.AddPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dst = NewTable("", 0)
|
||||
o.tasks.Add(1)
|
||||
go func() {
|
||||
defer o.tasks.Done()
|
||||
content, err := ioutil.ReadAll(src)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if _, err := dst.ReadListFrom(content); err != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
func (o *Output) AddTable() (dst *Table, err error) {
|
||||
src, err := o.AddPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dst = NewTable("", 0)
|
||||
o.tasks.Add(1)
|
||||
go func() {
|
||||
defer o.tasks.Done()
|
||||
if _, err := dst.ReadFrom(src); err != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
return dst, nil
|
||||
}
|
||||
|
|
140
engine/table.go
140
engine/table.go
|
@ -1,140 +0,0 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"sort"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Table struct {
|
||||
Data []*Env
|
||||
sortKey string
|
||||
Chan chan *Env
|
||||
}
|
||||
|
||||
func NewTable(sortKey string, sizeHint int) *Table {
|
||||
return &Table{
|
||||
make([]*Env, 0, sizeHint),
|
||||
sortKey,
|
||||
make(chan *Env),
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Table) SetKey(sortKey string) {
|
||||
t.sortKey = sortKey
|
||||
}
|
||||
|
||||
func (t *Table) Add(env *Env) {
|
||||
t.Data = append(t.Data, env)
|
||||
}
|
||||
|
||||
func (t *Table) Len() int {
|
||||
return len(t.Data)
|
||||
}
|
||||
|
||||
func (t *Table) Less(a, b int) bool {
|
||||
return t.lessBy(a, b, t.sortKey)
|
||||
}
|
||||
|
||||
func (t *Table) lessBy(a, b int, by string) bool {
|
||||
keyA := t.Data[a].Get(by)
|
||||
keyB := t.Data[b].Get(by)
|
||||
intA, errA := strconv.ParseInt(keyA, 10, 64)
|
||||
intB, errB := strconv.ParseInt(keyB, 10, 64)
|
||||
if errA == nil && errB == nil {
|
||||
return intA < intB
|
||||
}
|
||||
return keyA < keyB
|
||||
}
|
||||
|
||||
func (t *Table) Swap(a, b int) {
|
||||
tmp := t.Data[a]
|
||||
t.Data[a] = t.Data[b]
|
||||
t.Data[b] = tmp
|
||||
}
|
||||
|
||||
func (t *Table) Sort() {
|
||||
sort.Sort(t)
|
||||
}
|
||||
|
||||
func (t *Table) ReverseSort() {
|
||||
sort.Sort(sort.Reverse(t))
|
||||
}
|
||||
|
||||
func (t *Table) WriteListTo(dst io.Writer) (n int64, err error) {
|
||||
if _, err := dst.Write([]byte{'['}); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
n = 1
|
||||
for i, env := range t.Data {
|
||||
bytes, err := env.WriteTo(dst)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
n += bytes
|
||||
if i != len(t.Data)-1 {
|
||||
if _, err := dst.Write([]byte{','}); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
n++
|
||||
}
|
||||
}
|
||||
if _, err := dst.Write([]byte{']'}); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return n + 1, nil
|
||||
}
|
||||
|
||||
func (t *Table) ToListString() (string, error) {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
if _, err := t.WriteListTo(buffer); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buffer.String(), nil
|
||||
}
|
||||
|
||||
func (t *Table) WriteTo(dst io.Writer) (n int64, err error) {
|
||||
for _, env := range t.Data {
|
||||
bytes, err := env.WriteTo(dst)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
n += bytes
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (t *Table) ReadListFrom(src []byte) (n int64, err error) {
|
||||
var array []interface{}
|
||||
|
||||
if err := json.Unmarshal(src, &array); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
for _, item := range array {
|
||||
if m, ok := item.(map[string]interface{}); ok {
|
||||
env := &Env{}
|
||||
for key, value := range m {
|
||||
env.SetAuto(key, value)
|
||||
}
|
||||
t.Add(env)
|
||||
}
|
||||
}
|
||||
|
||||
return int64(len(src)), nil
|
||||
}
|
||||
|
||||
func (t *Table) ReadFrom(src io.Reader) (n int64, err error) {
|
||||
decoder := NewDecoder(src)
|
||||
for {
|
||||
env, err := decoder.Decode()
|
||||
if err == io.EOF {
|
||||
return 0, nil
|
||||
} else if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
t.Add(env)
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTableWriteTo(t *testing.T) {
|
||||
table := NewTable("", 0)
|
||||
e := &Env{}
|
||||
e.Set("foo", "bar")
|
||||
table.Add(e)
|
||||
var buf bytes.Buffer
|
||||
if _, err := table.WriteTo(&buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
output := make(map[string]string)
|
||||
if err := json.Unmarshal(buf.Bytes(), &output); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(output) != 1 {
|
||||
t.Fatalf("Incorrect output: %v", output)
|
||||
}
|
||||
if val, exists := output["foo"]; !exists || val != "bar" {
|
||||
t.Fatalf("Inccorect output: %v", output)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTableSortStringValue(t *testing.T) {
|
||||
table := NewTable("Key", 0)
|
||||
|
||||
e := &Env{}
|
||||
e.Set("Key", "A")
|
||||
table.Add(e)
|
||||
|
||||
e = &Env{}
|
||||
e.Set("Key", "D")
|
||||
table.Add(e)
|
||||
|
||||
e = &Env{}
|
||||
e.Set("Key", "B")
|
||||
table.Add(e)
|
||||
|
||||
e = &Env{}
|
||||
e.Set("Key", "C")
|
||||
table.Add(e)
|
||||
|
||||
table.Sort()
|
||||
|
||||
if len := table.Len(); len != 4 {
|
||||
t.Fatalf("Expected 4, got %d", len)
|
||||
}
|
||||
|
||||
if value := table.Data[0].Get("Key"); value != "A" {
|
||||
t.Fatalf("Expected A, got %s", value)
|
||||
}
|
||||
|
||||
if value := table.Data[1].Get("Key"); value != "B" {
|
||||
t.Fatalf("Expected B, got %s", value)
|
||||
}
|
||||
|
||||
if value := table.Data[2].Get("Key"); value != "C" {
|
||||
t.Fatalf("Expected C, got %s", value)
|
||||
}
|
||||
|
||||
if value := table.Data[3].Get("Key"); value != "D" {
|
||||
t.Fatalf("Expected D, got %s", value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTableReverseSortStringValue(t *testing.T) {
|
||||
table := NewTable("Key", 0)
|
||||
|
||||
e := &Env{}
|
||||
e.Set("Key", "A")
|
||||
table.Add(e)
|
||||
|
||||
e = &Env{}
|
||||
e.Set("Key", "D")
|
||||
table.Add(e)
|
||||
|
||||
e = &Env{}
|
||||
e.Set("Key", "B")
|
||||
table.Add(e)
|
||||
|
||||
e = &Env{}
|
||||
e.Set("Key", "C")
|
||||
table.Add(e)
|
||||
|
||||
table.ReverseSort()
|
||||
|
||||
if len := table.Len(); len != 4 {
|
||||
t.Fatalf("Expected 4, got %d", len)
|
||||
}
|
||||
|
||||
if value := table.Data[0].Get("Key"); value != "D" {
|
||||
t.Fatalf("Expected D, got %s", value)
|
||||
}
|
||||
|
||||
if value := table.Data[1].Get("Key"); value != "C" {
|
||||
t.Fatalf("Expected B, got %s", value)
|
||||
}
|
||||
|
||||
if value := table.Data[2].Get("Key"); value != "B" {
|
||||
t.Fatalf("Expected C, got %s", value)
|
||||
}
|
||||
|
||||
if value := table.Data[3].Get("Key"); value != "A" {
|
||||
t.Fatalf("Expected A, got %s", value)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package graph
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"path"
|
||||
|
@ -9,7 +8,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/engine"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/pkg/parsers/filters"
|
||||
"github.com/docker/docker/utils"
|
||||
|
@ -20,13 +18,19 @@ var acceptedImageFilterTags = map[string]struct{}{
|
|||
"label": {},
|
||||
}
|
||||
|
||||
type ImagesConfig struct {
|
||||
Filters string
|
||||
Filter string
|
||||
All bool
|
||||
}
|
||||
|
||||
type ByCreated []*types.Image
|
||||
|
||||
func (r ByCreated) Len() int { return len(r) }
|
||||
func (r ByCreated) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
||||
func (r ByCreated) Less(i, j int) bool { return r[i].Created < r[j].Created }
|
||||
|
||||
func (s *TagStore) CmdImages(job *engine.Job) error {
|
||||
func (s *TagStore) Images(config *ImagesConfig) ([]*types.Image, error) {
|
||||
var (
|
||||
allImages map[string]*image.Image
|
||||
err error
|
||||
|
@ -34,13 +38,13 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
|
|||
filtLabel = false
|
||||
)
|
||||
|
||||
imageFilters, err := filters.FromParam(job.Getenv("filters"))
|
||||
imageFilters, err := filters.FromParam(config.Filters)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
for name := range imageFilters {
|
||||
if _, ok := acceptedImageFilterTags[name]; !ok {
|
||||
return fmt.Errorf("Invalid filter '%s'", name)
|
||||
return nil, fmt.Errorf("Invalid filter '%s'", name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,20 +58,20 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
|
|||
|
||||
_, filtLabel = imageFilters["label"]
|
||||
|
||||
if job.GetenvBool("all") && filtTagged {
|
||||
if config.All && filtTagged {
|
||||
allImages, err = s.graph.Map()
|
||||
} else {
|
||||
allImages, err = s.graph.Heads()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lookup := make(map[string]*types.Image)
|
||||
s.Lock()
|
||||
for repoName, repository := range s.Repositories {
|
||||
if job.Getenv("filter") != "" {
|
||||
if match, _ := path.Match(job.Getenv("filter"), repoName); !match {
|
||||
if config.Filter != "" {
|
||||
if match, _ := path.Match(config.Filter, repoName); !match {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +128,7 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
|
|||
}
|
||||
|
||||
// Display images which aren't part of a repository/tag
|
||||
if job.Getenv("filter") == "" || filtLabel {
|
||||
if config.Filter == "" || filtLabel {
|
||||
for _, image := range allImages {
|
||||
if !imageFilters.MatchKVList("label", image.ContainerConfig.Labels) {
|
||||
continue
|
||||
|
@ -145,8 +149,5 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
|
|||
|
||||
sort.Sort(sort.Reverse(ByCreated(images)))
|
||||
|
||||
if err = json.NewEncoder(job.Stdout).Encode(images); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return images, nil
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ func (s *TagStore) Install(eng *engine.Engine) error {
|
|||
"image_tarlayer": s.CmdTarLayer,
|
||||
"image_export": s.CmdImageExport,
|
||||
"history": s.CmdHistory,
|
||||
"images": s.CmdImages,
|
||||
"viz": s.CmdViz,
|
||||
"load": s.CmdLoad,
|
||||
"import": s.CmdImport,
|
||||
|
|
26
integration-cli/docker_api_images_test.go
Normal file
26
integration-cli/docker_api_images_test.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
)
|
||||
|
||||
func TestLegacyImages(t *testing.T) {
|
||||
body, err := sockRequest("GET", "/v1.6/images/json", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Error on GET: %s", err)
|
||||
}
|
||||
|
||||
images := []types.LegacyImage{}
|
||||
if err = json.Unmarshal(body, &images); err != nil {
|
||||
t.Fatalf("Error on unmarshal: %s", err)
|
||||
}
|
||||
|
||||
if len(images) == 0 || images[0].Tag == "" || images[0].Repository == "" {
|
||||
t.Fatalf("Bad data: %q", images)
|
||||
}
|
||||
|
||||
logDone("images - checking legacy json")
|
||||
}
|
|
@ -767,8 +767,8 @@ func TestDeleteImages(t *testing.T) {
|
|||
|
||||
images := getImages(eng, t, true, "")
|
||||
|
||||
if len(images.Data[0].GetList("RepoTags")) != len(initialImages.Data[0].GetList("RepoTags"))+1 {
|
||||
t.Errorf("Expected %d images, %d found", len(initialImages.Data[0].GetList("RepoTags"))+1, len(images.Data[0].GetList("RepoTags")))
|
||||
if len(images[0].RepoTags) != len(initialImages[0].RepoTags)+1 {
|
||||
t.Errorf("Expected %d images, %d found", len(initialImages[0].RepoTags)+1, len(images[0].RepoTags))
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("DELETE", "/images/"+unitTestImageID, nil)
|
||||
|
@ -805,8 +805,8 @@ func TestDeleteImages(t *testing.T) {
|
|||
}
|
||||
images = getImages(eng, t, false, "")
|
||||
|
||||
if images.Len() != initialImages.Len() {
|
||||
t.Errorf("Expected %d image, %d found", initialImages.Len(), images.Len())
|
||||
if len(images) != len(initialImages) {
|
||||
t.Errorf("Expected %d image, %d found", len(initialImages), len(images))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/docker/docker/daemon"
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/docker/docker/engine"
|
||||
"github.com/docker/docker/graph"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/nat"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
|
@ -65,17 +66,13 @@ func cleanup(eng *engine.Engine, t *testing.T) error {
|
|||
container.Kill()
|
||||
daemon.Rm(container)
|
||||
}
|
||||
job := eng.Job("images")
|
||||
images, err := job.Stdout.AddTable()
|
||||
images, err := daemon.Repositories().Images(&graph.ImagesConfig{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, image := range images.Data {
|
||||
if image.Get("Id") != unitTestImageID {
|
||||
eng.Job("image_delete", image.Get("Id")).Run()
|
||||
for _, image := range images {
|
||||
if image.ID != unitTestImageID {
|
||||
eng.Job("image_delete", image.ID).Run()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -253,25 +253,25 @@ func TestImagesFilter(t *testing.T) {
|
|||
|
||||
images := getImages(eng, t, false, "utest*/*")
|
||||
|
||||
if len(images.Data[0].GetList("RepoTags")) != 2 {
|
||||
if len(images[0].RepoTags) != 2 {
|
||||
t.Fatal("incorrect number of matches returned")
|
||||
}
|
||||
|
||||
images = getImages(eng, t, false, "utest")
|
||||
|
||||
if len(images.Data[0].GetList("RepoTags")) != 1 {
|
||||
if len(images[0].RepoTags) != 1 {
|
||||
t.Fatal("incorrect number of matches returned")
|
||||
}
|
||||
|
||||
images = getImages(eng, t, false, "utest*")
|
||||
|
||||
if len(images.Data[0].GetList("RepoTags")) != 1 {
|
||||
if len(images[0].RepoTags) != 1 {
|
||||
t.Fatal("incorrect number of matches returned")
|
||||
}
|
||||
|
||||
images = getImages(eng, t, false, "*5000*/*")
|
||||
|
||||
if len(images.Data[0].GetList("RepoTags")) != 1 {
|
||||
if len(images[0].RepoTags) != 1 {
|
||||
t.Fatal("incorrect number of matches returned")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,11 @@ import (
|
|||
|
||||
"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/builtins"
|
||||
"github.com/docker/docker/daemon"
|
||||
"github.com/docker/docker/engine"
|
||||
"github.com/docker/docker/graph"
|
||||
flag "github.com/docker/docker/pkg/mflag"
|
||||
"github.com/docker/docker/registry"
|
||||
"github.com/docker/docker/runconfig"
|
||||
|
@ -329,19 +331,17 @@ func fakeTar() (io.ReadCloser, error) {
|
|||
return ioutil.NopCloser(buf), nil
|
||||
}
|
||||
|
||||
func getImages(eng *engine.Engine, t *testing.T, all bool, filter string) *engine.Table {
|
||||
job := eng.Job("images")
|
||||
job.SetenvBool("all", all)
|
||||
job.Setenv("filter", filter)
|
||||
images, err := job.Stdout.AddListTable()
|
||||
func getImages(eng *engine.Engine, t *testing.T, all bool, filter string) []*types.Image {
|
||||
config := graph.ImagesConfig{
|
||||
Filter: filter,
|
||||
All: all,
|
||||
}
|
||||
images, err := getDaemon(eng).Repositories().Images(&config)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := job.Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return images
|
||||
|
||||
return images
|
||||
}
|
||||
|
||||
func parseRun(args []string) (*runconfig.Config, *runconfig.HostConfig, *flag.FlagSet, error) {
|
||||
|
@ -350,3 +350,7 @@ func parseRun(args []string) (*runconfig.Config, *runconfig.HostConfig, *flag.Fl
|
|||
cmd.Usage = nil
|
||||
return runconfig.Parse(cmd, args)
|
||||
}
|
||||
|
||||
func getDaemon(eng *engine.Engine) *daemon.Daemon {
|
||||
return eng.HackGetGlobalVar("httpapi.daemon").(*daemon.Daemon)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue