github.com/kunnos/engine@v1.13.1/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  	// TODO Windows (@jhowardmsft). Needs a follow-up PR to 22181 to
  1869  	// support backslash such as .\\ being equivalent to ./ and c:\\ being
  1870  	// equivalent to c:/. This is not currently (nor ever has been) supported
  1871  	// by docker on the Windows platform.
  1872  	dockerfile := `
  1873  		FROM busybox
  1874  			# No trailing slash on COPY/ADD
  1875  			# Results in dir being changed to a file
  1876  			WORKDIR /wc1
  1877  			COPY wc1 c:/wc1
  1878  			WORKDIR /wc2
  1879  			ADD wc2 c:/wc2
  1880  			WORKDIR c:/
  1881  			RUN sh -c "[ $(cat c:/wc1/wc1) = 'hellowc1' ]"
  1882  			RUN sh -c "[ $(cat c:/wc2/wc2) = 'worldwc2' ]"
  1883  
  1884  			# Trailing slash on COPY/ADD, Windows-style path.
  1885  			WORKDIR /wd1
  1886  			COPY wd1 c:/wd1/
  1887  			WORKDIR /wd2
  1888  			ADD wd2 c:/wd2/
  1889  			RUN sh -c "[ $(cat c:/wd1/wd1) = 'hellowd1' ]"
  1890  			RUN sh -c "[ $(cat c:/wd2/wd2) = 'worldwd2' ]"
  1891  			`
  1892  	ctx, err := fakeContext(dockerfile, map[string]string{
  1893  		"wc1": "hellowc1",
  1894  		"wc2": "worldwc2",
  1895  		"wd1": "hellowd1",
  1896  		"wd2": "worldwd2",
  1897  	})
  1898  	if err != nil {
  1899  		c.Fatal(err)
  1900  	}
  1901  	defer ctx.Close()
  1902  	_, err = buildImageFromContext(name, ctx, false)
  1903  	if err != nil {
  1904  		c.Fatal(err)
  1905  	}
  1906  }
  1907  
  1908  func (s *DockerSuite) TestBuildWorkdirWithEnvVariables(c *check.C) {
  1909  	name := "testbuildworkdirwithenvvariables"
  1910  
  1911  	var expected string
  1912  	if daemonPlatform == "windows" {
  1913  		expected = `C:\test1\test2`
  1914  	} else {
  1915  		expected = `/test1/test2`
  1916  	}
  1917  
  1918  	_, err := buildImage(name,
  1919  		`FROM busybox
  1920  		ENV DIRPATH /test1
  1921  		ENV SUBDIRNAME test2
  1922  		WORKDIR $DIRPATH
  1923  		WORKDIR $SUBDIRNAME/$MISSING_VAR`,
  1924  		true)
  1925  	if err != nil {
  1926  		c.Fatal(err)
  1927  	}
  1928  	res := inspectField(c, name, "Config.WorkingDir")
  1929  	if res != expected {
  1930  		c.Fatalf("Workdir %s, expected %s", res, expected)
  1931  	}
  1932  }
  1933  
  1934  func (s *DockerSuite) TestBuildRelativeCopy(c *check.C) {
  1935  	// cat /test1/test2/foo gets permission denied for the user
  1936  	testRequires(c, NotUserNamespace)
  1937  
  1938  	var expected string
  1939  	if daemonPlatform == "windows" {
  1940  		expected = `C:/test1/test2`
  1941  	} else {
  1942  		expected = `/test1/test2`
  1943  	}
  1944  
  1945  	name := "testbuildrelativecopy"
  1946  	dockerfile := `
  1947  		FROM busybox
  1948  			WORKDIR /test1
  1949  			WORKDIR test2
  1950  			RUN sh -c "[ "$PWD" = '` + expected + `' ]"
  1951  			COPY foo ./
  1952  			RUN sh -c "[ $(cat /test1/test2/foo) = 'hello' ]"
  1953  			ADD foo ./bar/baz
  1954  			RUN sh -c "[ $(cat /test1/test2/bar/baz) = 'hello' ]"
  1955  			COPY foo ./bar/baz2
  1956  			RUN sh -c "[ $(cat /test1/test2/bar/baz2) = 'hello' ]"
  1957  			WORKDIR ..
  1958  			COPY foo ./
  1959  			RUN sh -c "[ $(cat /test1/foo) = 'hello' ]"
  1960  			COPY foo /test3/
  1961  			RUN sh -c "[ $(cat /test3/foo) = 'hello' ]"
  1962  			WORKDIR /test4
  1963  			COPY . .
  1964  			RUN sh -c "[ $(cat /test4/foo) = 'hello' ]"
  1965  			WORKDIR /test5/test6
  1966  			COPY foo ../
  1967  			RUN sh -c "[ $(cat /test5/foo) = 'hello' ]"
  1968  			`
  1969  	ctx, err := fakeContext(dockerfile, map[string]string{
  1970  		"foo": "hello",
  1971  	})
  1972  	if err != nil {
  1973  		c.Fatal(err)
  1974  	}
  1975  	defer ctx.Close()
  1976  	_, err = buildImageFromContext(name, ctx, false)
  1977  	if err != nil {
  1978  		c.Fatal(err)
  1979  	}
  1980  }
  1981  
  1982  func (s *DockerSuite) TestBuildBlankName(c *check.C) {
  1983  	name := "testbuildblankname"
  1984  	_, _, stderr, err := buildImageWithStdoutStderr(name,
  1985  		`FROM busybox
  1986  		ENV =`,
  1987  		true)
  1988  	if err == nil {
  1989  		c.Fatal("Build was supposed to fail but didn't")
  1990  	}
  1991  	if !strings.Contains(stderr, "ENV names can not be blank") {
  1992  		c.Fatalf("Missing error message, got: %s", stderr)
  1993  	}
  1994  
  1995  	_, _, stderr, err = buildImageWithStdoutStderr(name,
  1996  		`FROM busybox
  1997  		LABEL =`,
  1998  		true)
  1999  	if err == nil {
  2000  		c.Fatal("Build was supposed to fail but didn't")
  2001  	}
  2002  	if !strings.Contains(stderr, "LABEL names can not be blank") {
  2003  		c.Fatalf("Missing error message, got: %s", stderr)
  2004  	}
  2005  
  2006  	_, _, stderr, err = buildImageWithStdoutStderr(name,
  2007  		`FROM busybox
  2008  		ARG =foo`,
  2009  		true)
  2010  	if err == nil {
  2011  		c.Fatal("Build was supposed to fail but didn't")
  2012  	}
  2013  	if !strings.Contains(stderr, "ARG names can not be blank") {
  2014  		c.Fatalf("Missing error message, got: %s", stderr)
  2015  	}
  2016  }
  2017  
  2018  func (s *DockerSuite) TestBuildEnv(c *check.C) {
  2019  	testRequires(c, DaemonIsLinux) // ENV expansion is different in Windows
  2020  	name := "testbuildenv"
  2021  	expected := "[PATH=/test:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PORT=2375]"
  2022  	_, err := buildImage(name,
  2023  		`FROM busybox
  2024  		ENV PATH /test:$PATH
  2025          ENV PORT 2375
  2026  		RUN [ $(env | grep PORT) = 'PORT=2375' ]`,
  2027  		true)
  2028  	if err != nil {
  2029  		c.Fatal(err)
  2030  	}
  2031  	res := inspectField(c, name, "Config.Env")
  2032  	if res != expected {
  2033  		c.Fatalf("Env %s, expected %s", res, expected)
  2034  	}
  2035  }
  2036  
  2037  func (s *DockerSuite) TestBuildPATH(c *check.C) {
  2038  	testRequires(c, DaemonIsLinux) // ENV expansion is different in Windows
  2039  
  2040  	defPath := "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  2041  
  2042  	fn := func(dockerfile string, exp string) {
  2043  		_, err := buildImage("testbldpath", dockerfile, true)
  2044  		c.Assert(err, check.IsNil)
  2045  
  2046  		res := inspectField(c, "testbldpath", "Config.Env")
  2047  
  2048  		if res != exp {
  2049  			c.Fatalf("Env %q, expected %q for dockerfile:%q", res, exp, dockerfile)
  2050  		}
  2051  	}
  2052  
  2053  	tests := []struct{ dockerfile, exp string }{
  2054  		{"FROM scratch\nMAINTAINER me", "[PATH=" + defPath + "]"},
  2055  		{"FROM busybox\nMAINTAINER me", "[PATH=" + defPath + "]"},
  2056  		{"FROM scratch\nENV FOO=bar", "[PATH=" + defPath + " FOO=bar]"},
  2057  		{"FROM busybox\nENV FOO=bar", "[PATH=" + defPath + " FOO=bar]"},
  2058  		{"FROM scratch\nENV PATH=/test", "[PATH=/test]"},
  2059  		{"FROM busybox\nENV PATH=/test", "[PATH=/test]"},
  2060  		{"FROM scratch\nENV PATH=''", "[PATH=]"},
  2061  		{"FROM busybox\nENV PATH=''", "[PATH=]"},
  2062  	}
  2063  
  2064  	for _, test := range tests {
  2065  		fn(test.dockerfile, test.exp)
  2066  	}
  2067  }
  2068  
  2069  func (s *DockerSuite) TestBuildContextCleanup(c *check.C) {
  2070  	testRequires(c, SameHostDaemon)
  2071  
  2072  	name := "testbuildcontextcleanup"
  2073  	entries, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  2074  	if err != nil {
  2075  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2076  	}
  2077  	_, err = buildImage(name,
  2078  		`FROM `+minimalBaseImage()+`
  2079          ENTRYPOINT ["/bin/echo"]`,
  2080  		true)
  2081  	if err != nil {
  2082  		c.Fatal(err)
  2083  	}
  2084  	entriesFinal, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  2085  	if err != nil {
  2086  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2087  	}
  2088  	if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  2089  		c.Fatalf("context should have been deleted, but wasn't")
  2090  	}
  2091  
  2092  }
  2093  
  2094  func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *check.C) {
  2095  	testRequires(c, SameHostDaemon)
  2096  
  2097  	name := "testbuildcontextcleanup"
  2098  	entries, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  2099  	if err != nil {
  2100  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2101  	}
  2102  	_, err = buildImage(name,
  2103  		`FROM `+minimalBaseImage()+`
  2104  	RUN /non/existing/command`,
  2105  		true)
  2106  	if err == nil {
  2107  		c.Fatalf("expected build to fail, but it didn't")
  2108  	}
  2109  	entriesFinal, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  2110  	if err != nil {
  2111  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2112  	}
  2113  	if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  2114  		c.Fatalf("context should have been deleted, but wasn't")
  2115  	}
  2116  
  2117  }
  2118  
  2119  func (s *DockerSuite) TestBuildCmd(c *check.C) {
  2120  	name := "testbuildcmd"
  2121  
  2122  	expected := "[/bin/echo Hello World]"
  2123  	_, err := buildImage(name,
  2124  		`FROM `+minimalBaseImage()+`
  2125          CMD ["/bin/echo", "Hello World"]`,
  2126  		true)
  2127  	if err != nil {
  2128  		c.Fatal(err)
  2129  	}
  2130  	res := inspectField(c, name, "Config.Cmd")
  2131  	if res != expected {
  2132  		c.Fatalf("Cmd %s, expected %s", res, expected)
  2133  	}
  2134  }
  2135  
  2136  func (s *DockerSuite) TestBuildExpose(c *check.C) {
  2137  	testRequires(c, DaemonIsLinux) // Expose not implemented on Windows
  2138  	name := "testbuildexpose"
  2139  	expected := "map[2375/tcp:{}]"
  2140  	_, err := buildImage(name,
  2141  		`FROM scratch
  2142          EXPOSE 2375`,
  2143  		true)
  2144  	if err != nil {
  2145  		c.Fatal(err)
  2146  	}
  2147  	res := inspectField(c, name, "Config.ExposedPorts")
  2148  	if res != expected {
  2149  		c.Fatalf("Exposed ports %s, expected %s", res, expected)
  2150  	}
  2151  }
  2152  
  2153  func (s *DockerSuite) TestBuildExposeMorePorts(c *check.C) {
  2154  	testRequires(c, DaemonIsLinux) // Expose not implemented on Windows
  2155  	// start building docker file with a large number of ports
  2156  	portList := make([]string, 50)
  2157  	line := make([]string, 100)
  2158  	expectedPorts := make([]int, len(portList)*len(line))
  2159  	for i := 0; i < len(portList); i++ {
  2160  		for j := 0; j < len(line); j++ {
  2161  			p := i*len(line) + j + 1
  2162  			line[j] = strconv.Itoa(p)
  2163  			expectedPorts[p-1] = p
  2164  		}
  2165  		if i == len(portList)-1 {
  2166  			portList[i] = strings.Join(line, " ")
  2167  		} else {
  2168  			portList[i] = strings.Join(line, " ") + ` \`
  2169  		}
  2170  	}
  2171  
  2172  	dockerfile := `FROM scratch
  2173  	EXPOSE {{range .}} {{.}}
  2174  	{{end}}`
  2175  	tmpl := template.Must(template.New("dockerfile").Parse(dockerfile))
  2176  	buf := bytes.NewBuffer(nil)
  2177  	tmpl.Execute(buf, portList)
  2178  
  2179  	name := "testbuildexpose"
  2180  	_, err := buildImage(name, buf.String(), true)
  2181  	if err != nil {
  2182  		c.Fatal(err)
  2183  	}
  2184  
  2185  	// check if all the ports are saved inside Config.ExposedPorts
  2186  	res := inspectFieldJSON(c, name, "Config.ExposedPorts")
  2187  	var exposedPorts map[string]interface{}
  2188  	if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
  2189  		c.Fatal(err)
  2190  	}
  2191  
  2192  	for _, p := range expectedPorts {
  2193  		ep := fmt.Sprintf("%d/tcp", p)
  2194  		if _, ok := exposedPorts[ep]; !ok {
  2195  			c.Errorf("Port(%s) is not exposed", ep)
  2196  		} else {
  2197  			delete(exposedPorts, ep)
  2198  		}
  2199  	}
  2200  	if len(exposedPorts) != 0 {
  2201  		c.Errorf("Unexpected extra exposed ports %v", exposedPorts)
  2202  	}
  2203  }
  2204  
  2205  func (s *DockerSuite) TestBuildExposeOrder(c *check.C) {
  2206  	testRequires(c, DaemonIsLinux) // Expose not implemented on Windows
  2207  	buildID := func(name, exposed string) string {
  2208  		_, err := buildImage(name, fmt.Sprintf(`FROM scratch
  2209  		EXPOSE %s`, exposed), true)
  2210  		if err != nil {
  2211  			c.Fatal(err)
  2212  		}
  2213  		id := inspectField(c, name, "Id")
  2214  		return id
  2215  	}
  2216  
  2217  	id1 := buildID("testbuildexpose1", "80 2375")
  2218  	id2 := buildID("testbuildexpose2", "2375 80")
  2219  	if id1 != id2 {
  2220  		c.Errorf("EXPOSE should invalidate the cache only when ports actually changed")
  2221  	}
  2222  }
  2223  
  2224  func (s *DockerSuite) TestBuildExposeUpperCaseProto(c *check.C) {
  2225  	testRequires(c, DaemonIsLinux) // Expose not implemented on Windows
  2226  	name := "testbuildexposeuppercaseproto"
  2227  	expected := "map[5678/udp:{}]"
  2228  	_, err := buildImage(name,
  2229  		`FROM scratch
  2230          EXPOSE 5678/UDP`,
  2231  		true)
  2232  	if err != nil {
  2233  		c.Fatal(err)
  2234  	}
  2235  	res := inspectField(c, name, "Config.ExposedPorts")
  2236  	if res != expected {
  2237  		c.Fatalf("Exposed ports %s, expected %s", res, expected)
  2238  	}
  2239  }
  2240  
  2241  func (s *DockerSuite) TestBuildEmptyEntrypointInheritance(c *check.C) {
  2242  	name := "testbuildentrypointinheritance"
  2243  	name2 := "testbuildentrypointinheritance2"
  2244  
  2245  	_, err := buildImage(name,
  2246  		`FROM busybox
  2247          ENTRYPOINT ["/bin/echo"]`,
  2248  		true)
  2249  	if err != nil {
  2250  		c.Fatal(err)
  2251  	}
  2252  	res := inspectField(c, name, "Config.Entrypoint")
  2253  
  2254  	expected := "[/bin/echo]"
  2255  	if res != expected {
  2256  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2257  	}
  2258  
  2259  	_, err = buildImage(name2,
  2260  		fmt.Sprintf(`FROM %s
  2261          ENTRYPOINT []`, name),
  2262  		true)
  2263  	if err != nil {
  2264  		c.Fatal(err)
  2265  	}
  2266  	res = inspectField(c, name2, "Config.Entrypoint")
  2267  
  2268  	expected = "[]"
  2269  
  2270  	if res != expected {
  2271  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2272  	}
  2273  
  2274  }
  2275  
  2276  func (s *DockerSuite) TestBuildEmptyEntrypoint(c *check.C) {
  2277  	name := "testbuildentrypoint"
  2278  	expected := "[]"
  2279  
  2280  	_, err := buildImage(name,
  2281  		`FROM busybox
  2282          ENTRYPOINT []`,
  2283  		true)
  2284  	if err != nil {
  2285  		c.Fatal(err)
  2286  	}
  2287  	res := inspectField(c, name, "Config.Entrypoint")
  2288  	if res != expected {
  2289  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2290  	}
  2291  
  2292  }
  2293  
  2294  func (s *DockerSuite) TestBuildEntrypoint(c *check.C) {
  2295  	name := "testbuildentrypoint"
  2296  
  2297  	expected := "[/bin/echo]"
  2298  	_, err := buildImage(name,
  2299  		`FROM `+minimalBaseImage()+`
  2300          ENTRYPOINT ["/bin/echo"]`,
  2301  		true)
  2302  	if err != nil {
  2303  		c.Fatal(err)
  2304  	}
  2305  	res := inspectField(c, name, "Config.Entrypoint")
  2306  	if res != expected {
  2307  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2308  	}
  2309  
  2310  }
  2311  
  2312  // #6445 ensure ONBUILD triggers aren't committed to grandchildren
  2313  func (s *DockerSuite) TestBuildOnBuildLimitedInheritence(c *check.C) {
  2314  	var (
  2315  		out2, out3 string
  2316  	)
  2317  	{
  2318  		name1 := "testonbuildtrigger1"
  2319  		dockerfile1 := `
  2320  		FROM busybox
  2321  		RUN echo "GRANDPARENT"
  2322  		ONBUILD RUN echo "ONBUILD PARENT"
  2323  		`
  2324  		ctx, err := fakeContext(dockerfile1, nil)
  2325  		if err != nil {
  2326  			c.Fatal(err)
  2327  		}
  2328  		defer ctx.Close()
  2329  
  2330  		out1, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", name1, ".")
  2331  		if err != nil {
  2332  			c.Fatalf("build failed to complete: %s, %v", out1, err)
  2333  		}
  2334  	}
  2335  	{
  2336  		name2 := "testonbuildtrigger2"
  2337  		dockerfile2 := `
  2338  		FROM testonbuildtrigger1
  2339  		`
  2340  		ctx, err := fakeContext(dockerfile2, nil)
  2341  		if err != nil {
  2342  			c.Fatal(err)
  2343  		}
  2344  		defer ctx.Close()
  2345  
  2346  		out2, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name2, ".")
  2347  		if err != nil {
  2348  			c.Fatalf("build failed to complete: %s, %v", out2, err)
  2349  		}
  2350  	}
  2351  	{
  2352  		name3 := "testonbuildtrigger3"
  2353  		dockerfile3 := `
  2354  		FROM testonbuildtrigger2
  2355  		`
  2356  		ctx, err := fakeContext(dockerfile3, nil)
  2357  		if err != nil {
  2358  			c.Fatal(err)
  2359  		}
  2360  		defer ctx.Close()
  2361  
  2362  		out3, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name3, ".")
  2363  		if err != nil {
  2364  			c.Fatalf("build failed to complete: %s, %v", out3, err)
  2365  		}
  2366  
  2367  	}
  2368  
  2369  	// ONBUILD should be run in second build.
  2370  	if !strings.Contains(out2, "ONBUILD PARENT") {
  2371  		c.Fatalf("ONBUILD instruction did not run in child of ONBUILD parent")
  2372  	}
  2373  
  2374  	// ONBUILD should *not* be run in third build.
  2375  	if strings.Contains(out3, "ONBUILD PARENT") {
  2376  		c.Fatalf("ONBUILD instruction ran in grandchild of ONBUILD parent")
  2377  	}
  2378  
  2379  }
  2380  
  2381  func (s *DockerSuite) TestBuildWithCache(c *check.C) {
  2382  	testRequires(c, DaemonIsLinux) // Expose not implemented on Windows
  2383  	name := "testbuildwithcache"
  2384  	id1, err := buildImage(name,
  2385  		`FROM scratch
  2386  		MAINTAINER dockerio
  2387  		EXPOSE 5432
  2388          ENTRYPOINT ["/bin/echo"]`,
  2389  		true)
  2390  	if err != nil {
  2391  		c.Fatal(err)
  2392  	}
  2393  	id2, err := buildImage(name,
  2394  		`FROM scratch
  2395  		MAINTAINER dockerio
  2396  		EXPOSE 5432
  2397          ENTRYPOINT ["/bin/echo"]`,
  2398  		true)
  2399  	if err != nil {
  2400  		c.Fatal(err)
  2401  	}
  2402  	if id1 != id2 {
  2403  		c.Fatal("The cache should have been used but hasn't.")
  2404  	}
  2405  }
  2406  
  2407  func (s *DockerSuite) TestBuildWithoutCache(c *check.C) {
  2408  	testRequires(c, DaemonIsLinux) // Expose not implemented on Windows
  2409  	name := "testbuildwithoutcache"
  2410  	name2 := "testbuildwithoutcache2"
  2411  	id1, err := buildImage(name,
  2412  		`FROM scratch
  2413  		MAINTAINER dockerio
  2414  		EXPOSE 5432
  2415          ENTRYPOINT ["/bin/echo"]`,
  2416  		true)
  2417  	if err != nil {
  2418  		c.Fatal(err)
  2419  	}
  2420  
  2421  	id2, err := buildImage(name2,
  2422  		`FROM scratch
  2423  		MAINTAINER dockerio
  2424  		EXPOSE 5432
  2425          ENTRYPOINT ["/bin/echo"]`,
  2426  		false)
  2427  	if err != nil {
  2428  		c.Fatal(err)
  2429  	}
  2430  	if id1 == id2 {
  2431  		c.Fatal("The cache should have been invalided but hasn't.")
  2432  	}
  2433  }
  2434  
  2435  func (s *DockerSuite) TestBuildConditionalCache(c *check.C) {
  2436  	name := "testbuildconditionalcache"
  2437  
  2438  	dockerfile := `
  2439  		FROM busybox
  2440          ADD foo /tmp/`
  2441  	ctx, err := fakeContext(dockerfile, map[string]string{
  2442  		"foo": "hello",
  2443  	})
  2444  	if err != nil {
  2445  		c.Fatal(err)
  2446  	}
  2447  	defer ctx.Close()
  2448  
  2449  	id1, err := buildImageFromContext(name, ctx, true)
  2450  	if err != nil {
  2451  		c.Fatalf("Error building #1: %s", err)
  2452  	}
  2453  
  2454  	if err := ctx.Add("foo", "bye"); err != nil {
  2455  		c.Fatalf("Error modifying foo: %s", err)
  2456  	}
  2457  
  2458  	id2, err := buildImageFromContext(name, ctx, false)
  2459  	if err != nil {
  2460  		c.Fatalf("Error building #2: %s", err)
  2461  	}
  2462  	if id2 == id1 {
  2463  		c.Fatal("Should not have used the cache")
  2464  	}
  2465  
  2466  	id3, err := buildImageFromContext(name, ctx, true)
  2467  	if err != nil {
  2468  		c.Fatalf("Error building #3: %s", err)
  2469  	}
  2470  	if id3 != id2 {
  2471  		c.Fatal("Should have used the cache")
  2472  	}
  2473  }
  2474  
  2475  func (s *DockerSuite) TestBuildAddLocalFileWithCache(c *check.C) {
  2476  	// local files are not owned by the correct user
  2477  	testRequires(c, NotUserNamespace)
  2478  	name := "testbuildaddlocalfilewithcache"
  2479  	name2 := "testbuildaddlocalfilewithcache2"
  2480  	dockerfile := `
  2481  		FROM busybox
  2482          MAINTAINER dockerio
  2483          ADD foo /usr/lib/bla/bar
  2484  		RUN sh -c "[ $(cat /usr/lib/bla/bar) = "hello" ]"`
  2485  	ctx, err := fakeContext(dockerfile, map[string]string{
  2486  		"foo": "hello",
  2487  	})
  2488  	if err != nil {
  2489  		c.Fatal(err)
  2490  	}
  2491  	defer ctx.Close()
  2492  	id1, err := buildImageFromContext(name, ctx, true)
  2493  	if err != nil {
  2494  		c.Fatal(err)
  2495  	}
  2496  	id2, err := buildImageFromContext(name2, ctx, true)
  2497  	if err != nil {
  2498  		c.Fatal(err)
  2499  	}
  2500  	if id1 != id2 {
  2501  		c.Fatal("The cache should have been used but hasn't.")
  2502  	}
  2503  }
  2504  
  2505  func (s *DockerSuite) TestBuildAddMultipleLocalFileWithCache(c *check.C) {
  2506  	name := "testbuildaddmultiplelocalfilewithcache"
  2507  	name2 := "testbuildaddmultiplelocalfilewithcache2"
  2508  	dockerfile := `
  2509  		FROM busybox
  2510          MAINTAINER dockerio
  2511          ADD foo Dockerfile /usr/lib/bla/
  2512  		RUN sh -c "[ $(cat /usr/lib/bla/foo) = "hello" ]"`
  2513  	ctx, err := fakeContext(dockerfile, map[string]string{
  2514  		"foo": "hello",
  2515  	})
  2516  	if err != nil {
  2517  		c.Fatal(err)
  2518  	}
  2519  	defer ctx.Close()
  2520  	id1, err := buildImageFromContext(name, ctx, true)
  2521  	if err != nil {
  2522  		c.Fatal(err)
  2523  	}
  2524  	id2, err := buildImageFromContext(name2, ctx, true)
  2525  	if err != nil {
  2526  		c.Fatal(err)
  2527  	}
  2528  	if id1 != id2 {
  2529  		c.Fatal("The cache should have been used but hasn't.")
  2530  	}
  2531  }
  2532  
  2533  func (s *DockerSuite) TestBuildAddLocalFileWithoutCache(c *check.C) {
  2534  	// local files are not owned by the correct user
  2535  	testRequires(c, NotUserNamespace)
  2536  	name := "testbuildaddlocalfilewithoutcache"
  2537  	name2 := "testbuildaddlocalfilewithoutcache2"
  2538  	dockerfile := `
  2539  		FROM busybox
  2540          MAINTAINER dockerio
  2541          ADD foo /usr/lib/bla/bar
  2542  		RUN sh -c "[ $(cat /usr/lib/bla/bar) = "hello" ]"`
  2543  	ctx, err := fakeContext(dockerfile, map[string]string{
  2544  		"foo": "hello",
  2545  	})
  2546  	if err != nil {
  2547  		c.Fatal(err)
  2548  	}
  2549  	defer ctx.Close()
  2550  	id1, err := buildImageFromContext(name, ctx, true)
  2551  	if err != nil {
  2552  		c.Fatal(err)
  2553  	}
  2554  	id2, err := buildImageFromContext(name2, ctx, false)
  2555  	if err != nil {
  2556  		c.Fatal(err)
  2557  	}
  2558  	if id1 == id2 {
  2559  		c.Fatal("The cache should have been invalided but hasn't.")
  2560  	}
  2561  }
  2562  
  2563  func (s *DockerSuite) TestBuildCopyDirButNotFile(c *check.C) {
  2564  	name := "testbuildcopydirbutnotfile"
  2565  	name2 := "testbuildcopydirbutnotfile2"
  2566  
  2567  	dockerfile := `
  2568          FROM ` + minimalBaseImage() + `
  2569          COPY dir /tmp/`
  2570  	ctx, err := fakeContext(dockerfile, map[string]string{
  2571  		"dir/foo": "hello",
  2572  	})
  2573  	if err != nil {
  2574  		c.Fatal(err)
  2575  	}
  2576  	defer ctx.Close()
  2577  	id1, err := buildImageFromContext(name, ctx, true)
  2578  	if err != nil {
  2579  		c.Fatal(err)
  2580  	}
  2581  	// Check that adding file with similar name doesn't mess with cache
  2582  	if err := ctx.Add("dir_file", "hello2"); err != nil {
  2583  		c.Fatal(err)
  2584  	}
  2585  	id2, err := buildImageFromContext(name2, ctx, true)
  2586  	if err != nil {
  2587  		c.Fatal(err)
  2588  	}
  2589  	if id1 != id2 {
  2590  		c.Fatal("The cache should have been used but wasn't")
  2591  	}
  2592  }
  2593  
  2594  func (s *DockerSuite) TestBuildAddCurrentDirWithCache(c *check.C) {
  2595  	name := "testbuildaddcurrentdirwithcache"
  2596  	name2 := name + "2"
  2597  	name3 := name + "3"
  2598  	name4 := name + "4"
  2599  	dockerfile := `
  2600          FROM ` + minimalBaseImage() + `
  2601          MAINTAINER dockerio
  2602          ADD . /usr/lib/bla`
  2603  	ctx, err := fakeContext(dockerfile, map[string]string{
  2604  		"foo": "hello",
  2605  	})
  2606  	if err != nil {
  2607  		c.Fatal(err)
  2608  	}
  2609  	defer ctx.Close()
  2610  	id1, err := buildImageFromContext(name, ctx, true)
  2611  	if err != nil {
  2612  		c.Fatal(err)
  2613  	}
  2614  	// Check that adding file invalidate cache of "ADD ."
  2615  	if err := ctx.Add("bar", "hello2"); err != nil {
  2616  		c.Fatal(err)
  2617  	}
  2618  	id2, err := buildImageFromContext(name2, ctx, true)
  2619  	if err != nil {
  2620  		c.Fatal(err)
  2621  	}
  2622  	if id1 == id2 {
  2623  		c.Fatal("The cache should have been invalided but hasn't.")
  2624  	}
  2625  	// Check that changing file invalidate cache of "ADD ."
  2626  	if err := ctx.Add("foo", "hello1"); err != nil {
  2627  		c.Fatal(err)
  2628  	}
  2629  	id3, err := buildImageFromContext(name3, ctx, true)
  2630  	if err != nil {
  2631  		c.Fatal(err)
  2632  	}
  2633  	if id2 == id3 {
  2634  		c.Fatal("The cache should have been invalided but hasn't.")
  2635  	}
  2636  	// Check that changing file to same content with different mtime does not
  2637  	// invalidate cache of "ADD ."
  2638  	time.Sleep(1 * time.Second) // wait second because of mtime precision
  2639  	if err := ctx.Add("foo", "hello1"); err != nil {
  2640  		c.Fatal(err)
  2641  	}
  2642  	id4, err := buildImageFromContext(name4, ctx, true)
  2643  	if err != nil {
  2644  		c.Fatal(err)
  2645  	}
  2646  	if id3 != id4 {
  2647  		c.Fatal("The cache should have been used but hasn't.")
  2648  	}
  2649  }
  2650  
  2651  func (s *DockerSuite) TestBuildAddCurrentDirWithoutCache(c *check.C) {
  2652  	name := "testbuildaddcurrentdirwithoutcache"
  2653  	name2 := "testbuildaddcurrentdirwithoutcache2"
  2654  	dockerfile := `
  2655          FROM ` + minimalBaseImage() + `
  2656          MAINTAINER dockerio
  2657          ADD . /usr/lib/bla`
  2658  	ctx, err := fakeContext(dockerfile, map[string]string{
  2659  		"foo": "hello",
  2660  	})
  2661  	if err != nil {
  2662  		c.Fatal(err)
  2663  	}
  2664  	defer ctx.Close()
  2665  	id1, err := buildImageFromContext(name, ctx, true)
  2666  	if err != nil {
  2667  		c.Fatal(err)
  2668  	}
  2669  	id2, err := buildImageFromContext(name2, ctx, false)
  2670  	if err != nil {
  2671  		c.Fatal(err)
  2672  	}
  2673  	if id1 == id2 {
  2674  		c.Fatal("The cache should have been invalided but hasn't.")
  2675  	}
  2676  }
  2677  
  2678  func (s *DockerSuite) TestBuildAddRemoteFileWithCache(c *check.C) {
  2679  	name := "testbuildaddremotefilewithcache"
  2680  	server, err := fakeStorage(map[string]string{
  2681  		"baz": "hello",
  2682  	})
  2683  	if err != nil {
  2684  		c.Fatal(err)
  2685  	}
  2686  	defer server.Close()
  2687  
  2688  	id1, err := buildImage(name,
  2689  		fmt.Sprintf(`FROM `+minimalBaseImage()+`
  2690          MAINTAINER dockerio
  2691          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2692  		true)
  2693  	if err != nil {
  2694  		c.Fatal(err)
  2695  	}
  2696  	id2, err := buildImage(name,
  2697  		fmt.Sprintf(`FROM `+minimalBaseImage()+`
  2698          MAINTAINER dockerio
  2699          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2700  		true)
  2701  	if err != nil {
  2702  		c.Fatal(err)
  2703  	}
  2704  	if id1 != id2 {
  2705  		c.Fatal("The cache should have been used but hasn't.")
  2706  	}
  2707  }
  2708  
  2709  func (s *DockerSuite) TestBuildAddRemoteFileWithoutCache(c *check.C) {
  2710  	name := "testbuildaddremotefilewithoutcache"
  2711  	name2 := "testbuildaddremotefilewithoutcache2"
  2712  	server, err := fakeStorage(map[string]string{
  2713  		"baz": "hello",
  2714  	})
  2715  	if err != nil {
  2716  		c.Fatal(err)
  2717  	}
  2718  	defer server.Close()
  2719  
  2720  	id1, err := buildImage(name,
  2721  		fmt.Sprintf(`FROM `+minimalBaseImage()+`
  2722          MAINTAINER dockerio
  2723          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2724  		true)
  2725  	if err != nil {
  2726  		c.Fatal(err)
  2727  	}
  2728  	id2, err := buildImage(name2,
  2729  		fmt.Sprintf(`FROM `+minimalBaseImage()+`
  2730          MAINTAINER dockerio
  2731          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2732  		false)
  2733  	if err != nil {
  2734  		c.Fatal(err)
  2735  	}
  2736  	if id1 == id2 {
  2737  		c.Fatal("The cache should have been invalided but hasn't.")
  2738  	}
  2739  }
  2740  
  2741  func (s *DockerSuite) TestBuildAddRemoteFileMTime(c *check.C) {
  2742  	name := "testbuildaddremotefilemtime"
  2743  	name2 := name + "2"
  2744  	name3 := name + "3"
  2745  
  2746  	files := map[string]string{"baz": "hello"}
  2747  	server, err := fakeStorage(files)
  2748  	if err != nil {
  2749  		c.Fatal(err)
  2750  	}
  2751  	defer server.Close()
  2752  
  2753  	ctx, err := fakeContext(fmt.Sprintf(`FROM `+minimalBaseImage()+`
  2754          MAINTAINER dockerio
  2755          ADD %s/baz /usr/lib/baz/quux`, server.URL()), nil)
  2756  	if err != nil {
  2757  		c.Fatal(err)
  2758  	}
  2759  	defer ctx.Close()
  2760  
  2761  	id1, err := buildImageFromContext(name, ctx, true)
  2762  	if err != nil {
  2763  		c.Fatal(err)
  2764  	}
  2765  
  2766  	id2, err := buildImageFromContext(name2, ctx, true)
  2767  	if err != nil {
  2768  		c.Fatal(err)
  2769  	}
  2770  	if id1 != id2 {
  2771  		c.Fatal("The cache should have been used but wasn't - #1")
  2772  	}
  2773  
  2774  	// Now create a different server with same contents (causes different mtime)
  2775  	// The cache should still be used
  2776  
  2777  	// allow some time for clock to pass as mtime precision is only 1s
  2778  	time.Sleep(2 * time.Second)
  2779  
  2780  	server2, err := fakeStorage(files)
  2781  	if err != nil {
  2782  		c.Fatal(err)
  2783  	}
  2784  	defer server2.Close()
  2785  
  2786  	ctx2, err := fakeContext(fmt.Sprintf(`FROM `+minimalBaseImage()+`
  2787          MAINTAINER dockerio
  2788          ADD %s/baz /usr/lib/baz/quux`, server2.URL()), nil)
  2789  	if err != nil {
  2790  		c.Fatal(err)
  2791  	}
  2792  	defer ctx2.Close()
  2793  	id3, err := buildImageFromContext(name3, ctx2, true)
  2794  	if err != nil {
  2795  		c.Fatal(err)
  2796  	}
  2797  	if id1 != id3 {
  2798  		c.Fatal("The cache should have been used but wasn't")
  2799  	}
  2800  }
  2801  
  2802  func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithCache(c *check.C) {
  2803  	name := "testbuildaddlocalandremotefilewithcache"
  2804  	server, err := fakeStorage(map[string]string{
  2805  		"baz": "hello",
  2806  	})
  2807  	if err != nil {
  2808  		c.Fatal(err)
  2809  	}
  2810  	defer server.Close()
  2811  
  2812  	ctx, err := fakeContext(fmt.Sprintf(`FROM `+minimalBaseImage()+`
  2813          MAINTAINER dockerio
  2814          ADD foo /usr/lib/bla/bar
  2815          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2816  		map[string]string{
  2817  			"foo": "hello world",
  2818  		})
  2819  	if err != nil {
  2820  		c.Fatal(err)
  2821  	}
  2822  	defer ctx.Close()
  2823  	id1, err := buildImageFromContext(name, ctx, true)
  2824  	if err != nil {
  2825  		c.Fatal(err)
  2826  	}
  2827  	id2, err := buildImageFromContext(name, ctx, true)
  2828  	if err != nil {
  2829  		c.Fatal(err)
  2830  	}
  2831  	if id1 != id2 {
  2832  		c.Fatal("The cache should have been used but hasn't.")
  2833  	}
  2834  }
  2835  
  2836  func testContextTar(c *check.C, compression archive.Compression) {
  2837  	ctx, err := fakeContext(
  2838  		`FROM busybox
  2839  ADD foo /foo
  2840  CMD ["cat", "/foo"]`,
  2841  		map[string]string{
  2842  			"foo": "bar",
  2843  		},
  2844  	)
  2845  	if err != nil {
  2846  		c.Fatal(err)
  2847  	}
  2848  	defer ctx.Close()
  2849  	context, err := archive.Tar(ctx.Dir, compression)
  2850  	if err != nil {
  2851  		c.Fatalf("failed to build context tar: %v", err)
  2852  	}
  2853  	name := "contexttar"
  2854  	buildCmd := exec.Command(dockerBinary, "build", "-t", name, "-")
  2855  	buildCmd.Stdin = context
  2856  
  2857  	if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  2858  		c.Fatalf("build failed to complete: %v %v", out, err)
  2859  	}
  2860  }
  2861  
  2862  func (s *DockerSuite) TestBuildContextTarGzip(c *check.C) {
  2863  	testContextTar(c, archive.Gzip)
  2864  }
  2865  
  2866  func (s *DockerSuite) TestBuildContextTarNoCompression(c *check.C) {
  2867  	testContextTar(c, archive.Uncompressed)
  2868  }
  2869  
  2870  func (s *DockerSuite) TestBuildNoContext(c *check.C) {
  2871  	buildCmd := exec.Command(dockerBinary, "build", "-t", "nocontext", "-")
  2872  	buildCmd.Stdin = strings.NewReader(
  2873  		`FROM busybox
  2874  		CMD ["echo", "ok"]`)
  2875  
  2876  	if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  2877  		c.Fatalf("build failed to complete: %v %v", out, err)
  2878  	}
  2879  
  2880  	if out, _ := dockerCmd(c, "run", "--rm", "nocontext"); out != "ok\n" {
  2881  		c.Fatalf("run produced invalid output: %q, expected %q", out, "ok")
  2882  	}
  2883  }
  2884  
  2885  // TODO: TestCaching
  2886  func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithoutCache(c *check.C) {
  2887  	name := "testbuildaddlocalandremotefilewithoutcache"
  2888  	name2 := "testbuildaddlocalandremotefilewithoutcache2"
  2889  	server, err := fakeStorage(map[string]string{
  2890  		"baz": "hello",
  2891  	})
  2892  	if err != nil {
  2893  		c.Fatal(err)
  2894  	}
  2895  	defer server.Close()
  2896  
  2897  	ctx, err := fakeContext(fmt.Sprintf(`FROM `+minimalBaseImage()+`
  2898          MAINTAINER dockerio
  2899          ADD foo /usr/lib/bla/bar
  2900          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2901  		map[string]string{
  2902  			"foo": "hello world",
  2903  		})
  2904  	if err != nil {
  2905  		c.Fatal(err)
  2906  	}
  2907  	defer ctx.Close()
  2908  	id1, err := buildImageFromContext(name, ctx, true)
  2909  	if err != nil {
  2910  		c.Fatal(err)
  2911  	}
  2912  	id2, err := buildImageFromContext(name2, ctx, false)
  2913  	if err != nil {
  2914  		c.Fatal(err)
  2915  	}
  2916  	if id1 == id2 {
  2917  		c.Fatal("The cache should have been invalidated but hasn't.")
  2918  	}
  2919  }
  2920  
  2921  func (s *DockerSuite) TestBuildWithVolumeOwnership(c *check.C) {
  2922  	testRequires(c, DaemonIsLinux)
  2923  	name := "testbuildimg"
  2924  
  2925  	_, err := buildImage(name,
  2926  		`FROM busybox:latest
  2927          RUN mkdir /test && chown daemon:daemon /test && chmod 0600 /test
  2928          VOLUME /test`,
  2929  		true)
  2930  
  2931  	if err != nil {
  2932  		c.Fatal(err)
  2933  	}
  2934  
  2935  	out, _ := dockerCmd(c, "run", "--rm", "testbuildimg", "ls", "-la", "/test")
  2936  
  2937  	if expected := "drw-------"; !strings.Contains(out, expected) {
  2938  		c.Fatalf("expected %s received %s", expected, out)
  2939  	}
  2940  
  2941  	if expected := "daemon   daemon"; !strings.Contains(out, expected) {
  2942  		c.Fatalf("expected %s received %s", expected, out)
  2943  	}
  2944  
  2945  }
  2946  
  2947  // testing #1405 - config.Cmd does not get cleaned up if
  2948  // utilizing cache
  2949  func (s *DockerSuite) TestBuildEntrypointRunCleanup(c *check.C) {
  2950  	name := "testbuildcmdcleanup"
  2951  	if _, err := buildImage(name,
  2952  		`FROM busybox
  2953          RUN echo "hello"`,
  2954  		true); err != nil {
  2955  		c.Fatal(err)
  2956  	}
  2957  
  2958  	ctx, err := fakeContext(`FROM busybox
  2959          RUN echo "hello"
  2960          ADD foo /foo
  2961          ENTRYPOINT ["/bin/echo"]`,
  2962  		map[string]string{
  2963  			"foo": "hello",
  2964  		})
  2965  	if err != nil {
  2966  		c.Fatal(err)
  2967  	}
  2968  	defer ctx.Close()
  2969  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2970  		c.Fatal(err)
  2971  	}
  2972  	res := inspectField(c, name, "Config.Cmd")
  2973  	// Cmd must be cleaned up
  2974  	if res != "[]" {
  2975  		c.Fatalf("Cmd %s, expected nil", res)
  2976  	}
  2977  }
  2978  
  2979  func (s *DockerSuite) TestBuildAddFileNotFound(c *check.C) {
  2980  	name := "testbuildaddnotfound"
  2981  	expected := "foo: no such file or directory"
  2982  
  2983  	if daemonPlatform == "windows" {
  2984  		expected = "foo: The system cannot find the file specified"
  2985  	}
  2986  
  2987  	ctx, err := fakeContext(`FROM `+minimalBaseImage()+`
  2988          ADD foo /usr/local/bar`,
  2989  		map[string]string{"bar": "hello"})
  2990  	if err != nil {
  2991  		c.Fatal(err)
  2992  	}
  2993  	defer ctx.Close()
  2994  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2995  		if !strings.Contains(err.Error(), expected) {
  2996  			c.Fatalf("Wrong error %v, must be about missing foo file or directory", err)
  2997  		}
  2998  	} else {
  2999  		c.Fatal("Error must not be nil")
  3000  	}
  3001  }
  3002  
  3003  func (s *DockerSuite) TestBuildInheritance(c *check.C) {
  3004  	testRequires(c, DaemonIsLinux)
  3005  	name := "testbuildinheritance"
  3006  
  3007  	_, err := buildImage(name,
  3008  		`FROM scratch
  3009  		EXPOSE 2375`,
  3010  		true)
  3011  	if err != nil {
  3012  		c.Fatal(err)
  3013  	}
  3014  	ports1 := inspectField(c, name, "Config.ExposedPorts")
  3015  
  3016  	_, err = buildImage(name,
  3017  		fmt.Sprintf(`FROM %s
  3018  		ENTRYPOINT ["/bin/echo"]`, name),
  3019  		true)
  3020  	if err != nil {
  3021  		c.Fatal(err)
  3022  	}
  3023  
  3024  	res := inspectField(c, name, "Config.Entrypoint")
  3025  	if expected := "[/bin/echo]"; res != expected {
  3026  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  3027  	}
  3028  	ports2 := inspectField(c, name, "Config.ExposedPorts")
  3029  	if ports1 != ports2 {
  3030  		c.Fatalf("Ports must be same: %s != %s", ports1, ports2)
  3031  	}
  3032  }
  3033  
  3034  func (s *DockerSuite) TestBuildFails(c *check.C) {
  3035  	name := "testbuildfails"
  3036  	_, err := buildImage(name,
  3037  		`FROM busybox
  3038  		RUN sh -c "exit 23"`,
  3039  		true)
  3040  	if err != nil {
  3041  		if !strings.Contains(err.Error(), "returned a non-zero code: 23") {
  3042  			c.Fatalf("Wrong error %v, must be about non-zero code 23", err)
  3043  		}
  3044  	} else {
  3045  		c.Fatal("Error must not be nil")
  3046  	}
  3047  }
  3048  
  3049  func (s *DockerSuite) TestBuildOnBuild(c *check.C) {
  3050  	name := "testbuildonbuild"
  3051  	_, err := buildImage(name,
  3052  		`FROM busybox
  3053  		ONBUILD RUN touch foobar`,
  3054  		true)
  3055  	if err != nil {
  3056  		c.Fatal(err)
  3057  	}
  3058  	_, err = buildImage(name,
  3059  		fmt.Sprintf(`FROM %s
  3060  		RUN [ -f foobar ]`, name),
  3061  		true)
  3062  	if err != nil {
  3063  		c.Fatal(err)
  3064  	}
  3065  }
  3066  
  3067  // gh #2446
  3068  func (s *DockerSuite) TestBuildAddToSymlinkDest(c *check.C) {
  3069  	makeLink := `ln -s /foo /bar`
  3070  	if daemonPlatform == "windows" {
  3071  		makeLink = `mklink /D C:\bar C:\foo`
  3072  	}
  3073  	name := "testbuildaddtosymlinkdest"
  3074  	ctx, err := fakeContext(`FROM busybox
  3075          RUN sh -c "mkdir /foo"
  3076          RUN `+makeLink+`
  3077          ADD foo /bar/
  3078          RUN sh -c "[ -f /bar/foo ]"
  3079          RUN sh -c "[ -f /foo/foo ]"`,
  3080  		map[string]string{
  3081  			"foo": "hello",
  3082  		})
  3083  	if err != nil {
  3084  		c.Fatal(err)
  3085  	}
  3086  	defer ctx.Close()
  3087  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3088  		c.Fatal(err)
  3089  	}
  3090  }
  3091  
  3092  func (s *DockerSuite) TestBuildEscapeWhitespace(c *check.C) {
  3093  	name := "testbuildescapewhitespace"
  3094  
  3095  	_, err := buildImage(name, `
  3096    # ESCAPE=\
  3097    FROM busybox
  3098    MAINTAINER "Docker \
  3099  IO <io@\
  3100  docker.com>"
  3101    `, true)
  3102  	if err != nil {
  3103  		c.Fatal(err)
  3104  	}
  3105  
  3106  	res := inspectField(c, name, "Author")
  3107  
  3108  	if res != "\"Docker IO <io@docker.com>\"" {
  3109  		c.Fatalf("Parsed string did not match the escaped string. Got: %q", res)
  3110  	}
  3111  
  3112  }
  3113  
  3114  func (s *DockerSuite) TestBuildVerifyIntString(c *check.C) {
  3115  	// Verify that strings that look like ints are still passed as strings
  3116  	name := "testbuildstringing"
  3117  
  3118  	_, err := buildImage(name, `
  3119    FROM busybox
  3120    MAINTAINER 123
  3121    `, true)
  3122  
  3123  	if err != nil {
  3124  		c.Fatal(err)
  3125  	}
  3126  
  3127  	out, _ := dockerCmd(c, "inspect", name)
  3128  
  3129  	if !strings.Contains(out, "\"123\"") {
  3130  		c.Fatalf("Output does not contain the int as a string:\n%s", out)
  3131  	}
  3132  
  3133  }
  3134  
  3135  func (s *DockerSuite) TestBuildDockerignore(c *check.C) {
  3136  	name := "testbuilddockerignore"
  3137  	dockerfile := `
  3138          FROM busybox
  3139          ADD . /bla
  3140  		RUN sh -c "[[ -f /bla/src/x.go ]]"
  3141  		RUN sh -c "[[ -f /bla/Makefile ]]"
  3142  		RUN sh -c "[[ ! -e /bla/src/_vendor ]]"
  3143  		RUN sh -c "[[ ! -e /bla/.gitignore ]]"
  3144  		RUN sh -c "[[ ! -e /bla/README.md ]]"
  3145  		RUN sh -c "[[ ! -e /bla/dir/foo ]]"
  3146  		RUN sh -c "[[ ! -e /bla/foo ]]"
  3147  		RUN sh -c "[[ ! -e /bla/.git ]]"
  3148  		RUN sh -c "[[ ! -e v.cc ]]"
  3149  		RUN sh -c "[[ ! -e src/v.cc ]]"
  3150  		RUN sh -c "[[ ! -e src/_vendor/v.cc ]]"`
  3151  	ctx, err := fakeContext(dockerfile, map[string]string{
  3152  		"Makefile":         "all:",
  3153  		".git/HEAD":        "ref: foo",
  3154  		"src/x.go":         "package main",
  3155  		"src/_vendor/v.go": "package main",
  3156  		"src/_vendor/v.cc": "package main",
  3157  		"src/v.cc":         "package main",
  3158  		"v.cc":             "package main",
  3159  		"dir/foo":          "",
  3160  		".gitignore":       "",
  3161  		"README.md":        "readme",
  3162  		".dockerignore": `
  3163  .git
  3164  pkg
  3165  .gitignore
  3166  src/_vendor
  3167  *.md
  3168  **/*.cc
  3169  dir`,
  3170  	})
  3171  	if err != nil {
  3172  		c.Fatal(err)
  3173  	}
  3174  	defer ctx.Close()
  3175  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3176  		c.Fatal(err)
  3177  	}
  3178  }
  3179  
  3180  func (s *DockerSuite) TestBuildDockerignoreCleanPaths(c *check.C) {
  3181  	name := "testbuilddockerignorecleanpaths"
  3182  	dockerfile := `
  3183          FROM busybox
  3184          ADD . /tmp/
  3185          RUN sh -c "(! ls /tmp/foo) && (! ls /tmp/foo2) && (! ls /tmp/dir1/foo)"`
  3186  	ctx, err := fakeContext(dockerfile, map[string]string{
  3187  		"foo":           "foo",
  3188  		"foo2":          "foo2",
  3189  		"dir1/foo":      "foo in dir1",
  3190  		".dockerignore": "./foo\ndir1//foo\n./dir1/../foo2",
  3191  	})
  3192  	if err != nil {
  3193  		c.Fatal(err)
  3194  	}
  3195  	defer ctx.Close()
  3196  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3197  		c.Fatal(err)
  3198  	}
  3199  }
  3200  
  3201  func (s *DockerSuite) TestBuildDockerignoreExceptions(c *check.C) {
  3202  	name := "testbuilddockerignoreexceptions"
  3203  	dockerfile := `
  3204          FROM busybox
  3205          ADD . /bla
  3206  		RUN sh -c "[[ -f /bla/src/x.go ]]"
  3207  		RUN sh -c "[[ -f /bla/Makefile ]]"
  3208  		RUN sh -c "[[ ! -e /bla/src/_vendor ]]"
  3209  		RUN sh -c "[[ ! -e /bla/.gitignore ]]"
  3210  		RUN sh -c "[[ ! -e /bla/README.md ]]"
  3211  		RUN sh -c "[[  -e /bla/dir/dir/foo ]]"
  3212  		RUN sh -c "[[ ! -e /bla/dir/foo1 ]]"
  3213  		RUN sh -c "[[ -f /bla/dir/e ]]"
  3214  		RUN sh -c "[[ -f /bla/dir/e-dir/foo ]]"
  3215  		RUN sh -c "[[ ! -e /bla/foo ]]"
  3216  		RUN sh -c "[[ ! -e /bla/.git ]]"
  3217  		RUN sh -c "[[ -e /bla/dir/a.cc ]]"`
  3218  	ctx, err := fakeContext(dockerfile, map[string]string{
  3219  		"Makefile":         "all:",
  3220  		".git/HEAD":        "ref: foo",
  3221  		"src/x.go":         "package main",
  3222  		"src/_vendor/v.go": "package main",
  3223  		"dir/foo":          "",
  3224  		"dir/foo1":         "",
  3225  		"dir/dir/f1":       "",
  3226  		"dir/dir/foo":      "",
  3227  		"dir/e":            "",
  3228  		"dir/e-dir/foo":    "",
  3229  		".gitignore":       "",
  3230  		"README.md":        "readme",
  3231  		"dir/a.cc":         "hello",
  3232  		".dockerignore": `
  3233  .git
  3234  pkg
  3235  .gitignore
  3236  src/_vendor
  3237  *.md
  3238  dir
  3239  !dir/e*
  3240  !dir/dir/foo
  3241  **/*.cc
  3242  !**/*.cc`,
  3243  	})
  3244  	if err != nil {
  3245  		c.Fatal(err)
  3246  	}
  3247  	defer ctx.Close()
  3248  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3249  		c.Fatal(err)
  3250  	}
  3251  }
  3252  
  3253  func (s *DockerSuite) TestBuildDockerignoringDockerfile(c *check.C) {
  3254  	name := "testbuilddockerignoredockerfile"
  3255  	dockerfile := `
  3256          FROM busybox
  3257  		ADD . /tmp/
  3258  		RUN sh -c "! ls /tmp/Dockerfile"
  3259  		RUN ls /tmp/.dockerignore`
  3260  	ctx, err := fakeContext(dockerfile, map[string]string{
  3261  		"Dockerfile":    dockerfile,
  3262  		".dockerignore": "Dockerfile\n",
  3263  	})
  3264  	if err != nil {
  3265  		c.Fatal(err)
  3266  	}
  3267  	defer ctx.Close()
  3268  
  3269  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3270  		c.Fatalf("Didn't ignore Dockerfile correctly:%s", err)
  3271  	}
  3272  
  3273  	// now try it with ./Dockerfile
  3274  	ctx.Add(".dockerignore", "./Dockerfile\n")
  3275  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3276  		c.Fatalf("Didn't ignore ./Dockerfile correctly:%s", err)
  3277  	}
  3278  
  3279  }
  3280  
  3281  func (s *DockerSuite) TestBuildDockerignoringRenamedDockerfile(c *check.C) {
  3282  	name := "testbuilddockerignoredockerfile"
  3283  	dockerfile := `
  3284          FROM busybox
  3285  		ADD . /tmp/
  3286  		RUN ls /tmp/Dockerfile
  3287  		RUN sh -c "! ls /tmp/MyDockerfile"
  3288  		RUN ls /tmp/.dockerignore`
  3289  	ctx, err := fakeContext(dockerfile, map[string]string{
  3290  		"Dockerfile":    "Should not use me",
  3291  		"MyDockerfile":  dockerfile,
  3292  		".dockerignore": "MyDockerfile\n",
  3293  	})
  3294  	if err != nil {
  3295  		c.Fatal(err)
  3296  	}
  3297  	defer ctx.Close()
  3298  
  3299  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3300  		c.Fatalf("Didn't ignore MyDockerfile correctly:%s", err)
  3301  	}
  3302  
  3303  	// now try it with ./MyDockerfile
  3304  	ctx.Add(".dockerignore", "./MyDockerfile\n")
  3305  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3306  		c.Fatalf("Didn't ignore ./MyDockerfile correctly:%s", err)
  3307  	}
  3308  
  3309  }
  3310  
  3311  func (s *DockerSuite) TestBuildDockerignoringDockerignore(c *check.C) {
  3312  	name := "testbuilddockerignoredockerignore"
  3313  	dockerfile := `
  3314          FROM busybox
  3315  		ADD . /tmp/
  3316  		RUN sh -c "! ls /tmp/.dockerignore"
  3317  		RUN ls /tmp/Dockerfile`
  3318  	ctx, err := fakeContext(dockerfile, map[string]string{
  3319  		"Dockerfile":    dockerfile,
  3320  		".dockerignore": ".dockerignore\n",
  3321  	})
  3322  	if err != nil {
  3323  		c.Fatal(err)
  3324  	}
  3325  	defer ctx.Close()
  3326  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3327  		c.Fatalf("Didn't ignore .dockerignore correctly:%s", err)
  3328  	}
  3329  }
  3330  
  3331  func (s *DockerSuite) TestBuildDockerignoreTouchDockerfile(c *check.C) {
  3332  	var id1 string
  3333  	var id2 string
  3334  
  3335  	name := "testbuilddockerignoretouchdockerfile"
  3336  	dockerfile := `
  3337          FROM busybox
  3338  		ADD . /tmp/`
  3339  	ctx, err := fakeContext(dockerfile, map[string]string{
  3340  		"Dockerfile":    dockerfile,
  3341  		".dockerignore": "Dockerfile\n",
  3342  	})
  3343  	if err != nil {
  3344  		c.Fatal(err)
  3345  	}
  3346  	defer ctx.Close()
  3347  
  3348  	if id1, err = buildImageFromContext(name, ctx, true); err != nil {
  3349  		c.Fatalf("Didn't build it correctly:%s", err)
  3350  	}
  3351  
  3352  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3353  		c.Fatalf("Didn't build it correctly:%s", err)
  3354  	}
  3355  	if id1 != id2 {
  3356  		c.Fatalf("Didn't use the cache - 1")
  3357  	}
  3358  
  3359  	// Now make sure touching Dockerfile doesn't invalidate the cache
  3360  	if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3361  		c.Fatalf("Didn't add Dockerfile: %s", err)
  3362  	}
  3363  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3364  		c.Fatalf("Didn't build it correctly:%s", err)
  3365  	}
  3366  	if id1 != id2 {
  3367  		c.Fatalf("Didn't use the cache - 2")
  3368  	}
  3369  
  3370  	// One more time but just 'touch' it instead of changing the content
  3371  	if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3372  		c.Fatalf("Didn't add Dockerfile: %s", err)
  3373  	}
  3374  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3375  		c.Fatalf("Didn't build it correctly:%s", err)
  3376  	}
  3377  	if id1 != id2 {
  3378  		c.Fatalf("Didn't use the cache - 3")
  3379  	}
  3380  
  3381  }
  3382  
  3383  func (s *DockerSuite) TestBuildDockerignoringWholeDir(c *check.C) {
  3384  	name := "testbuilddockerignorewholedir"
  3385  	dockerfile := `
  3386          FROM busybox
  3387  		COPY . /
  3388  		RUN sh -c "[[ ! -e /.gitignore ]]"
  3389  		RUN sh -c "[[ -f /Makefile ]]"`
  3390  	ctx, err := fakeContext(dockerfile, map[string]string{
  3391  		"Dockerfile":    "FROM scratch",
  3392  		"Makefile":      "all:",
  3393  		".gitignore":    "",
  3394  		".dockerignore": ".*\n",
  3395  	})
  3396  	c.Assert(err, check.IsNil)
  3397  	defer ctx.Close()
  3398  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3399  		c.Fatal(err)
  3400  	}
  3401  
  3402  	c.Assert(ctx.Add(".dockerfile", "*"), check.IsNil)
  3403  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3404  		c.Fatal(err)
  3405  	}
  3406  
  3407  	c.Assert(ctx.Add(".dockerfile", "."), check.IsNil)
  3408  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3409  		c.Fatal(err)
  3410  	}
  3411  
  3412  	c.Assert(ctx.Add(".dockerfile", "?"), check.IsNil)
  3413  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3414  		c.Fatal(err)
  3415  	}
  3416  }
  3417  
  3418  func (s *DockerSuite) TestBuildDockerignoringBadExclusion(c *check.C) {
  3419  	name := "testbuilddockerignorebadexclusion"
  3420  	dockerfile := `
  3421          FROM busybox
  3422  		COPY . /
  3423  		RUN sh -c "[[ ! -e /.gitignore ]]"
  3424  		RUN sh -c "[[ -f /Makefile ]]"`
  3425  	ctx, err := fakeContext(dockerfile, map[string]string{
  3426  		"Dockerfile":    "FROM scratch",
  3427  		"Makefile":      "all:",
  3428  		".gitignore":    "",
  3429  		".dockerignore": "!\n",
  3430  	})
  3431  	c.Assert(err, check.IsNil)
  3432  	defer ctx.Close()
  3433  	if _, err = buildImageFromContext(name, ctx, true); err == nil {
  3434  		c.Fatalf("Build was supposed to fail but didn't")
  3435  	}
  3436  
  3437  	if err.Error() != "failed to build the image: Error checking context: 'Illegal exclusion pattern: !'.\n" {
  3438  		c.Fatalf("Incorrect output, got:%q", err.Error())
  3439  	}
  3440  }
  3441  
  3442  func (s *DockerSuite) TestBuildDockerignoringWildTopDir(c *check.C) {
  3443  	dockerfile := `
  3444          FROM busybox
  3445  		COPY . /
  3446  		RUN sh -c "[[ ! -e /.dockerignore ]]"
  3447  		RUN sh -c "[[ ! -e /Dockerfile ]]"
  3448  		RUN sh -c "[[ ! -e /file1 ]]"
  3449  		RUN sh -c "[[ ! -e /dir ]]"`
  3450  
  3451  	ctx, err := fakeContext(dockerfile, map[string]string{
  3452  		"Dockerfile": "FROM scratch",
  3453  		"file1":      "",
  3454  		"dir/dfile1": "",
  3455  	})
  3456  	c.Assert(err, check.IsNil)
  3457  	defer ctx.Close()
  3458  
  3459  	// All of these should result in ignoring all files
  3460  	for _, variant := range []string{"**", "**/", "**/**", "*"} {
  3461  		ctx.Add(".dockerignore", variant)
  3462  		_, err = buildImageFromContext("noname", ctx, true)
  3463  		c.Assert(err, check.IsNil, check.Commentf("variant: %s", variant))
  3464  	}
  3465  }
  3466  
  3467  func (s *DockerSuite) TestBuildDockerignoringWildDirs(c *check.C) {
  3468  	dockerfile := `
  3469          FROM busybox
  3470  		COPY . /
  3471  		#RUN sh -c "[[ -e /.dockerignore ]]"
  3472  		RUN sh -c "[[ -e /Dockerfile ]]           && \
  3473  		           [[ ! -e /file0 ]]              && \
  3474  		           [[ ! -e /dir1/file0 ]]         && \
  3475  		           [[ ! -e /dir2/file0 ]]         && \
  3476  		           [[ ! -e /file1 ]]              && \
  3477  		           [[ ! -e /dir1/file1 ]]         && \
  3478  		           [[ ! -e /dir1/dir2/file1 ]]    && \
  3479  		           [[ ! -e /dir1/file2 ]]         && \
  3480  		           [[   -e /dir1/dir2/file2 ]]    && \
  3481  		           [[ ! -e /dir1/dir2/file4 ]]    && \
  3482  		           [[ ! -e /dir1/dir2/file5 ]]    && \
  3483  		           [[ ! -e /dir1/dir2/file6 ]]    && \
  3484  		           [[ ! -e /dir1/dir3/file7 ]]    && \
  3485  		           [[ ! -e /dir1/dir3/file8 ]]    && \
  3486  		           [[   -e /dir1/dir3 ]]          && \
  3487  		           [[   -e /dir1/dir4 ]]          && \
  3488  		           [[ ! -e 'dir1/dir5/fileAA' ]]  && \
  3489  		           [[   -e 'dir1/dir5/fileAB' ]]  && \
  3490  		           [[   -e 'dir1/dir5/fileB' ]]"   # "." in pattern means nothing
  3491  
  3492  		RUN echo all done!`
  3493  
  3494  	ctx, err := fakeContext(dockerfile, map[string]string{
  3495  		"Dockerfile":      "FROM scratch",
  3496  		"file0":           "",
  3497  		"dir1/file0":      "",
  3498  		"dir1/dir2/file0": "",
  3499  
  3500  		"file1":           "",
  3501  		"dir1/file1":      "",
  3502  		"dir1/dir2/file1": "",
  3503  
  3504  		"dir1/file2":      "",
  3505  		"dir1/dir2/file2": "", // remains
  3506  
  3507  		"dir1/dir2/file4": "",
  3508  		"dir1/dir2/file5": "",
  3509  		"dir1/dir2/file6": "",
  3510  		"dir1/dir3/file7": "",
  3511  		"dir1/dir3/file8": "",
  3512  		"dir1/dir4/file9": "",
  3513  
  3514  		"dir1/dir5/fileAA": "",
  3515  		"dir1/dir5/fileAB": "",
  3516  		"dir1/dir5/fileB":  "",
  3517  
  3518  		".dockerignore": `
  3519  **/file0
  3520  **/*file1
  3521  **/dir1/file2
  3522  dir1/**/file4
  3523  **/dir2/file5
  3524  **/dir1/dir2/file6
  3525  dir1/dir3/**
  3526  **/dir4/**
  3527  **/file?A
  3528  **/file\?B
  3529  **/dir5/file.
  3530  `,
  3531  	})
  3532  	c.Assert(err, check.IsNil)
  3533  	defer ctx.Close()
  3534  
  3535  	_, err = buildImageFromContext("noname", ctx, true)
  3536  	c.Assert(err, check.IsNil)
  3537  }
  3538  
  3539  func (s *DockerSuite) TestBuildLineBreak(c *check.C) {
  3540  	testRequires(c, DaemonIsLinux)
  3541  	name := "testbuildlinebreak"
  3542  	_, err := buildImage(name,
  3543  		`FROM  busybox
  3544  RUN    sh -c 'echo root:testpass \
  3545  	> /tmp/passwd'
  3546  RUN    mkdir -p /var/run/sshd
  3547  RUN    sh -c "[ "$(cat /tmp/passwd)" = "root:testpass" ]"
  3548  RUN    sh -c "[ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]"`,
  3549  		true)
  3550  	if err != nil {
  3551  		c.Fatal(err)
  3552  	}
  3553  }
  3554  
  3555  func (s *DockerSuite) TestBuildEOLInLine(c *check.C) {
  3556  	testRequires(c, DaemonIsLinux)
  3557  	name := "testbuildeolinline"
  3558  	_, err := buildImage(name,
  3559  		`FROM   busybox
  3560  RUN    sh -c 'echo root:testpass > /tmp/passwd'
  3561  RUN    echo "foo \n bar"; echo "baz"
  3562  RUN    mkdir -p /var/run/sshd
  3563  RUN    sh -c "[ "$(cat /tmp/passwd)" = "root:testpass" ]"
  3564  RUN    sh -c "[ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]"`,
  3565  		true)
  3566  	if err != nil {
  3567  		c.Fatal(err)
  3568  	}
  3569  }
  3570  
  3571  func (s *DockerSuite) TestBuildCommentsShebangs(c *check.C) {
  3572  	testRequires(c, DaemonIsLinux)
  3573  	name := "testbuildcomments"
  3574  	_, err := buildImage(name,
  3575  		`FROM busybox
  3576  # This is an ordinary comment.
  3577  RUN { echo '#!/bin/sh'; echo 'echo hello world'; } > /hello.sh
  3578  RUN [ ! -x /hello.sh ]
  3579  # comment with line break \
  3580  RUN chmod +x /hello.sh
  3581  RUN [ -x /hello.sh ]
  3582  RUN [ "$(cat /hello.sh)" = $'#!/bin/sh\necho hello world' ]
  3583  RUN [ "$(/hello.sh)" = "hello world" ]`,
  3584  		true)
  3585  	if err != nil {
  3586  		c.Fatal(err)
  3587  	}
  3588  }
  3589  
  3590  func (s *DockerSuite) TestBuildUsersAndGroups(c *check.C) {
  3591  	testRequires(c, DaemonIsLinux)
  3592  	name := "testbuildusers"
  3593  	_, err := buildImage(name,
  3594  		`FROM busybox
  3595  
  3596  # Make sure our defaults work
  3597  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)" = '0:0/root:root' ]
  3598  
  3599  # 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)
  3600  USER root
  3601  RUN [ "$(id -G):$(id -Gn)" = '0 10:root wheel' ]
  3602  
  3603  # Setup dockerio user and group
  3604  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd && \
  3605  	echo 'dockerio:x:1001:' >> /etc/group
  3606  
  3607  # Make sure we can switch to our user and all the information is exactly as we expect it to be
  3608  USER dockerio
  3609  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3610  
  3611  # Switch back to root and double check that worked exactly as we might expect it to
  3612  USER root
  3613  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '0:0/root:root/0 10:root wheel' ] && \
  3614          # Add a "supplementary" group for our dockerio user
  3615  	echo 'supplementary:x:1002:dockerio' >> /etc/group
  3616  
  3617  # ... and then go verify that we get it like we expect
  3618  USER dockerio
  3619  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3620  USER 1001
  3621  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3622  
  3623  # super test the new "user:group" syntax
  3624  USER dockerio:dockerio
  3625  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3626  USER 1001:dockerio
  3627  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3628  USER dockerio:1001
  3629  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3630  USER 1001:1001
  3631  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3632  USER dockerio:supplementary
  3633  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3634  USER dockerio:1002
  3635  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3636  USER 1001:supplementary
  3637  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3638  USER 1001:1002
  3639  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3640  
  3641  # make sure unknown uid/gid still works properly
  3642  USER 1042:1043
  3643  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1042:1043/1042:1043/1043:1043' ]`,
  3644  		true)
  3645  	if err != nil {
  3646  		c.Fatal(err)
  3647  	}
  3648  }
  3649  
  3650  func (s *DockerSuite) TestBuildEnvUsage(c *check.C) {
  3651  	// /docker/world/hello is not owned by the correct user
  3652  	testRequires(c, NotUserNamespace)
  3653  	testRequires(c, DaemonIsLinux)
  3654  	name := "testbuildenvusage"
  3655  	dockerfile := `FROM busybox
  3656  ENV    HOME /root
  3657  ENV    PATH $HOME/bin:$PATH
  3658  ENV    PATH /tmp:$PATH
  3659  RUN    [ "$PATH" = "/tmp:$HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ]
  3660  ENV    FOO /foo/baz
  3661  ENV    BAR /bar
  3662  ENV    BAZ $BAR
  3663  ENV    FOOPATH $PATH:$FOO
  3664  RUN    [ "$BAR" = "$BAZ" ]
  3665  RUN    [ "$FOOPATH" = "$PATH:/foo/baz" ]
  3666  ENV	   FROM hello/docker/world
  3667  ENV    TO /docker/world/hello
  3668  ADD    $FROM $TO
  3669  RUN    [ "$(cat $TO)" = "hello" ]
  3670  ENV    abc=def
  3671  ENV    ghi=$abc
  3672  RUN    [ "$ghi" = "def" ]
  3673  `
  3674  	ctx, err := fakeContext(dockerfile, map[string]string{
  3675  		"hello/docker/world": "hello",
  3676  	})
  3677  	if err != nil {
  3678  		c.Fatal(err)
  3679  	}
  3680  	defer ctx.Close()
  3681  
  3682  	_, err = buildImageFromContext(name, ctx, true)
  3683  	if err != nil {
  3684  		c.Fatal(err)
  3685  	}
  3686  }
  3687  
  3688  func (s *DockerSuite) TestBuildEnvUsage2(c *check.C) {
  3689  	// /docker/world/hello is not owned by the correct user
  3690  	testRequires(c, NotUserNamespace)
  3691  	testRequires(c, DaemonIsLinux)
  3692  	name := "testbuildenvusage2"
  3693  	dockerfile := `FROM busybox
  3694  ENV    abc=def def="hello world"
  3695  RUN    [ "$abc,$def" = "def,hello world" ]
  3696  ENV    def=hello\ world v1=abc v2="hi there" v3='boogie nights' v4="with'quotes too"
  3697  RUN    [ "$def,$v1,$v2,$v3,$v4" = "hello world,abc,hi there,boogie nights,with'quotes too" ]
  3698  ENV    abc=zzz FROM=hello/docker/world
  3699  ENV    abc=zzz TO=/docker/world/hello
  3700  ADD    $FROM $TO
  3701  RUN    [ "$abc,$(cat $TO)" = "zzz,hello" ]
  3702  ENV    abc 'yyy'
  3703  RUN    [ $abc = 'yyy' ]
  3704  ENV    abc=
  3705  RUN    [ "$abc" = "" ]
  3706  
  3707  # use grep to make sure if the builder substitutes \$foo by mistake
  3708  # we don't get a false positive
  3709  ENV    abc=\$foo
  3710  RUN    [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  3711  ENV    abc \$foo
  3712  RUN    [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  3713  
  3714  ENV    abc=\'foo\' abc2=\"foo\"
  3715  RUN    [ "$abc,$abc2" = "'foo',\"foo\"" ]
  3716  ENV    abc "foo"
  3717  RUN    [ "$abc" = "foo" ]
  3718  ENV    abc 'foo'
  3719  RUN    [ "$abc" = 'foo' ]
  3720  ENV    abc \'foo\'
  3721  RUN    [ "$abc" = "'foo'" ]
  3722  ENV    abc \"foo\"
  3723  RUN    [ "$abc" = '"foo"' ]
  3724  
  3725  ENV    abc=ABC
  3726  RUN    [ "$abc" = "ABC" ]
  3727  ENV    def1=${abc:-DEF} def2=${ccc:-DEF}
  3728  ENV    def3=${ccc:-${def2}xx} def4=${abc:+ALT} def5=${def2:+${abc}:} def6=${ccc:-\$abc:} def7=${ccc:-\${abc}:}
  3729  RUN    [ "$def1,$def2,$def3,$def4,$def5,$def6,$def7" = 'ABC,DEF,DEFxx,ALT,ABC:,$abc:,${abc:}' ]
  3730  ENV    mypath=${mypath:+$mypath:}/home
  3731  ENV    mypath=${mypath:+$mypath:}/away
  3732  RUN    [ "$mypath" = '/home:/away' ]
  3733  
  3734  ENV    e1=bar
  3735  ENV    e2=$e1 e3=$e11 e4=\$e1 e5=\$e11
  3736  RUN    [ "$e0,$e1,$e2,$e3,$e4,$e5" = ',bar,bar,,$e1,$e11' ]
  3737  
  3738  ENV    ee1 bar
  3739  ENV    ee2 $ee1
  3740  ENV    ee3 $ee11
  3741  ENV    ee4 \$ee1
  3742  ENV    ee5 \$ee11
  3743  RUN    [ "$ee1,$ee2,$ee3,$ee4,$ee5" = 'bar,bar,,$ee1,$ee11' ]
  3744  
  3745  ENV    eee1="foo" eee2='foo'
  3746  ENV    eee3 "foo"
  3747  ENV    eee4 'foo'
  3748  RUN    [ "$eee1,$eee2,$eee3,$eee4" = 'foo,foo,foo,foo' ]
  3749  
  3750  `
  3751  	ctx, err := fakeContext(dockerfile, map[string]string{
  3752  		"hello/docker/world": "hello",
  3753  	})
  3754  	if err != nil {
  3755  		c.Fatal(err)
  3756  	}
  3757  	defer ctx.Close()
  3758  
  3759  	_, err = buildImageFromContext(name, ctx, true)
  3760  	if err != nil {
  3761  		c.Fatal(err)
  3762  	}
  3763  }
  3764  
  3765  func (s *DockerSuite) TestBuildAddScript(c *check.C) {
  3766  	testRequires(c, DaemonIsLinux)
  3767  	name := "testbuildaddscript"
  3768  	dockerfile := `
  3769  FROM busybox
  3770  ADD test /test
  3771  RUN ["chmod","+x","/test"]
  3772  RUN ["/test"]
  3773  RUN [ "$(cat /testfile)" = 'test!' ]`
  3774  	ctx, err := fakeContext(dockerfile, map[string]string{
  3775  		"test": "#!/bin/sh\necho 'test!' > /testfile",
  3776  	})
  3777  	if err != nil {
  3778  		c.Fatal(err)
  3779  	}
  3780  	defer ctx.Close()
  3781  
  3782  	_, err = buildImageFromContext(name, ctx, true)
  3783  	if err != nil {
  3784  		c.Fatal(err)
  3785  	}
  3786  }
  3787  
  3788  func (s *DockerSuite) TestBuildAddTar(c *check.C) {
  3789  	// /test/foo is not owned by the correct user
  3790  	testRequires(c, NotUserNamespace)
  3791  	name := "testbuildaddtar"
  3792  
  3793  	ctx := func() *FakeContext {
  3794  		dockerfile := `
  3795  FROM busybox
  3796  ADD test.tar /
  3797  RUN cat /test/foo | grep Hi
  3798  ADD test.tar /test.tar
  3799  RUN cat /test.tar/test/foo | grep Hi
  3800  ADD test.tar /unlikely-to-exist
  3801  RUN cat /unlikely-to-exist/test/foo | grep Hi
  3802  ADD test.tar /unlikely-to-exist-trailing-slash/
  3803  RUN cat /unlikely-to-exist-trailing-slash/test/foo | grep Hi
  3804  RUN sh -c "mkdir /existing-directory" #sh -c is needed on Windows to use the correct mkdir
  3805  ADD test.tar /existing-directory
  3806  RUN cat /existing-directory/test/foo | grep Hi
  3807  ADD test.tar /existing-directory-trailing-slash/
  3808  RUN cat /existing-directory-trailing-slash/test/foo | grep Hi`
  3809  		tmpDir, err := ioutil.TempDir("", "fake-context")
  3810  		c.Assert(err, check.IsNil)
  3811  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3812  		if err != nil {
  3813  			c.Fatalf("failed to create test.tar archive: %v", err)
  3814  		}
  3815  		defer testTar.Close()
  3816  
  3817  		tw := tar.NewWriter(testTar)
  3818  
  3819  		if err := tw.WriteHeader(&tar.Header{
  3820  			Name: "test/foo",
  3821  			Size: 2,
  3822  		}); err != nil {
  3823  			c.Fatalf("failed to write tar file header: %v", err)
  3824  		}
  3825  		if _, err := tw.Write([]byte("Hi")); err != nil {
  3826  			c.Fatalf("failed to write tar file content: %v", err)
  3827  		}
  3828  		if err := tw.Close(); err != nil {
  3829  			c.Fatalf("failed to close tar archive: %v", err)
  3830  		}
  3831  
  3832  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3833  			c.Fatalf("failed to open destination dockerfile: %v", err)
  3834  		}
  3835  		return fakeContextFromDir(tmpDir)
  3836  	}()
  3837  	defer ctx.Close()
  3838  
  3839  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3840  		c.Fatalf("build failed to complete for TestBuildAddTar: %v", err)
  3841  	}
  3842  
  3843  }
  3844  
  3845  func (s *DockerSuite) TestBuildAddBrokenTar(c *check.C) {
  3846  	name := "testbuildaddbrokentar"
  3847  
  3848  	ctx := func() *FakeContext {
  3849  		dockerfile := `
  3850  FROM busybox
  3851  ADD test.tar /`
  3852  		tmpDir, err := ioutil.TempDir("", "fake-context")
  3853  		c.Assert(err, check.IsNil)
  3854  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3855  		if err != nil {
  3856  			c.Fatalf("failed to create test.tar archive: %v", err)
  3857  		}
  3858  		defer testTar.Close()
  3859  
  3860  		tw := tar.NewWriter(testTar)
  3861  
  3862  		if err := tw.WriteHeader(&tar.Header{
  3863  			Name: "test/foo",
  3864  			Size: 2,
  3865  		}); err != nil {
  3866  			c.Fatalf("failed to write tar file header: %v", err)
  3867  		}
  3868  		if _, err := tw.Write([]byte("Hi")); err != nil {
  3869  			c.Fatalf("failed to write tar file content: %v", err)
  3870  		}
  3871  		if err := tw.Close(); err != nil {
  3872  			c.Fatalf("failed to close tar archive: %v", err)
  3873  		}
  3874  
  3875  		// Corrupt the tar by removing one byte off the end
  3876  		stat, err := testTar.Stat()
  3877  		if err != nil {
  3878  			c.Fatalf("failed to stat tar archive: %v", err)
  3879  		}
  3880  		if err := testTar.Truncate(stat.Size() - 1); err != nil {
  3881  			c.Fatalf("failed to truncate tar archive: %v", err)
  3882  		}
  3883  
  3884  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3885  			c.Fatalf("failed to open destination dockerfile: %v", err)
  3886  		}
  3887  		return fakeContextFromDir(tmpDir)
  3888  	}()
  3889  	defer ctx.Close()
  3890  
  3891  	if _, err := buildImageFromContext(name, ctx, true); err == nil {
  3892  		c.Fatalf("build should have failed for TestBuildAddBrokenTar")
  3893  	}
  3894  }
  3895  
  3896  func (s *DockerSuite) TestBuildAddNonTar(c *check.C) {
  3897  	name := "testbuildaddnontar"
  3898  
  3899  	// Should not try to extract test.tar
  3900  	ctx, err := fakeContext(`
  3901  		FROM busybox
  3902  		ADD test.tar /
  3903  		RUN test -f /test.tar`,
  3904  		map[string]string{"test.tar": "not_a_tar_file"})
  3905  
  3906  	if err != nil {
  3907  		c.Fatal(err)
  3908  	}
  3909  	defer ctx.Close()
  3910  
  3911  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3912  		c.Fatalf("build failed for TestBuildAddNonTar")
  3913  	}
  3914  }
  3915  
  3916  func (s *DockerSuite) TestBuildAddTarXz(c *check.C) {
  3917  	// /test/foo is not owned by the correct user
  3918  	testRequires(c, NotUserNamespace)
  3919  	testRequires(c, DaemonIsLinux)
  3920  	name := "testbuildaddtarxz"
  3921  
  3922  	ctx := func() *FakeContext {
  3923  		dockerfile := `
  3924  			FROM busybox
  3925  			ADD test.tar.xz /
  3926  			RUN cat /test/foo | grep Hi`
  3927  		tmpDir, err := ioutil.TempDir("", "fake-context")
  3928  		c.Assert(err, check.IsNil)
  3929  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3930  		if err != nil {
  3931  			c.Fatalf("failed to create test.tar archive: %v", err)
  3932  		}
  3933  		defer testTar.Close()
  3934  
  3935  		tw := tar.NewWriter(testTar)
  3936  
  3937  		if err := tw.WriteHeader(&tar.Header{
  3938  			Name: "test/foo",
  3939  			Size: 2,
  3940  		}); err != nil {
  3941  			c.Fatalf("failed to write tar file header: %v", err)
  3942  		}
  3943  		if _, err := tw.Write([]byte("Hi")); err != nil {
  3944  			c.Fatalf("failed to write tar file content: %v", err)
  3945  		}
  3946  		if err := tw.Close(); err != nil {
  3947  			c.Fatalf("failed to close tar archive: %v", err)
  3948  		}
  3949  
  3950  		xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  3951  		xzCompressCmd.Dir = tmpDir
  3952  		out, _, err := runCommandWithOutput(xzCompressCmd)
  3953  		if err != nil {
  3954  			c.Fatal(err, out)
  3955  		}
  3956  
  3957  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3958  			c.Fatalf("failed to open destination dockerfile: %v", err)
  3959  		}
  3960  		return fakeContextFromDir(tmpDir)
  3961  	}()
  3962  
  3963  	defer ctx.Close()
  3964  
  3965  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3966  		c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  3967  	}
  3968  
  3969  }
  3970  
  3971  func (s *DockerSuite) TestBuildAddTarXzGz(c *check.C) {
  3972  	testRequires(c, DaemonIsLinux)
  3973  	name := "testbuildaddtarxzgz"
  3974  
  3975  	ctx := func() *FakeContext {
  3976  		dockerfile := `
  3977  			FROM busybox
  3978  			ADD test.tar.xz.gz /
  3979  			RUN ls /test.tar.xz.gz`
  3980  		tmpDir, err := ioutil.TempDir("", "fake-context")
  3981  		c.Assert(err, check.IsNil)
  3982  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3983  		if err != nil {
  3984  			c.Fatalf("failed to create test.tar archive: %v", err)
  3985  		}
  3986  		defer testTar.Close()
  3987  
  3988  		tw := tar.NewWriter(testTar)
  3989  
  3990  		if err := tw.WriteHeader(&tar.Header{
  3991  			Name: "test/foo",
  3992  			Size: 2,
  3993  		}); err != nil {
  3994  			c.Fatalf("failed to write tar file header: %v", err)
  3995  		}
  3996  		if _, err := tw.Write([]byte("Hi")); err != nil {
  3997  			c.Fatalf("failed to write tar file content: %v", err)
  3998  		}
  3999  		if err := tw.Close(); err != nil {
  4000  			c.Fatalf("failed to close tar archive: %v", err)
  4001  		}
  4002  
  4003  		xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  4004  		xzCompressCmd.Dir = tmpDir
  4005  		out, _, err := runCommandWithOutput(xzCompressCmd)
  4006  		if err != nil {
  4007  			c.Fatal(err, out)
  4008  		}
  4009  
  4010  		gzipCompressCmd := exec.Command("gzip", "test.tar.xz")
  4011  		gzipCompressCmd.Dir = tmpDir
  4012  		out, _, err = runCommandWithOutput(gzipCompressCmd)
  4013  		if err != nil {
  4014  			c.Fatal(err, out)
  4015  		}
  4016  
  4017  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  4018  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4019  		}
  4020  		return fakeContextFromDir(tmpDir)
  4021  	}()
  4022  
  4023  	defer ctx.Close()
  4024  
  4025  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4026  		c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  4027  	}
  4028  
  4029  }
  4030  
  4031  func (s *DockerSuite) TestBuildFromGit(c *check.C) {
  4032  	name := "testbuildfromgit"
  4033  	git, err := newFakeGit("repo", map[string]string{
  4034  		"Dockerfile": `FROM busybox
  4035  					ADD first /first
  4036  					RUN [ -f /first ]
  4037  					MAINTAINER docker`,
  4038  		"first": "test git data",
  4039  	}, true)
  4040  	if err != nil {
  4041  		c.Fatal(err)
  4042  	}
  4043  	defer git.Close()
  4044  
  4045  	_, err = buildImageFromPath(name, git.RepoURL, true)
  4046  	if err != nil {
  4047  		c.Fatal(err)
  4048  	}
  4049  	res := inspectField(c, name, "Author")
  4050  	if res != "docker" {
  4051  		c.Fatalf("Maintainer should be docker, got %s", res)
  4052  	}
  4053  }
  4054  
  4055  func (s *DockerSuite) TestBuildFromGitWithContext(c *check.C) {
  4056  	name := "testbuildfromgit"
  4057  	git, err := newFakeGit("repo", map[string]string{
  4058  		"docker/Dockerfile": `FROM busybox
  4059  					ADD first /first
  4060  					RUN [ -f /first ]
  4061  					MAINTAINER docker`,
  4062  		"docker/first": "test git data",
  4063  	}, true)
  4064  	if err != nil {
  4065  		c.Fatal(err)
  4066  	}
  4067  	defer git.Close()
  4068  
  4069  	u := fmt.Sprintf("%s#master:docker", git.RepoURL)
  4070  	_, err = buildImageFromPath(name, u, true)
  4071  	if err != nil {
  4072  		c.Fatal(err)
  4073  	}
  4074  	res := inspectField(c, name, "Author")
  4075  	if res != "docker" {
  4076  		c.Fatalf("Maintainer should be docker, got %s", res)
  4077  	}
  4078  }
  4079  
  4080  func (s *DockerSuite) TestBuildFromGitwithF(c *check.C) {
  4081  	name := "testbuildfromgitwithf"
  4082  	git, err := newFakeGit("repo", map[string]string{
  4083  		"myApp/myDockerfile": `FROM busybox
  4084  					RUN echo hi from Dockerfile`,
  4085  	}, true)
  4086  	if err != nil {
  4087  		c.Fatal(err)
  4088  	}
  4089  	defer git.Close()
  4090  
  4091  	out, _, err := dockerCmdWithError("build", "-t", name, "--no-cache", "-f", "myApp/myDockerfile", git.RepoURL)
  4092  	if err != nil {
  4093  		c.Fatalf("Error on build. Out: %s\nErr: %v", out, err)
  4094  	}
  4095  
  4096  	if !strings.Contains(out, "hi from Dockerfile") {
  4097  		c.Fatalf("Missing expected output, got:\n%s", out)
  4098  	}
  4099  }
  4100  
  4101  func (s *DockerSuite) TestBuildFromRemoteTarball(c *check.C) {
  4102  	name := "testbuildfromremotetarball"
  4103  
  4104  	buffer := new(bytes.Buffer)
  4105  	tw := tar.NewWriter(buffer)
  4106  	defer tw.Close()
  4107  
  4108  	dockerfile := []byte(`FROM busybox
  4109  					MAINTAINER docker`)
  4110  	if err := tw.WriteHeader(&tar.Header{
  4111  		Name: "Dockerfile",
  4112  		Size: int64(len(dockerfile)),
  4113  	}); err != nil {
  4114  		c.Fatalf("failed to write tar file header: %v", err)
  4115  	}
  4116  	if _, err := tw.Write(dockerfile); err != nil {
  4117  		c.Fatalf("failed to write tar file content: %v", err)
  4118  	}
  4119  	if err := tw.Close(); err != nil {
  4120  		c.Fatalf("failed to close tar archive: %v", err)
  4121  	}
  4122  
  4123  	server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
  4124  		"testT.tar": buffer,
  4125  	})
  4126  	c.Assert(err, check.IsNil)
  4127  
  4128  	defer server.Close()
  4129  
  4130  	_, err = buildImageFromPath(name, server.URL()+"/testT.tar", true)
  4131  	c.Assert(err, check.IsNil)
  4132  
  4133  	res := inspectField(c, name, "Author")
  4134  
  4135  	if res != "docker" {
  4136  		c.Fatalf("Maintainer should be docker, got %s", res)
  4137  	}
  4138  }
  4139  
  4140  func (s *DockerSuite) TestBuildCleanupCmdOnEntrypoint(c *check.C) {
  4141  	name := "testbuildcmdcleanuponentrypoint"
  4142  	if _, err := buildImage(name,
  4143  		`FROM `+minimalBaseImage()+`
  4144          CMD ["test"]
  4145  		ENTRYPOINT ["echo"]`,
  4146  		true); err != nil {
  4147  		c.Fatal(err)
  4148  	}
  4149  	if _, err := buildImage(name,
  4150  		fmt.Sprintf(`FROM %s
  4151  		ENTRYPOINT ["cat"]`, name),
  4152  		true); err != nil {
  4153  		c.Fatal(err)
  4154  	}
  4155  	res := inspectField(c, name, "Config.Cmd")
  4156  	if res != "[]" {
  4157  		c.Fatalf("Cmd %s, expected nil", res)
  4158  	}
  4159  
  4160  	res = inspectField(c, name, "Config.Entrypoint")
  4161  	if expected := "[cat]"; res != expected {
  4162  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  4163  	}
  4164  }
  4165  
  4166  func (s *DockerSuite) TestBuildClearCmd(c *check.C) {
  4167  	name := "testbuildclearcmd"
  4168  	_, err := buildImage(name,
  4169  		`From `+minimalBaseImage()+`
  4170     ENTRYPOINT ["/bin/bash"]
  4171     CMD []`,
  4172  		true)
  4173  	if err != nil {
  4174  		c.Fatal(err)
  4175  	}
  4176  	res := inspectFieldJSON(c, name, "Config.Cmd")
  4177  	if res != "[]" {
  4178  		c.Fatalf("Cmd %s, expected %s", res, "[]")
  4179  	}
  4180  }
  4181  
  4182  func (s *DockerSuite) TestBuildEmptyCmd(c *check.C) {
  4183  	// Skip on Windows. Base image on Windows has a CMD set in the image.
  4184  	testRequires(c, DaemonIsLinux)
  4185  
  4186  	name := "testbuildemptycmd"
  4187  	if _, err := buildImage(name, "FROM "+minimalBaseImage()+"\nMAINTAINER quux\n", true); err != nil {
  4188  		c.Fatal(err)
  4189  	}
  4190  	res := inspectFieldJSON(c, name, "Config.Cmd")
  4191  	if res != "null" {
  4192  		c.Fatalf("Cmd %s, expected %s", res, "null")
  4193  	}
  4194  }
  4195  
  4196  func (s *DockerSuite) TestBuildOnBuildOutput(c *check.C) {
  4197  	name := "testbuildonbuildparent"
  4198  	if _, err := buildImage(name, "FROM busybox\nONBUILD RUN echo foo\n", true); err != nil {
  4199  		c.Fatal(err)
  4200  	}
  4201  
  4202  	_, out, err := buildImageWithOut(name, "FROM "+name+"\nMAINTAINER quux\n", true)
  4203  	if err != nil {
  4204  		c.Fatal(err)
  4205  	}
  4206  
  4207  	if !strings.Contains(out, "# Executing 1 build trigger") {
  4208  		c.Fatal("failed to find the build trigger output", out)
  4209  	}
  4210  }
  4211  
  4212  func (s *DockerSuite) TestBuildInvalidTag(c *check.C) {
  4213  	name := "abcd:" + stringutils.GenerateRandomAlphaOnlyString(200)
  4214  	_, out, err := buildImageWithOut(name, "FROM "+minimalBaseImage()+"\nMAINTAINER quux\n", true)
  4215  	// if the error doesn't check for illegal tag name, or the image is built
  4216  	// then this should fail
  4217  	if !strings.Contains(out, "Error parsing reference") || strings.Contains(out, "Sending build context to Docker daemon") {
  4218  		c.Fatalf("failed to stop before building. Error: %s, Output: %s", err, out)
  4219  	}
  4220  }
  4221  
  4222  func (s *DockerSuite) TestBuildCmdShDashC(c *check.C) {
  4223  	name := "testbuildcmdshc"
  4224  	if _, err := buildImage(name, "FROM busybox\nCMD echo cmd\n", true); err != nil {
  4225  		c.Fatal(err)
  4226  	}
  4227  
  4228  	res := inspectFieldJSON(c, name, "Config.Cmd")
  4229  
  4230  	expected := `["/bin/sh","-c","echo cmd"]`
  4231  	if daemonPlatform == "windows" {
  4232  		expected = `["cmd","/S","/C","echo cmd"]`
  4233  	}
  4234  
  4235  	if res != expected {
  4236  		c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  4237  	}
  4238  
  4239  }
  4240  
  4241  func (s *DockerSuite) TestBuildCmdSpaces(c *check.C) {
  4242  	// Test to make sure that when we strcat arrays we take into account
  4243  	// the arg separator to make sure ["echo","hi"] and ["echo hi"] don't
  4244  	// look the same
  4245  	name := "testbuildcmdspaces"
  4246  	var id1 string
  4247  	var id2 string
  4248  	var err error
  4249  
  4250  	if id1, err = buildImage(name, "FROM busybox\nCMD [\"echo hi\"]\n", true); err != nil {
  4251  		c.Fatal(err)
  4252  	}
  4253  
  4254  	if id2, err = buildImage(name, "FROM busybox\nCMD [\"echo\", \"hi\"]\n", true); err != nil {
  4255  		c.Fatal(err)
  4256  	}
  4257  
  4258  	if id1 == id2 {
  4259  		c.Fatal("Should not have resulted in the same CMD")
  4260  	}
  4261  
  4262  	// Now do the same with ENTRYPOINT
  4263  	if id1, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo hi\"]\n", true); err != nil {
  4264  		c.Fatal(err)
  4265  	}
  4266  
  4267  	if id2, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo\", \"hi\"]\n", true); err != nil {
  4268  		c.Fatal(err)
  4269  	}
  4270  
  4271  	if id1 == id2 {
  4272  		c.Fatal("Should not have resulted in the same ENTRYPOINT")
  4273  	}
  4274  
  4275  }
  4276  
  4277  func (s *DockerSuite) TestBuildCmdJSONNoShDashC(c *check.C) {
  4278  	name := "testbuildcmdjson"
  4279  	if _, err := buildImage(name, "FROM busybox\nCMD [\"echo\", \"cmd\"]", true); err != nil {
  4280  		c.Fatal(err)
  4281  	}
  4282  
  4283  	res := inspectFieldJSON(c, name, "Config.Cmd")
  4284  
  4285  	expected := `["echo","cmd"]`
  4286  
  4287  	if res != expected {
  4288  		c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  4289  	}
  4290  
  4291  }
  4292  
  4293  func (s *DockerSuite) TestBuildEntrypointInheritance(c *check.C) {
  4294  
  4295  	if _, err := buildImage("parent", `
  4296      FROM busybox
  4297      ENTRYPOINT exit 130
  4298      `, true); err != nil {
  4299  		c.Fatal(err)
  4300  	}
  4301  
  4302  	if _, status, _ := dockerCmdWithError("run", "parent"); status != 130 {
  4303  		c.Fatalf("expected exit code 130 but received %d", status)
  4304  	}
  4305  
  4306  	if _, err := buildImage("child", `
  4307      FROM parent
  4308      ENTRYPOINT exit 5
  4309      `, true); err != nil {
  4310  		c.Fatal(err)
  4311  	}
  4312  
  4313  	if _, status, _ := dockerCmdWithError("run", "child"); status != 5 {
  4314  		c.Fatalf("expected exit code 5 but received %d", status)
  4315  	}
  4316  
  4317  }
  4318  
  4319  func (s *DockerSuite) TestBuildEntrypointInheritanceInspect(c *check.C) {
  4320  	var (
  4321  		name     = "testbuildepinherit"
  4322  		name2    = "testbuildepinherit2"
  4323  		expected = `["/bin/sh","-c","echo quux"]`
  4324  	)
  4325  
  4326  	if daemonPlatform == "windows" {
  4327  		expected = `["cmd","/S","/C","echo quux"]`
  4328  	}
  4329  
  4330  	if _, err := buildImage(name, "FROM busybox\nENTRYPOINT /foo/bar", true); err != nil {
  4331  		c.Fatal(err)
  4332  	}
  4333  
  4334  	if _, err := buildImage(name2, fmt.Sprintf("FROM %s\nENTRYPOINT echo quux", name), true); err != nil {
  4335  		c.Fatal(err)
  4336  	}
  4337  
  4338  	res := inspectFieldJSON(c, name2, "Config.Entrypoint")
  4339  
  4340  	if res != expected {
  4341  		c.Fatalf("Expected value %s not in Config.Entrypoint: %s", expected, res)
  4342  	}
  4343  
  4344  	out, _ := dockerCmd(c, "run", name2)
  4345  
  4346  	expected = "quux"
  4347  
  4348  	if strings.TrimSpace(out) != expected {
  4349  		c.Fatalf("Expected output is %s, got %s", expected, out)
  4350  	}
  4351  
  4352  }
  4353  
  4354  func (s *DockerSuite) TestBuildRunShEntrypoint(c *check.C) {
  4355  	name := "testbuildentrypoint"
  4356  	_, err := buildImage(name,
  4357  		`FROM busybox
  4358                                  ENTRYPOINT echo`,
  4359  		true)
  4360  	if err != nil {
  4361  		c.Fatal(err)
  4362  	}
  4363  
  4364  	dockerCmd(c, "run", "--rm", name)
  4365  }
  4366  
  4367  func (s *DockerSuite) TestBuildExoticShellInterpolation(c *check.C) {
  4368  	testRequires(c, DaemonIsLinux)
  4369  	name := "testbuildexoticshellinterpolation"
  4370  
  4371  	_, err := buildImage(name, `
  4372  		FROM busybox
  4373  
  4374  		ENV SOME_VAR a.b.c
  4375  
  4376  		RUN [ "$SOME_VAR"       = 'a.b.c' ]
  4377  		RUN [ "${SOME_VAR}"     = 'a.b.c' ]
  4378  		RUN [ "${SOME_VAR%.*}"  = 'a.b'   ]
  4379  		RUN [ "${SOME_VAR%%.*}" = 'a'     ]
  4380  		RUN [ "${SOME_VAR#*.}"  = 'b.c'   ]
  4381  		RUN [ "${SOME_VAR##*.}" = 'c'     ]
  4382  		RUN [ "${SOME_VAR/c/d}" = 'a.b.d' ]
  4383  		RUN [ "${#SOME_VAR}"    = '5'     ]
  4384  
  4385  		RUN [ "${SOME_UNSET_VAR:-$SOME_VAR}" = 'a.b.c' ]
  4386  		RUN [ "${SOME_VAR:+Version: ${SOME_VAR}}" = 'Version: a.b.c' ]
  4387  		RUN [ "${SOME_UNSET_VAR:+${SOME_VAR}}" = '' ]
  4388  		RUN [ "${SOME_UNSET_VAR:-${SOME_VAR:-d.e.f}}" = 'a.b.c' ]
  4389  	`, false)
  4390  	if err != nil {
  4391  		c.Fatal(err)
  4392  	}
  4393  
  4394  }
  4395  
  4396  func (s *DockerSuite) TestBuildVerifySingleQuoteFails(c *check.C) {
  4397  	// This testcase is supposed to generate an error because the
  4398  	// JSON array we're passing in on the CMD uses single quotes instead
  4399  	// of double quotes (per the JSON spec). This means we interpret it
  4400  	// as a "string" instead of "JSON array" and pass it on to "sh -c" and
  4401  	// it should barf on it.
  4402  	name := "testbuildsinglequotefails"
  4403  
  4404  	if _, err := buildImage(name,
  4405  		`FROM busybox
  4406  		CMD [ '/bin/sh', '-c', 'echo hi' ]`,
  4407  		true); err != nil {
  4408  		c.Fatal(err)
  4409  	}
  4410  
  4411  	if _, _, err := dockerCmdWithError("run", "--rm", name); err == nil {
  4412  		c.Fatal("The image was not supposed to be able to run")
  4413  	}
  4414  
  4415  }
  4416  
  4417  func (s *DockerSuite) TestBuildVerboseOut(c *check.C) {
  4418  	name := "testbuildverboseout"
  4419  	expected := "\n123\n"
  4420  
  4421  	if daemonPlatform == "windows" {
  4422  		expected = "\n123\r\n"
  4423  	}
  4424  
  4425  	_, out, err := buildImageWithOut(name,
  4426  		`FROM busybox
  4427  RUN echo 123`,
  4428  		false)
  4429  
  4430  	if err != nil {
  4431  		c.Fatal(err)
  4432  	}
  4433  	if !strings.Contains(out, expected) {
  4434  		c.Fatalf("Output should contain %q: %q", "123", out)
  4435  	}
  4436  
  4437  }
  4438  
  4439  func (s *DockerSuite) TestBuildWithTabs(c *check.C) {
  4440  	name := "testbuildwithtabs"
  4441  	_, err := buildImage(name,
  4442  		"FROM busybox\nRUN echo\tone\t\ttwo", true)
  4443  	if err != nil {
  4444  		c.Fatal(err)
  4445  	}
  4446  	res := inspectFieldJSON(c, name, "ContainerConfig.Cmd")
  4447  	expected1 := `["/bin/sh","-c","echo\tone\t\ttwo"]`
  4448  	expected2 := `["/bin/sh","-c","echo\u0009one\u0009\u0009two"]` // syntactically equivalent, and what Go 1.3 generates
  4449  	if daemonPlatform == "windows" {
  4450  		expected1 = `["cmd","/S","/C","echo\tone\t\ttwo"]`
  4451  		expected2 = `["cmd","/S","/C","echo\u0009one\u0009\u0009two"]` // syntactically equivalent, and what Go 1.3 generates
  4452  	}
  4453  	if res != expected1 && res != expected2 {
  4454  		c.Fatalf("Missing tabs.\nGot: %s\nExp: %s or %s", res, expected1, expected2)
  4455  	}
  4456  }
  4457  
  4458  func (s *DockerSuite) TestBuildLabels(c *check.C) {
  4459  	name := "testbuildlabel"
  4460  	expected := `{"License":"GPL","Vendor":"Acme"}`
  4461  	_, err := buildImage(name,
  4462  		`FROM busybox
  4463  		LABEL Vendor=Acme
  4464                  LABEL License GPL`,
  4465  		true)
  4466  	if err != nil {
  4467  		c.Fatal(err)
  4468  	}
  4469  	res := inspectFieldJSON(c, name, "Config.Labels")
  4470  	if res != expected {
  4471  		c.Fatalf("Labels %s, expected %s", res, expected)
  4472  	}
  4473  }
  4474  
  4475  func (s *DockerSuite) TestBuildLabelsCache(c *check.C) {
  4476  	name := "testbuildlabelcache"
  4477  
  4478  	id1, err := buildImage(name,
  4479  		`FROM busybox
  4480  		LABEL Vendor=Acme`, false)
  4481  	if err != nil {
  4482  		c.Fatalf("Build 1 should have worked: %v", err)
  4483  	}
  4484  
  4485  	id2, err := buildImage(name,
  4486  		`FROM busybox
  4487  		LABEL Vendor=Acme`, true)
  4488  	if err != nil || id1 != id2 {
  4489  		c.Fatalf("Build 2 should have worked & used cache(%s,%s): %v", id1, id2, err)
  4490  	}
  4491  
  4492  	id2, err = buildImage(name,
  4493  		`FROM busybox
  4494  		LABEL Vendor=Acme1`, true)
  4495  	if err != nil || id1 == id2 {
  4496  		c.Fatalf("Build 3 should have worked & NOT used cache(%s,%s): %v", id1, id2, err)
  4497  	}
  4498  
  4499  	id2, err = buildImage(name,
  4500  		`FROM busybox
  4501  		LABEL Vendor Acme`, true) // Note: " " and "=" should be same
  4502  	if err != nil || id1 != id2 {
  4503  		c.Fatalf("Build 4 should have worked & used cache(%s,%s): %v", id1, id2, err)
  4504  	}
  4505  
  4506  	// Now make sure the cache isn't used by mistake
  4507  	id1, err = buildImage(name,
  4508  		`FROM busybox
  4509         LABEL f1=b1 f2=b2`, false)
  4510  	if err != nil {
  4511  		c.Fatalf("Build 5 should have worked: %q", err)
  4512  	}
  4513  
  4514  	id2, err = buildImage(name,
  4515  		`FROM busybox
  4516         LABEL f1="b1 f2=b2"`, true)
  4517  	if err != nil || id1 == id2 {
  4518  		c.Fatalf("Build 6 should have worked & NOT used the cache(%s,%s): %q", id1, id2, err)
  4519  	}
  4520  
  4521  }
  4522  
  4523  func (s *DockerSuite) TestBuildNotVerboseSuccess(c *check.C) {
  4524  	// This test makes sure that -q works correctly when build is successful:
  4525  	// stdout has only the image ID (long image ID) and stderr is empty.
  4526  	var stdout, stderr string
  4527  	var err error
  4528  	outRegexp := regexp.MustCompile("^(sha256:|)[a-z0-9]{64}\\n$")
  4529  
  4530  	tt := []struct {
  4531  		Name      string
  4532  		BuildFunc func(string)
  4533  	}{
  4534  		{
  4535  			Name: "quiet_build_stdin_success",
  4536  			BuildFunc: func(name string) {
  4537  				_, stdout, stderr, err = buildImageWithStdoutStderr(name, "FROM busybox", true, "-q", "--force-rm", "--rm")
  4538  			},
  4539  		},
  4540  		{
  4541  			Name: "quiet_build_ctx_success",
  4542  			BuildFunc: func(name string) {
  4543  				ctx, err := fakeContext("FROM busybox", map[string]string{
  4544  					"quiet_build_success_fctx": "test",
  4545  				})
  4546  				if err != nil {
  4547  					c.Fatalf("Failed to create context: %s", err.Error())
  4548  				}
  4549  				defer ctx.Close()
  4550  				_, stdout, stderr, err = buildImageFromContextWithStdoutStderr(name, ctx, true, "-q", "--force-rm", "--rm")
  4551  			},
  4552  		},
  4553  		{
  4554  			Name: "quiet_build_git_success",
  4555  			BuildFunc: func(name string) {
  4556  				git, err := newFakeGit("repo", map[string]string{
  4557  					"Dockerfile": "FROM busybox",
  4558  				}, true)
  4559  				if err != nil {
  4560  					c.Fatalf("Failed to create the git repo: %s", err.Error())
  4561  				}
  4562  				defer git.Close()
  4563  				_, stdout, stderr, err = buildImageFromGitWithStdoutStderr(name, git, true, "-q", "--force-rm", "--rm")
  4564  
  4565  			},
  4566  		},
  4567  	}
  4568  
  4569  	for _, te := range tt {
  4570  		te.BuildFunc(te.Name)
  4571  		if err != nil {
  4572  			c.Fatalf("Test %s shouldn't fail, but got the following error: %s", te.Name, err.Error())
  4573  		}
  4574  		if outRegexp.Find([]byte(stdout)) == nil {
  4575  			c.Fatalf("Test %s expected stdout to match the [%v] regexp, but it is [%v]", te.Name, outRegexp, stdout)
  4576  		}
  4577  
  4578  		if stderr != "" {
  4579  			c.Fatalf("Test %s expected stderr to be empty, but it is [%#v]", te.Name, stderr)
  4580  		}
  4581  	}
  4582  
  4583  }
  4584  
  4585  func (s *DockerSuite) TestBuildNotVerboseFailureWithNonExistImage(c *check.C) {
  4586  	// This test makes sure that -q works correctly when build fails by
  4587  	// comparing between the stderr output in quiet mode and in stdout
  4588  	// and stderr output in verbose mode
  4589  	testRequires(c, Network)
  4590  	testName := "quiet_build_not_exists_image"
  4591  	buildCmd := "FROM busybox11"
  4592  	_, _, qstderr, qerr := buildImageWithStdoutStderr(testName, buildCmd, false, "-q", "--force-rm", "--rm")
  4593  	_, vstdout, vstderr, verr := buildImageWithStdoutStderr(testName, buildCmd, false, "--force-rm", "--rm")
  4594  	if verr == nil || qerr == nil {
  4595  		c.Fatal(fmt.Errorf("Test [%s] expected to fail but didn't", testName))
  4596  	}
  4597  	if qstderr != vstdout+vstderr {
  4598  		c.Fatal(fmt.Errorf("Test[%s] expected that quiet stderr and verbose stdout are equal; quiet [%v], verbose [%v]", testName, qstderr, vstdout+vstderr))
  4599  	}
  4600  }
  4601  
  4602  func (s *DockerSuite) TestBuildNotVerboseFailure(c *check.C) {
  4603  	// This test makes sure that -q works correctly when build fails by
  4604  	// comparing between the stderr output in quiet mode and in stdout
  4605  	// and stderr output in verbose mode
  4606  	tt := []struct {
  4607  		TestName  string
  4608  		BuildCmds string
  4609  	}{
  4610  		{"quiet_build_no_from_at_the_beginning", "RUN whoami"},
  4611  		{"quiet_build_unknown_instr", "FROMD busybox"},
  4612  	}
  4613  
  4614  	for _, te := range tt {
  4615  		_, _, qstderr, qerr := buildImageWithStdoutStderr(te.TestName, te.BuildCmds, false, "-q", "--force-rm", "--rm")
  4616  		_, vstdout, vstderr, verr := buildImageWithStdoutStderr(te.TestName, te.BuildCmds, false, "--force-rm", "--rm")
  4617  		if verr == nil || qerr == nil {
  4618  			c.Fatal(fmt.Errorf("Test [%s] expected to fail but didn't", te.TestName))
  4619  		}
  4620  		if qstderr != vstdout+vstderr {
  4621  			c.Fatal(fmt.Errorf("Test[%s] expected that quiet stderr and verbose stdout are equal; quiet [%v], verbose [%v]", te.TestName, qstderr, vstdout+vstderr))
  4622  		}
  4623  	}
  4624  }
  4625  
  4626  func (s *DockerSuite) TestBuildNotVerboseFailureRemote(c *check.C) {
  4627  	// This test ensures that when given a wrong URL, stderr in quiet mode and
  4628  	// stderr in verbose mode are identical.
  4629  	// TODO(vdemeester) with cobra, stdout has a carriage return too much so this test should not check stdout
  4630  	URL := "http://something.invalid"
  4631  	Name := "quiet_build_wrong_remote"
  4632  	_, _, qstderr, qerr := buildImageWithStdoutStderr(Name, "", false, "-q", "--force-rm", "--rm", URL)
  4633  	_, _, vstderr, verr := buildImageWithStdoutStderr(Name, "", false, "--force-rm", "--rm", URL)
  4634  	if qerr == nil || verr == nil {
  4635  		c.Fatal(fmt.Errorf("Test [%s] expected to fail but didn't", Name))
  4636  	}
  4637  	if qstderr != vstderr {
  4638  		c.Fatal(fmt.Errorf("Test[%s] expected that quiet stderr and verbose stdout are equal; quiet [%v], verbose [%v]", Name, qstderr, vstderr))
  4639  	}
  4640  }
  4641  
  4642  func (s *DockerSuite) TestBuildStderr(c *check.C) {
  4643  	// This test just makes sure that no non-error output goes
  4644  	// to stderr
  4645  	name := "testbuildstderr"
  4646  	_, _, stderr, err := buildImageWithStdoutStderr(name,
  4647  		"FROM busybox\nRUN echo one", true)
  4648  	if err != nil {
  4649  		c.Fatal(err)
  4650  	}
  4651  
  4652  	if runtime.GOOS == "windows" &&
  4653  		daemonPlatform != "windows" {
  4654  		// Windows to non-Windows should have a security warning
  4655  		if !strings.Contains(stderr, "SECURITY WARNING:") {
  4656  			c.Fatalf("Stderr contains unexpected output: %q", stderr)
  4657  		}
  4658  	} else {
  4659  		// Other platform combinations should have no stderr written too
  4660  		if stderr != "" {
  4661  			c.Fatalf("Stderr should have been empty, instead it's: %q", stderr)
  4662  		}
  4663  	}
  4664  }
  4665  
  4666  func (s *DockerSuite) TestBuildChownSingleFile(c *check.C) {
  4667  	testRequires(c, UnixCli) // test uses chown: not available on windows
  4668  	testRequires(c, DaemonIsLinux)
  4669  
  4670  	name := "testbuildchownsinglefile"
  4671  
  4672  	ctx, err := fakeContext(`
  4673  FROM busybox
  4674  COPY test /
  4675  RUN ls -l /test
  4676  RUN [ $(ls -l /test | awk '{print $3":"$4}') = 'root:root' ]
  4677  `, map[string]string{
  4678  		"test": "test",
  4679  	})
  4680  	if err != nil {
  4681  		c.Fatal(err)
  4682  	}
  4683  	defer ctx.Close()
  4684  
  4685  	if err := os.Chown(filepath.Join(ctx.Dir, "test"), 4242, 4242); err != nil {
  4686  		c.Fatal(err)
  4687  	}
  4688  
  4689  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4690  		c.Fatal(err)
  4691  	}
  4692  
  4693  }
  4694  
  4695  func (s *DockerSuite) TestBuildSymlinkBreakout(c *check.C) {
  4696  	name := "testbuildsymlinkbreakout"
  4697  	tmpdir, err := ioutil.TempDir("", name)
  4698  	c.Assert(err, check.IsNil)
  4699  	defer os.RemoveAll(tmpdir)
  4700  	ctx := filepath.Join(tmpdir, "context")
  4701  	if err := os.MkdirAll(ctx, 0755); err != nil {
  4702  		c.Fatal(err)
  4703  	}
  4704  	if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte(`
  4705  	from busybox
  4706  	add symlink.tar /
  4707  	add inject /symlink/
  4708  	`), 0644); err != nil {
  4709  		c.Fatal(err)
  4710  	}
  4711  	inject := filepath.Join(ctx, "inject")
  4712  	if err := ioutil.WriteFile(inject, nil, 0644); err != nil {
  4713  		c.Fatal(err)
  4714  	}
  4715  	f, err := os.Create(filepath.Join(ctx, "symlink.tar"))
  4716  	if err != nil {
  4717  		c.Fatal(err)
  4718  	}
  4719  	w := tar.NewWriter(f)
  4720  	w.WriteHeader(&tar.Header{
  4721  		Name:     "symlink2",
  4722  		Typeflag: tar.TypeSymlink,
  4723  		Linkname: "/../../../../../../../../../../../../../../",
  4724  		Uid:      os.Getuid(),
  4725  		Gid:      os.Getgid(),
  4726  	})
  4727  	w.WriteHeader(&tar.Header{
  4728  		Name:     "symlink",
  4729  		Typeflag: tar.TypeSymlink,
  4730  		Linkname: filepath.Join("symlink2", tmpdir),
  4731  		Uid:      os.Getuid(),
  4732  		Gid:      os.Getgid(),
  4733  	})
  4734  	w.Close()
  4735  	f.Close()
  4736  	if _, err := buildImageFromContext(name, fakeContextFromDir(ctx), false); err != nil {
  4737  		c.Fatal(err)
  4738  	}
  4739  	if _, err := os.Lstat(filepath.Join(tmpdir, "inject")); err == nil {
  4740  		c.Fatal("symlink breakout - inject")
  4741  	} else if !os.IsNotExist(err) {
  4742  		c.Fatalf("unexpected error: %v", err)
  4743  	}
  4744  }
  4745  
  4746  func (s *DockerSuite) TestBuildXZHost(c *check.C) {
  4747  	// /usr/local/sbin/xz gets permission denied for the user
  4748  	testRequires(c, NotUserNamespace)
  4749  	testRequires(c, DaemonIsLinux)
  4750  	name := "testbuildxzhost"
  4751  
  4752  	ctx, err := fakeContext(`
  4753  FROM busybox
  4754  ADD xz /usr/local/sbin/
  4755  RUN chmod 755 /usr/local/sbin/xz
  4756  ADD test.xz /
  4757  RUN [ ! -e /injected ]`,
  4758  		map[string]string{
  4759  			"test.xz": "\xfd\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00" +
  4760  				"\x21\x01\x16\x00\x00\x00\x74\x2f\xe5\xa3\x01\x00\x3f\xfd" +
  4761  				"\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00\x21",
  4762  			"xz": "#!/bin/sh\ntouch /injected",
  4763  		})
  4764  
  4765  	if err != nil {
  4766  		c.Fatal(err)
  4767  	}
  4768  	defer ctx.Close()
  4769  
  4770  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4771  		c.Fatal(err)
  4772  	}
  4773  
  4774  }
  4775  
  4776  func (s *DockerSuite) TestBuildVolumesRetainContents(c *check.C) {
  4777  	// /foo/file gets permission denied for the user
  4778  	testRequires(c, NotUserNamespace)
  4779  	testRequires(c, DaemonIsLinux) // TODO Windows: Issue #20127
  4780  	var (
  4781  		name     = "testbuildvolumescontent"
  4782  		expected = "some text"
  4783  		volName  = "/foo"
  4784  	)
  4785  
  4786  	if daemonPlatform == "windows" {
  4787  		volName = "C:/foo"
  4788  	}
  4789  
  4790  	ctx, err := fakeContext(`
  4791  FROM busybox
  4792  COPY content /foo/file
  4793  VOLUME `+volName+`
  4794  CMD cat /foo/file`,
  4795  		map[string]string{
  4796  			"content": expected,
  4797  		})
  4798  	if err != nil {
  4799  		c.Fatal(err)
  4800  	}
  4801  	defer ctx.Close()
  4802  
  4803  	if _, err := buildImageFromContext(name, ctx, false); err != nil {
  4804  		c.Fatal(err)
  4805  	}
  4806  
  4807  	out, _ := dockerCmd(c, "run", "--rm", name)
  4808  	if out != expected {
  4809  		c.Fatalf("expected file contents for /foo/file to be %q but received %q", expected, out)
  4810  	}
  4811  
  4812  }
  4813  
  4814  func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) {
  4815  
  4816  	ctx, err := fakeContext(`FROM busybox
  4817  	RUN echo from Dockerfile`,
  4818  		map[string]string{
  4819  			"Dockerfile":       "FROM busybox\nRUN echo from Dockerfile",
  4820  			"files/Dockerfile": "FROM busybox\nRUN echo from files/Dockerfile",
  4821  			"files/dFile":      "FROM busybox\nRUN echo from files/dFile",
  4822  			"dFile":            "FROM busybox\nRUN echo from dFile",
  4823  			"files/dFile2":     "FROM busybox\nRUN echo from files/dFile2",
  4824  		})
  4825  	if err != nil {
  4826  		c.Fatal(err)
  4827  	}
  4828  	defer ctx.Close()
  4829  
  4830  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4831  	if err != nil {
  4832  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4833  	}
  4834  	if !strings.Contains(out, "from Dockerfile") {
  4835  		c.Fatalf("test1 should have used Dockerfile, output:%s", out)
  4836  	}
  4837  
  4838  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-f", filepath.Join("files", "Dockerfile"), "-t", "test2", ".")
  4839  	if err != nil {
  4840  		c.Fatal(err)
  4841  	}
  4842  	if !strings.Contains(out, "from files/Dockerfile") {
  4843  		c.Fatalf("test2 should have used files/Dockerfile, output:%s", out)
  4844  	}
  4845  
  4846  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", filepath.Join("files", "dFile")), "-t", "test3", ".")
  4847  	if err != nil {
  4848  		c.Fatal(err)
  4849  	}
  4850  	if !strings.Contains(out, "from files/dFile") {
  4851  		c.Fatalf("test3 should have used files/dFile, output:%s", out)
  4852  	}
  4853  
  4854  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "--file=dFile", "-t", "test4", ".")
  4855  	if err != nil {
  4856  		c.Fatal(err)
  4857  	}
  4858  	if !strings.Contains(out, "from dFile") {
  4859  		c.Fatalf("test4 should have used dFile, output:%s", out)
  4860  	}
  4861  
  4862  	dirWithNoDockerfile, err := ioutil.TempDir(os.TempDir(), "test5")
  4863  	c.Assert(err, check.IsNil)
  4864  	nonDockerfileFile := filepath.Join(dirWithNoDockerfile, "notDockerfile")
  4865  	if _, err = os.Create(nonDockerfileFile); err != nil {
  4866  		c.Fatal(err)
  4867  	}
  4868  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", nonDockerfileFile), "-t", "test5", ".")
  4869  
  4870  	if err == nil {
  4871  		c.Fatalf("test5 was supposed to fail to find passwd")
  4872  	}
  4873  
  4874  	if expected := fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", nonDockerfileFile); !strings.Contains(out, expected) {
  4875  		c.Fatalf("wrong error message:%v\nexpected to contain=%v", out, expected)
  4876  	}
  4877  
  4878  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test6", "..")
  4879  	if err != nil {
  4880  		c.Fatalf("test6 failed: %s", err)
  4881  	}
  4882  	if !strings.Contains(out, "from Dockerfile") {
  4883  		c.Fatalf("test6 should have used root Dockerfile, output:%s", out)
  4884  	}
  4885  
  4886  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join(ctx.Dir, "files", "Dockerfile"), "-t", "test7", "..")
  4887  	if err != nil {
  4888  		c.Fatalf("test7 failed: %s", err)
  4889  	}
  4890  	if !strings.Contains(out, "from files/Dockerfile") {
  4891  		c.Fatalf("test7 should have used files Dockerfile, output:%s", out)
  4892  	}
  4893  
  4894  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test8", ".")
  4895  	if err == nil || !strings.Contains(out, "must be within the build context") {
  4896  		c.Fatalf("test8 should have failed with Dockerfile out of context: %s", err)
  4897  	}
  4898  
  4899  	tmpDir := os.TempDir()
  4900  	out, _, err = dockerCmdInDir(c, tmpDir, "build", "-t", "test9", ctx.Dir)
  4901  	if err != nil {
  4902  		c.Fatalf("test9 - failed: %s", err)
  4903  	}
  4904  	if !strings.Contains(out, "from Dockerfile") {
  4905  		c.Fatalf("test9 should have used root Dockerfile, output:%s", out)
  4906  	}
  4907  
  4908  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", "dFile2", "-t", "test10", ".")
  4909  	if err != nil {
  4910  		c.Fatalf("test10 should have worked: %s", err)
  4911  	}
  4912  	if !strings.Contains(out, "from files/dFile2") {
  4913  		c.Fatalf("test10 should have used files/dFile2, output:%s", out)
  4914  	}
  4915  
  4916  }
  4917  
  4918  func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) {
  4919  	testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  4920  	testRequires(c, DaemonIsLinux)
  4921  
  4922  	ctx, err := fakeContext(`FROM busybox
  4923  	RUN echo from dockerfile`,
  4924  		map[string]string{
  4925  			"dockerfile": "FROM busybox\nRUN echo from dockerfile",
  4926  		})
  4927  	if err != nil {
  4928  		c.Fatal(err)
  4929  	}
  4930  	defer ctx.Close()
  4931  
  4932  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4933  	if err != nil {
  4934  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4935  	}
  4936  
  4937  	if !strings.Contains(out, "from dockerfile") {
  4938  		c.Fatalf("Missing proper output: %s", out)
  4939  	}
  4940  
  4941  }
  4942  
  4943  func (s *DockerSuite) TestBuildWithTwoDockerfiles(c *check.C) {
  4944  	testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  4945  	testRequires(c, DaemonIsLinux)
  4946  
  4947  	ctx, err := fakeContext(`FROM busybox
  4948  RUN echo from Dockerfile`,
  4949  		map[string]string{
  4950  			"dockerfile": "FROM busybox\nRUN echo from dockerfile",
  4951  		})
  4952  	if err != nil {
  4953  		c.Fatal(err)
  4954  	}
  4955  	defer ctx.Close()
  4956  
  4957  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4958  	if err != nil {
  4959  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4960  	}
  4961  
  4962  	if !strings.Contains(out, "from Dockerfile") {
  4963  		c.Fatalf("Missing proper output: %s", out)
  4964  	}
  4965  
  4966  }
  4967  
  4968  func (s *DockerSuite) TestBuildFromURLWithF(c *check.C) {
  4969  	server, err := fakeStorage(map[string]string{"baz": `FROM busybox
  4970  RUN echo from baz
  4971  COPY * /tmp/
  4972  RUN find /tmp/`})
  4973  	if err != nil {
  4974  		c.Fatal(err)
  4975  	}
  4976  	defer server.Close()
  4977  
  4978  	ctx, err := fakeContext(`FROM busybox
  4979  RUN echo from Dockerfile`,
  4980  		map[string]string{})
  4981  	if err != nil {
  4982  		c.Fatal(err)
  4983  	}
  4984  	defer ctx.Close()
  4985  
  4986  	// Make sure that -f is ignored and that we don't use the Dockerfile
  4987  	// that's in the current dir
  4988  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-f", "baz", "-t", "test1", server.URL()+"/baz")
  4989  	if err != nil {
  4990  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4991  	}
  4992  
  4993  	if !strings.Contains(out, "from baz") ||
  4994  		strings.Contains(out, "/tmp/baz") ||
  4995  		!strings.Contains(out, "/tmp/Dockerfile") {
  4996  		c.Fatalf("Missing proper output: %s", out)
  4997  	}
  4998  
  4999  }
  5000  
  5001  func (s *DockerSuite) TestBuildFromStdinWithF(c *check.C) {
  5002  	testRequires(c, DaemonIsLinux) // TODO Windows: This test is flaky; no idea why
  5003  	ctx, err := fakeContext(`FROM busybox
  5004  RUN echo "from Dockerfile"`,
  5005  		map[string]string{})
  5006  	if err != nil {
  5007  		c.Fatal(err)
  5008  	}
  5009  	defer ctx.Close()
  5010  
  5011  	// Make sure that -f is ignored and that we don't use the Dockerfile
  5012  	// that's in the current dir
  5013  	dockerCommand := exec.Command(dockerBinary, "build", "-f", "baz", "-t", "test1", "-")
  5014  	dockerCommand.Dir = ctx.Dir
  5015  	dockerCommand.Stdin = strings.NewReader(`FROM busybox
  5016  RUN echo "from baz"
  5017  COPY * /tmp/
  5018  RUN sh -c "find /tmp/" # sh -c is needed on Windows to use the correct find`)
  5019  	out, status, err := runCommandWithOutput(dockerCommand)
  5020  	if err != nil || status != 0 {
  5021  		c.Fatalf("Error building: %s", err)
  5022  	}
  5023  
  5024  	if !strings.Contains(out, "from baz") ||
  5025  		strings.Contains(out, "/tmp/baz") ||
  5026  		!strings.Contains(out, "/tmp/Dockerfile") {
  5027  		c.Fatalf("Missing proper output: %s", out)
  5028  	}
  5029  
  5030  }
  5031  
  5032  func (s *DockerSuite) TestBuildFromOfficialNames(c *check.C) {
  5033  	name := "testbuildfromofficial"
  5034  	fromNames := []string{
  5035  		"busybox",
  5036  		"docker.io/busybox",
  5037  		"index.docker.io/busybox",
  5038  		"library/busybox",
  5039  		"docker.io/library/busybox",
  5040  		"index.docker.io/library/busybox",
  5041  	}
  5042  	for idx, fromName := range fromNames {
  5043  		imgName := fmt.Sprintf("%s%d", name, idx)
  5044  		_, err := buildImage(imgName, "FROM "+fromName, true)
  5045  		if err != nil {
  5046  			c.Errorf("Build failed using FROM %s: %s", fromName, err)
  5047  		}
  5048  		deleteImages(imgName)
  5049  	}
  5050  }
  5051  
  5052  func (s *DockerSuite) TestBuildDockerfileOutsideContext(c *check.C) {
  5053  	testRequires(c, UnixCli) // uses os.Symlink: not implemented in windows at the time of writing (go-1.4.2)
  5054  	testRequires(c, DaemonIsLinux)
  5055  
  5056  	name := "testbuilddockerfileoutsidecontext"
  5057  	tmpdir, err := ioutil.TempDir("", name)
  5058  	c.Assert(err, check.IsNil)
  5059  	defer os.RemoveAll(tmpdir)
  5060  	ctx := filepath.Join(tmpdir, "context")
  5061  	if err := os.MkdirAll(ctx, 0755); err != nil {
  5062  		c.Fatal(err)
  5063  	}
  5064  	if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte("FROM scratch\nENV X Y"), 0644); err != nil {
  5065  		c.Fatal(err)
  5066  	}
  5067  	wd, err := os.Getwd()
  5068  	if err != nil {
  5069  		c.Fatal(err)
  5070  	}
  5071  	defer os.Chdir(wd)
  5072  	if err := os.Chdir(ctx); err != nil {
  5073  		c.Fatal(err)
  5074  	}
  5075  	if err := ioutil.WriteFile(filepath.Join(tmpdir, "outsideDockerfile"), []byte("FROM scratch\nENV x y"), 0644); err != nil {
  5076  		c.Fatal(err)
  5077  	}
  5078  	if err := os.Symlink(filepath.Join("..", "outsideDockerfile"), filepath.Join(ctx, "dockerfile1")); err != nil {
  5079  		c.Fatal(err)
  5080  	}
  5081  	if err := os.Symlink(filepath.Join(tmpdir, "outsideDockerfile"), filepath.Join(ctx, "dockerfile2")); err != nil {
  5082  		c.Fatal(err)
  5083  	}
  5084  
  5085  	for _, dockerfilePath := range []string{
  5086  		filepath.Join("..", "outsideDockerfile"),
  5087  		filepath.Join(ctx, "dockerfile1"),
  5088  		filepath.Join(ctx, "dockerfile2"),
  5089  	} {
  5090  		result := dockerCmdWithResult("build", "-t", name, "--no-cache", "-f", dockerfilePath, ".")
  5091  		c.Assert(result, icmd.Matches, icmd.Expected{
  5092  			Err:      "must be within the build context",
  5093  			ExitCode: 1,
  5094  		})
  5095  		deleteImages(name)
  5096  	}
  5097  
  5098  	os.Chdir(tmpdir)
  5099  
  5100  	// Path to Dockerfile should be resolved relative to working directory, not relative to context.
  5101  	// There is a Dockerfile in the context, but since there is no Dockerfile in the current directory, the following should fail
  5102  	out, _, err := dockerCmdWithError("build", "-t", name, "--no-cache", "-f", "Dockerfile", ctx)
  5103  	if err == nil {
  5104  		c.Fatalf("Expected error. Out: %s", out)
  5105  	}
  5106  }
  5107  
  5108  func (s *DockerSuite) TestBuildSpaces(c *check.C) {
  5109  	// Test to make sure that leading/trailing spaces on a command
  5110  	// doesn't change the error msg we get
  5111  	var (
  5112  		err1 error
  5113  		err2 error
  5114  	)
  5115  
  5116  	name := "testspaces"
  5117  	ctx, err := fakeContext("FROM busybox\nCOPY\n",
  5118  		map[string]string{
  5119  			"Dockerfile": "FROM busybox\nCOPY\n",
  5120  		})
  5121  	if err != nil {
  5122  		c.Fatal(err)
  5123  	}
  5124  	defer ctx.Close()
  5125  
  5126  	if _, err1 = buildImageFromContext(name, ctx, false); err1 == nil {
  5127  		c.Fatal("Build 1 was supposed to fail, but didn't")
  5128  	}
  5129  
  5130  	ctx.Add("Dockerfile", "FROM busybox\nCOPY    ")
  5131  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5132  		c.Fatal("Build 2 was supposed to fail, but didn't")
  5133  	}
  5134  
  5135  	removeLogTimestamps := func(s string) string {
  5136  		return regexp.MustCompile(`time="(.*?)"`).ReplaceAllString(s, `time=[TIMESTAMP]`)
  5137  	}
  5138  
  5139  	// Skip over the times
  5140  	e1 := removeLogTimestamps(err1.Error())
  5141  	e2 := removeLogTimestamps(err2.Error())
  5142  
  5143  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5144  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5145  		c.Fatalf("Build 2's error wasn't the same as build 1's\n1:%s\n2:%s", err1, err2)
  5146  	}
  5147  
  5148  	ctx.Add("Dockerfile", "FROM busybox\n   COPY")
  5149  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5150  		c.Fatal("Build 3 was supposed to fail, but didn't")
  5151  	}
  5152  
  5153  	// Skip over the times
  5154  	e1 = removeLogTimestamps(err1.Error())
  5155  	e2 = removeLogTimestamps(err2.Error())
  5156  
  5157  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5158  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5159  		c.Fatalf("Build 3's error wasn't the same as build 1's\n1:%s\n3:%s", err1, err2)
  5160  	}
  5161  
  5162  	ctx.Add("Dockerfile", "FROM busybox\n   COPY    ")
  5163  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5164  		c.Fatal("Build 4 was supposed to fail, but didn't")
  5165  	}
  5166  
  5167  	// Skip over the times
  5168  	e1 = removeLogTimestamps(err1.Error())
  5169  	e2 = removeLogTimestamps(err2.Error())
  5170  
  5171  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5172  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5173  		c.Fatalf("Build 4's error wasn't the same as build 1's\n1:%s\n4:%s", err1, err2)
  5174  	}
  5175  
  5176  }
  5177  
  5178  func (s *DockerSuite) TestBuildSpacesWithQuotes(c *check.C) {
  5179  	// Test to make sure that spaces in quotes aren't lost
  5180  	name := "testspacesquotes"
  5181  
  5182  	dockerfile := `FROM busybox
  5183  RUN echo "  \
  5184    foo  "`
  5185  
  5186  	_, out, err := buildImageWithOut(name, dockerfile, false)
  5187  	if err != nil {
  5188  		c.Fatal("Build failed:", err)
  5189  	}
  5190  
  5191  	expecting := "\n    foo  \n"
  5192  	// Windows uses the builtin echo, which preserves quotes
  5193  	if daemonPlatform == "windows" {
  5194  		expecting = "\"    foo  \""
  5195  	}
  5196  	if !strings.Contains(out, expecting) {
  5197  		c.Fatalf("Bad output: %q expecting to contain %q", out, expecting)
  5198  	}
  5199  
  5200  }
  5201  
  5202  // #4393
  5203  func (s *DockerSuite) TestBuildVolumeFileExistsinContainer(c *check.C) {
  5204  	testRequires(c, DaemonIsLinux) // TODO Windows: This should error out
  5205  	buildCmd := exec.Command(dockerBinary, "build", "-t", "docker-test-errcreatevolumewithfile", "-")
  5206  	buildCmd.Stdin = strings.NewReader(`
  5207  	FROM busybox
  5208  	RUN touch /foo
  5209  	VOLUME /foo
  5210  	`)
  5211  
  5212  	out, _, err := runCommandWithOutput(buildCmd)
  5213  	if err == nil || !strings.Contains(out, "file exists") {
  5214  		c.Fatalf("expected build to fail when file exists in container at requested volume path")
  5215  	}
  5216  
  5217  }
  5218  
  5219  func (s *DockerSuite) TestBuildMissingArgs(c *check.C) {
  5220  	// Test to make sure that all Dockerfile commands (except the ones listed
  5221  	// in skipCmds) will generate an error if no args are provided.
  5222  	// Note: INSERT is deprecated so we exclude it because of that.
  5223  	skipCmds := map[string]struct{}{
  5224  		"CMD":        {},
  5225  		"RUN":        {},
  5226  		"ENTRYPOINT": {},
  5227  		"INSERT":     {},
  5228  	}
  5229  
  5230  	if daemonPlatform == "windows" {
  5231  		skipCmds = map[string]struct{}{
  5232  			"CMD":        {},
  5233  			"RUN":        {},
  5234  			"ENTRYPOINT": {},
  5235  			"INSERT":     {},
  5236  			"STOPSIGNAL": {},
  5237  			"ARG":        {},
  5238  			"USER":       {},
  5239  			"EXPOSE":     {},
  5240  		}
  5241  	}
  5242  
  5243  	for cmd := range command.Commands {
  5244  		cmd = strings.ToUpper(cmd)
  5245  		if _, ok := skipCmds[cmd]; ok {
  5246  			continue
  5247  		}
  5248  
  5249  		var dockerfile string
  5250  		if cmd == "FROM" {
  5251  			dockerfile = cmd
  5252  		} else {
  5253  			// Add FROM to make sure we don't complain about it missing
  5254  			dockerfile = "FROM busybox\n" + cmd
  5255  		}
  5256  
  5257  		ctx, err := fakeContext(dockerfile, map[string]string{})
  5258  		if err != nil {
  5259  			c.Fatal(err)
  5260  		}
  5261  		defer ctx.Close()
  5262  		var out string
  5263  		if out, err = buildImageFromContext("args", ctx, true); err == nil {
  5264  			c.Fatalf("%s was supposed to fail. Out:%s", cmd, out)
  5265  		}
  5266  		if !strings.Contains(err.Error(), cmd+" requires") {
  5267  			c.Fatalf("%s returned the wrong type of error:%s", cmd, err)
  5268  		}
  5269  	}
  5270  
  5271  }
  5272  
  5273  func (s *DockerSuite) TestBuildEmptyScratch(c *check.C) {
  5274  	testRequires(c, DaemonIsLinux)
  5275  	_, out, err := buildImageWithOut("sc", "FROM scratch", true)
  5276  	if err == nil {
  5277  		c.Fatalf("Build was supposed to fail")
  5278  	}
  5279  	if !strings.Contains(out, "No image was generated") {
  5280  		c.Fatalf("Wrong error message: %v", out)
  5281  	}
  5282  }
  5283  
  5284  func (s *DockerSuite) TestBuildDotDotFile(c *check.C) {
  5285  	ctx, err := fakeContext("FROM busybox\n",
  5286  		map[string]string{
  5287  			"..gitme": "",
  5288  		})
  5289  	if err != nil {
  5290  		c.Fatal(err)
  5291  	}
  5292  	defer ctx.Close()
  5293  
  5294  	if _, err = buildImageFromContext("sc", ctx, false); err != nil {
  5295  		c.Fatalf("Build was supposed to work: %s", err)
  5296  	}
  5297  }
  5298  
  5299  func (s *DockerSuite) TestBuildRUNoneJSON(c *check.C) {
  5300  	testRequires(c, DaemonIsLinux) // No hello-world Windows image
  5301  	name := "testbuildrunonejson"
  5302  
  5303  	ctx, err := fakeContext(`FROM hello-world:frozen
  5304  RUN [ "/hello" ]`, map[string]string{})
  5305  	if err != nil {
  5306  		c.Fatal(err)
  5307  	}
  5308  	defer ctx.Close()
  5309  
  5310  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--no-cache", "-t", name, ".")
  5311  	if err != nil {
  5312  		c.Fatalf("failed to build the image: %s, %v", out, err)
  5313  	}
  5314  
  5315  	if !strings.Contains(out, "Hello from Docker") {
  5316  		c.Fatalf("bad output: %s", out)
  5317  	}
  5318  
  5319  }
  5320  
  5321  func (s *DockerSuite) TestBuildEmptyStringVolume(c *check.C) {
  5322  	name := "testbuildemptystringvolume"
  5323  
  5324  	_, err := buildImage(name, `
  5325    FROM busybox
  5326    ENV foo=""
  5327    VOLUME $foo
  5328    `, false)
  5329  	if err == nil {
  5330  		c.Fatal("Should have failed to build")
  5331  	}
  5332  
  5333  }
  5334  
  5335  func (s *DockerSuite) TestBuildContainerWithCgroupParent(c *check.C) {
  5336  	testRequires(c, SameHostDaemon)
  5337  	testRequires(c, DaemonIsLinux)
  5338  
  5339  	cgroupParent := "test"
  5340  	data, err := ioutil.ReadFile("/proc/self/cgroup")
  5341  	if err != nil {
  5342  		c.Fatalf("failed to read '/proc/self/cgroup - %v", err)
  5343  	}
  5344  	selfCgroupPaths := parseCgroupPaths(string(data))
  5345  	_, found := selfCgroupPaths["memory"]
  5346  	if !found {
  5347  		c.Fatalf("unable to find self memory cgroup path. CgroupsPath: %v", selfCgroupPaths)
  5348  	}
  5349  	cmd := exec.Command(dockerBinary, "build", "--cgroup-parent", cgroupParent, "-")
  5350  	cmd.Stdin = strings.NewReader(`
  5351  FROM busybox
  5352  RUN cat /proc/self/cgroup
  5353  `)
  5354  
  5355  	out, _, err := runCommandWithOutput(cmd)
  5356  	if err != nil {
  5357  		c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
  5358  	}
  5359  	m, err := regexp.MatchString(fmt.Sprintf("memory:.*/%s/.*", cgroupParent), out)
  5360  	c.Assert(err, check.IsNil)
  5361  	if !m {
  5362  		c.Fatalf("There is no expected memory cgroup with parent /%s/: %s", cgroupParent, out)
  5363  	}
  5364  }
  5365  
  5366  func (s *DockerSuite) TestBuildNoDupOutput(c *check.C) {
  5367  	// Check to make sure our build output prints the Dockerfile cmd
  5368  	// property - there was a bug that caused it to be duplicated on the
  5369  	// Step X  line
  5370  	name := "testbuildnodupoutput"
  5371  
  5372  	_, out, err := buildImageWithOut(name, `
  5373    FROM busybox
  5374    RUN env`, false)
  5375  	if err != nil {
  5376  		c.Fatalf("Build should have worked: %q", err)
  5377  	}
  5378  
  5379  	exp := "\nStep 2/2 : RUN env\n"
  5380  	if !strings.Contains(out, exp) {
  5381  		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  5382  	}
  5383  }
  5384  
  5385  // GH15826
  5386  func (s *DockerSuite) TestBuildStartsFromOne(c *check.C) {
  5387  	// Explicit check to ensure that build starts from step 1 rather than 0
  5388  	name := "testbuildstartsfromone"
  5389  
  5390  	_, out, err := buildImageWithOut(name, `
  5391    FROM busybox`, false)
  5392  	if err != nil {
  5393  		c.Fatalf("Build should have worked: %q", err)
  5394  	}
  5395  
  5396  	exp := "\nStep 1/1 : FROM busybox\n"
  5397  	if !strings.Contains(out, exp) {
  5398  		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  5399  	}
  5400  }
  5401  
  5402  func (s *DockerSuite) TestBuildRUNErrMsg(c *check.C) {
  5403  	// Test to make sure the bad command is quoted with just "s and
  5404  	// not as a Go []string
  5405  	name := "testbuildbadrunerrmsg"
  5406  	_, out, err := buildImageWithOut(name, `
  5407    FROM busybox
  5408    RUN badEXE a1 \& a2	a3`, false) // tab between a2 and a3
  5409  	if err == nil {
  5410  		c.Fatal("Should have failed to build")
  5411  	}
  5412  	shell := "/bin/sh -c"
  5413  	exitCode := "127"
  5414  	if daemonPlatform == "windows" {
  5415  		shell = "cmd /S /C"
  5416  		// architectural - Windows has to start the container to determine the exe is bad, Linux does not
  5417  		exitCode = "1"
  5418  	}
  5419  	exp := `The command '` + shell + ` badEXE a1 \& a2	a3' returned a non-zero code: ` + exitCode
  5420  	if !strings.Contains(out, exp) {
  5421  		c.Fatalf("RUN doesn't have the correct output:\nGot:%s\nExpected:%s", out, exp)
  5422  	}
  5423  }
  5424  
  5425  func (s *DockerTrustSuite) TestTrustedBuild(c *check.C) {
  5426  	repoName := s.setupTrustedImage(c, "trusted-build")
  5427  	dockerFile := fmt.Sprintf(`
  5428    FROM %s
  5429    RUN []
  5430      `, repoName)
  5431  
  5432  	name := "testtrustedbuild"
  5433  
  5434  	buildCmd := buildImageCmd(name, dockerFile, true)
  5435  	s.trustedCmd(buildCmd)
  5436  	out, _, err := runCommandWithOutput(buildCmd)
  5437  	if err != nil {
  5438  		c.Fatalf("Error running trusted build: %s\n%s", err, out)
  5439  	}
  5440  
  5441  	if !strings.Contains(out, fmt.Sprintf("FROM %s@sha", repoName[:len(repoName)-7])) {
  5442  		c.Fatalf("Unexpected output on trusted build:\n%s", out)
  5443  	}
  5444  
  5445  	// We should also have a tag reference for the image.
  5446  	if out, exitCode := dockerCmd(c, "inspect", repoName); exitCode != 0 {
  5447  		c.Fatalf("unexpected exit code inspecting image %q: %d: %s", repoName, exitCode, out)
  5448  	}
  5449  
  5450  	// We should now be able to remove the tag reference.
  5451  	if out, exitCode := dockerCmd(c, "rmi", repoName); exitCode != 0 {
  5452  		c.Fatalf("unexpected exit code inspecting image %q: %d: %s", repoName, exitCode, out)
  5453  	}
  5454  }
  5455  
  5456  func (s *DockerTrustSuite) TestTrustedBuildUntrustedTag(c *check.C) {
  5457  	repoName := fmt.Sprintf("%v/dockercli/build-untrusted-tag:latest", privateRegistryURL)
  5458  	dockerFile := fmt.Sprintf(`
  5459    FROM %s
  5460    RUN []
  5461      `, repoName)
  5462  
  5463  	name := "testtrustedbuilduntrustedtag"
  5464  
  5465  	buildCmd := buildImageCmd(name, dockerFile, true)
  5466  	s.trustedCmd(buildCmd)
  5467  	out, _, err := runCommandWithOutput(buildCmd)
  5468  	if err == nil {
  5469  		c.Fatalf("Expected error on trusted build with untrusted tag: %s\n%s", err, out)
  5470  	}
  5471  
  5472  	if !strings.Contains(out, "does not have trust data for") {
  5473  		c.Fatalf("Unexpected output on trusted build with untrusted tag:\n%s", out)
  5474  	}
  5475  }
  5476  
  5477  func (s *DockerTrustSuite) TestBuildContextDirIsSymlink(c *check.C) {
  5478  	testRequires(c, DaemonIsLinux)
  5479  	tempDir, err := ioutil.TempDir("", "test-build-dir-is-symlink-")
  5480  	c.Assert(err, check.IsNil)
  5481  	defer os.RemoveAll(tempDir)
  5482  
  5483  	// Make a real context directory in this temp directory with a simple
  5484  	// Dockerfile.
  5485  	realContextDirname := filepath.Join(tempDir, "context")
  5486  	if err := os.Mkdir(realContextDirname, os.FileMode(0755)); err != nil {
  5487  		c.Fatal(err)
  5488  	}
  5489  
  5490  	if err = ioutil.WriteFile(
  5491  		filepath.Join(realContextDirname, "Dockerfile"),
  5492  		[]byte(`
  5493  			FROM busybox
  5494  			RUN echo hello world
  5495  		`),
  5496  		os.FileMode(0644),
  5497  	); err != nil {
  5498  		c.Fatal(err)
  5499  	}
  5500  
  5501  	// Make a symlink to the real context directory.
  5502  	contextSymlinkName := filepath.Join(tempDir, "context_link")
  5503  	if err := os.Symlink(realContextDirname, contextSymlinkName); err != nil {
  5504  		c.Fatal(err)
  5505  	}
  5506  
  5507  	// Executing the build with the symlink as the specified context should
  5508  	// *not* fail.
  5509  	if out, exitStatus := dockerCmd(c, "build", contextSymlinkName); exitStatus != 0 {
  5510  		c.Fatalf("build failed with exit status %d: %s", exitStatus, out)
  5511  	}
  5512  }
  5513  
  5514  func (s *DockerTrustSuite) TestTrustedBuildTagFromReleasesRole(c *check.C) {
  5515  	testRequires(c, NotaryHosting)
  5516  
  5517  	latestTag := s.setupTrustedImage(c, "trusted-build-releases-role")
  5518  	repoName := strings.TrimSuffix(latestTag, ":latest")
  5519  
  5520  	// Now create the releases role
  5521  	s.notaryCreateDelegation(c, repoName, "targets/releases", s.not.keys[0].Public)
  5522  	s.notaryImportKey(c, repoName, "targets/releases", s.not.keys[0].Private)
  5523  	s.notaryPublish(c, repoName)
  5524  
  5525  	// push a different tag to the releases role
  5526  	otherTag := fmt.Sprintf("%s:other", repoName)
  5527  	dockerCmd(c, "tag", "busybox", otherTag)
  5528  
  5529  	pushCmd := exec.Command(dockerBinary, "push", otherTag)
  5530  	s.trustedCmd(pushCmd)
  5531  	out, _, err := runCommandWithOutput(pushCmd)
  5532  	c.Assert(err, check.IsNil, check.Commentf("Trusted push failed: %s", out))
  5533  	s.assertTargetInRoles(c, repoName, "other", "targets/releases")
  5534  	s.assertTargetNotInRoles(c, repoName, "other", "targets")
  5535  
  5536  	out, status := dockerCmd(c, "rmi", otherTag)
  5537  	c.Assert(status, check.Equals, 0, check.Commentf("docker rmi failed: %s", out))
  5538  
  5539  	dockerFile := fmt.Sprintf(`
  5540    FROM %s
  5541    RUN []
  5542      `, otherTag)
  5543  
  5544  	name := "testtrustedbuildreleasesrole"
  5545  
  5546  	buildCmd := buildImageCmd(name, dockerFile, true)
  5547  	s.trustedCmd(buildCmd)
  5548  	out, _, err = runCommandWithOutput(buildCmd)
  5549  	c.Assert(err, check.IsNil, check.Commentf("Trusted build failed: %s", out))
  5550  	c.Assert(out, checker.Contains, fmt.Sprintf("FROM %s@sha", repoName))
  5551  }
  5552  
  5553  func (s *DockerTrustSuite) TestTrustedBuildTagIgnoresOtherDelegationRoles(c *check.C) {
  5554  	testRequires(c, NotaryHosting)
  5555  
  5556  	latestTag := s.setupTrustedImage(c, "trusted-build-releases-role")
  5557  	repoName := strings.TrimSuffix(latestTag, ":latest")
  5558  
  5559  	// Now create a non-releases delegation role
  5560  	s.notaryCreateDelegation(c, repoName, "targets/other", s.not.keys[0].Public)
  5561  	s.notaryImportKey(c, repoName, "targets/other", s.not.keys[0].Private)
  5562  	s.notaryPublish(c, repoName)
  5563  
  5564  	// push a different tag to the other role
  5565  	otherTag := fmt.Sprintf("%s:other", repoName)
  5566  	dockerCmd(c, "tag", "busybox", otherTag)
  5567  
  5568  	pushCmd := exec.Command(dockerBinary, "push", otherTag)
  5569  	s.trustedCmd(pushCmd)
  5570  	out, _, err := runCommandWithOutput(pushCmd)
  5571  	c.Assert(err, check.IsNil, check.Commentf("Trusted push failed: %s", out))
  5572  	s.assertTargetInRoles(c, repoName, "other", "targets/other")
  5573  	s.assertTargetNotInRoles(c, repoName, "other", "targets")
  5574  
  5575  	out, status := dockerCmd(c, "rmi", otherTag)
  5576  	c.Assert(status, check.Equals, 0, check.Commentf("docker rmi failed: %s", out))
  5577  
  5578  	dockerFile := fmt.Sprintf(`
  5579    FROM %s
  5580    RUN []
  5581      `, otherTag)
  5582  
  5583  	name := "testtrustedbuildotherrole"
  5584  
  5585  	buildCmd := buildImageCmd(name, dockerFile, true)
  5586  	s.trustedCmd(buildCmd)
  5587  	out, _, err = runCommandWithOutput(buildCmd)
  5588  	c.Assert(err, check.NotNil, check.Commentf("Trusted build expected to fail: %s", out))
  5589  }
  5590  
  5591  // Issue #15634: COPY fails when path starts with "null"
  5592  func (s *DockerSuite) TestBuildNullStringInAddCopyVolume(c *check.C) {
  5593  	name := "testbuildnullstringinaddcopyvolume"
  5594  
  5595  	volName := "nullvolume"
  5596  
  5597  	if daemonPlatform == "windows" {
  5598  		volName = `C:\\nullvolume`
  5599  	}
  5600  
  5601  	ctx, err := fakeContext(`
  5602  		FROM busybox
  5603  
  5604  		ADD null /
  5605  		COPY nullfile /
  5606  		VOLUME `+volName+`
  5607  		`,
  5608  		map[string]string{
  5609  			"null":     "test1",
  5610  			"nullfile": "test2",
  5611  		},
  5612  	)
  5613  	c.Assert(err, check.IsNil)
  5614  	defer ctx.Close()
  5615  
  5616  	_, err = buildImageFromContext(name, ctx, true)
  5617  	c.Assert(err, check.IsNil)
  5618  }
  5619  
  5620  func (s *DockerSuite) TestBuildStopSignal(c *check.C) {
  5621  	testRequires(c, DaemonIsLinux) // Windows does not support STOPSIGNAL yet
  5622  	imgName := "test_build_stop_signal"
  5623  	_, err := buildImage(imgName,
  5624  		`FROM busybox
  5625  		 STOPSIGNAL SIGKILL`,
  5626  		true)
  5627  	c.Assert(err, check.IsNil)
  5628  	res := inspectFieldJSON(c, imgName, "Config.StopSignal")
  5629  	if res != `"SIGKILL"` {
  5630  		c.Fatalf("Signal %s, expected SIGKILL", res)
  5631  	}
  5632  
  5633  	containerName := "test-container-stop-signal"
  5634  	dockerCmd(c, "run", "-d", "--name", containerName, imgName, "top")
  5635  
  5636  	res = inspectFieldJSON(c, containerName, "Config.StopSignal")
  5637  	if res != `"SIGKILL"` {
  5638  		c.Fatalf("Signal %s, expected SIGKILL", res)
  5639  	}
  5640  }
  5641  
  5642  func (s *DockerSuite) TestBuildBuildTimeArg(c *check.C) {
  5643  	imgName := "bldargtest"
  5644  	envKey := "foo"
  5645  	envVal := "bar"
  5646  	args := []string{"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal)}
  5647  	var dockerfile string
  5648  	if daemonPlatform == "windows" {
  5649  		// Bugs in Windows busybox port - use the default base image and native cmd stuff
  5650  		dockerfile = fmt.Sprintf(`FROM `+minimalBaseImage()+`
  5651  			ARG %s
  5652  			RUN echo %%%s%%
  5653  			CMD setlocal enableextensions && if defined %s (echo %%%s%%)`, envKey, envKey, envKey, envKey)
  5654  	} else {
  5655  		dockerfile = fmt.Sprintf(`FROM busybox
  5656  			ARG %s
  5657  			RUN echo $%s
  5658  			CMD echo $%s`, envKey, envKey, envKey)
  5659  
  5660  	}
  5661  
  5662  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || !strings.Contains(out, envVal) {
  5663  		if err != nil {
  5664  			c.Fatalf("build failed to complete: %q %q", out, err)
  5665  		}
  5666  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envVal)
  5667  	}
  5668  
  5669  	containerName := "bldargCont"
  5670  	out, _ := dockerCmd(c, "run", "--name", containerName, imgName)
  5671  	out = strings.Trim(out, " \r\n'")
  5672  	if out != "" {
  5673  		c.Fatalf("run produced invalid output: %q, expected empty string", out)
  5674  	}
  5675  }
  5676  
  5677  func (s *DockerSuite) TestBuildBuildTimeArgHistory(c *check.C) {
  5678  	imgName := "bldargtest"
  5679  	envKey := "foo"
  5680  	envVal := "bar"
  5681  	envDef := "bar1"
  5682  	args := []string{
  5683  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5684  	}
  5685  	dockerfile := fmt.Sprintf(`FROM busybox
  5686  		ARG %s=%s`, envKey, envDef)
  5687  
  5688  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || !strings.Contains(out, envVal) {
  5689  		if err != nil {
  5690  			c.Fatalf("build failed to complete: %q %q", out, err)
  5691  		}
  5692  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envVal)
  5693  	}
  5694  
  5695  	out, _ := dockerCmd(c, "history", "--no-trunc", imgName)
  5696  	outputTabs := strings.Split(out, "\n")[1]
  5697  	if !strings.Contains(outputTabs, envDef) {
  5698  		c.Fatalf("failed to find arg default in image history output: %q expected: %q", outputTabs, envDef)
  5699  	}
  5700  }
  5701  
  5702  func (s *DockerSuite) TestBuildBuildTimeArgCacheHit(c *check.C) {
  5703  	imgName := "bldargtest"
  5704  	envKey := "foo"
  5705  	envVal := "bar"
  5706  	args := []string{
  5707  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5708  	}
  5709  	dockerfile := fmt.Sprintf(`FROM busybox
  5710  		ARG %s
  5711  		RUN echo $%s`, envKey, envKey)
  5712  
  5713  	origImgID := ""
  5714  	var err error
  5715  	if origImgID, err = buildImage(imgName, dockerfile, true, args...); err != nil {
  5716  		c.Fatal(err)
  5717  	}
  5718  
  5719  	imgNameCache := "bldargtestcachehit"
  5720  	if newImgID, err := buildImage(imgNameCache, dockerfile, true, args...); err != nil || newImgID != origImgID {
  5721  		if err != nil {
  5722  			c.Fatal(err)
  5723  		}
  5724  		c.Fatalf("build didn't use cache! expected image id: %q built image id: %q", origImgID, newImgID)
  5725  	}
  5726  }
  5727  
  5728  func (s *DockerSuite) TestBuildBuildTimeArgCacheMissExtraArg(c *check.C) {
  5729  	imgName := "bldargtest"
  5730  	envKey := "foo"
  5731  	envVal := "bar"
  5732  	extraEnvKey := "foo1"
  5733  	extraEnvVal := "bar1"
  5734  	args := []string{
  5735  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5736  	}
  5737  
  5738  	dockerfile := fmt.Sprintf(`FROM busybox
  5739  		ARG %s
  5740  		ARG %s
  5741  		RUN echo $%s`, envKey, extraEnvKey, envKey)
  5742  
  5743  	origImgID := ""
  5744  	var err error
  5745  	if origImgID, err = buildImage(imgName, dockerfile, true, args...); err != nil {
  5746  		c.Fatal(err)
  5747  	}
  5748  
  5749  	imgNameCache := "bldargtestcachemiss"
  5750  	args = append(args, "--build-arg", fmt.Sprintf("%s=%s", extraEnvKey, extraEnvVal))
  5751  	if newImgID, err := buildImage(imgNameCache, dockerfile, true, args...); err != nil || newImgID == origImgID {
  5752  		if err != nil {
  5753  			c.Fatal(err)
  5754  		}
  5755  		c.Fatalf("build used cache, expected a miss!")
  5756  	}
  5757  }
  5758  
  5759  func (s *DockerSuite) TestBuildBuildTimeArgCacheMissSameArgDiffVal(c *check.C) {
  5760  	imgName := "bldargtest"
  5761  	envKey := "foo"
  5762  	envVal := "bar"
  5763  	newEnvVal := "bar1"
  5764  	args := []string{
  5765  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5766  	}
  5767  
  5768  	dockerfile := fmt.Sprintf(`FROM busybox
  5769  		ARG %s
  5770  		RUN echo $%s`, envKey, envKey)
  5771  
  5772  	origImgID := ""
  5773  	var err error
  5774  	if origImgID, err = buildImage(imgName, dockerfile, true, args...); err != nil {
  5775  		c.Fatal(err)
  5776  	}
  5777  
  5778  	imgNameCache := "bldargtestcachemiss"
  5779  	args = []string{
  5780  		"--build-arg", fmt.Sprintf("%s=%s", envKey, newEnvVal),
  5781  	}
  5782  	if newImgID, err := buildImage(imgNameCache, dockerfile, true, args...); err != nil || newImgID == origImgID {
  5783  		if err != nil {
  5784  			c.Fatal(err)
  5785  		}
  5786  		c.Fatalf("build used cache, expected a miss!")
  5787  	}
  5788  }
  5789  
  5790  func (s *DockerSuite) TestBuildBuildTimeArgOverrideArgDefinedBeforeEnv(c *check.C) {
  5791  	testRequires(c, DaemonIsLinux) // Windows does not support ARG
  5792  	imgName := "bldargtest"
  5793  	envKey := "foo"
  5794  	envVal := "bar"
  5795  	envValOveride := "barOverride"
  5796  	args := []string{
  5797  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5798  	}
  5799  	dockerfile := fmt.Sprintf(`FROM busybox
  5800  		ARG %s
  5801  		ENV %s %s
  5802  		RUN echo $%s
  5803  		CMD echo $%s
  5804          `, envKey, envKey, envValOveride, envKey, envKey)
  5805  
  5806  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 2 {
  5807  		if err != nil {
  5808  			c.Fatalf("build failed to complete: %q %q", out, err)
  5809  		}
  5810  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  5811  	}
  5812  
  5813  	containerName := "bldargCont"
  5814  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  5815  		c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  5816  	}
  5817  }
  5818  
  5819  func (s *DockerSuite) TestBuildBuildTimeArgOverrideEnvDefinedBeforeArg(c *check.C) {
  5820  	testRequires(c, DaemonIsLinux) // Windows does not support ARG
  5821  	imgName := "bldargtest"
  5822  	envKey := "foo"
  5823  	envVal := "bar"
  5824  	envValOveride := "barOverride"
  5825  	args := []string{
  5826  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5827  	}
  5828  	dockerfile := fmt.Sprintf(`FROM busybox
  5829  		ENV %s %s
  5830  		ARG %s
  5831  		RUN echo $%s
  5832  		CMD echo $%s
  5833          `, envKey, envValOveride, envKey, envKey, envKey)
  5834  
  5835  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 2 {
  5836  		if err != nil {
  5837  			c.Fatalf("build failed to complete: %q %q", out, err)
  5838  		}
  5839  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  5840  	}
  5841  
  5842  	containerName := "bldargCont"
  5843  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  5844  		c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  5845  	}
  5846  }
  5847  
  5848  func (s *DockerSuite) TestBuildBuildTimeArgExpansion(c *check.C) {
  5849  	testRequires(c, DaemonIsLinux) // Windows does not support ARG
  5850  	imgName := "bldvarstest"
  5851  
  5852  	wdVar := "WDIR"
  5853  	wdVal := "/tmp/"
  5854  	addVar := "AFILE"
  5855  	addVal := "addFile"
  5856  	copyVar := "CFILE"
  5857  	copyVal := "copyFile"
  5858  	envVar := "foo"
  5859  	envVal := "bar"
  5860  	exposeVar := "EPORT"
  5861  	exposeVal := "9999"
  5862  	userVar := "USER"
  5863  	userVal := "testUser"
  5864  	volVar := "VOL"
  5865  	volVal := "/testVol/"
  5866  	args := []string{
  5867  		"--build-arg", fmt.Sprintf("%s=%s", wdVar, wdVal),
  5868  		"--build-arg", fmt.Sprintf("%s=%s", addVar, addVal),
  5869  		"--build-arg", fmt.Sprintf("%s=%s", copyVar, copyVal),
  5870  		"--build-arg", fmt.Sprintf("%s=%s", envVar, envVal),
  5871  		"--build-arg", fmt.Sprintf("%s=%s", exposeVar, exposeVal),
  5872  		"--build-arg", fmt.Sprintf("%s=%s", userVar, userVal),
  5873  		"--build-arg", fmt.Sprintf("%s=%s", volVar, volVal),
  5874  	}
  5875  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  5876  		ARG %s
  5877  		WORKDIR ${%s}
  5878  		ARG %s
  5879  		ADD ${%s} testDir/
  5880  		ARG %s
  5881  		COPY $%s testDir/
  5882  		ARG %s
  5883  		ENV %s=${%s}
  5884  		ARG %s
  5885  		EXPOSE $%s
  5886  		ARG %s
  5887  		USER $%s
  5888  		ARG %s
  5889  		VOLUME ${%s}`,
  5890  		wdVar, wdVar, addVar, addVar, copyVar, copyVar, envVar, envVar,
  5891  		envVar, exposeVar, exposeVar, userVar, userVar, volVar, volVar),
  5892  		map[string]string{
  5893  			addVal:  "some stuff",
  5894  			copyVal: "some stuff",
  5895  		})
  5896  	if err != nil {
  5897  		c.Fatal(err)
  5898  	}
  5899  	defer ctx.Close()
  5900  
  5901  	if _, err := buildImageFromContext(imgName, ctx, true, args...); err != nil {
  5902  		c.Fatal(err)
  5903  	}
  5904  
  5905  	var resMap map[string]interface{}
  5906  	var resArr []string
  5907  	res := ""
  5908  	res = inspectField(c, imgName, "Config.WorkingDir")
  5909  	if res != filepath.ToSlash(filepath.Clean(wdVal)) {
  5910  		c.Fatalf("Config.WorkingDir value mismatch. Expected: %s, got: %s", filepath.ToSlash(filepath.Clean(wdVal)), res)
  5911  	}
  5912  
  5913  	inspectFieldAndMarshall(c, imgName, "Config.Env", &resArr)
  5914  
  5915  	found := false
  5916  	for _, v := range resArr {
  5917  		if fmt.Sprintf("%s=%s", envVar, envVal) == v {
  5918  			found = true
  5919  			break
  5920  		}
  5921  	}
  5922  	if !found {
  5923  		c.Fatalf("Config.Env value mismatch. Expected <key=value> to exist: %s=%s, got: %v",
  5924  			envVar, envVal, resArr)
  5925  	}
  5926  
  5927  	inspectFieldAndMarshall(c, imgName, "Config.ExposedPorts", &resMap)
  5928  	if _, ok := resMap[fmt.Sprintf("%s/tcp", exposeVal)]; !ok {
  5929  		c.Fatalf("Config.ExposedPorts value mismatch. Expected exposed port: %s/tcp, got: %v", exposeVal, resMap)
  5930  	}
  5931  
  5932  	res = inspectField(c, imgName, "Config.User")
  5933  	if res != userVal {
  5934  		c.Fatalf("Config.User value mismatch. Expected: %s, got: %s", userVal, res)
  5935  	}
  5936  
  5937  	inspectFieldAndMarshall(c, imgName, "Config.Volumes", &resMap)
  5938  	if _, ok := resMap[volVal]; !ok {
  5939  		c.Fatalf("Config.Volumes value mismatch. Expected volume: %s, got: %v", volVal, resMap)
  5940  	}
  5941  }
  5942  
  5943  func (s *DockerSuite) TestBuildBuildTimeArgExpansionOverride(c *check.C) {
  5944  	testRequires(c, DaemonIsLinux) // Windows does not support ARG
  5945  	imgName := "bldvarstest"
  5946  	envKey := "foo"
  5947  	envVal := "bar"
  5948  	envKey1 := "foo1"
  5949  	envValOveride := "barOverride"
  5950  	args := []string{
  5951  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5952  	}
  5953  	dockerfile := fmt.Sprintf(`FROM busybox
  5954  		ARG %s
  5955  		ENV %s %s
  5956  		ENV %s ${%s}
  5957  		RUN echo $%s
  5958  		CMD echo $%s`, envKey, envKey, envValOveride, envKey1, envKey, envKey1, envKey1)
  5959  
  5960  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 2 {
  5961  		if err != nil {
  5962  			c.Fatalf("build failed to complete: %q %q", out, err)
  5963  		}
  5964  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  5965  	}
  5966  
  5967  	containerName := "bldargCont"
  5968  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  5969  		c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  5970  	}
  5971  }
  5972  
  5973  func (s *DockerSuite) TestBuildBuildTimeArgUntrustedDefinedAfterUse(c *check.C) {
  5974  	testRequires(c, DaemonIsLinux) // Windows does not support ARG
  5975  	imgName := "bldargtest"
  5976  	envKey := "foo"
  5977  	envVal := "bar"
  5978  	args := []string{
  5979  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5980  	}
  5981  	dockerfile := fmt.Sprintf(`FROM busybox
  5982  		RUN echo $%s
  5983  		ARG %s
  5984  		CMD echo $%s`, envKey, envKey, envKey)
  5985  
  5986  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Contains(out, envVal) {
  5987  		if err != nil {
  5988  			c.Fatalf("build failed to complete: %q %q", out, err)
  5989  		}
  5990  		c.Fatalf("able to access environment variable in output: %q expected to be missing", out)
  5991  	}
  5992  
  5993  	containerName := "bldargCont"
  5994  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); out != "\n" {
  5995  		c.Fatalf("run produced invalid output: %q, expected empty string", out)
  5996  	}
  5997  }
  5998  
  5999  func (s *DockerSuite) TestBuildBuildTimeArgBuiltinArg(c *check.C) {
  6000  	testRequires(c, DaemonIsLinux) // Windows does not support --build-arg
  6001  	imgName := "bldargtest"
  6002  	envKey := "HTTP_PROXY"
  6003  	envVal := "bar"
  6004  	args := []string{
  6005  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6006  	}
  6007  	dockerfile := fmt.Sprintf(`FROM busybox
  6008  		RUN echo $%s
  6009  		CMD echo $%s`, envKey, envKey)
  6010  
  6011  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || !strings.Contains(out, envVal) {
  6012  		if err != nil {
  6013  			c.Fatalf("build failed to complete: %q %q", out, err)
  6014  		}
  6015  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envVal)
  6016  	}
  6017  
  6018  	containerName := "bldargCont"
  6019  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); out != "\n" {
  6020  		c.Fatalf("run produced invalid output: %q, expected empty string", out)
  6021  	}
  6022  }
  6023  
  6024  func (s *DockerSuite) TestBuildBuildTimeArgDefaultOverride(c *check.C) {
  6025  	testRequires(c, DaemonIsLinux) // Windows does not support ARG
  6026  	imgName := "bldargtest"
  6027  	envKey := "foo"
  6028  	envVal := "bar"
  6029  	envValOveride := "barOverride"
  6030  	args := []string{
  6031  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envValOveride),
  6032  	}
  6033  	dockerfile := fmt.Sprintf(`FROM busybox
  6034  		ARG %s=%s
  6035  		ENV %s $%s
  6036  		RUN echo $%s
  6037  		CMD echo $%s`, envKey, envVal, envKey, envKey, envKey, envKey)
  6038  
  6039  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 1 {
  6040  		if err != nil {
  6041  			c.Fatalf("build failed to complete: %q %q", out, err)
  6042  		}
  6043  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  6044  	}
  6045  
  6046  	containerName := "bldargCont"
  6047  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  6048  		c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  6049  	}
  6050  }
  6051  
  6052  func (s *DockerSuite) TestBuildBuildTimeArgUnconsumedArg(c *check.C) {
  6053  	imgName := "bldargtest"
  6054  	envKey := "foo"
  6055  	envVal := "bar"
  6056  	args := []string{
  6057  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6058  	}
  6059  	dockerfile := fmt.Sprintf(`FROM busybox
  6060  		RUN echo $%s
  6061  		CMD echo $%s`, envKey, envKey)
  6062  
  6063  	warnStr := "[Warning] One or more build-args"
  6064  
  6065  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); !strings.Contains(out, warnStr) {
  6066  		c.Fatalf("build completed without warning: %q %q", out, err)
  6067  	} else if err != nil {
  6068  		c.Fatalf("build failed to complete: %q %q", out, err)
  6069  	}
  6070  
  6071  }
  6072  
  6073  func (s *DockerSuite) TestBuildBuildTimeArgEnv(c *check.C) {
  6074  	testRequires(c, DaemonIsLinux) // Windows does not support ARG
  6075  	args := []string{
  6076  		"build",
  6077  		"--build-arg", fmt.Sprintf("FOO1=fromcmd"),
  6078  		"--build-arg", fmt.Sprintf("FOO2="),
  6079  		"--build-arg", fmt.Sprintf("FOO3"), // set in env
  6080  		"--build-arg", fmt.Sprintf("FOO4"), // not set in env
  6081  		"--build-arg", fmt.Sprintf("FOO5=fromcmd"),
  6082  		// FOO6 is not set at all
  6083  		"--build-arg", fmt.Sprintf("FOO7=fromcmd"), // should produce a warning
  6084  		"--build-arg", fmt.Sprintf("FOO8="), // should produce a warning
  6085  		"--build-arg", fmt.Sprintf("FOO9"), // should produce a warning
  6086  		".",
  6087  	}
  6088  
  6089  	dockerfile := fmt.Sprintf(`FROM busybox
  6090  		ARG FOO1=fromfile
  6091  		ARG FOO2=fromfile
  6092  		ARG FOO3=fromfile
  6093  		ARG FOO4=fromfile
  6094  		ARG FOO5
  6095  		ARG FOO6
  6096  		RUN env
  6097  		RUN [ "$FOO1" == "fromcmd" ]
  6098  		RUN [ "$FOO2" == "" ]
  6099  		RUN [ "$FOO3" == "fromenv" ]
  6100  		RUN [ "$FOO4" == "fromfile" ]
  6101  		RUN [ "$FOO5" == "fromcmd" ]
  6102  		# The following should not exist at all in the env
  6103  		RUN [ "$(env | grep FOO6)" == "" ]
  6104  		RUN [ "$(env | grep FOO7)" == "" ]
  6105  		RUN [ "$(env | grep FOO8)" == "" ]
  6106  		RUN [ "$(env | grep FOO9)" == "" ]
  6107  	    `)
  6108  
  6109  	ctx, err := fakeContext(dockerfile, nil)
  6110  	c.Assert(err, check.IsNil)
  6111  	defer ctx.Close()
  6112  
  6113  	cmd := exec.Command(dockerBinary, args...)
  6114  	cmd.Dir = ctx.Dir
  6115  	cmd.Env = append(os.Environ(),
  6116  		"FOO1=fromenv",
  6117  		"FOO2=fromenv",
  6118  		"FOO3=fromenv")
  6119  	out, _, err := runCommandWithOutput(cmd)
  6120  	if err != nil {
  6121  		c.Fatal(err, out)
  6122  	}
  6123  
  6124  	// Now check to make sure we got a warning msg about unused build-args
  6125  	i := strings.Index(out, "[Warning]")
  6126  	if i < 0 {
  6127  		c.Fatalf("Missing the build-arg warning in %q", out)
  6128  	}
  6129  
  6130  	out = out[i:] // "out" should contain just the warning message now
  6131  
  6132  	// These were specified on a --build-arg but no ARG was in the Dockerfile
  6133  	c.Assert(out, checker.Contains, "FOO7")
  6134  	c.Assert(out, checker.Contains, "FOO8")
  6135  	c.Assert(out, checker.Contains, "FOO9")
  6136  }
  6137  
  6138  func (s *DockerSuite) TestBuildBuildTimeArgQuotedValVariants(c *check.C) {
  6139  	imgName := "bldargtest"
  6140  	envKey := "foo"
  6141  	envKey1 := "foo1"
  6142  	envKey2 := "foo2"
  6143  	envKey3 := "foo3"
  6144  	args := []string{}
  6145  	dockerfile := fmt.Sprintf(`FROM busybox
  6146  		ARG %s=""
  6147  		ARG %s=''
  6148  		ARG %s="''"
  6149  		ARG %s='""'
  6150  		RUN [ "$%s" != "$%s" ]
  6151  		RUN [ "$%s" != "$%s" ]
  6152  		RUN [ "$%s" != "$%s" ]
  6153  		RUN [ "$%s" != "$%s" ]
  6154  		RUN [ "$%s" != "$%s" ]`, envKey, envKey1, envKey2, envKey3,
  6155  		envKey, envKey2, envKey, envKey3, envKey1, envKey2, envKey1, envKey3,
  6156  		envKey2, envKey3)
  6157  
  6158  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil {
  6159  		c.Fatalf("build failed to complete: %q %q", out, err)
  6160  	}
  6161  }
  6162  
  6163  func (s *DockerSuite) TestBuildBuildTimeArgEmptyValVariants(c *check.C) {
  6164  	testRequires(c, DaemonIsLinux) // Windows does not support ARG
  6165  	imgName := "bldargtest"
  6166  	envKey := "foo"
  6167  	envKey1 := "foo1"
  6168  	envKey2 := "foo2"
  6169  	args := []string{}
  6170  	dockerfile := fmt.Sprintf(`FROM busybox
  6171  		ARG %s=
  6172  		ARG %s=""
  6173  		ARG %s=''
  6174  		RUN [ "$%s" == "$%s" ]
  6175  		RUN [ "$%s" == "$%s" ]
  6176  		RUN [ "$%s" == "$%s" ]`, envKey, envKey1, envKey2, envKey, envKey1, envKey1, envKey2, envKey, envKey2)
  6177  
  6178  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil {
  6179  		c.Fatalf("build failed to complete: %q %q", out, err)
  6180  	}
  6181  }
  6182  
  6183  func (s *DockerSuite) TestBuildBuildTimeArgDefintionWithNoEnvInjection(c *check.C) {
  6184  	imgName := "bldargtest"
  6185  	envKey := "foo"
  6186  	args := []string{}
  6187  	dockerfile := fmt.Sprintf(`FROM busybox
  6188  		ARG %s
  6189  		RUN env`, envKey)
  6190  
  6191  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envKey) != 1 {
  6192  		if err != nil {
  6193  			c.Fatalf("build failed to complete: %q %q", out, err)
  6194  		}
  6195  		c.Fatalf("unexpected number of occurrences of the arg in output: %q expected: 1", out)
  6196  	}
  6197  }
  6198  
  6199  func (s *DockerSuite) TestBuildNoNamedVolume(c *check.C) {
  6200  	volName := "testname:/foo"
  6201  
  6202  	if daemonPlatform == "windows" {
  6203  		volName = "testname:C:\\foo"
  6204  	}
  6205  	dockerCmd(c, "run", "-v", volName, "busybox", "sh", "-c", "touch /foo/oops")
  6206  
  6207  	dockerFile := `FROM busybox
  6208  	VOLUME ` + volName + `
  6209  	RUN ls /foo/oops
  6210  	`
  6211  	_, err := buildImage("test", dockerFile, false)
  6212  	c.Assert(err, check.NotNil, check.Commentf("image build should have failed"))
  6213  }
  6214  
  6215  func (s *DockerSuite) TestBuildTagEvent(c *check.C) {
  6216  	since := daemonUnixTime(c)
  6217  
  6218  	dockerFile := `FROM busybox
  6219  	RUN echo events
  6220  	`
  6221  	_, err := buildImage("test", dockerFile, false)
  6222  	c.Assert(err, check.IsNil)
  6223  
  6224  	until := daemonUnixTime(c)
  6225  	out, _ := dockerCmd(c, "events", "--since", since, "--until", until, "--filter", "type=image")
  6226  	events := strings.Split(strings.TrimSpace(out), "\n")
  6227  	actions := eventActionsByIDAndType(c, events, "test:latest", "image")
  6228  	var foundTag bool
  6229  	for _, a := range actions {
  6230  		if a == "tag" {
  6231  			foundTag = true
  6232  			break
  6233  		}
  6234  	}
  6235  
  6236  	c.Assert(foundTag, checker.True, check.Commentf("No tag event found:\n%s", out))
  6237  }
  6238  
  6239  // #15780
  6240  func (s *DockerSuite) TestBuildMultipleTags(c *check.C) {
  6241  	dockerfile := `
  6242  	FROM busybox
  6243  	MAINTAINER test-15780
  6244  	`
  6245  	cmd := exec.Command(dockerBinary, "build", "-t", "tag1", "-t", "tag2:v2",
  6246  		"-t", "tag1:latest", "-t", "tag1", "--no-cache", "-")
  6247  	cmd.Stdin = strings.NewReader(dockerfile)
  6248  	_, err := runCommand(cmd)
  6249  	c.Assert(err, check.IsNil)
  6250  
  6251  	id1, err := getIDByName("tag1")
  6252  	c.Assert(err, check.IsNil)
  6253  	id2, err := getIDByName("tag2:v2")
  6254  	c.Assert(err, check.IsNil)
  6255  	c.Assert(id1, check.Equals, id2)
  6256  }
  6257  
  6258  // #17290
  6259  func (s *DockerSuite) TestBuildCacheBrokenSymlink(c *check.C) {
  6260  	name := "testbuildbrokensymlink"
  6261  	ctx, err := fakeContext(`
  6262  	FROM busybox
  6263  	COPY . ./`,
  6264  		map[string]string{
  6265  			"foo": "bar",
  6266  		})
  6267  	c.Assert(err, checker.IsNil)
  6268  	defer ctx.Close()
  6269  
  6270  	err = os.Symlink(filepath.Join(ctx.Dir, "nosuchfile"), filepath.Join(ctx.Dir, "asymlink"))
  6271  	c.Assert(err, checker.IsNil)
  6272  
  6273  	// warm up cache
  6274  	_, err = buildImageFromContext(name, ctx, true)
  6275  	c.Assert(err, checker.IsNil)
  6276  
  6277  	// add new file to context, should invalidate cache
  6278  	err = ioutil.WriteFile(filepath.Join(ctx.Dir, "newfile"), []byte("foo"), 0644)
  6279  	c.Assert(err, checker.IsNil)
  6280  
  6281  	_, out, err := buildImageFromContextWithOut(name, ctx, true)
  6282  	c.Assert(err, checker.IsNil)
  6283  
  6284  	c.Assert(out, checker.Not(checker.Contains), "Using cache")
  6285  
  6286  }
  6287  
  6288  func (s *DockerSuite) TestBuildFollowSymlinkToFile(c *check.C) {
  6289  	name := "testbuildbrokensymlink"
  6290  	ctx, err := fakeContext(`
  6291  	FROM busybox
  6292  	COPY asymlink target`,
  6293  		map[string]string{
  6294  			"foo": "bar",
  6295  		})
  6296  	c.Assert(err, checker.IsNil)
  6297  	defer ctx.Close()
  6298  
  6299  	err = os.Symlink("foo", filepath.Join(ctx.Dir, "asymlink"))
  6300  	c.Assert(err, checker.IsNil)
  6301  
  6302  	id, err := buildImageFromContext(name, ctx, true)
  6303  	c.Assert(err, checker.IsNil)
  6304  
  6305  	out, _ := dockerCmd(c, "run", "--rm", id, "cat", "target")
  6306  	c.Assert(out, checker.Matches, "bar")
  6307  
  6308  	// change target file should invalidate cache
  6309  	err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("baz"), 0644)
  6310  	c.Assert(err, checker.IsNil)
  6311  
  6312  	id, out, err = buildImageFromContextWithOut(name, ctx, true)
  6313  	c.Assert(err, checker.IsNil)
  6314  	c.Assert(out, checker.Not(checker.Contains), "Using cache")
  6315  
  6316  	out, _ = dockerCmd(c, "run", "--rm", id, "cat", "target")
  6317  	c.Assert(out, checker.Matches, "baz")
  6318  }
  6319  
  6320  func (s *DockerSuite) TestBuildFollowSymlinkToDir(c *check.C) {
  6321  	name := "testbuildbrokensymlink"
  6322  	ctx, err := fakeContext(`
  6323  	FROM busybox
  6324  	COPY asymlink /`,
  6325  		map[string]string{
  6326  			"foo/abc": "bar",
  6327  			"foo/def": "baz",
  6328  		})
  6329  	c.Assert(err, checker.IsNil)
  6330  	defer ctx.Close()
  6331  
  6332  	err = os.Symlink("foo", filepath.Join(ctx.Dir, "asymlink"))
  6333  	c.Assert(err, checker.IsNil)
  6334  
  6335  	id, err := buildImageFromContext(name, ctx, true)
  6336  	c.Assert(err, checker.IsNil)
  6337  
  6338  	out, _ := dockerCmd(c, "run", "--rm", id, "cat", "abc", "def")
  6339  	c.Assert(out, checker.Matches, "barbaz")
  6340  
  6341  	// change target file should invalidate cache
  6342  	err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo/def"), []byte("bax"), 0644)
  6343  	c.Assert(err, checker.IsNil)
  6344  
  6345  	id, out, err = buildImageFromContextWithOut(name, ctx, true)
  6346  	c.Assert(err, checker.IsNil)
  6347  	c.Assert(out, checker.Not(checker.Contains), "Using cache")
  6348  
  6349  	out, _ = dockerCmd(c, "run", "--rm", id, "cat", "abc", "def")
  6350  	c.Assert(out, checker.Matches, "barbax")
  6351  
  6352  }
  6353  
  6354  // TestBuildSymlinkBasename tests that target file gets basename from symlink,
  6355  // not from the target file.
  6356  func (s *DockerSuite) TestBuildSymlinkBasename(c *check.C) {
  6357  	name := "testbuildbrokensymlink"
  6358  	ctx, err := fakeContext(`
  6359  	FROM busybox
  6360  	COPY asymlink /`,
  6361  		map[string]string{
  6362  			"foo": "bar",
  6363  		})
  6364  	c.Assert(err, checker.IsNil)
  6365  	defer ctx.Close()
  6366  
  6367  	err = os.Symlink("foo", filepath.Join(ctx.Dir, "asymlink"))
  6368  	c.Assert(err, checker.IsNil)
  6369  
  6370  	id, err := buildImageFromContext(name, ctx, true)
  6371  	c.Assert(err, checker.IsNil)
  6372  
  6373  	out, _ := dockerCmd(c, "run", "--rm", id, "cat", "asymlink")
  6374  	c.Assert(out, checker.Matches, "bar")
  6375  
  6376  }
  6377  
  6378  // #17827
  6379  func (s *DockerSuite) TestBuildCacheRootSource(c *check.C) {
  6380  	name := "testbuildrootsource"
  6381  	ctx, err := fakeContext(`
  6382  	FROM busybox
  6383  	COPY / /data`,
  6384  		map[string]string{
  6385  			"foo": "bar",
  6386  		})
  6387  	c.Assert(err, checker.IsNil)
  6388  	defer ctx.Close()
  6389  
  6390  	// warm up cache
  6391  	_, err = buildImageFromContext(name, ctx, true)
  6392  	c.Assert(err, checker.IsNil)
  6393  
  6394  	// change file, should invalidate cache
  6395  	err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("baz"), 0644)
  6396  	c.Assert(err, checker.IsNil)
  6397  
  6398  	_, out, err := buildImageFromContextWithOut(name, ctx, true)
  6399  	c.Assert(err, checker.IsNil)
  6400  
  6401  	c.Assert(out, checker.Not(checker.Contains), "Using cache")
  6402  }
  6403  
  6404  // #19375
  6405  func (s *DockerSuite) TestBuildFailsGitNotCallable(c *check.C) {
  6406  	cmd := exec.Command(dockerBinary, "build", "github.com/docker/v1.10-migrator.git")
  6407  	cmd.Env = append(cmd.Env, "PATH=")
  6408  	out, _, err := runCommandWithOutput(cmd)
  6409  	c.Assert(err, checker.NotNil)
  6410  	c.Assert(out, checker.Contains, "unable to prepare context: unable to find 'git': ")
  6411  
  6412  	cmd = exec.Command(dockerBinary, "build", "https://github.com/docker/v1.10-migrator.git")
  6413  	cmd.Env = append(cmd.Env, "PATH=")
  6414  	out, _, err = runCommandWithOutput(cmd)
  6415  	c.Assert(err, checker.NotNil)
  6416  	c.Assert(out, checker.Contains, "unable to prepare context: unable to find 'git': ")
  6417  }
  6418  
  6419  // TestBuildWorkdirWindowsPath tests that a Windows style path works as a workdir
  6420  func (s *DockerSuite) TestBuildWorkdirWindowsPath(c *check.C) {
  6421  	testRequires(c, DaemonIsWindows)
  6422  	name := "testbuildworkdirwindowspath"
  6423  
  6424  	_, err := buildImage(name, `
  6425  	FROM `+WindowsBaseImage+`
  6426  	RUN mkdir C:\\work
  6427  	WORKDIR C:\\work
  6428  	RUN if "%CD%" NEQ "C:\work" exit -1
  6429  	`, true)
  6430  
  6431  	if err != nil {
  6432  		c.Fatal(err)
  6433  	}
  6434  }
  6435  
  6436  func (s *DockerSuite) TestBuildLabel(c *check.C) {
  6437  	name := "testbuildlabel"
  6438  	testLabel := "foo"
  6439  
  6440  	_, err := buildImage(name, `
  6441    FROM `+minimalBaseImage()+`
  6442    LABEL default foo
  6443  `, false, "--label", testLabel)
  6444  
  6445  	c.Assert(err, checker.IsNil)
  6446  
  6447  	res := inspectFieldJSON(c, name, "Config.Labels")
  6448  
  6449  	var labels map[string]string
  6450  
  6451  	if err := json.Unmarshal([]byte(res), &labels); err != nil {
  6452  		c.Fatal(err)
  6453  	}
  6454  
  6455  	if _, ok := labels[testLabel]; !ok {
  6456  		c.Fatal("label not found in image")
  6457  	}
  6458  }
  6459  
  6460  func (s *DockerSuite) TestBuildLabelOneNode(c *check.C) {
  6461  	name := "testbuildlabel"
  6462  
  6463  	_, err := buildImage(name, "FROM busybox", false, "--label", "foo=bar")
  6464  
  6465  	c.Assert(err, checker.IsNil)
  6466  
  6467  	res, err := inspectImage(name, "json .Config.Labels")
  6468  	c.Assert(err, checker.IsNil)
  6469  	var labels map[string]string
  6470  
  6471  	if err := json.Unmarshal([]byte(res), &labels); err != nil {
  6472  		c.Fatal(err)
  6473  	}
  6474  
  6475  	v, ok := labels["foo"]
  6476  	if !ok {
  6477  		c.Fatal("label `foo` not found in image")
  6478  	}
  6479  	c.Assert(v, checker.Equals, "bar")
  6480  }
  6481  
  6482  func (s *DockerSuite) TestBuildLabelCacheCommit(c *check.C) {
  6483  	name := "testbuildlabelcachecommit"
  6484  	testLabel := "foo"
  6485  
  6486  	if _, err := buildImage(name, `
  6487    FROM `+minimalBaseImage()+`
  6488    LABEL default foo
  6489    `, false); err != nil {
  6490  		c.Fatal(err)
  6491  	}
  6492  
  6493  	_, err := buildImage(name, `
  6494    FROM `+minimalBaseImage()+`
  6495    LABEL default foo
  6496  `, true, "--label", testLabel)
  6497  
  6498  	c.Assert(err, checker.IsNil)
  6499  
  6500  	res := inspectFieldJSON(c, name, "Config.Labels")
  6501  
  6502  	var labels map[string]string
  6503  
  6504  	if err := json.Unmarshal([]byte(res), &labels); err != nil {
  6505  		c.Fatal(err)
  6506  	}
  6507  
  6508  	if _, ok := labels[testLabel]; !ok {
  6509  		c.Fatal("label not found in image")
  6510  	}
  6511  }
  6512  
  6513  func (s *DockerSuite) TestBuildLabelMultiple(c *check.C) {
  6514  	name := "testbuildlabelmultiple"
  6515  	testLabels := map[string]string{
  6516  		"foo": "bar",
  6517  		"123": "456",
  6518  	}
  6519  
  6520  	labelArgs := []string{}
  6521  
  6522  	for k, v := range testLabels {
  6523  		labelArgs = append(labelArgs, "--label", k+"="+v)
  6524  	}
  6525  
  6526  	_, err := buildImage(name, `
  6527    FROM `+minimalBaseImage()+`
  6528    LABEL default foo
  6529  `, false, labelArgs...)
  6530  
  6531  	if err != nil {
  6532  		c.Fatal("error building image with labels", err)
  6533  	}
  6534  
  6535  	res := inspectFieldJSON(c, name, "Config.Labels")
  6536  
  6537  	var labels map[string]string
  6538  
  6539  	if err := json.Unmarshal([]byte(res), &labels); err != nil {
  6540  		c.Fatal(err)
  6541  	}
  6542  
  6543  	for k, v := range testLabels {
  6544  		if x, ok := labels[k]; !ok || x != v {
  6545  			c.Fatalf("label %s=%s not found in image", k, v)
  6546  		}
  6547  	}
  6548  }
  6549  
  6550  func (s *DockerSuite) TestBuildLabelOverwrite(c *check.C) {
  6551  	name := "testbuildlabeloverwrite"
  6552  	testLabel := "foo"
  6553  	testValue := "bar"
  6554  
  6555  	_, err := buildImage(name, `
  6556    FROM `+minimalBaseImage()+`
  6557    LABEL `+testLabel+`+ foo
  6558  `, false, []string{"--label", testLabel + "=" + testValue}...)
  6559  
  6560  	if err != nil {
  6561  		c.Fatal("error building image with labels", err)
  6562  	}
  6563  
  6564  	res := inspectFieldJSON(c, name, "Config.Labels")
  6565  
  6566  	var labels map[string]string
  6567  
  6568  	if err := json.Unmarshal([]byte(res), &labels); err != nil {
  6569  		c.Fatal(err)
  6570  	}
  6571  
  6572  	v, ok := labels[testLabel]
  6573  	if !ok {
  6574  		c.Fatal("label not found in image")
  6575  	}
  6576  
  6577  	if v != testValue {
  6578  		c.Fatal("label not overwritten")
  6579  	}
  6580  }
  6581  
  6582  func (s *DockerRegistryAuthHtpasswdSuite) TestBuildFromAuthenticatedRegistry(c *check.C) {
  6583  	dockerCmd(c, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
  6584  
  6585  	baseImage := privateRegistryURL + "/baseimage"
  6586  
  6587  	_, err := buildImage(baseImage, `
  6588  	FROM busybox
  6589  	ENV env1 val1
  6590  	`, true)
  6591  
  6592  	c.Assert(err, checker.IsNil)
  6593  
  6594  	dockerCmd(c, "push", baseImage)
  6595  	dockerCmd(c, "rmi", baseImage)
  6596  
  6597  	_, err = buildImage(baseImage, fmt.Sprintf(`
  6598  	FROM %s
  6599  	ENV env2 val2
  6600  	`, baseImage), true)
  6601  
  6602  	c.Assert(err, checker.IsNil)
  6603  }
  6604  
  6605  func (s *DockerRegistryAuthHtpasswdSuite) TestBuildWithExternalAuth(c *check.C) {
  6606  	osPath := os.Getenv("PATH")
  6607  	defer os.Setenv("PATH", osPath)
  6608  
  6609  	workingDir, err := os.Getwd()
  6610  	c.Assert(err, checker.IsNil)
  6611  	absolute, err := filepath.Abs(filepath.Join(workingDir, "fixtures", "auth"))
  6612  	c.Assert(err, checker.IsNil)
  6613  	testPath := fmt.Sprintf("%s%c%s", osPath, filepath.ListSeparator, absolute)
  6614  
  6615  	os.Setenv("PATH", testPath)
  6616  
  6617  	repoName := fmt.Sprintf("%v/dockercli/busybox:authtest", privateRegistryURL)
  6618  
  6619  	tmp, err := ioutil.TempDir("", "integration-cli-")
  6620  	c.Assert(err, checker.IsNil)
  6621  
  6622  	externalAuthConfig := `{ "credsStore": "shell-test" }`
  6623  
  6624  	configPath := filepath.Join(tmp, "config.json")
  6625  	err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
  6626  	c.Assert(err, checker.IsNil)
  6627  
  6628  	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
  6629  
  6630  	b, err := ioutil.ReadFile(configPath)
  6631  	c.Assert(err, checker.IsNil)
  6632  	c.Assert(string(b), checker.Not(checker.Contains), "\"auth\":")
  6633  
  6634  	dockerCmd(c, "--config", tmp, "tag", "busybox", repoName)
  6635  	dockerCmd(c, "--config", tmp, "push", repoName)
  6636  
  6637  	// make sure the image is pulled when building
  6638  	dockerCmd(c, "rmi", repoName)
  6639  
  6640  	buildCmd := exec.Command(dockerBinary, "--config", tmp, "build", "-")
  6641  	buildCmd.Stdin = strings.NewReader(fmt.Sprintf("FROM %s", repoName))
  6642  
  6643  	out, _, err := runCommandWithOutput(buildCmd)
  6644  	c.Assert(err, check.IsNil, check.Commentf(out))
  6645  }
  6646  
  6647  // Test cases in #22036
  6648  func (s *DockerSuite) TestBuildLabelsOverride(c *check.C) {
  6649  	// Command line option labels will always override
  6650  	name := "scratchy"
  6651  	expected := `{"bar":"from-flag","foo":"from-flag"}`
  6652  	_, err := buildImage(name,
  6653  		`FROM `+minimalBaseImage()+`
  6654                  LABEL foo=from-dockerfile`,
  6655  		true, "--label", "foo=from-flag", "--label", "bar=from-flag")
  6656  	c.Assert(err, check.IsNil)
  6657  
  6658  	res := inspectFieldJSON(c, name, "Config.Labels")
  6659  	if res != expected {
  6660  		c.Fatalf("Labels %s, expected %s", res, expected)
  6661  	}
  6662  
  6663  	name = "from"
  6664  	expected = `{"foo":"from-dockerfile"}`
  6665  	_, err = buildImage(name,
  6666  		`FROM `+minimalBaseImage()+`
  6667                  LABEL foo from-dockerfile`,
  6668  		true)
  6669  	c.Assert(err, check.IsNil)
  6670  
  6671  	res = inspectFieldJSON(c, name, "Config.Labels")
  6672  	if res != expected {
  6673  		c.Fatalf("Labels %s, expected %s", res, expected)
  6674  	}
  6675  
  6676  	// Command line option label will override even via `FROM`
  6677  	name = "new"
  6678  	expected = `{"bar":"from-dockerfile2","foo":"new"}`
  6679  	_, err = buildImage(name,
  6680  		`FROM from
  6681                  LABEL bar from-dockerfile2`,
  6682  		true, "--label", "foo=new")
  6683  	c.Assert(err, check.IsNil)
  6684  
  6685  	res = inspectFieldJSON(c, name, "Config.Labels")
  6686  	if res != expected {
  6687  		c.Fatalf("Labels %s, expected %s", res, expected)
  6688  	}
  6689  
  6690  	// Command line option without a value set (--label foo, --label bar=)
  6691  	// will be treated as --label foo="", --label bar=""
  6692  	name = "scratchy2"
  6693  	expected = `{"bar":"","foo":""}`
  6694  	_, err = buildImage(name,
  6695  		`FROM `+minimalBaseImage()+`
  6696                  LABEL foo=from-dockerfile`,
  6697  		true, "--label", "foo", "--label", "bar=")
  6698  	c.Assert(err, check.IsNil)
  6699  
  6700  	res = inspectFieldJSON(c, name, "Config.Labels")
  6701  	if res != expected {
  6702  		c.Fatalf("Labels %s, expected %s", res, expected)
  6703  	}
  6704  
  6705  	// Command line option without a value set (--label foo, --label bar=)
  6706  	// will be treated as --label foo="", --label bar=""
  6707  	// This time is for inherited images
  6708  	name = "new2"
  6709  	expected = `{"bar":"","foo":""}`
  6710  	_, err = buildImage(name,
  6711  		`FROM from
  6712                  LABEL bar from-dockerfile2`,
  6713  		true, "--label", "foo=", "--label", "bar")
  6714  	c.Assert(err, check.IsNil)
  6715  
  6716  	res = inspectFieldJSON(c, name, "Config.Labels")
  6717  	if res != expected {
  6718  		c.Fatalf("Labels %s, expected %s", res, expected)
  6719  	}
  6720  
  6721  	// Command line option labels with only `FROM`
  6722  	name = "scratchy"
  6723  	expected = `{"bar":"from-flag","foo":"from-flag"}`
  6724  	_, err = buildImage(name,
  6725  		`FROM `+minimalBaseImage(),
  6726  		true, "--label", "foo=from-flag", "--label", "bar=from-flag")
  6727  	c.Assert(err, check.IsNil)
  6728  
  6729  	res = inspectFieldJSON(c, name, "Config.Labels")
  6730  	if res != expected {
  6731  		c.Fatalf("Labels %s, expected %s", res, expected)
  6732  	}
  6733  
  6734  	// Command line option labels with env var
  6735  	name = "scratchz"
  6736  	expected = `{"bar":"$PATH"}`
  6737  	_, err = buildImage(name,
  6738  		`FROM `+minimalBaseImage(),
  6739  		true, "--label", "bar=$PATH")
  6740  	c.Assert(err, check.IsNil)
  6741  
  6742  	res = inspectFieldJSON(c, name, "Config.Labels")
  6743  	if res != expected {
  6744  		c.Fatalf("Labels %s, expected %s", res, expected)
  6745  	}
  6746  
  6747  }
  6748  
  6749  // Test case for #22855
  6750  func (s *DockerSuite) TestBuildDeleteCommittedFile(c *check.C) {
  6751  	name := "test-delete-committed-file"
  6752  
  6753  	_, err := buildImage(name,
  6754  		`FROM busybox
  6755  		RUN echo test > file
  6756  		RUN test -e file
  6757  		RUN rm file
  6758  		RUN sh -c "! test -e file"`, false)
  6759  	if err != nil {
  6760  		c.Fatal(err)
  6761  	}
  6762  }
  6763  
  6764  // #20083
  6765  func (s *DockerSuite) TestBuildDockerignoreComment(c *check.C) {
  6766  	// TODO Windows: Figure out why this test is flakey on TP5. If you add
  6767  	// something like RUN sleep 5, or even RUN ls /tmp after the ADD line,
  6768  	// it is more reliable, but that's not a good fix.
  6769  	testRequires(c, DaemonIsLinux)
  6770  
  6771  	name := "testbuilddockerignorecleanpaths"
  6772  	dockerfile := `
  6773          FROM busybox
  6774          ADD . /tmp/
  6775          RUN sh -c "(ls -la /tmp/#1)"
  6776          RUN sh -c "(! ls -la /tmp/#2)"
  6777          RUN sh -c "(! ls /tmp/foo) && (! ls /tmp/foo2) && (ls /tmp/dir1/foo)"`
  6778  	ctx, err := fakeContext(dockerfile, map[string]string{
  6779  		"foo":      "foo",
  6780  		"foo2":     "foo2",
  6781  		"dir1/foo": "foo in dir1",
  6782  		"#1":       "# file 1",
  6783  		"#2":       "# file 2",
  6784  		".dockerignore": `# Visual C++ cache files
  6785  # because we have git ;-)
  6786  # The above comment is from #20083
  6787  foo
  6788  #dir1/foo
  6789  foo2
  6790  # The following is considered as comment as # is at the beginning
  6791  #1
  6792  # The following is not considered as comment as # is not at the beginning
  6793    #2
  6794  `,
  6795  	})
  6796  	if err != nil {
  6797  		c.Fatal(err)
  6798  	}
  6799  	defer ctx.Close()
  6800  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  6801  		c.Fatal(err)
  6802  	}
  6803  }
  6804  
  6805  // Test case for #23221
  6806  func (s *DockerSuite) TestBuildWithUTF8BOM(c *check.C) {
  6807  	name := "test-with-utf8-bom"
  6808  	dockerfile := []byte(`FROM busybox`)
  6809  	bomDockerfile := append([]byte{0xEF, 0xBB, 0xBF}, dockerfile...)
  6810  	ctx, err := fakeContextFromNewTempDir()
  6811  	c.Assert(err, check.IsNil)
  6812  	defer ctx.Close()
  6813  	err = ctx.addFile("Dockerfile", bomDockerfile)
  6814  	c.Assert(err, check.IsNil)
  6815  	_, err = buildImageFromContext(name, ctx, true)
  6816  	c.Assert(err, check.IsNil)
  6817  }
  6818  
  6819  // Test case for UTF-8 BOM in .dockerignore, related to #23221
  6820  func (s *DockerSuite) TestBuildWithUTF8BOMDockerignore(c *check.C) {
  6821  	name := "test-with-utf8-bom-dockerignore"
  6822  	dockerfile := `
  6823          FROM busybox
  6824  		ADD . /tmp/
  6825  		RUN ls -la /tmp
  6826  		RUN sh -c "! ls /tmp/Dockerfile"
  6827  		RUN ls /tmp/.dockerignore`
  6828  	dockerignore := []byte("./Dockerfile\n")
  6829  	bomDockerignore := append([]byte{0xEF, 0xBB, 0xBF}, dockerignore...)
  6830  	ctx, err := fakeContext(dockerfile, map[string]string{
  6831  		"Dockerfile": dockerfile,
  6832  	})
  6833  	c.Assert(err, check.IsNil)
  6834  	defer ctx.Close()
  6835  	err = ctx.addFile(".dockerignore", bomDockerignore)
  6836  	c.Assert(err, check.IsNil)
  6837  	_, err = buildImageFromContext(name, ctx, true)
  6838  	if err != nil {
  6839  		c.Fatal(err)
  6840  	}
  6841  }
  6842  
  6843  // #22489 Shell test to confirm config gets updated correctly
  6844  func (s *DockerSuite) TestBuildShellUpdatesConfig(c *check.C) {
  6845  	name := "testbuildshellupdatesconfig"
  6846  
  6847  	expected := `["foo","-bar","#(nop) ","SHELL [foo -bar]"]`
  6848  	_, err := buildImage(name,
  6849  		`FROM `+minimalBaseImage()+`
  6850          SHELL ["foo", "-bar"]`,
  6851  		true)
  6852  	if err != nil {
  6853  		c.Fatal(err)
  6854  	}
  6855  	res := inspectFieldJSON(c, name, "ContainerConfig.Cmd")
  6856  	if res != expected {
  6857  		c.Fatalf("%s, expected %s", res, expected)
  6858  	}
  6859  	res = inspectFieldJSON(c, name, "ContainerConfig.Shell")
  6860  	if res != `["foo","-bar"]` {
  6861  		c.Fatalf(`%s, expected ["foo","-bar"]`, res)
  6862  	}
  6863  }
  6864  
  6865  // #22489 Changing the shell multiple times and CMD after.
  6866  func (s *DockerSuite) TestBuildShellMultiple(c *check.C) {
  6867  	name := "testbuildshellmultiple"
  6868  
  6869  	_, out, _, err := buildImageWithStdoutStderr(name,
  6870  		`FROM busybox
  6871  		RUN echo defaultshell
  6872  		SHELL ["echo"]
  6873  		RUN echoshell
  6874  		SHELL ["ls"]
  6875  		RUN -l
  6876  		CMD -l`,
  6877  		true)
  6878  	if err != nil {
  6879  		c.Fatal(err)
  6880  	}
  6881  
  6882  	// Must contain 'defaultshell' twice
  6883  	if len(strings.Split(out, "defaultshell")) != 3 {
  6884  		c.Fatalf("defaultshell should have appeared twice in %s", out)
  6885  	}
  6886  
  6887  	// Must contain 'echoshell' twice
  6888  	if len(strings.Split(out, "echoshell")) != 3 {
  6889  		c.Fatalf("echoshell should have appeared twice in %s", out)
  6890  	}
  6891  
  6892  	// Must contain "total " (part of ls -l)
  6893  	if !strings.Contains(out, "total ") {
  6894  		c.Fatalf("%s should have contained 'total '", out)
  6895  	}
  6896  
  6897  	// A container started from the image uses the shell-form CMD.
  6898  	// Last shell is ls. CMD is -l. So should contain 'total '.
  6899  	outrun, _ := dockerCmd(c, "run", "--rm", name)
  6900  	if !strings.Contains(outrun, "total ") {
  6901  		c.Fatalf("Expected started container to run ls -l. %s", outrun)
  6902  	}
  6903  }
  6904  
  6905  // #22489. Changed SHELL with ENTRYPOINT
  6906  func (s *DockerSuite) TestBuildShellEntrypoint(c *check.C) {
  6907  	name := "testbuildshellentrypoint"
  6908  
  6909  	_, err := buildImage(name,
  6910  		`FROM busybox
  6911  		SHELL ["ls"]
  6912  		ENTRYPOINT -l`,
  6913  		true)
  6914  	if err != nil {
  6915  		c.Fatal(err)
  6916  	}
  6917  
  6918  	// A container started from the image uses the shell-form ENTRYPOINT.
  6919  	// Shell is ls. ENTRYPOINT is -l. So should contain 'total '.
  6920  	outrun, _ := dockerCmd(c, "run", "--rm", name)
  6921  	if !strings.Contains(outrun, "total ") {
  6922  		c.Fatalf("Expected started container to run ls -l. %s", outrun)
  6923  	}
  6924  }
  6925  
  6926  // #22489 Shell test to confirm shell is inherited in a subsequent build
  6927  func (s *DockerSuite) TestBuildShellInherited(c *check.C) {
  6928  	name1 := "testbuildshellinherited1"
  6929  	_, err := buildImage(name1,
  6930  		`FROM busybox
  6931          SHELL ["ls"]`,
  6932  		true)
  6933  	if err != nil {
  6934  		c.Fatal(err)
  6935  	}
  6936  
  6937  	name2 := "testbuildshellinherited2"
  6938  	_, out, _, err := buildImageWithStdoutStderr(name2,
  6939  		`FROM `+name1+`
  6940          RUN -l`,
  6941  		true)
  6942  	if err != nil {
  6943  		c.Fatal(err)
  6944  	}
  6945  
  6946  	// ls -l has "total " followed by some number in it, ls without -l does not.
  6947  	if !strings.Contains(out, "total ") {
  6948  		c.Fatalf("Should have seen total in 'ls -l'.\n%s", out)
  6949  	}
  6950  }
  6951  
  6952  // #22489 Shell test to confirm non-JSON doesn't work
  6953  func (s *DockerSuite) TestBuildShellNotJSON(c *check.C) {
  6954  	name := "testbuildshellnotjson"
  6955  
  6956  	_, err := buildImage(name,
  6957  		`FROM `+minimalBaseImage()+`
  6958          sHeLl exec -form`, // Casing explicit to ensure error is upper-cased.
  6959  		true)
  6960  	if err == nil {
  6961  		c.Fatal("Image build should have failed")
  6962  	}
  6963  	if !strings.Contains(err.Error(), "SHELL requires the arguments to be in JSON form") {
  6964  		c.Fatal("Error didn't indicate that arguments must be in JSON form")
  6965  	}
  6966  }
  6967  
  6968  // #22489 Windows shell test to confirm native is powershell if executing a PS command
  6969  // This would error if the default shell were still cmd.
  6970  func (s *DockerSuite) TestBuildShellWindowsPowershell(c *check.C) {
  6971  	testRequires(c, DaemonIsWindows)
  6972  	name := "testbuildshellpowershell"
  6973  	_, out, err := buildImageWithOut(name,
  6974  		`FROM `+minimalBaseImage()+`
  6975          SHELL ["powershell", "-command"]
  6976  		RUN Write-Host John`,
  6977  		true)
  6978  	if err != nil {
  6979  		c.Fatal(err)
  6980  	}
  6981  	if !strings.Contains(out, "\nJohn\n") {
  6982  		c.Fatalf("Line with 'John' not found in output %q", out)
  6983  	}
  6984  }
  6985  
  6986  // Verify that escape is being correctly applied to words when escape directive is not \.
  6987  // Tests WORKDIR, ADD
  6988  func (s *DockerSuite) TestBuildEscapeNotBackslashWordTest(c *check.C) {
  6989  	testRequires(c, DaemonIsWindows)
  6990  	name := "testbuildescapenotbackslashwordtesta"
  6991  	_, out, err := buildImageWithOut(name,
  6992  		`# escape= `+"`"+`
  6993  		FROM `+minimalBaseImage()+`
  6994          WORKDIR c:\windows
  6995  		RUN dir /w`,
  6996  		true)
  6997  	if err != nil {
  6998  		c.Fatal(err)
  6999  	}
  7000  	if !strings.Contains(strings.ToLower(out), "[system32]") {
  7001  		c.Fatalf("Line with '[windows]' not found in output %q", out)
  7002  	}
  7003  
  7004  	name = "testbuildescapenotbackslashwordtestb"
  7005  	_, out, err = buildImageWithOut(name,
  7006  		`# escape= `+"`"+`
  7007  		FROM `+minimalBaseImage()+`
  7008  		SHELL ["powershell.exe"]
  7009          WORKDIR c:\foo
  7010  		ADD Dockerfile c:\foo\
  7011  		RUN dir Dockerfile`,
  7012  		true)
  7013  	if err != nil {
  7014  		c.Fatal(err)
  7015  	}
  7016  	if !strings.Contains(strings.ToLower(out), "-a----") {
  7017  		c.Fatalf("Line with '-a----' not found in output %q", out)
  7018  	}
  7019  
  7020  }
  7021  
  7022  // #22868. Make sure shell-form CMD is marked as escaped in the config of the image
  7023  func (s *DockerSuite) TestBuildCmdShellArgsEscaped(c *check.C) {
  7024  	testRequires(c, DaemonIsWindows)
  7025  	name := "testbuildcmdshellescaped"
  7026  	_, err := buildImage(name, `
  7027    FROM `+minimalBaseImage()+`
  7028    CMD "ipconfig"
  7029    `, true)
  7030  	if err != nil {
  7031  		c.Fatal(err)
  7032  	}
  7033  	res := inspectFieldJSON(c, name, "Config.ArgsEscaped")
  7034  	if res != "true" {
  7035  		c.Fatalf("CMD did not update Config.ArgsEscaped on image: %v", res)
  7036  	}
  7037  	dockerCmd(c, "run", "--name", "inspectme", name)
  7038  	dockerCmd(c, "wait", "inspectme")
  7039  	res = inspectFieldJSON(c, name, "Config.Cmd")
  7040  
  7041  	if res != `["cmd","/S","/C","\"ipconfig\""]` {
  7042  		c.Fatalf("CMD was not escaped Config.Cmd: got %v", res)
  7043  	}
  7044  }
  7045  
  7046  // Test case for #24912.
  7047  func (s *DockerSuite) TestBuildStepsWithProgress(c *check.C) {
  7048  	name := "testbuildstepswithprogress"
  7049  
  7050  	totalRun := 5
  7051  	_, out, err := buildImageWithOut(name, "FROM busybox\n"+strings.Repeat("RUN echo foo\n", totalRun), true)
  7052  	c.Assert(err, checker.IsNil)
  7053  	c.Assert(out, checker.Contains, fmt.Sprintf("Step 1/%d : FROM busybox", 1+totalRun))
  7054  	for i := 2; i <= 1+totalRun; i++ {
  7055  		c.Assert(out, checker.Contains, fmt.Sprintf("Step %d/%d : RUN echo foo", i, 1+totalRun))
  7056  	}
  7057  }
  7058  
  7059  func (s *DockerSuite) TestBuildWithFailure(c *check.C) {
  7060  	name := "testbuildwithfailure"
  7061  
  7062  	// First test case can only detect `nobody` in runtime so all steps will show up
  7063  	buildCmd := "FROM busybox\nRUN nobody"
  7064  	_, stdout, _, err := buildImageWithStdoutStderr(name, buildCmd, false, "--force-rm", "--rm")
  7065  	c.Assert(err, checker.NotNil)
  7066  	c.Assert(stdout, checker.Contains, "Step 1/2 : FROM busybox")
  7067  	c.Assert(stdout, checker.Contains, "Step 2/2 : RUN nobody")
  7068  
  7069  	// Second test case `FFOM` should have been detected before build runs so no steps
  7070  	buildCmd = "FFOM nobody\nRUN nobody"
  7071  	_, stdout, _, err = buildImageWithStdoutStderr(name, buildCmd, false, "--force-rm", "--rm")
  7072  	c.Assert(err, checker.NotNil)
  7073  	c.Assert(stdout, checker.Not(checker.Contains), "Step 1/2 : FROM busybox")
  7074  	c.Assert(stdout, checker.Not(checker.Contains), "Step 2/2 : RUN nobody")
  7075  }
  7076  
  7077  func (s *DockerSuite) TestBuildCacheFrom(c *check.C) {
  7078  	testRequires(c, DaemonIsLinux) // All tests that do save are skipped in windows
  7079  	dockerfile := `
  7080  		FROM busybox
  7081  		ENV FOO=bar
  7082  		ADD baz /
  7083  		RUN touch bax`
  7084  	ctx, err := fakeContext(dockerfile, map[string]string{
  7085  		"Dockerfile": dockerfile,
  7086  		"baz":        "baz",
  7087  	})
  7088  	c.Assert(err, checker.IsNil)
  7089  	defer ctx.Close()
  7090  
  7091  	id1, err := buildImageFromContext("build1", ctx, true)
  7092  	c.Assert(err, checker.IsNil)
  7093  
  7094  	// rebuild with cache-from
  7095  	id2, out, err := buildImageFromContextWithOut("build2", ctx, true, "--cache-from=build1")
  7096  	c.Assert(err, checker.IsNil)
  7097  	c.Assert(id1, checker.Equals, id2)
  7098  	c.Assert(strings.Count(out, "Using cache"), checker.Equals, 3)
  7099  	dockerCmd(c, "rmi", "build2")
  7100  
  7101  	// no cache match with unknown source
  7102  	id2, out, err = buildImageFromContextWithOut("build2", ctx, true, "--cache-from=nosuchtag")
  7103  	c.Assert(err, checker.IsNil)
  7104  	c.Assert(id1, checker.Not(checker.Equals), id2)
  7105  	c.Assert(strings.Count(out, "Using cache"), checker.Equals, 0)
  7106  	dockerCmd(c, "rmi", "build2")
  7107  
  7108  	// clear parent images
  7109  	tempDir, err := ioutil.TempDir("", "test-build-cache-from-")
  7110  	if err != nil {
  7111  		c.Fatalf("failed to create temporary directory: %s", tempDir)
  7112  	}
  7113  	defer os.RemoveAll(tempDir)
  7114  	tempFile := filepath.Join(tempDir, "img.tar")
  7115  	dockerCmd(c, "save", "-o", tempFile, "build1")
  7116  	dockerCmd(c, "rmi", "build1")
  7117  	dockerCmd(c, "load", "-i", tempFile)
  7118  	parentID, _ := dockerCmd(c, "inspect", "-f", "{{.Parent}}", "build1")
  7119  	c.Assert(strings.TrimSpace(parentID), checker.Equals, "")
  7120  
  7121  	// cache still applies without parents
  7122  	id2, out, err = buildImageFromContextWithOut("build2", ctx, true, "--cache-from=build1")
  7123  	c.Assert(err, checker.IsNil)
  7124  	c.Assert(id1, checker.Equals, id2)
  7125  	c.Assert(strings.Count(out, "Using cache"), checker.Equals, 3)
  7126  	history1, _ := dockerCmd(c, "history", "-q", "build2")
  7127  
  7128  	// Retry, no new intermediate images
  7129  	id3, out, err := buildImageFromContextWithOut("build3", ctx, true, "--cache-from=build1")
  7130  	c.Assert(err, checker.IsNil)
  7131  	c.Assert(id1, checker.Equals, id3)
  7132  	c.Assert(strings.Count(out, "Using cache"), checker.Equals, 3)
  7133  	history2, _ := dockerCmd(c, "history", "-q", "build3")
  7134  
  7135  	c.Assert(history1, checker.Equals, history2)
  7136  	dockerCmd(c, "rmi", "build2")
  7137  	dockerCmd(c, "rmi", "build3")
  7138  	dockerCmd(c, "rmi", "build1")
  7139  	dockerCmd(c, "load", "-i", tempFile)
  7140  
  7141  	// Modify file, everything up to last command and layers are reused
  7142  	dockerfile = `
  7143  		FROM busybox
  7144  		ENV FOO=bar
  7145  		ADD baz /
  7146  		RUN touch newfile`
  7147  	err = ioutil.WriteFile(filepath.Join(ctx.Dir, "Dockerfile"), []byte(dockerfile), 0644)
  7148  	c.Assert(err, checker.IsNil)
  7149  
  7150  	id2, out, err = buildImageFromContextWithOut("build2", ctx, true, "--cache-from=build1")
  7151  	c.Assert(err, checker.IsNil)
  7152  	c.Assert(id1, checker.Not(checker.Equals), id2)
  7153  	c.Assert(strings.Count(out, "Using cache"), checker.Equals, 2)
  7154  
  7155  	layers1Str, _ := dockerCmd(c, "inspect", "-f", "{{json .RootFS.Layers}}", "build1")
  7156  	layers2Str, _ := dockerCmd(c, "inspect", "-f", "{{json .RootFS.Layers}}", "build2")
  7157  
  7158  	var layers1 []string
  7159  	var layers2 []string
  7160  	c.Assert(json.Unmarshal([]byte(layers1Str), &layers1), checker.IsNil)
  7161  	c.Assert(json.Unmarshal([]byte(layers2Str), &layers2), checker.IsNil)
  7162  
  7163  	c.Assert(len(layers1), checker.Equals, len(layers2))
  7164  	for i := 0; i < len(layers1)-1; i++ {
  7165  		c.Assert(layers1[i], checker.Equals, layers2[i])
  7166  	}
  7167  	c.Assert(layers1[len(layers1)-1], checker.Not(checker.Equals), layers2[len(layers1)-1])
  7168  }
  7169  
  7170  func (s *DockerSuite) TestBuildNetNone(c *check.C) {
  7171  	testRequires(c, DaemonIsLinux)
  7172  
  7173  	name := "testbuildnetnone"
  7174  	_, out, err := buildImageWithOut(name, `
  7175    FROM busybox
  7176    RUN ping -c 1 8.8.8.8
  7177    `, true, "--network=none")
  7178  	c.Assert(err, checker.NotNil)
  7179  	c.Assert(out, checker.Contains, "unreachable")
  7180  }
  7181  
  7182  func (s *DockerSuite) TestBuildNetContainer(c *check.C) {
  7183  	testRequires(c, DaemonIsLinux)
  7184  
  7185  	id, _ := dockerCmd(c, "run", "--hostname", "foobar", "-d", "busybox", "nc", "-ll", "-p", "1234", "-e", "hostname")
  7186  
  7187  	name := "testbuildnetcontainer"
  7188  	out, err := buildImage(name, `
  7189    FROM busybox
  7190    RUN nc localhost 1234 > /otherhost
  7191    `, true, "--network=container:"+strings.TrimSpace(id))
  7192  	c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
  7193  
  7194  	host, _ := dockerCmd(c, "run", "testbuildnetcontainer", "cat", "/otherhost")
  7195  	c.Assert(strings.TrimSpace(host), check.Equals, "foobar")
  7196  }
  7197  
  7198  func (s *DockerSuite) TestBuildSquashParent(c *check.C) {
  7199  	testRequires(c, ExperimentalDaemon)
  7200  	dockerFile := `
  7201  		FROM busybox
  7202  		RUN echo hello > /hello
  7203  		RUN echo world >> /hello
  7204  		RUN echo hello > /remove_me
  7205  		ENV HELLO world
  7206  		RUN rm /remove_me
  7207  		`
  7208  	// build and get the ID that we can use later for history comparison
  7209  	origID, err := buildImage("test", dockerFile, false)
  7210  	c.Assert(err, checker.IsNil)
  7211  
  7212  	// build with squash
  7213  	id, err := buildImage("test", dockerFile, true, "--squash")
  7214  	c.Assert(err, checker.IsNil)
  7215  
  7216  	out, _ := dockerCmd(c, "run", "--rm", id, "/bin/sh", "-c", "cat /hello")
  7217  	c.Assert(strings.TrimSpace(out), checker.Equals, "hello\nworld")
  7218  
  7219  	dockerCmd(c, "run", "--rm", id, "/bin/sh", "-c", "[ ! -f /remove_me ]")
  7220  	dockerCmd(c, "run", "--rm", id, "/bin/sh", "-c", `[ "$(echo $HELLO)" == "world" ]`)
  7221  
  7222  	// make sure the ID produced is the ID of the tag we specified
  7223  	inspectID, err := inspectImage("test", ".ID")
  7224  	c.Assert(err, checker.IsNil)
  7225  	c.Assert(inspectID, checker.Equals, id)
  7226  
  7227  	origHistory, _ := dockerCmd(c, "history", origID)
  7228  	testHistory, _ := dockerCmd(c, "history", "test")
  7229  
  7230  	splitOrigHistory := strings.Split(strings.TrimSpace(origHistory), "\n")
  7231  	splitTestHistory := strings.Split(strings.TrimSpace(testHistory), "\n")
  7232  	c.Assert(len(splitTestHistory), checker.Equals, len(splitOrigHistory)+1)
  7233  
  7234  	out, err = inspectImage(id, "len .RootFS.Layers")
  7235  	c.Assert(err, checker.IsNil)
  7236  	c.Assert(strings.TrimSpace(out), checker.Equals, "3")
  7237  }
  7238  
  7239  func (s *DockerSuite) TestBuildContChar(c *check.C) {
  7240  	name := "testbuildcontchar"
  7241  
  7242  	_, out, err := buildImageWithOut(name,
  7243  		`FROM busybox\`, true)
  7244  	c.Assert(err, checker.IsNil)
  7245  	c.Assert(out, checker.Contains, "Step 1/1 : FROM busybox")
  7246  
  7247  	_, out, err = buildImageWithOut(name,
  7248  		`FROM busybox
  7249  		 RUN echo hi \`, true)
  7250  	c.Assert(err, checker.IsNil)
  7251  	c.Assert(out, checker.Contains, "Step 1/2 : FROM busybox")
  7252  	c.Assert(out, checker.Contains, "Step 2/2 : RUN echo hi\n")
  7253  
  7254  	_, out, err = buildImageWithOut(name,
  7255  		`FROM busybox
  7256  		 RUN echo hi \\`, true)
  7257  	c.Assert(err, checker.IsNil)
  7258  	c.Assert(out, checker.Contains, "Step 1/2 : FROM busybox")
  7259  	c.Assert(out, checker.Contains, "Step 2/2 : RUN echo hi \\\n")
  7260  
  7261  	_, out, err = buildImageWithOut(name,
  7262  		`FROM busybox
  7263  		 RUN echo hi \\\`, true)
  7264  	c.Assert(err, checker.IsNil)
  7265  	c.Assert(out, checker.Contains, "Step 1/2 : FROM busybox")
  7266  	c.Assert(out, checker.Contains, "Step 2/2 : RUN echo hi \\\\\n")
  7267  }
  7268  
  7269  // TestBuildOpaqueDirectory tests that a build succeeds which
  7270  // creates opaque directories.
  7271  // See https://github.com/docker/docker/issues/25244
  7272  func (s *DockerSuite) TestBuildOpaqueDirectory(c *check.C) {
  7273  	testRequires(c, DaemonIsLinux)
  7274  
  7275  	dockerFile := `
  7276  		FROM busybox
  7277  		RUN mkdir /dir1 && touch /dir1/f1
  7278  		RUN rm -rf /dir1 && mkdir /dir1 && touch /dir1/f2
  7279  		RUN touch /dir1/f3
  7280  		RUN [ -f /dir1/f2 ]
  7281  		`
  7282  
  7283  	// Test that build succeeds, last command fails if opaque directory
  7284  	// was not handled correctly
  7285  	_, err := buildImage("testopaquedirectory", dockerFile, false)
  7286  	c.Assert(err, checker.IsNil)
  7287  }
  7288  
  7289  // Windows test for USER in dockerfile
  7290  func (s *DockerSuite) TestBuildWindowsUser(c *check.C) {
  7291  	testRequires(c, DaemonIsWindows)
  7292  	name := "testbuildwindowsuser"
  7293  	_, out, err := buildImageWithOut(name,
  7294  		`FROM `+WindowsBaseImage+`
  7295  		RUN net user user /add
  7296  		USER user
  7297  		RUN set username
  7298  		`,
  7299  		true)
  7300  	if err != nil {
  7301  		c.Fatal(err)
  7302  	}
  7303  	c.Assert(strings.ToLower(out), checker.Contains, "username=user")
  7304  }
  7305  
  7306  // Verifies if COPY file . when WORKDIR is set to a non-existing directory,
  7307  // the directory is created and the file is copied into the directory,
  7308  // as opposed to the file being copied as a file with the name of the
  7309  // directory. Fix for 27545 (found on Windows, but regression good for Linux too).
  7310  // Note 27545 was reverted in 28505, but a new fix was added subsequently in 28514.
  7311  func (s *DockerSuite) TestBuildCopyFileDotWithWorkdir(c *check.C) {
  7312  	name := "testbuildcopyfiledotwithworkdir"
  7313  	ctx, err := fakeContext(`FROM busybox 
  7314  WORKDIR /foo 
  7315  COPY file . 
  7316  RUN ["cat", "/foo/file"] 
  7317  `,
  7318  		map[string]string{})
  7319  
  7320  	if err != nil {
  7321  		c.Fatal(err)
  7322  	}
  7323  	defer ctx.Close()
  7324  
  7325  	if err := ctx.Add("file", "content"); err != nil {
  7326  		c.Fatal(err)
  7327  	}
  7328  
  7329  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  7330  		c.Fatal(err)
  7331  	}
  7332  }
  7333  
  7334  // Case-insensitive environment variables on Windows
  7335  func (s *DockerSuite) TestBuildWindowsEnvCaseInsensitive(c *check.C) {
  7336  	testRequires(c, DaemonIsWindows)
  7337  	name := "testbuildwindowsenvcaseinsensitive"
  7338  	if _, err := buildImage(name, `
  7339  		FROM `+WindowsBaseImage+`
  7340  		ENV FOO=bar foo=bar
  7341    `, true); err != nil {
  7342  		c.Fatal(err)
  7343  	}
  7344  	res := inspectFieldJSON(c, name, "Config.Env")
  7345  	if res != `["foo=bar"]` { // Should not have FOO=bar in it - takes the last one processed. And only one entry as deduped.
  7346  		c.Fatalf("Case insensitive environment variables on Windows failed. Got %s", res)
  7347  	}
  7348  }
  7349  
  7350  // Test case for 29667
  7351  func (s *DockerSuite) TestBuildWorkdirImageCmd(c *check.C) {
  7352  	testRequires(c, DaemonIsLinux)
  7353  
  7354  	image := "testworkdirimagecmd"
  7355  	dockerfile := `
  7356  FROM busybox
  7357  WORKDIR /foo/bar
  7358  `
  7359  	out, err := buildImage(image, dockerfile, true)
  7360  	c.Assert(err, checker.IsNil, check.Commentf("Output: %s", out))
  7361  
  7362  	out, _ = dockerCmd(c, "inspect", "--format", "{{ json .Config.Cmd }}", image)
  7363  	c.Assert(strings.TrimSpace(out), checker.Equals, `["sh"]`)
  7364  
  7365  	image = "testworkdirlabelimagecmd"
  7366  	dockerfile = `
  7367  FROM busybox
  7368  WORKDIR /foo/bar
  7369  LABEL a=b
  7370  `
  7371  	out, err = buildImage(image, dockerfile, true)
  7372  	c.Assert(err, checker.IsNil, check.Commentf("Output: %s", out))
  7373  
  7374  	out, _ = dockerCmd(c, "inspect", "--format", "{{ json .Config.Cmd }}", image)
  7375  	c.Assert(strings.TrimSpace(out), checker.Equals, `["sh"]`)
  7376  }
  7377  
  7378  // Test case for 28902/28090
  7379  func (s *DockerSuite) TestBuildWorkdirCmd(c *check.C) {
  7380  	testRequires(c, DaemonIsLinux)
  7381  
  7382  	dockerFile := `
  7383                  FROM golang:1.7-alpine
  7384                  WORKDIR /
  7385                  `
  7386  	_, err := buildImage("testbuildworkdircmd", dockerFile, true)
  7387  	c.Assert(err, checker.IsNil)
  7388  
  7389  	_, out, err := buildImageWithOut("testbuildworkdircmd", dockerFile, true)
  7390  	c.Assert(err, checker.IsNil)
  7391  	c.Assert(strings.Count(out, "Using cache"), checker.Equals, 1)
  7392  }