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