github.com/endocode/docker@v1.4.2-0.20160113120958-46eb4700391e/integration-cli/docker_cli_build_test.go (about)

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