github.com/robertojrojas/docker@v1.9.1/integration-cli/docker_cli_build_test.go (about)

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