github.com/hustcat/docker@v1.3.3-0.20160314103604-901c67a8eeab/integration-cli/docker_cli_build_test.go (about)

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