Add compat 1.8
Docker-DCO-1.1-Signed-off-by: Victor Vieux <victor.vieux@docker.com> (github: vieux)
This commit is contained in:
parent
17a806c8a0
commit
3a610f754f
7 changed files with 112 additions and 99 deletions
7
api.go
7
api.go
|
@ -28,7 +28,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
APIVERSION = 1.8
|
||||
APIVERSION = 1.9
|
||||
DEFAULTHTTPHOST = "127.0.0.1"
|
||||
DEFAULTHTTPPORT = 4243
|
||||
DEFAULTUNIXSOCKET = "/var/run/docker.sock"
|
||||
|
@ -181,18 +181,15 @@ func getImagesJSON(srv *Server, version float64, w http.ResponseWriter, r *http.
|
|||
if err := parseForm(r); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("getImagesJSON\n")
|
||||
job := srv.Eng.Job("images")
|
||||
job.Setenv("filter", r.Form.Get("filter"))
|
||||
job.Setenv("all", r.Form.Get("all"))
|
||||
// FIXME: 1.7 clients expect a single json list
|
||||
job.SetenvBool("list", version <= 1.8)
|
||||
job.Stdout.Add(w)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Printf("running images job\n")
|
||||
if err := job.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("job has been run\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
105
commands.go
105
commands.go
|
@ -1137,36 +1137,38 @@ func (cli *DockerCli) CmdImages(args ...string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
var outs []APIImages
|
||||
if err := json.Unmarshal(body, &outs); err != nil {
|
||||
outs := engine.NewTable("Created", 0)
|
||||
|
||||
if _, err := outs.ReadFrom(bytes.NewReader(body)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
printNode func(cli *DockerCli, noTrunc bool, image APIImages, prefix string)
|
||||
startImage APIImages
|
||||
printNode func(cli *DockerCli, noTrunc bool, image *engine.Env, prefix string)
|
||||
startImage *engine.Env
|
||||
|
||||
roots []APIImages
|
||||
byParent = make(map[string][]APIImages)
|
||||
roots = engine.NewTable("Created", outs.Len())
|
||||
byParent = make(map[string]*engine.Table)
|
||||
)
|
||||
|
||||
for _, image := range outs {
|
||||
if image.ParentId == "" {
|
||||
roots = append(roots, image)
|
||||
for _, image := range outs.Data {
|
||||
if image.Get("ParentId") == "" {
|
||||
roots.Add(image)
|
||||
} else {
|
||||
if children, exists := byParent[image.ParentId]; exists {
|
||||
byParent[image.ParentId] = append(children, image)
|
||||
if children, exists := byParent[image.Get("ParentId")]; exists {
|
||||
children.Add(image)
|
||||
} else {
|
||||
byParent[image.ParentId] = []APIImages{image}
|
||||
byParent[image.Get("ParentId")] = engine.NewTable("Created", 1)
|
||||
byParent[image.Get("ParentId")].Add(image)
|
||||
}
|
||||
}
|
||||
|
||||
if filter != "" {
|
||||
if filter == image.ID || filter == utils.TruncateID(image.ID) {
|
||||
if filter == image.Get("ID") || filter == utils.TruncateID(image.Get("ID")) {
|
||||
startImage = image
|
||||
}
|
||||
|
||||
for _, repotag := range image.RepoTags {
|
||||
for _, repotag := range image.GetList("RepoTags") {
|
||||
if repotag == filter {
|
||||
startImage = image
|
||||
}
|
||||
|
@ -1181,10 +1183,12 @@ func (cli *DockerCli) CmdImages(args ...string) error {
|
|||
printNode = (*DockerCli).printTreeNode
|
||||
}
|
||||
|
||||
if startImage.ID != "" {
|
||||
cli.WalkTree(*noTrunc, &[]APIImages{startImage}, byParent, "", printNode)
|
||||
if startImage != nil {
|
||||
root := engine.NewTable("Created", 1)
|
||||
root.Add(startImage)
|
||||
cli.WalkTree(*noTrunc, root, byParent, "", printNode)
|
||||
} else if filter == "" {
|
||||
cli.WalkTree(*noTrunc, &roots, byParent, "", printNode)
|
||||
cli.WalkTree(*noTrunc, roots, byParent, "", printNode)
|
||||
}
|
||||
if *flViz {
|
||||
fmt.Fprintf(cli.out, " base [style=invisible]\n}\n")
|
||||
|
@ -1203,9 +1207,8 @@ func (cli *DockerCli) CmdImages(args ...string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
var outs []APIImages
|
||||
err = json.Unmarshal(body, &outs)
|
||||
if err != nil {
|
||||
outs := engine.NewTable("Created", 0)
|
||||
if _, err := outs.ReadFrom(bytes.NewReader(body)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -1214,19 +1217,19 @@ func (cli *DockerCli) CmdImages(args ...string) error {
|
|||
fmt.Fprintln(w, "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tVIRTUAL SIZE")
|
||||
}
|
||||
|
||||
for _, out := range outs {
|
||||
for _, repotag := range out.RepoTags {
|
||||
for _, out := range outs.Data {
|
||||
for _, repotag := range out.GetList("RepoTags") {
|
||||
|
||||
repo, tag := utils.ParseRepositoryTag(repotag)
|
||||
|
||||
outID := out.Get("ID")
|
||||
if !*noTrunc {
|
||||
out.ID = utils.TruncateID(out.ID)
|
||||
outID = utils.TruncateID(outID)
|
||||
}
|
||||
|
||||
if !*quiet {
|
||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, out.ID, utils.HumanDuration(time.Now().UTC().Sub(time.Unix(out.Created, 0))), utils.HumanSize(out.VirtualSize))
|
||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, outID, utils.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), utils.HumanSize(out.GetInt64("VirtualSize")))
|
||||
} else {
|
||||
fmt.Fprintln(w, out.ID)
|
||||
fmt.Fprintln(w, outID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1238,66 +1241,66 @@ func (cli *DockerCli) CmdImages(args ...string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (cli *DockerCli) WalkTree(noTrunc bool, images *[]APIImages, byParent map[string][]APIImages, prefix string, printNode func(cli *DockerCli, noTrunc bool, image APIImages, prefix string)) {
|
||||
length := len(*images)
|
||||
func (cli *DockerCli) WalkTree(noTrunc bool, images *engine.Table, byParent map[string]*engine.Table, prefix string, printNode func(cli *DockerCli, noTrunc bool, image *engine.Env, prefix string)) {
|
||||
length := images.Len()
|
||||
if length > 1 {
|
||||
for index, image := range *images {
|
||||
for index, image := range images.Data {
|
||||
if index+1 == length {
|
||||
printNode(cli, noTrunc, image, prefix+"└─")
|
||||
if subimages, exists := byParent[image.ID]; exists {
|
||||
cli.WalkTree(noTrunc, &subimages, byParent, prefix+" ", printNode)
|
||||
if subimages, exists := byParent[image.Get("ID")]; exists {
|
||||
cli.WalkTree(noTrunc, subimages, byParent, prefix+" ", printNode)
|
||||
}
|
||||
} else {
|
||||
printNode(cli, noTrunc, image, prefix+"├─")
|
||||
if subimages, exists := byParent[image.ID]; exists {
|
||||
cli.WalkTree(noTrunc, &subimages, byParent, prefix+"│ ", printNode)
|
||||
printNode(cli, noTrunc, image, prefix+"\u251C─")
|
||||
if subimages, exists := byParent[image.Get("ID")]; exists {
|
||||
cli.WalkTree(noTrunc, subimages, byParent, prefix+"\u2502 ", printNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, image := range *images {
|
||||
for _, image := range images.Data {
|
||||
printNode(cli, noTrunc, image, prefix+"└─")
|
||||
if subimages, exists := byParent[image.ID]; exists {
|
||||
cli.WalkTree(noTrunc, &subimages, byParent, prefix+" ", printNode)
|
||||
if subimages, exists := byParent[image.Get("ID")]; exists {
|
||||
cli.WalkTree(noTrunc, subimages, byParent, prefix+" ", printNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *DockerCli) printVizNode(noTrunc bool, image APIImages, prefix string) {
|
||||
func (cli *DockerCli) printVizNode(noTrunc bool, image *engine.Env, prefix string) {
|
||||
var (
|
||||
imageID string
|
||||
parentID string
|
||||
)
|
||||
if noTrunc {
|
||||
imageID = image.ID
|
||||
parentID = image.ParentId
|
||||
imageID = image.Get("ID")
|
||||
parentID = image.Get("ParentId")
|
||||
} else {
|
||||
imageID = utils.TruncateID(image.ID)
|
||||
parentID = utils.TruncateID(image.ParentId)
|
||||
imageID = utils.TruncateID(image.Get("ID"))
|
||||
parentID = utils.TruncateID(image.Get("ParentId"))
|
||||
}
|
||||
if image.ParentId == "" {
|
||||
if parentID == "" {
|
||||
fmt.Fprintf(cli.out, " base -> \"%s\" [style=invis]\n", imageID)
|
||||
} else {
|
||||
fmt.Fprintf(cli.out, " \"%s\" -> \"%s\"\n", parentID, imageID)
|
||||
}
|
||||
if image.RepoTags[0] != "<none>:<none>" {
|
||||
if image.GetList("RepoTags")[0] != "<none>:<none>" {
|
||||
fmt.Fprintf(cli.out, " \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n",
|
||||
imageID, imageID, strings.Join(image.RepoTags, "\\n"))
|
||||
imageID, imageID, strings.Join(image.GetList("RepoTags"), "\\n"))
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *DockerCli) printTreeNode(noTrunc bool, image APIImages, prefix string) {
|
||||
func (cli *DockerCli) printTreeNode(noTrunc bool, image *engine.Env, prefix string) {
|
||||
var imageID string
|
||||
if noTrunc {
|
||||
imageID = image.ID
|
||||
imageID = image.Get("ID")
|
||||
} else {
|
||||
imageID = utils.TruncateID(image.ID)
|
||||
imageID = utils.TruncateID(image.Get("ID"))
|
||||
}
|
||||
|
||||
fmt.Fprintf(cli.out, "%s%s Virtual Size: %s", prefix, imageID, utils.HumanSize(image.VirtualSize))
|
||||
if image.RepoTags[0] != "<none>:<none>" {
|
||||
fmt.Fprintf(cli.out, " Tags: %s\n", strings.Join(image.RepoTags, ", "))
|
||||
fmt.Fprintf(cli.out, "%s%s Virtual Size: %s", prefix, imageID, utils.HumanSize(image.GetInt64("VirtualSize")))
|
||||
if image.GetList("RepoTags")[0] != "<none>:<none>" {
|
||||
fmt.Fprintf(cli.out, " Tags: %s\n", strings.Join(image.GetList("RepoTags"), ", "))
|
||||
} else {
|
||||
fmt.Fprint(cli.out, "\n")
|
||||
}
|
||||
|
|
|
@ -237,15 +237,21 @@ func (env *Env) Map() map[string]string {
|
|||
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)
|
||||
}
|
||||
|
@ -279,16 +285,41 @@ 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 += 1
|
||||
}
|
||||
}
|
||||
if _, err := dst.Write([]byte{']'}); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return n + 1, 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
|
||||
}
|
||||
if _, err := dst.Write([]byte{'\n'}); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
n += bytes + 1
|
||||
n += bytes
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
|
|
@ -204,18 +204,18 @@ func TestGetImagesJSON(t *testing.T) {
|
|||
}
|
||||
assertHttpNotError(r2, t)
|
||||
|
||||
images2 := []docker.APIImages{}
|
||||
if err := json.Unmarshal(r2.Body.Bytes(), &images2); err != nil {
|
||||
images2 := engine.NewTable("ID", 0)
|
||||
if _, err := images2.ReadFrom(r2.Body); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(images2) != initialImages.Len() {
|
||||
t.Errorf("Expected %d image, %d found", initialImages.Len(), len(images2))
|
||||
if images2.Len() != initialImages.Len() {
|
||||
t.Errorf("Expected %d image, %d found", initialImages.Len(), images2.Len())
|
||||
}
|
||||
|
||||
found = false
|
||||
for _, img := range images2 {
|
||||
if img.ID == unitTestImageID {
|
||||
for _, img := range images2.Data {
|
||||
if img.Get("ID") == unitTestImageID {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
|
@ -237,29 +237,13 @@ func TestGetImagesJSON(t *testing.T) {
|
|||
}
|
||||
assertHttpNotError(r3, t)
|
||||
|
||||
images3 := []docker.APIImages{}
|
||||
if err := json.Unmarshal(r3.Body.Bytes(), &images3); err != nil {
|
||||
images3 := engine.NewTable("ID", 0)
|
||||
if _, err := images3.ReadFrom(r3.Body); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(images3) != 0 {
|
||||
t.Errorf("Expected 0 image, %d found", len(images3))
|
||||
}
|
||||
|
||||
r4 := httptest.NewRecorder()
|
||||
|
||||
// all=foobar
|
||||
req4, err := http.NewRequest("GET", "/images/json?all=foobar", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := docker.ServeRequest(srv, docker.APIVERSION, r4, req4); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Don't assert against HTTP error since we expect an error
|
||||
if r4.Code != http.StatusBadRequest {
|
||||
t.Fatalf("%d Bad Request expected, received %d\n", http.StatusBadRequest, r4.Code)
|
||||
if images3.Len() != 0 {
|
||||
t.Errorf("Expected 0 image, %d found", images3.Len())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1136,8 +1120,8 @@ func TestDeleteImages(t *testing.T) {
|
|||
|
||||
images := getImages(eng, t, true, "")
|
||||
|
||||
if images.Len() != initialImages.Len()+1 {
|
||||
t.Errorf("Expected %d images, %d found", initialImages.Len()+1, images.Len())
|
||||
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")))
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("DELETE", "/images/"+unitTestImageID, nil)
|
||||
|
|
|
@ -324,8 +324,6 @@ func TestImagesFilter(t *testing.T) {
|
|||
eng := NewTestEngine(t)
|
||||
defer nuke(mkRuntimeFromEngine(eng, t))
|
||||
|
||||
srv := mkServerFromEngine(eng, t)
|
||||
|
||||
if err := eng.Job("tag", unitTestImageName, "utest", "tag1").Run(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -43,8 +43,8 @@ func TestServerListOrderedImagesByCreationDateAndTag(t *testing.T) {
|
|||
|
||||
images := getImages(eng, t, true, "")
|
||||
|
||||
if images.Data[0].GetList("RepoTags")[0] != "repo:zed" && images.Data[0].GetList("RepoTags")[0] != "repo:bar" {
|
||||
t.Errorf("Expected []APIImges to be ordered by most recent creation date. %s", images)
|
||||
if repoTags := images.Data[0].GetList("RepoTags"); repoTags[0] != "repo:zed" && repoTags[0] != "repo:bar" {
|
||||
t.Errorf("Expected Images to be ordered by most recent creation date.")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
14
server.go
14
server.go
|
@ -573,8 +573,6 @@ func (srv *Server) ImagesViz(out io.Writer) error {
|
|||
}
|
||||
|
||||
func (srv *Server) Images(job *engine.Job) engine.Status {
|
||||
fmt.Printf("Images()\n")
|
||||
srv.Eng.Job("version").Run()
|
||||
var (
|
||||
allImages map[string]*Image
|
||||
err error
|
||||
|
@ -639,13 +637,15 @@ func (srv *Server) Images(job *engine.Job) engine.Status {
|
|||
}
|
||||
}
|
||||
|
||||
outs.Sort()
|
||||
job.Logf("Sending %d images to stdout", outs.Len())
|
||||
if n, err := outs.WriteTo(job.Stdout); err != nil {
|
||||
outs.ReverseSort()
|
||||
if job.GetenvBool("list") {
|
||||
if _, err := outs.WriteListTo(job.Stdout); err != nil {
|
||||
job.Errorf("%s", err)
|
||||
return engine.StatusErr
|
||||
}
|
||||
} else if _, err := outs.WriteTo(job.Stdout); err != nil {
|
||||
job.Errorf("%s", err)
|
||||
return engine.StatusErr
|
||||
} else {
|
||||
job.Logf("%d bytes sent", n)
|
||||
}
|
||||
return engine.StatusOK
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue