github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/integration-cli/docker_cli_build_test.go (about)

     1  package main
     2  
     3  import (
     4  	"archive/tar"
     5  	"bufio"
     6  	"bytes"
     7  	"encoding/json"
     8  	"fmt"
     9  	"io/ioutil"
    10  	"net/http"
    11  	"os"
    12  	"os/exec"
    13  	"path/filepath"
    14  	"reflect"
    15  	"regexp"
    16  	"runtime"
    17  	"strconv"
    18  	"strings"
    19  	"text/template"
    20  	"time"
    21  
    22  	"github.com/docker/docker/builder/dockerfile/command"
    23  	"github.com/docker/docker/pkg/archive"
    24  	"github.com/docker/docker/pkg/integration/checker"
    25  	"github.com/docker/docker/pkg/stringutils"
    26  	"github.com/go-check/check"
    27  )
    28  
    29  func (s *DockerSuite) TestBuildJSONEmptyRun(c *check.C) {
    30  	testRequires(c, DaemonIsLinux)
    31  	name := "testbuildjsonemptyrun"
    32  
    33  	_, err := buildImage(
    34  		name,
    35  		`
    36      FROM busybox
    37      RUN []
    38      `,
    39  		true)
    40  
    41  	if err != nil {
    42  		c.Fatal("error when dealing with a RUN statement with empty JSON array")
    43  	}
    44  
    45  }
    46  
    47  func (s *DockerSuite) TestBuildEmptyWhitespace(c *check.C) {
    48  	testRequires(c, DaemonIsLinux)
    49  	name := "testbuildemptywhitespace"
    50  
    51  	_, err := buildImage(
    52  		name,
    53  		`
    54      FROM busybox
    55      COPY
    56        quux \
    57        bar
    58      `,
    59  		true)
    60  
    61  	if err == nil {
    62  		c.Fatal("no error when dealing with a COPY statement with no content on the same line")
    63  	}
    64  
    65  }
    66  
    67  func (s *DockerSuite) TestBuildShCmdJSONEntrypoint(c *check.C) {
    68  	testRequires(c, DaemonIsLinux)
    69  	name := "testbuildshcmdjsonentrypoint"
    70  
    71  	_, err := buildImage(
    72  		name,
    73  		`
    74      FROM busybox
    75      ENTRYPOINT ["/bin/echo"]
    76      CMD echo test
    77      `,
    78  		true)
    79  
    80  	if err != nil {
    81  		c.Fatal(err)
    82  	}
    83  
    84  	out, _ := dockerCmd(c, "run", "--rm", name)
    85  
    86  	if strings.TrimSpace(out) != "/bin/sh -c echo test" {
    87  		c.Fatalf("CMD did not contain /bin/sh -c : %s", out)
    88  	}
    89  
    90  }
    91  
    92  func (s *DockerSuite) TestBuildEnvironmentReplacementUser(c *check.C) {
    93  	testRequires(c, DaemonIsLinux)
    94  	name := "testbuildenvironmentreplacement"
    95  
    96  	_, err := buildImage(name, `
    97    FROM scratch
    98    ENV user foo
    99    USER ${user}
   100    `, true)
   101  	if err != nil {
   102  		c.Fatal(err)
   103  	}
   104  
   105  	res, err := inspectFieldJSON(name, "Config.User")
   106  	if err != nil {
   107  		c.Fatal(err)
   108  	}
   109  
   110  	if res != `"foo"` {
   111  		c.Fatal("User foo from environment not in Config.User on image")
   112  	}
   113  
   114  }
   115  
   116  func (s *DockerSuite) TestBuildEnvironmentReplacementVolume(c *check.C) {
   117  	testRequires(c, DaemonIsLinux)
   118  	name := "testbuildenvironmentreplacement"
   119  
   120  	_, err := buildImage(name, `
   121    FROM scratch
   122    ENV volume /quux
   123    VOLUME ${volume}
   124    `, true)
   125  	if err != nil {
   126  		c.Fatal(err)
   127  	}
   128  
   129  	res, err := inspectFieldJSON(name, "Config.Volumes")
   130  	if err != nil {
   131  		c.Fatal(err)
   132  	}
   133  
   134  	var volumes map[string]interface{}
   135  
   136  	if err := json.Unmarshal([]byte(res), &volumes); err != nil {
   137  		c.Fatal(err)
   138  	}
   139  
   140  	if _, ok := volumes["/quux"]; !ok {
   141  		c.Fatal("Volume /quux from environment not in Config.Volumes on image")
   142  	}
   143  
   144  }
   145  
   146  func (s *DockerSuite) TestBuildEnvironmentReplacementExpose(c *check.C) {
   147  	testRequires(c, DaemonIsLinux)
   148  	name := "testbuildenvironmentreplacement"
   149  
   150  	_, err := buildImage(name, `
   151    FROM scratch
   152    ENV port 80
   153    EXPOSE ${port}
   154    ENV ports "  99   100 "
   155    EXPOSE ${ports}
   156    `, true)
   157  	if err != nil {
   158  		c.Fatal(err)
   159  	}
   160  
   161  	res, err := inspectFieldJSON(name, "Config.ExposedPorts")
   162  	if err != nil {
   163  		c.Fatal(err)
   164  	}
   165  
   166  	var exposedPorts map[string]interface{}
   167  
   168  	if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
   169  		c.Fatal(err)
   170  	}
   171  
   172  	exp := []int{80, 99, 100}
   173  
   174  	for _, p := range exp {
   175  		tmp := fmt.Sprintf("%d/tcp", p)
   176  		if _, ok := exposedPorts[tmp]; !ok {
   177  			c.Fatalf("Exposed port %d from environment not in Config.ExposedPorts on image", p)
   178  		}
   179  	}
   180  
   181  }
   182  
   183  func (s *DockerSuite) TestBuildEnvironmentReplacementWorkdir(c *check.C) {
   184  	testRequires(c, DaemonIsLinux)
   185  	name := "testbuildenvironmentreplacement"
   186  
   187  	_, err := buildImage(name, `
   188    FROM busybox
   189    ENV MYWORKDIR /work
   190    RUN mkdir ${MYWORKDIR}
   191    WORKDIR ${MYWORKDIR}
   192    `, true)
   193  
   194  	if err != nil {
   195  		c.Fatal(err)
   196  	}
   197  
   198  }
   199  
   200  func (s *DockerSuite) TestBuildEnvironmentReplacementAddCopy(c *check.C) {
   201  	testRequires(c, DaemonIsLinux)
   202  	name := "testbuildenvironmentreplacement"
   203  
   204  	ctx, err := fakeContext(`
   205    FROM scratch
   206    ENV baz foo
   207    ENV quux bar
   208    ENV dot .
   209    ENV fee fff
   210    ENV gee ggg
   211  
   212    ADD ${baz} ${dot}
   213    COPY ${quux} ${dot}
   214    ADD ${zzz:-${fee}} ${dot}
   215    COPY ${zzz:-${gee}} ${dot}
   216    `,
   217  		map[string]string{
   218  			"foo": "test1",
   219  			"bar": "test2",
   220  			"fff": "test3",
   221  			"ggg": "test4",
   222  		})
   223  
   224  	if err != nil {
   225  		c.Fatal(err)
   226  	}
   227  	defer ctx.Close()
   228  
   229  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   230  		c.Fatal(err)
   231  	}
   232  
   233  }
   234  
   235  func (s *DockerSuite) TestBuildEnvironmentReplacementEnv(c *check.C) {
   236  	testRequires(c, DaemonIsLinux)
   237  	name := "testbuildenvironmentreplacement"
   238  
   239  	_, err := buildImage(name,
   240  		`
   241    FROM busybox
   242    ENV foo zzz
   243    ENV bar ${foo}
   244    ENV abc1='$foo'
   245    ENV env1=$foo env2=${foo} env3="$foo" env4="${foo}"
   246    RUN [ "$abc1" = '$foo' ] && (echo "$abc1" | grep -q foo)
   247    ENV abc2="\$foo"
   248    RUN [ "$abc2" = '$foo' ] && (echo "$abc2" | grep -q foo)
   249    ENV abc3 '$foo'
   250    RUN [ "$abc3" = '$foo' ] && (echo "$abc3" | grep -q foo)
   251    ENV abc4 "\$foo"
   252    RUN [ "$abc4" = '$foo' ] && (echo "$abc4" | grep -q foo)
   253    `, true)
   254  
   255  	if err != nil {
   256  		c.Fatal(err)
   257  	}
   258  
   259  	res, err := inspectFieldJSON(name, "Config.Env")
   260  	if err != nil {
   261  		c.Fatal(err)
   262  	}
   263  
   264  	envResult := []string{}
   265  
   266  	if err = unmarshalJSON([]byte(res), &envResult); err != nil {
   267  		c.Fatal(err)
   268  	}
   269  
   270  	found := false
   271  	envCount := 0
   272  
   273  	for _, env := range envResult {
   274  		parts := strings.SplitN(env, "=", 2)
   275  		if parts[0] == "bar" {
   276  			found = true
   277  			if parts[1] != "zzz" {
   278  				c.Fatalf("Could not find replaced var for env `bar`: got %q instead of `zzz`", parts[1])
   279  			}
   280  		} else if strings.HasPrefix(parts[0], "env") {
   281  			envCount++
   282  			if parts[1] != "zzz" {
   283  				c.Fatalf("%s should be 'foo' but instead its %q", parts[0], parts[1])
   284  			}
   285  		} else if strings.HasPrefix(parts[0], "env") {
   286  			envCount++
   287  			if parts[1] != "foo" {
   288  				c.Fatalf("%s should be 'foo' but instead its %q", parts[0], parts[1])
   289  			}
   290  		}
   291  	}
   292  
   293  	if !found {
   294  		c.Fatal("Never found the `bar` env variable")
   295  	}
   296  
   297  	if envCount != 4 {
   298  		c.Fatalf("Didn't find all env vars - only saw %d\n%s", envCount, envResult)
   299  	}
   300  
   301  }
   302  
   303  func (s *DockerSuite) TestBuildHandleEscapes(c *check.C) {
   304  	testRequires(c, DaemonIsLinux)
   305  	name := "testbuildhandleescapes"
   306  
   307  	_, err := buildImage(name,
   308  		`
   309    FROM scratch
   310    ENV FOO bar
   311    VOLUME ${FOO}
   312    `, true)
   313  
   314  	if err != nil {
   315  		c.Fatal(err)
   316  	}
   317  
   318  	var result map[string]map[string]struct{}
   319  
   320  	res, err := inspectFieldJSON(name, "Config.Volumes")
   321  	if err != nil {
   322  		c.Fatal(err)
   323  	}
   324  
   325  	if err = unmarshalJSON([]byte(res), &result); err != nil {
   326  		c.Fatal(err)
   327  	}
   328  
   329  	if _, ok := result["bar"]; !ok {
   330  		c.Fatal("Could not find volume bar set from env foo in volumes table")
   331  	}
   332  
   333  	deleteImages(name)
   334  
   335  	_, err = buildImage(name,
   336  		`
   337    FROM scratch
   338    ENV FOO bar
   339    VOLUME \${FOO}
   340    `, true)
   341  
   342  	if err != nil {
   343  		c.Fatal(err)
   344  	}
   345  
   346  	res, err = inspectFieldJSON(name, "Config.Volumes")
   347  	if err != nil {
   348  		c.Fatal(err)
   349  	}
   350  
   351  	if err = unmarshalJSON([]byte(res), &result); err != nil {
   352  		c.Fatal(err)
   353  	}
   354  
   355  	if _, ok := result["${FOO}"]; !ok {
   356  		c.Fatal("Could not find volume ${FOO} set from env foo in volumes table")
   357  	}
   358  
   359  	deleteImages(name)
   360  
   361  	// this test in particular provides *7* backslashes and expects 6 to come back.
   362  	// Like above, the first escape is swallowed and the rest are treated as
   363  	// literals, this one is just less obvious because of all the character noise.
   364  
   365  	_, err = buildImage(name,
   366  		`
   367    FROM scratch
   368    ENV FOO bar
   369    VOLUME \\\\\\\${FOO}
   370    `, true)
   371  
   372  	if err != nil {
   373  		c.Fatal(err)
   374  	}
   375  
   376  	res, err = inspectFieldJSON(name, "Config.Volumes")
   377  	if err != nil {
   378  		c.Fatal(err)
   379  	}
   380  
   381  	if err = unmarshalJSON([]byte(res), &result); err != nil {
   382  		c.Fatal(err)
   383  	}
   384  
   385  	if _, ok := result[`\\\${FOO}`]; !ok {
   386  		c.Fatal(`Could not find volume \\\${FOO} set from env foo in volumes table`, result)
   387  	}
   388  
   389  }
   390  
   391  func (s *DockerSuite) TestBuildOnBuildLowercase(c *check.C) {
   392  	testRequires(c, DaemonIsLinux)
   393  	name := "testbuildonbuildlowercase"
   394  	name2 := "testbuildonbuildlowercase2"
   395  
   396  	_, err := buildImage(name,
   397  		`
   398    FROM busybox
   399    onbuild run echo quux
   400    `, true)
   401  
   402  	if err != nil {
   403  		c.Fatal(err)
   404  	}
   405  
   406  	_, out, err := buildImageWithOut(name2, fmt.Sprintf(`
   407    FROM %s
   408    `, name), true)
   409  
   410  	if err != nil {
   411  		c.Fatal(err)
   412  	}
   413  
   414  	if !strings.Contains(out, "quux") {
   415  		c.Fatalf("Did not receive the expected echo text, got %s", out)
   416  	}
   417  
   418  	if strings.Contains(out, "ONBUILD ONBUILD") {
   419  		c.Fatalf("Got an ONBUILD ONBUILD error with no error: got %s", out)
   420  	}
   421  
   422  }
   423  
   424  func (s *DockerSuite) TestBuildEnvEscapes(c *check.C) {
   425  	testRequires(c, DaemonIsLinux)
   426  	name := "testbuildenvescapes"
   427  	_, err := buildImage(name,
   428  		`
   429      FROM busybox
   430      ENV TEST foo
   431      CMD echo \$
   432      `,
   433  		true)
   434  
   435  	if err != nil {
   436  		c.Fatal(err)
   437  	}
   438  
   439  	out, _ := dockerCmd(c, "run", "-t", name)
   440  
   441  	if strings.TrimSpace(out) != "$" {
   442  		c.Fatalf("Env TEST was not overwritten with bar when foo was supplied to dockerfile: was %q", strings.TrimSpace(out))
   443  	}
   444  
   445  }
   446  
   447  func (s *DockerSuite) TestBuildEnvOverwrite(c *check.C) {
   448  	testRequires(c, DaemonIsLinux)
   449  	name := "testbuildenvoverwrite"
   450  
   451  	_, err := buildImage(name,
   452  		`
   453      FROM busybox
   454      ENV TEST foo
   455      CMD echo ${TEST}
   456      `,
   457  		true)
   458  
   459  	if err != nil {
   460  		c.Fatal(err)
   461  	}
   462  
   463  	out, _ := dockerCmd(c, "run", "-e", "TEST=bar", "-t", name)
   464  
   465  	if strings.TrimSpace(out) != "bar" {
   466  		c.Fatalf("Env TEST was not overwritten with bar when foo was supplied to dockerfile: was %q", strings.TrimSpace(out))
   467  	}
   468  
   469  }
   470  
   471  func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainerInSourceImage(c *check.C) {
   472  	testRequires(c, DaemonIsLinux)
   473  	name := "testbuildonbuildforbiddenmaintainerinsourceimage"
   474  
   475  	out, _ := dockerCmd(c, "create", "busybox", "true")
   476  
   477  	cleanedContainerID := strings.TrimSpace(out)
   478  
   479  	dockerCmd(c, "commit", "--run", "{\"OnBuild\":[\"MAINTAINER docker.io\"]}", cleanedContainerID, "onbuild")
   480  
   481  	_, err := buildImage(name,
   482  		`FROM onbuild`,
   483  		true)
   484  	if err != nil {
   485  		if !strings.Contains(err.Error(), "maintainer isn't allowed as an ONBUILD trigger") {
   486  			c.Fatalf("Wrong error %v, must be about MAINTAINER and ONBUILD in source image", err)
   487  		}
   488  	} else {
   489  		c.Fatal("Error must not be nil")
   490  	}
   491  
   492  }
   493  
   494  func (s *DockerSuite) TestBuildOnBuildForbiddenFromInSourceImage(c *check.C) {
   495  	testRequires(c, DaemonIsLinux)
   496  	name := "testbuildonbuildforbiddenfrominsourceimage"
   497  
   498  	out, _ := dockerCmd(c, "create", "busybox", "true")
   499  
   500  	cleanedContainerID := strings.TrimSpace(out)
   501  
   502  	dockerCmd(c, "commit", "--run", "{\"OnBuild\":[\"FROM busybox\"]}", cleanedContainerID, "onbuild")
   503  
   504  	_, err := buildImage(name,
   505  		`FROM onbuild`,
   506  		true)
   507  	if err != nil {
   508  		if !strings.Contains(err.Error(), "from isn't allowed as an ONBUILD trigger") {
   509  			c.Fatalf("Wrong error %v, must be about FROM and ONBUILD in source image", err)
   510  		}
   511  	} else {
   512  		c.Fatal("Error must not be nil")
   513  	}
   514  
   515  }
   516  
   517  func (s *DockerSuite) TestBuildOnBuildForbiddenChainedInSourceImage(c *check.C) {
   518  	testRequires(c, DaemonIsLinux)
   519  	name := "testbuildonbuildforbiddenchainedinsourceimage"
   520  
   521  	out, _ := dockerCmd(c, "create", "busybox", "true")
   522  
   523  	cleanedContainerID := strings.TrimSpace(out)
   524  
   525  	dockerCmd(c, "commit", "--run", "{\"OnBuild\":[\"ONBUILD RUN ls\"]}", cleanedContainerID, "onbuild")
   526  
   527  	_, err := buildImage(name,
   528  		`FROM onbuild`,
   529  		true)
   530  	if err != nil {
   531  		if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
   532  			c.Fatalf("Wrong error %v, must be about chaining ONBUILD in source image", err)
   533  		}
   534  	} else {
   535  		c.Fatal("Error must not be nil")
   536  	}
   537  
   538  }
   539  
   540  func (s *DockerSuite) TestBuildOnBuildCmdEntrypointJSON(c *check.C) {
   541  	testRequires(c, DaemonIsLinux)
   542  	name1 := "onbuildcmd"
   543  	name2 := "onbuildgenerated"
   544  
   545  	_, err := buildImage(name1, `
   546  FROM busybox
   547  ONBUILD CMD ["hello world"]
   548  ONBUILD ENTRYPOINT ["echo"]
   549  ONBUILD RUN ["true"]`,
   550  		false)
   551  
   552  	if err != nil {
   553  		c.Fatal(err)
   554  	}
   555  
   556  	_, err = buildImage(name2, fmt.Sprintf(`FROM %s`, name1), false)
   557  
   558  	if err != nil {
   559  		c.Fatal(err)
   560  	}
   561  
   562  	out, _ := dockerCmd(c, "run", "-t", name2)
   563  
   564  	if !regexp.MustCompile(`(?m)^hello world`).MatchString(out) {
   565  		c.Fatal("did not get echo output from onbuild", out)
   566  	}
   567  
   568  }
   569  
   570  func (s *DockerSuite) TestBuildOnBuildEntrypointJSON(c *check.C) {
   571  	testRequires(c, DaemonIsLinux)
   572  	name1 := "onbuildcmd"
   573  	name2 := "onbuildgenerated"
   574  
   575  	_, err := buildImage(name1, `
   576  FROM busybox
   577  ONBUILD ENTRYPOINT ["echo"]`,
   578  		false)
   579  
   580  	if err != nil {
   581  		c.Fatal(err)
   582  	}
   583  
   584  	_, err = buildImage(name2, fmt.Sprintf("FROM %s\nCMD [\"hello world\"]\n", name1), false)
   585  
   586  	if err != nil {
   587  		c.Fatal(err)
   588  	}
   589  
   590  	out, _ := dockerCmd(c, "run", "-t", name2)
   591  
   592  	if !regexp.MustCompile(`(?m)^hello world`).MatchString(out) {
   593  		c.Fatal("got malformed output from onbuild", out)
   594  	}
   595  
   596  }
   597  
   598  func (s *DockerSuite) TestBuildCacheAdd(c *check.C) {
   599  	testRequires(c, DaemonIsLinux)
   600  	name := "testbuildtwoimageswithadd"
   601  	server, err := fakeStorage(map[string]string{
   602  		"robots.txt": "hello",
   603  		"index.html": "world",
   604  	})
   605  	if err != nil {
   606  		c.Fatal(err)
   607  	}
   608  	defer server.Close()
   609  
   610  	if _, err := buildImage(name,
   611  		fmt.Sprintf(`FROM scratch
   612  		ADD %s/robots.txt /`, server.URL()),
   613  		true); err != nil {
   614  		c.Fatal(err)
   615  	}
   616  	if err != nil {
   617  		c.Fatal(err)
   618  	}
   619  	deleteImages(name)
   620  	_, out, err := buildImageWithOut(name,
   621  		fmt.Sprintf(`FROM scratch
   622  		ADD %s/index.html /`, server.URL()),
   623  		true)
   624  	if err != nil {
   625  		c.Fatal(err)
   626  	}
   627  	if strings.Contains(out, "Using cache") {
   628  		c.Fatal("2nd build used cache on ADD, it shouldn't")
   629  	}
   630  
   631  }
   632  
   633  func (s *DockerSuite) TestBuildLastModified(c *check.C) {
   634  	testRequires(c, DaemonIsLinux)
   635  	name := "testbuildlastmodified"
   636  
   637  	server, err := fakeStorage(map[string]string{
   638  		"file": "hello",
   639  	})
   640  	if err != nil {
   641  		c.Fatal(err)
   642  	}
   643  	defer server.Close()
   644  
   645  	var out, out2 string
   646  
   647  	dFmt := `FROM busybox
   648  ADD %s/file /
   649  RUN ls -le /file`
   650  
   651  	dockerfile := fmt.Sprintf(dFmt, server.URL())
   652  
   653  	if _, out, err = buildImageWithOut(name, dockerfile, false); err != nil {
   654  		c.Fatal(err)
   655  	}
   656  
   657  	originMTime := regexp.MustCompile(`root.*/file.*\n`).FindString(out)
   658  	// Make sure our regexp is correct
   659  	if strings.Index(originMTime, "/file") < 0 {
   660  		c.Fatalf("Missing ls info on 'file':\n%s", out)
   661  	}
   662  
   663  	// Build it again and make sure the mtime of the file didn't change.
   664  	// Wait a few seconds to make sure the time changed enough to notice
   665  	time.Sleep(2 * time.Second)
   666  
   667  	if _, out2, err = buildImageWithOut(name, dockerfile, false); err != nil {
   668  		c.Fatal(err)
   669  	}
   670  
   671  	newMTime := regexp.MustCompile(`root.*/file.*\n`).FindString(out2)
   672  	if newMTime != originMTime {
   673  		c.Fatalf("MTime changed:\nOrigin:%s\nNew:%s", originMTime, newMTime)
   674  	}
   675  
   676  	// Now 'touch' the file and make sure the timestamp DID change this time
   677  	// Create a new fakeStorage instead of just using Add() to help windows
   678  	server, err = fakeStorage(map[string]string{
   679  		"file": "hello",
   680  	})
   681  	if err != nil {
   682  		c.Fatal(err)
   683  	}
   684  	defer server.Close()
   685  
   686  	dockerfile = fmt.Sprintf(dFmt, server.URL())
   687  
   688  	if _, out2, err = buildImageWithOut(name, dockerfile, false); err != nil {
   689  		c.Fatal(err)
   690  	}
   691  
   692  	newMTime = regexp.MustCompile(`root.*/file.*\n`).FindString(out2)
   693  	if newMTime == originMTime {
   694  		c.Fatalf("MTime didn't change:\nOrigin:%s\nNew:%s", originMTime, newMTime)
   695  	}
   696  
   697  }
   698  
   699  func (s *DockerSuite) TestBuildSixtySteps(c *check.C) {
   700  	testRequires(c, DaemonIsLinux)
   701  	name := "foobuildsixtysteps"
   702  	ctx, err := fakeContext("FROM scratch\n"+strings.Repeat("ADD foo /\n", 60),
   703  		map[string]string{
   704  			"foo": "test1",
   705  		})
   706  	if err != nil {
   707  		c.Fatal(err)
   708  	}
   709  	defer ctx.Close()
   710  
   711  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   712  		c.Fatal(err)
   713  	}
   714  }
   715  
   716  func (s *DockerSuite) TestBuildAddSingleFileToRoot(c *check.C) {
   717  	testRequires(c, DaemonIsLinux)
   718  	name := "testaddimg"
   719  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
   720  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
   721  RUN echo 'dockerio:x:1001:' >> /etc/group
   722  RUN touch /exists
   723  RUN chown dockerio.dockerio /exists
   724  ADD test_file /
   725  RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
   726  RUN [ $(ls -l /test_file | awk '{print $1}') = '%s' ]
   727  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
   728  		map[string]string{
   729  			"test_file": "test1",
   730  		})
   731  	if err != nil {
   732  		c.Fatal(err)
   733  	}
   734  	defer ctx.Close()
   735  
   736  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   737  		c.Fatal(err)
   738  	}
   739  }
   740  
   741  // Issue #3960: "ADD src ." hangs
   742  func (s *DockerSuite) TestBuildAddSingleFileToWorkdir(c *check.C) {
   743  	testRequires(c, DaemonIsLinux)
   744  	name := "testaddsinglefiletoworkdir"
   745  	ctx, err := fakeContext(`FROM busybox
   746  ADD test_file .`,
   747  		map[string]string{
   748  			"test_file": "test1",
   749  		})
   750  	if err != nil {
   751  		c.Fatal(err)
   752  	}
   753  	defer ctx.Close()
   754  
   755  	errChan := make(chan error)
   756  	go func() {
   757  		_, err := buildImageFromContext(name, ctx, true)
   758  		errChan <- err
   759  		close(errChan)
   760  	}()
   761  	select {
   762  	case <-time.After(15 * time.Second):
   763  		c.Fatal("Build with adding to workdir timed out")
   764  	case err := <-errChan:
   765  		c.Assert(err, check.IsNil)
   766  	}
   767  }
   768  
   769  func (s *DockerSuite) TestBuildAddSingleFileToExistDir(c *check.C) {
   770  	testRequires(c, DaemonIsLinux)
   771  	name := "testaddsinglefiletoexistdir"
   772  	ctx, err := fakeContext(`FROM busybox
   773  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
   774  RUN echo 'dockerio:x:1001:' >> /etc/group
   775  RUN mkdir /exists
   776  RUN touch /exists/exists_file
   777  RUN chown -R dockerio.dockerio /exists
   778  ADD test_file /exists/
   779  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
   780  RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]
   781  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
   782  		map[string]string{
   783  			"test_file": "test1",
   784  		})
   785  	if err != nil {
   786  		c.Fatal(err)
   787  	}
   788  	defer ctx.Close()
   789  
   790  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   791  		c.Fatal(err)
   792  	}
   793  }
   794  
   795  func (s *DockerSuite) TestBuildCopyAddMultipleFiles(c *check.C) {
   796  	testRequires(c, DaemonIsLinux)
   797  	server, err := fakeStorage(map[string]string{
   798  		"robots.txt": "hello",
   799  	})
   800  	if err != nil {
   801  		c.Fatal(err)
   802  	}
   803  	defer server.Close()
   804  
   805  	name := "testcopymultiplefilestofile"
   806  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
   807  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
   808  RUN echo 'dockerio:x:1001:' >> /etc/group
   809  RUN mkdir /exists
   810  RUN touch /exists/exists_file
   811  RUN chown -R dockerio.dockerio /exists
   812  COPY test_file1 test_file2 /exists/
   813  ADD test_file3 test_file4 %s/robots.txt /exists/
   814  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
   815  RUN [ $(ls -l /exists/test_file1 | awk '{print $3":"$4}') = 'root:root' ]
   816  RUN [ $(ls -l /exists/test_file2 | awk '{print $3":"$4}') = 'root:root' ]
   817  
   818  RUN [ $(ls -l /exists/test_file3 | awk '{print $3":"$4}') = 'root:root' ]
   819  RUN [ $(ls -l /exists/test_file4 | awk '{print $3":"$4}') = 'root:root' ]
   820  RUN [ $(ls -l /exists/robots.txt | awk '{print $3":"$4}') = 'root:root' ]
   821  
   822  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
   823  `, server.URL()),
   824  		map[string]string{
   825  			"test_file1": "test1",
   826  			"test_file2": "test2",
   827  			"test_file3": "test3",
   828  			"test_file4": "test4",
   829  		})
   830  	if err != nil {
   831  		c.Fatal(err)
   832  	}
   833  	defer ctx.Close()
   834  
   835  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   836  		c.Fatal(err)
   837  	}
   838  }
   839  
   840  func (s *DockerSuite) TestBuildAddMultipleFilesToFile(c *check.C) {
   841  	testRequires(c, DaemonIsLinux)
   842  	name := "testaddmultiplefilestofile"
   843  	ctx, err := fakeContext(`FROM scratch
   844  	ADD file1.txt file2.txt test
   845  	`,
   846  		map[string]string{
   847  			"file1.txt": "test1",
   848  			"file2.txt": "test1",
   849  		})
   850  	if err != nil {
   851  		c.Fatal(err)
   852  	}
   853  	defer ctx.Close()
   854  
   855  	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
   856  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   857  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
   858  	}
   859  
   860  }
   861  
   862  func (s *DockerSuite) TestBuildJSONAddMultipleFilesToFile(c *check.C) {
   863  	testRequires(c, DaemonIsLinux)
   864  	name := "testjsonaddmultiplefilestofile"
   865  	ctx, err := fakeContext(`FROM scratch
   866  	ADD ["file1.txt", "file2.txt", "test"]
   867  	`,
   868  		map[string]string{
   869  			"file1.txt": "test1",
   870  			"file2.txt": "test1",
   871  		})
   872  	if err != nil {
   873  		c.Fatal(err)
   874  	}
   875  	defer ctx.Close()
   876  
   877  	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
   878  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   879  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
   880  	}
   881  
   882  }
   883  
   884  func (s *DockerSuite) TestBuildAddMultipleFilesToFileWild(c *check.C) {
   885  	testRequires(c, DaemonIsLinux)
   886  	name := "testaddmultiplefilestofilewild"
   887  	ctx, err := fakeContext(`FROM scratch
   888  	ADD file*.txt test
   889  	`,
   890  		map[string]string{
   891  			"file1.txt": "test1",
   892  			"file2.txt": "test1",
   893  		})
   894  	if err != nil {
   895  		c.Fatal(err)
   896  	}
   897  	defer ctx.Close()
   898  
   899  	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
   900  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   901  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
   902  	}
   903  
   904  }
   905  
   906  func (s *DockerSuite) TestBuildJSONAddMultipleFilesToFileWild(c *check.C) {
   907  	testRequires(c, DaemonIsLinux)
   908  	name := "testjsonaddmultiplefilestofilewild"
   909  	ctx, err := fakeContext(`FROM scratch
   910  	ADD ["file*.txt", "test"]
   911  	`,
   912  		map[string]string{
   913  			"file1.txt": "test1",
   914  			"file2.txt": "test1",
   915  		})
   916  	if err != nil {
   917  		c.Fatal(err)
   918  	}
   919  	defer ctx.Close()
   920  
   921  	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
   922  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   923  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
   924  	}
   925  
   926  }
   927  
   928  func (s *DockerSuite) TestBuildCopyMultipleFilesToFile(c *check.C) {
   929  	testRequires(c, DaemonIsLinux)
   930  	name := "testcopymultiplefilestofile"
   931  	ctx, err := fakeContext(`FROM scratch
   932  	COPY file1.txt file2.txt test
   933  	`,
   934  		map[string]string{
   935  			"file1.txt": "test1",
   936  			"file2.txt": "test1",
   937  		})
   938  	if err != nil {
   939  		c.Fatal(err)
   940  	}
   941  	defer ctx.Close()
   942  
   943  	expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
   944  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   945  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
   946  	}
   947  
   948  }
   949  
   950  func (s *DockerSuite) TestBuildJSONCopyMultipleFilesToFile(c *check.C) {
   951  	testRequires(c, DaemonIsLinux)
   952  	name := "testjsoncopymultiplefilestofile"
   953  	ctx, err := fakeContext(`FROM scratch
   954  	COPY ["file1.txt", "file2.txt", "test"]
   955  	`,
   956  		map[string]string{
   957  			"file1.txt": "test1",
   958  			"file2.txt": "test1",
   959  		})
   960  	if err != nil {
   961  		c.Fatal(err)
   962  	}
   963  	defer ctx.Close()
   964  
   965  	expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
   966  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   967  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
   968  	}
   969  
   970  }
   971  
   972  func (s *DockerSuite) TestBuildAddFileWithWhitespace(c *check.C) {
   973  	testRequires(c, DaemonIsLinux)
   974  	name := "testaddfilewithwhitespace"
   975  	ctx, err := fakeContext(`FROM busybox
   976  RUN mkdir "/test dir"
   977  RUN mkdir "/test_dir"
   978  ADD [ "test file1", "/test_file1" ]
   979  ADD [ "test_file2", "/test file2" ]
   980  ADD [ "test file3", "/test file3" ]
   981  ADD [ "test dir/test_file4", "/test_dir/test_file4" ]
   982  ADD [ "test_dir/test_file5", "/test dir/test_file5" ]
   983  ADD [ "test dir/test_file6", "/test dir/test_file6" ]
   984  RUN [ $(cat "/test_file1") = 'test1' ]
   985  RUN [ $(cat "/test file2") = 'test2' ]
   986  RUN [ $(cat "/test file3") = 'test3' ]
   987  RUN [ $(cat "/test_dir/test_file4") = 'test4' ]
   988  RUN [ $(cat "/test dir/test_file5") = 'test5' ]
   989  RUN [ $(cat "/test dir/test_file6") = 'test6' ]`,
   990  		map[string]string{
   991  			"test file1":          "test1",
   992  			"test_file2":          "test2",
   993  			"test file3":          "test3",
   994  			"test dir/test_file4": "test4",
   995  			"test_dir/test_file5": "test5",
   996  			"test dir/test_file6": "test6",
   997  		})
   998  	if err != nil {
   999  		c.Fatal(err)
  1000  	}
  1001  	defer ctx.Close()
  1002  
  1003  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1004  		c.Fatal(err)
  1005  	}
  1006  }
  1007  
  1008  func (s *DockerSuite) TestBuildCopyFileWithWhitespace(c *check.C) {
  1009  	testRequires(c, DaemonIsLinux)
  1010  	name := "testcopyfilewithwhitespace"
  1011  	ctx, err := fakeContext(`FROM busybox
  1012  RUN mkdir "/test dir"
  1013  RUN mkdir "/test_dir"
  1014  COPY [ "test file1", "/test_file1" ]
  1015  COPY [ "test_file2", "/test file2" ]
  1016  COPY [ "test file3", "/test file3" ]
  1017  COPY [ "test dir/test_file4", "/test_dir/test_file4" ]
  1018  COPY [ "test_dir/test_file5", "/test dir/test_file5" ]
  1019  COPY [ "test dir/test_file6", "/test dir/test_file6" ]
  1020  RUN [ $(cat "/test_file1") = 'test1' ]
  1021  RUN [ $(cat "/test file2") = 'test2' ]
  1022  RUN [ $(cat "/test file3") = 'test3' ]
  1023  RUN [ $(cat "/test_dir/test_file4") = 'test4' ]
  1024  RUN [ $(cat "/test dir/test_file5") = 'test5' ]
  1025  RUN [ $(cat "/test dir/test_file6") = 'test6' ]`,
  1026  		map[string]string{
  1027  			"test file1":          "test1",
  1028  			"test_file2":          "test2",
  1029  			"test file3":          "test3",
  1030  			"test dir/test_file4": "test4",
  1031  			"test_dir/test_file5": "test5",
  1032  			"test dir/test_file6": "test6",
  1033  		})
  1034  	if err != nil {
  1035  		c.Fatal(err)
  1036  	}
  1037  	defer ctx.Close()
  1038  
  1039  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1040  		c.Fatal(err)
  1041  	}
  1042  }
  1043  
  1044  func (s *DockerSuite) TestBuildAddMultipleFilesToFileWithWhitespace(c *check.C) {
  1045  	testRequires(c, DaemonIsLinux)
  1046  	name := "testaddmultiplefilestofilewithwhitespace"
  1047  	ctx, err := fakeContext(`FROM busybox
  1048  	ADD [ "test file1", "test file2", "test" ]
  1049      `,
  1050  		map[string]string{
  1051  			"test file1": "test1",
  1052  			"test file2": "test2",
  1053  		})
  1054  	if err != nil {
  1055  		c.Fatal(err)
  1056  	}
  1057  	defer ctx.Close()
  1058  
  1059  	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
  1060  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  1061  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  1062  	}
  1063  
  1064  }
  1065  
  1066  func (s *DockerSuite) TestBuildCopyMultipleFilesToFileWithWhitespace(c *check.C) {
  1067  	testRequires(c, DaemonIsLinux)
  1068  	name := "testcopymultiplefilestofilewithwhitespace"
  1069  	ctx, err := fakeContext(`FROM busybox
  1070  	COPY [ "test file1", "test file2", "test" ]
  1071          `,
  1072  		map[string]string{
  1073  			"test file1": "test1",
  1074  			"test file2": "test2",
  1075  		})
  1076  	if err != nil {
  1077  		c.Fatal(err)
  1078  	}
  1079  	defer ctx.Close()
  1080  
  1081  	expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
  1082  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  1083  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  1084  	}
  1085  
  1086  }
  1087  
  1088  func (s *DockerSuite) TestBuildCopyWildcard(c *check.C) {
  1089  	testRequires(c, DaemonIsLinux)
  1090  	name := "testcopywildcard"
  1091  	server, err := fakeStorage(map[string]string{
  1092  		"robots.txt": "hello",
  1093  		"index.html": "world",
  1094  	})
  1095  	if err != nil {
  1096  		c.Fatal(err)
  1097  	}
  1098  	defer server.Close()
  1099  
  1100  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1101  	COPY file*.txt /tmp/
  1102  	RUN ls /tmp/file1.txt /tmp/file2.txt
  1103  	RUN mkdir /tmp1
  1104  	COPY dir* /tmp1/
  1105  	RUN ls /tmp1/dirt /tmp1/nested_file /tmp1/nested_dir/nest_nest_file
  1106  	RUN mkdir /tmp2
  1107          ADD dir/*dir %s/robots.txt /tmp2/
  1108  	RUN ls /tmp2/nest_nest_file /tmp2/robots.txt
  1109  	`, server.URL()),
  1110  		map[string]string{
  1111  			"file1.txt":                     "test1",
  1112  			"file2.txt":                     "test2",
  1113  			"dir/nested_file":               "nested file",
  1114  			"dir/nested_dir/nest_nest_file": "2 times nested",
  1115  			"dirt": "dirty",
  1116  		})
  1117  	if err != nil {
  1118  		c.Fatal(err)
  1119  	}
  1120  	defer ctx.Close()
  1121  
  1122  	id1, err := buildImageFromContext(name, ctx, true)
  1123  	if err != nil {
  1124  		c.Fatal(err)
  1125  	}
  1126  
  1127  	// Now make sure we use a cache the 2nd time
  1128  	id2, err := buildImageFromContext(name, ctx, true)
  1129  	if err != nil {
  1130  		c.Fatal(err)
  1131  	}
  1132  
  1133  	if id1 != id2 {
  1134  		c.Fatal("didn't use the cache")
  1135  	}
  1136  
  1137  }
  1138  
  1139  func (s *DockerSuite) TestBuildCopyWildcardNoFind(c *check.C) {
  1140  	testRequires(c, DaemonIsLinux)
  1141  	name := "testcopywildcardnofind"
  1142  	ctx, err := fakeContext(`FROM busybox
  1143  	COPY file*.txt /tmp/
  1144  	`, nil)
  1145  	if err != nil {
  1146  		c.Fatal(err)
  1147  	}
  1148  	defer ctx.Close()
  1149  
  1150  	_, err = buildImageFromContext(name, ctx, true)
  1151  	if err == nil {
  1152  		c.Fatal("should have failed to find a file")
  1153  	}
  1154  	if !strings.Contains(err.Error(), "No source files were specified") {
  1155  		c.Fatalf("Wrong error %v, must be about no source files", err)
  1156  	}
  1157  
  1158  }
  1159  
  1160  func (s *DockerSuite) TestBuildCopyWildcardInName(c *check.C) {
  1161  	testRequires(c, DaemonIsLinux)
  1162  	name := "testcopywildcardinname"
  1163  	ctx, err := fakeContext(`FROM busybox
  1164  	COPY *.txt /tmp/
  1165  	RUN [ "$(cat /tmp/\*.txt)" = 'hi there' ]
  1166  	`, map[string]string{"*.txt": "hi there"})
  1167  
  1168  	if err != nil {
  1169  		// Normally we would do c.Fatal(err) here but given that
  1170  		// the odds of this failing are so rare, it must be because
  1171  		// the OS we're running the client on doesn't support * in
  1172  		// filenames (like windows).  So, instead of failing the test
  1173  		// just let it pass. Then we don't need to explicitly
  1174  		// say which OSs this works on or not.
  1175  		return
  1176  	}
  1177  	defer ctx.Close()
  1178  
  1179  	_, err = buildImageFromContext(name, ctx, true)
  1180  	if err != nil {
  1181  		c.Fatalf("should have built: %q", err)
  1182  	}
  1183  }
  1184  
  1185  func (s *DockerSuite) TestBuildCopyWildcardCache(c *check.C) {
  1186  	testRequires(c, DaemonIsLinux)
  1187  	name := "testcopywildcardcache"
  1188  	ctx, err := fakeContext(`FROM busybox
  1189  	COPY file1.txt /tmp/`,
  1190  		map[string]string{
  1191  			"file1.txt": "test1",
  1192  		})
  1193  	if err != nil {
  1194  		c.Fatal(err)
  1195  	}
  1196  	defer ctx.Close()
  1197  
  1198  	id1, err := buildImageFromContext(name, ctx, true)
  1199  	if err != nil {
  1200  		c.Fatal(err)
  1201  	}
  1202  
  1203  	// Now make sure we use a cache the 2nd time even with wild cards.
  1204  	// Use the same context so the file is the same and the checksum will match
  1205  	ctx.Add("Dockerfile", `FROM busybox
  1206  	COPY file*.txt /tmp/`)
  1207  
  1208  	id2, err := buildImageFromContext(name, ctx, true)
  1209  	if err != nil {
  1210  		c.Fatal(err)
  1211  	}
  1212  
  1213  	if id1 != id2 {
  1214  		c.Fatal("didn't use the cache")
  1215  	}
  1216  
  1217  }
  1218  
  1219  func (s *DockerSuite) TestBuildAddSingleFileToNonExistingDir(c *check.C) {
  1220  	testRequires(c, DaemonIsLinux)
  1221  	name := "testaddsinglefiletononexistingdir"
  1222  	ctx, err := fakeContext(`FROM busybox
  1223  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1224  RUN echo 'dockerio:x:1001:' >> /etc/group
  1225  RUN touch /exists
  1226  RUN chown dockerio.dockerio /exists
  1227  ADD test_file /test_dir/
  1228  RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1229  RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1230  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1231  		map[string]string{
  1232  			"test_file": "test1",
  1233  		})
  1234  	if err != nil {
  1235  		c.Fatal(err)
  1236  	}
  1237  	defer ctx.Close()
  1238  
  1239  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1240  		c.Fatal(err)
  1241  	}
  1242  
  1243  }
  1244  
  1245  func (s *DockerSuite) TestBuildAddDirContentToRoot(c *check.C) {
  1246  	testRequires(c, DaemonIsLinux)
  1247  	name := "testadddircontenttoroot"
  1248  	ctx, err := fakeContext(`FROM busybox
  1249  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1250  RUN echo 'dockerio:x:1001:' >> /etc/group
  1251  RUN touch /exists
  1252  RUN chown dockerio.dockerio exists
  1253  ADD test_dir /
  1254  RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1255  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1256  		map[string]string{
  1257  			"test_dir/test_file": "test1",
  1258  		})
  1259  	if err != nil {
  1260  		c.Fatal(err)
  1261  	}
  1262  	defer ctx.Close()
  1263  
  1264  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1265  		c.Fatal(err)
  1266  	}
  1267  }
  1268  
  1269  func (s *DockerSuite) TestBuildAddDirContentToExistingDir(c *check.C) {
  1270  	testRequires(c, DaemonIsLinux)
  1271  	name := "testadddircontenttoexistingdir"
  1272  	ctx, err := fakeContext(`FROM busybox
  1273  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1274  RUN echo 'dockerio:x:1001:' >> /etc/group
  1275  RUN mkdir /exists
  1276  RUN touch /exists/exists_file
  1277  RUN chown -R dockerio.dockerio /exists
  1278  ADD test_dir/ /exists/
  1279  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1280  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1281  RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`,
  1282  		map[string]string{
  1283  			"test_dir/test_file": "test1",
  1284  		})
  1285  	if err != nil {
  1286  		c.Fatal(err)
  1287  	}
  1288  	defer ctx.Close()
  1289  
  1290  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1291  		c.Fatal(err)
  1292  	}
  1293  }
  1294  
  1295  func (s *DockerSuite) TestBuildAddWholeDirToRoot(c *check.C) {
  1296  	testRequires(c, DaemonIsLinux)
  1297  	name := "testaddwholedirtoroot"
  1298  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1299  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1300  RUN echo 'dockerio:x:1001:' >> /etc/group
  1301  RUN touch /exists
  1302  RUN chown dockerio.dockerio exists
  1303  ADD test_dir /test_dir
  1304  RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1305  RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ]
  1306  RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1307  RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '%s' ]
  1308  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  1309  		map[string]string{
  1310  			"test_dir/test_file": "test1",
  1311  		})
  1312  	if err != nil {
  1313  		c.Fatal(err)
  1314  	}
  1315  	defer ctx.Close()
  1316  
  1317  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1318  		c.Fatal(err)
  1319  	}
  1320  }
  1321  
  1322  // Testing #5941
  1323  func (s *DockerSuite) TestBuildAddEtcToRoot(c *check.C) {
  1324  	testRequires(c, DaemonIsLinux)
  1325  	name := "testaddetctoroot"
  1326  	ctx, err := fakeContext(`FROM scratch
  1327  ADD . /`,
  1328  		map[string]string{
  1329  			"etc/test_file": "test1",
  1330  		})
  1331  	if err != nil {
  1332  		c.Fatal(err)
  1333  	}
  1334  	defer ctx.Close()
  1335  
  1336  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1337  		c.Fatal(err)
  1338  	}
  1339  }
  1340  
  1341  // Testing #9401
  1342  func (s *DockerSuite) TestBuildAddPreservesFilesSpecialBits(c *check.C) {
  1343  	testRequires(c, DaemonIsLinux)
  1344  	name := "testaddpreservesfilesspecialbits"
  1345  	ctx, err := fakeContext(`FROM busybox
  1346  ADD suidbin /usr/bin/suidbin
  1347  RUN chmod 4755 /usr/bin/suidbin
  1348  RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ]
  1349  ADD ./data/ /
  1350  RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ]`,
  1351  		map[string]string{
  1352  			"suidbin":             "suidbin",
  1353  			"/data/usr/test_file": "test1",
  1354  		})
  1355  	if err != nil {
  1356  		c.Fatal(err)
  1357  	}
  1358  	defer ctx.Close()
  1359  
  1360  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1361  		c.Fatal(err)
  1362  	}
  1363  }
  1364  
  1365  func (s *DockerSuite) TestBuildCopySingleFileToRoot(c *check.C) {
  1366  	testRequires(c, DaemonIsLinux)
  1367  	name := "testcopysinglefiletoroot"
  1368  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1369  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1370  RUN echo 'dockerio:x:1001:' >> /etc/group
  1371  RUN touch /exists
  1372  RUN chown dockerio.dockerio /exists
  1373  COPY test_file /
  1374  RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1375  RUN [ $(ls -l /test_file | awk '{print $1}') = '%s' ]
  1376  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  1377  		map[string]string{
  1378  			"test_file": "test1",
  1379  		})
  1380  	if err != nil {
  1381  		c.Fatal(err)
  1382  	}
  1383  	defer ctx.Close()
  1384  
  1385  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1386  		c.Fatal(err)
  1387  	}
  1388  }
  1389  
  1390  // Issue #3960: "ADD src ." hangs - adapted for COPY
  1391  func (s *DockerSuite) TestBuildCopySingleFileToWorkdir(c *check.C) {
  1392  	testRequires(c, DaemonIsLinux)
  1393  	name := "testcopysinglefiletoworkdir"
  1394  	ctx, err := fakeContext(`FROM busybox
  1395  COPY test_file .`,
  1396  		map[string]string{
  1397  			"test_file": "test1",
  1398  		})
  1399  	if err != nil {
  1400  		c.Fatal(err)
  1401  	}
  1402  	defer ctx.Close()
  1403  
  1404  	errChan := make(chan error)
  1405  	go func() {
  1406  		_, err := buildImageFromContext(name, ctx, true)
  1407  		errChan <- err
  1408  		close(errChan)
  1409  	}()
  1410  	select {
  1411  	case <-time.After(15 * time.Second):
  1412  		c.Fatal("Build with adding to workdir timed out")
  1413  	case err := <-errChan:
  1414  		c.Assert(err, check.IsNil)
  1415  	}
  1416  }
  1417  
  1418  func (s *DockerSuite) TestBuildCopySingleFileToExistDir(c *check.C) {
  1419  	testRequires(c, DaemonIsLinux)
  1420  	name := "testcopysinglefiletoexistdir"
  1421  	ctx, err := fakeContext(`FROM busybox
  1422  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1423  RUN echo 'dockerio:x:1001:' >> /etc/group
  1424  RUN mkdir /exists
  1425  RUN touch /exists/exists_file
  1426  RUN chown -R dockerio.dockerio /exists
  1427  COPY test_file /exists/
  1428  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1429  RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1430  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1431  		map[string]string{
  1432  			"test_file": "test1",
  1433  		})
  1434  	if err != nil {
  1435  		c.Fatal(err)
  1436  	}
  1437  	defer ctx.Close()
  1438  
  1439  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1440  		c.Fatal(err)
  1441  	}
  1442  }
  1443  
  1444  func (s *DockerSuite) TestBuildCopySingleFileToNonExistDir(c *check.C) {
  1445  	testRequires(c, DaemonIsLinux)
  1446  	name := "testcopysinglefiletononexistdir"
  1447  	ctx, err := fakeContext(`FROM busybox
  1448  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1449  RUN echo 'dockerio:x:1001:' >> /etc/group
  1450  RUN touch /exists
  1451  RUN chown dockerio.dockerio /exists
  1452  COPY test_file /test_dir/
  1453  RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1454  RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1455  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1456  		map[string]string{
  1457  			"test_file": "test1",
  1458  		})
  1459  	if err != nil {
  1460  		c.Fatal(err)
  1461  	}
  1462  	defer ctx.Close()
  1463  
  1464  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1465  		c.Fatal(err)
  1466  	}
  1467  }
  1468  
  1469  func (s *DockerSuite) TestBuildCopyDirContentToRoot(c *check.C) {
  1470  	testRequires(c, DaemonIsLinux)
  1471  	name := "testcopydircontenttoroot"
  1472  	ctx, err := fakeContext(`FROM busybox
  1473  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1474  RUN echo 'dockerio:x:1001:' >> /etc/group
  1475  RUN touch /exists
  1476  RUN chown dockerio.dockerio exists
  1477  COPY test_dir /
  1478  RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1479  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1480  		map[string]string{
  1481  			"test_dir/test_file": "test1",
  1482  		})
  1483  	if err != nil {
  1484  		c.Fatal(err)
  1485  	}
  1486  	defer ctx.Close()
  1487  
  1488  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1489  		c.Fatal(err)
  1490  	}
  1491  }
  1492  
  1493  func (s *DockerSuite) TestBuildCopyDirContentToExistDir(c *check.C) {
  1494  	testRequires(c, DaemonIsLinux)
  1495  	name := "testcopydircontenttoexistdir"
  1496  	ctx, err := fakeContext(`FROM busybox
  1497  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1498  RUN echo 'dockerio:x:1001:' >> /etc/group
  1499  RUN mkdir /exists
  1500  RUN touch /exists/exists_file
  1501  RUN chown -R dockerio.dockerio /exists
  1502  COPY test_dir/ /exists/
  1503  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1504  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1505  RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`,
  1506  		map[string]string{
  1507  			"test_dir/test_file": "test1",
  1508  		})
  1509  	if err != nil {
  1510  		c.Fatal(err)
  1511  	}
  1512  	defer ctx.Close()
  1513  
  1514  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1515  		c.Fatal(err)
  1516  	}
  1517  }
  1518  
  1519  func (s *DockerSuite) TestBuildCopyWholeDirToRoot(c *check.C) {
  1520  	testRequires(c, DaemonIsLinux)
  1521  	name := "testcopywholedirtoroot"
  1522  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1523  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1524  RUN echo 'dockerio:x:1001:' >> /etc/group
  1525  RUN touch /exists
  1526  RUN chown dockerio.dockerio exists
  1527  COPY test_dir /test_dir
  1528  RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1529  RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ]
  1530  RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1531  RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '%s' ]
  1532  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  1533  		map[string]string{
  1534  			"test_dir/test_file": "test1",
  1535  		})
  1536  	if err != nil {
  1537  		c.Fatal(err)
  1538  	}
  1539  	defer ctx.Close()
  1540  
  1541  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1542  		c.Fatal(err)
  1543  	}
  1544  }
  1545  
  1546  func (s *DockerSuite) TestBuildCopyEtcToRoot(c *check.C) {
  1547  	testRequires(c, DaemonIsLinux)
  1548  	name := "testcopyetctoroot"
  1549  	ctx, err := fakeContext(`FROM scratch
  1550  COPY . /`,
  1551  		map[string]string{
  1552  			"etc/test_file": "test1",
  1553  		})
  1554  	if err != nil {
  1555  		c.Fatal(err)
  1556  	}
  1557  	defer ctx.Close()
  1558  
  1559  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1560  		c.Fatal(err)
  1561  	}
  1562  }
  1563  
  1564  func (s *DockerSuite) TestBuildCopyDisallowRemote(c *check.C) {
  1565  	testRequires(c, DaemonIsLinux)
  1566  	name := "testcopydisallowremote"
  1567  	_, out, err := buildImageWithOut(name, `FROM scratch
  1568  COPY https://index.docker.io/robots.txt /`,
  1569  		true)
  1570  	if err == nil || !strings.Contains(out, "Source can't be a URL for COPY") {
  1571  		c.Fatalf("Error should be about disallowed remote source, got err: %s, out: %q", err, out)
  1572  	}
  1573  }
  1574  
  1575  func (s *DockerSuite) TestBuildAddBadLinks(c *check.C) {
  1576  	testRequires(c, DaemonIsLinux)
  1577  	const (
  1578  		dockerfile = `
  1579  			FROM scratch
  1580  			ADD links.tar /
  1581  			ADD foo.txt /symlink/
  1582  			`
  1583  		targetFile = "foo.txt"
  1584  	)
  1585  	var (
  1586  		name = "test-link-absolute"
  1587  	)
  1588  	ctx, err := fakeContext(dockerfile, nil)
  1589  	if err != nil {
  1590  		c.Fatal(err)
  1591  	}
  1592  	defer ctx.Close()
  1593  
  1594  	tempDir, err := ioutil.TempDir("", "test-link-absolute-temp-")
  1595  	if err != nil {
  1596  		c.Fatalf("failed to create temporary directory: %s", tempDir)
  1597  	}
  1598  	defer os.RemoveAll(tempDir)
  1599  
  1600  	var symlinkTarget string
  1601  	if runtime.GOOS == "windows" {
  1602  		var driveLetter string
  1603  		if abs, err := filepath.Abs(tempDir); err != nil {
  1604  			c.Fatal(err)
  1605  		} else {
  1606  			driveLetter = abs[:1]
  1607  		}
  1608  		tempDirWithoutDrive := tempDir[2:]
  1609  		symlinkTarget = fmt.Sprintf(`%s:\..\..\..\..\..\..\..\..\..\..\..\..%s`, driveLetter, tempDirWithoutDrive)
  1610  	} else {
  1611  		symlinkTarget = fmt.Sprintf("/../../../../../../../../../../../..%s", tempDir)
  1612  	}
  1613  
  1614  	tarPath := filepath.Join(ctx.Dir, "links.tar")
  1615  	nonExistingFile := filepath.Join(tempDir, targetFile)
  1616  	fooPath := filepath.Join(ctx.Dir, targetFile)
  1617  
  1618  	tarOut, err := os.Create(tarPath)
  1619  	if err != nil {
  1620  		c.Fatal(err)
  1621  	}
  1622  
  1623  	tarWriter := tar.NewWriter(tarOut)
  1624  
  1625  	header := &tar.Header{
  1626  		Name:     "symlink",
  1627  		Typeflag: tar.TypeSymlink,
  1628  		Linkname: symlinkTarget,
  1629  		Mode:     0755,
  1630  		Uid:      0,
  1631  		Gid:      0,
  1632  	}
  1633  
  1634  	err = tarWriter.WriteHeader(header)
  1635  	if err != nil {
  1636  		c.Fatal(err)
  1637  	}
  1638  
  1639  	tarWriter.Close()
  1640  	tarOut.Close()
  1641  
  1642  	foo, err := os.Create(fooPath)
  1643  	if err != nil {
  1644  		c.Fatal(err)
  1645  	}
  1646  	defer foo.Close()
  1647  
  1648  	if _, err := foo.WriteString("test"); err != nil {
  1649  		c.Fatal(err)
  1650  	}
  1651  
  1652  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1653  		c.Fatal(err)
  1654  	}
  1655  
  1656  	if _, err := os.Stat(nonExistingFile); err == nil || err != nil && !os.IsNotExist(err) {
  1657  		c.Fatalf("%s shouldn't have been written and it shouldn't exist", nonExistingFile)
  1658  	}
  1659  
  1660  }
  1661  
  1662  func (s *DockerSuite) TestBuildAddBadLinksVolume(c *check.C) {
  1663  	testRequires(c, DaemonIsLinux)
  1664  	const (
  1665  		dockerfileTemplate = `
  1666  		FROM busybox
  1667  		RUN ln -s /../../../../../../../../%s /x
  1668  		VOLUME /x
  1669  		ADD foo.txt /x/`
  1670  		targetFile = "foo.txt"
  1671  	)
  1672  	var (
  1673  		name       = "test-link-absolute-volume"
  1674  		dockerfile = ""
  1675  	)
  1676  
  1677  	tempDir, err := ioutil.TempDir("", "test-link-absolute-volume-temp-")
  1678  	if err != nil {
  1679  		c.Fatalf("failed to create temporary directory: %s", tempDir)
  1680  	}
  1681  	defer os.RemoveAll(tempDir)
  1682  
  1683  	dockerfile = fmt.Sprintf(dockerfileTemplate, tempDir)
  1684  	nonExistingFile := filepath.Join(tempDir, targetFile)
  1685  
  1686  	ctx, err := fakeContext(dockerfile, nil)
  1687  	if err != nil {
  1688  		c.Fatal(err)
  1689  	}
  1690  	defer ctx.Close()
  1691  	fooPath := filepath.Join(ctx.Dir, targetFile)
  1692  
  1693  	foo, err := os.Create(fooPath)
  1694  	if err != nil {
  1695  		c.Fatal(err)
  1696  	}
  1697  	defer foo.Close()
  1698  
  1699  	if _, err := foo.WriteString("test"); err != nil {
  1700  		c.Fatal(err)
  1701  	}
  1702  
  1703  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1704  		c.Fatal(err)
  1705  	}
  1706  
  1707  	if _, err := os.Stat(nonExistingFile); err == nil || err != nil && !os.IsNotExist(err) {
  1708  		c.Fatalf("%s shouldn't have been written and it shouldn't exist", nonExistingFile)
  1709  	}
  1710  
  1711  }
  1712  
  1713  // Issue #5270 - ensure we throw a better error than "unexpected EOF"
  1714  // when we can't access files in the context.
  1715  func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) {
  1716  	testRequires(c, DaemonIsLinux)
  1717  	testRequires(c, UnixCli) // test uses chown/chmod: not available on windows
  1718  
  1719  	{
  1720  		name := "testbuildinaccessiblefiles"
  1721  		ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{"fileWithoutReadAccess": "foo"})
  1722  		if err != nil {
  1723  			c.Fatal(err)
  1724  		}
  1725  		defer ctx.Close()
  1726  		// This is used to ensure we detect inaccessible files early during build in the cli client
  1727  		pathToFileWithoutReadAccess := filepath.Join(ctx.Dir, "fileWithoutReadAccess")
  1728  
  1729  		if err = os.Chown(pathToFileWithoutReadAccess, 0, 0); err != nil {
  1730  			c.Fatalf("failed to chown file to root: %s", err)
  1731  		}
  1732  		if err = os.Chmod(pathToFileWithoutReadAccess, 0700); err != nil {
  1733  			c.Fatalf("failed to chmod file to 700: %s", err)
  1734  		}
  1735  		buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1736  		buildCmd.Dir = ctx.Dir
  1737  		out, _, err := runCommandWithOutput(buildCmd)
  1738  		if err == nil {
  1739  			c.Fatalf("build should have failed: %s %s", err, out)
  1740  		}
  1741  
  1742  		// check if we've detected the failure before we started building
  1743  		if !strings.Contains(out, "no permission to read from ") {
  1744  			c.Fatalf("output should've contained the string: no permission to read from but contained: %s", out)
  1745  		}
  1746  
  1747  		if !strings.Contains(out, "Error checking context") {
  1748  			c.Fatalf("output should've contained the string: Error checking context")
  1749  		}
  1750  	}
  1751  	{
  1752  		name := "testbuildinaccessibledirectory"
  1753  		ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{"directoryWeCantStat/bar": "foo"})
  1754  		if err != nil {
  1755  			c.Fatal(err)
  1756  		}
  1757  		defer ctx.Close()
  1758  		// This is used to ensure we detect inaccessible directories early during build in the cli client
  1759  		pathToDirectoryWithoutReadAccess := filepath.Join(ctx.Dir, "directoryWeCantStat")
  1760  		pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar")
  1761  
  1762  		if err = os.Chown(pathToDirectoryWithoutReadAccess, 0, 0); err != nil {
  1763  			c.Fatalf("failed to chown directory to root: %s", err)
  1764  		}
  1765  		if err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444); err != nil {
  1766  			c.Fatalf("failed to chmod directory to 444: %s", err)
  1767  		}
  1768  		if err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700); err != nil {
  1769  			c.Fatalf("failed to chmod file to 700: %s", err)
  1770  		}
  1771  
  1772  		buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1773  		buildCmd.Dir = ctx.Dir
  1774  		out, _, err := runCommandWithOutput(buildCmd)
  1775  		if err == nil {
  1776  			c.Fatalf("build should have failed: %s %s", err, out)
  1777  		}
  1778  
  1779  		// check if we've detected the failure before we started building
  1780  		if !strings.Contains(out, "can't stat") {
  1781  			c.Fatalf("output should've contained the string: can't access %s", out)
  1782  		}
  1783  
  1784  		if !strings.Contains(out, "Error checking context") {
  1785  			c.Fatalf("output should've contained the string: Error checking context\ngot:%s", out)
  1786  		}
  1787  
  1788  	}
  1789  	{
  1790  		name := "testlinksok"
  1791  		ctx, err := fakeContext("FROM scratch\nADD . /foo/", nil)
  1792  		if err != nil {
  1793  			c.Fatal(err)
  1794  		}
  1795  		defer ctx.Close()
  1796  
  1797  		target := "../../../../../../../../../../../../../../../../../../../azA"
  1798  		if err := os.Symlink(filepath.Join(ctx.Dir, "g"), target); err != nil {
  1799  			c.Fatal(err)
  1800  		}
  1801  		defer os.Remove(target)
  1802  		// This is used to ensure we don't follow links when checking if everything in the context is accessible
  1803  		// This test doesn't require that we run commands as an unprivileged user
  1804  		if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1805  			c.Fatal(err)
  1806  		}
  1807  	}
  1808  	{
  1809  		name := "testbuildignoredinaccessible"
  1810  		ctx, err := fakeContext("FROM scratch\nADD . /foo/",
  1811  			map[string]string{
  1812  				"directoryWeCantStat/bar": "foo",
  1813  				".dockerignore":           "directoryWeCantStat",
  1814  			})
  1815  		if err != nil {
  1816  			c.Fatal(err)
  1817  		}
  1818  		defer ctx.Close()
  1819  		// This is used to ensure we don't try to add inaccessible files when they are ignored by a .dockerignore pattern
  1820  		pathToDirectoryWithoutReadAccess := filepath.Join(ctx.Dir, "directoryWeCantStat")
  1821  		pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar")
  1822  		if err = os.Chown(pathToDirectoryWithoutReadAccess, 0, 0); err != nil {
  1823  			c.Fatalf("failed to chown directory to root: %s", err)
  1824  		}
  1825  		if err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444); err != nil {
  1826  			c.Fatalf("failed to chmod directory to 755: %s", err)
  1827  		}
  1828  		if err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700); err != nil {
  1829  			c.Fatalf("failed to chmod file to 444: %s", err)
  1830  		}
  1831  
  1832  		buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1833  		buildCmd.Dir = ctx.Dir
  1834  		if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  1835  			c.Fatalf("build should have worked: %s %s", err, out)
  1836  		}
  1837  
  1838  	}
  1839  }
  1840  
  1841  func (s *DockerSuite) TestBuildForceRm(c *check.C) {
  1842  	testRequires(c, DaemonIsLinux)
  1843  	containerCountBefore, err := getContainerCount()
  1844  	if err != nil {
  1845  		c.Fatalf("failed to get the container count: %s", err)
  1846  	}
  1847  	name := "testbuildforcerm"
  1848  	ctx, err := fakeContext("FROM scratch\nRUN true\nRUN thiswillfail", nil)
  1849  	if err != nil {
  1850  		c.Fatal(err)
  1851  	}
  1852  	defer ctx.Close()
  1853  
  1854  	dockerCmdInDir(c, ctx.Dir, "build", "-t", name, "--force-rm", ".")
  1855  
  1856  	containerCountAfter, err := getContainerCount()
  1857  	if err != nil {
  1858  		c.Fatalf("failed to get the container count: %s", err)
  1859  	}
  1860  
  1861  	if containerCountBefore != containerCountAfter {
  1862  		c.Fatalf("--force-rm shouldn't have left containers behind")
  1863  	}
  1864  
  1865  }
  1866  
  1867  // Test that an infinite sleep during a build is killed if the client disconnects.
  1868  // This test is fairly hairy because there are lots of ways to race.
  1869  // Strategy:
  1870  // * Monitor the output of docker events starting from before
  1871  // * Run a 1-year-long sleep from a docker build.
  1872  // * When docker events sees container start, close the "docker build" command
  1873  // * Wait for docker events to emit a dying event.
  1874  func (s *DockerSuite) TestBuildCancellationKillsSleep(c *check.C) {
  1875  	testRequires(c, DaemonIsLinux)
  1876  	name := "testbuildcancellation"
  1877  
  1878  	// (Note: one year, will never finish)
  1879  	ctx, err := fakeContext("FROM busybox\nRUN sleep 31536000", nil)
  1880  	if err != nil {
  1881  		c.Fatal(err)
  1882  	}
  1883  	defer ctx.Close()
  1884  
  1885  	finish := make(chan struct{})
  1886  	defer close(finish)
  1887  
  1888  	eventStart := make(chan struct{})
  1889  	eventDie := make(chan struct{})
  1890  	containerID := make(chan string)
  1891  
  1892  	startEpoch := daemonTime(c).Unix()
  1893  	// Watch for events since epoch.
  1894  	eventsCmd := exec.Command(dockerBinary, "events", "--since", strconv.FormatInt(startEpoch, 10))
  1895  	stdout, err := eventsCmd.StdoutPipe()
  1896  	if err != nil {
  1897  		c.Fatal(err)
  1898  	}
  1899  	if err := eventsCmd.Start(); err != nil {
  1900  		c.Fatal(err)
  1901  	}
  1902  	defer eventsCmd.Process.Kill()
  1903  
  1904  	// Goroutine responsible for watching start/die events from `docker events`
  1905  	go func() {
  1906  		cid := <-containerID
  1907  
  1908  		matchStart := regexp.MustCompile(cid + `(.*) start$`)
  1909  		matchDie := regexp.MustCompile(cid + `(.*) die$`)
  1910  
  1911  		//
  1912  		// Read lines of `docker events` looking for container start and stop.
  1913  		//
  1914  		scanner := bufio.NewScanner(stdout)
  1915  		for scanner.Scan() {
  1916  			switch {
  1917  			case matchStart.MatchString(scanner.Text()):
  1918  				close(eventStart)
  1919  			case matchDie.MatchString(scanner.Text()):
  1920  				close(eventDie)
  1921  			}
  1922  		}
  1923  	}()
  1924  
  1925  	buildCmd := exec.Command(dockerBinary, "build", "-t", name, ".")
  1926  	buildCmd.Dir = ctx.Dir
  1927  
  1928  	stdoutBuild, err := buildCmd.StdoutPipe()
  1929  	if err := buildCmd.Start(); err != nil {
  1930  		c.Fatalf("failed to run build: %s", err)
  1931  	}
  1932  
  1933  	matchCID := regexp.MustCompile("Running in (.+)")
  1934  	scanner := bufio.NewScanner(stdoutBuild)
  1935  	for scanner.Scan() {
  1936  		line := scanner.Text()
  1937  		if matches := matchCID.FindStringSubmatch(line); len(matches) > 0 {
  1938  			containerID <- matches[1]
  1939  			break
  1940  		}
  1941  	}
  1942  
  1943  	select {
  1944  	case <-time.After(5 * time.Second):
  1945  		c.Fatal("failed to observe build container start in timely fashion")
  1946  	case <-eventStart:
  1947  		// Proceeds from here when we see the container fly past in the
  1948  		// output of "docker events".
  1949  		// Now we know the container is running.
  1950  	}
  1951  
  1952  	// Send a kill to the `docker build` command.
  1953  	// Causes the underlying build to be cancelled due to socket close.
  1954  	if err := buildCmd.Process.Kill(); err != nil {
  1955  		c.Fatalf("error killing build command: %s", err)
  1956  	}
  1957  
  1958  	// Get the exit status of `docker build`, check it exited because killed.
  1959  	if err := buildCmd.Wait(); err != nil && !isKilled(err) {
  1960  		c.Fatalf("wait failed during build run: %T %s", err, err)
  1961  	}
  1962  
  1963  	select {
  1964  	case <-time.After(5 * time.Second):
  1965  		// If we don't get here in a timely fashion, it wasn't killed.
  1966  		c.Fatal("container cancel did not succeed")
  1967  	case <-eventDie:
  1968  		// We saw the container shut down in the `docker events` stream,
  1969  		// as expected.
  1970  	}
  1971  
  1972  }
  1973  
  1974  func (s *DockerSuite) TestBuildRm(c *check.C) {
  1975  	testRequires(c, DaemonIsLinux)
  1976  	name := "testbuildrm"
  1977  	ctx, err := fakeContext("FROM scratch\nADD foo /\nADD foo /", map[string]string{"foo": "bar"})
  1978  	if err != nil {
  1979  		c.Fatal(err)
  1980  	}
  1981  	defer ctx.Close()
  1982  	{
  1983  		containerCountBefore, err := getContainerCount()
  1984  		if err != nil {
  1985  			c.Fatalf("failed to get the container count: %s", err)
  1986  		}
  1987  
  1988  		out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--rm", "-t", name, ".")
  1989  
  1990  		if err != nil {
  1991  			c.Fatal("failed to build the image", out)
  1992  		}
  1993  
  1994  		containerCountAfter, err := getContainerCount()
  1995  		if err != nil {
  1996  			c.Fatalf("failed to get the container count: %s", err)
  1997  		}
  1998  
  1999  		if containerCountBefore != containerCountAfter {
  2000  			c.Fatalf("-rm shouldn't have left containers behind")
  2001  		}
  2002  		deleteImages(name)
  2003  	}
  2004  
  2005  	{
  2006  		containerCountBefore, err := getContainerCount()
  2007  		if err != nil {
  2008  			c.Fatalf("failed to get the container count: %s", err)
  2009  		}
  2010  
  2011  		out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", name, ".")
  2012  
  2013  		if err != nil {
  2014  			c.Fatal("failed to build the image", out)
  2015  		}
  2016  
  2017  		containerCountAfter, err := getContainerCount()
  2018  		if err != nil {
  2019  			c.Fatalf("failed to get the container count: %s", err)
  2020  		}
  2021  
  2022  		if containerCountBefore != containerCountAfter {
  2023  			c.Fatalf("--rm shouldn't have left containers behind")
  2024  		}
  2025  		deleteImages(name)
  2026  	}
  2027  
  2028  	{
  2029  		containerCountBefore, err := getContainerCount()
  2030  		if err != nil {
  2031  			c.Fatalf("failed to get the container count: %s", err)
  2032  		}
  2033  
  2034  		out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--rm=false", "-t", name, ".")
  2035  
  2036  		if err != nil {
  2037  			c.Fatal("failed to build the image", out)
  2038  		}
  2039  
  2040  		containerCountAfter, err := getContainerCount()
  2041  		if err != nil {
  2042  			c.Fatalf("failed to get the container count: %s", err)
  2043  		}
  2044  
  2045  		if containerCountBefore == containerCountAfter {
  2046  			c.Fatalf("--rm=false should have left containers behind")
  2047  		}
  2048  		deleteImages(name)
  2049  
  2050  	}
  2051  
  2052  }
  2053  
  2054  func (s *DockerSuite) TestBuildWithVolumes(c *check.C) {
  2055  	testRequires(c, DaemonIsLinux)
  2056  	var (
  2057  		result   map[string]map[string]struct{}
  2058  		name     = "testbuildvolumes"
  2059  		emptyMap = make(map[string]struct{})
  2060  		expected = map[string]map[string]struct{}{
  2061  			"/test1":  emptyMap,
  2062  			"/test2":  emptyMap,
  2063  			"/test3":  emptyMap,
  2064  			"/test4":  emptyMap,
  2065  			"/test5":  emptyMap,
  2066  			"/test6":  emptyMap,
  2067  			"[/test7": emptyMap,
  2068  			"/test8]": emptyMap,
  2069  		}
  2070  	)
  2071  	_, err := buildImage(name,
  2072  		`FROM scratch
  2073  		VOLUME /test1
  2074  		VOLUME /test2
  2075      VOLUME /test3 /test4
  2076      VOLUME ["/test5", "/test6"]
  2077      VOLUME [/test7 /test8]
  2078      `,
  2079  		true)
  2080  	if err != nil {
  2081  		c.Fatal(err)
  2082  	}
  2083  	res, err := inspectFieldJSON(name, "Config.Volumes")
  2084  	if err != nil {
  2085  		c.Fatal(err)
  2086  	}
  2087  
  2088  	err = unmarshalJSON([]byte(res), &result)
  2089  	if err != nil {
  2090  		c.Fatal(err)
  2091  	}
  2092  
  2093  	equal := reflect.DeepEqual(&result, &expected)
  2094  
  2095  	if !equal {
  2096  		c.Fatalf("Volumes %s, expected %s", result, expected)
  2097  	}
  2098  
  2099  }
  2100  
  2101  func (s *DockerSuite) TestBuildMaintainer(c *check.C) {
  2102  	testRequires(c, DaemonIsLinux)
  2103  	name := "testbuildmaintainer"
  2104  	expected := "dockerio"
  2105  	_, err := buildImage(name,
  2106  		`FROM scratch
  2107          MAINTAINER dockerio`,
  2108  		true)
  2109  	if err != nil {
  2110  		c.Fatal(err)
  2111  	}
  2112  	res, err := inspectField(name, "Author")
  2113  	if err != nil {
  2114  		c.Fatal(err)
  2115  	}
  2116  	if res != expected {
  2117  		c.Fatalf("Maintainer %s, expected %s", res, expected)
  2118  	}
  2119  }
  2120  
  2121  func (s *DockerSuite) TestBuildUser(c *check.C) {
  2122  	testRequires(c, DaemonIsLinux)
  2123  	name := "testbuilduser"
  2124  	expected := "dockerio"
  2125  	_, err := buildImage(name,
  2126  		`FROM busybox
  2127  		RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  2128  		USER dockerio
  2129  		RUN [ $(whoami) = 'dockerio' ]`,
  2130  		true)
  2131  	if err != nil {
  2132  		c.Fatal(err)
  2133  	}
  2134  	res, err := inspectField(name, "Config.User")
  2135  	if err != nil {
  2136  		c.Fatal(err)
  2137  	}
  2138  	if res != expected {
  2139  		c.Fatalf("User %s, expected %s", res, expected)
  2140  	}
  2141  }
  2142  
  2143  func (s *DockerSuite) TestBuildRelativeWorkdir(c *check.C) {
  2144  	testRequires(c, DaemonIsLinux)
  2145  	name := "testbuildrelativeworkdir"
  2146  	expected := "/test2/test3"
  2147  	_, err := buildImage(name,
  2148  		`FROM busybox
  2149  		RUN [ "$PWD" = '/' ]
  2150  		WORKDIR test1
  2151  		RUN [ "$PWD" = '/test1' ]
  2152  		WORKDIR /test2
  2153  		RUN [ "$PWD" = '/test2' ]
  2154  		WORKDIR test3
  2155  		RUN [ "$PWD" = '/test2/test3' ]`,
  2156  		true)
  2157  	if err != nil {
  2158  		c.Fatal(err)
  2159  	}
  2160  	res, err := inspectField(name, "Config.WorkingDir")
  2161  	if err != nil {
  2162  		c.Fatal(err)
  2163  	}
  2164  	if res != expected {
  2165  		c.Fatalf("Workdir %s, expected %s", res, expected)
  2166  	}
  2167  }
  2168  
  2169  func (s *DockerSuite) TestBuildWorkdirWithEnvVariables(c *check.C) {
  2170  	testRequires(c, DaemonIsLinux)
  2171  	name := "testbuildworkdirwithenvvariables"
  2172  	expected := "/test1/test2"
  2173  	_, err := buildImage(name,
  2174  		`FROM busybox
  2175  		ENV DIRPATH /test1
  2176  		ENV SUBDIRNAME test2
  2177  		WORKDIR $DIRPATH
  2178  		WORKDIR $SUBDIRNAME/$MISSING_VAR`,
  2179  		true)
  2180  	if err != nil {
  2181  		c.Fatal(err)
  2182  	}
  2183  	res, err := inspectField(name, "Config.WorkingDir")
  2184  	if err != nil {
  2185  		c.Fatal(err)
  2186  	}
  2187  	if res != expected {
  2188  		c.Fatalf("Workdir %s, expected %s", res, expected)
  2189  	}
  2190  }
  2191  
  2192  func (s *DockerSuite) TestBuildRelativeCopy(c *check.C) {
  2193  	// cat /test1/test2/foo gets permission denied for the user
  2194  	testRequires(c, NotUserNamespace)
  2195  	testRequires(c, DaemonIsLinux)
  2196  	name := "testbuildrelativecopy"
  2197  	dockerfile := `
  2198  		FROM busybox
  2199  			WORKDIR /test1
  2200  			WORKDIR test2
  2201  			RUN [ "$PWD" = '/test1/test2' ]
  2202  			COPY foo ./
  2203  			RUN [ "$(cat /test1/test2/foo)" = 'hello' ]
  2204  			ADD foo ./bar/baz
  2205  			RUN [ "$(cat /test1/test2/bar/baz)" = 'hello' ]
  2206  			COPY foo ./bar/baz2
  2207  			RUN [ "$(cat /test1/test2/bar/baz2)" = 'hello' ]
  2208  			WORKDIR ..
  2209  			COPY foo ./
  2210  			RUN [ "$(cat /test1/foo)" = 'hello' ]
  2211  			COPY foo /test3/
  2212  			RUN [ "$(cat /test3/foo)" = 'hello' ]
  2213  			WORKDIR /test4
  2214  			COPY . .
  2215  			RUN [ "$(cat /test4/foo)" = 'hello' ]
  2216  			WORKDIR /test5/test6
  2217  			COPY foo ../
  2218  			RUN [ "$(cat /test5/foo)" = 'hello' ]
  2219  			`
  2220  	ctx, err := fakeContext(dockerfile, map[string]string{
  2221  		"foo": "hello",
  2222  	})
  2223  	if err != nil {
  2224  		c.Fatal(err)
  2225  	}
  2226  	defer ctx.Close()
  2227  	_, err = buildImageFromContext(name, ctx, false)
  2228  	if err != nil {
  2229  		c.Fatal(err)
  2230  	}
  2231  }
  2232  
  2233  func (s *DockerSuite) TestBuildEnv(c *check.C) {
  2234  	testRequires(c, DaemonIsLinux)
  2235  	name := "testbuildenv"
  2236  	expected := "[PATH=/test:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PORT=2375]"
  2237  	_, err := buildImage(name,
  2238  		`FROM busybox
  2239  		ENV PATH /test:$PATH
  2240          ENV PORT 2375
  2241  		RUN [ $(env | grep PORT) = 'PORT=2375' ]`,
  2242  		true)
  2243  	if err != nil {
  2244  		c.Fatal(err)
  2245  	}
  2246  	res, err := inspectField(name, "Config.Env")
  2247  	if err != nil {
  2248  		c.Fatal(err)
  2249  	}
  2250  	if res != expected {
  2251  		c.Fatalf("Env %s, expected %s", res, expected)
  2252  	}
  2253  }
  2254  
  2255  func (s *DockerSuite) TestBuildContextCleanup(c *check.C) {
  2256  	testRequires(c, DaemonIsLinux)
  2257  	testRequires(c, SameHostDaemon)
  2258  
  2259  	name := "testbuildcontextcleanup"
  2260  	entries, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  2261  	if err != nil {
  2262  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2263  	}
  2264  	_, err = buildImage(name,
  2265  		`FROM scratch
  2266          ENTRYPOINT ["/bin/echo"]`,
  2267  		true)
  2268  	if err != nil {
  2269  		c.Fatal(err)
  2270  	}
  2271  	entriesFinal, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  2272  	if err != nil {
  2273  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2274  	}
  2275  	if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  2276  		c.Fatalf("context should have been deleted, but wasn't")
  2277  	}
  2278  
  2279  }
  2280  
  2281  func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *check.C) {
  2282  	testRequires(c, DaemonIsLinux)
  2283  	testRequires(c, SameHostDaemon)
  2284  
  2285  	name := "testbuildcontextcleanup"
  2286  	entries, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  2287  	if err != nil {
  2288  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2289  	}
  2290  	_, err = buildImage(name,
  2291  		`FROM scratch
  2292  	RUN /non/existing/command`,
  2293  		true)
  2294  	if err == nil {
  2295  		c.Fatalf("expected build to fail, but it didn't")
  2296  	}
  2297  	entriesFinal, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  2298  	if err != nil {
  2299  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2300  	}
  2301  	if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  2302  		c.Fatalf("context should have been deleted, but wasn't")
  2303  	}
  2304  
  2305  }
  2306  
  2307  func (s *DockerSuite) TestBuildCmd(c *check.C) {
  2308  	testRequires(c, DaemonIsLinux)
  2309  	name := "testbuildcmd"
  2310  	expected := "{[/bin/echo Hello World]}"
  2311  	_, err := buildImage(name,
  2312  		`FROM scratch
  2313          CMD ["/bin/echo", "Hello World"]`,
  2314  		true)
  2315  	if err != nil {
  2316  		c.Fatal(err)
  2317  	}
  2318  	res, err := inspectField(name, "Config.Cmd")
  2319  	if err != nil {
  2320  		c.Fatal(err)
  2321  	}
  2322  	if res != expected {
  2323  		c.Fatalf("Cmd %s, expected %s", res, expected)
  2324  	}
  2325  }
  2326  
  2327  func (s *DockerSuite) TestBuildExpose(c *check.C) {
  2328  	testRequires(c, DaemonIsLinux)
  2329  	name := "testbuildexpose"
  2330  	expected := "map[2375/tcp:{}]"
  2331  	_, err := buildImage(name,
  2332  		`FROM scratch
  2333          EXPOSE 2375`,
  2334  		true)
  2335  	if err != nil {
  2336  		c.Fatal(err)
  2337  	}
  2338  	res, err := inspectField(name, "Config.ExposedPorts")
  2339  	if err != nil {
  2340  		c.Fatal(err)
  2341  	}
  2342  	if res != expected {
  2343  		c.Fatalf("Exposed ports %s, expected %s", res, expected)
  2344  	}
  2345  }
  2346  
  2347  func (s *DockerSuite) TestBuildExposeMorePorts(c *check.C) {
  2348  	testRequires(c, DaemonIsLinux)
  2349  	// start building docker file with a large number of ports
  2350  	portList := make([]string, 50)
  2351  	line := make([]string, 100)
  2352  	expectedPorts := make([]int, len(portList)*len(line))
  2353  	for i := 0; i < len(portList); i++ {
  2354  		for j := 0; j < len(line); j++ {
  2355  			p := i*len(line) + j + 1
  2356  			line[j] = strconv.Itoa(p)
  2357  			expectedPorts[p-1] = p
  2358  		}
  2359  		if i == len(portList)-1 {
  2360  			portList[i] = strings.Join(line, " ")
  2361  		} else {
  2362  			portList[i] = strings.Join(line, " ") + ` \`
  2363  		}
  2364  	}
  2365  
  2366  	dockerfile := `FROM scratch
  2367  	EXPOSE {{range .}} {{.}}
  2368  	{{end}}`
  2369  	tmpl := template.Must(template.New("dockerfile").Parse(dockerfile))
  2370  	buf := bytes.NewBuffer(nil)
  2371  	tmpl.Execute(buf, portList)
  2372  
  2373  	name := "testbuildexpose"
  2374  	_, err := buildImage(name, buf.String(), true)
  2375  	if err != nil {
  2376  		c.Fatal(err)
  2377  	}
  2378  
  2379  	// check if all the ports are saved inside Config.ExposedPorts
  2380  	res, err := inspectFieldJSON(name, "Config.ExposedPorts")
  2381  	if err != nil {
  2382  		c.Fatal(err)
  2383  	}
  2384  	var exposedPorts map[string]interface{}
  2385  	if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
  2386  		c.Fatal(err)
  2387  	}
  2388  
  2389  	for _, p := range expectedPorts {
  2390  		ep := fmt.Sprintf("%d/tcp", p)
  2391  		if _, ok := exposedPorts[ep]; !ok {
  2392  			c.Errorf("Port(%s) is not exposed", ep)
  2393  		} else {
  2394  			delete(exposedPorts, ep)
  2395  		}
  2396  	}
  2397  	if len(exposedPorts) != 0 {
  2398  		c.Errorf("Unexpected extra exposed ports %v", exposedPorts)
  2399  	}
  2400  }
  2401  
  2402  func (s *DockerSuite) TestBuildExposeOrder(c *check.C) {
  2403  	testRequires(c, DaemonIsLinux)
  2404  	buildID := func(name, exposed string) string {
  2405  		_, err := buildImage(name, fmt.Sprintf(`FROM scratch
  2406  		EXPOSE %s`, exposed), true)
  2407  		if err != nil {
  2408  			c.Fatal(err)
  2409  		}
  2410  		id, err := inspectField(name, "Id")
  2411  		if err != nil {
  2412  			c.Fatal(err)
  2413  		}
  2414  		return id
  2415  	}
  2416  
  2417  	id1 := buildID("testbuildexpose1", "80 2375")
  2418  	id2 := buildID("testbuildexpose2", "2375 80")
  2419  	if id1 != id2 {
  2420  		c.Errorf("EXPOSE should invalidate the cache only when ports actually changed")
  2421  	}
  2422  }
  2423  
  2424  func (s *DockerSuite) TestBuildExposeUpperCaseProto(c *check.C) {
  2425  	testRequires(c, DaemonIsLinux)
  2426  	name := "testbuildexposeuppercaseproto"
  2427  	expected := "map[5678/udp:{}]"
  2428  	_, err := buildImage(name,
  2429  		`FROM scratch
  2430          EXPOSE 5678/UDP`,
  2431  		true)
  2432  	if err != nil {
  2433  		c.Fatal(err)
  2434  	}
  2435  	res, err := inspectField(name, "Config.ExposedPorts")
  2436  	if err != nil {
  2437  		c.Fatal(err)
  2438  	}
  2439  	if res != expected {
  2440  		c.Fatalf("Exposed ports %s, expected %s", res, expected)
  2441  	}
  2442  }
  2443  
  2444  func (s *DockerSuite) TestBuildEmptyEntrypointInheritance(c *check.C) {
  2445  	testRequires(c, DaemonIsLinux)
  2446  	name := "testbuildentrypointinheritance"
  2447  	name2 := "testbuildentrypointinheritance2"
  2448  
  2449  	_, err := buildImage(name,
  2450  		`FROM busybox
  2451          ENTRYPOINT ["/bin/echo"]`,
  2452  		true)
  2453  	if err != nil {
  2454  		c.Fatal(err)
  2455  	}
  2456  	res, err := inspectField(name, "Config.Entrypoint")
  2457  	if err != nil {
  2458  		c.Fatal(err)
  2459  	}
  2460  
  2461  	expected := "{[/bin/echo]}"
  2462  	if res != expected {
  2463  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2464  	}
  2465  
  2466  	_, err = buildImage(name2,
  2467  		fmt.Sprintf(`FROM %s
  2468          ENTRYPOINT []`, name),
  2469  		true)
  2470  	if err != nil {
  2471  		c.Fatal(err)
  2472  	}
  2473  	res, err = inspectField(name2, "Config.Entrypoint")
  2474  	if err != nil {
  2475  		c.Fatal(err)
  2476  	}
  2477  
  2478  	expected = "{[]}"
  2479  
  2480  	if res != expected {
  2481  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2482  	}
  2483  
  2484  }
  2485  
  2486  func (s *DockerSuite) TestBuildEmptyEntrypoint(c *check.C) {
  2487  	testRequires(c, DaemonIsLinux)
  2488  	name := "testbuildentrypoint"
  2489  	expected := "{[]}"
  2490  
  2491  	_, err := buildImage(name,
  2492  		`FROM busybox
  2493          ENTRYPOINT []`,
  2494  		true)
  2495  	if err != nil {
  2496  		c.Fatal(err)
  2497  	}
  2498  	res, err := inspectField(name, "Config.Entrypoint")
  2499  	if err != nil {
  2500  		c.Fatal(err)
  2501  	}
  2502  	if res != expected {
  2503  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2504  	}
  2505  
  2506  }
  2507  
  2508  func (s *DockerSuite) TestBuildEntrypoint(c *check.C) {
  2509  	testRequires(c, DaemonIsLinux)
  2510  	name := "testbuildentrypoint"
  2511  	expected := "{[/bin/echo]}"
  2512  	_, err := buildImage(name,
  2513  		`FROM scratch
  2514          ENTRYPOINT ["/bin/echo"]`,
  2515  		true)
  2516  	if err != nil {
  2517  		c.Fatal(err)
  2518  	}
  2519  	res, err := inspectField(name, "Config.Entrypoint")
  2520  	if err != nil {
  2521  		c.Fatal(err)
  2522  	}
  2523  	if res != expected {
  2524  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2525  	}
  2526  
  2527  }
  2528  
  2529  // #6445 ensure ONBUILD triggers aren't committed to grandchildren
  2530  func (s *DockerSuite) TestBuildOnBuildLimitedInheritence(c *check.C) {
  2531  	testRequires(c, DaemonIsLinux)
  2532  	var (
  2533  		out2, out3 string
  2534  	)
  2535  	{
  2536  		name1 := "testonbuildtrigger1"
  2537  		dockerfile1 := `
  2538  		FROM busybox
  2539  		RUN echo "GRANDPARENT"
  2540  		ONBUILD RUN echo "ONBUILD PARENT"
  2541  		`
  2542  		ctx, err := fakeContext(dockerfile1, nil)
  2543  		if err != nil {
  2544  			c.Fatal(err)
  2545  		}
  2546  		defer ctx.Close()
  2547  
  2548  		out1, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", name1, ".")
  2549  		if err != nil {
  2550  			c.Fatalf("build failed to complete: %s, %v", out1, err)
  2551  		}
  2552  	}
  2553  	{
  2554  		name2 := "testonbuildtrigger2"
  2555  		dockerfile2 := `
  2556  		FROM testonbuildtrigger1
  2557  		`
  2558  		ctx, err := fakeContext(dockerfile2, nil)
  2559  		if err != nil {
  2560  			c.Fatal(err)
  2561  		}
  2562  		defer ctx.Close()
  2563  
  2564  		out2, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name2, ".")
  2565  		if err != nil {
  2566  			c.Fatalf("build failed to complete: %s, %v", out2, err)
  2567  		}
  2568  	}
  2569  	{
  2570  		name3 := "testonbuildtrigger3"
  2571  		dockerfile3 := `
  2572  		FROM testonbuildtrigger2
  2573  		`
  2574  		ctx, err := fakeContext(dockerfile3, nil)
  2575  		if err != nil {
  2576  			c.Fatal(err)
  2577  		}
  2578  		defer ctx.Close()
  2579  
  2580  		out3, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name3, ".")
  2581  		if err != nil {
  2582  			c.Fatalf("build failed to complete: %s, %v", out3, err)
  2583  		}
  2584  
  2585  	}
  2586  
  2587  	// ONBUILD should be run in second build.
  2588  	if !strings.Contains(out2, "ONBUILD PARENT") {
  2589  		c.Fatalf("ONBUILD instruction did not run in child of ONBUILD parent")
  2590  	}
  2591  
  2592  	// ONBUILD should *not* be run in third build.
  2593  	if strings.Contains(out3, "ONBUILD PARENT") {
  2594  		c.Fatalf("ONBUILD instruction ran in grandchild of ONBUILD parent")
  2595  	}
  2596  
  2597  }
  2598  
  2599  func (s *DockerSuite) TestBuildWithCache(c *check.C) {
  2600  	testRequires(c, DaemonIsLinux)
  2601  	name := "testbuildwithcache"
  2602  	id1, err := buildImage(name,
  2603  		`FROM scratch
  2604  		MAINTAINER dockerio
  2605  		EXPOSE 5432
  2606          ENTRYPOINT ["/bin/echo"]`,
  2607  		true)
  2608  	if err != nil {
  2609  		c.Fatal(err)
  2610  	}
  2611  	id2, err := buildImage(name,
  2612  		`FROM scratch
  2613  		MAINTAINER dockerio
  2614  		EXPOSE 5432
  2615          ENTRYPOINT ["/bin/echo"]`,
  2616  		true)
  2617  	if err != nil {
  2618  		c.Fatal(err)
  2619  	}
  2620  	if id1 != id2 {
  2621  		c.Fatal("The cache should have been used but hasn't.")
  2622  	}
  2623  }
  2624  
  2625  func (s *DockerSuite) TestBuildWithoutCache(c *check.C) {
  2626  	testRequires(c, DaemonIsLinux)
  2627  	name := "testbuildwithoutcache"
  2628  	name2 := "testbuildwithoutcache2"
  2629  	id1, err := buildImage(name,
  2630  		`FROM scratch
  2631  		MAINTAINER dockerio
  2632  		EXPOSE 5432
  2633          ENTRYPOINT ["/bin/echo"]`,
  2634  		true)
  2635  	if err != nil {
  2636  		c.Fatal(err)
  2637  	}
  2638  
  2639  	id2, err := buildImage(name2,
  2640  		`FROM scratch
  2641  		MAINTAINER dockerio
  2642  		EXPOSE 5432
  2643          ENTRYPOINT ["/bin/echo"]`,
  2644  		false)
  2645  	if err != nil {
  2646  		c.Fatal(err)
  2647  	}
  2648  	if id1 == id2 {
  2649  		c.Fatal("The cache should have been invalided but hasn't.")
  2650  	}
  2651  }
  2652  
  2653  func (s *DockerSuite) TestBuildConditionalCache(c *check.C) {
  2654  	testRequires(c, DaemonIsLinux)
  2655  	name := "testbuildconditionalcache"
  2656  
  2657  	dockerfile := `
  2658  		FROM busybox
  2659          ADD foo /tmp/`
  2660  	ctx, err := fakeContext(dockerfile, map[string]string{
  2661  		"foo": "hello",
  2662  	})
  2663  	if err != nil {
  2664  		c.Fatal(err)
  2665  	}
  2666  	defer ctx.Close()
  2667  
  2668  	id1, err := buildImageFromContext(name, ctx, true)
  2669  	if err != nil {
  2670  		c.Fatalf("Error building #1: %s", err)
  2671  	}
  2672  
  2673  	if err := ctx.Add("foo", "bye"); err != nil {
  2674  		c.Fatalf("Error modifying foo: %s", err)
  2675  	}
  2676  
  2677  	id2, err := buildImageFromContext(name, ctx, false)
  2678  	if err != nil {
  2679  		c.Fatalf("Error building #2: %s", err)
  2680  	}
  2681  	if id2 == id1 {
  2682  		c.Fatal("Should not have used the cache")
  2683  	}
  2684  
  2685  	id3, err := buildImageFromContext(name, ctx, true)
  2686  	if err != nil {
  2687  		c.Fatalf("Error building #3: %s", err)
  2688  	}
  2689  	if id3 != id2 {
  2690  		c.Fatal("Should have used the cache")
  2691  	}
  2692  }
  2693  
  2694  func (s *DockerSuite) TestBuildAddLocalFileWithCache(c *check.C) {
  2695  	// local files are not owned by the correct user
  2696  	testRequires(c, NotUserNamespace)
  2697  	testRequires(c, DaemonIsLinux)
  2698  	name := "testbuildaddlocalfilewithcache"
  2699  	name2 := "testbuildaddlocalfilewithcache2"
  2700  	dockerfile := `
  2701  		FROM busybox
  2702          MAINTAINER dockerio
  2703          ADD foo /usr/lib/bla/bar
  2704  		RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2705  	ctx, err := fakeContext(dockerfile, map[string]string{
  2706  		"foo": "hello",
  2707  	})
  2708  	if err != nil {
  2709  		c.Fatal(err)
  2710  	}
  2711  	defer ctx.Close()
  2712  	id1, err := buildImageFromContext(name, ctx, true)
  2713  	if err != nil {
  2714  		c.Fatal(err)
  2715  	}
  2716  	id2, err := buildImageFromContext(name2, ctx, true)
  2717  	if err != nil {
  2718  		c.Fatal(err)
  2719  	}
  2720  	if id1 != id2 {
  2721  		c.Fatal("The cache should have been used but hasn't.")
  2722  	}
  2723  }
  2724  
  2725  func (s *DockerSuite) TestBuildAddMultipleLocalFileWithCache(c *check.C) {
  2726  	testRequires(c, DaemonIsLinux)
  2727  	name := "testbuildaddmultiplelocalfilewithcache"
  2728  	name2 := "testbuildaddmultiplelocalfilewithcache2"
  2729  	dockerfile := `
  2730  		FROM busybox
  2731          MAINTAINER dockerio
  2732          ADD foo Dockerfile /usr/lib/bla/
  2733  		RUN [ "$(cat /usr/lib/bla/foo)" = "hello" ]`
  2734  	ctx, err := fakeContext(dockerfile, map[string]string{
  2735  		"foo": "hello",
  2736  	})
  2737  	if err != nil {
  2738  		c.Fatal(err)
  2739  	}
  2740  	defer ctx.Close()
  2741  	id1, err := buildImageFromContext(name, ctx, true)
  2742  	if err != nil {
  2743  		c.Fatal(err)
  2744  	}
  2745  	id2, err := buildImageFromContext(name2, ctx, true)
  2746  	if err != nil {
  2747  		c.Fatal(err)
  2748  	}
  2749  	if id1 != id2 {
  2750  		c.Fatal("The cache should have been used but hasn't.")
  2751  	}
  2752  }
  2753  
  2754  func (s *DockerSuite) TestBuildAddLocalFileWithoutCache(c *check.C) {
  2755  	// local files are not owned by the correct user
  2756  	testRequires(c, NotUserNamespace)
  2757  	testRequires(c, DaemonIsLinux)
  2758  	name := "testbuildaddlocalfilewithoutcache"
  2759  	name2 := "testbuildaddlocalfilewithoutcache2"
  2760  	dockerfile := `
  2761  		FROM busybox
  2762          MAINTAINER dockerio
  2763          ADD foo /usr/lib/bla/bar
  2764  		RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2765  	ctx, err := fakeContext(dockerfile, map[string]string{
  2766  		"foo": "hello",
  2767  	})
  2768  	if err != nil {
  2769  		c.Fatal(err)
  2770  	}
  2771  	defer ctx.Close()
  2772  	id1, err := buildImageFromContext(name, ctx, true)
  2773  	if err != nil {
  2774  		c.Fatal(err)
  2775  	}
  2776  	id2, err := buildImageFromContext(name2, ctx, false)
  2777  	if err != nil {
  2778  		c.Fatal(err)
  2779  	}
  2780  	if id1 == id2 {
  2781  		c.Fatal("The cache should have been invalided but hasn't.")
  2782  	}
  2783  }
  2784  
  2785  func (s *DockerSuite) TestBuildCopyDirButNotFile(c *check.C) {
  2786  	testRequires(c, DaemonIsLinux)
  2787  	name := "testbuildcopydirbutnotfile"
  2788  	name2 := "testbuildcopydirbutnotfile2"
  2789  	dockerfile := `
  2790          FROM scratch
  2791          COPY dir /tmp/`
  2792  	ctx, err := fakeContext(dockerfile, map[string]string{
  2793  		"dir/foo": "hello",
  2794  	})
  2795  	if err != nil {
  2796  		c.Fatal(err)
  2797  	}
  2798  	defer ctx.Close()
  2799  	id1, err := buildImageFromContext(name, ctx, true)
  2800  	if err != nil {
  2801  		c.Fatal(err)
  2802  	}
  2803  	// Check that adding file with similar name doesn't mess with cache
  2804  	if err := ctx.Add("dir_file", "hello2"); err != nil {
  2805  		c.Fatal(err)
  2806  	}
  2807  	id2, err := buildImageFromContext(name2, ctx, true)
  2808  	if err != nil {
  2809  		c.Fatal(err)
  2810  	}
  2811  	if id1 != id2 {
  2812  		c.Fatal("The cache should have been used but wasn't")
  2813  	}
  2814  }
  2815  
  2816  func (s *DockerSuite) TestBuildAddCurrentDirWithCache(c *check.C) {
  2817  	testRequires(c, DaemonIsLinux)
  2818  	name := "testbuildaddcurrentdirwithcache"
  2819  	name2 := name + "2"
  2820  	name3 := name + "3"
  2821  	name4 := name + "4"
  2822  	dockerfile := `
  2823          FROM scratch
  2824          MAINTAINER dockerio
  2825          ADD . /usr/lib/bla`
  2826  	ctx, err := fakeContext(dockerfile, map[string]string{
  2827  		"foo": "hello",
  2828  	})
  2829  	if err != nil {
  2830  		c.Fatal(err)
  2831  	}
  2832  	defer ctx.Close()
  2833  	id1, err := buildImageFromContext(name, ctx, true)
  2834  	if err != nil {
  2835  		c.Fatal(err)
  2836  	}
  2837  	// Check that adding file invalidate cache of "ADD ."
  2838  	if err := ctx.Add("bar", "hello2"); err != nil {
  2839  		c.Fatal(err)
  2840  	}
  2841  	id2, err := buildImageFromContext(name2, ctx, true)
  2842  	if err != nil {
  2843  		c.Fatal(err)
  2844  	}
  2845  	if id1 == id2 {
  2846  		c.Fatal("The cache should have been invalided but hasn't.")
  2847  	}
  2848  	// Check that changing file invalidate cache of "ADD ."
  2849  	if err := ctx.Add("foo", "hello1"); err != nil {
  2850  		c.Fatal(err)
  2851  	}
  2852  	id3, err := buildImageFromContext(name3, ctx, true)
  2853  	if err != nil {
  2854  		c.Fatal(err)
  2855  	}
  2856  	if id2 == id3 {
  2857  		c.Fatal("The cache should have been invalided but hasn't.")
  2858  	}
  2859  	// Check that changing file to same content with different mtime does not
  2860  	// invalidate cache of "ADD ."
  2861  	time.Sleep(1 * time.Second) // wait second because of mtime precision
  2862  	if err := ctx.Add("foo", "hello1"); err != nil {
  2863  		c.Fatal(err)
  2864  	}
  2865  	id4, err := buildImageFromContext(name4, ctx, true)
  2866  	if err != nil {
  2867  		c.Fatal(err)
  2868  	}
  2869  	if id3 != id4 {
  2870  		c.Fatal("The cache should have been used but hasn't.")
  2871  	}
  2872  }
  2873  
  2874  func (s *DockerSuite) TestBuildAddCurrentDirWithoutCache(c *check.C) {
  2875  	testRequires(c, DaemonIsLinux)
  2876  	name := "testbuildaddcurrentdirwithoutcache"
  2877  	name2 := "testbuildaddcurrentdirwithoutcache2"
  2878  	dockerfile := `
  2879          FROM scratch
  2880          MAINTAINER dockerio
  2881          ADD . /usr/lib/bla`
  2882  	ctx, err := fakeContext(dockerfile, map[string]string{
  2883  		"foo": "hello",
  2884  	})
  2885  	if err != nil {
  2886  		c.Fatal(err)
  2887  	}
  2888  	defer ctx.Close()
  2889  	id1, err := buildImageFromContext(name, ctx, true)
  2890  	if err != nil {
  2891  		c.Fatal(err)
  2892  	}
  2893  	id2, err := buildImageFromContext(name2, ctx, false)
  2894  	if err != nil {
  2895  		c.Fatal(err)
  2896  	}
  2897  	if id1 == id2 {
  2898  		c.Fatal("The cache should have been invalided but hasn't.")
  2899  	}
  2900  }
  2901  
  2902  func (s *DockerSuite) TestBuildAddRemoteFileWithCache(c *check.C) {
  2903  	testRequires(c, DaemonIsLinux)
  2904  	name := "testbuildaddremotefilewithcache"
  2905  	server, err := fakeStorage(map[string]string{
  2906  		"baz": "hello",
  2907  	})
  2908  	if err != nil {
  2909  		c.Fatal(err)
  2910  	}
  2911  	defer server.Close()
  2912  
  2913  	id1, err := buildImage(name,
  2914  		fmt.Sprintf(`FROM scratch
  2915          MAINTAINER dockerio
  2916          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2917  		true)
  2918  	if err != nil {
  2919  		c.Fatal(err)
  2920  	}
  2921  	id2, err := buildImage(name,
  2922  		fmt.Sprintf(`FROM scratch
  2923          MAINTAINER dockerio
  2924          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2925  		true)
  2926  	if err != nil {
  2927  		c.Fatal(err)
  2928  	}
  2929  	if id1 != id2 {
  2930  		c.Fatal("The cache should have been used but hasn't.")
  2931  	}
  2932  }
  2933  
  2934  func (s *DockerSuite) TestBuildAddRemoteFileWithoutCache(c *check.C) {
  2935  	testRequires(c, DaemonIsLinux)
  2936  	name := "testbuildaddremotefilewithoutcache"
  2937  	name2 := "testbuildaddremotefilewithoutcache2"
  2938  	server, err := fakeStorage(map[string]string{
  2939  		"baz": "hello",
  2940  	})
  2941  	if err != nil {
  2942  		c.Fatal(err)
  2943  	}
  2944  	defer server.Close()
  2945  
  2946  	id1, err := buildImage(name,
  2947  		fmt.Sprintf(`FROM scratch
  2948          MAINTAINER dockerio
  2949          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2950  		true)
  2951  	if err != nil {
  2952  		c.Fatal(err)
  2953  	}
  2954  	id2, err := buildImage(name2,
  2955  		fmt.Sprintf(`FROM scratch
  2956          MAINTAINER dockerio
  2957          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2958  		false)
  2959  	if err != nil {
  2960  		c.Fatal(err)
  2961  	}
  2962  	if id1 == id2 {
  2963  		c.Fatal("The cache should have been invalided but hasn't.")
  2964  	}
  2965  }
  2966  
  2967  func (s *DockerSuite) TestBuildAddRemoteFileMTime(c *check.C) {
  2968  	testRequires(c, DaemonIsLinux)
  2969  	name := "testbuildaddremotefilemtime"
  2970  	name2 := name + "2"
  2971  	name3 := name + "3"
  2972  
  2973  	files := map[string]string{"baz": "hello"}
  2974  	server, err := fakeStorage(files)
  2975  	if err != nil {
  2976  		c.Fatal(err)
  2977  	}
  2978  	defer server.Close()
  2979  
  2980  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2981          MAINTAINER dockerio
  2982          ADD %s/baz /usr/lib/baz/quux`, server.URL()), nil)
  2983  	if err != nil {
  2984  		c.Fatal(err)
  2985  	}
  2986  	defer ctx.Close()
  2987  
  2988  	id1, err := buildImageFromContext(name, ctx, true)
  2989  	if err != nil {
  2990  		c.Fatal(err)
  2991  	}
  2992  
  2993  	id2, err := buildImageFromContext(name2, ctx, true)
  2994  	if err != nil {
  2995  		c.Fatal(err)
  2996  	}
  2997  	if id1 != id2 {
  2998  		c.Fatal("The cache should have been used but wasn't - #1")
  2999  	}
  3000  
  3001  	// Now create a different server with same contents (causes different mtime)
  3002  	// The cache should still be used
  3003  
  3004  	// allow some time for clock to pass as mtime precision is only 1s
  3005  	time.Sleep(2 * time.Second)
  3006  
  3007  	server2, err := fakeStorage(files)
  3008  	if err != nil {
  3009  		c.Fatal(err)
  3010  	}
  3011  	defer server2.Close()
  3012  
  3013  	ctx2, err := fakeContext(fmt.Sprintf(`FROM scratch
  3014          MAINTAINER dockerio
  3015          ADD %s/baz /usr/lib/baz/quux`, server2.URL()), nil)
  3016  	if err != nil {
  3017  		c.Fatal(err)
  3018  	}
  3019  	defer ctx2.Close()
  3020  	id3, err := buildImageFromContext(name3, ctx2, true)
  3021  	if err != nil {
  3022  		c.Fatal(err)
  3023  	}
  3024  	if id1 != id3 {
  3025  		c.Fatal("The cache should have been used but wasn't")
  3026  	}
  3027  }
  3028  
  3029  func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithCache(c *check.C) {
  3030  	testRequires(c, DaemonIsLinux)
  3031  	name := "testbuildaddlocalandremotefilewithcache"
  3032  	server, err := fakeStorage(map[string]string{
  3033  		"baz": "hello",
  3034  	})
  3035  	if err != nil {
  3036  		c.Fatal(err)
  3037  	}
  3038  	defer server.Close()
  3039  
  3040  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  3041          MAINTAINER dockerio
  3042          ADD foo /usr/lib/bla/bar
  3043          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  3044  		map[string]string{
  3045  			"foo": "hello world",
  3046  		})
  3047  	if err != nil {
  3048  		c.Fatal(err)
  3049  	}
  3050  	defer ctx.Close()
  3051  	id1, err := buildImageFromContext(name, ctx, true)
  3052  	if err != nil {
  3053  		c.Fatal(err)
  3054  	}
  3055  	id2, err := buildImageFromContext(name, ctx, true)
  3056  	if err != nil {
  3057  		c.Fatal(err)
  3058  	}
  3059  	if id1 != id2 {
  3060  		c.Fatal("The cache should have been used but hasn't.")
  3061  	}
  3062  }
  3063  
  3064  func testContextTar(c *check.C, compression archive.Compression) {
  3065  	testRequires(c, DaemonIsLinux)
  3066  	ctx, err := fakeContext(
  3067  		`FROM busybox
  3068  ADD foo /foo
  3069  CMD ["cat", "/foo"]`,
  3070  		map[string]string{
  3071  			"foo": "bar",
  3072  		},
  3073  	)
  3074  	if err != nil {
  3075  		c.Fatal(err)
  3076  	}
  3077  	defer ctx.Close()
  3078  	context, err := archive.Tar(ctx.Dir, compression)
  3079  	if err != nil {
  3080  		c.Fatalf("failed to build context tar: %v", err)
  3081  	}
  3082  	name := "contexttar"
  3083  	buildCmd := exec.Command(dockerBinary, "build", "-t", name, "-")
  3084  	buildCmd.Stdin = context
  3085  
  3086  	if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  3087  		c.Fatalf("build failed to complete: %v %v", out, err)
  3088  	}
  3089  }
  3090  
  3091  func (s *DockerSuite) TestBuildContextTarGzip(c *check.C) {
  3092  	testContextTar(c, archive.Gzip)
  3093  }
  3094  
  3095  func (s *DockerSuite) TestBuildContextTarNoCompression(c *check.C) {
  3096  	testContextTar(c, archive.Uncompressed)
  3097  }
  3098  
  3099  func (s *DockerSuite) TestBuildNoContext(c *check.C) {
  3100  	testRequires(c, DaemonIsLinux)
  3101  	buildCmd := exec.Command(dockerBinary, "build", "-t", "nocontext", "-")
  3102  	buildCmd.Stdin = strings.NewReader("FROM busybox\nCMD echo ok\n")
  3103  
  3104  	if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  3105  		c.Fatalf("build failed to complete: %v %v", out, err)
  3106  	}
  3107  
  3108  	if out, _ := dockerCmd(c, "run", "--rm", "nocontext"); out != "ok\n" {
  3109  		c.Fatalf("run produced invalid output: %q, expected %q", out, "ok")
  3110  	}
  3111  }
  3112  
  3113  // TODO: TestCaching
  3114  func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithoutCache(c *check.C) {
  3115  	testRequires(c, DaemonIsLinux)
  3116  	name := "testbuildaddlocalandremotefilewithoutcache"
  3117  	name2 := "testbuildaddlocalandremotefilewithoutcache2"
  3118  	server, err := fakeStorage(map[string]string{
  3119  		"baz": "hello",
  3120  	})
  3121  	if err != nil {
  3122  		c.Fatal(err)
  3123  	}
  3124  	defer server.Close()
  3125  
  3126  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  3127          MAINTAINER dockerio
  3128          ADD foo /usr/lib/bla/bar
  3129          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  3130  		map[string]string{
  3131  			"foo": "hello world",
  3132  		})
  3133  	if err != nil {
  3134  		c.Fatal(err)
  3135  	}
  3136  	defer ctx.Close()
  3137  	id1, err := buildImageFromContext(name, ctx, true)
  3138  	if err != nil {
  3139  		c.Fatal(err)
  3140  	}
  3141  	id2, err := buildImageFromContext(name2, ctx, false)
  3142  	if err != nil {
  3143  		c.Fatal(err)
  3144  	}
  3145  	if id1 == id2 {
  3146  		c.Fatal("The cache should have been invalided but hasn't.")
  3147  	}
  3148  }
  3149  
  3150  func (s *DockerSuite) TestBuildWithVolumeOwnership(c *check.C) {
  3151  	testRequires(c, DaemonIsLinux)
  3152  	name := "testbuildimg"
  3153  
  3154  	_, err := buildImage(name,
  3155  		`FROM busybox:latest
  3156          RUN mkdir /test && chown daemon:daemon /test && chmod 0600 /test
  3157          VOLUME /test`,
  3158  		true)
  3159  
  3160  	if err != nil {
  3161  		c.Fatal(err)
  3162  	}
  3163  
  3164  	out, _ := dockerCmd(c, "run", "--rm", "testbuildimg", "ls", "-la", "/test")
  3165  
  3166  	if expected := "drw-------"; !strings.Contains(out, expected) {
  3167  		c.Fatalf("expected %s received %s", expected, out)
  3168  	}
  3169  
  3170  	if expected := "daemon   daemon"; !strings.Contains(out, expected) {
  3171  		c.Fatalf("expected %s received %s", expected, out)
  3172  	}
  3173  
  3174  }
  3175  
  3176  // testing #1405 - config.Cmd does not get cleaned up if
  3177  // utilizing cache
  3178  func (s *DockerSuite) TestBuildEntrypointRunCleanup(c *check.C) {
  3179  	testRequires(c, DaemonIsLinux)
  3180  	name := "testbuildcmdcleanup"
  3181  	if _, err := buildImage(name,
  3182  		`FROM busybox
  3183          RUN echo "hello"`,
  3184  		true); err != nil {
  3185  		c.Fatal(err)
  3186  	}
  3187  
  3188  	ctx, err := fakeContext(`FROM busybox
  3189          RUN echo "hello"
  3190          ADD foo /foo
  3191          ENTRYPOINT ["/bin/echo"]`,
  3192  		map[string]string{
  3193  			"foo": "hello",
  3194  		})
  3195  	if err != nil {
  3196  		c.Fatal(err)
  3197  	}
  3198  	defer ctx.Close()
  3199  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3200  		c.Fatal(err)
  3201  	}
  3202  	res, err := inspectField(name, "Config.Cmd")
  3203  	if err != nil {
  3204  		c.Fatal(err)
  3205  	}
  3206  	// Cmd must be cleaned up
  3207  	if res != "<nil>" {
  3208  		c.Fatalf("Cmd %s, expected nil", res)
  3209  	}
  3210  }
  3211  
  3212  func (s *DockerSuite) TestBuildForbiddenContextPath(c *check.C) {
  3213  	testRequires(c, DaemonIsLinux)
  3214  	name := "testbuildforbidpath"
  3215  	ctx, err := fakeContext(`FROM scratch
  3216          ADD ../../ test/
  3217          `,
  3218  		map[string]string{
  3219  			"test.txt":  "test1",
  3220  			"other.txt": "other",
  3221  		})
  3222  	if err != nil {
  3223  		c.Fatal(err)
  3224  	}
  3225  	defer ctx.Close()
  3226  
  3227  	expected := "Forbidden path outside the build context: ../../ "
  3228  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  3229  		c.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
  3230  	}
  3231  
  3232  }
  3233  
  3234  func (s *DockerSuite) TestBuildAddFileNotFound(c *check.C) {
  3235  	testRequires(c, DaemonIsLinux)
  3236  	name := "testbuildaddnotfound"
  3237  	ctx, err := fakeContext(`FROM scratch
  3238          ADD foo /usr/local/bar`,
  3239  		map[string]string{"bar": "hello"})
  3240  	if err != nil {
  3241  		c.Fatal(err)
  3242  	}
  3243  	defer ctx.Close()
  3244  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3245  		if !strings.Contains(err.Error(), "foo: no such file or directory") {
  3246  			c.Fatalf("Wrong error %v, must be about missing foo file or directory", err)
  3247  		}
  3248  	} else {
  3249  		c.Fatal("Error must not be nil")
  3250  	}
  3251  }
  3252  
  3253  func (s *DockerSuite) TestBuildInheritance(c *check.C) {
  3254  	testRequires(c, DaemonIsLinux)
  3255  	name := "testbuildinheritance"
  3256  
  3257  	_, err := buildImage(name,
  3258  		`FROM scratch
  3259  		EXPOSE 2375`,
  3260  		true)
  3261  	if err != nil {
  3262  		c.Fatal(err)
  3263  	}
  3264  	ports1, err := inspectField(name, "Config.ExposedPorts")
  3265  	if err != nil {
  3266  		c.Fatal(err)
  3267  	}
  3268  
  3269  	_, err = buildImage(name,
  3270  		fmt.Sprintf(`FROM %s
  3271  		ENTRYPOINT ["/bin/echo"]`, name),
  3272  		true)
  3273  	if err != nil {
  3274  		c.Fatal(err)
  3275  	}
  3276  
  3277  	res, err := inspectField(name, "Config.Entrypoint")
  3278  	if err != nil {
  3279  		c.Fatal(err)
  3280  	}
  3281  	if expected := "{[/bin/echo]}"; res != expected {
  3282  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  3283  	}
  3284  	ports2, err := inspectField(name, "Config.ExposedPorts")
  3285  	if err != nil {
  3286  		c.Fatal(err)
  3287  	}
  3288  	if ports1 != ports2 {
  3289  		c.Fatalf("Ports must be same: %s != %s", ports1, ports2)
  3290  	}
  3291  }
  3292  
  3293  func (s *DockerSuite) TestBuildFails(c *check.C) {
  3294  	testRequires(c, DaemonIsLinux)
  3295  	name := "testbuildfails"
  3296  	_, err := buildImage(name,
  3297  		`FROM busybox
  3298  		RUN sh -c "exit 23"`,
  3299  		true)
  3300  	if err != nil {
  3301  		if !strings.Contains(err.Error(), "returned a non-zero code: 23") {
  3302  			c.Fatalf("Wrong error %v, must be about non-zero code 23", err)
  3303  		}
  3304  	} else {
  3305  		c.Fatal("Error must not be nil")
  3306  	}
  3307  }
  3308  
  3309  func (s *DockerSuite) TestBuildFailsDockerfileEmpty(c *check.C) {
  3310  	name := "testbuildfails"
  3311  	_, err := buildImage(name, ``, true)
  3312  	if err != nil {
  3313  		if !strings.Contains(err.Error(), "The Dockerfile (Dockerfile) cannot be empty") {
  3314  			c.Fatalf("Wrong error %v, must be about empty Dockerfile", err)
  3315  		}
  3316  	} else {
  3317  		c.Fatal("Error must not be nil")
  3318  	}
  3319  }
  3320  
  3321  func (s *DockerSuite) TestBuildOnBuild(c *check.C) {
  3322  	testRequires(c, DaemonIsLinux)
  3323  	name := "testbuildonbuild"
  3324  	_, err := buildImage(name,
  3325  		`FROM busybox
  3326  		ONBUILD RUN touch foobar`,
  3327  		true)
  3328  	if err != nil {
  3329  		c.Fatal(err)
  3330  	}
  3331  	_, err = buildImage(name,
  3332  		fmt.Sprintf(`FROM %s
  3333  		RUN [ -f foobar ]`, name),
  3334  		true)
  3335  	if err != nil {
  3336  		c.Fatal(err)
  3337  	}
  3338  }
  3339  
  3340  func (s *DockerSuite) TestBuildOnBuildForbiddenChained(c *check.C) {
  3341  	testRequires(c, DaemonIsLinux)
  3342  	name := "testbuildonbuildforbiddenchained"
  3343  	_, err := buildImage(name,
  3344  		`FROM busybox
  3345  		ONBUILD ONBUILD RUN touch foobar`,
  3346  		true)
  3347  	if err != nil {
  3348  		if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
  3349  			c.Fatalf("Wrong error %v, must be about chaining ONBUILD", err)
  3350  		}
  3351  	} else {
  3352  		c.Fatal("Error must not be nil")
  3353  	}
  3354  }
  3355  
  3356  func (s *DockerSuite) TestBuildOnBuildForbiddenFrom(c *check.C) {
  3357  	testRequires(c, DaemonIsLinux)
  3358  	name := "testbuildonbuildforbiddenfrom"
  3359  	_, err := buildImage(name,
  3360  		`FROM busybox
  3361  		ONBUILD FROM scratch`,
  3362  		true)
  3363  	if err != nil {
  3364  		if !strings.Contains(err.Error(), "FROM isn't allowed as an ONBUILD trigger") {
  3365  			c.Fatalf("Wrong error %v, must be about FROM forbidden", err)
  3366  		}
  3367  	} else {
  3368  		c.Fatal("Error must not be nil")
  3369  	}
  3370  }
  3371  
  3372  func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainer(c *check.C) {
  3373  	testRequires(c, DaemonIsLinux)
  3374  	name := "testbuildonbuildforbiddenmaintainer"
  3375  	_, err := buildImage(name,
  3376  		`FROM busybox
  3377  		ONBUILD MAINTAINER docker.io`,
  3378  		true)
  3379  	if err != nil {
  3380  		if !strings.Contains(err.Error(), "MAINTAINER isn't allowed as an ONBUILD trigger") {
  3381  			c.Fatalf("Wrong error %v, must be about MAINTAINER forbidden", err)
  3382  		}
  3383  	} else {
  3384  		c.Fatal("Error must not be nil")
  3385  	}
  3386  }
  3387  
  3388  // gh #2446
  3389  func (s *DockerSuite) TestBuildAddToSymlinkDest(c *check.C) {
  3390  	testRequires(c, DaemonIsLinux)
  3391  	name := "testbuildaddtosymlinkdest"
  3392  	ctx, err := fakeContext(`FROM busybox
  3393          RUN mkdir /foo
  3394          RUN ln -s /foo /bar
  3395          ADD foo /bar/
  3396          RUN [ -f /bar/foo ]
  3397          RUN [ -f /foo/foo ]`,
  3398  		map[string]string{
  3399  			"foo": "hello",
  3400  		})
  3401  	if err != nil {
  3402  		c.Fatal(err)
  3403  	}
  3404  	defer ctx.Close()
  3405  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3406  		c.Fatal(err)
  3407  	}
  3408  }
  3409  
  3410  func (s *DockerSuite) TestBuildEscapeWhitespace(c *check.C) {
  3411  	testRequires(c, DaemonIsLinux)
  3412  	name := "testbuildescaping"
  3413  
  3414  	_, err := buildImage(name, `
  3415    FROM busybox
  3416    MAINTAINER "Docker \
  3417  IO <io@\
  3418  docker.com>"
  3419    `, true)
  3420  	if err != nil {
  3421  		c.Fatal(err)
  3422  	}
  3423  
  3424  	res, err := inspectField(name, "Author")
  3425  
  3426  	if err != nil {
  3427  		c.Fatal(err)
  3428  	}
  3429  
  3430  	if res != "\"Docker IO <io@docker.com>\"" {
  3431  		c.Fatalf("Parsed string did not match the escaped string. Got: %q", res)
  3432  	}
  3433  
  3434  }
  3435  
  3436  func (s *DockerSuite) TestBuildVerifyIntString(c *check.C) {
  3437  	testRequires(c, DaemonIsLinux)
  3438  	// Verify that strings that look like ints are still passed as strings
  3439  	name := "testbuildstringing"
  3440  
  3441  	_, err := buildImage(name, `
  3442    FROM busybox
  3443    MAINTAINER 123
  3444    `, true)
  3445  
  3446  	if err != nil {
  3447  		c.Fatal(err)
  3448  	}
  3449  
  3450  	out, _ := dockerCmd(c, "inspect", name)
  3451  
  3452  	if !strings.Contains(out, "\"123\"") {
  3453  		c.Fatalf("Output does not contain the int as a string:\n%s", out)
  3454  	}
  3455  
  3456  }
  3457  
  3458  func (s *DockerSuite) TestBuildDockerignore(c *check.C) {
  3459  	testRequires(c, DaemonIsLinux)
  3460  	name := "testbuilddockerignore"
  3461  	dockerfile := `
  3462          FROM busybox
  3463          ADD . /bla
  3464  		RUN [[ -f /bla/src/x.go ]]
  3465  		RUN [[ -f /bla/Makefile ]]
  3466  		RUN [[ ! -e /bla/src/_vendor ]]
  3467  		RUN [[ ! -e /bla/.gitignore ]]
  3468  		RUN [[ ! -e /bla/README.md ]]
  3469  		RUN [[ ! -e /bla/dir/foo ]]
  3470  		RUN [[ ! -e /bla/foo ]]
  3471  		RUN [[ ! -e /bla/.git ]]
  3472  		RUN [[ ! -e v.cc ]]
  3473  		RUN [[ ! -e src/v.cc ]]
  3474  		RUN [[ ! -e src/_vendor/v.cc ]]`
  3475  	ctx, err := fakeContext(dockerfile, map[string]string{
  3476  		"Makefile":         "all:",
  3477  		".git/HEAD":        "ref: foo",
  3478  		"src/x.go":         "package main",
  3479  		"src/_vendor/v.go": "package main",
  3480  		"src/_vendor/v.cc": "package main",
  3481  		"src/v.cc":         "package main",
  3482  		"v.cc":             "package main",
  3483  		"dir/foo":          "",
  3484  		".gitignore":       "",
  3485  		"README.md":        "readme",
  3486  		".dockerignore": `
  3487  .git
  3488  pkg
  3489  .gitignore
  3490  src/_vendor
  3491  *.md
  3492  **/*.cc
  3493  dir`,
  3494  	})
  3495  	if err != nil {
  3496  		c.Fatal(err)
  3497  	}
  3498  	defer ctx.Close()
  3499  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3500  		c.Fatal(err)
  3501  	}
  3502  }
  3503  
  3504  func (s *DockerSuite) TestBuildDockerignoreCleanPaths(c *check.C) {
  3505  	testRequires(c, DaemonIsLinux)
  3506  	name := "testbuilddockerignorecleanpaths"
  3507  	dockerfile := `
  3508          FROM busybox
  3509          ADD . /tmp/
  3510          RUN (! ls /tmp/foo) && (! ls /tmp/foo2) && (! ls /tmp/dir1/foo)`
  3511  	ctx, err := fakeContext(dockerfile, map[string]string{
  3512  		"foo":           "foo",
  3513  		"foo2":          "foo2",
  3514  		"dir1/foo":      "foo in dir1",
  3515  		".dockerignore": "./foo\ndir1//foo\n./dir1/../foo2",
  3516  	})
  3517  	if err != nil {
  3518  		c.Fatal(err)
  3519  	}
  3520  	defer ctx.Close()
  3521  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3522  		c.Fatal(err)
  3523  	}
  3524  }
  3525  
  3526  func (s *DockerSuite) TestBuildDockerignoreExceptions(c *check.C) {
  3527  	testRequires(c, DaemonIsLinux)
  3528  	name := "testbuilddockerignoreexceptions"
  3529  	dockerfile := `
  3530          FROM busybox
  3531          ADD . /bla
  3532  		RUN [[ -f /bla/src/x.go ]]
  3533  		RUN [[ -f /bla/Makefile ]]
  3534  		RUN [[ ! -e /bla/src/_vendor ]]
  3535  		RUN [[ ! -e /bla/.gitignore ]]
  3536  		RUN [[ ! -e /bla/README.md ]]
  3537  		RUN [[  -e /bla/dir/dir/foo ]]
  3538  		RUN [[ ! -e /bla/dir/foo1 ]]
  3539  		RUN [[ -f /bla/dir/e ]]
  3540  		RUN [[ -f /bla/dir/e-dir/foo ]]
  3541  		RUN [[ ! -e /bla/foo ]]
  3542  		RUN [[ ! -e /bla/.git ]]
  3543  		RUN [[ -e /bla/dir/a.cc ]]`
  3544  	ctx, err := fakeContext(dockerfile, map[string]string{
  3545  		"Makefile":         "all:",
  3546  		".git/HEAD":        "ref: foo",
  3547  		"src/x.go":         "package main",
  3548  		"src/_vendor/v.go": "package main",
  3549  		"dir/foo":          "",
  3550  		"dir/foo1":         "",
  3551  		"dir/dir/f1":       "",
  3552  		"dir/dir/foo":      "",
  3553  		"dir/e":            "",
  3554  		"dir/e-dir/foo":    "",
  3555  		".gitignore":       "",
  3556  		"README.md":        "readme",
  3557  		"dir/a.cc":         "hello",
  3558  		".dockerignore": `
  3559  .git
  3560  pkg
  3561  .gitignore
  3562  src/_vendor
  3563  *.md
  3564  dir
  3565  !dir/e*
  3566  !dir/dir/foo
  3567  **/*.cc
  3568  !**/*.cc`,
  3569  	})
  3570  	if err != nil {
  3571  		c.Fatal(err)
  3572  	}
  3573  	defer ctx.Close()
  3574  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3575  		c.Fatal(err)
  3576  	}
  3577  }
  3578  
  3579  func (s *DockerSuite) TestBuildDockerignoringDockerfile(c *check.C) {
  3580  	testRequires(c, DaemonIsLinux)
  3581  	name := "testbuilddockerignoredockerfile"
  3582  	dockerfile := `
  3583          FROM busybox
  3584  		ADD . /tmp/
  3585  		RUN ! ls /tmp/Dockerfile
  3586  		RUN ls /tmp/.dockerignore`
  3587  	ctx, err := fakeContext(dockerfile, map[string]string{
  3588  		"Dockerfile":    dockerfile,
  3589  		".dockerignore": "Dockerfile\n",
  3590  	})
  3591  	if err != nil {
  3592  		c.Fatal(err)
  3593  	}
  3594  	defer ctx.Close()
  3595  
  3596  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3597  		c.Fatalf("Didn't ignore Dockerfile correctly:%s", err)
  3598  	}
  3599  
  3600  	// now try it with ./Dockerfile
  3601  	ctx.Add(".dockerignore", "./Dockerfile\n")
  3602  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3603  		c.Fatalf("Didn't ignore ./Dockerfile correctly:%s", err)
  3604  	}
  3605  
  3606  }
  3607  
  3608  func (s *DockerSuite) TestBuildDockerignoringRenamedDockerfile(c *check.C) {
  3609  	testRequires(c, DaemonIsLinux)
  3610  	name := "testbuilddockerignoredockerfile"
  3611  	dockerfile := `
  3612          FROM busybox
  3613  		ADD . /tmp/
  3614  		RUN ls /tmp/Dockerfile
  3615  		RUN ! ls /tmp/MyDockerfile
  3616  		RUN ls /tmp/.dockerignore`
  3617  	ctx, err := fakeContext(dockerfile, map[string]string{
  3618  		"Dockerfile":    "Should not use me",
  3619  		"MyDockerfile":  dockerfile,
  3620  		".dockerignore": "MyDockerfile\n",
  3621  	})
  3622  	if err != nil {
  3623  		c.Fatal(err)
  3624  	}
  3625  	defer ctx.Close()
  3626  
  3627  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3628  		c.Fatalf("Didn't ignore MyDockerfile correctly:%s", err)
  3629  	}
  3630  
  3631  	// now try it with ./MyDockerfile
  3632  	ctx.Add(".dockerignore", "./MyDockerfile\n")
  3633  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3634  		c.Fatalf("Didn't ignore ./MyDockerfile correctly:%s", err)
  3635  	}
  3636  
  3637  }
  3638  
  3639  func (s *DockerSuite) TestBuildDockerignoringDockerignore(c *check.C) {
  3640  	testRequires(c, DaemonIsLinux)
  3641  	name := "testbuilddockerignoredockerignore"
  3642  	dockerfile := `
  3643          FROM busybox
  3644  		ADD . /tmp/
  3645  		RUN ! ls /tmp/.dockerignore
  3646  		RUN ls /tmp/Dockerfile`
  3647  	ctx, err := fakeContext(dockerfile, map[string]string{
  3648  		"Dockerfile":    dockerfile,
  3649  		".dockerignore": ".dockerignore\n",
  3650  	})
  3651  	if err != nil {
  3652  		c.Fatal(err)
  3653  	}
  3654  	defer ctx.Close()
  3655  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3656  		c.Fatalf("Didn't ignore .dockerignore correctly:%s", err)
  3657  	}
  3658  }
  3659  
  3660  func (s *DockerSuite) TestBuildDockerignoreTouchDockerfile(c *check.C) {
  3661  	testRequires(c, DaemonIsLinux)
  3662  	var id1 string
  3663  	var id2 string
  3664  
  3665  	name := "testbuilddockerignoretouchdockerfile"
  3666  	dockerfile := `
  3667          FROM busybox
  3668  		ADD . /tmp/`
  3669  	ctx, err := fakeContext(dockerfile, map[string]string{
  3670  		"Dockerfile":    dockerfile,
  3671  		".dockerignore": "Dockerfile\n",
  3672  	})
  3673  	if err != nil {
  3674  		c.Fatal(err)
  3675  	}
  3676  	defer ctx.Close()
  3677  
  3678  	if id1, err = buildImageFromContext(name, ctx, true); err != nil {
  3679  		c.Fatalf("Didn't build it correctly:%s", err)
  3680  	}
  3681  
  3682  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3683  		c.Fatalf("Didn't build it correctly:%s", err)
  3684  	}
  3685  	if id1 != id2 {
  3686  		c.Fatalf("Didn't use the cache - 1")
  3687  	}
  3688  
  3689  	// Now make sure touching Dockerfile doesn't invalidate the cache
  3690  	if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3691  		c.Fatalf("Didn't add Dockerfile: %s", err)
  3692  	}
  3693  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3694  		c.Fatalf("Didn't build it correctly:%s", err)
  3695  	}
  3696  	if id1 != id2 {
  3697  		c.Fatalf("Didn't use the cache - 2")
  3698  	}
  3699  
  3700  	// One more time but just 'touch' it instead of changing the content
  3701  	if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3702  		c.Fatalf("Didn't add Dockerfile: %s", err)
  3703  	}
  3704  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3705  		c.Fatalf("Didn't build it correctly:%s", err)
  3706  	}
  3707  	if id1 != id2 {
  3708  		c.Fatalf("Didn't use the cache - 3")
  3709  	}
  3710  
  3711  }
  3712  
  3713  func (s *DockerSuite) TestBuildDockerignoringWholeDir(c *check.C) {
  3714  	testRequires(c, DaemonIsLinux)
  3715  	name := "testbuilddockerignorewholedir"
  3716  	dockerfile := `
  3717          FROM busybox
  3718  		COPY . /
  3719  		RUN [[ ! -e /.gitignore ]]
  3720  		RUN [[ -f /Makefile ]]`
  3721  	ctx, err := fakeContext(dockerfile, map[string]string{
  3722  		"Dockerfile":    "FROM scratch",
  3723  		"Makefile":      "all:",
  3724  		".gitignore":    "",
  3725  		".dockerignore": ".*\n",
  3726  	})
  3727  	c.Assert(err, check.IsNil)
  3728  	defer ctx.Close()
  3729  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3730  		c.Fatal(err)
  3731  	}
  3732  
  3733  	c.Assert(ctx.Add(".dockerfile", "*"), check.IsNil)
  3734  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3735  		c.Fatal(err)
  3736  	}
  3737  
  3738  	c.Assert(ctx.Add(".dockerfile", "."), check.IsNil)
  3739  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3740  		c.Fatal(err)
  3741  	}
  3742  
  3743  	c.Assert(ctx.Add(".dockerfile", "?"), check.IsNil)
  3744  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3745  		c.Fatal(err)
  3746  	}
  3747  }
  3748  
  3749  func (s *DockerSuite) TestBuildDockerignoringBadExclusion(c *check.C) {
  3750  	testRequires(c, DaemonIsLinux)
  3751  	name := "testbuilddockerignorebadexclusion"
  3752  	dockerfile := `
  3753          FROM busybox
  3754  		COPY . /
  3755  		RUN [[ ! -e /.gitignore ]]
  3756  		RUN [[ -f /Makefile ]]`
  3757  	ctx, err := fakeContext(dockerfile, map[string]string{
  3758  		"Dockerfile":    "FROM scratch",
  3759  		"Makefile":      "all:",
  3760  		".gitignore":    "",
  3761  		".dockerignore": "!\n",
  3762  	})
  3763  	c.Assert(err, check.IsNil)
  3764  	defer ctx.Close()
  3765  	if _, err = buildImageFromContext(name, ctx, true); err == nil {
  3766  		c.Fatalf("Build was supposed to fail but didn't")
  3767  	}
  3768  
  3769  	if err.Error() != "failed to build the image: Error checking context: 'Illegal exclusion pattern: !'.\n" {
  3770  		c.Fatalf("Incorrect output, got:%q", err.Error())
  3771  	}
  3772  }
  3773  
  3774  func (s *DockerSuite) TestBuildDockerignoringWildTopDir(c *check.C) {
  3775  	testRequires(c, DaemonIsLinux)
  3776  
  3777  	dockerfile := `
  3778          FROM busybox
  3779  		COPY . /
  3780  		RUN [[ ! -e /.dockerignore ]]
  3781  		RUN [[ ! -e /Dockerfile ]]
  3782  		RUN [[ ! -e /file1 ]]
  3783  		RUN [[ ! -e /dir ]]`
  3784  
  3785  	ctx, err := fakeContext(dockerfile, map[string]string{
  3786  		"Dockerfile": "FROM scratch",
  3787  		"file1":      "",
  3788  		"dir/dfile1": "",
  3789  	})
  3790  	c.Assert(err, check.IsNil)
  3791  	defer ctx.Close()
  3792  
  3793  	// All of these should result in ignoring all files
  3794  	for _, variant := range []string{"**", "**/", "**/**", "*"} {
  3795  		ctx.Add(".dockerignore", variant)
  3796  		_, err = buildImageFromContext("noname", ctx, true)
  3797  		c.Assert(err, check.IsNil, check.Commentf("variant: %s", variant))
  3798  	}
  3799  }
  3800  
  3801  func (s *DockerSuite) TestBuildDockerignoringWildDirs(c *check.C) {
  3802  	testRequires(c, DaemonIsLinux)
  3803  
  3804  	dockerfile := `
  3805          FROM busybox
  3806  		COPY . /
  3807  		RUN [[ -e /.dockerignore ]]
  3808  		RUN [[ -e /Dockerfile ]]
  3809  
  3810  		RUN [[ ! -e /file0 ]]
  3811  		RUN [[ ! -e /dir1/file0 ]]
  3812  		RUN [[ ! -e /dir2/file0 ]]
  3813  
  3814  		RUN [[ ! -e /file1 ]]
  3815  		RUN [[ ! -e /dir1/file1 ]]
  3816  		RUN [[ ! -e /dir1/dir2/file1 ]]
  3817  
  3818  		RUN [[ ! -e /dir1/file2 ]]
  3819  		RUN [[   -e /dir1/dir2/file2 ]]
  3820  
  3821  		RUN [[ ! -e /dir1/dir2/file4 ]]
  3822  		RUN [[ ! -e /dir1/dir2/file5 ]]
  3823  		RUN [[ ! -e /dir1/dir2/file6 ]]
  3824  		RUN [[ ! -e /dir1/dir3/file7 ]]
  3825  		RUN [[ ! -e /dir1/dir3/file8 ]]
  3826  		RUN [[   -e /dir1/dir3 ]]
  3827  		RUN [[   -e /dir1/dir4 ]]
  3828  
  3829  		RUN [[ ! -e 'dir1/dir5/fileAA' ]]
  3830  		RUN [[   -e 'dir1/dir5/fileAB' ]]
  3831  		RUN [[   -e 'dir1/dir5/fileB' ]]   # "." in pattern means nothing
  3832  
  3833  		RUN echo all done!`
  3834  
  3835  	ctx, err := fakeContext(dockerfile, map[string]string{
  3836  		"Dockerfile":      "FROM scratch",
  3837  		"file0":           "",
  3838  		"dir1/file0":      "",
  3839  		"dir1/dir2/file0": "",
  3840  
  3841  		"file1":           "",
  3842  		"dir1/file1":      "",
  3843  		"dir1/dir2/file1": "",
  3844  
  3845  		"dir1/file2":      "",
  3846  		"dir1/dir2/file2": "", // remains
  3847  
  3848  		"dir1/dir2/file4": "",
  3849  		"dir1/dir2/file5": "",
  3850  		"dir1/dir2/file6": "",
  3851  		"dir1/dir3/file7": "",
  3852  		"dir1/dir3/file8": "",
  3853  		"dir1/dir4/file9": "",
  3854  
  3855  		"dir1/dir5/fileAA": "",
  3856  		"dir1/dir5/fileAB": "",
  3857  		"dir1/dir5/fileB":  "",
  3858  
  3859  		".dockerignore": `
  3860  **/file0
  3861  **/*file1
  3862  **/dir1/file2
  3863  dir1/**/file4
  3864  **/dir2/file5
  3865  **/dir1/dir2/file6
  3866  dir1/dir3/**
  3867  **/dir4/**
  3868  **/file?A
  3869  **/file\?B
  3870  **/dir5/file.
  3871  `,
  3872  	})
  3873  	c.Assert(err, check.IsNil)
  3874  	defer ctx.Close()
  3875  
  3876  	_, err = buildImageFromContext("noname", ctx, true)
  3877  	c.Assert(err, check.IsNil)
  3878  }
  3879  
  3880  func (s *DockerSuite) TestBuildLineBreak(c *check.C) {
  3881  	testRequires(c, DaemonIsLinux)
  3882  	name := "testbuildlinebreak"
  3883  	_, err := buildImage(name,
  3884  		`FROM  busybox
  3885  RUN    sh -c 'echo root:testpass \
  3886  	> /tmp/passwd'
  3887  RUN    mkdir -p /var/run/sshd
  3888  RUN    [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3889  RUN    [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3890  		true)
  3891  	if err != nil {
  3892  		c.Fatal(err)
  3893  	}
  3894  }
  3895  
  3896  func (s *DockerSuite) TestBuildEOLInLine(c *check.C) {
  3897  	testRequires(c, DaemonIsLinux)
  3898  	name := "testbuildeolinline"
  3899  	_, err := buildImage(name,
  3900  		`FROM   busybox
  3901  RUN    sh -c 'echo root:testpass > /tmp/passwd'
  3902  RUN    echo "foo \n bar"; echo "baz"
  3903  RUN    mkdir -p /var/run/sshd
  3904  RUN    [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3905  RUN    [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3906  		true)
  3907  	if err != nil {
  3908  		c.Fatal(err)
  3909  	}
  3910  }
  3911  
  3912  func (s *DockerSuite) TestBuildCommentsShebangs(c *check.C) {
  3913  	testRequires(c, DaemonIsLinux)
  3914  	name := "testbuildcomments"
  3915  	_, err := buildImage(name,
  3916  		`FROM busybox
  3917  # This is an ordinary comment.
  3918  RUN { echo '#!/bin/sh'; echo 'echo hello world'; } > /hello.sh
  3919  RUN [ ! -x /hello.sh ]
  3920  # comment with line break \
  3921  RUN chmod +x /hello.sh
  3922  RUN [ -x /hello.sh ]
  3923  RUN [ "$(cat /hello.sh)" = $'#!/bin/sh\necho hello world' ]
  3924  RUN [ "$(/hello.sh)" = "hello world" ]`,
  3925  		true)
  3926  	if err != nil {
  3927  		c.Fatal(err)
  3928  	}
  3929  }
  3930  
  3931  func (s *DockerSuite) TestBuildUsersAndGroups(c *check.C) {
  3932  	testRequires(c, DaemonIsLinux)
  3933  	name := "testbuildusers"
  3934  	_, err := buildImage(name,
  3935  		`FROM busybox
  3936  
  3937  # Make sure our defaults work
  3938  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)" = '0:0/root:root' ]
  3939  
  3940  # TODO decide if "args.user = strconv.Itoa(syscall.Getuid())" is acceptable behavior for changeUser in sysvinit instead of "return nil" when "USER" isn't specified (so that we get the proper group list even if that is the empty list, even in the default case of not supplying an explicit USER to run as, which implies USER 0)
  3941  USER root
  3942  RUN [ "$(id -G):$(id -Gn)" = '0 10:root wheel' ]
  3943  
  3944  # Setup dockerio user and group
  3945  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  3946  RUN echo 'dockerio:x:1001:' >> /etc/group
  3947  
  3948  # Make sure we can switch to our user and all the information is exactly as we expect it to be
  3949  USER dockerio
  3950  RUN id -G
  3951  RUN id -Gn
  3952  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3953  
  3954  # Switch back to root and double check that worked exactly as we might expect it to
  3955  USER root
  3956  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '0:0/root:root/0 10:root wheel' ]
  3957  
  3958  # Add a "supplementary" group for our dockerio user
  3959  RUN echo 'supplementary:x:1002:dockerio' >> /etc/group
  3960  
  3961  # ... and then go verify that we get it like we expect
  3962  USER dockerio
  3963  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3964  USER 1001
  3965  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3966  
  3967  # super test the new "user:group" syntax
  3968  USER dockerio:dockerio
  3969  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3970  USER 1001:dockerio
  3971  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3972  USER dockerio:1001
  3973  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3974  USER 1001:1001
  3975  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3976  USER dockerio:supplementary
  3977  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3978  USER dockerio:1002
  3979  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3980  USER 1001:supplementary
  3981  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3982  USER 1001:1002
  3983  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3984  
  3985  # make sure unknown uid/gid still works properly
  3986  USER 1042:1043
  3987  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1042:1043/1042:1043/1043:1043' ]`,
  3988  		true)
  3989  	if err != nil {
  3990  		c.Fatal(err)
  3991  	}
  3992  }
  3993  
  3994  func (s *DockerSuite) TestBuildEnvUsage(c *check.C) {
  3995  	// /docker/world/hello is not owned by the correct user
  3996  	testRequires(c, NotUserNamespace)
  3997  	testRequires(c, DaemonIsLinux)
  3998  	name := "testbuildenvusage"
  3999  	dockerfile := `FROM busybox
  4000  ENV    HOME /root
  4001  ENV    PATH $HOME/bin:$PATH
  4002  ENV    PATH /tmp:$PATH
  4003  RUN    [ "$PATH" = "/tmp:$HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ]
  4004  ENV    FOO /foo/baz
  4005  ENV    BAR /bar
  4006  ENV    BAZ $BAR
  4007  ENV    FOOPATH $PATH:$FOO
  4008  RUN    [ "$BAR" = "$BAZ" ]
  4009  RUN    [ "$FOOPATH" = "$PATH:/foo/baz" ]
  4010  ENV	   FROM hello/docker/world
  4011  ENV    TO /docker/world/hello
  4012  ADD    $FROM $TO
  4013  RUN    [ "$(cat $TO)" = "hello" ]
  4014  ENV    abc=def
  4015  ENV    ghi=$abc
  4016  RUN    [ "$ghi" = "def" ]
  4017  `
  4018  	ctx, err := fakeContext(dockerfile, map[string]string{
  4019  		"hello/docker/world": "hello",
  4020  	})
  4021  	if err != nil {
  4022  		c.Fatal(err)
  4023  	}
  4024  	defer ctx.Close()
  4025  
  4026  	_, err = buildImageFromContext(name, ctx, true)
  4027  	if err != nil {
  4028  		c.Fatal(err)
  4029  	}
  4030  }
  4031  
  4032  func (s *DockerSuite) TestBuildEnvUsage2(c *check.C) {
  4033  	// /docker/world/hello is not owned by the correct user
  4034  	testRequires(c, NotUserNamespace)
  4035  	testRequires(c, DaemonIsLinux)
  4036  	name := "testbuildenvusage2"
  4037  	dockerfile := `FROM busybox
  4038  ENV    abc=def
  4039  RUN    [ "$abc" = "def" ]
  4040  ENV    def="hello world"
  4041  RUN    [ "$def" = "hello world" ]
  4042  ENV    def=hello\ world
  4043  RUN    [ "$def" = "hello world" ]
  4044  ENV    v1=abc v2="hi there"
  4045  RUN    [ "$v1" = "abc" ]
  4046  RUN    [ "$v2" = "hi there" ]
  4047  ENV    v3='boogie nights' v4="with'quotes too"
  4048  RUN    [ "$v3" = "boogie nights" ]
  4049  RUN    [ "$v4" = "with'quotes too" ]
  4050  ENV    abc=zzz FROM=hello/docker/world
  4051  ENV    abc=zzz TO=/docker/world/hello
  4052  ADD    $FROM $TO
  4053  RUN    [ "$(cat $TO)" = "hello" ]
  4054  ENV    abc "zzz"
  4055  RUN    [ $abc = "zzz" ]
  4056  ENV    abc 'yyy'
  4057  RUN    [ $abc = 'yyy' ]
  4058  ENV    abc=
  4059  RUN    [ "$abc" = "" ]
  4060  
  4061  # use grep to make sure if the builder substitutes \$foo by mistake
  4062  # we don't get a false positive
  4063  ENV    abc=\$foo
  4064  RUN    [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  4065  ENV    abc \$foo
  4066  RUN    [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  4067  
  4068  ENV    abc=\'foo\'
  4069  RUN    [ "$abc" = "'foo'" ]
  4070  ENV    abc=\"foo\"
  4071  RUN    [ "$abc" = "\"foo\"" ]
  4072  ENV    abc "foo"
  4073  RUN    [ "$abc" = "foo" ]
  4074  ENV    abc 'foo'
  4075  RUN    [ "$abc" = 'foo' ]
  4076  ENV    abc \'foo\'
  4077  RUN    [ "$abc" = "'foo'" ]
  4078  ENV    abc \"foo\"
  4079  RUN    [ "$abc" = '"foo"' ]
  4080  
  4081  ENV    abc=ABC
  4082  RUN    [ "$abc" = "ABC" ]
  4083  ENV    def=${abc:-DEF}
  4084  RUN    [ "$def" = "ABC" ]
  4085  ENV    def=${ccc:-DEF}
  4086  RUN    [ "$def" = "DEF" ]
  4087  ENV    def=${ccc:-${def}xx}
  4088  RUN    [ "$def" = "DEFxx" ]
  4089  ENV    def=${def:+ALT}
  4090  RUN    [ "$def" = "ALT" ]
  4091  ENV    def=${def:+${abc}:}
  4092  RUN    [ "$def" = "ABC:" ]
  4093  ENV    def=${ccc:-\$abc:}
  4094  RUN    [ "$def" = '$abc:' ]
  4095  ENV    def=${ccc:-\${abc}:}
  4096  RUN    [ "$def" = '${abc:}' ]
  4097  ENV    mypath=${mypath:+$mypath:}/home
  4098  RUN    [ "$mypath" = '/home' ]
  4099  ENV    mypath=${mypath:+$mypath:}/away
  4100  RUN    [ "$mypath" = '/home:/away' ]
  4101  
  4102  ENV    e1=bar
  4103  ENV    e2=$e1
  4104  ENV    e3=$e11
  4105  ENV    e4=\$e1
  4106  ENV    e5=\$e11
  4107  RUN    [ "$e0,$e1,$e2,$e3,$e4,$e5" = ',bar,bar,,$e1,$e11' ]
  4108  
  4109  ENV    ee1 bar
  4110  ENV    ee2 $ee1
  4111  ENV    ee3 $ee11
  4112  ENV    ee4 \$ee1
  4113  ENV    ee5 \$ee11
  4114  RUN    [ "$ee1,$ee2,$ee3,$ee4,$ee5" = 'bar,bar,,$ee1,$ee11' ]
  4115  
  4116  ENV    eee1="foo"
  4117  ENV    eee2='foo'
  4118  ENV    eee3 "foo"
  4119  ENV    eee4 'foo'
  4120  RUN    [ "$eee1,$eee2,$eee3,$eee4" = 'foo,foo,foo,foo' ]
  4121  
  4122  `
  4123  	ctx, err := fakeContext(dockerfile, map[string]string{
  4124  		"hello/docker/world": "hello",
  4125  	})
  4126  	if err != nil {
  4127  		c.Fatal(err)
  4128  	}
  4129  	defer ctx.Close()
  4130  
  4131  	_, err = buildImageFromContext(name, ctx, true)
  4132  	if err != nil {
  4133  		c.Fatal(err)
  4134  	}
  4135  }
  4136  
  4137  func (s *DockerSuite) TestBuildAddScript(c *check.C) {
  4138  	testRequires(c, DaemonIsLinux)
  4139  	name := "testbuildaddscript"
  4140  	dockerfile := `
  4141  FROM busybox
  4142  ADD test /test
  4143  RUN ["chmod","+x","/test"]
  4144  RUN ["/test"]
  4145  RUN [ "$(cat /testfile)" = 'test!' ]`
  4146  	ctx, err := fakeContext(dockerfile, map[string]string{
  4147  		"test": "#!/bin/sh\necho 'test!' > /testfile",
  4148  	})
  4149  	if err != nil {
  4150  		c.Fatal(err)
  4151  	}
  4152  	defer ctx.Close()
  4153  
  4154  	_, err = buildImageFromContext(name, ctx, true)
  4155  	if err != nil {
  4156  		c.Fatal(err)
  4157  	}
  4158  }
  4159  
  4160  func (s *DockerSuite) TestBuildAddTar(c *check.C) {
  4161  	// /test/foo is not owned by the correct user
  4162  	testRequires(c, NotUserNamespace)
  4163  	testRequires(c, DaemonIsLinux)
  4164  	name := "testbuildaddtar"
  4165  
  4166  	ctx := func() *FakeContext {
  4167  		dockerfile := `
  4168  FROM busybox
  4169  ADD test.tar /
  4170  RUN cat /test/foo | grep Hi
  4171  ADD test.tar /test.tar
  4172  RUN cat /test.tar/test/foo | grep Hi
  4173  ADD test.tar /unlikely-to-exist
  4174  RUN cat /unlikely-to-exist/test/foo | grep Hi
  4175  ADD test.tar /unlikely-to-exist-trailing-slash/
  4176  RUN cat /unlikely-to-exist-trailing-slash/test/foo | grep Hi
  4177  RUN mkdir /existing-directory
  4178  ADD test.tar /existing-directory
  4179  RUN cat /existing-directory/test/foo | grep Hi
  4180  ADD test.tar /existing-directory-trailing-slash/
  4181  RUN cat /existing-directory-trailing-slash/test/foo | grep Hi`
  4182  		tmpDir, err := ioutil.TempDir("", "fake-context")
  4183  		c.Assert(err, check.IsNil)
  4184  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  4185  		if err != nil {
  4186  			c.Fatalf("failed to create test.tar archive: %v", err)
  4187  		}
  4188  		defer testTar.Close()
  4189  
  4190  		tw := tar.NewWriter(testTar)
  4191  
  4192  		if err := tw.WriteHeader(&tar.Header{
  4193  			Name: "test/foo",
  4194  			Size: 2,
  4195  		}); err != nil {
  4196  			c.Fatalf("failed to write tar file header: %v", err)
  4197  		}
  4198  		if _, err := tw.Write([]byte("Hi")); err != nil {
  4199  			c.Fatalf("failed to write tar file content: %v", err)
  4200  		}
  4201  		if err := tw.Close(); err != nil {
  4202  			c.Fatalf("failed to close tar archive: %v", err)
  4203  		}
  4204  
  4205  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  4206  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4207  		}
  4208  		return fakeContextFromDir(tmpDir)
  4209  	}()
  4210  	defer ctx.Close()
  4211  
  4212  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4213  		c.Fatalf("build failed to complete for TestBuildAddTar: %v", err)
  4214  	}
  4215  
  4216  }
  4217  
  4218  func (s *DockerSuite) TestBuildAddBrokenTar(c *check.C) {
  4219  	testRequires(c, DaemonIsLinux)
  4220  	name := "testbuildaddbrokentar"
  4221  
  4222  	ctx := func() *FakeContext {
  4223  		dockerfile := `
  4224  FROM busybox
  4225  ADD test.tar /`
  4226  		tmpDir, err := ioutil.TempDir("", "fake-context")
  4227  		c.Assert(err, check.IsNil)
  4228  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  4229  		if err != nil {
  4230  			c.Fatalf("failed to create test.tar archive: %v", err)
  4231  		}
  4232  		defer testTar.Close()
  4233  
  4234  		tw := tar.NewWriter(testTar)
  4235  
  4236  		if err := tw.WriteHeader(&tar.Header{
  4237  			Name: "test/foo",
  4238  			Size: 2,
  4239  		}); err != nil {
  4240  			c.Fatalf("failed to write tar file header: %v", err)
  4241  		}
  4242  		if _, err := tw.Write([]byte("Hi")); err != nil {
  4243  			c.Fatalf("failed to write tar file content: %v", err)
  4244  		}
  4245  		if err := tw.Close(); err != nil {
  4246  			c.Fatalf("failed to close tar archive: %v", err)
  4247  		}
  4248  
  4249  		// Corrupt the tar by removing one byte off the end
  4250  		stat, err := testTar.Stat()
  4251  		if err != nil {
  4252  			c.Fatalf("failed to stat tar archive: %v", err)
  4253  		}
  4254  		if err := testTar.Truncate(stat.Size() - 1); err != nil {
  4255  			c.Fatalf("failed to truncate tar archive: %v", err)
  4256  		}
  4257  
  4258  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  4259  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4260  		}
  4261  		return fakeContextFromDir(tmpDir)
  4262  	}()
  4263  	defer ctx.Close()
  4264  
  4265  	if _, err := buildImageFromContext(name, ctx, true); err == nil {
  4266  		c.Fatalf("build should have failed for TestBuildAddBrokenTar")
  4267  	}
  4268  }
  4269  
  4270  func (s *DockerSuite) TestBuildAddNonTar(c *check.C) {
  4271  	testRequires(c, DaemonIsLinux)
  4272  	name := "testbuildaddnontar"
  4273  
  4274  	// Should not try to extract test.tar
  4275  	ctx, err := fakeContext(`
  4276  		FROM busybox
  4277  		ADD test.tar /
  4278  		RUN test -f /test.tar`,
  4279  		map[string]string{"test.tar": "not_a_tar_file"})
  4280  
  4281  	if err != nil {
  4282  		c.Fatal(err)
  4283  	}
  4284  	defer ctx.Close()
  4285  
  4286  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4287  		c.Fatalf("build failed for TestBuildAddNonTar")
  4288  	}
  4289  }
  4290  
  4291  func (s *DockerSuite) TestBuildAddTarXz(c *check.C) {
  4292  	// /test/foo is not owned by the correct user
  4293  	testRequires(c, NotUserNamespace)
  4294  	testRequires(c, DaemonIsLinux)
  4295  	name := "testbuildaddtarxz"
  4296  
  4297  	ctx := func() *FakeContext {
  4298  		dockerfile := `
  4299  			FROM busybox
  4300  			ADD test.tar.xz /
  4301  			RUN cat /test/foo | grep Hi`
  4302  		tmpDir, err := ioutil.TempDir("", "fake-context")
  4303  		c.Assert(err, check.IsNil)
  4304  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  4305  		if err != nil {
  4306  			c.Fatalf("failed to create test.tar archive: %v", err)
  4307  		}
  4308  		defer testTar.Close()
  4309  
  4310  		tw := tar.NewWriter(testTar)
  4311  
  4312  		if err := tw.WriteHeader(&tar.Header{
  4313  			Name: "test/foo",
  4314  			Size: 2,
  4315  		}); err != nil {
  4316  			c.Fatalf("failed to write tar file header: %v", err)
  4317  		}
  4318  		if _, err := tw.Write([]byte("Hi")); err != nil {
  4319  			c.Fatalf("failed to write tar file content: %v", err)
  4320  		}
  4321  		if err := tw.Close(); err != nil {
  4322  			c.Fatalf("failed to close tar archive: %v", err)
  4323  		}
  4324  
  4325  		xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  4326  		xzCompressCmd.Dir = tmpDir
  4327  		out, _, err := runCommandWithOutput(xzCompressCmd)
  4328  		if err != nil {
  4329  			c.Fatal(err, out)
  4330  		}
  4331  
  4332  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  4333  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4334  		}
  4335  		return fakeContextFromDir(tmpDir)
  4336  	}()
  4337  
  4338  	defer ctx.Close()
  4339  
  4340  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4341  		c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  4342  	}
  4343  
  4344  }
  4345  
  4346  func (s *DockerSuite) TestBuildAddTarXzGz(c *check.C) {
  4347  	testRequires(c, DaemonIsLinux)
  4348  	name := "testbuildaddtarxzgz"
  4349  
  4350  	ctx := func() *FakeContext {
  4351  		dockerfile := `
  4352  			FROM busybox
  4353  			ADD test.tar.xz.gz /
  4354  			RUN ls /test.tar.xz.gz`
  4355  		tmpDir, err := ioutil.TempDir("", "fake-context")
  4356  		c.Assert(err, check.IsNil)
  4357  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  4358  		if err != nil {
  4359  			c.Fatalf("failed to create test.tar archive: %v", err)
  4360  		}
  4361  		defer testTar.Close()
  4362  
  4363  		tw := tar.NewWriter(testTar)
  4364  
  4365  		if err := tw.WriteHeader(&tar.Header{
  4366  			Name: "test/foo",
  4367  			Size: 2,
  4368  		}); err != nil {
  4369  			c.Fatalf("failed to write tar file header: %v", err)
  4370  		}
  4371  		if _, err := tw.Write([]byte("Hi")); err != nil {
  4372  			c.Fatalf("failed to write tar file content: %v", err)
  4373  		}
  4374  		if err := tw.Close(); err != nil {
  4375  			c.Fatalf("failed to close tar archive: %v", err)
  4376  		}
  4377  
  4378  		xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  4379  		xzCompressCmd.Dir = tmpDir
  4380  		out, _, err := runCommandWithOutput(xzCompressCmd)
  4381  		if err != nil {
  4382  			c.Fatal(err, out)
  4383  		}
  4384  
  4385  		gzipCompressCmd := exec.Command("gzip", "test.tar.xz")
  4386  		gzipCompressCmd.Dir = tmpDir
  4387  		out, _, err = runCommandWithOutput(gzipCompressCmd)
  4388  		if err != nil {
  4389  			c.Fatal(err, out)
  4390  		}
  4391  
  4392  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  4393  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4394  		}
  4395  		return fakeContextFromDir(tmpDir)
  4396  	}()
  4397  
  4398  	defer ctx.Close()
  4399  
  4400  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4401  		c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  4402  	}
  4403  
  4404  }
  4405  
  4406  func (s *DockerSuite) TestBuildFromGIT(c *check.C) {
  4407  	testRequires(c, DaemonIsLinux)
  4408  	name := "testbuildfromgit"
  4409  	git, err := newFakeGit("repo", map[string]string{
  4410  		"Dockerfile": `FROM busybox
  4411  					ADD first /first
  4412  					RUN [ -f /first ]
  4413  					MAINTAINER docker`,
  4414  		"first": "test git data",
  4415  	}, true)
  4416  	if err != nil {
  4417  		c.Fatal(err)
  4418  	}
  4419  	defer git.Close()
  4420  
  4421  	_, err = buildImageFromPath(name, git.RepoURL, true)
  4422  	if err != nil {
  4423  		c.Fatal(err)
  4424  	}
  4425  	res, err := inspectField(name, "Author")
  4426  	if err != nil {
  4427  		c.Fatal(err)
  4428  	}
  4429  	if res != "docker" {
  4430  		c.Fatalf("Maintainer should be docker, got %s", res)
  4431  	}
  4432  }
  4433  
  4434  func (s *DockerSuite) TestBuildFromGITWithContext(c *check.C) {
  4435  	testRequires(c, DaemonIsLinux)
  4436  	name := "testbuildfromgit"
  4437  	git, err := newFakeGit("repo", map[string]string{
  4438  		"docker/Dockerfile": `FROM busybox
  4439  					ADD first /first
  4440  					RUN [ -f /first ]
  4441  					MAINTAINER docker`,
  4442  		"docker/first": "test git data",
  4443  	}, true)
  4444  	if err != nil {
  4445  		c.Fatal(err)
  4446  	}
  4447  	defer git.Close()
  4448  
  4449  	u := fmt.Sprintf("%s#master:docker", git.RepoURL)
  4450  	_, err = buildImageFromPath(name, u, true)
  4451  	if err != nil {
  4452  		c.Fatal(err)
  4453  	}
  4454  	res, err := inspectField(name, "Author")
  4455  	if err != nil {
  4456  		c.Fatal(err)
  4457  	}
  4458  	if res != "docker" {
  4459  		c.Fatalf("Maintainer should be docker, got %s", res)
  4460  	}
  4461  }
  4462  
  4463  func (s *DockerSuite) TestBuildFromGITwithF(c *check.C) {
  4464  	testRequires(c, DaemonIsLinux)
  4465  	name := "testbuildfromgitwithf"
  4466  	git, err := newFakeGit("repo", map[string]string{
  4467  		"myApp/myDockerfile": `FROM busybox
  4468  					RUN echo hi from Dockerfile`,
  4469  	}, true)
  4470  	if err != nil {
  4471  		c.Fatal(err)
  4472  	}
  4473  	defer git.Close()
  4474  
  4475  	out, _, err := dockerCmdWithError("build", "-t", name, "--no-cache", "-f", "myApp/myDockerfile", git.RepoURL)
  4476  	if err != nil {
  4477  		c.Fatalf("Error on build. Out: %s\nErr: %v", out, err)
  4478  	}
  4479  
  4480  	if !strings.Contains(out, "hi from Dockerfile") {
  4481  		c.Fatalf("Missing expected output, got:\n%s", out)
  4482  	}
  4483  }
  4484  
  4485  func (s *DockerSuite) TestBuildFromRemoteTarball(c *check.C) {
  4486  	testRequires(c, DaemonIsLinux)
  4487  	name := "testbuildfromremotetarball"
  4488  
  4489  	buffer := new(bytes.Buffer)
  4490  	tw := tar.NewWriter(buffer)
  4491  	defer tw.Close()
  4492  
  4493  	dockerfile := []byte(`FROM busybox
  4494  					MAINTAINER docker`)
  4495  	if err := tw.WriteHeader(&tar.Header{
  4496  		Name: "Dockerfile",
  4497  		Size: int64(len(dockerfile)),
  4498  	}); err != nil {
  4499  		c.Fatalf("failed to write tar file header: %v", err)
  4500  	}
  4501  	if _, err := tw.Write(dockerfile); err != nil {
  4502  		c.Fatalf("failed to write tar file content: %v", err)
  4503  	}
  4504  	if err := tw.Close(); err != nil {
  4505  		c.Fatalf("failed to close tar archive: %v", err)
  4506  	}
  4507  
  4508  	server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
  4509  		"testT.tar": buffer,
  4510  	})
  4511  	c.Assert(err, check.IsNil)
  4512  
  4513  	defer server.Close()
  4514  
  4515  	_, err = buildImageFromPath(name, server.URL()+"/testT.tar", true)
  4516  	c.Assert(err, check.IsNil)
  4517  
  4518  	res, err := inspectField(name, "Author")
  4519  	c.Assert(err, check.IsNil)
  4520  
  4521  	if res != "docker" {
  4522  		c.Fatalf("Maintainer should be docker, got %s", res)
  4523  	}
  4524  }
  4525  
  4526  func (s *DockerSuite) TestBuildCleanupCmdOnEntrypoint(c *check.C) {
  4527  	testRequires(c, DaemonIsLinux)
  4528  	name := "testbuildcmdcleanuponentrypoint"
  4529  	if _, err := buildImage(name,
  4530  		`FROM scratch
  4531          CMD ["test"]
  4532  		ENTRYPOINT ["echo"]`,
  4533  		true); err != nil {
  4534  		c.Fatal(err)
  4535  	}
  4536  	if _, err := buildImage(name,
  4537  		fmt.Sprintf(`FROM %s
  4538  		ENTRYPOINT ["cat"]`, name),
  4539  		true); err != nil {
  4540  		c.Fatal(err)
  4541  	}
  4542  	res, err := inspectField(name, "Config.Cmd")
  4543  	if err != nil {
  4544  		c.Fatal(err)
  4545  	}
  4546  	if res != "<nil>" {
  4547  		c.Fatalf("Cmd %s, expected nil", res)
  4548  	}
  4549  
  4550  	res, err = inspectField(name, "Config.Entrypoint")
  4551  	if err != nil {
  4552  		c.Fatal(err)
  4553  	}
  4554  	if expected := "{[cat]}"; res != expected {
  4555  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  4556  	}
  4557  }
  4558  
  4559  func (s *DockerSuite) TestBuildClearCmd(c *check.C) {
  4560  	testRequires(c, DaemonIsLinux)
  4561  	name := "testbuildclearcmd"
  4562  	_, err := buildImage(name,
  4563  		`From scratch
  4564     ENTRYPOINT ["/bin/bash"]
  4565     CMD []`,
  4566  		true)
  4567  	if err != nil {
  4568  		c.Fatal(err)
  4569  	}
  4570  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4571  	if err != nil {
  4572  		c.Fatal(err)
  4573  	}
  4574  	if res != "[]" {
  4575  		c.Fatalf("Cmd %s, expected %s", res, "[]")
  4576  	}
  4577  }
  4578  
  4579  func (s *DockerSuite) TestBuildEmptyCmd(c *check.C) {
  4580  	testRequires(c, DaemonIsLinux)
  4581  	name := "testbuildemptycmd"
  4582  	if _, err := buildImage(name, "FROM scratch\nMAINTAINER quux\n", true); err != nil {
  4583  		c.Fatal(err)
  4584  	}
  4585  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4586  	if err != nil {
  4587  		c.Fatal(err)
  4588  	}
  4589  	if res != "null" {
  4590  		c.Fatalf("Cmd %s, expected %s", res, "null")
  4591  	}
  4592  }
  4593  
  4594  func (s *DockerSuite) TestBuildOnBuildOutput(c *check.C) {
  4595  	testRequires(c, DaemonIsLinux)
  4596  	name := "testbuildonbuildparent"
  4597  	if _, err := buildImage(name, "FROM busybox\nONBUILD RUN echo foo\n", true); err != nil {
  4598  		c.Fatal(err)
  4599  	}
  4600  
  4601  	_, out, err := buildImageWithOut(name, "FROM "+name+"\nMAINTAINER quux\n", true)
  4602  	if err != nil {
  4603  		c.Fatal(err)
  4604  	}
  4605  
  4606  	if !strings.Contains(out, "# Executing 1 build trigger") {
  4607  		c.Fatal("failed to find the build trigger output", out)
  4608  	}
  4609  }
  4610  
  4611  func (s *DockerSuite) TestBuildInvalidTag(c *check.C) {
  4612  	testRequires(c, DaemonIsLinux)
  4613  	name := "abcd:" + stringutils.GenerateRandomAlphaOnlyString(200)
  4614  	_, out, err := buildImageWithOut(name, "FROM scratch\nMAINTAINER quux\n", true)
  4615  	// if the error doesn't check for illegal tag name, or the image is built
  4616  	// then this should fail
  4617  	if !strings.Contains(out, "Error parsing reference") || strings.Contains(out, "Sending build context to Docker daemon") {
  4618  		c.Fatalf("failed to stop before building. Error: %s, Output: %s", err, out)
  4619  	}
  4620  }
  4621  
  4622  func (s *DockerSuite) TestBuildCmdShDashC(c *check.C) {
  4623  	testRequires(c, DaemonIsLinux)
  4624  	name := "testbuildcmdshc"
  4625  	if _, err := buildImage(name, "FROM busybox\nCMD echo cmd\n", true); err != nil {
  4626  		c.Fatal(err)
  4627  	}
  4628  
  4629  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4630  	if err != nil {
  4631  		c.Fatal(err, res)
  4632  	}
  4633  
  4634  	expected := `["/bin/sh","-c","echo cmd"]`
  4635  
  4636  	if res != expected {
  4637  		c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  4638  	}
  4639  
  4640  }
  4641  
  4642  func (s *DockerSuite) TestBuildCmdSpaces(c *check.C) {
  4643  	testRequires(c, DaemonIsLinux)
  4644  	// Test to make sure that when we strcat arrays we take into account
  4645  	// the arg separator to make sure ["echo","hi"] and ["echo hi"] don't
  4646  	// look the same
  4647  	name := "testbuildcmdspaces"
  4648  	var id1 string
  4649  	var id2 string
  4650  	var err error
  4651  
  4652  	if id1, err = buildImage(name, "FROM busybox\nCMD [\"echo hi\"]\n", true); err != nil {
  4653  		c.Fatal(err)
  4654  	}
  4655  
  4656  	if id2, err = buildImage(name, "FROM busybox\nCMD [\"echo\", \"hi\"]\n", true); err != nil {
  4657  		c.Fatal(err)
  4658  	}
  4659  
  4660  	if id1 == id2 {
  4661  		c.Fatal("Should not have resulted in the same CMD")
  4662  	}
  4663  
  4664  	// Now do the same with ENTRYPOINT
  4665  	if id1, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo hi\"]\n", true); err != nil {
  4666  		c.Fatal(err)
  4667  	}
  4668  
  4669  	if id2, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo\", \"hi\"]\n", true); err != nil {
  4670  		c.Fatal(err)
  4671  	}
  4672  
  4673  	if id1 == id2 {
  4674  		c.Fatal("Should not have resulted in the same ENTRYPOINT")
  4675  	}
  4676  
  4677  }
  4678  
  4679  func (s *DockerSuite) TestBuildCmdJSONNoShDashC(c *check.C) {
  4680  	testRequires(c, DaemonIsLinux)
  4681  	name := "testbuildcmdjson"
  4682  	if _, err := buildImage(name, "FROM busybox\nCMD [\"echo\", \"cmd\"]", true); err != nil {
  4683  		c.Fatal(err)
  4684  	}
  4685  
  4686  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4687  	if err != nil {
  4688  		c.Fatal(err, res)
  4689  	}
  4690  
  4691  	expected := `["echo","cmd"]`
  4692  
  4693  	if res != expected {
  4694  		c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  4695  	}
  4696  
  4697  }
  4698  
  4699  func (s *DockerSuite) TestBuildErrorInvalidInstruction(c *check.C) {
  4700  	testRequires(c, DaemonIsLinux)
  4701  	name := "testbuildignoreinvalidinstruction"
  4702  
  4703  	out, _, err := buildImageWithOut(name, "FROM busybox\nfoo bar", true)
  4704  	if err == nil {
  4705  		c.Fatalf("Should have failed: %s", out)
  4706  	}
  4707  
  4708  }
  4709  
  4710  func (s *DockerSuite) TestBuildEntrypointInheritance(c *check.C) {
  4711  	testRequires(c, DaemonIsLinux)
  4712  
  4713  	if _, err := buildImage("parent", `
  4714      FROM busybox
  4715      ENTRYPOINT exit 130
  4716      `, true); err != nil {
  4717  		c.Fatal(err)
  4718  	}
  4719  
  4720  	if _, status, _ := dockerCmdWithError("run", "parent"); status != 130 {
  4721  		c.Fatalf("expected exit code 130 but received %d", status)
  4722  	}
  4723  
  4724  	if _, err := buildImage("child", `
  4725      FROM parent
  4726      ENTRYPOINT exit 5
  4727      `, true); err != nil {
  4728  		c.Fatal(err)
  4729  	}
  4730  
  4731  	if _, status, _ := dockerCmdWithError("run", "child"); status != 5 {
  4732  		c.Fatalf("expected exit code 5 but received %d", status)
  4733  	}
  4734  
  4735  }
  4736  
  4737  func (s *DockerSuite) TestBuildEntrypointInheritanceInspect(c *check.C) {
  4738  	testRequires(c, DaemonIsLinux)
  4739  	var (
  4740  		name     = "testbuildepinherit"
  4741  		name2    = "testbuildepinherit2"
  4742  		expected = `["/bin/sh","-c","echo quux"]`
  4743  	)
  4744  
  4745  	if _, err := buildImage(name, "FROM busybox\nENTRYPOINT /foo/bar", true); err != nil {
  4746  		c.Fatal(err)
  4747  	}
  4748  
  4749  	if _, err := buildImage(name2, fmt.Sprintf("FROM %s\nENTRYPOINT echo quux", name), true); err != nil {
  4750  		c.Fatal(err)
  4751  	}
  4752  
  4753  	res, err := inspectFieldJSON(name2, "Config.Entrypoint")
  4754  	if err != nil {
  4755  		c.Fatal(err, res)
  4756  	}
  4757  
  4758  	if res != expected {
  4759  		c.Fatalf("Expected value %s not in Config.Entrypoint: %s", expected, res)
  4760  	}
  4761  
  4762  	out, _ := dockerCmd(c, "run", "-t", name2)
  4763  
  4764  	expected = "quux"
  4765  
  4766  	if strings.TrimSpace(out) != expected {
  4767  		c.Fatalf("Expected output is %s, got %s", expected, out)
  4768  	}
  4769  
  4770  }
  4771  
  4772  func (s *DockerSuite) TestBuildRunShEntrypoint(c *check.C) {
  4773  	testRequires(c, DaemonIsLinux)
  4774  	name := "testbuildentrypoint"
  4775  	_, err := buildImage(name,
  4776  		`FROM busybox
  4777                                  ENTRYPOINT /bin/echo`,
  4778  		true)
  4779  	if err != nil {
  4780  		c.Fatal(err)
  4781  	}
  4782  
  4783  	dockerCmd(c, "run", "--rm", name)
  4784  }
  4785  
  4786  func (s *DockerSuite) TestBuildExoticShellInterpolation(c *check.C) {
  4787  	testRequires(c, DaemonIsLinux)
  4788  	name := "testbuildexoticshellinterpolation"
  4789  
  4790  	_, err := buildImage(name, `
  4791  		FROM busybox
  4792  
  4793  		ENV SOME_VAR a.b.c
  4794  
  4795  		RUN [ "$SOME_VAR"       = 'a.b.c' ]
  4796  		RUN [ "${SOME_VAR}"     = 'a.b.c' ]
  4797  		RUN [ "${SOME_VAR%.*}"  = 'a.b'   ]
  4798  		RUN [ "${SOME_VAR%%.*}" = 'a'     ]
  4799  		RUN [ "${SOME_VAR#*.}"  = 'b.c'   ]
  4800  		RUN [ "${SOME_VAR##*.}" = 'c'     ]
  4801  		RUN [ "${SOME_VAR/c/d}" = 'a.b.d' ]
  4802  		RUN [ "${#SOME_VAR}"    = '5'     ]
  4803  
  4804  		RUN [ "${SOME_UNSET_VAR:-$SOME_VAR}" = 'a.b.c' ]
  4805  		RUN [ "${SOME_VAR:+Version: ${SOME_VAR}}" = 'Version: a.b.c' ]
  4806  		RUN [ "${SOME_UNSET_VAR:+${SOME_VAR}}" = '' ]
  4807  		RUN [ "${SOME_UNSET_VAR:-${SOME_VAR:-d.e.f}}" = 'a.b.c' ]
  4808  	`, false)
  4809  	if err != nil {
  4810  		c.Fatal(err)
  4811  	}
  4812  
  4813  }
  4814  
  4815  func (s *DockerSuite) TestBuildVerifySingleQuoteFails(c *check.C) {
  4816  	testRequires(c, DaemonIsLinux)
  4817  	// This testcase is supposed to generate an error because the
  4818  	// JSON array we're passing in on the CMD uses single quotes instead
  4819  	// of double quotes (per the JSON spec). This means we interpret it
  4820  	// as a "string" instead of "JSON array" and pass it on to "sh -c" and
  4821  	// it should barf on it.
  4822  	name := "testbuildsinglequotefails"
  4823  
  4824  	if _, err := buildImage(name,
  4825  		`FROM busybox
  4826  		CMD [ '/bin/sh', '-c', 'echo hi' ]`,
  4827  		true); err != nil {
  4828  		c.Fatal(err)
  4829  	}
  4830  
  4831  	if _, _, err := dockerCmdWithError("run", "--rm", name); err == nil {
  4832  		c.Fatal("The image was not supposed to be able to run")
  4833  	}
  4834  
  4835  }
  4836  
  4837  func (s *DockerSuite) TestBuildVerboseOut(c *check.C) {
  4838  	testRequires(c, DaemonIsLinux)
  4839  	name := "testbuildverboseout"
  4840  
  4841  	_, out, err := buildImageWithOut(name,
  4842  		`FROM busybox
  4843  RUN echo 123`,
  4844  		false)
  4845  
  4846  	if err != nil {
  4847  		c.Fatal(err)
  4848  	}
  4849  	if !strings.Contains(out, "\n123\n") {
  4850  		c.Fatalf("Output should contain %q: %q", "123", out)
  4851  	}
  4852  
  4853  }
  4854  
  4855  func (s *DockerSuite) TestBuildWithTabs(c *check.C) {
  4856  	testRequires(c, DaemonIsLinux)
  4857  	name := "testbuildwithtabs"
  4858  	_, err := buildImage(name,
  4859  		"FROM busybox\nRUN echo\tone\t\ttwo", true)
  4860  	if err != nil {
  4861  		c.Fatal(err)
  4862  	}
  4863  	res, err := inspectFieldJSON(name, "ContainerConfig.Cmd")
  4864  	if err != nil {
  4865  		c.Fatal(err)
  4866  	}
  4867  	expected1 := `["/bin/sh","-c","echo\tone\t\ttwo"]`
  4868  	expected2 := `["/bin/sh","-c","echo\u0009one\u0009\u0009two"]` // syntactically equivalent, and what Go 1.3 generates
  4869  	if res != expected1 && res != expected2 {
  4870  		c.Fatalf("Missing tabs.\nGot: %s\nExp: %s or %s", res, expected1, expected2)
  4871  	}
  4872  }
  4873  
  4874  func (s *DockerSuite) TestBuildLabels(c *check.C) {
  4875  	testRequires(c, DaemonIsLinux)
  4876  	name := "testbuildlabel"
  4877  	expected := `{"License":"GPL","Vendor":"Acme"}`
  4878  	_, err := buildImage(name,
  4879  		`FROM busybox
  4880  		LABEL Vendor=Acme
  4881                  LABEL License GPL`,
  4882  		true)
  4883  	if err != nil {
  4884  		c.Fatal(err)
  4885  	}
  4886  	res, err := inspectFieldJSON(name, "Config.Labels")
  4887  	if err != nil {
  4888  		c.Fatal(err)
  4889  	}
  4890  	if res != expected {
  4891  		c.Fatalf("Labels %s, expected %s", res, expected)
  4892  	}
  4893  }
  4894  
  4895  func (s *DockerSuite) TestBuildLabelsCache(c *check.C) {
  4896  	testRequires(c, DaemonIsLinux)
  4897  	name := "testbuildlabelcache"
  4898  
  4899  	id1, err := buildImage(name,
  4900  		`FROM busybox
  4901  		LABEL Vendor=Acme`, false)
  4902  	if err != nil {
  4903  		c.Fatalf("Build 1 should have worked: %v", err)
  4904  	}
  4905  
  4906  	id2, err := buildImage(name,
  4907  		`FROM busybox
  4908  		LABEL Vendor=Acme`, true)
  4909  	if err != nil || id1 != id2 {
  4910  		c.Fatalf("Build 2 should have worked & used cache(%s,%s): %v", id1, id2, err)
  4911  	}
  4912  
  4913  	id2, err = buildImage(name,
  4914  		`FROM busybox
  4915  		LABEL Vendor=Acme1`, true)
  4916  	if err != nil || id1 == id2 {
  4917  		c.Fatalf("Build 3 should have worked & NOT used cache(%s,%s): %v", id1, id2, err)
  4918  	}
  4919  
  4920  	id2, err = buildImage(name,
  4921  		`FROM busybox
  4922  		LABEL Vendor Acme`, true) // Note: " " and "=" should be same
  4923  	if err != nil || id1 != id2 {
  4924  		c.Fatalf("Build 4 should have worked & used cache(%s,%s): %v", id1, id2, err)
  4925  	}
  4926  
  4927  	// Now make sure the cache isn't used by mistake
  4928  	id1, err = buildImage(name,
  4929  		`FROM busybox
  4930         LABEL f1=b1 f2=b2`, false)
  4931  	if err != nil {
  4932  		c.Fatalf("Build 5 should have worked: %q", err)
  4933  	}
  4934  
  4935  	id2, err = buildImage(name,
  4936  		`FROM busybox
  4937         LABEL f1="b1 f2=b2"`, true)
  4938  	if err != nil || id1 == id2 {
  4939  		c.Fatalf("Build 6 should have worked & NOT used the cache(%s,%s): %q", id1, id2, err)
  4940  	}
  4941  
  4942  }
  4943  
  4944  func (s *DockerSuite) TestBuildStderr(c *check.C) {
  4945  	testRequires(c, DaemonIsLinux)
  4946  	// This test just makes sure that no non-error output goes
  4947  	// to stderr
  4948  	name := "testbuildstderr"
  4949  	_, _, stderr, err := buildImageWithStdoutStderr(name,
  4950  		"FROM busybox\nRUN echo one", true)
  4951  	if err != nil {
  4952  		c.Fatal(err)
  4953  	}
  4954  
  4955  	if runtime.GOOS == "windows" {
  4956  		// stderr might contain a security warning on windows
  4957  		lines := strings.Split(stderr, "\n")
  4958  		for _, v := range lines {
  4959  			if v != "" && !strings.Contains(v, "SECURITY WARNING:") {
  4960  				c.Fatalf("Stderr contains unexpected output line: %q", v)
  4961  			}
  4962  		}
  4963  	} else {
  4964  		if stderr != "" {
  4965  			c.Fatalf("Stderr should have been empty, instead its: %q", stderr)
  4966  		}
  4967  	}
  4968  }
  4969  
  4970  func (s *DockerSuite) TestBuildChownSingleFile(c *check.C) {
  4971  	testRequires(c, UnixCli) // test uses chown: not available on windows
  4972  	testRequires(c, DaemonIsLinux)
  4973  
  4974  	name := "testbuildchownsinglefile"
  4975  
  4976  	ctx, err := fakeContext(`
  4977  FROM busybox
  4978  COPY test /
  4979  RUN ls -l /test
  4980  RUN [ $(ls -l /test | awk '{print $3":"$4}') = 'root:root' ]
  4981  `, map[string]string{
  4982  		"test": "test",
  4983  	})
  4984  	if err != nil {
  4985  		c.Fatal(err)
  4986  	}
  4987  	defer ctx.Close()
  4988  
  4989  	if err := os.Chown(filepath.Join(ctx.Dir, "test"), 4242, 4242); err != nil {
  4990  		c.Fatal(err)
  4991  	}
  4992  
  4993  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4994  		c.Fatal(err)
  4995  	}
  4996  
  4997  }
  4998  
  4999  func (s *DockerSuite) TestBuildSymlinkBreakout(c *check.C) {
  5000  	testRequires(c, DaemonIsLinux)
  5001  	name := "testbuildsymlinkbreakout"
  5002  	tmpdir, err := ioutil.TempDir("", name)
  5003  	c.Assert(err, check.IsNil)
  5004  	defer os.RemoveAll(tmpdir)
  5005  	ctx := filepath.Join(tmpdir, "context")
  5006  	if err := os.MkdirAll(ctx, 0755); err != nil {
  5007  		c.Fatal(err)
  5008  	}
  5009  	if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte(`
  5010  	from busybox
  5011  	add symlink.tar /
  5012  	add inject /symlink/
  5013  	`), 0644); err != nil {
  5014  		c.Fatal(err)
  5015  	}
  5016  	inject := filepath.Join(ctx, "inject")
  5017  	if err := ioutil.WriteFile(inject, nil, 0644); err != nil {
  5018  		c.Fatal(err)
  5019  	}
  5020  	f, err := os.Create(filepath.Join(ctx, "symlink.tar"))
  5021  	if err != nil {
  5022  		c.Fatal(err)
  5023  	}
  5024  	w := tar.NewWriter(f)
  5025  	w.WriteHeader(&tar.Header{
  5026  		Name:     "symlink2",
  5027  		Typeflag: tar.TypeSymlink,
  5028  		Linkname: "/../../../../../../../../../../../../../../",
  5029  		Uid:      os.Getuid(),
  5030  		Gid:      os.Getgid(),
  5031  	})
  5032  	w.WriteHeader(&tar.Header{
  5033  		Name:     "symlink",
  5034  		Typeflag: tar.TypeSymlink,
  5035  		Linkname: filepath.Join("symlink2", tmpdir),
  5036  		Uid:      os.Getuid(),
  5037  		Gid:      os.Getgid(),
  5038  	})
  5039  	w.Close()
  5040  	f.Close()
  5041  	if _, err := buildImageFromContext(name, fakeContextFromDir(ctx), false); err != nil {
  5042  		c.Fatal(err)
  5043  	}
  5044  	if _, err := os.Lstat(filepath.Join(tmpdir, "inject")); err == nil {
  5045  		c.Fatal("symlink breakout - inject")
  5046  	} else if !os.IsNotExist(err) {
  5047  		c.Fatalf("unexpected error: %v", err)
  5048  	}
  5049  }
  5050  
  5051  func (s *DockerSuite) TestBuildXZHost(c *check.C) {
  5052  	// /usr/local/sbin/xz gets permission denied for the user
  5053  	testRequires(c, NotUserNamespace)
  5054  	testRequires(c, DaemonIsLinux)
  5055  	name := "testbuildxzhost"
  5056  
  5057  	ctx, err := fakeContext(`
  5058  FROM busybox
  5059  ADD xz /usr/local/sbin/
  5060  RUN chmod 755 /usr/local/sbin/xz
  5061  ADD test.xz /
  5062  RUN [ ! -e /injected ]`,
  5063  		map[string]string{
  5064  			"test.xz": "\xfd\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00" +
  5065  				"\x21\x01\x16\x00\x00\x00\x74\x2f\xe5\xa3\x01\x00\x3f\xfd" +
  5066  				"\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00\x21",
  5067  			"xz": "#!/bin/sh\ntouch /injected",
  5068  		})
  5069  
  5070  	if err != nil {
  5071  		c.Fatal(err)
  5072  	}
  5073  	defer ctx.Close()
  5074  
  5075  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  5076  		c.Fatal(err)
  5077  	}
  5078  
  5079  }
  5080  
  5081  func (s *DockerSuite) TestBuildVolumesRetainContents(c *check.C) {
  5082  	// /foo/file gets permission denied for the user
  5083  	testRequires(c, NotUserNamespace)
  5084  	testRequires(c, DaemonIsLinux)
  5085  	var (
  5086  		name     = "testbuildvolumescontent"
  5087  		expected = "some text"
  5088  	)
  5089  	ctx, err := fakeContext(`
  5090  FROM busybox
  5091  COPY content /foo/file
  5092  VOLUME /foo
  5093  CMD cat /foo/file`,
  5094  		map[string]string{
  5095  			"content": expected,
  5096  		})
  5097  	if err != nil {
  5098  		c.Fatal(err)
  5099  	}
  5100  	defer ctx.Close()
  5101  
  5102  	if _, err := buildImageFromContext(name, ctx, false); err != nil {
  5103  		c.Fatal(err)
  5104  	}
  5105  
  5106  	out, _ := dockerCmd(c, "run", "--rm", name)
  5107  	if out != expected {
  5108  		c.Fatalf("expected file contents for /foo/file to be %q but received %q", expected, out)
  5109  	}
  5110  
  5111  }
  5112  
  5113  func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) {
  5114  	testRequires(c, DaemonIsLinux)
  5115  
  5116  	ctx, err := fakeContext(`FROM busybox
  5117  	RUN echo from Dockerfile`,
  5118  		map[string]string{
  5119  			"Dockerfile":       "FROM busybox\nRUN echo from Dockerfile",
  5120  			"files/Dockerfile": "FROM busybox\nRUN echo from files/Dockerfile",
  5121  			"files/dFile":      "FROM busybox\nRUN echo from files/dFile",
  5122  			"dFile":            "FROM busybox\nRUN echo from dFile",
  5123  			"files/dFile2":     "FROM busybox\nRUN echo from files/dFile2",
  5124  		})
  5125  	if err != nil {
  5126  		c.Fatal(err)
  5127  	}
  5128  	defer ctx.Close()
  5129  
  5130  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  5131  	if err != nil {
  5132  		c.Fatalf("Failed to build: %s\n%s", out, err)
  5133  	}
  5134  	if !strings.Contains(out, "from Dockerfile") {
  5135  		c.Fatalf("test1 should have used Dockerfile, output:%s", out)
  5136  	}
  5137  
  5138  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-f", filepath.Join("files", "Dockerfile"), "-t", "test2", ".")
  5139  	if err != nil {
  5140  		c.Fatal(err)
  5141  	}
  5142  	if !strings.Contains(out, "from files/Dockerfile") {
  5143  		c.Fatalf("test2 should have used files/Dockerfile, output:%s", out)
  5144  	}
  5145  
  5146  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", filepath.Join("files", "dFile")), "-t", "test3", ".")
  5147  	if err != nil {
  5148  		c.Fatal(err)
  5149  	}
  5150  	if !strings.Contains(out, "from files/dFile") {
  5151  		c.Fatalf("test3 should have used files/dFile, output:%s", out)
  5152  	}
  5153  
  5154  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "--file=dFile", "-t", "test4", ".")
  5155  	if err != nil {
  5156  		c.Fatal(err)
  5157  	}
  5158  	if !strings.Contains(out, "from dFile") {
  5159  		c.Fatalf("test4 should have used dFile, output:%s", out)
  5160  	}
  5161  
  5162  	dirWithNoDockerfile, err := ioutil.TempDir(os.TempDir(), "test5")
  5163  	c.Assert(err, check.IsNil)
  5164  	nonDockerfileFile := filepath.Join(dirWithNoDockerfile, "notDockerfile")
  5165  	if _, err = os.Create(nonDockerfileFile); err != nil {
  5166  		c.Fatal(err)
  5167  	}
  5168  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", nonDockerfileFile), "-t", "test5", ".")
  5169  
  5170  	if err == nil {
  5171  		c.Fatalf("test5 was supposed to fail to find passwd")
  5172  	}
  5173  
  5174  	if expected := fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", nonDockerfileFile); !strings.Contains(out, expected) {
  5175  		c.Fatalf("wrong error messsage:%v\nexpected to contain=%v", out, expected)
  5176  	}
  5177  
  5178  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test6", "..")
  5179  	if err != nil {
  5180  		c.Fatalf("test6 failed: %s", err)
  5181  	}
  5182  	if !strings.Contains(out, "from Dockerfile") {
  5183  		c.Fatalf("test6 should have used root Dockerfile, output:%s", out)
  5184  	}
  5185  
  5186  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join(ctx.Dir, "files", "Dockerfile"), "-t", "test7", "..")
  5187  	if err != nil {
  5188  		c.Fatalf("test7 failed: %s", err)
  5189  	}
  5190  	if !strings.Contains(out, "from files/Dockerfile") {
  5191  		c.Fatalf("test7 should have used files Dockerfile, output:%s", out)
  5192  	}
  5193  
  5194  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test8", ".")
  5195  	if err == nil || !strings.Contains(out, "must be within the build context") {
  5196  		c.Fatalf("test8 should have failed with Dockerfile out of context: %s", err)
  5197  	}
  5198  
  5199  	tmpDir := os.TempDir()
  5200  	out, _, err = dockerCmdInDir(c, tmpDir, "build", "-t", "test9", ctx.Dir)
  5201  	if err != nil {
  5202  		c.Fatalf("test9 - failed: %s", err)
  5203  	}
  5204  	if !strings.Contains(out, "from Dockerfile") {
  5205  		c.Fatalf("test9 should have used root Dockerfile, output:%s", out)
  5206  	}
  5207  
  5208  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", "dFile2", "-t", "test10", ".")
  5209  	if err != nil {
  5210  		c.Fatalf("test10 should have worked: %s", err)
  5211  	}
  5212  	if !strings.Contains(out, "from files/dFile2") {
  5213  		c.Fatalf("test10 should have used files/dFile2, output:%s", out)
  5214  	}
  5215  
  5216  }
  5217  
  5218  func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) {
  5219  	testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  5220  	testRequires(c, DaemonIsLinux)
  5221  
  5222  	ctx, err := fakeContext(`FROM busybox
  5223  	RUN echo from dockerfile`,
  5224  		map[string]string{
  5225  			"dockerfile": "FROM busybox\nRUN echo from dockerfile",
  5226  		})
  5227  	if err != nil {
  5228  		c.Fatal(err)
  5229  	}
  5230  	defer ctx.Close()
  5231  
  5232  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  5233  	if err != nil {
  5234  		c.Fatalf("Failed to build: %s\n%s", out, err)
  5235  	}
  5236  
  5237  	if !strings.Contains(out, "from dockerfile") {
  5238  		c.Fatalf("Missing proper output: %s", out)
  5239  	}
  5240  
  5241  }
  5242  
  5243  func (s *DockerSuite) TestBuildWithTwoDockerfiles(c *check.C) {
  5244  	testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  5245  	testRequires(c, DaemonIsLinux)
  5246  
  5247  	ctx, err := fakeContext(`FROM busybox
  5248  RUN echo from Dockerfile`,
  5249  		map[string]string{
  5250  			"dockerfile": "FROM busybox\nRUN echo from dockerfile",
  5251  		})
  5252  	if err != nil {
  5253  		c.Fatal(err)
  5254  	}
  5255  	defer ctx.Close()
  5256  
  5257  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  5258  	if err != nil {
  5259  		c.Fatalf("Failed to build: %s\n%s", out, err)
  5260  	}
  5261  
  5262  	if !strings.Contains(out, "from Dockerfile") {
  5263  		c.Fatalf("Missing proper output: %s", out)
  5264  	}
  5265  
  5266  }
  5267  
  5268  func (s *DockerSuite) TestBuildFromURLWithF(c *check.C) {
  5269  	testRequires(c, DaemonIsLinux)
  5270  
  5271  	server, err := fakeStorage(map[string]string{"baz": `FROM busybox
  5272  RUN echo from baz
  5273  COPY * /tmp/
  5274  RUN find /tmp/`})
  5275  	if err != nil {
  5276  		c.Fatal(err)
  5277  	}
  5278  	defer server.Close()
  5279  
  5280  	ctx, err := fakeContext(`FROM busybox
  5281  RUN echo from Dockerfile`,
  5282  		map[string]string{})
  5283  	if err != nil {
  5284  		c.Fatal(err)
  5285  	}
  5286  	defer ctx.Close()
  5287  
  5288  	// Make sure that -f is ignored and that we don't use the Dockerfile
  5289  	// that's in the current dir
  5290  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-f", "baz", "-t", "test1", server.URL()+"/baz")
  5291  	if err != nil {
  5292  		c.Fatalf("Failed to build: %s\n%s", out, err)
  5293  	}
  5294  
  5295  	if !strings.Contains(out, "from baz") ||
  5296  		strings.Contains(out, "/tmp/baz") ||
  5297  		!strings.Contains(out, "/tmp/Dockerfile") {
  5298  		c.Fatalf("Missing proper output: %s", out)
  5299  	}
  5300  
  5301  }
  5302  
  5303  func (s *DockerSuite) TestBuildFromStdinWithF(c *check.C) {
  5304  	testRequires(c, DaemonIsLinux)
  5305  	ctx, err := fakeContext(`FROM busybox
  5306  RUN echo from Dockerfile`,
  5307  		map[string]string{})
  5308  	if err != nil {
  5309  		c.Fatal(err)
  5310  	}
  5311  	defer ctx.Close()
  5312  
  5313  	// Make sure that -f is ignored and that we don't use the Dockerfile
  5314  	// that's in the current dir
  5315  	dockerCommand := exec.Command(dockerBinary, "build", "-f", "baz", "-t", "test1", "-")
  5316  	dockerCommand.Dir = ctx.Dir
  5317  	dockerCommand.Stdin = strings.NewReader(`FROM busybox
  5318  RUN echo from baz
  5319  COPY * /tmp/
  5320  RUN find /tmp/`)
  5321  	out, status, err := runCommandWithOutput(dockerCommand)
  5322  	if err != nil || status != 0 {
  5323  		c.Fatalf("Error building: %s", err)
  5324  	}
  5325  
  5326  	if !strings.Contains(out, "from baz") ||
  5327  		strings.Contains(out, "/tmp/baz") ||
  5328  		!strings.Contains(out, "/tmp/Dockerfile") {
  5329  		c.Fatalf("Missing proper output: %s", out)
  5330  	}
  5331  
  5332  }
  5333  
  5334  func (s *DockerSuite) TestBuildFromOfficialNames(c *check.C) {
  5335  	testRequires(c, DaemonIsLinux)
  5336  	name := "testbuildfromofficial"
  5337  	fromNames := []string{
  5338  		"busybox",
  5339  		"docker.io/busybox",
  5340  		"index.docker.io/busybox",
  5341  		"library/busybox",
  5342  		"docker.io/library/busybox",
  5343  		"index.docker.io/library/busybox",
  5344  	}
  5345  	for idx, fromName := range fromNames {
  5346  		imgName := fmt.Sprintf("%s%d", name, idx)
  5347  		_, err := buildImage(imgName, "FROM "+fromName, true)
  5348  		if err != nil {
  5349  			c.Errorf("Build failed using FROM %s: %s", fromName, err)
  5350  		}
  5351  		deleteImages(imgName)
  5352  	}
  5353  }
  5354  
  5355  func (s *DockerSuite) TestBuildDockerfileOutsideContext(c *check.C) {
  5356  	testRequires(c, UnixCli) // uses os.Symlink: not implemented in windows at the time of writing (go-1.4.2)
  5357  	testRequires(c, DaemonIsLinux)
  5358  
  5359  	name := "testbuilddockerfileoutsidecontext"
  5360  	tmpdir, err := ioutil.TempDir("", name)
  5361  	c.Assert(err, check.IsNil)
  5362  	defer os.RemoveAll(tmpdir)
  5363  	ctx := filepath.Join(tmpdir, "context")
  5364  	if err := os.MkdirAll(ctx, 0755); err != nil {
  5365  		c.Fatal(err)
  5366  	}
  5367  	if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte("FROM scratch\nENV X Y"), 0644); err != nil {
  5368  		c.Fatal(err)
  5369  	}
  5370  	wd, err := os.Getwd()
  5371  	if err != nil {
  5372  		c.Fatal(err)
  5373  	}
  5374  	defer os.Chdir(wd)
  5375  	if err := os.Chdir(ctx); err != nil {
  5376  		c.Fatal(err)
  5377  	}
  5378  	if err := ioutil.WriteFile(filepath.Join(tmpdir, "outsideDockerfile"), []byte("FROM scratch\nENV x y"), 0644); err != nil {
  5379  		c.Fatal(err)
  5380  	}
  5381  	if err := os.Symlink(filepath.Join("..", "outsideDockerfile"), filepath.Join(ctx, "dockerfile1")); err != nil {
  5382  		c.Fatal(err)
  5383  	}
  5384  	if err := os.Symlink(filepath.Join(tmpdir, "outsideDockerfile"), filepath.Join(ctx, "dockerfile2")); err != nil {
  5385  		c.Fatal(err)
  5386  	}
  5387  
  5388  	for _, dockerfilePath := range []string{
  5389  		filepath.Join("..", "outsideDockerfile"),
  5390  		filepath.Join(ctx, "dockerfile1"),
  5391  		filepath.Join(ctx, "dockerfile2"),
  5392  	} {
  5393  		out, _, err := dockerCmdWithError("build", "-t", name, "--no-cache", "-f", dockerfilePath, ".")
  5394  		if err == nil {
  5395  			c.Fatalf("Expected error with %s. Out: %s", dockerfilePath, out)
  5396  		}
  5397  		if !strings.Contains(out, "must be within the build context") && !strings.Contains(out, "Cannot locate Dockerfile") {
  5398  			c.Fatalf("Unexpected error with %s. Out: %s", dockerfilePath, out)
  5399  		}
  5400  		deleteImages(name)
  5401  	}
  5402  
  5403  	os.Chdir(tmpdir)
  5404  
  5405  	// Path to Dockerfile should be resolved relative to working directory, not relative to context.
  5406  	// There is a Dockerfile in the context, but since there is no Dockerfile in the current directory, the following should fail
  5407  	out, _, err := dockerCmdWithError("build", "-t", name, "--no-cache", "-f", "Dockerfile", ctx)
  5408  	if err == nil {
  5409  		c.Fatalf("Expected error. Out: %s", out)
  5410  	}
  5411  }
  5412  
  5413  func (s *DockerSuite) TestBuildSpaces(c *check.C) {
  5414  	testRequires(c, DaemonIsLinux)
  5415  	// Test to make sure that leading/trailing spaces on a command
  5416  	// doesn't change the error msg we get
  5417  	var (
  5418  		err1 error
  5419  		err2 error
  5420  	)
  5421  
  5422  	name := "testspaces"
  5423  	ctx, err := fakeContext("FROM busybox\nCOPY\n",
  5424  		map[string]string{
  5425  			"Dockerfile": "FROM busybox\nCOPY\n",
  5426  		})
  5427  	if err != nil {
  5428  		c.Fatal(err)
  5429  	}
  5430  	defer ctx.Close()
  5431  
  5432  	if _, err1 = buildImageFromContext(name, ctx, false); err1 == nil {
  5433  		c.Fatal("Build 1 was supposed to fail, but didn't")
  5434  	}
  5435  
  5436  	ctx.Add("Dockerfile", "FROM busybox\nCOPY    ")
  5437  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5438  		c.Fatal("Build 2 was supposed to fail, but didn't")
  5439  	}
  5440  
  5441  	removeLogTimestamps := func(s string) string {
  5442  		return regexp.MustCompile(`time="(.*?)"`).ReplaceAllString(s, `time=[TIMESTAMP]`)
  5443  	}
  5444  
  5445  	// Skip over the times
  5446  	e1 := removeLogTimestamps(err1.Error())
  5447  	e2 := removeLogTimestamps(err2.Error())
  5448  
  5449  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5450  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5451  		c.Fatalf("Build 2's error wasn't the same as build 1's\n1:%s\n2:%s", err1, err2)
  5452  	}
  5453  
  5454  	ctx.Add("Dockerfile", "FROM busybox\n   COPY")
  5455  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5456  		c.Fatal("Build 3 was supposed to fail, but didn't")
  5457  	}
  5458  
  5459  	// Skip over the times
  5460  	e1 = removeLogTimestamps(err1.Error())
  5461  	e2 = removeLogTimestamps(err2.Error())
  5462  
  5463  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5464  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5465  		c.Fatalf("Build 3's error wasn't the same as build 1's\n1:%s\n3:%s", err1, err2)
  5466  	}
  5467  
  5468  	ctx.Add("Dockerfile", "FROM busybox\n   COPY    ")
  5469  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5470  		c.Fatal("Build 4 was supposed to fail, but didn't")
  5471  	}
  5472  
  5473  	// Skip over the times
  5474  	e1 = removeLogTimestamps(err1.Error())
  5475  	e2 = removeLogTimestamps(err2.Error())
  5476  
  5477  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5478  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5479  		c.Fatalf("Build 4's error wasn't the same as build 1's\n1:%s\n4:%s", err1, err2)
  5480  	}
  5481  
  5482  }
  5483  
  5484  func (s *DockerSuite) TestBuildSpacesWithQuotes(c *check.C) {
  5485  	testRequires(c, DaemonIsLinux)
  5486  	// Test to make sure that spaces in quotes aren't lost
  5487  	name := "testspacesquotes"
  5488  
  5489  	dockerfile := `FROM busybox
  5490  RUN echo "  \
  5491    foo  "`
  5492  
  5493  	_, out, err := buildImageWithOut(name, dockerfile, false)
  5494  	if err != nil {
  5495  		c.Fatal("Build failed:", err)
  5496  	}
  5497  
  5498  	expecting := "\n    foo  \n"
  5499  	if !strings.Contains(out, expecting) {
  5500  		c.Fatalf("Bad output: %q expecting to contain %q", out, expecting)
  5501  	}
  5502  
  5503  }
  5504  
  5505  // #4393
  5506  func (s *DockerSuite) TestBuildVolumeFileExistsinContainer(c *check.C) {
  5507  	testRequires(c, DaemonIsLinux)
  5508  	buildCmd := exec.Command(dockerBinary, "build", "-t", "docker-test-errcreatevolumewithfile", "-")
  5509  	buildCmd.Stdin = strings.NewReader(`
  5510  	FROM busybox
  5511  	RUN touch /foo
  5512  	VOLUME /foo
  5513  	`)
  5514  
  5515  	out, _, err := runCommandWithOutput(buildCmd)
  5516  	if err == nil || !strings.Contains(out, "file exists") {
  5517  		c.Fatalf("expected build to fail when file exists in container at requested volume path")
  5518  	}
  5519  
  5520  }
  5521  
  5522  func (s *DockerSuite) TestBuildMissingArgs(c *check.C) {
  5523  	testRequires(c, DaemonIsLinux)
  5524  	// Test to make sure that all Dockerfile commands (except the ones listed
  5525  	// in skipCmds) will generate an error if no args are provided.
  5526  	// Note: INSERT is deprecated so we exclude it because of that.
  5527  	skipCmds := map[string]struct{}{
  5528  		"CMD":        {},
  5529  		"RUN":        {},
  5530  		"ENTRYPOINT": {},
  5531  		"INSERT":     {},
  5532  	}
  5533  
  5534  	for cmd := range command.Commands {
  5535  		cmd = strings.ToUpper(cmd)
  5536  		if _, ok := skipCmds[cmd]; ok {
  5537  			continue
  5538  		}
  5539  
  5540  		var dockerfile string
  5541  		if cmd == "FROM" {
  5542  			dockerfile = cmd
  5543  		} else {
  5544  			// Add FROM to make sure we don't complain about it missing
  5545  			dockerfile = "FROM busybox\n" + cmd
  5546  		}
  5547  
  5548  		ctx, err := fakeContext(dockerfile, map[string]string{})
  5549  		if err != nil {
  5550  			c.Fatal(err)
  5551  		}
  5552  		defer ctx.Close()
  5553  		var out string
  5554  		if out, err = buildImageFromContext("args", ctx, true); err == nil {
  5555  			c.Fatalf("%s was supposed to fail. Out:%s", cmd, out)
  5556  		}
  5557  		if !strings.Contains(err.Error(), cmd+" requires") {
  5558  			c.Fatalf("%s returned the wrong type of error:%s", cmd, err)
  5559  		}
  5560  	}
  5561  
  5562  }
  5563  
  5564  func (s *DockerSuite) TestBuildEmptyScratch(c *check.C) {
  5565  	testRequires(c, DaemonIsLinux)
  5566  	_, out, err := buildImageWithOut("sc", "FROM scratch", true)
  5567  	if err == nil {
  5568  		c.Fatalf("Build was supposed to fail")
  5569  	}
  5570  	if !strings.Contains(out, "No image was generated") {
  5571  		c.Fatalf("Wrong error message: %v", out)
  5572  	}
  5573  }
  5574  
  5575  func (s *DockerSuite) TestBuildDotDotFile(c *check.C) {
  5576  	testRequires(c, DaemonIsLinux)
  5577  
  5578  	ctx, err := fakeContext("FROM busybox\n",
  5579  		map[string]string{
  5580  			"..gitme": "",
  5581  		})
  5582  	if err != nil {
  5583  		c.Fatal(err)
  5584  	}
  5585  	defer ctx.Close()
  5586  
  5587  	if _, err = buildImageFromContext("sc", ctx, false); err != nil {
  5588  		c.Fatalf("Build was supposed to work: %s", err)
  5589  	}
  5590  }
  5591  
  5592  func (s *DockerSuite) TestBuildNotVerbose(c *check.C) {
  5593  	testRequires(c, DaemonIsLinux)
  5594  	ctx, err := fakeContext("FROM busybox\nENV abc=hi\nRUN echo $abc there", map[string]string{})
  5595  	if err != nil {
  5596  		c.Fatal(err)
  5597  	}
  5598  	defer ctx.Close()
  5599  
  5600  	// First do it w/verbose - baseline
  5601  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--no-cache", "-t", "verbose", ".")
  5602  	if err != nil {
  5603  		c.Fatalf("failed to build the image w/o -q: %s, %v", out, err)
  5604  	}
  5605  	if !strings.Contains(out, "hi there") {
  5606  		c.Fatalf("missing output:%s\n", out)
  5607  	}
  5608  
  5609  	// Now do it w/o verbose
  5610  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "--no-cache", "-q", "-t", "verbose", ".")
  5611  	if err != nil {
  5612  		c.Fatalf("failed to build the image w/ -q: %s, %v", out, err)
  5613  	}
  5614  	if strings.Contains(out, "hi there") {
  5615  		c.Fatalf("Bad output, should not contain 'hi there':%s", out)
  5616  	}
  5617  
  5618  }
  5619  
  5620  func (s *DockerSuite) TestBuildRUNoneJSON(c *check.C) {
  5621  	testRequires(c, DaemonIsLinux)
  5622  	name := "testbuildrunonejson"
  5623  
  5624  	ctx, err := fakeContext(`FROM hello-world:frozen
  5625  RUN [ "/hello" ]`, map[string]string{})
  5626  	if err != nil {
  5627  		c.Fatal(err)
  5628  	}
  5629  	defer ctx.Close()
  5630  
  5631  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--no-cache", "-t", name, ".")
  5632  	if err != nil {
  5633  		c.Fatalf("failed to build the image: %s, %v", out, err)
  5634  	}
  5635  
  5636  	if !strings.Contains(out, "Hello from Docker") {
  5637  		c.Fatalf("bad output: %s", out)
  5638  	}
  5639  
  5640  }
  5641  
  5642  func (s *DockerSuite) TestBuildEmptyStringVolume(c *check.C) {
  5643  	testRequires(c, DaemonIsLinux)
  5644  	name := "testbuildemptystringvolume"
  5645  
  5646  	_, err := buildImage(name, `
  5647    FROM busybox
  5648    ENV foo=""
  5649    VOLUME $foo
  5650    `, false)
  5651  	if err == nil {
  5652  		c.Fatal("Should have failed to build")
  5653  	}
  5654  
  5655  }
  5656  
  5657  func (s *DockerSuite) TestBuildContainerWithCgroupParent(c *check.C) {
  5658  	testRequires(c, SameHostDaemon)
  5659  	testRequires(c, DaemonIsLinux)
  5660  
  5661  	cgroupParent := "test"
  5662  	data, err := ioutil.ReadFile("/proc/self/cgroup")
  5663  	if err != nil {
  5664  		c.Fatalf("failed to read '/proc/self/cgroup - %v", err)
  5665  	}
  5666  	selfCgroupPaths := parseCgroupPaths(string(data))
  5667  	_, found := selfCgroupPaths["memory"]
  5668  	if !found {
  5669  		c.Fatalf("unable to find self memory cgroup path. CgroupsPath: %v", selfCgroupPaths)
  5670  	}
  5671  	cmd := exec.Command(dockerBinary, "build", "--cgroup-parent", cgroupParent, "-")
  5672  	cmd.Stdin = strings.NewReader(`
  5673  FROM busybox
  5674  RUN cat /proc/self/cgroup
  5675  `)
  5676  
  5677  	out, _, err := runCommandWithOutput(cmd)
  5678  	if err != nil {
  5679  		c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
  5680  	}
  5681  	m, err := regexp.MatchString(fmt.Sprintf("memory:.*/%s/.*", cgroupParent), out)
  5682  	c.Assert(err, check.IsNil)
  5683  	if !m {
  5684  		c.Fatalf("There is no expected memory cgroup with parent /%s/: %s", cgroupParent, out)
  5685  	}
  5686  }
  5687  
  5688  func (s *DockerSuite) TestBuildNoDupOutput(c *check.C) {
  5689  	testRequires(c, DaemonIsLinux)
  5690  	// Check to make sure our build output prints the Dockerfile cmd
  5691  	// property - there was a bug that caused it to be duplicated on the
  5692  	// Step X  line
  5693  	name := "testbuildnodupoutput"
  5694  
  5695  	_, out, err := buildImageWithOut(name, `
  5696    FROM busybox
  5697    RUN env`, false)
  5698  	if err != nil {
  5699  		c.Fatalf("Build should have worked: %q", err)
  5700  	}
  5701  
  5702  	exp := "\nStep 2 : RUN env\n"
  5703  	if !strings.Contains(out, exp) {
  5704  		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  5705  	}
  5706  }
  5707  
  5708  // GH15826
  5709  func (s *DockerSuite) TestBuildStartsFromOne(c *check.C) {
  5710  	testRequires(c, DaemonIsLinux)
  5711  	// Explicit check to ensure that build starts from step 1 rather than 0
  5712  	name := "testbuildstartsfromone"
  5713  
  5714  	_, out, err := buildImageWithOut(name, `
  5715    FROM busybox`, false)
  5716  	if err != nil {
  5717  		c.Fatalf("Build should have worked: %q", err)
  5718  	}
  5719  
  5720  	exp := "\nStep 1 : FROM busybox\n"
  5721  	if !strings.Contains(out, exp) {
  5722  		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  5723  	}
  5724  }
  5725  
  5726  func (s *DockerSuite) TestBuildBadCmdFlag(c *check.C) {
  5727  	testRequires(c, DaemonIsLinux)
  5728  	name := "testbuildbadcmdflag"
  5729  
  5730  	_, out, err := buildImageWithOut(name, `
  5731    FROM busybox
  5732    MAINTAINER --boo joe@example.com`, false)
  5733  	if err == nil {
  5734  		c.Fatal("Build should have failed")
  5735  	}
  5736  
  5737  	exp := "\nUnknown flag: boo\n"
  5738  	if !strings.Contains(out, exp) {
  5739  		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  5740  	}
  5741  }
  5742  
  5743  func (s *DockerSuite) TestBuildRUNErrMsg(c *check.C) {
  5744  	testRequires(c, DaemonIsLinux)
  5745  	// Test to make sure the bad command is quoted with just "s and
  5746  	// not as a Go []string
  5747  	name := "testbuildbadrunerrmsg"
  5748  	_, out, err := buildImageWithOut(name, `
  5749    FROM busybox
  5750    RUN badEXE a1 \& a2	a3`, false) // tab between a2 and a3
  5751  	if err == nil {
  5752  		c.Fatal("Should have failed to build")
  5753  	}
  5754  
  5755  	exp := `The command '/bin/sh -c badEXE a1 \& a2	a3' returned a non-zero code: 127`
  5756  	if !strings.Contains(out, exp) {
  5757  		c.Fatalf("RUN doesn't have the correct output:\nGot:%s\nExpected:%s", out, exp)
  5758  	}
  5759  }
  5760  
  5761  func (s *DockerTrustSuite) TestTrustedBuild(c *check.C) {
  5762  	repoName := s.setupTrustedImage(c, "trusted-build")
  5763  	dockerFile := fmt.Sprintf(`
  5764    FROM %s
  5765    RUN []
  5766      `, repoName)
  5767  
  5768  	name := "testtrustedbuild"
  5769  
  5770  	buildCmd := buildImageCmd(name, dockerFile, true)
  5771  	s.trustedCmd(buildCmd)
  5772  	out, _, err := runCommandWithOutput(buildCmd)
  5773  	if err != nil {
  5774  		c.Fatalf("Error running trusted build: %s\n%s", err, out)
  5775  	}
  5776  
  5777  	if !strings.Contains(out, fmt.Sprintf("FROM %s@sha", repoName[:len(repoName)-7])) {
  5778  		c.Fatalf("Unexpected output on trusted build:\n%s", out)
  5779  	}
  5780  
  5781  	// We should also have a tag reference for the image.
  5782  	if out, exitCode := dockerCmd(c, "inspect", repoName); exitCode != 0 {
  5783  		c.Fatalf("unexpected exit code inspecting image %q: %d: %s", repoName, exitCode, out)
  5784  	}
  5785  
  5786  	// We should now be able to remove the tag reference.
  5787  	if out, exitCode := dockerCmd(c, "rmi", repoName); exitCode != 0 {
  5788  		c.Fatalf("unexpected exit code inspecting image %q: %d: %s", repoName, exitCode, out)
  5789  	}
  5790  }
  5791  
  5792  func (s *DockerTrustSuite) TestTrustedBuildUntrustedTag(c *check.C) {
  5793  	repoName := fmt.Sprintf("%v/dockercli/build-untrusted-tag:latest", privateRegistryURL)
  5794  	dockerFile := fmt.Sprintf(`
  5795    FROM %s
  5796    RUN []
  5797      `, repoName)
  5798  
  5799  	name := "testtrustedbuilduntrustedtag"
  5800  
  5801  	buildCmd := buildImageCmd(name, dockerFile, true)
  5802  	s.trustedCmd(buildCmd)
  5803  	out, _, err := runCommandWithOutput(buildCmd)
  5804  	if err == nil {
  5805  		c.Fatalf("Expected error on trusted build with untrusted tag: %s\n%s", err, out)
  5806  	}
  5807  
  5808  	if !strings.Contains(out, fmt.Sprintf("no trust data available")) {
  5809  		c.Fatalf("Unexpected output on trusted build with untrusted tag:\n%s", out)
  5810  	}
  5811  }
  5812  
  5813  func (s *DockerTrustSuite) TestBuildContextDirIsSymlink(c *check.C) {
  5814  	testRequires(c, DaemonIsLinux)
  5815  	tempDir, err := ioutil.TempDir("", "test-build-dir-is-symlink-")
  5816  	c.Assert(err, check.IsNil)
  5817  	defer os.RemoveAll(tempDir)
  5818  
  5819  	// Make a real context directory in this temp directory with a simple
  5820  	// Dockerfile.
  5821  	realContextDirname := filepath.Join(tempDir, "context")
  5822  	if err := os.Mkdir(realContextDirname, os.FileMode(0755)); err != nil {
  5823  		c.Fatal(err)
  5824  	}
  5825  
  5826  	if err = ioutil.WriteFile(
  5827  		filepath.Join(realContextDirname, "Dockerfile"),
  5828  		[]byte(`
  5829  			FROM busybox
  5830  			RUN echo hello world
  5831  		`),
  5832  		os.FileMode(0644),
  5833  	); err != nil {
  5834  		c.Fatal(err)
  5835  	}
  5836  
  5837  	// Make a symlink to the real context directory.
  5838  	contextSymlinkName := filepath.Join(tempDir, "context_link")
  5839  	if err := os.Symlink(realContextDirname, contextSymlinkName); err != nil {
  5840  		c.Fatal(err)
  5841  	}
  5842  
  5843  	// Executing the build with the symlink as the specified context should
  5844  	// *not* fail.
  5845  	if out, exitStatus := dockerCmd(c, "build", contextSymlinkName); exitStatus != 0 {
  5846  		c.Fatalf("build failed with exit status %d: %s", exitStatus, out)
  5847  	}
  5848  }
  5849  
  5850  // Issue #15634: COPY fails when path starts with "null"
  5851  func (s *DockerSuite) TestBuildNullStringInAddCopyVolume(c *check.C) {
  5852  	testRequires(c, DaemonIsLinux)
  5853  	name := "testbuildnullstringinaddcopyvolume"
  5854  
  5855  	ctx, err := fakeContext(`
  5856  		FROM busybox
  5857  
  5858  		ADD null /
  5859  		COPY nullfile /
  5860  		VOLUME nullvolume
  5861  		`,
  5862  		map[string]string{
  5863  			"null":     "test1",
  5864  			"nullfile": "test2",
  5865  		},
  5866  	)
  5867  	c.Assert(err, check.IsNil)
  5868  	defer ctx.Close()
  5869  
  5870  	_, err = buildImageFromContext(name, ctx, true)
  5871  	c.Assert(err, check.IsNil)
  5872  }
  5873  
  5874  func (s *DockerSuite) TestBuildStopSignal(c *check.C) {
  5875  	testRequires(c, DaemonIsLinux)
  5876  	name := "test_build_stop_signal"
  5877  	_, err := buildImage(name,
  5878  		`FROM busybox
  5879  		 STOPSIGNAL SIGKILL`,
  5880  		true)
  5881  	c.Assert(err, check.IsNil)
  5882  	res, err := inspectFieldJSON(name, "Config.StopSignal")
  5883  	c.Assert(err, check.IsNil)
  5884  
  5885  	if res != `"SIGKILL"` {
  5886  		c.Fatalf("Signal %s, expected SIGKILL", res)
  5887  	}
  5888  }
  5889  
  5890  func (s *DockerSuite) TestBuildBuildTimeArg(c *check.C) {
  5891  	testRequires(c, DaemonIsLinux)
  5892  	imgName := "bldargtest"
  5893  	envKey := "foo"
  5894  	envVal := "bar"
  5895  	args := []string{
  5896  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5897  	}
  5898  	dockerfile := fmt.Sprintf(`FROM busybox
  5899  		ARG %s
  5900  		RUN echo $%s
  5901  		CMD echo $%s`, envKey, envKey, envKey)
  5902  
  5903  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || !strings.Contains(out, envVal) {
  5904  		if err != nil {
  5905  			c.Fatalf("build failed to complete: %q %q", out, err)
  5906  		}
  5907  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envVal)
  5908  	}
  5909  
  5910  	containerName := "bldargCont"
  5911  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); out != "\n" {
  5912  		c.Fatalf("run produced invalid output: %q, expected empty string", out)
  5913  	}
  5914  }
  5915  
  5916  func (s *DockerSuite) TestBuildBuildTimeArgHistory(c *check.C) {
  5917  	testRequires(c, DaemonIsLinux)
  5918  	imgName := "bldargtest"
  5919  	envKey := "foo"
  5920  	envVal := "bar"
  5921  	envDef := "bar1"
  5922  	args := []string{
  5923  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5924  	}
  5925  	dockerfile := fmt.Sprintf(`FROM busybox
  5926  		ARG %s=%s`, envKey, envDef)
  5927  
  5928  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || !strings.Contains(out, envVal) {
  5929  		if err != nil {
  5930  			c.Fatalf("build failed to complete: %q %q", out, err)
  5931  		}
  5932  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envVal)
  5933  	}
  5934  
  5935  	out, _ := dockerCmd(c, "history", "--no-trunc", imgName)
  5936  	outputTabs := strings.Split(out, "\n")[1]
  5937  	if !strings.Contains(outputTabs, envDef) {
  5938  		c.Fatalf("failed to find arg default in image history output: %q expected: %q", outputTabs, envDef)
  5939  	}
  5940  }
  5941  
  5942  func (s *DockerSuite) TestBuildBuildTimeArgCacheHit(c *check.C) {
  5943  	testRequires(c, DaemonIsLinux)
  5944  	imgName := "bldargtest"
  5945  	envKey := "foo"
  5946  	envVal := "bar"
  5947  	args := []string{
  5948  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5949  	}
  5950  	dockerfile := fmt.Sprintf(`FROM busybox
  5951  		ARG %s
  5952  		RUN echo $%s`, envKey, envKey)
  5953  
  5954  	origImgID := ""
  5955  	var err error
  5956  	if origImgID, err = buildImage(imgName, dockerfile, true, args...); err != nil {
  5957  		c.Fatal(err)
  5958  	}
  5959  
  5960  	imgNameCache := "bldargtestcachehit"
  5961  	if newImgID, err := buildImage(imgNameCache, dockerfile, true, args...); err != nil || newImgID != origImgID {
  5962  		if err != nil {
  5963  			c.Fatal(err)
  5964  		}
  5965  		c.Fatalf("build didn't use cache! expected image id: %q built image id: %q", origImgID, newImgID)
  5966  	}
  5967  }
  5968  
  5969  func (s *DockerSuite) TestBuildBuildTimeArgCacheMissExtraArg(c *check.C) {
  5970  	testRequires(c, DaemonIsLinux)
  5971  	imgName := "bldargtest"
  5972  	envKey := "foo"
  5973  	envVal := "bar"
  5974  	extraEnvKey := "foo1"
  5975  	extraEnvVal := "bar1"
  5976  	args := []string{
  5977  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5978  	}
  5979  
  5980  	dockerfile := fmt.Sprintf(`FROM busybox
  5981  		ARG %s
  5982  		ARG %s
  5983  		RUN echo $%s`, envKey, extraEnvKey, envKey)
  5984  
  5985  	origImgID := ""
  5986  	var err error
  5987  	if origImgID, err = buildImage(imgName, dockerfile, true, args...); err != nil {
  5988  		c.Fatal(err)
  5989  	}
  5990  
  5991  	imgNameCache := "bldargtestcachemiss"
  5992  	args = append(args, "--build-arg", fmt.Sprintf("%s=%s", extraEnvKey, extraEnvVal))
  5993  	if newImgID, err := buildImage(imgNameCache, dockerfile, true, args...); err != nil || newImgID == origImgID {
  5994  		if err != nil {
  5995  			c.Fatal(err)
  5996  		}
  5997  		c.Fatalf("build used cache, expected a miss!")
  5998  	}
  5999  }
  6000  
  6001  func (s *DockerSuite) TestBuildBuildTimeArgCacheMissSameArgDiffVal(c *check.C) {
  6002  	testRequires(c, DaemonIsLinux)
  6003  	imgName := "bldargtest"
  6004  	envKey := "foo"
  6005  	envVal := "bar"
  6006  	newEnvVal := "bar1"
  6007  	args := []string{
  6008  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6009  	}
  6010  
  6011  	dockerfile := fmt.Sprintf(`FROM busybox
  6012  		ARG %s
  6013  		RUN echo $%s`, envKey, envKey)
  6014  
  6015  	origImgID := ""
  6016  	var err error
  6017  	if origImgID, err = buildImage(imgName, dockerfile, true, args...); err != nil {
  6018  		c.Fatal(err)
  6019  	}
  6020  
  6021  	imgNameCache := "bldargtestcachemiss"
  6022  	args = []string{
  6023  		"--build-arg", fmt.Sprintf("%s=%s", envKey, newEnvVal),
  6024  	}
  6025  	if newImgID, err := buildImage(imgNameCache, dockerfile, true, args...); err != nil || newImgID == origImgID {
  6026  		if err != nil {
  6027  			c.Fatal(err)
  6028  		}
  6029  		c.Fatalf("build used cache, expected a miss!")
  6030  	}
  6031  }
  6032  
  6033  func (s *DockerSuite) TestBuildBuildTimeArgOverrideArgDefinedBeforeEnv(c *check.C) {
  6034  	testRequires(c, DaemonIsLinux)
  6035  	imgName := "bldargtest"
  6036  	envKey := "foo"
  6037  	envVal := "bar"
  6038  	envValOveride := "barOverride"
  6039  	args := []string{
  6040  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6041  	}
  6042  	dockerfile := fmt.Sprintf(`FROM busybox
  6043  		ARG %s
  6044  		ENV %s %s
  6045  		RUN echo $%s
  6046  		CMD echo $%s
  6047          `, envKey, envKey, envValOveride, envKey, envKey)
  6048  
  6049  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 2 {
  6050  		if err != nil {
  6051  			c.Fatalf("build failed to complete: %q %q", out, err)
  6052  		}
  6053  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  6054  	}
  6055  
  6056  	containerName := "bldargCont"
  6057  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  6058  		c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  6059  	}
  6060  }
  6061  
  6062  func (s *DockerSuite) TestBuildBuildTimeArgOverrideEnvDefinedBeforeArg(c *check.C) {
  6063  	testRequires(c, DaemonIsLinux)
  6064  	imgName := "bldargtest"
  6065  	envKey := "foo"
  6066  	envVal := "bar"
  6067  	envValOveride := "barOverride"
  6068  	args := []string{
  6069  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6070  	}
  6071  	dockerfile := fmt.Sprintf(`FROM busybox
  6072  		ENV %s %s
  6073  		ARG %s
  6074  		RUN echo $%s
  6075  		CMD echo $%s
  6076          `, envKey, envValOveride, envKey, envKey, envKey)
  6077  
  6078  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 2 {
  6079  		if err != nil {
  6080  			c.Fatalf("build failed to complete: %q %q", out, err)
  6081  		}
  6082  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  6083  	}
  6084  
  6085  	containerName := "bldargCont"
  6086  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  6087  		c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  6088  	}
  6089  }
  6090  
  6091  func (s *DockerSuite) TestBuildBuildTimeArgExpansion(c *check.C) {
  6092  	testRequires(c, DaemonIsLinux)
  6093  	imgName := "bldvarstest"
  6094  
  6095  	wdVar := "WDIR"
  6096  	wdVal := "/tmp/"
  6097  	addVar := "AFILE"
  6098  	addVal := "addFile"
  6099  	copyVar := "CFILE"
  6100  	copyVal := "copyFile"
  6101  	envVar := "foo"
  6102  	envVal := "bar"
  6103  	exposeVar := "EPORT"
  6104  	exposeVal := "9999"
  6105  	userVar := "USER"
  6106  	userVal := "testUser"
  6107  	volVar := "VOL"
  6108  	volVal := "/testVol/"
  6109  	args := []string{
  6110  		"--build-arg", fmt.Sprintf("%s=%s", wdVar, wdVal),
  6111  		"--build-arg", fmt.Sprintf("%s=%s", addVar, addVal),
  6112  		"--build-arg", fmt.Sprintf("%s=%s", copyVar, copyVal),
  6113  		"--build-arg", fmt.Sprintf("%s=%s", envVar, envVal),
  6114  		"--build-arg", fmt.Sprintf("%s=%s", exposeVar, exposeVal),
  6115  		"--build-arg", fmt.Sprintf("%s=%s", userVar, userVal),
  6116  		"--build-arg", fmt.Sprintf("%s=%s", volVar, volVal),
  6117  	}
  6118  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  6119  		ARG %s
  6120  		WORKDIR ${%s}
  6121  		ARG %s
  6122  		ADD ${%s} testDir/
  6123  		ARG %s
  6124  		COPY $%s testDir/
  6125  		ARG %s
  6126  		ENV %s=${%s}
  6127  		ARG %s
  6128  		EXPOSE $%s
  6129  		ARG %s
  6130  		USER $%s
  6131  		ARG %s
  6132  		VOLUME ${%s}`,
  6133  		wdVar, wdVar, addVar, addVar, copyVar, copyVar, envVar, envVar,
  6134  		envVar, exposeVar, exposeVar, userVar, userVar, volVar, volVar),
  6135  		map[string]string{
  6136  			addVal:  "some stuff",
  6137  			copyVal: "some stuff",
  6138  		})
  6139  	if err != nil {
  6140  		c.Fatal(err)
  6141  	}
  6142  	defer ctx.Close()
  6143  
  6144  	if _, err := buildImageFromContext(imgName, ctx, true, args...); err != nil {
  6145  		c.Fatal(err)
  6146  	}
  6147  
  6148  	var resMap map[string]interface{}
  6149  	var resArr []string
  6150  	res := ""
  6151  	res, err = inspectField(imgName, "Config.WorkingDir")
  6152  	if err != nil {
  6153  		c.Fatal(err)
  6154  	}
  6155  	if res != wdVal {
  6156  		c.Fatalf("Config.WorkingDir value mismatch. Expected: %s, got: %s", wdVal, res)
  6157  	}
  6158  
  6159  	err = inspectFieldAndMarshall(imgName, "Config.Env", &resArr)
  6160  	if err != nil {
  6161  		c.Fatal(err)
  6162  	}
  6163  
  6164  	found := false
  6165  	for _, v := range resArr {
  6166  		if fmt.Sprintf("%s=%s", envVar, envVal) == v {
  6167  			found = true
  6168  			break
  6169  		}
  6170  	}
  6171  	if !found {
  6172  		c.Fatalf("Config.Env value mismatch. Expected <key=value> to exist: %s=%s, got: %v",
  6173  			envVar, envVal, resArr)
  6174  	}
  6175  
  6176  	err = inspectFieldAndMarshall(imgName, "Config.ExposedPorts", &resMap)
  6177  	if err != nil {
  6178  		c.Fatal(err)
  6179  	}
  6180  	if _, ok := resMap[fmt.Sprintf("%s/tcp", exposeVal)]; !ok {
  6181  		c.Fatalf("Config.ExposedPorts value mismatch. Expected exposed port: %s/tcp, got: %v", exposeVal, resMap)
  6182  	}
  6183  
  6184  	res, err = inspectField(imgName, "Config.User")
  6185  	if err != nil {
  6186  		c.Fatal(err)
  6187  	}
  6188  	if res != userVal {
  6189  		c.Fatalf("Config.User value mismatch. Expected: %s, got: %s", userVal, res)
  6190  	}
  6191  
  6192  	err = inspectFieldAndMarshall(imgName, "Config.Volumes", &resMap)
  6193  	if err != nil {
  6194  		c.Fatal(err)
  6195  	}
  6196  	if _, ok := resMap[volVal]; !ok {
  6197  		c.Fatalf("Config.Volumes value mismatch. Expected volume: %s, got: %v", volVal, resMap)
  6198  	}
  6199  }
  6200  
  6201  func (s *DockerSuite) TestBuildBuildTimeArgExpansionOverride(c *check.C) {
  6202  	testRequires(c, DaemonIsLinux)
  6203  	imgName := "bldvarstest"
  6204  	envKey := "foo"
  6205  	envVal := "bar"
  6206  	envKey1 := "foo1"
  6207  	envValOveride := "barOverride"
  6208  	args := []string{
  6209  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6210  	}
  6211  	dockerfile := fmt.Sprintf(`FROM busybox
  6212  		ARG %s
  6213  		ENV %s %s
  6214  		ENV %s ${%s}
  6215  		RUN echo $%s
  6216  		CMD echo $%s`, envKey, envKey, envValOveride, envKey1, envKey, envKey1, envKey1)
  6217  
  6218  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 2 {
  6219  		if err != nil {
  6220  			c.Fatalf("build failed to complete: %q %q", out, err)
  6221  		}
  6222  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  6223  	}
  6224  
  6225  	containerName := "bldargCont"
  6226  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  6227  		c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  6228  	}
  6229  }
  6230  
  6231  func (s *DockerSuite) TestBuildBuildTimeArgUntrustedDefinedAfterUse(c *check.C) {
  6232  	testRequires(c, DaemonIsLinux)
  6233  	imgName := "bldargtest"
  6234  	envKey := "foo"
  6235  	envVal := "bar"
  6236  	args := []string{
  6237  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6238  	}
  6239  	dockerfile := fmt.Sprintf(`FROM busybox
  6240  		RUN echo $%s
  6241  		ARG %s
  6242  		CMD echo $%s`, envKey, envKey, envKey)
  6243  
  6244  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Contains(out, envVal) {
  6245  		if err != nil {
  6246  			c.Fatalf("build failed to complete: %q %q", out, err)
  6247  		}
  6248  		c.Fatalf("able to access environment variable in output: %q expected to be missing", out)
  6249  	}
  6250  
  6251  	containerName := "bldargCont"
  6252  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); out != "\n" {
  6253  		c.Fatalf("run produced invalid output: %q, expected empty string", out)
  6254  	}
  6255  }
  6256  
  6257  func (s *DockerSuite) TestBuildBuildTimeArgBuiltinArg(c *check.C) {
  6258  	testRequires(c, DaemonIsLinux)
  6259  	imgName := "bldargtest"
  6260  	envKey := "HTTP_PROXY"
  6261  	envVal := "bar"
  6262  	args := []string{
  6263  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6264  	}
  6265  	dockerfile := fmt.Sprintf(`FROM busybox
  6266  		RUN echo $%s
  6267  		CMD echo $%s`, envKey, envKey)
  6268  
  6269  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || !strings.Contains(out, envVal) {
  6270  		if err != nil {
  6271  			c.Fatalf("build failed to complete: %q %q", out, err)
  6272  		}
  6273  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envVal)
  6274  	}
  6275  
  6276  	containerName := "bldargCont"
  6277  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); out != "\n" {
  6278  		c.Fatalf("run produced invalid output: %q, expected empty string", out)
  6279  	}
  6280  }
  6281  
  6282  func (s *DockerSuite) TestBuildBuildTimeArgDefaultOverride(c *check.C) {
  6283  	testRequires(c, DaemonIsLinux)
  6284  	imgName := "bldargtest"
  6285  	envKey := "foo"
  6286  	envVal := "bar"
  6287  	envValOveride := "barOverride"
  6288  	args := []string{
  6289  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envValOveride),
  6290  	}
  6291  	dockerfile := fmt.Sprintf(`FROM busybox
  6292  		ARG %s=%s
  6293  		ENV %s $%s
  6294  		RUN echo $%s
  6295  		CMD echo $%s`, envKey, envVal, envKey, envKey, envKey, envKey)
  6296  
  6297  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 1 {
  6298  		if err != nil {
  6299  			c.Fatalf("build failed to complete: %q %q", out, err)
  6300  		}
  6301  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  6302  	}
  6303  
  6304  	containerName := "bldargCont"
  6305  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  6306  		c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  6307  	}
  6308  }
  6309  
  6310  func (s *DockerSuite) TestBuildBuildTimeArgMultiArgsSameLine(c *check.C) {
  6311  	testRequires(c, DaemonIsLinux)
  6312  	imgName := "bldargtest"
  6313  	envKey := "foo"
  6314  	envKey1 := "foo1"
  6315  	args := []string{}
  6316  	dockerfile := fmt.Sprintf(`FROM busybox
  6317  		ARG %s %s`, envKey, envKey1)
  6318  
  6319  	errStr := "ARG requires exactly one argument definition"
  6320  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err == nil {
  6321  		c.Fatalf("build succeeded, expected to fail. Output: %v", out)
  6322  	} else if !strings.Contains(out, errStr) {
  6323  		c.Fatalf("Unexpected error. output: %q, expected error: %q", out, errStr)
  6324  	}
  6325  }
  6326  
  6327  func (s *DockerSuite) TestBuildBuildTimeArgUnconsumedArg(c *check.C) {
  6328  	testRequires(c, DaemonIsLinux)
  6329  	imgName := "bldargtest"
  6330  	envKey := "foo"
  6331  	envVal := "bar"
  6332  	args := []string{
  6333  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6334  	}
  6335  	dockerfile := fmt.Sprintf(`FROM busybox
  6336  		RUN echo $%s
  6337  		CMD echo $%s`, envKey, envKey)
  6338  
  6339  	errStr := "One or more build-args"
  6340  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err == nil {
  6341  		c.Fatalf("build succeeded, expected to fail. Output: %v", out)
  6342  	} else if !strings.Contains(out, errStr) {
  6343  		c.Fatalf("Unexpected error. output: %q, expected error: %q", out, errStr)
  6344  	}
  6345  
  6346  }
  6347  
  6348  func (s *DockerSuite) TestBuildBuildTimeArgQuotedValVariants(c *check.C) {
  6349  	testRequires(c, DaemonIsLinux)
  6350  	imgName := "bldargtest"
  6351  	envKey := "foo"
  6352  	envKey1 := "foo1"
  6353  	envKey2 := "foo2"
  6354  	envKey3 := "foo3"
  6355  	args := []string{}
  6356  	dockerfile := fmt.Sprintf(`FROM busybox
  6357  		ARG %s=""
  6358  		ARG %s=''
  6359  		ARG %s="''"
  6360  		ARG %s='""'
  6361  		RUN [ "$%s" != "$%s" ]
  6362  		RUN [ "$%s" != "$%s" ]
  6363  		RUN [ "$%s" != "$%s" ]
  6364  		RUN [ "$%s" != "$%s" ]
  6365  		RUN [ "$%s" != "$%s" ]`, envKey, envKey1, envKey2, envKey3,
  6366  		envKey, envKey2, envKey, envKey3, envKey1, envKey2, envKey1, envKey3,
  6367  		envKey2, envKey3)
  6368  
  6369  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil {
  6370  		c.Fatalf("build failed to complete: %q %q", out, err)
  6371  	}
  6372  }
  6373  
  6374  func (s *DockerSuite) TestBuildBuildTimeArgEmptyValVariants(c *check.C) {
  6375  	testRequires(c, DaemonIsLinux)
  6376  	imgName := "bldargtest"
  6377  	envKey := "foo"
  6378  	envKey1 := "foo1"
  6379  	envKey2 := "foo2"
  6380  	args := []string{}
  6381  	dockerfile := fmt.Sprintf(`FROM busybox
  6382  		ARG %s=
  6383  		ARG %s=""
  6384  		ARG %s=''
  6385  		RUN [ "$%s" == "$%s" ]
  6386  		RUN [ "$%s" == "$%s" ]
  6387  		RUN [ "$%s" == "$%s" ]`, envKey, envKey1, envKey2, envKey, envKey1, envKey1, envKey2, envKey, envKey2)
  6388  
  6389  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil {
  6390  		c.Fatalf("build failed to complete: %q %q", out, err)
  6391  	}
  6392  }
  6393  
  6394  func (s *DockerSuite) TestBuildBuildTimeArgDefintionWithNoEnvInjection(c *check.C) {
  6395  	testRequires(c, DaemonIsLinux)
  6396  	imgName := "bldargtest"
  6397  	envKey := "foo"
  6398  	args := []string{}
  6399  	dockerfile := fmt.Sprintf(`FROM busybox
  6400  		ARG %s
  6401  		RUN env`, envKey)
  6402  
  6403  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envKey) != 1 {
  6404  		if err != nil {
  6405  			c.Fatalf("build failed to complete: %q %q", out, err)
  6406  		}
  6407  		c.Fatalf("unexpected number of occurrences of the arg in output: %q expected: 1", out)
  6408  	}
  6409  }
  6410  
  6411  func (s *DockerSuite) TestBuildNoNamedVolume(c *check.C) {
  6412  	testRequires(c, DaemonIsLinux)
  6413  	dockerCmd(c, "run", "-v", "testname:/foo", "busybox", "sh", "-c", "touch /foo/oops")
  6414  
  6415  	dockerFile := `FROM busybox
  6416  	VOLUME testname:/foo
  6417  	RUN ls /foo/oops
  6418  	`
  6419  	_, err := buildImage("test", dockerFile, false)
  6420  	c.Assert(err, check.NotNil, check.Commentf("image build should have failed"))
  6421  }
  6422  
  6423  func (s *DockerSuite) TestBuildTagEvent(c *check.C) {
  6424  	testRequires(c, DaemonIsLinux)
  6425  	resp, rc, err := sockRequestRaw("GET", `/events?filters={"event":["tag"]}`, nil, "application/json")
  6426  	c.Assert(err, check.IsNil)
  6427  	defer rc.Close()
  6428  	c.Assert(resp.StatusCode, check.Equals, http.StatusOK)
  6429  
  6430  	type event struct {
  6431  		Status string `json:"status"`
  6432  		ID     string `json:"id"`
  6433  	}
  6434  	ch := make(chan event)
  6435  	go func() {
  6436  		ev := event{}
  6437  		if err := json.NewDecoder(rc).Decode(&ev); err == nil {
  6438  			ch <- ev
  6439  		}
  6440  	}()
  6441  
  6442  	dockerFile := `FROM busybox
  6443  	RUN echo events
  6444  	`
  6445  	_, err = buildImage("test", dockerFile, false)
  6446  	c.Assert(err, check.IsNil)
  6447  
  6448  	select {
  6449  	case ev := <-ch:
  6450  		c.Assert(ev.Status, check.Equals, "tag")
  6451  		c.Assert(ev.ID, check.Equals, "test:latest")
  6452  	case <-time.After(5 * time.Second):
  6453  		c.Fatal("The 'tag' event not heard from the server")
  6454  	}
  6455  }
  6456  
  6457  // #15780
  6458  func (s *DockerSuite) TestBuildMultipleTags(c *check.C) {
  6459  	dockerfile := `
  6460  	FROM busybox
  6461  	MAINTAINER test-15780
  6462  	`
  6463  	cmd := exec.Command(dockerBinary, "build", "-t", "tag1", "-t", "tag2:v2",
  6464  		"-t", "tag1:latest", "-t", "tag1", "--no-cache", "-")
  6465  	cmd.Stdin = strings.NewReader(dockerfile)
  6466  	_, err := runCommand(cmd)
  6467  	c.Assert(err, check.IsNil)
  6468  
  6469  	id1, err := getIDByName("tag1")
  6470  	c.Assert(err, check.IsNil)
  6471  	id2, err := getIDByName("tag2:v2")
  6472  	c.Assert(err, check.IsNil)
  6473  	c.Assert(id1, check.Equals, id2)
  6474  }
  6475  
  6476  // #17290
  6477  func (s *DockerSuite) TestBuildCacheBrokenSymlink(c *check.C) {
  6478  	testRequires(c, DaemonIsLinux)
  6479  	name := "testbuildbrokensymlink"
  6480  	ctx, err := fakeContext(`
  6481  	FROM busybox
  6482  	COPY . ./`,
  6483  		map[string]string{
  6484  			"foo": "bar",
  6485  		})
  6486  	c.Assert(err, checker.IsNil)
  6487  	defer ctx.Close()
  6488  
  6489  	err = os.Symlink(filepath.Join(ctx.Dir, "nosuchfile"), filepath.Join(ctx.Dir, "asymlink"))
  6490  	c.Assert(err, checker.IsNil)
  6491  
  6492  	// warm up cache
  6493  	_, err = buildImageFromContext(name, ctx, true)
  6494  	c.Assert(err, checker.IsNil)
  6495  
  6496  	// add new file to context, should invalidate cache
  6497  	err = ioutil.WriteFile(filepath.Join(ctx.Dir, "newfile"), []byte("foo"), 0644)
  6498  	c.Assert(err, checker.IsNil)
  6499  
  6500  	_, out, err := buildImageFromContextWithOut(name, ctx, true)
  6501  	c.Assert(err, checker.IsNil)
  6502  
  6503  	c.Assert(out, checker.Not(checker.Contains), "Using cache")
  6504  
  6505  }
  6506  
  6507  func (s *DockerSuite) TestBuildFollowSymlinkToFile(c *check.C) {
  6508  	testRequires(c, DaemonIsLinux)
  6509  	name := "testbuildbrokensymlink"
  6510  	ctx, err := fakeContext(`
  6511  	FROM busybox
  6512  	COPY asymlink target`,
  6513  		map[string]string{
  6514  			"foo": "bar",
  6515  		})
  6516  	c.Assert(err, checker.IsNil)
  6517  	defer ctx.Close()
  6518  
  6519  	err = os.Symlink("foo", filepath.Join(ctx.Dir, "asymlink"))
  6520  	c.Assert(err, checker.IsNil)
  6521  
  6522  	id, err := buildImageFromContext(name, ctx, true)
  6523  	c.Assert(err, checker.IsNil)
  6524  
  6525  	out, _ := dockerCmd(c, "run", "--rm", id, "cat", "target")
  6526  	c.Assert(out, checker.Matches, "bar")
  6527  
  6528  	// change target file should invalidate cache
  6529  	err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("baz"), 0644)
  6530  	c.Assert(err, checker.IsNil)
  6531  
  6532  	id, out, err = buildImageFromContextWithOut(name, ctx, true)
  6533  	c.Assert(err, checker.IsNil)
  6534  	c.Assert(out, checker.Not(checker.Contains), "Using cache")
  6535  
  6536  	out, _ = dockerCmd(c, "run", "--rm", id, "cat", "target")
  6537  	c.Assert(out, checker.Matches, "baz")
  6538  }
  6539  
  6540  func (s *DockerSuite) TestBuildFollowSymlinkToDir(c *check.C) {
  6541  	testRequires(c, DaemonIsLinux)
  6542  	name := "testbuildbrokensymlink"
  6543  	ctx, err := fakeContext(`
  6544  	FROM busybox
  6545  	COPY asymlink /`,
  6546  		map[string]string{
  6547  			"foo/abc": "bar",
  6548  			"foo/def": "baz",
  6549  		})
  6550  	c.Assert(err, checker.IsNil)
  6551  	defer ctx.Close()
  6552  
  6553  	err = os.Symlink("foo", filepath.Join(ctx.Dir, "asymlink"))
  6554  	c.Assert(err, checker.IsNil)
  6555  
  6556  	id, err := buildImageFromContext(name, ctx, true)
  6557  	c.Assert(err, checker.IsNil)
  6558  
  6559  	out, _ := dockerCmd(c, "run", "--rm", id, "cat", "abc", "def")
  6560  	c.Assert(out, checker.Matches, "barbaz")
  6561  
  6562  	// change target file should invalidate cache
  6563  	err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo/def"), []byte("bax"), 0644)
  6564  	c.Assert(err, checker.IsNil)
  6565  
  6566  	id, out, err = buildImageFromContextWithOut(name, ctx, true)
  6567  	c.Assert(err, checker.IsNil)
  6568  	c.Assert(out, checker.Not(checker.Contains), "Using cache")
  6569  
  6570  	out, _ = dockerCmd(c, "run", "--rm", id, "cat", "abc", "def")
  6571  	c.Assert(out, checker.Matches, "barbax")
  6572  
  6573  }
  6574  
  6575  // TestBuildSymlinkBasename tests that target file gets basename from symlink,
  6576  // not from the target file.
  6577  func (s *DockerSuite) TestBuildSymlinkBasename(c *check.C) {
  6578  	testRequires(c, DaemonIsLinux)
  6579  	name := "testbuildbrokensymlink"
  6580  	ctx, err := fakeContext(`
  6581  	FROM busybox
  6582  	COPY asymlink /`,
  6583  		map[string]string{
  6584  			"foo": "bar",
  6585  		})
  6586  	c.Assert(err, checker.IsNil)
  6587  	defer ctx.Close()
  6588  
  6589  	err = os.Symlink("foo", filepath.Join(ctx.Dir, "asymlink"))
  6590  	c.Assert(err, checker.IsNil)
  6591  
  6592  	id, err := buildImageFromContext(name, ctx, true)
  6593  	c.Assert(err, checker.IsNil)
  6594  
  6595  	out, _ := dockerCmd(c, "run", "--rm", id, "cat", "asymlink")
  6596  	c.Assert(out, checker.Matches, "bar")
  6597  
  6598  }
  6599  
  6600  // #17827
  6601  func (s *DockerSuite) TestBuildCacheRootSource(c *check.C) {
  6602  	testRequires(c, DaemonIsLinux)
  6603  	name := "testbuildrootsource"
  6604  	ctx, err := fakeContext(`
  6605  	FROM busybox
  6606  	COPY / /data`,
  6607  		map[string]string{
  6608  			"foo": "bar",
  6609  		})
  6610  	c.Assert(err, checker.IsNil)
  6611  	defer ctx.Close()
  6612  
  6613  	// warm up cache
  6614  	_, err = buildImageFromContext(name, ctx, true)
  6615  	c.Assert(err, checker.IsNil)
  6616  
  6617  	// change file, should invalidate cache
  6618  	err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("baz"), 0644)
  6619  	c.Assert(err, checker.IsNil)
  6620  
  6621  	_, out, err := buildImageFromContextWithOut(name, ctx, true)
  6622  	c.Assert(err, checker.IsNil)
  6623  
  6624  	c.Assert(out, checker.Not(checker.Contains), "Using cache")
  6625  }