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