github.com/ncdc/docker@v0.10.1-0.20160129113957-6c6729ef5b74/integration-cli/docker_cli_build_test.go (about)

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