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