2014-02-25 16:17:48 +00:00
package main
import (
2014-11-03 11:11:29 +00:00
"fmt"
2015-12-18 13:03:41 +00:00
"io/ioutil"
"os"
"path/filepath"
2014-11-03 11:11:29 +00:00
"reflect"
"sort"
2014-02-25 16:17:48 +00:00
"strings"
2014-06-23 18:19:52 +00:00
"time"
2015-03-18 14:11:01 +00:00
2016-12-30 17:23:00 +00:00
"github.com/docker/docker/integration-cli/checker"
2015-03-24 11:25:26 +00:00
"github.com/docker/docker/pkg/stringid"
2015-04-18 16:46:47 +00:00
"github.com/go-check/check"
2014-02-25 16:17:48 +00:00
)
2015-04-18 16:46:47 +00:00
func ( s * DockerSuite ) TestImagesEnsureImageIsListed ( c * check . C ) {
2015-10-26 18:47:21 +00:00
imagesOut , _ := dockerCmd ( c , "images" )
c . Assert ( imagesOut , checker . Contains , "busybox" )
2014-02-25 16:17:48 +00:00
}
2014-04-04 00:57:41 +00:00
2015-08-08 13:58:48 +00:00
func ( s * DockerSuite ) TestImagesEnsureImageWithTagIsListed ( c * check . C ) {
2015-11-25 02:43:14 +00:00
name := "imagewithtag"
dockerCmd ( c , "tag" , "busybox" , name + ":v1" )
dockerCmd ( c , "tag" , "busybox" , name + ":v1v1" )
dockerCmd ( c , "tag" , "busybox" , name + ":v2" )
2015-08-08 13:58:48 +00:00
2015-11-25 02:43:14 +00:00
imagesOut , _ := dockerCmd ( c , "images" , name + ":v1" )
c . Assert ( imagesOut , checker . Contains , name )
2015-10-26 18:47:21 +00:00
c . Assert ( imagesOut , checker . Contains , "v1" )
c . Assert ( imagesOut , checker . Not ( checker . Contains ) , "v2" )
2015-11-25 02:43:14 +00:00
c . Assert ( imagesOut , checker . Not ( checker . Contains ) , "v1v1" )
2015-08-08 13:58:48 +00:00
2015-11-25 02:43:14 +00:00
imagesOut , _ = dockerCmd ( c , "images" , name )
c . Assert ( imagesOut , checker . Contains , name )
2015-10-26 18:47:21 +00:00
c . Assert ( imagesOut , checker . Contains , "v1" )
2015-11-25 02:43:14 +00:00
c . Assert ( imagesOut , checker . Contains , "v1v1" )
2015-10-26 18:47:21 +00:00
c . Assert ( imagesOut , checker . Contains , "v2" )
2015-08-08 13:58:48 +00:00
}
func ( s * DockerSuite ) TestImagesEnsureImageWithBadTagIsNotListed ( c * check . C ) {
2015-10-26 18:47:21 +00:00
imagesOut , _ := dockerCmd ( c , "images" , "busybox:nonexistent" )
c . Assert ( imagesOut , checker . Not ( checker . Contains ) , "busybox" )
2015-08-08 13:58:48 +00:00
}
2015-04-18 16:46:47 +00:00
func ( s * DockerSuite ) TestImagesOrderedByCreationDate ( c * check . C ) {
2014-06-23 18:19:52 +00:00
id1 , err := buildImage ( "order:test_a" ,
2016-08-30 22:20:55 +00:00
` FROM busybox
2015-12-18 13:03:41 +00:00
MAINTAINER dockerio1 ` , true )
2015-10-26 18:47:21 +00:00
c . Assert ( err , checker . IsNil )
2015-08-11 07:41:11 +00:00
time . Sleep ( 1 * time . Second )
2014-06-23 18:19:52 +00:00
id2 , err := buildImage ( "order:test_c" ,
2016-08-30 22:20:55 +00:00
` FROM busybox
2015-12-18 13:03:41 +00:00
MAINTAINER dockerio2 ` , true )
2015-10-26 18:47:21 +00:00
c . Assert ( err , checker . IsNil )
2015-08-11 07:41:11 +00:00
time . Sleep ( 1 * time . Second )
2014-06-23 18:19:52 +00:00
id3 , err := buildImage ( "order:test_b" ,
2016-08-30 22:20:55 +00:00
` FROM busybox
2015-12-18 13:03:41 +00:00
MAINTAINER dockerio3 ` , true )
2015-10-26 18:47:21 +00:00
c . Assert ( err , checker . IsNil )
2014-06-23 18:19:52 +00:00
2015-07-20 06:55:40 +00:00
out , _ := dockerCmd ( c , "images" , "-q" , "--no-trunc" )
2014-06-23 18:19:52 +00:00
imgs := strings . Split ( out , "\n" )
2015-10-26 18:47:21 +00:00
c . Assert ( imgs [ 0 ] , checker . Equals , id3 , check . Commentf ( "First image must be %s, got %s" , id3 , imgs [ 0 ] ) )
c . Assert ( imgs [ 1 ] , checker . Equals , id2 , check . Commentf ( "First image must be %s, got %s" , id2 , imgs [ 1 ] ) )
c . Assert ( imgs [ 2 ] , checker . Equals , id1 , check . Commentf ( "First image must be %s, got %s" , id1 , imgs [ 2 ] ) )
2014-06-23 18:19:52 +00:00
}
2014-11-03 11:11:29 +00:00
2015-04-18 16:46:47 +00:00
func ( s * DockerSuite ) TestImagesErrorWithInvalidFilterNameTest ( c * check . C ) {
2015-07-27 18:13:25 +00:00
out , _ , err := dockerCmdWithError ( "images" , "-f" , "FOO=123" )
2015-10-26 18:47:21 +00:00
c . Assert ( err , checker . NotNil )
c . Assert ( out , checker . Contains , "Invalid filter" )
2014-11-03 11:11:29 +00:00
}
2015-11-26 01:27:11 +00:00
func ( s * DockerSuite ) TestImagesFilterLabelMatch ( c * check . C ) {
2015-01-07 00:04:10 +00:00
imageName1 := "images_filter_test1"
imageName2 := "images_filter_test2"
imageName3 := "images_filter_test3"
image1ID , err := buildImage ( imageName1 ,
2016-08-30 22:20:55 +00:00
` FROM busybox
2015-12-18 13:03:41 +00:00
LABEL match me ` , true )
2015-08-22 12:06:48 +00:00
c . Assert ( err , check . IsNil )
2015-01-07 00:04:10 +00:00
image2ID , err := buildImage ( imageName2 ,
2016-08-30 22:20:55 +00:00
` FROM busybox
2015-12-18 13:03:41 +00:00
LABEL match = "me too" ` , true )
2015-08-22 12:06:48 +00:00
c . Assert ( err , check . IsNil )
2015-01-07 00:04:10 +00:00
image3ID , err := buildImage ( imageName3 ,
2016-08-30 22:20:55 +00:00
` FROM busybox
2015-12-18 13:03:41 +00:00
LABEL nomatch me ` , true )
2015-08-22 12:06:48 +00:00
c . Assert ( err , check . IsNil )
2015-01-07 00:04:10 +00:00
2015-07-20 06:55:40 +00:00
out , _ := dockerCmd ( c , "images" , "--no-trunc" , "-q" , "-f" , "label=match" )
2015-01-07 00:04:10 +00:00
out = strings . TrimSpace ( out )
2015-11-18 22:20:54 +00:00
c . Assert ( out , check . Matches , fmt . Sprintf ( "[\\s\\w:]*%s[\\s\\w:]*" , image1ID ) )
c . Assert ( out , check . Matches , fmt . Sprintf ( "[\\s\\w:]*%s[\\s\\w:]*" , image2ID ) )
c . Assert ( out , check . Not ( check . Matches ) , fmt . Sprintf ( "[\\s\\w:]*%s[\\s\\w:]*" , image3ID ) )
2015-01-07 00:04:10 +00:00
2015-07-20 06:55:40 +00:00
out , _ = dockerCmd ( c , "images" , "--no-trunc" , "-q" , "-f" , "label=match=me too" )
2015-01-07 00:04:10 +00:00
out = strings . TrimSpace ( out )
2015-08-22 12:06:48 +00:00
c . Assert ( out , check . Equals , image2ID )
}
// Regression : #15659
func ( s * DockerSuite ) TestImagesFilterLabelWithCommit ( c * check . C ) {
// Create a container
dockerCmd ( c , "run" , "--name" , "bar" , "busybox" , "/bin/sh" )
// Commit with labels "using changes"
out , _ := dockerCmd ( c , "commit" , "-c" , "LABEL foo.version=1.0.0-1" , "-c" , "LABEL foo.name=bar" , "-c" , "LABEL foo.author=starlord" , "bar" , "bar:1.0.0-1" )
imageID := strings . TrimSpace ( out )
out , _ = dockerCmd ( c , "images" , "--no-trunc" , "-q" , "-f" , "label=foo.version=1.0.0-1" )
out = strings . TrimSpace ( out )
c . Assert ( out , check . Equals , imageID )
2015-01-07 00:04:10 +00:00
}
2016-05-25 11:49:10 +00:00
func ( s * DockerSuite ) TestImagesFilterSinceAndBefore ( c * check . C ) {
imageID1 , err := buildImage ( "image:1" , ` FROM ` + minimalBaseImage ( ) + `
LABEL number = 1 ` , true )
c . Assert ( err , checker . IsNil )
imageID2 , err := buildImage ( "image:2" , ` FROM ` + minimalBaseImage ( ) + `
LABEL number = 2 ` , true )
c . Assert ( err , checker . IsNil )
imageID3 , err := buildImage ( "image:3" , ` FROM ` + minimalBaseImage ( ) + `
LABEL number = 3 ` , true )
c . Assert ( err , checker . IsNil )
expected := [ ] string { imageID3 , imageID2 }
out , _ := dockerCmd ( c , "images" , "-f" , "since=image:1" , "image" )
c . Assert ( assertImageList ( out , expected ) , checker . Equals , true , check . Commentf ( "SINCE filter: Image list is not in the correct order: %v\n%s" , expected , out ) )
out , _ = dockerCmd ( c , "images" , "-f" , "since=" + imageID1 , "image" )
c . Assert ( assertImageList ( out , expected ) , checker . Equals , true , check . Commentf ( "SINCE filter: Image list is not in the correct order: %v\n%s" , expected , out ) )
expected = [ ] string { imageID3 }
out , _ = dockerCmd ( c , "images" , "-f" , "since=image:2" , "image" )
c . Assert ( assertImageList ( out , expected ) , checker . Equals , true , check . Commentf ( "SINCE filter: Image list is not in the correct order: %v\n%s" , expected , out ) )
out , _ = dockerCmd ( c , "images" , "-f" , "since=" + imageID2 , "image" )
c . Assert ( assertImageList ( out , expected ) , checker . Equals , true , check . Commentf ( "SINCE filter: Image list is not in the correct order: %v\n%s" , expected , out ) )
expected = [ ] string { imageID2 , imageID1 }
out , _ = dockerCmd ( c , "images" , "-f" , "before=image:3" , "image" )
c . Assert ( assertImageList ( out , expected ) , checker . Equals , true , check . Commentf ( "BEFORE filter: Image list is not in the correct order: %v\n%s" , expected , out ) )
out , _ = dockerCmd ( c , "images" , "-f" , "before=" + imageID3 , "image" )
c . Assert ( assertImageList ( out , expected ) , checker . Equals , true , check . Commentf ( "BEFORE filter: Image list is not in the correct order: %v\n%s" , expected , out ) )
expected = [ ] string { imageID1 }
out , _ = dockerCmd ( c , "images" , "-f" , "before=image:2" , "image" )
c . Assert ( assertImageList ( out , expected ) , checker . Equals , true , check . Commentf ( "BEFORE filter: Image list is not in the correct order: %v\n%s" , expected , out ) )
out , _ = dockerCmd ( c , "images" , "-f" , "before=" + imageID2 , "image" )
c . Assert ( assertImageList ( out , expected ) , checker . Equals , true , check . Commentf ( "BEFORE filter: Image list is not in the correct order: %v\n%s" , expected , out ) )
}
func assertImageList ( out string , expected [ ] string ) bool {
lines := strings . Split ( strings . Trim ( out , "\n " ) , "\n" )
if len ( lines ) - 1 != len ( expected ) {
return false
}
imageIDIndex := strings . Index ( lines [ 0 ] , "IMAGE ID" )
for i := 0 ; i < len ( expected ) ; i ++ {
imageID := lines [ i + 1 ] [ imageIDIndex : imageIDIndex + 12 ]
found := false
for _ , e := range expected {
if imageID == e [ 7 : 19 ] {
found = true
break
}
}
if ! found {
return false
}
}
return true
}
2015-04-18 16:46:47 +00:00
func ( s * DockerSuite ) TestImagesFilterSpaceTrimCase ( c * check . C ) {
2014-11-03 11:11:29 +00:00
imageName := "images_filter_test"
buildImage ( imageName ,
2016-08-30 22:20:55 +00:00
` FROM busybox
2015-12-18 13:03:41 +00:00
RUN touch / test / foo
RUN touch / test / bar
RUN touch / test / baz ` , true )
2014-11-03 11:11:29 +00:00
filters := [ ] string {
"dangling=true" ,
"Dangling=true" ,
" dangling=true" ,
"dangling=true " ,
"dangling = true" ,
}
imageListings := make ( [ ] [ ] string , 5 , 5 )
for idx , filter := range filters {
2015-07-20 06:55:40 +00:00
out , _ := dockerCmd ( c , "images" , "-q" , "-f" , filter )
2014-11-03 11:11:29 +00:00
listing := strings . Split ( out , "\n" )
sort . Strings ( listing )
imageListings [ idx ] = listing
}
for idx , listing := range imageListings {
if idx < 4 && ! reflect . DeepEqual ( listing , imageListings [ idx + 1 ] ) {
for idx , errListing := range imageListings {
2016-08-23 00:59:45 +00:00
fmt . Printf ( "out %d\n" , idx )
2014-11-03 11:11:29 +00:00
for _ , image := range errListing {
fmt . Print ( image )
}
fmt . Print ( "" )
}
2015-04-18 16:46:47 +00:00
c . Fatalf ( "All output must be the same" )
2014-11-03 11:11:29 +00:00
}
}
}
2015-03-18 14:11:01 +00:00
2015-04-18 16:46:47 +00:00
func ( s * DockerSuite ) TestImagesEnsureDanglingImageOnlyListedOnce ( c * check . C ) {
2015-08-28 17:36:42 +00:00
testRequires ( c , DaemonIsLinux )
2015-03-18 14:11:01 +00:00
// create container 1
2015-07-20 06:55:40 +00:00
out , _ := dockerCmd ( c , "run" , "-d" , "busybox" , "true" )
2015-07-22 12:59:24 +00:00
containerID1 := strings . TrimSpace ( out )
2015-03-18 14:11:01 +00:00
// tag as foobox
2015-07-22 12:59:24 +00:00
out , _ = dockerCmd ( c , "commit" , containerID1 , "foobox" )
imageID := stringid . TruncateID ( strings . TrimSpace ( out ) )
2015-03-18 14:11:01 +00:00
// overwrite the tag, making the previous image dangling
2016-05-29 15:16:39 +00:00
dockerCmd ( c , "tag" , "busybox" , "foobox" )
2015-03-18 14:11:01 +00:00
2015-07-20 06:55:40 +00:00
out , _ = dockerCmd ( c , "images" , "-q" , "-f" , "dangling=true" )
2015-12-13 16:00:39 +00:00
// Expect one dangling image
2015-10-26 18:47:21 +00:00
c . Assert ( strings . Count ( out , imageID ) , checker . Equals , 1 )
2016-01-14 06:58:31 +00:00
out , _ = dockerCmd ( c , "images" , "-q" , "-f" , "dangling=false" )
//dangling=false would not include dangling images
c . Assert ( out , checker . Not ( checker . Contains ) , imageID )
out , _ = dockerCmd ( c , "images" )
//docker images still include dangling images
c . Assert ( out , checker . Contains , imageID )
2015-03-18 14:11:01 +00:00
}
2015-10-16 14:09:32 +00:00
func ( s * DockerSuite ) TestImagesWithIncorrectFilter ( c * check . C ) {
out , _ , err := dockerCmdWithError ( "images" , "-f" , "dangling=invalid" )
c . Assert ( err , check . NotNil )
c . Assert ( out , checker . Contains , "Invalid filter" )
}
2015-10-09 17:13:45 +00:00
func ( s * DockerSuite ) TestImagesEnsureOnlyHeadsImagesShown ( c * check . C ) {
dockerfile := `
2016-08-30 22:20:55 +00:00
FROM busybox
2015-10-09 17:13:45 +00:00
MAINTAINER docker
ENV foo bar `
head , out , err := buildImageWithOut ( "scratch-image" , dockerfile , false )
c . Assert ( err , check . IsNil )
2015-10-11 07:32:52 +00:00
// this is just the output of docker build
// we're interested in getting the image id of the MAINTAINER instruction
// and that's located at output, line 5, from 7 to end
2015-10-09 17:13:45 +00:00
split := strings . Split ( out , "\n" )
intermediate := strings . TrimSpace ( split [ 5 ] [ 7 : ] )
out , _ = dockerCmd ( c , "images" )
2015-10-26 18:47:21 +00:00
// images shouldn't show non-heads images
c . Assert ( out , checker . Not ( checker . Contains ) , intermediate )
// images should contain final built images
2015-11-18 22:20:54 +00:00
c . Assert ( out , checker . Contains , stringid . TruncateID ( head ) )
2015-10-09 17:13:45 +00:00
}
func ( s * DockerSuite ) TestImagesEnsureImagesFromScratchShown ( c * check . C ) {
2016-08-30 22:20:55 +00:00
testRequires ( c , DaemonIsLinux ) // Windows does not support FROM scratch
2015-10-09 17:13:45 +00:00
dockerfile := `
FROM scratch
MAINTAINER docker `
id , _ , err := buildImageWithOut ( "scratch-image" , dockerfile , false )
c . Assert ( err , check . IsNil )
out , _ := dockerCmd ( c , "images" )
2015-10-26 18:47:21 +00:00
// images should contain images built from scratch
2015-11-18 22:20:54 +00:00
c . Assert ( out , checker . Contains , stringid . TruncateID ( id ) )
2015-10-09 17:13:45 +00:00
}
2015-11-25 02:43:14 +00:00
2016-08-30 22:20:55 +00:00
// For W2W - equivalent to TestImagesEnsureImagesFromScratchShown but Windows
// doesn't support from scratch
func ( s * DockerSuite ) TestImagesEnsureImagesFromBusyboxShown ( c * check . C ) {
dockerfile := `
FROM busybox
MAINTAINER docker `
id , _ , err := buildImageWithOut ( "busybox-image" , dockerfile , false )
c . Assert ( err , check . IsNil )
out , _ := dockerCmd ( c , "images" )
// images should contain images built from busybox
c . Assert ( out , checker . Contains , stringid . TruncateID ( id ) )
}
2015-11-25 02:43:14 +00:00
// #18181
func ( s * DockerSuite ) TestImagesFilterNameWithPort ( c * check . C ) {
tag := "a.b.c.d:5000/hello"
dockerCmd ( c , "tag" , "busybox" , tag )
out , _ := dockerCmd ( c , "images" , tag )
c . Assert ( out , checker . Contains , tag )
out , _ = dockerCmd ( c , "images" , tag + ":latest" )
c . Assert ( out , checker . Contains , tag )
out , _ = dockerCmd ( c , "images" , tag + ":no-such-tag" )
c . Assert ( out , checker . Not ( checker . Contains ) , tag )
}
2015-12-18 13:03:41 +00:00
func ( s * DockerSuite ) TestImagesFormat ( c * check . C ) {
// testRequires(c, DaemonIsLinux)
tag := "myimage"
dockerCmd ( c , "tag" , "busybox" , tag + ":v1" )
dockerCmd ( c , "tag" , "busybox" , tag + ":v2" )
out , _ := dockerCmd ( c , "images" , "--format" , "{{.Repository}}" , tag )
lines := strings . Split ( strings . TrimSpace ( string ( out ) ) , "\n" )
expected := [ ] string { "myimage" , "myimage" }
var names [ ] string
2016-10-13 16:34:19 +00:00
names = append ( names , lines ... )
2015-12-18 13:03:41 +00:00
c . Assert ( expected , checker . DeepEquals , names , check . Commentf ( "Expected array with truncated names: %v, got: %v" , expected , names ) )
}
// ImagesDefaultFormatAndQuiet
func ( s * DockerSuite ) TestImagesFormatDefaultFormat ( c * check . C ) {
testRequires ( c , DaemonIsLinux )
// create container 1
out , _ := dockerCmd ( c , "run" , "-d" , "busybox" , "true" )
containerID1 := strings . TrimSpace ( out )
// tag as foobox
out , _ = dockerCmd ( c , "commit" , containerID1 , "myimage" )
imageID := stringid . TruncateID ( strings . TrimSpace ( out ) )
config := ` {
"imagesFormat" : "{{ .ID }} default"
} `
d , err := ioutil . TempDir ( "" , "integration-cli-" )
c . Assert ( err , checker . IsNil )
defer os . RemoveAll ( d )
err = ioutil . WriteFile ( filepath . Join ( d , "config.json" ) , [ ] byte ( config ) , 0644 )
c . Assert ( err , checker . IsNil )
out , _ = dockerCmd ( c , "--config" , d , "images" , "-q" , "myimage" )
c . Assert ( out , checker . Equals , imageID + "\n" , check . Commentf ( "Expected to print only the image id, got %v\n" , out ) )
}