github.com/SamWhited/moby@v1.13.1/integration-cli/docker_cli_images_test.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"reflect"
     9  	"sort"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/docker/docker/pkg/integration/checker"
    14  	"github.com/docker/docker/pkg/stringid"
    15  	"github.com/go-check/check"
    16  )
    17  
    18  func (s *DockerSuite) TestImagesEnsureImageIsListed(c *check.C) {
    19  	imagesOut, _ := dockerCmd(c, "images")
    20  	c.Assert(imagesOut, checker.Contains, "busybox")
    21  }
    22  
    23  func (s *DockerSuite) TestImagesEnsureImageWithTagIsListed(c *check.C) {
    24  	name := "imagewithtag"
    25  	dockerCmd(c, "tag", "busybox", name+":v1")
    26  	dockerCmd(c, "tag", "busybox", name+":v1v1")
    27  	dockerCmd(c, "tag", "busybox", name+":v2")
    28  
    29  	imagesOut, _ := dockerCmd(c, "images", name+":v1")
    30  	c.Assert(imagesOut, checker.Contains, name)
    31  	c.Assert(imagesOut, checker.Contains, "v1")
    32  	c.Assert(imagesOut, checker.Not(checker.Contains), "v2")
    33  	c.Assert(imagesOut, checker.Not(checker.Contains), "v1v1")
    34  
    35  	imagesOut, _ = dockerCmd(c, "images", name)
    36  	c.Assert(imagesOut, checker.Contains, name)
    37  	c.Assert(imagesOut, checker.Contains, "v1")
    38  	c.Assert(imagesOut, checker.Contains, "v1v1")
    39  	c.Assert(imagesOut, checker.Contains, "v2")
    40  }
    41  
    42  func (s *DockerSuite) TestImagesEnsureImageWithBadTagIsNotListed(c *check.C) {
    43  	imagesOut, _ := dockerCmd(c, "images", "busybox:nonexistent")
    44  	c.Assert(imagesOut, checker.Not(checker.Contains), "busybox")
    45  }
    46  
    47  func (s *DockerSuite) TestImagesOrderedByCreationDate(c *check.C) {
    48  	id1, err := buildImage("order:test_a",
    49  		`FROM busybox
    50                  MAINTAINER dockerio1`, true)
    51  	c.Assert(err, checker.IsNil)
    52  	time.Sleep(1 * time.Second)
    53  	id2, err := buildImage("order:test_c",
    54  		`FROM busybox
    55                  MAINTAINER dockerio2`, true)
    56  	c.Assert(err, checker.IsNil)
    57  	time.Sleep(1 * time.Second)
    58  	id3, err := buildImage("order:test_b",
    59  		`FROM busybox
    60                  MAINTAINER dockerio3`, true)
    61  	c.Assert(err, checker.IsNil)
    62  
    63  	out, _ := dockerCmd(c, "images", "-q", "--no-trunc")
    64  	imgs := strings.Split(out, "\n")
    65  	c.Assert(imgs[0], checker.Equals, id3, check.Commentf("First image must be %s, got %s", id3, imgs[0]))
    66  	c.Assert(imgs[1], checker.Equals, id2, check.Commentf("First image must be %s, got %s", id2, imgs[1]))
    67  	c.Assert(imgs[2], checker.Equals, id1, check.Commentf("First image must be %s, got %s", id1, imgs[2]))
    68  }
    69  
    70  func (s *DockerSuite) TestImagesErrorWithInvalidFilterNameTest(c *check.C) {
    71  	out, _, err := dockerCmdWithError("images", "-f", "FOO=123")
    72  	c.Assert(err, checker.NotNil)
    73  	c.Assert(out, checker.Contains, "Invalid filter")
    74  }
    75  
    76  func (s *DockerSuite) TestImagesFilterLabelMatch(c *check.C) {
    77  	imageName1 := "images_filter_test1"
    78  	imageName2 := "images_filter_test2"
    79  	imageName3 := "images_filter_test3"
    80  	image1ID, err := buildImage(imageName1,
    81  		`FROM busybox
    82                   LABEL match me`, true)
    83  	c.Assert(err, check.IsNil)
    84  
    85  	image2ID, err := buildImage(imageName2,
    86  		`FROM busybox
    87                   LABEL match="me too"`, true)
    88  	c.Assert(err, check.IsNil)
    89  
    90  	image3ID, err := buildImage(imageName3,
    91  		`FROM busybox
    92                   LABEL nomatch me`, true)
    93  	c.Assert(err, check.IsNil)
    94  
    95  	out, _ := dockerCmd(c, "images", "--no-trunc", "-q", "-f", "label=match")
    96  	out = strings.TrimSpace(out)
    97  	c.Assert(out, check.Matches, fmt.Sprintf("[\\s\\w:]*%s[\\s\\w:]*", image1ID))
    98  	c.Assert(out, check.Matches, fmt.Sprintf("[\\s\\w:]*%s[\\s\\w:]*", image2ID))
    99  	c.Assert(out, check.Not(check.Matches), fmt.Sprintf("[\\s\\w:]*%s[\\s\\w:]*", image3ID))
   100  
   101  	out, _ = dockerCmd(c, "images", "--no-trunc", "-q", "-f", "label=match=me too")
   102  	out = strings.TrimSpace(out)
   103  	c.Assert(out, check.Equals, image2ID)
   104  }
   105  
   106  // Regression : #15659
   107  func (s *DockerSuite) TestImagesFilterLabelWithCommit(c *check.C) {
   108  	// Create a container
   109  	dockerCmd(c, "run", "--name", "bar", "busybox", "/bin/sh")
   110  	// Commit with labels "using changes"
   111  	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")
   112  	imageID := strings.TrimSpace(out)
   113  
   114  	out, _ = dockerCmd(c, "images", "--no-trunc", "-q", "-f", "label=foo.version=1.0.0-1")
   115  	out = strings.TrimSpace(out)
   116  	c.Assert(out, check.Equals, imageID)
   117  }
   118  
   119  func (s *DockerSuite) TestImagesFilterSinceAndBefore(c *check.C) {
   120  	imageID1, err := buildImage("image:1", `FROM `+minimalBaseImage()+`
   121  LABEL number=1`, true)
   122  	c.Assert(err, checker.IsNil)
   123  	imageID2, err := buildImage("image:2", `FROM `+minimalBaseImage()+`
   124  LABEL number=2`, true)
   125  	c.Assert(err, checker.IsNil)
   126  	imageID3, err := buildImage("image:3", `FROM `+minimalBaseImage()+`
   127  LABEL number=3`, true)
   128  	c.Assert(err, checker.IsNil)
   129  
   130  	expected := []string{imageID3, imageID2}
   131  
   132  	out, _ := dockerCmd(c, "images", "-f", "since=image:1", "image")
   133  	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))
   134  
   135  	out, _ = dockerCmd(c, "images", "-f", "since="+imageID1, "image")
   136  	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))
   137  
   138  	expected = []string{imageID3}
   139  
   140  	out, _ = dockerCmd(c, "images", "-f", "since=image:2", "image")
   141  	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))
   142  
   143  	out, _ = dockerCmd(c, "images", "-f", "since="+imageID2, "image")
   144  	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))
   145  
   146  	expected = []string{imageID2, imageID1}
   147  
   148  	out, _ = dockerCmd(c, "images", "-f", "before=image:3", "image")
   149  	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))
   150  
   151  	out, _ = dockerCmd(c, "images", "-f", "before="+imageID3, "image")
   152  	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))
   153  
   154  	expected = []string{imageID1}
   155  
   156  	out, _ = dockerCmd(c, "images", "-f", "before=image:2", "image")
   157  	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))
   158  
   159  	out, _ = dockerCmd(c, "images", "-f", "before="+imageID2, "image")
   160  	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))
   161  }
   162  
   163  func assertImageList(out string, expected []string) bool {
   164  	lines := strings.Split(strings.Trim(out, "\n "), "\n")
   165  
   166  	if len(lines)-1 != len(expected) {
   167  		return false
   168  	}
   169  
   170  	imageIDIndex := strings.Index(lines[0], "IMAGE ID")
   171  	for i := 0; i < len(expected); i++ {
   172  		imageID := lines[i+1][imageIDIndex : imageIDIndex+12]
   173  		found := false
   174  		for _, e := range expected {
   175  			if imageID == e[7:19] {
   176  				found = true
   177  				break
   178  			}
   179  		}
   180  		if !found {
   181  			return false
   182  		}
   183  	}
   184  
   185  	return true
   186  }
   187  
   188  func (s *DockerSuite) TestImagesFilterSpaceTrimCase(c *check.C) {
   189  	imageName := "images_filter_test"
   190  	buildImage(imageName,
   191  		`FROM busybox
   192                   RUN touch /test/foo
   193                   RUN touch /test/bar
   194                   RUN touch /test/baz`, true)
   195  
   196  	filters := []string{
   197  		"dangling=true",
   198  		"Dangling=true",
   199  		" dangling=true",
   200  		"dangling=true ",
   201  		"dangling = true",
   202  	}
   203  
   204  	imageListings := make([][]string, 5, 5)
   205  	for idx, filter := range filters {
   206  		out, _ := dockerCmd(c, "images", "-q", "-f", filter)
   207  		listing := strings.Split(out, "\n")
   208  		sort.Strings(listing)
   209  		imageListings[idx] = listing
   210  	}
   211  
   212  	for idx, listing := range imageListings {
   213  		if idx < 4 && !reflect.DeepEqual(listing, imageListings[idx+1]) {
   214  			for idx, errListing := range imageListings {
   215  				fmt.Printf("out %d\n", idx)
   216  				for _, image := range errListing {
   217  					fmt.Print(image)
   218  				}
   219  				fmt.Print("")
   220  			}
   221  			c.Fatalf("All output must be the same")
   222  		}
   223  	}
   224  }
   225  
   226  func (s *DockerSuite) TestImagesEnsureDanglingImageOnlyListedOnce(c *check.C) {
   227  	testRequires(c, DaemonIsLinux)
   228  	// create container 1
   229  	out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
   230  	containerID1 := strings.TrimSpace(out)
   231  
   232  	// tag as foobox
   233  	out, _ = dockerCmd(c, "commit", containerID1, "foobox")
   234  	imageID := stringid.TruncateID(strings.TrimSpace(out))
   235  
   236  	// overwrite the tag, making the previous image dangling
   237  	dockerCmd(c, "tag", "busybox", "foobox")
   238  
   239  	out, _ = dockerCmd(c, "images", "-q", "-f", "dangling=true")
   240  	// Expect one dangling image
   241  	c.Assert(strings.Count(out, imageID), checker.Equals, 1)
   242  
   243  	out, _ = dockerCmd(c, "images", "-q", "-f", "dangling=false")
   244  	//dangling=false would not include dangling images
   245  	c.Assert(out, checker.Not(checker.Contains), imageID)
   246  
   247  	out, _ = dockerCmd(c, "images")
   248  	//docker images still include dangling images
   249  	c.Assert(out, checker.Contains, imageID)
   250  
   251  }
   252  
   253  func (s *DockerSuite) TestImagesWithIncorrectFilter(c *check.C) {
   254  	out, _, err := dockerCmdWithError("images", "-f", "dangling=invalid")
   255  	c.Assert(err, check.NotNil)
   256  	c.Assert(out, checker.Contains, "Invalid filter")
   257  }
   258  
   259  func (s *DockerSuite) TestImagesEnsureOnlyHeadsImagesShown(c *check.C) {
   260  	dockerfile := `
   261          FROM busybox
   262          MAINTAINER docker
   263          ENV foo bar`
   264  
   265  	head, out, err := buildImageWithOut("scratch-image", dockerfile, false)
   266  	c.Assert(err, check.IsNil)
   267  
   268  	// this is just the output of docker build
   269  	// we're interested in getting the image id of the MAINTAINER instruction
   270  	// and that's located at output, line 5, from 7 to end
   271  	split := strings.Split(out, "\n")
   272  	intermediate := strings.TrimSpace(split[5][7:])
   273  
   274  	out, _ = dockerCmd(c, "images")
   275  	// images shouldn't show non-heads images
   276  	c.Assert(out, checker.Not(checker.Contains), intermediate)
   277  	// images should contain final built images
   278  	c.Assert(out, checker.Contains, stringid.TruncateID(head))
   279  }
   280  
   281  func (s *DockerSuite) TestImagesEnsureImagesFromScratchShown(c *check.C) {
   282  	testRequires(c, DaemonIsLinux) // Windows does not support FROM scratch
   283  
   284  	dockerfile := `
   285          FROM scratch
   286          MAINTAINER docker`
   287  
   288  	id, _, err := buildImageWithOut("scratch-image", dockerfile, false)
   289  	c.Assert(err, check.IsNil)
   290  
   291  	out, _ := dockerCmd(c, "images")
   292  	// images should contain images built from scratch
   293  	c.Assert(out, checker.Contains, stringid.TruncateID(id))
   294  }
   295  
   296  // For W2W - equivalent to TestImagesEnsureImagesFromScratchShown but Windows
   297  // doesn't support from scratch
   298  func (s *DockerSuite) TestImagesEnsureImagesFromBusyboxShown(c *check.C) {
   299  	dockerfile := `
   300          FROM busybox
   301          MAINTAINER docker`
   302  
   303  	id, _, err := buildImageWithOut("busybox-image", dockerfile, false)
   304  	c.Assert(err, check.IsNil)
   305  
   306  	out, _ := dockerCmd(c, "images")
   307  	// images should contain images built from busybox
   308  	c.Assert(out, checker.Contains, stringid.TruncateID(id))
   309  }
   310  
   311  // #18181
   312  func (s *DockerSuite) TestImagesFilterNameWithPort(c *check.C) {
   313  	tag := "a.b.c.d:5000/hello"
   314  	dockerCmd(c, "tag", "busybox", tag)
   315  	out, _ := dockerCmd(c, "images", tag)
   316  	c.Assert(out, checker.Contains, tag)
   317  
   318  	out, _ = dockerCmd(c, "images", tag+":latest")
   319  	c.Assert(out, checker.Contains, tag)
   320  
   321  	out, _ = dockerCmd(c, "images", tag+":no-such-tag")
   322  	c.Assert(out, checker.Not(checker.Contains), tag)
   323  }
   324  
   325  func (s *DockerSuite) TestImagesFormat(c *check.C) {
   326  	// testRequires(c, DaemonIsLinux)
   327  	tag := "myimage"
   328  	dockerCmd(c, "tag", "busybox", tag+":v1")
   329  	dockerCmd(c, "tag", "busybox", tag+":v2")
   330  
   331  	out, _ := dockerCmd(c, "images", "--format", "{{.Repository}}", tag)
   332  	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
   333  
   334  	expected := []string{"myimage", "myimage"}
   335  	var names []string
   336  	names = append(names, lines...)
   337  	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with truncated names: %v, got: %v", expected, names))
   338  }
   339  
   340  // ImagesDefaultFormatAndQuiet
   341  func (s *DockerSuite) TestImagesFormatDefaultFormat(c *check.C) {
   342  	testRequires(c, DaemonIsLinux)
   343  
   344  	// create container 1
   345  	out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
   346  	containerID1 := strings.TrimSpace(out)
   347  
   348  	// tag as foobox
   349  	out, _ = dockerCmd(c, "commit", containerID1, "myimage")
   350  	imageID := stringid.TruncateID(strings.TrimSpace(out))
   351  
   352  	config := `{
   353  		"imagesFormat": "{{ .ID }} default"
   354  }`
   355  	d, err := ioutil.TempDir("", "integration-cli-")
   356  	c.Assert(err, checker.IsNil)
   357  	defer os.RemoveAll(d)
   358  
   359  	err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644)
   360  	c.Assert(err, checker.IsNil)
   361  
   362  	out, _ = dockerCmd(c, "--config", d, "images", "-q", "myimage")
   363  	c.Assert(out, checker.Equals, imageID+"\n", check.Commentf("Expected to print only the image id, got %v\n", out))
   364  }