2014-02-25 18:17:48 +02:00
package main
import (
2014-11-03 20:11:29 +09:00
"fmt"
2015-12-18 14:03:41 +01:00
"io/ioutil"
"os"
"path/filepath"
2014-11-03 20:11:29 +09:00
"reflect"
"sort"
2014-02-25 18:17:48 +02:00
"strings"
2014-06-23 22:19:52 +04:00
"time"
2015-03-18 10:11:01 -04:00
2015-10-16 22:09:32 +08:00
"github.com/docker/docker/pkg/integration/checker"
2015-03-24 12:25:26 +01:00
"github.com/docker/docker/pkg/stringid"
2015-04-18 09:46:47 -07:00
"github.com/go-check/check"
2014-02-25 18:17:48 +02:00
)
2015-04-18 09:46:47 -07:00
func ( s * DockerSuite ) TestImagesEnsureImageIsListed ( c * check . C ) {
2015-10-26 13:47:21 -05:00
imagesOut , _ := dockerCmd ( c , "images" )
c . Assert ( imagesOut , checker . Contains , "busybox" )
2014-02-25 18:17:48 +02:00
}
2014-04-04 00:57:41 +00:00
2015-08-08 15:58:48 +02:00
func ( s * DockerSuite ) TestImagesEnsureImageWithTagIsListed ( c * check . C ) {
2015-11-25 10:43:14 +08:00
name := "imagewithtag"
dockerCmd ( c , "tag" , "busybox" , name + ":v1" )
dockerCmd ( c , "tag" , "busybox" , name + ":v1v1" )
dockerCmd ( c , "tag" , "busybox" , name + ":v2" )
2015-08-08 15:58:48 +02:00
2015-11-25 10:43:14 +08:00
imagesOut , _ := dockerCmd ( c , "images" , name + ":v1" )
c . Assert ( imagesOut , checker . Contains , name )
2015-10-26 13:47:21 -05:00
c . Assert ( imagesOut , checker . Contains , "v1" )
c . Assert ( imagesOut , checker . Not ( checker . Contains ) , "v2" )
2015-11-25 10:43:14 +08:00
c . Assert ( imagesOut , checker . Not ( checker . Contains ) , "v1v1" )
2015-08-08 15:58:48 +02:00
2015-11-25 10:43:14 +08:00
imagesOut , _ = dockerCmd ( c , "images" , name )
c . Assert ( imagesOut , checker . Contains , name )
2015-10-26 13:47:21 -05:00
c . Assert ( imagesOut , checker . Contains , "v1" )
2015-11-25 10:43:14 +08:00
c . Assert ( imagesOut , checker . Contains , "v1v1" )
2015-10-26 13:47:21 -05:00
c . Assert ( imagesOut , checker . Contains , "v2" )
2015-08-08 15:58:48 +02:00
}
func ( s * DockerSuite ) TestImagesEnsureImageWithBadTagIsNotListed ( c * check . C ) {
2015-10-26 13:47:21 -05:00
imagesOut , _ := dockerCmd ( c , "images" , "busybox:nonexistent" )
c . Assert ( imagesOut , checker . Not ( checker . Contains ) , "busybox" )
2015-08-08 15:58:48 +02:00
}
2015-04-18 09:46:47 -07:00
func ( s * DockerSuite ) TestImagesOrderedByCreationDate ( c * check . C ) {
2014-06-23 22:19:52 +04:00
id1 , err := buildImage ( "order:test_a" ,
2016-08-30 15:20:55 -07:00
` FROM busybox
2015-12-18 14:03:41 +01:00
MAINTAINER dockerio1 ` , true )
2015-10-26 13:47:21 -05:00
c . Assert ( err , checker . IsNil )
2015-08-11 09:41:11 +02:00
time . Sleep ( 1 * time . Second )
2014-06-23 22:19:52 +04:00
id2 , err := buildImage ( "order:test_c" ,
2016-08-30 15:20:55 -07:00
` FROM busybox
2015-12-18 14:03:41 +01:00
MAINTAINER dockerio2 ` , true )
2015-10-26 13:47:21 -05:00
c . Assert ( err , checker . IsNil )
2015-08-11 09:41:11 +02:00
time . Sleep ( 1 * time . Second )
2014-06-23 22:19:52 +04:00
id3 , err := buildImage ( "order:test_b" ,
2016-08-30 15:20:55 -07:00
` FROM busybox
2015-12-18 14:03:41 +01:00
MAINTAINER dockerio3 ` , true )
2015-10-26 13:47:21 -05:00
c . Assert ( err , checker . IsNil )
2014-06-23 22:19:52 +04:00
2015-07-20 14:55:40 +08:00
out , _ := dockerCmd ( c , "images" , "-q" , "--no-trunc" )
2014-06-23 22:19:52 +04:00
imgs := strings . Split ( out , "\n" )
2015-10-26 13:47:21 -05: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 22:19:52 +04:00
}
2014-11-03 20:11:29 +09:00
2015-04-18 09:46:47 -07:00
func ( s * DockerSuite ) TestImagesErrorWithInvalidFilterNameTest ( c * check . C ) {
2015-07-27 14:13:25 -04:00
out , _ , err := dockerCmdWithError ( "images" , "-f" , "FOO=123" )
2015-10-26 13:47:21 -05:00
c . Assert ( err , checker . NotNil )
c . Assert ( out , checker . Contains , "Invalid filter" )
2014-11-03 20:11:29 +09:00
}
2015-11-25 20:27:11 -05:00
func ( s * DockerSuite ) TestImagesFilterLabelMatch ( c * check . C ) {
2015-01-06 17:04:10 -07:00
imageName1 := "images_filter_test1"
imageName2 := "images_filter_test2"
imageName3 := "images_filter_test3"
image1ID , err := buildImage ( imageName1 ,
2016-08-30 15:20:55 -07:00
` FROM busybox
2015-12-18 14:03:41 +01:00
LABEL match me ` , true )
2015-08-22 14:06:48 +02:00
c . Assert ( err , check . IsNil )
2015-01-06 17:04:10 -07:00
image2ID , err := buildImage ( imageName2 ,
2016-08-30 15:20:55 -07:00
` FROM busybox
2015-12-18 14:03:41 +01:00
LABEL match = "me too" ` , true )
2015-08-22 14:06:48 +02:00
c . Assert ( err , check . IsNil )
2015-01-06 17:04:10 -07:00
image3ID , err := buildImage ( imageName3 ,
2016-08-30 15:20:55 -07:00
` FROM busybox
2015-12-18 14:03:41 +01:00
LABEL nomatch me ` , true )
2015-08-22 14:06:48 +02:00
c . Assert ( err , check . IsNil )
2015-01-06 17:04:10 -07:00
2015-07-20 14:55:40 +08:00
out , _ := dockerCmd ( c , "images" , "--no-trunc" , "-q" , "-f" , "label=match" )
2015-01-06 17:04:10 -07:00
out = strings . TrimSpace ( out )
2015-11-18 14:20:54 -08: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-06 17:04:10 -07:00
2015-07-20 14:55:40 +08:00
out , _ = dockerCmd ( c , "images" , "--no-trunc" , "-q" , "-f" , "label=match=me too" )
2015-01-06 17:04:10 -07:00
out = strings . TrimSpace ( out )
2015-08-22 14:06:48 +02: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-06 17:04:10 -07:00
}
2016-05-25 13:49:10 +02: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 09:46:47 -07:00
func ( s * DockerSuite ) TestImagesFilterSpaceTrimCase ( c * check . C ) {
2014-11-03 20:11:29 +09:00
imageName := "images_filter_test"
buildImage ( imageName ,
2016-08-30 15:20:55 -07:00
` FROM busybox
2015-12-18 14:03:41 +01:00
RUN touch / test / foo
RUN touch / test / bar
RUN touch / test / baz ` , true )
2014-11-03 20:11:29 +09: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 14:55:40 +08:00
out , _ := dockerCmd ( c , "images" , "-q" , "-f" , filter )
2014-11-03 20:11:29 +09: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 08:59:45 +08:00
fmt . Printf ( "out %d\n" , idx )
2014-11-03 20:11:29 +09:00
for _ , image := range errListing {
fmt . Print ( image )
}
fmt . Print ( "" )
}
2015-04-18 09:46:47 -07:00
c . Fatalf ( "All output must be the same" )
2014-11-03 20:11:29 +09:00
}
}
}
2015-03-18 10:11:01 -04:00
2015-04-18 09:46:47 -07:00
func ( s * DockerSuite ) TestImagesEnsureDanglingImageOnlyListedOnce ( c * check . C ) {
2015-08-28 10:36:42 -07:00
testRequires ( c , DaemonIsLinux )
2015-03-18 10:11:01 -04:00
// create container 1
2015-07-20 14:55:40 +08:00
out , _ := dockerCmd ( c , "run" , "-d" , "busybox" , "true" )
2015-07-22 13:59:24 +01:00
containerID1 := strings . TrimSpace ( out )
2015-03-18 10:11:01 -04:00
// tag as foobox
2015-07-22 13:59:24 +01:00
out , _ = dockerCmd ( c , "commit" , containerID1 , "foobox" )
imageID := stringid . TruncateID ( strings . TrimSpace ( out ) )
2015-03-18 10:11:01 -04:00
// overwrite the tag, making the previous image dangling
2016-05-29 08:16:39 -07:00
dockerCmd ( c , "tag" , "busybox" , "foobox" )
2015-03-18 10:11:01 -04:00
2015-07-20 14:55:40 +08:00
out , _ = dockerCmd ( c , "images" , "-q" , "-f" , "dangling=true" )
2015-12-13 18:00:39 +02:00
// Expect one dangling image
2015-10-26 13:47:21 -05: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 10:11:01 -04:00
}
2015-10-16 22:09:32 +08: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 19:13:45 +02:00
func ( s * DockerSuite ) TestImagesEnsureOnlyHeadsImagesShown ( c * check . C ) {
dockerfile := `
2016-08-30 15:20:55 -07:00
FROM busybox
2015-10-09 19:13:45 +02:00
MAINTAINER docker
ENV foo bar `
head , out , err := buildImageWithOut ( "scratch-image" , dockerfile , false )
c . Assert ( err , check . IsNil )
2015-10-11 09:32:52 +02: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 19:13:45 +02:00
split := strings . Split ( out , "\n" )
intermediate := strings . TrimSpace ( split [ 5 ] [ 7 : ] )
out , _ = dockerCmd ( c , "images" )
2015-10-26 13:47:21 -05: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 14:20:54 -08:00
c . Assert ( out , checker . Contains , stringid . TruncateID ( head ) )
2015-10-09 19:13:45 +02:00
}
func ( s * DockerSuite ) TestImagesEnsureImagesFromScratchShown ( c * check . C ) {
2016-08-30 15:20:55 -07:00
testRequires ( c , DaemonIsLinux ) // Windows does not support FROM scratch
2015-10-09 19:13:45 +02: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 13:47:21 -05:00
// images should contain images built from scratch
2015-11-18 14:20:54 -08:00
c . Assert ( out , checker . Contains , stringid . TruncateID ( id ) )
2015-10-09 19:13:45 +02:00
}
2015-11-25 10:43:14 +08:00
2016-08-30 15:20:55 -07: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 10:43:14 +08: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 14:03:41 +01: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 09:34:19 -07:00
names = append ( names , lines ... )
2015-12-18 14:03:41 +01: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 ) )
}