github.com/chenchun/docker@v1.3.2-0.20150629222414-20467faf132b/integration-cli/docker_cli_build_test.go (about)

     1  package main
     2  
     3  import (
     4  	"archive/tar"
     5  	"bufio"
     6  	"bytes"
     7  	"encoding/json"
     8  	"fmt"
     9  	"io/ioutil"
    10  	"os"
    11  	"os/exec"
    12  	"path/filepath"
    13  	"reflect"
    14  	"regexp"
    15  	"runtime"
    16  	"strconv"
    17  	"strings"
    18  	"text/template"
    19  	"time"
    20  
    21  	"github.com/docker/docker/builder/command"
    22  	"github.com/docker/docker/pkg/archive"
    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 ["/bin/echo"]
    71      CMD echo test
    72      `,
    73  		true)
    74  
    75  	if err != nil {
    76  		c.Fatal(err)
    77  	}
    78  
    79  	out, _, err := runCommandWithOutput(
    80  		exec.Command(
    81  			dockerBinary,
    82  			"run",
    83  			"--rm",
    84  			name))
    85  
    86  	if err != nil {
    87  		c.Fatal(err)
    88  	}
    89  
    90  	if strings.TrimSpace(out) != "/bin/sh -c echo test" {
    91  		c.Fatal("CMD did not contain /bin/sh -c")
    92  	}
    93  
    94  }
    95  
    96  func (s *DockerSuite) TestBuildEnvironmentReplacementUser(c *check.C) {
    97  	name := "testbuildenvironmentreplacement"
    98  
    99  	_, err := buildImage(name, `
   100    FROM scratch
   101    ENV user foo
   102    USER ${user}
   103    `, true)
   104  	if err != nil {
   105  		c.Fatal(err)
   106  	}
   107  
   108  	res, err := inspectFieldJSON(name, "Config.User")
   109  	if err != nil {
   110  		c.Fatal(err)
   111  	}
   112  
   113  	if res != `"foo"` {
   114  		c.Fatal("User foo from environment not in Config.User on image")
   115  	}
   116  
   117  }
   118  
   119  func (s *DockerSuite) TestBuildEnvironmentReplacementVolume(c *check.C) {
   120  	name := "testbuildenvironmentreplacement"
   121  
   122  	_, err := buildImage(name, `
   123    FROM scratch
   124    ENV volume /quux
   125    VOLUME ${volume}
   126    `, true)
   127  	if err != nil {
   128  		c.Fatal(err)
   129  	}
   130  
   131  	res, err := inspectFieldJSON(name, "Config.Volumes")
   132  	if err != nil {
   133  		c.Fatal(err)
   134  	}
   135  
   136  	var volumes map[string]interface{}
   137  
   138  	if err := json.Unmarshal([]byte(res), &volumes); err != nil {
   139  		c.Fatal(err)
   140  	}
   141  
   142  	if _, ok := volumes["/quux"]; !ok {
   143  		c.Fatal("Volume /quux from environment not in Config.Volumes on image")
   144  	}
   145  
   146  }
   147  
   148  func (s *DockerSuite) TestBuildEnvironmentReplacementExpose(c *check.C) {
   149  	name := "testbuildenvironmentreplacement"
   150  
   151  	_, err := buildImage(name, `
   152    FROM scratch
   153    ENV port 80
   154    EXPOSE ${port}
   155    `, true)
   156  	if err != nil {
   157  		c.Fatal(err)
   158  	}
   159  
   160  	res, err := inspectFieldJSON(name, "Config.ExposedPorts")
   161  	if err != nil {
   162  		c.Fatal(err)
   163  	}
   164  
   165  	var exposedPorts map[string]interface{}
   166  
   167  	if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
   168  		c.Fatal(err)
   169  	}
   170  
   171  	if _, ok := exposedPorts["80/tcp"]; !ok {
   172  		c.Fatal("Exposed port 80 from environment not in Config.ExposedPorts on image")
   173  	}
   174  
   175  }
   176  
   177  func (s *DockerSuite) TestBuildEnvironmentReplacementWorkdir(c *check.C) {
   178  	name := "testbuildenvironmentreplacement"
   179  
   180  	_, err := buildImage(name, `
   181    FROM busybox
   182    ENV MYWORKDIR /work
   183    RUN mkdir ${MYWORKDIR}
   184    WORKDIR ${MYWORKDIR}
   185    `, true)
   186  
   187  	if err != nil {
   188  		c.Fatal(err)
   189  	}
   190  
   191  }
   192  
   193  func (s *DockerSuite) TestBuildEnvironmentReplacementAddCopy(c *check.C) {
   194  	name := "testbuildenvironmentreplacement"
   195  
   196  	ctx, err := fakeContext(`
   197    FROM scratch
   198    ENV baz foo
   199    ENV quux bar
   200    ENV dot .
   201    ENV fee fff
   202    ENV gee ggg
   203  
   204    ADD ${baz} ${dot}
   205    COPY ${quux} ${dot}
   206    ADD ${zzz:-${fee}} ${dot}
   207    COPY ${zzz:-${gee}} ${dot}
   208    `,
   209  		map[string]string{
   210  			"foo": "test1",
   211  			"bar": "test2",
   212  			"fff": "test3",
   213  			"ggg": "test4",
   214  		})
   215  
   216  	if err != nil {
   217  		c.Fatal(err)
   218  	}
   219  	defer ctx.Close()
   220  
   221  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   222  		c.Fatal(err)
   223  	}
   224  
   225  }
   226  
   227  func (s *DockerSuite) TestBuildEnvironmentReplacementEnv(c *check.C) {
   228  	name := "testbuildenvironmentreplacement"
   229  
   230  	_, err := buildImage(name,
   231  		`
   232    FROM busybox
   233    ENV foo zzz
   234    ENV bar ${foo}
   235    ENV abc1='$foo'
   236    ENV env1=$foo env2=${foo} env3="$foo" env4="${foo}"
   237    RUN [ "$abc1" = '$foo' ] && (echo "$abc1" | grep -q foo)
   238    ENV abc2="\$foo"
   239    RUN [ "$abc2" = '$foo' ] && (echo "$abc2" | grep -q foo)
   240    ENV abc3 '$foo'
   241    RUN [ "$abc3" = '$foo' ] && (echo "$abc3" | grep -q foo)
   242    ENV abc4 "\$foo"
   243    RUN [ "$abc4" = '$foo' ] && (echo "$abc4" | grep -q foo)
   244    `, true)
   245  
   246  	if err != nil {
   247  		c.Fatal(err)
   248  	}
   249  
   250  	res, err := inspectFieldJSON(name, "Config.Env")
   251  	if err != nil {
   252  		c.Fatal(err)
   253  	}
   254  
   255  	envResult := []string{}
   256  
   257  	if err = unmarshalJSON([]byte(res), &envResult); err != nil {
   258  		c.Fatal(err)
   259  	}
   260  
   261  	found := false
   262  	envCount := 0
   263  
   264  	for _, env := range envResult {
   265  		parts := strings.SplitN(env, "=", 2)
   266  		if parts[0] == "bar" {
   267  			found = true
   268  			if parts[1] != "zzz" {
   269  				c.Fatalf("Could not find replaced var for env `bar`: got %q instead of `zzz`", parts[1])
   270  			}
   271  		} else if strings.HasPrefix(parts[0], "env") {
   272  			envCount++
   273  			if parts[1] != "zzz" {
   274  				c.Fatalf("%s should be 'foo' but instead its %q", parts[0], parts[1])
   275  			}
   276  		} else if strings.HasPrefix(parts[0], "env") {
   277  			envCount++
   278  			if parts[1] != "foo" {
   279  				c.Fatalf("%s should be 'foo' but instead its %q", parts[0], parts[1])
   280  			}
   281  		}
   282  	}
   283  
   284  	if !found {
   285  		c.Fatal("Never found the `bar` env variable")
   286  	}
   287  
   288  	if envCount != 4 {
   289  		c.Fatalf("Didn't find all env vars - only saw %d\n%s", envCount, envResult)
   290  	}
   291  
   292  }
   293  
   294  func (s *DockerSuite) TestBuildHandleEscapes(c *check.C) {
   295  	name := "testbuildhandleescapes"
   296  
   297  	_, err := buildImage(name,
   298  		`
   299    FROM scratch
   300    ENV FOO bar
   301    VOLUME ${FOO}
   302    `, true)
   303  
   304  	if err != nil {
   305  		c.Fatal(err)
   306  	}
   307  
   308  	var result map[string]map[string]struct{}
   309  
   310  	res, err := inspectFieldJSON(name, "Config.Volumes")
   311  	if err != nil {
   312  		c.Fatal(err)
   313  	}
   314  
   315  	if err = unmarshalJSON([]byte(res), &result); err != nil {
   316  		c.Fatal(err)
   317  	}
   318  
   319  	if _, ok := result["bar"]; !ok {
   320  		c.Fatal("Could not find volume bar set from env foo in volumes table")
   321  	}
   322  
   323  	deleteImages(name)
   324  
   325  	_, err = buildImage(name,
   326  		`
   327    FROM scratch
   328    ENV FOO bar
   329    VOLUME \${FOO}
   330    `, true)
   331  
   332  	if err != nil {
   333  		c.Fatal(err)
   334  	}
   335  
   336  	res, err = inspectFieldJSON(name, "Config.Volumes")
   337  	if err != nil {
   338  		c.Fatal(err)
   339  	}
   340  
   341  	if err = unmarshalJSON([]byte(res), &result); err != nil {
   342  		c.Fatal(err)
   343  	}
   344  
   345  	if _, ok := result["${FOO}"]; !ok {
   346  		c.Fatal("Could not find volume ${FOO} set from env foo in volumes table")
   347  	}
   348  
   349  	deleteImages(name)
   350  
   351  	// this test in particular provides *7* backslashes and expects 6 to come back.
   352  	// Like above, the first escape is swallowed and the rest are treated as
   353  	// literals, this one is just less obvious because of all the character noise.
   354  
   355  	_, err = buildImage(name,
   356  		`
   357    FROM scratch
   358    ENV FOO bar
   359    VOLUME \\\\\\\${FOO}
   360    `, true)
   361  
   362  	if err != nil {
   363  		c.Fatal(err)
   364  	}
   365  
   366  	res, err = inspectFieldJSON(name, "Config.Volumes")
   367  	if err != nil {
   368  		c.Fatal(err)
   369  	}
   370  
   371  	if err = unmarshalJSON([]byte(res), &result); err != nil {
   372  		c.Fatal(err)
   373  	}
   374  
   375  	if _, ok := result[`\\\${FOO}`]; !ok {
   376  		c.Fatal(`Could not find volume \\\${FOO} set from env foo in volumes table`, result)
   377  	}
   378  
   379  }
   380  
   381  func (s *DockerSuite) TestBuildOnBuildLowercase(c *check.C) {
   382  	name := "testbuildonbuildlowercase"
   383  	name2 := "testbuildonbuildlowercase2"
   384  
   385  	_, err := buildImage(name,
   386  		`
   387    FROM busybox
   388    onbuild run echo quux
   389    `, true)
   390  
   391  	if err != nil {
   392  		c.Fatal(err)
   393  	}
   394  
   395  	_, out, err := buildImageWithOut(name2, fmt.Sprintf(`
   396    FROM %s
   397    `, name), true)
   398  
   399  	if err != nil {
   400  		c.Fatal(err)
   401  	}
   402  
   403  	if !strings.Contains(out, "quux") {
   404  		c.Fatalf("Did not receive the expected echo text, got %s", out)
   405  	}
   406  
   407  	if strings.Contains(out, "ONBUILD ONBUILD") {
   408  		c.Fatalf("Got an ONBUILD ONBUILD error with no error: got %s", out)
   409  	}
   410  
   411  }
   412  
   413  func (s *DockerSuite) TestBuildEnvEscapes(c *check.C) {
   414  	name := "testbuildenvescapes"
   415  	_, err := buildImage(name,
   416  		`
   417      FROM busybox
   418      ENV TEST foo
   419      CMD echo \$
   420      `,
   421  		true)
   422  
   423  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name))
   424  
   425  	if err != nil {
   426  		c.Fatal(err)
   427  	}
   428  
   429  	if strings.TrimSpace(out) != "$" {
   430  		c.Fatalf("Env TEST was not overwritten with bar when foo was supplied to dockerfile: was %q", strings.TrimSpace(out))
   431  	}
   432  
   433  }
   434  
   435  func (s *DockerSuite) TestBuildEnvOverwrite(c *check.C) {
   436  	name := "testbuildenvoverwrite"
   437  
   438  	_, err := buildImage(name,
   439  		`
   440      FROM busybox
   441      ENV TEST foo
   442      CMD echo ${TEST}
   443      `,
   444  		true)
   445  
   446  	if err != nil {
   447  		c.Fatal(err)
   448  	}
   449  
   450  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-e", "TEST=bar", "-t", name))
   451  
   452  	if err != nil {
   453  		c.Fatal(err)
   454  	}
   455  
   456  	if strings.TrimSpace(out) != "bar" {
   457  		c.Fatalf("Env TEST was not overwritten with bar when foo was supplied to dockerfile: was %q", strings.TrimSpace(out))
   458  	}
   459  
   460  }
   461  
   462  func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainerInSourceImage(c *check.C) {
   463  	name := "testbuildonbuildforbiddenmaintainerinsourceimage"
   464  
   465  	createCmd := exec.Command(dockerBinary, "create", "busybox", "true")
   466  	out, _, _, err := runCommandWithStdoutStderr(createCmd)
   467  	if err != nil {
   468  		c.Fatal(out, err)
   469  	}
   470  
   471  	cleanedContainerID := strings.TrimSpace(out)
   472  
   473  	commitCmd := exec.Command(dockerBinary, "commit", "--run", "{\"OnBuild\":[\"MAINTAINER docker.io\"]}", cleanedContainerID, "onbuild")
   474  
   475  	if _, err := runCommand(commitCmd); err != nil {
   476  		c.Fatal(err)
   477  	}
   478  
   479  	_, err = buildImage(name,
   480  		`FROM onbuild`,
   481  		true)
   482  	if err != nil {
   483  		if !strings.Contains(err.Error(), "maintainer isn't allowed as an ONBUILD trigger") {
   484  			c.Fatalf("Wrong error %v, must be about MAINTAINER and ONBUILD in source image", err)
   485  		}
   486  	} else {
   487  		c.Fatal("Error must not be nil")
   488  	}
   489  
   490  }
   491  
   492  func (s *DockerSuite) TestBuildOnBuildForbiddenFromInSourceImage(c *check.C) {
   493  	name := "testbuildonbuildforbiddenfrominsourceimage"
   494  
   495  	createCmd := exec.Command(dockerBinary, "create", "busybox", "true")
   496  	out, _, _, err := runCommandWithStdoutStderr(createCmd)
   497  	if err != nil {
   498  		c.Fatal(out, err)
   499  	}
   500  
   501  	cleanedContainerID := strings.TrimSpace(out)
   502  
   503  	commitCmd := exec.Command(dockerBinary, "commit", "--run", "{\"OnBuild\":[\"FROM busybox\"]}", cleanedContainerID, "onbuild")
   504  
   505  	if _, err := runCommand(commitCmd); err != nil {
   506  		c.Fatal(err)
   507  	}
   508  
   509  	_, err = buildImage(name,
   510  		`FROM onbuild`,
   511  		true)
   512  	if err != nil {
   513  		if !strings.Contains(err.Error(), "from isn't allowed as an ONBUILD trigger") {
   514  			c.Fatalf("Wrong error %v, must be about FROM and ONBUILD in source image", err)
   515  		}
   516  	} else {
   517  		c.Fatal("Error must not be nil")
   518  	}
   519  
   520  }
   521  
   522  func (s *DockerSuite) TestBuildOnBuildForbiddenChainedInSourceImage(c *check.C) {
   523  	name := "testbuildonbuildforbiddenchainedinsourceimage"
   524  
   525  	createCmd := exec.Command(dockerBinary, "create", "busybox", "true")
   526  	out, _, _, err := runCommandWithStdoutStderr(createCmd)
   527  	if err != nil {
   528  		c.Fatal(out, err)
   529  	}
   530  
   531  	cleanedContainerID := strings.TrimSpace(out)
   532  
   533  	commitCmd := exec.Command(dockerBinary, "commit", "--run", "{\"OnBuild\":[\"ONBUILD RUN ls\"]}", cleanedContainerID, "onbuild")
   534  
   535  	if _, err := runCommand(commitCmd); err != nil {
   536  		c.Fatal(err)
   537  	}
   538  
   539  	_, err = buildImage(name,
   540  		`FROM onbuild`,
   541  		true)
   542  	if err != nil {
   543  		if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
   544  			c.Fatalf("Wrong error %v, must be about chaining ONBUILD in source image", err)
   545  		}
   546  	} else {
   547  		c.Fatal("Error must not be nil")
   548  	}
   549  
   550  }
   551  
   552  func (s *DockerSuite) TestBuildOnBuildCmdEntrypointJSON(c *check.C) {
   553  	name1 := "onbuildcmd"
   554  	name2 := "onbuildgenerated"
   555  
   556  	_, err := buildImage(name1, `
   557  FROM busybox
   558  ONBUILD CMD ["hello world"]
   559  ONBUILD ENTRYPOINT ["echo"]
   560  ONBUILD RUN ["true"]`,
   561  		false)
   562  
   563  	if err != nil {
   564  		c.Fatal(err)
   565  	}
   566  
   567  	_, err = buildImage(name2, fmt.Sprintf(`FROM %s`, name1), false)
   568  
   569  	if err != nil {
   570  		c.Fatal(err)
   571  	}
   572  
   573  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name2))
   574  	if err != nil {
   575  		c.Fatal(err)
   576  	}
   577  
   578  	if !regexp.MustCompile(`(?m)^hello world`).MatchString(out) {
   579  		c.Fatal("did not get echo output from onbuild", out)
   580  	}
   581  
   582  }
   583  
   584  func (s *DockerSuite) TestBuildOnBuildEntrypointJSON(c *check.C) {
   585  	name1 := "onbuildcmd"
   586  	name2 := "onbuildgenerated"
   587  
   588  	_, err := buildImage(name1, `
   589  FROM busybox
   590  ONBUILD ENTRYPOINT ["echo"]`,
   591  		false)
   592  
   593  	if err != nil {
   594  		c.Fatal(err)
   595  	}
   596  
   597  	_, err = buildImage(name2, fmt.Sprintf("FROM %s\nCMD [\"hello world\"]\n", name1), false)
   598  
   599  	if err != nil {
   600  		c.Fatal(err)
   601  	}
   602  
   603  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name2))
   604  	if err != nil {
   605  		c.Fatal(err)
   606  	}
   607  
   608  	if !regexp.MustCompile(`(?m)^hello world`).MatchString(out) {
   609  		c.Fatal("got malformed output from onbuild", out)
   610  	}
   611  
   612  }
   613  
   614  func (s *DockerSuite) TestBuildCacheAdd(c *check.C) {
   615  	name := "testbuildtwoimageswithadd"
   616  	server, err := fakeStorage(map[string]string{
   617  		"robots.txt": "hello",
   618  		"index.html": "world",
   619  	})
   620  	if err != nil {
   621  		c.Fatal(err)
   622  	}
   623  	defer server.Close()
   624  
   625  	if _, err := buildImage(name,
   626  		fmt.Sprintf(`FROM scratch
   627  		ADD %s/robots.txt /`, server.URL()),
   628  		true); err != nil {
   629  		c.Fatal(err)
   630  	}
   631  	if err != nil {
   632  		c.Fatal(err)
   633  	}
   634  	deleteImages(name)
   635  	_, out, err := buildImageWithOut(name,
   636  		fmt.Sprintf(`FROM scratch
   637  		ADD %s/index.html /`, server.URL()),
   638  		true)
   639  	if err != nil {
   640  		c.Fatal(err)
   641  	}
   642  	if strings.Contains(out, "Using cache") {
   643  		c.Fatal("2nd build used cache on ADD, it shouldn't")
   644  	}
   645  
   646  }
   647  
   648  func (s *DockerSuite) TestBuildLastModified(c *check.C) {
   649  	name := "testbuildlastmodified"
   650  
   651  	server, err := fakeStorage(map[string]string{
   652  		"file": "hello",
   653  	})
   654  	if err != nil {
   655  		c.Fatal(err)
   656  	}
   657  	defer server.Close()
   658  
   659  	var out, out2 string
   660  
   661  	dFmt := `FROM busybox
   662  ADD %s/file /
   663  RUN ls -le /file`
   664  
   665  	dockerfile := fmt.Sprintf(dFmt, server.URL())
   666  
   667  	if _, out, err = buildImageWithOut(name, dockerfile, false); err != nil {
   668  		c.Fatal(err)
   669  	}
   670  
   671  	originMTime := regexp.MustCompile(`root.*/file.*\n`).FindString(out)
   672  	// Make sure our regexp is correct
   673  	if strings.Index(originMTime, "/file") < 0 {
   674  		c.Fatalf("Missing ls info on 'file':\n%s", out)
   675  	}
   676  
   677  	// Build it again and make sure the mtime of the file didn't change.
   678  	// Wait a few seconds to make sure the time changed enough to notice
   679  	time.Sleep(2 * time.Second)
   680  
   681  	if _, out2, err = buildImageWithOut(name, dockerfile, false); err != nil {
   682  		c.Fatal(err)
   683  	}
   684  
   685  	newMTime := regexp.MustCompile(`root.*/file.*\n`).FindString(out2)
   686  	if newMTime != originMTime {
   687  		c.Fatalf("MTime changed:\nOrigin:%s\nNew:%s", originMTime, newMTime)
   688  	}
   689  
   690  	// Now 'touch' the file and make sure the timestamp DID change this time
   691  	// Create a new fakeStorage instead of just using Add() to help windows
   692  	server, err = fakeStorage(map[string]string{
   693  		"file": "hello",
   694  	})
   695  	if err != nil {
   696  		c.Fatal(err)
   697  	}
   698  	defer server.Close()
   699  
   700  	dockerfile = fmt.Sprintf(dFmt, server.URL())
   701  
   702  	if _, out2, err = buildImageWithOut(name, dockerfile, false); err != nil {
   703  		c.Fatal(err)
   704  	}
   705  
   706  	newMTime = regexp.MustCompile(`root.*/file.*\n`).FindString(out2)
   707  	if newMTime == originMTime {
   708  		c.Fatalf("MTime didn't change:\nOrigin:%s\nNew:%s", originMTime, newMTime)
   709  	}
   710  
   711  }
   712  
   713  func (s *DockerSuite) TestBuildSixtySteps(c *check.C) {
   714  	name := "foobuildsixtysteps"
   715  	ctx, err := fakeContext("FROM scratch\n"+strings.Repeat("ADD foo /\n", 60),
   716  		map[string]string{
   717  			"foo": "test1",
   718  		})
   719  	if err != nil {
   720  		c.Fatal(err)
   721  	}
   722  	defer ctx.Close()
   723  
   724  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   725  		c.Fatal(err)
   726  	}
   727  }
   728  
   729  func (s *DockerSuite) TestBuildAddSingleFileToRoot(c *check.C) {
   730  	name := "testaddimg"
   731  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
   732  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
   733  RUN echo 'dockerio:x:1001:' >> /etc/group
   734  RUN touch /exists
   735  RUN chown dockerio.dockerio /exists
   736  ADD test_file /
   737  RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
   738  RUN [ $(ls -l /test_file | awk '{print $1}') = '%s' ]
   739  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
   740  		map[string]string{
   741  			"test_file": "test1",
   742  		})
   743  	if err != nil {
   744  		c.Fatal(err)
   745  	}
   746  	defer ctx.Close()
   747  
   748  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   749  		c.Fatal(err)
   750  	}
   751  }
   752  
   753  // Issue #3960: "ADD src ." hangs
   754  func (s *DockerSuite) TestBuildAddSingleFileToWorkdir(c *check.C) {
   755  	name := "testaddsinglefiletoworkdir"
   756  	ctx, err := fakeContext(`FROM busybox
   757  ADD test_file .`,
   758  		map[string]string{
   759  			"test_file": "test1",
   760  		})
   761  	if err != nil {
   762  		c.Fatal(err)
   763  	}
   764  	defer ctx.Close()
   765  
   766  	errChan := make(chan error)
   767  	go func() {
   768  		_, err := buildImageFromContext(name, ctx, true)
   769  		errChan <- err
   770  		close(errChan)
   771  	}()
   772  	select {
   773  	case <-time.After(5 * time.Second):
   774  		c.Fatal("Build with adding to workdir timed out")
   775  	case err := <-errChan:
   776  		c.Assert(err, check.IsNil)
   777  	}
   778  }
   779  
   780  func (s *DockerSuite) TestBuildAddSingleFileToExistDir(c *check.C) {
   781  	name := "testaddsinglefiletoexistdir"
   782  	ctx, err := fakeContext(`FROM busybox
   783  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
   784  RUN echo 'dockerio:x:1001:' >> /etc/group
   785  RUN mkdir /exists
   786  RUN touch /exists/exists_file
   787  RUN chown -R dockerio.dockerio /exists
   788  ADD test_file /exists/
   789  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
   790  RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]
   791  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
   792  		map[string]string{
   793  			"test_file": "test1",
   794  		})
   795  	if err != nil {
   796  		c.Fatal(err)
   797  	}
   798  	defer ctx.Close()
   799  
   800  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   801  		c.Fatal(err)
   802  	}
   803  }
   804  
   805  func (s *DockerSuite) TestBuildCopyAddMultipleFiles(c *check.C) {
   806  	server, err := fakeStorage(map[string]string{
   807  		"robots.txt": "hello",
   808  	})
   809  	if err != nil {
   810  		c.Fatal(err)
   811  	}
   812  	defer server.Close()
   813  
   814  	name := "testcopymultiplefilestofile"
   815  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
   816  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
   817  RUN echo 'dockerio:x:1001:' >> /etc/group
   818  RUN mkdir /exists
   819  RUN touch /exists/exists_file
   820  RUN chown -R dockerio.dockerio /exists
   821  COPY test_file1 test_file2 /exists/
   822  ADD test_file3 test_file4 %s/robots.txt /exists/
   823  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
   824  RUN [ $(ls -l /exists/test_file1 | awk '{print $3":"$4}') = 'root:root' ]
   825  RUN [ $(ls -l /exists/test_file2 | awk '{print $3":"$4}') = 'root:root' ]
   826  
   827  RUN [ $(ls -l /exists/test_file3 | awk '{print $3":"$4}') = 'root:root' ]
   828  RUN [ $(ls -l /exists/test_file4 | awk '{print $3":"$4}') = 'root:root' ]
   829  RUN [ $(ls -l /exists/robots.txt | awk '{print $3":"$4}') = 'root:root' ]
   830  
   831  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
   832  `, server.URL()),
   833  		map[string]string{
   834  			"test_file1": "test1",
   835  			"test_file2": "test2",
   836  			"test_file3": "test3",
   837  			"test_file4": "test4",
   838  		})
   839  	defer ctx.Close()
   840  	if err != nil {
   841  		c.Fatal(err)
   842  	}
   843  
   844  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
   845  		c.Fatal(err)
   846  	}
   847  }
   848  
   849  func (s *DockerSuite) TestBuildAddMultipleFilesToFile(c *check.C) {
   850  	name := "testaddmultiplefilestofile"
   851  	ctx, err := fakeContext(`FROM scratch
   852  	ADD file1.txt file2.txt test
   853  	`,
   854  		map[string]string{
   855  			"file1.txt": "test1",
   856  			"file2.txt": "test1",
   857  		})
   858  	defer ctx.Close()
   859  	if err != nil {
   860  		c.Fatal(err)
   861  	}
   862  
   863  	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
   864  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   865  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
   866  	}
   867  
   868  }
   869  
   870  func (s *DockerSuite) TestBuildJSONAddMultipleFilesToFile(c *check.C) {
   871  	name := "testjsonaddmultiplefilestofile"
   872  	ctx, err := fakeContext(`FROM scratch
   873  	ADD ["file1.txt", "file2.txt", "test"]
   874  	`,
   875  		map[string]string{
   876  			"file1.txt": "test1",
   877  			"file2.txt": "test1",
   878  		})
   879  	defer ctx.Close()
   880  	if err != nil {
   881  		c.Fatal(err)
   882  	}
   883  
   884  	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
   885  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   886  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
   887  	}
   888  
   889  }
   890  
   891  func (s *DockerSuite) TestBuildAddMultipleFilesToFileWild(c *check.C) {
   892  	name := "testaddmultiplefilestofilewild"
   893  	ctx, err := fakeContext(`FROM scratch
   894  	ADD file*.txt test
   895  	`,
   896  		map[string]string{
   897  			"file1.txt": "test1",
   898  			"file2.txt": "test1",
   899  		})
   900  	defer ctx.Close()
   901  	if err != nil {
   902  		c.Fatal(err)
   903  	}
   904  
   905  	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
   906  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   907  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
   908  	}
   909  
   910  }
   911  
   912  func (s *DockerSuite) TestBuildJSONAddMultipleFilesToFileWild(c *check.C) {
   913  	name := "testjsonaddmultiplefilestofilewild"
   914  	ctx, err := fakeContext(`FROM scratch
   915  	ADD ["file*.txt", "test"]
   916  	`,
   917  		map[string]string{
   918  			"file1.txt": "test1",
   919  			"file2.txt": "test1",
   920  		})
   921  	defer ctx.Close()
   922  	if err != nil {
   923  		c.Fatal(err)
   924  	}
   925  
   926  	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
   927  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   928  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
   929  	}
   930  
   931  }
   932  
   933  func (s *DockerSuite) TestBuildCopyMultipleFilesToFile(c *check.C) {
   934  	name := "testcopymultiplefilestofile"
   935  	ctx, err := fakeContext(`FROM scratch
   936  	COPY file1.txt file2.txt test
   937  	`,
   938  		map[string]string{
   939  			"file1.txt": "test1",
   940  			"file2.txt": "test1",
   941  		})
   942  	defer ctx.Close()
   943  	if err != nil {
   944  		c.Fatal(err)
   945  	}
   946  
   947  	expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
   948  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   949  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
   950  	}
   951  
   952  }
   953  
   954  func (s *DockerSuite) TestBuildJSONCopyMultipleFilesToFile(c *check.C) {
   955  	name := "testjsoncopymultiplefilestofile"
   956  	ctx, err := fakeContext(`FROM scratch
   957  	COPY ["file1.txt", "file2.txt", "test"]
   958  	`,
   959  		map[string]string{
   960  			"file1.txt": "test1",
   961  			"file2.txt": "test1",
   962  		})
   963  	defer ctx.Close()
   964  	if err != nil {
   965  		c.Fatal(err)
   966  	}
   967  
   968  	expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
   969  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
   970  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
   971  	}
   972  
   973  }
   974  
   975  func (s *DockerSuite) TestBuildAddFileWithWhitespace(c *check.C) {
   976  	name := "testaddfilewithwhitespace"
   977  	ctx, err := fakeContext(`FROM busybox
   978  RUN mkdir "/test dir"
   979  RUN mkdir "/test_dir"
   980  ADD [ "test file1", "/test_file1" ]
   981  ADD [ "test_file2", "/test file2" ]
   982  ADD [ "test file3", "/test file3" ]
   983  ADD [ "test dir/test_file4", "/test_dir/test_file4" ]
   984  ADD [ "test_dir/test_file5", "/test dir/test_file5" ]
   985  ADD [ "test dir/test_file6", "/test dir/test_file6" ]
   986  RUN [ $(cat "/test_file1") = 'test1' ]
   987  RUN [ $(cat "/test file2") = 'test2' ]
   988  RUN [ $(cat "/test file3") = 'test3' ]
   989  RUN [ $(cat "/test_dir/test_file4") = 'test4' ]
   990  RUN [ $(cat "/test dir/test_file5") = 'test5' ]
   991  RUN [ $(cat "/test dir/test_file6") = 'test6' ]`,
   992  		map[string]string{
   993  			"test file1":          "test1",
   994  			"test_file2":          "test2",
   995  			"test file3":          "test3",
   996  			"test dir/test_file4": "test4",
   997  			"test_dir/test_file5": "test5",
   998  			"test dir/test_file6": "test6",
   999  		})
  1000  	defer ctx.Close()
  1001  	if err != nil {
  1002  		c.Fatal(err)
  1003  	}
  1004  
  1005  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1006  		c.Fatal(err)
  1007  	}
  1008  }
  1009  
  1010  func (s *DockerSuite) TestBuildCopyFileWithWhitespace(c *check.C) {
  1011  	name := "testcopyfilewithwhitespace"
  1012  	ctx, err := fakeContext(`FROM busybox
  1013  RUN mkdir "/test dir"
  1014  RUN mkdir "/test_dir"
  1015  COPY [ "test file1", "/test_file1" ]
  1016  COPY [ "test_file2", "/test file2" ]
  1017  COPY [ "test file3", "/test file3" ]
  1018  COPY [ "test dir/test_file4", "/test_dir/test_file4" ]
  1019  COPY [ "test_dir/test_file5", "/test dir/test_file5" ]
  1020  COPY [ "test dir/test_file6", "/test dir/test_file6" ]
  1021  RUN [ $(cat "/test_file1") = 'test1' ]
  1022  RUN [ $(cat "/test file2") = 'test2' ]
  1023  RUN [ $(cat "/test file3") = 'test3' ]
  1024  RUN [ $(cat "/test_dir/test_file4") = 'test4' ]
  1025  RUN [ $(cat "/test dir/test_file5") = 'test5' ]
  1026  RUN [ $(cat "/test dir/test_file6") = 'test6' ]`,
  1027  		map[string]string{
  1028  			"test file1":          "test1",
  1029  			"test_file2":          "test2",
  1030  			"test file3":          "test3",
  1031  			"test dir/test_file4": "test4",
  1032  			"test_dir/test_file5": "test5",
  1033  			"test dir/test_file6": "test6",
  1034  		})
  1035  	defer ctx.Close()
  1036  	if err != nil {
  1037  		c.Fatal(err)
  1038  	}
  1039  
  1040  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1041  		c.Fatal(err)
  1042  	}
  1043  }
  1044  
  1045  func (s *DockerSuite) TestBuildAddMultipleFilesToFileWithWhitespace(c *check.C) {
  1046  	name := "testaddmultiplefilestofilewithwhitespace"
  1047  	ctx, err := fakeContext(`FROM busybox
  1048  	ADD [ "test file1", "test file2", "test" ]
  1049      `,
  1050  		map[string]string{
  1051  			"test file1": "test1",
  1052  			"test file2": "test2",
  1053  		})
  1054  	defer ctx.Close()
  1055  	if err != nil {
  1056  		c.Fatal(err)
  1057  	}
  1058  
  1059  	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
  1060  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  1061  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  1062  	}
  1063  
  1064  }
  1065  
  1066  func (s *DockerSuite) TestBuildCopyMultipleFilesToFileWithWhitespace(c *check.C) {
  1067  	name := "testcopymultiplefilestofilewithwhitespace"
  1068  	ctx, err := fakeContext(`FROM busybox
  1069  	COPY [ "test file1", "test file2", "test" ]
  1070          `,
  1071  		map[string]string{
  1072  			"test file1": "test1",
  1073  			"test file2": "test2",
  1074  		})
  1075  	defer ctx.Close()
  1076  	if err != nil {
  1077  		c.Fatal(err)
  1078  	}
  1079  
  1080  	expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
  1081  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  1082  		c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  1083  	}
  1084  
  1085  }
  1086  
  1087  func (s *DockerSuite) TestBuildCopyWildcard(c *check.C) {
  1088  	name := "testcopywildcard"
  1089  	server, err := fakeStorage(map[string]string{
  1090  		"robots.txt": "hello",
  1091  		"index.html": "world",
  1092  	})
  1093  	if err != nil {
  1094  		c.Fatal(err)
  1095  	}
  1096  	defer server.Close()
  1097  
  1098  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1099  	COPY file*.txt /tmp/
  1100  	RUN ls /tmp/file1.txt /tmp/file2.txt
  1101  	RUN mkdir /tmp1
  1102  	COPY dir* /tmp1/
  1103  	RUN ls /tmp1/dirt /tmp1/nested_file /tmp1/nested_dir/nest_nest_file
  1104  	RUN mkdir /tmp2
  1105          ADD dir/*dir %s/robots.txt /tmp2/
  1106  	RUN ls /tmp2/nest_nest_file /tmp2/robots.txt
  1107  	`, server.URL()),
  1108  		map[string]string{
  1109  			"file1.txt":                     "test1",
  1110  			"file2.txt":                     "test2",
  1111  			"dir/nested_file":               "nested file",
  1112  			"dir/nested_dir/nest_nest_file": "2 times nested",
  1113  			"dirt": "dirty",
  1114  		})
  1115  	if err != nil {
  1116  		c.Fatal(err)
  1117  	}
  1118  	defer ctx.Close()
  1119  
  1120  	id1, err := buildImageFromContext(name, ctx, true)
  1121  	if err != nil {
  1122  		c.Fatal(err)
  1123  	}
  1124  
  1125  	// Now make sure we use a cache the 2nd time
  1126  	id2, err := buildImageFromContext(name, ctx, true)
  1127  	if err != nil {
  1128  		c.Fatal(err)
  1129  	}
  1130  
  1131  	if id1 != id2 {
  1132  		c.Fatal("didn't use the cache")
  1133  	}
  1134  
  1135  }
  1136  
  1137  func (s *DockerSuite) TestBuildCopyWildcardNoFind(c *check.C) {
  1138  	name := "testcopywildcardnofind"
  1139  	ctx, err := fakeContext(`FROM busybox
  1140  	COPY file*.txt /tmp/
  1141  	`, nil)
  1142  	defer ctx.Close()
  1143  	if err != nil {
  1144  		c.Fatal(err)
  1145  	}
  1146  
  1147  	_, err = buildImageFromContext(name, ctx, true)
  1148  	if err == nil {
  1149  		c.Fatal("should have failed to find a file")
  1150  	}
  1151  	if !strings.Contains(err.Error(), "No source files were specified") {
  1152  		c.Fatalf("Wrong error %v, must be about no source files", err)
  1153  	}
  1154  
  1155  }
  1156  
  1157  func (s *DockerSuite) TestBuildCopyWildcardInName(c *check.C) {
  1158  	name := "testcopywildcardinname"
  1159  	defer deleteImages(name)
  1160  	ctx, err := fakeContext(`FROM busybox
  1161  	COPY *.txt /tmp/
  1162  	RUN [ "$(cat /tmp/\*.txt)" = 'hi there' ]
  1163  	`, map[string]string{"*.txt": "hi there"})
  1164  
  1165  	if err != nil {
  1166  		// Normally we would do c.Fatal(err) here but given that
  1167  		// the odds of this failing are so rare, it must be because
  1168  		// the OS we're running the client on doesn't support * in
  1169  		// filenames (like windows).  So, instead of failing the test
  1170  		// just let it pass. Then we don't need to explicitly
  1171  		// say which OSs this works on or not.
  1172  		return
  1173  	}
  1174  	defer ctx.Close()
  1175  
  1176  	_, err = buildImageFromContext(name, ctx, true)
  1177  	if err != nil {
  1178  		c.Fatalf("should have built: %q", err)
  1179  	}
  1180  }
  1181  
  1182  func (s *DockerSuite) TestBuildCopyWildcardCache(c *check.C) {
  1183  	name := "testcopywildcardcache"
  1184  	ctx, err := fakeContext(`FROM busybox
  1185  	COPY file1.txt /tmp/`,
  1186  		map[string]string{
  1187  			"file1.txt": "test1",
  1188  		})
  1189  	defer ctx.Close()
  1190  	if err != nil {
  1191  		c.Fatal(err)
  1192  	}
  1193  
  1194  	id1, err := buildImageFromContext(name, ctx, true)
  1195  	if err != nil {
  1196  		c.Fatal(err)
  1197  	}
  1198  
  1199  	// Now make sure we use a cache the 2nd time even with wild cards.
  1200  	// Use the same context so the file is the same and the checksum will match
  1201  	ctx.Add("Dockerfile", `FROM busybox
  1202  	COPY file*.txt /tmp/`)
  1203  
  1204  	id2, err := buildImageFromContext(name, ctx, true)
  1205  	if err != nil {
  1206  		c.Fatal(err)
  1207  	}
  1208  
  1209  	if id1 != id2 {
  1210  		c.Fatal("didn't use the cache")
  1211  	}
  1212  
  1213  }
  1214  
  1215  func (s *DockerSuite) TestBuildAddSingleFileToNonExistingDir(c *check.C) {
  1216  	name := "testaddsinglefiletononexistingdir"
  1217  	ctx, err := fakeContext(`FROM busybox
  1218  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1219  RUN echo 'dockerio:x:1001:' >> /etc/group
  1220  RUN touch /exists
  1221  RUN chown dockerio.dockerio /exists
  1222  ADD test_file /test_dir/
  1223  RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1224  RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1225  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1226  		map[string]string{
  1227  			"test_file": "test1",
  1228  		})
  1229  	if err != nil {
  1230  		c.Fatal(err)
  1231  	}
  1232  	defer ctx.Close()
  1233  
  1234  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1235  		c.Fatal(err)
  1236  	}
  1237  
  1238  }
  1239  
  1240  func (s *DockerSuite) TestBuildAddDirContentToRoot(c *check.C) {
  1241  	name := "testadddircontenttoroot"
  1242  	ctx, err := fakeContext(`FROM busybox
  1243  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1244  RUN echo 'dockerio:x:1001:' >> /etc/group
  1245  RUN touch /exists
  1246  RUN chown dockerio.dockerio exists
  1247  ADD test_dir /
  1248  RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1249  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1250  		map[string]string{
  1251  			"test_dir/test_file": "test1",
  1252  		})
  1253  	if err != nil {
  1254  		c.Fatal(err)
  1255  	}
  1256  	defer ctx.Close()
  1257  
  1258  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1259  		c.Fatal(err)
  1260  	}
  1261  }
  1262  
  1263  func (s *DockerSuite) TestBuildAddDirContentToExistingDir(c *check.C) {
  1264  	name := "testadddircontenttoexistingdir"
  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 mkdir /exists
  1269  RUN touch /exists/exists_file
  1270  RUN chown -R dockerio.dockerio /exists
  1271  ADD test_dir/ /exists/
  1272  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1273  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1274  RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`,
  1275  		map[string]string{
  1276  			"test_dir/test_file": "test1",
  1277  		})
  1278  	if err != nil {
  1279  		c.Fatal(err)
  1280  	}
  1281  	defer ctx.Close()
  1282  
  1283  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1284  		c.Fatal(err)
  1285  	}
  1286  }
  1287  
  1288  func (s *DockerSuite) TestBuildAddWholeDirToRoot(c *check.C) {
  1289  	name := "testaddwholedirtoroot"
  1290  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1291  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1292  RUN echo 'dockerio:x:1001:' >> /etc/group
  1293  RUN touch /exists
  1294  RUN chown dockerio.dockerio exists
  1295  ADD test_dir /test_dir
  1296  RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1297  RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ]
  1298  RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1299  RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '%s' ]
  1300  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  1301  		map[string]string{
  1302  			"test_dir/test_file": "test1",
  1303  		})
  1304  	if err != nil {
  1305  		c.Fatal(err)
  1306  	}
  1307  	defer ctx.Close()
  1308  
  1309  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1310  		c.Fatal(err)
  1311  	}
  1312  }
  1313  
  1314  // Testing #5941
  1315  func (s *DockerSuite) TestBuildAddEtcToRoot(c *check.C) {
  1316  	name := "testaddetctoroot"
  1317  	ctx, err := fakeContext(`FROM scratch
  1318  ADD . /`,
  1319  		map[string]string{
  1320  			"etc/test_file": "test1",
  1321  		})
  1322  	if err != nil {
  1323  		c.Fatal(err)
  1324  	}
  1325  	defer ctx.Close()
  1326  
  1327  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1328  		c.Fatal(err)
  1329  	}
  1330  }
  1331  
  1332  // Testing #9401
  1333  func (s *DockerSuite) TestBuildAddPreservesFilesSpecialBits(c *check.C) {
  1334  	name := "testaddpreservesfilesspecialbits"
  1335  	ctx, err := fakeContext(`FROM busybox
  1336  ADD suidbin /usr/bin/suidbin
  1337  RUN chmod 4755 /usr/bin/suidbin
  1338  RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ]
  1339  ADD ./data/ /
  1340  RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ]`,
  1341  		map[string]string{
  1342  			"suidbin":             "suidbin",
  1343  			"/data/usr/test_file": "test1",
  1344  		})
  1345  	if err != nil {
  1346  		c.Fatal(err)
  1347  	}
  1348  	defer ctx.Close()
  1349  
  1350  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1351  		c.Fatal(err)
  1352  	}
  1353  }
  1354  
  1355  func (s *DockerSuite) TestBuildCopySingleFileToRoot(c *check.C) {
  1356  	name := "testcopysinglefiletoroot"
  1357  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1358  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1359  RUN echo 'dockerio:x:1001:' >> /etc/group
  1360  RUN touch /exists
  1361  RUN chown dockerio.dockerio /exists
  1362  COPY test_file /
  1363  RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1364  RUN [ $(ls -l /test_file | awk '{print $1}') = '%s' ]
  1365  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  1366  		map[string]string{
  1367  			"test_file": "test1",
  1368  		})
  1369  	if err != nil {
  1370  		c.Fatal(err)
  1371  	}
  1372  	defer ctx.Close()
  1373  
  1374  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1375  		c.Fatal(err)
  1376  	}
  1377  }
  1378  
  1379  // Issue #3960: "ADD src ." hangs - adapted for COPY
  1380  func (s *DockerSuite) TestBuildCopySingleFileToWorkdir(c *check.C) {
  1381  	name := "testcopysinglefiletoworkdir"
  1382  	ctx, err := fakeContext(`FROM busybox
  1383  COPY test_file .`,
  1384  		map[string]string{
  1385  			"test_file": "test1",
  1386  		})
  1387  	if err != nil {
  1388  		c.Fatal(err)
  1389  	}
  1390  	defer ctx.Close()
  1391  
  1392  	errChan := make(chan error)
  1393  	go func() {
  1394  		_, err := buildImageFromContext(name, ctx, true)
  1395  		errChan <- err
  1396  		close(errChan)
  1397  	}()
  1398  	select {
  1399  	case <-time.After(5 * time.Second):
  1400  		c.Fatal("Build with adding to workdir timed out")
  1401  	case err := <-errChan:
  1402  		c.Assert(err, check.IsNil)
  1403  	}
  1404  }
  1405  
  1406  func (s *DockerSuite) TestBuildCopySingleFileToExistDir(c *check.C) {
  1407  	name := "testcopysinglefiletoexistdir"
  1408  	ctx, err := fakeContext(`FROM busybox
  1409  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1410  RUN echo 'dockerio:x:1001:' >> /etc/group
  1411  RUN mkdir /exists
  1412  RUN touch /exists/exists_file
  1413  RUN chown -R dockerio.dockerio /exists
  1414  COPY test_file /exists/
  1415  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1416  RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1417  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1418  		map[string]string{
  1419  			"test_file": "test1",
  1420  		})
  1421  	if err != nil {
  1422  		c.Fatal(err)
  1423  	}
  1424  	defer ctx.Close()
  1425  
  1426  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1427  		c.Fatal(err)
  1428  	}
  1429  }
  1430  
  1431  func (s *DockerSuite) TestBuildCopySingleFileToNonExistDir(c *check.C) {
  1432  	name := "testcopysinglefiletononexistdir"
  1433  	ctx, err := fakeContext(`FROM busybox
  1434  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1435  RUN echo 'dockerio:x:1001:' >> /etc/group
  1436  RUN touch /exists
  1437  RUN chown dockerio.dockerio /exists
  1438  COPY test_file /test_dir/
  1439  RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1440  RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1441  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1442  		map[string]string{
  1443  			"test_file": "test1",
  1444  		})
  1445  	if err != nil {
  1446  		c.Fatal(err)
  1447  	}
  1448  	defer ctx.Close()
  1449  
  1450  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1451  		c.Fatal(err)
  1452  	}
  1453  }
  1454  
  1455  func (s *DockerSuite) TestBuildCopyDirContentToRoot(c *check.C) {
  1456  	name := "testcopydircontenttoroot"
  1457  	ctx, err := fakeContext(`FROM busybox
  1458  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1459  RUN echo 'dockerio:x:1001:' >> /etc/group
  1460  RUN touch /exists
  1461  RUN chown dockerio.dockerio exists
  1462  COPY test_dir /
  1463  RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1464  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1465  		map[string]string{
  1466  			"test_dir/test_file": "test1",
  1467  		})
  1468  	if err != nil {
  1469  		c.Fatal(err)
  1470  	}
  1471  	defer ctx.Close()
  1472  
  1473  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1474  		c.Fatal(err)
  1475  	}
  1476  }
  1477  
  1478  func (s *DockerSuite) TestBuildCopyDirContentToExistDir(c *check.C) {
  1479  	name := "testcopydircontenttoexistdir"
  1480  	ctx, err := fakeContext(`FROM busybox
  1481  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1482  RUN echo 'dockerio:x:1001:' >> /etc/group
  1483  RUN mkdir /exists
  1484  RUN touch /exists/exists_file
  1485  RUN chown -R dockerio.dockerio /exists
  1486  COPY test_dir/ /exists/
  1487  RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1488  RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1489  RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`,
  1490  		map[string]string{
  1491  			"test_dir/test_file": "test1",
  1492  		})
  1493  	if err != nil {
  1494  		c.Fatal(err)
  1495  	}
  1496  	defer ctx.Close()
  1497  
  1498  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1499  		c.Fatal(err)
  1500  	}
  1501  }
  1502  
  1503  func (s *DockerSuite) TestBuildCopyWholeDirToRoot(c *check.C) {
  1504  	name := "testcopywholedirtoroot"
  1505  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1506  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1507  RUN echo 'dockerio:x:1001:' >> /etc/group
  1508  RUN touch /exists
  1509  RUN chown dockerio.dockerio exists
  1510  COPY test_dir /test_dir
  1511  RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1512  RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ]
  1513  RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1514  RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '%s' ]
  1515  RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  1516  		map[string]string{
  1517  			"test_dir/test_file": "test1",
  1518  		})
  1519  	if err != nil {
  1520  		c.Fatal(err)
  1521  	}
  1522  	defer ctx.Close()
  1523  
  1524  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1525  		c.Fatal(err)
  1526  	}
  1527  }
  1528  
  1529  func (s *DockerSuite) TestBuildCopyEtcToRoot(c *check.C) {
  1530  	name := "testcopyetctoroot"
  1531  	ctx, err := fakeContext(`FROM scratch
  1532  COPY . /`,
  1533  		map[string]string{
  1534  			"etc/test_file": "test1",
  1535  		})
  1536  	if err != nil {
  1537  		c.Fatal(err)
  1538  	}
  1539  	defer ctx.Close()
  1540  
  1541  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1542  		c.Fatal(err)
  1543  	}
  1544  }
  1545  
  1546  func (s *DockerSuite) TestBuildCopyDisallowRemote(c *check.C) {
  1547  	name := "testcopydisallowremote"
  1548  	_, out, err := buildImageWithOut(name, `FROM scratch
  1549  COPY https://index.docker.io/robots.txt /`,
  1550  		true)
  1551  	if err == nil || !strings.Contains(out, "Source can't be a URL for COPY") {
  1552  		c.Fatalf("Error should be about disallowed remote source, got err: %s, out: %q", err, out)
  1553  	}
  1554  }
  1555  
  1556  func (s *DockerSuite) TestBuildAddBadLinks(c *check.C) {
  1557  	const (
  1558  		dockerfile = `
  1559  			FROM scratch
  1560  			ADD links.tar /
  1561  			ADD foo.txt /symlink/
  1562  			`
  1563  		targetFile = "foo.txt"
  1564  	)
  1565  	var (
  1566  		name = "test-link-absolute"
  1567  	)
  1568  	ctx, err := fakeContext(dockerfile, nil)
  1569  	if err != nil {
  1570  		c.Fatal(err)
  1571  	}
  1572  	defer ctx.Close()
  1573  
  1574  	tempDir, err := ioutil.TempDir("", "test-link-absolute-temp-")
  1575  	if err != nil {
  1576  		c.Fatalf("failed to create temporary directory: %s", tempDir)
  1577  	}
  1578  	defer os.RemoveAll(tempDir)
  1579  
  1580  	var symlinkTarget string
  1581  	if runtime.GOOS == "windows" {
  1582  		var driveLetter string
  1583  		if abs, err := filepath.Abs(tempDir); err != nil {
  1584  			c.Fatal(err)
  1585  		} else {
  1586  			driveLetter = abs[:1]
  1587  		}
  1588  		tempDirWithoutDrive := tempDir[2:]
  1589  		symlinkTarget = fmt.Sprintf(`%s:\..\..\..\..\..\..\..\..\..\..\..\..%s`, driveLetter, tempDirWithoutDrive)
  1590  	} else {
  1591  		symlinkTarget = fmt.Sprintf("/../../../../../../../../../../../..%s", tempDir)
  1592  	}
  1593  
  1594  	tarPath := filepath.Join(ctx.Dir, "links.tar")
  1595  	nonExistingFile := filepath.Join(tempDir, targetFile)
  1596  	fooPath := filepath.Join(ctx.Dir, targetFile)
  1597  
  1598  	tarOut, err := os.Create(tarPath)
  1599  	if err != nil {
  1600  		c.Fatal(err)
  1601  	}
  1602  
  1603  	tarWriter := tar.NewWriter(tarOut)
  1604  
  1605  	header := &tar.Header{
  1606  		Name:     "symlink",
  1607  		Typeflag: tar.TypeSymlink,
  1608  		Linkname: symlinkTarget,
  1609  		Mode:     0755,
  1610  		Uid:      0,
  1611  		Gid:      0,
  1612  	}
  1613  
  1614  	err = tarWriter.WriteHeader(header)
  1615  	if err != nil {
  1616  		c.Fatal(err)
  1617  	}
  1618  
  1619  	tarWriter.Close()
  1620  	tarOut.Close()
  1621  
  1622  	foo, err := os.Create(fooPath)
  1623  	if err != nil {
  1624  		c.Fatal(err)
  1625  	}
  1626  	defer foo.Close()
  1627  
  1628  	if _, err := foo.WriteString("test"); err != nil {
  1629  		c.Fatal(err)
  1630  	}
  1631  
  1632  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1633  		c.Fatal(err)
  1634  	}
  1635  
  1636  	if _, err := os.Stat(nonExistingFile); err == nil || err != nil && !os.IsNotExist(err) {
  1637  		c.Fatalf("%s shouldn't have been written and it shouldn't exist", nonExistingFile)
  1638  	}
  1639  
  1640  }
  1641  
  1642  func (s *DockerSuite) TestBuildAddBadLinksVolume(c *check.C) {
  1643  	const (
  1644  		dockerfileTemplate = `
  1645  		FROM busybox
  1646  		RUN ln -s /../../../../../../../../%s /x
  1647  		VOLUME /x
  1648  		ADD foo.txt /x/`
  1649  		targetFile = "foo.txt"
  1650  	)
  1651  	var (
  1652  		name       = "test-link-absolute-volume"
  1653  		dockerfile = ""
  1654  	)
  1655  
  1656  	tempDir, err := ioutil.TempDir("", "test-link-absolute-volume-temp-")
  1657  	if err != nil {
  1658  		c.Fatalf("failed to create temporary directory: %s", tempDir)
  1659  	}
  1660  	defer os.RemoveAll(tempDir)
  1661  
  1662  	dockerfile = fmt.Sprintf(dockerfileTemplate, tempDir)
  1663  	nonExistingFile := filepath.Join(tempDir, targetFile)
  1664  
  1665  	ctx, err := fakeContext(dockerfile, nil)
  1666  	if err != nil {
  1667  		c.Fatal(err)
  1668  	}
  1669  	defer ctx.Close()
  1670  	fooPath := filepath.Join(ctx.Dir, targetFile)
  1671  
  1672  	foo, err := os.Create(fooPath)
  1673  	if err != nil {
  1674  		c.Fatal(err)
  1675  	}
  1676  	defer foo.Close()
  1677  
  1678  	if _, err := foo.WriteString("test"); err != nil {
  1679  		c.Fatal(err)
  1680  	}
  1681  
  1682  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1683  		c.Fatal(err)
  1684  	}
  1685  
  1686  	if _, err := os.Stat(nonExistingFile); err == nil || err != nil && !os.IsNotExist(err) {
  1687  		c.Fatalf("%s shouldn't have been written and it shouldn't exist", nonExistingFile)
  1688  	}
  1689  
  1690  }
  1691  
  1692  // Issue #5270 - ensure we throw a better error than "unexpected EOF"
  1693  // when we can't access files in the context.
  1694  func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) {
  1695  	testRequires(c, UnixCli) // test uses chown/chmod: not available on windows
  1696  
  1697  	{
  1698  		name := "testbuildinaccessiblefiles"
  1699  		ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{"fileWithoutReadAccess": "foo"})
  1700  		if err != nil {
  1701  			c.Fatal(err)
  1702  		}
  1703  		defer ctx.Close()
  1704  		// This is used to ensure we detect inaccessible files early during build in the cli client
  1705  		pathToFileWithoutReadAccess := filepath.Join(ctx.Dir, "fileWithoutReadAccess")
  1706  
  1707  		if err = os.Chown(pathToFileWithoutReadAccess, 0, 0); err != nil {
  1708  			c.Fatalf("failed to chown file to root: %s", err)
  1709  		}
  1710  		if err = os.Chmod(pathToFileWithoutReadAccess, 0700); err != nil {
  1711  			c.Fatalf("failed to chmod file to 700: %s", err)
  1712  		}
  1713  		buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1714  		buildCmd.Dir = ctx.Dir
  1715  		out, _, err := runCommandWithOutput(buildCmd)
  1716  		if err == nil {
  1717  			c.Fatalf("build should have failed: %s %s", err, out)
  1718  		}
  1719  
  1720  		// check if we've detected the failure before we started building
  1721  		if !strings.Contains(out, "no permission to read from ") {
  1722  			c.Fatalf("output should've contained the string: no permission to read from but contained: %s", out)
  1723  		}
  1724  
  1725  		if !strings.Contains(out, "Error checking context") {
  1726  			c.Fatalf("output should've contained the string: Error checking context")
  1727  		}
  1728  	}
  1729  	{
  1730  		name := "testbuildinaccessibledirectory"
  1731  		ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{"directoryWeCantStat/bar": "foo"})
  1732  		if err != nil {
  1733  			c.Fatal(err)
  1734  		}
  1735  		defer ctx.Close()
  1736  		// This is used to ensure we detect inaccessible directories early during build in the cli client
  1737  		pathToDirectoryWithoutReadAccess := filepath.Join(ctx.Dir, "directoryWeCantStat")
  1738  		pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar")
  1739  
  1740  		if err = os.Chown(pathToDirectoryWithoutReadAccess, 0, 0); err != nil {
  1741  			c.Fatalf("failed to chown directory to root: %s", err)
  1742  		}
  1743  		if err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444); err != nil {
  1744  			c.Fatalf("failed to chmod directory to 444: %s", err)
  1745  		}
  1746  		if err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700); err != nil {
  1747  			c.Fatalf("failed to chmod file to 700: %s", err)
  1748  		}
  1749  
  1750  		buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1751  		buildCmd.Dir = ctx.Dir
  1752  		out, _, err := runCommandWithOutput(buildCmd)
  1753  		if err == nil {
  1754  			c.Fatalf("build should have failed: %s %s", err, out)
  1755  		}
  1756  
  1757  		// check if we've detected the failure before we started building
  1758  		if !strings.Contains(out, "can't stat") {
  1759  			c.Fatalf("output should've contained the string: can't access %s", out)
  1760  		}
  1761  
  1762  		if !strings.Contains(out, "Error checking context") {
  1763  			c.Fatalf("output should've contained the string: Error checking context\ngot:%s", out)
  1764  		}
  1765  
  1766  	}
  1767  	{
  1768  		name := "testlinksok"
  1769  		ctx, err := fakeContext("FROM scratch\nADD . /foo/", nil)
  1770  		if err != nil {
  1771  			c.Fatal(err)
  1772  		}
  1773  		defer ctx.Close()
  1774  
  1775  		target := "../../../../../../../../../../../../../../../../../../../azA"
  1776  		if err := os.Symlink(filepath.Join(ctx.Dir, "g"), target); err != nil {
  1777  			c.Fatal(err)
  1778  		}
  1779  		defer os.Remove(target)
  1780  		// This is used to ensure we don't follow links when checking if everything in the context is accessible
  1781  		// This test doesn't require that we run commands as an unprivileged user
  1782  		if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1783  			c.Fatal(err)
  1784  		}
  1785  	}
  1786  	{
  1787  		name := "testbuildignoredinaccessible"
  1788  		ctx, err := fakeContext("FROM scratch\nADD . /foo/",
  1789  			map[string]string{
  1790  				"directoryWeCantStat/bar": "foo",
  1791  				".dockerignore":           "directoryWeCantStat",
  1792  			})
  1793  		if err != nil {
  1794  			c.Fatal(err)
  1795  		}
  1796  		defer ctx.Close()
  1797  		// This is used to ensure we don't try to add inaccessible files when they are ignored by a .dockerignore pattern
  1798  		pathToDirectoryWithoutReadAccess := filepath.Join(ctx.Dir, "directoryWeCantStat")
  1799  		pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar")
  1800  		if err = os.Chown(pathToDirectoryWithoutReadAccess, 0, 0); err != nil {
  1801  			c.Fatalf("failed to chown directory to root: %s", err)
  1802  		}
  1803  		if err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444); err != nil {
  1804  			c.Fatalf("failed to chmod directory to 755: %s", err)
  1805  		}
  1806  		if err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700); err != nil {
  1807  			c.Fatalf("failed to chmod file to 444: %s", err)
  1808  		}
  1809  
  1810  		buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1811  		buildCmd.Dir = ctx.Dir
  1812  		if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  1813  			c.Fatalf("build should have worked: %s %s", err, out)
  1814  		}
  1815  
  1816  	}
  1817  }
  1818  
  1819  func (s *DockerSuite) TestBuildForceRm(c *check.C) {
  1820  	containerCountBefore, err := getContainerCount()
  1821  	if err != nil {
  1822  		c.Fatalf("failed to get the container count: %s", err)
  1823  	}
  1824  	name := "testbuildforcerm"
  1825  	ctx, err := fakeContext("FROM scratch\nRUN true\nRUN thiswillfail", nil)
  1826  	if err != nil {
  1827  		c.Fatal(err)
  1828  	}
  1829  	defer ctx.Close()
  1830  
  1831  	buildCmd := exec.Command(dockerBinary, "build", "-t", name, "--force-rm", ".")
  1832  	buildCmd.Dir = ctx.Dir
  1833  	if out, _, err := runCommandWithOutput(buildCmd); err == nil {
  1834  		c.Fatalf("failed to build the image: %s, %v", out, err)
  1835  	}
  1836  
  1837  	containerCountAfter, err := getContainerCount()
  1838  	if err != nil {
  1839  		c.Fatalf("failed to get the container count: %s", err)
  1840  	}
  1841  
  1842  	if containerCountBefore != containerCountAfter {
  1843  		c.Fatalf("--force-rm shouldn't have left containers behind")
  1844  	}
  1845  
  1846  }
  1847  
  1848  // Test that an infinite sleep during a build is killed if the client disconnects.
  1849  // This test is fairly hairy because there are lots of ways to race.
  1850  // Strategy:
  1851  // * Monitor the output of docker events starting from before
  1852  // * Run a 1-year-long sleep from a docker build.
  1853  // * When docker events sees container start, close the "docker build" command
  1854  // * Wait for docker events to emit a dying event.
  1855  func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) {
  1856  	name := "testbuildcancelation"
  1857  
  1858  	// (Note: one year, will never finish)
  1859  	ctx, err := fakeContext("FROM busybox\nRUN sleep 31536000", nil)
  1860  	if err != nil {
  1861  		c.Fatal(err)
  1862  	}
  1863  	defer ctx.Close()
  1864  
  1865  	finish := make(chan struct{})
  1866  	defer close(finish)
  1867  
  1868  	eventStart := make(chan struct{})
  1869  	eventDie := make(chan struct{})
  1870  	containerID := make(chan string)
  1871  
  1872  	startEpoch := daemonTime(c).Unix()
  1873  	// Watch for events since epoch.
  1874  	eventsCmd := exec.Command(
  1875  		dockerBinary, "events",
  1876  		"--since", strconv.FormatInt(startEpoch, 10))
  1877  	stdout, err := eventsCmd.StdoutPipe()
  1878  	if err != nil {
  1879  		c.Fatal(err)
  1880  	}
  1881  	if err := eventsCmd.Start(); err != nil {
  1882  		c.Fatal(err)
  1883  	}
  1884  	defer eventsCmd.Process.Kill()
  1885  
  1886  	// Goroutine responsible for watching start/die events from `docker events`
  1887  	go func() {
  1888  		cid := <-containerID
  1889  
  1890  		matchStart := regexp.MustCompile(cid + `(.*) start$`)
  1891  		matchDie := regexp.MustCompile(cid + `(.*) die$`)
  1892  
  1893  		//
  1894  		// Read lines of `docker events` looking for container start and stop.
  1895  		//
  1896  		scanner := bufio.NewScanner(stdout)
  1897  		for scanner.Scan() {
  1898  			switch {
  1899  			case matchStart.MatchString(scanner.Text()):
  1900  				close(eventStart)
  1901  			case matchDie.MatchString(scanner.Text()):
  1902  				close(eventDie)
  1903  			}
  1904  		}
  1905  	}()
  1906  
  1907  	buildCmd := exec.Command(dockerBinary, "build", "-t", name, ".")
  1908  	buildCmd.Dir = ctx.Dir
  1909  
  1910  	stdoutBuild, err := buildCmd.StdoutPipe()
  1911  	if err := buildCmd.Start(); err != nil {
  1912  		c.Fatalf("failed to run build: %s", err)
  1913  	}
  1914  
  1915  	matchCID := regexp.MustCompile("Running in ")
  1916  	scanner := bufio.NewScanner(stdoutBuild)
  1917  	for scanner.Scan() {
  1918  		line := scanner.Text()
  1919  		if ok := matchCID.MatchString(line); ok {
  1920  			containerID <- line[len(line)-12:]
  1921  			break
  1922  		}
  1923  	}
  1924  
  1925  	select {
  1926  	case <-time.After(5 * time.Second):
  1927  		c.Fatal("failed to observe build container start in timely fashion")
  1928  	case <-eventStart:
  1929  		// Proceeds from here when we see the container fly past in the
  1930  		// output of "docker events".
  1931  		// Now we know the container is running.
  1932  	}
  1933  
  1934  	// Send a kill to the `docker build` command.
  1935  	// Causes the underlying build to be cancelled due to socket close.
  1936  	if err := buildCmd.Process.Kill(); err != nil {
  1937  		c.Fatalf("error killing build command: %s", err)
  1938  	}
  1939  
  1940  	// Get the exit status of `docker build`, check it exited because killed.
  1941  	if err := buildCmd.Wait(); err != nil && !IsKilled(err) {
  1942  		c.Fatalf("wait failed during build run: %T %s", err, err)
  1943  	}
  1944  
  1945  	select {
  1946  	case <-time.After(5 * time.Second):
  1947  		// If we don't get here in a timely fashion, it wasn't killed.
  1948  		c.Fatal("container cancel did not succeed")
  1949  	case <-eventDie:
  1950  		// We saw the container shut down in the `docker events` stream,
  1951  		// as expected.
  1952  	}
  1953  
  1954  }
  1955  
  1956  func (s *DockerSuite) TestBuildRm(c *check.C) {
  1957  	name := "testbuildrm"
  1958  	ctx, err := fakeContext("FROM scratch\nADD foo /\nADD foo /", map[string]string{"foo": "bar"})
  1959  	if err != nil {
  1960  		c.Fatal(err)
  1961  	}
  1962  	defer ctx.Close()
  1963  	{
  1964  		containerCountBefore, err := getContainerCount()
  1965  		if err != nil {
  1966  			c.Fatalf("failed to get the container count: %s", err)
  1967  		}
  1968  
  1969  		out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--rm", "-t", name, ".")
  1970  
  1971  		if err != nil {
  1972  			c.Fatal("failed to build the image", out)
  1973  		}
  1974  
  1975  		containerCountAfter, err := getContainerCount()
  1976  		if err != nil {
  1977  			c.Fatalf("failed to get the container count: %s", err)
  1978  		}
  1979  
  1980  		if containerCountBefore != containerCountAfter {
  1981  			c.Fatalf("-rm shouldn't have left containers behind")
  1982  		}
  1983  		deleteImages(name)
  1984  	}
  1985  
  1986  	{
  1987  		containerCountBefore, err := getContainerCount()
  1988  		if err != nil {
  1989  			c.Fatalf("failed to get the container count: %s", err)
  1990  		}
  1991  
  1992  		out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", name, ".")
  1993  
  1994  		if err != nil {
  1995  			c.Fatal("failed to build the image", out)
  1996  		}
  1997  
  1998  		containerCountAfter, err := getContainerCount()
  1999  		if err != nil {
  2000  			c.Fatalf("failed to get the container count: %s", err)
  2001  		}
  2002  
  2003  		if containerCountBefore != containerCountAfter {
  2004  			c.Fatalf("--rm shouldn't have left containers behind")
  2005  		}
  2006  		deleteImages(name)
  2007  	}
  2008  
  2009  	{
  2010  		containerCountBefore, err := getContainerCount()
  2011  		if err != nil {
  2012  			c.Fatalf("failed to get the container count: %s", err)
  2013  		}
  2014  
  2015  		out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--rm=false", "-t", name, ".")
  2016  
  2017  		if err != nil {
  2018  			c.Fatal("failed to build the image", out)
  2019  		}
  2020  
  2021  		containerCountAfter, err := getContainerCount()
  2022  		if err != nil {
  2023  			c.Fatalf("failed to get the container count: %s", err)
  2024  		}
  2025  
  2026  		if containerCountBefore == containerCountAfter {
  2027  			c.Fatalf("--rm=false should have left containers behind")
  2028  		}
  2029  		deleteImages(name)
  2030  
  2031  	}
  2032  
  2033  }
  2034  
  2035  func (s *DockerSuite) TestBuildWithVolumes(c *check.C) {
  2036  	var (
  2037  		result   map[string]map[string]struct{}
  2038  		name     = "testbuildvolumes"
  2039  		emptyMap = make(map[string]struct{})
  2040  		expected = map[string]map[string]struct{}{
  2041  			"/test1":  emptyMap,
  2042  			"/test2":  emptyMap,
  2043  			"/test3":  emptyMap,
  2044  			"/test4":  emptyMap,
  2045  			"/test5":  emptyMap,
  2046  			"/test6":  emptyMap,
  2047  			"[/test7": emptyMap,
  2048  			"/test8]": emptyMap,
  2049  		}
  2050  	)
  2051  	_, err := buildImage(name,
  2052  		`FROM scratch
  2053  		VOLUME /test1
  2054  		VOLUME /test2
  2055      VOLUME /test3 /test4
  2056      VOLUME ["/test5", "/test6"]
  2057      VOLUME [/test7 /test8]
  2058      `,
  2059  		true)
  2060  	if err != nil {
  2061  		c.Fatal(err)
  2062  	}
  2063  	res, err := inspectFieldJSON(name, "Config.Volumes")
  2064  	if err != nil {
  2065  		c.Fatal(err)
  2066  	}
  2067  
  2068  	err = unmarshalJSON([]byte(res), &result)
  2069  	if err != nil {
  2070  		c.Fatal(err)
  2071  	}
  2072  
  2073  	equal := reflect.DeepEqual(&result, &expected)
  2074  
  2075  	if !equal {
  2076  		c.Fatalf("Volumes %s, expected %s", result, expected)
  2077  	}
  2078  
  2079  }
  2080  
  2081  func (s *DockerSuite) TestBuildMaintainer(c *check.C) {
  2082  	name := "testbuildmaintainer"
  2083  	expected := "dockerio"
  2084  	_, err := buildImage(name,
  2085  		`FROM scratch
  2086          MAINTAINER dockerio`,
  2087  		true)
  2088  	if err != nil {
  2089  		c.Fatal(err)
  2090  	}
  2091  	res, err := inspectField(name, "Author")
  2092  	if err != nil {
  2093  		c.Fatal(err)
  2094  	}
  2095  	if res != expected {
  2096  		c.Fatalf("Maintainer %s, expected %s", res, expected)
  2097  	}
  2098  }
  2099  
  2100  func (s *DockerSuite) TestBuildUser(c *check.C) {
  2101  	name := "testbuilduser"
  2102  	expected := "dockerio"
  2103  	_, err := buildImage(name,
  2104  		`FROM busybox
  2105  		RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  2106  		USER dockerio
  2107  		RUN [ $(whoami) = 'dockerio' ]`,
  2108  		true)
  2109  	if err != nil {
  2110  		c.Fatal(err)
  2111  	}
  2112  	res, err := inspectField(name, "Config.User")
  2113  	if err != nil {
  2114  		c.Fatal(err)
  2115  	}
  2116  	if res != expected {
  2117  		c.Fatalf("User %s, expected %s", res, expected)
  2118  	}
  2119  }
  2120  
  2121  func (s *DockerSuite) TestBuildRelativeWorkdir(c *check.C) {
  2122  	name := "testbuildrelativeworkdir"
  2123  	expected := "/test2/test3"
  2124  	_, err := buildImage(name,
  2125  		`FROM busybox
  2126  		RUN [ "$PWD" = '/' ]
  2127  		WORKDIR test1
  2128  		RUN [ "$PWD" = '/test1' ]
  2129  		WORKDIR /test2
  2130  		RUN [ "$PWD" = '/test2' ]
  2131  		WORKDIR test3
  2132  		RUN [ "$PWD" = '/test2/test3' ]`,
  2133  		true)
  2134  	if err != nil {
  2135  		c.Fatal(err)
  2136  	}
  2137  	res, err := inspectField(name, "Config.WorkingDir")
  2138  	if err != nil {
  2139  		c.Fatal(err)
  2140  	}
  2141  	if res != expected {
  2142  		c.Fatalf("Workdir %s, expected %s", res, expected)
  2143  	}
  2144  }
  2145  
  2146  func (s *DockerSuite) TestBuildWorkdirWithEnvVariables(c *check.C) {
  2147  	name := "testbuildworkdirwithenvvariables"
  2148  	expected := "/test1/test2"
  2149  	_, err := buildImage(name,
  2150  		`FROM busybox
  2151  		ENV DIRPATH /test1
  2152  		ENV SUBDIRNAME test2
  2153  		WORKDIR $DIRPATH
  2154  		WORKDIR $SUBDIRNAME/$MISSING_VAR`,
  2155  		true)
  2156  	if err != nil {
  2157  		c.Fatal(err)
  2158  	}
  2159  	res, err := inspectField(name, "Config.WorkingDir")
  2160  	if err != nil {
  2161  		c.Fatal(err)
  2162  	}
  2163  	if res != expected {
  2164  		c.Fatalf("Workdir %s, expected %s", res, expected)
  2165  	}
  2166  }
  2167  
  2168  func (s *DockerSuite) TestBuildRelativeCopy(c *check.C) {
  2169  	name := "testbuildrelativecopy"
  2170  	dockerfile := `
  2171  		FROM busybox
  2172  			WORKDIR /test1
  2173  			WORKDIR test2
  2174  			RUN [ "$PWD" = '/test1/test2' ]
  2175  			COPY foo ./
  2176  			RUN [ "$(cat /test1/test2/foo)" = 'hello' ]
  2177  			ADD foo ./bar/baz
  2178  			RUN [ "$(cat /test1/test2/bar/baz)" = 'hello' ]
  2179  			COPY foo ./bar/baz2
  2180  			RUN [ "$(cat /test1/test2/bar/baz2)" = 'hello' ]
  2181  			WORKDIR ..
  2182  			COPY foo ./
  2183  			RUN [ "$(cat /test1/foo)" = 'hello' ]
  2184  			COPY foo /test3/
  2185  			RUN [ "$(cat /test3/foo)" = 'hello' ]
  2186  			WORKDIR /test4
  2187  			COPY . .
  2188  			RUN [ "$(cat /test4/foo)" = 'hello' ]
  2189  			WORKDIR /test5/test6
  2190  			COPY foo ../
  2191  			RUN [ "$(cat /test5/foo)" = 'hello' ]
  2192  			`
  2193  	ctx, err := fakeContext(dockerfile, map[string]string{
  2194  		"foo": "hello",
  2195  	})
  2196  	defer ctx.Close()
  2197  	if err != nil {
  2198  		c.Fatal(err)
  2199  	}
  2200  	_, err = buildImageFromContext(name, ctx, false)
  2201  	if err != nil {
  2202  		c.Fatal(err)
  2203  	}
  2204  }
  2205  
  2206  func (s *DockerSuite) TestBuildEnv(c *check.C) {
  2207  	name := "testbuildenv"
  2208  	expected := "[PATH=/test:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PORT=2375]"
  2209  	_, err := buildImage(name,
  2210  		`FROM busybox
  2211  		ENV PATH /test:$PATH
  2212          ENV PORT 2375
  2213  		RUN [ $(env | grep PORT) = 'PORT=2375' ]`,
  2214  		true)
  2215  	if err != nil {
  2216  		c.Fatal(err)
  2217  	}
  2218  	res, err := inspectField(name, "Config.Env")
  2219  	if err != nil {
  2220  		c.Fatal(err)
  2221  	}
  2222  	if res != expected {
  2223  		c.Fatalf("Env %s, expected %s", res, expected)
  2224  	}
  2225  }
  2226  
  2227  func (s *DockerSuite) TestBuildContextCleanup(c *check.C) {
  2228  	testRequires(c, SameHostDaemon)
  2229  
  2230  	name := "testbuildcontextcleanup"
  2231  	entries, err := ioutil.ReadDir("/var/lib/docker/tmp")
  2232  	if err != nil {
  2233  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2234  	}
  2235  	_, err = buildImage(name,
  2236  		`FROM scratch
  2237          ENTRYPOINT ["/bin/echo"]`,
  2238  		true)
  2239  	if err != nil {
  2240  		c.Fatal(err)
  2241  	}
  2242  	entriesFinal, err := ioutil.ReadDir("/var/lib/docker/tmp")
  2243  	if err != nil {
  2244  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2245  	}
  2246  	if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  2247  		c.Fatalf("context should have been deleted, but wasn't")
  2248  	}
  2249  
  2250  }
  2251  
  2252  func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *check.C) {
  2253  	testRequires(c, SameHostDaemon)
  2254  
  2255  	name := "testbuildcontextcleanup"
  2256  	entries, err := ioutil.ReadDir("/var/lib/docker/tmp")
  2257  	if err != nil {
  2258  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2259  	}
  2260  	_, err = buildImage(name,
  2261  		`FROM scratch
  2262  	RUN /non/existing/command`,
  2263  		true)
  2264  	if err == nil {
  2265  		c.Fatalf("expected build to fail, but it didn't")
  2266  	}
  2267  	entriesFinal, err := ioutil.ReadDir("/var/lib/docker/tmp")
  2268  	if err != nil {
  2269  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2270  	}
  2271  	if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  2272  		c.Fatalf("context should have been deleted, but wasn't")
  2273  	}
  2274  
  2275  }
  2276  
  2277  func (s *DockerSuite) TestBuildCmd(c *check.C) {
  2278  	name := "testbuildcmd"
  2279  	expected := "{[/bin/echo Hello World]}"
  2280  	_, err := buildImage(name,
  2281  		`FROM scratch
  2282          CMD ["/bin/echo", "Hello World"]`,
  2283  		true)
  2284  	if err != nil {
  2285  		c.Fatal(err)
  2286  	}
  2287  	res, err := inspectField(name, "Config.Cmd")
  2288  	if err != nil {
  2289  		c.Fatal(err)
  2290  	}
  2291  	if res != expected {
  2292  		c.Fatalf("Cmd %s, expected %s", res, expected)
  2293  	}
  2294  }
  2295  
  2296  func (s *DockerSuite) TestBuildExpose(c *check.C) {
  2297  	name := "testbuildexpose"
  2298  	expected := "map[2375/tcp:{}]"
  2299  	_, err := buildImage(name,
  2300  		`FROM scratch
  2301          EXPOSE 2375`,
  2302  		true)
  2303  	if err != nil {
  2304  		c.Fatal(err)
  2305  	}
  2306  	res, err := inspectField(name, "Config.ExposedPorts")
  2307  	if err != nil {
  2308  		c.Fatal(err)
  2309  	}
  2310  	if res != expected {
  2311  		c.Fatalf("Exposed ports %s, expected %s", res, expected)
  2312  	}
  2313  }
  2314  
  2315  func (s *DockerSuite) TestBuildExposeMorePorts(c *check.C) {
  2316  	// start building docker file with a large number of ports
  2317  	portList := make([]string, 50)
  2318  	line := make([]string, 100)
  2319  	expectedPorts := make([]int, len(portList)*len(line))
  2320  	for i := 0; i < len(portList); i++ {
  2321  		for j := 0; j < len(line); j++ {
  2322  			p := i*len(line) + j + 1
  2323  			line[j] = strconv.Itoa(p)
  2324  			expectedPorts[p-1] = p
  2325  		}
  2326  		if i == len(portList)-1 {
  2327  			portList[i] = strings.Join(line, " ")
  2328  		} else {
  2329  			portList[i] = strings.Join(line, " ") + ` \`
  2330  		}
  2331  	}
  2332  
  2333  	dockerfile := `FROM scratch
  2334  	EXPOSE {{range .}} {{.}}
  2335  	{{end}}`
  2336  	tmpl := template.Must(template.New("dockerfile").Parse(dockerfile))
  2337  	buf := bytes.NewBuffer(nil)
  2338  	tmpl.Execute(buf, portList)
  2339  
  2340  	name := "testbuildexpose"
  2341  	_, err := buildImage(name, buf.String(), true)
  2342  	if err != nil {
  2343  		c.Fatal(err)
  2344  	}
  2345  
  2346  	// check if all the ports are saved inside Config.ExposedPorts
  2347  	res, err := inspectFieldJSON(name, "Config.ExposedPorts")
  2348  	if err != nil {
  2349  		c.Fatal(err)
  2350  	}
  2351  	var exposedPorts map[string]interface{}
  2352  	if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
  2353  		c.Fatal(err)
  2354  	}
  2355  
  2356  	for _, p := range expectedPorts {
  2357  		ep := fmt.Sprintf("%d/tcp", p)
  2358  		if _, ok := exposedPorts[ep]; !ok {
  2359  			c.Errorf("Port(%s) is not exposed", ep)
  2360  		} else {
  2361  			delete(exposedPorts, ep)
  2362  		}
  2363  	}
  2364  	if len(exposedPorts) != 0 {
  2365  		c.Errorf("Unexpected extra exposed ports %v", exposedPorts)
  2366  	}
  2367  }
  2368  
  2369  func (s *DockerSuite) TestBuildExposeOrder(c *check.C) {
  2370  	buildID := func(name, exposed string) string {
  2371  		_, err := buildImage(name, fmt.Sprintf(`FROM scratch
  2372  		EXPOSE %s`, exposed), true)
  2373  		if err != nil {
  2374  			c.Fatal(err)
  2375  		}
  2376  		id, err := inspectField(name, "Id")
  2377  		if err != nil {
  2378  			c.Fatal(err)
  2379  		}
  2380  		return id
  2381  	}
  2382  
  2383  	id1 := buildID("testbuildexpose1", "80 2375")
  2384  	id2 := buildID("testbuildexpose2", "2375 80")
  2385  	if id1 != id2 {
  2386  		c.Errorf("EXPOSE should invalidate the cache only when ports actually changed")
  2387  	}
  2388  }
  2389  
  2390  func (s *DockerSuite) TestBuildExposeUpperCaseProto(c *check.C) {
  2391  	name := "testbuildexposeuppercaseproto"
  2392  	expected := "map[5678/udp:{}]"
  2393  	_, err := buildImage(name,
  2394  		`FROM scratch
  2395          EXPOSE 5678/UDP`,
  2396  		true)
  2397  	if err != nil {
  2398  		c.Fatal(err)
  2399  	}
  2400  	res, err := inspectField(name, "Config.ExposedPorts")
  2401  	if err != nil {
  2402  		c.Fatal(err)
  2403  	}
  2404  	if res != expected {
  2405  		c.Fatalf("Exposed ports %s, expected %s", res, expected)
  2406  	}
  2407  }
  2408  
  2409  func (s *DockerSuite) TestBuildEmptyEntrypointInheritance(c *check.C) {
  2410  	name := "testbuildentrypointinheritance"
  2411  	name2 := "testbuildentrypointinheritance2"
  2412  
  2413  	_, err := buildImage(name,
  2414  		`FROM busybox
  2415          ENTRYPOINT ["/bin/echo"]`,
  2416  		true)
  2417  	if err != nil {
  2418  		c.Fatal(err)
  2419  	}
  2420  	res, err := inspectField(name, "Config.Entrypoint")
  2421  	if err != nil {
  2422  		c.Fatal(err)
  2423  	}
  2424  
  2425  	expected := "{[/bin/echo]}"
  2426  	if res != expected {
  2427  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2428  	}
  2429  
  2430  	_, err = buildImage(name2,
  2431  		fmt.Sprintf(`FROM %s
  2432          ENTRYPOINT []`, name),
  2433  		true)
  2434  	if err != nil {
  2435  		c.Fatal(err)
  2436  	}
  2437  	res, err = inspectField(name2, "Config.Entrypoint")
  2438  	if err != nil {
  2439  		c.Fatal(err)
  2440  	}
  2441  
  2442  	expected = "{[]}"
  2443  
  2444  	if res != expected {
  2445  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2446  	}
  2447  
  2448  }
  2449  
  2450  func (s *DockerSuite) TestBuildEmptyEntrypoint(c *check.C) {
  2451  	name := "testbuildentrypoint"
  2452  	expected := "{[]}"
  2453  
  2454  	_, err := buildImage(name,
  2455  		`FROM busybox
  2456          ENTRYPOINT []`,
  2457  		true)
  2458  	if err != nil {
  2459  		c.Fatal(err)
  2460  	}
  2461  	res, err := inspectField(name, "Config.Entrypoint")
  2462  	if err != nil {
  2463  		c.Fatal(err)
  2464  	}
  2465  	if res != expected {
  2466  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2467  	}
  2468  
  2469  }
  2470  
  2471  func (s *DockerSuite) TestBuildEntrypoint(c *check.C) {
  2472  	name := "testbuildentrypoint"
  2473  	expected := "{[/bin/echo]}"
  2474  	_, err := buildImage(name,
  2475  		`FROM scratch
  2476          ENTRYPOINT ["/bin/echo"]`,
  2477  		true)
  2478  	if err != nil {
  2479  		c.Fatal(err)
  2480  	}
  2481  	res, err := inspectField(name, "Config.Entrypoint")
  2482  	if err != nil {
  2483  		c.Fatal(err)
  2484  	}
  2485  	if res != expected {
  2486  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2487  	}
  2488  
  2489  }
  2490  
  2491  // #6445 ensure ONBUILD triggers aren't committed to grandchildren
  2492  func (s *DockerSuite) TestBuildOnBuildLimitedInheritence(c *check.C) {
  2493  	var (
  2494  		out2, out3 string
  2495  	)
  2496  	{
  2497  		name1 := "testonbuildtrigger1"
  2498  		dockerfile1 := `
  2499  		FROM busybox
  2500  		RUN echo "GRANDPARENT"
  2501  		ONBUILD RUN echo "ONBUILD PARENT"
  2502  		`
  2503  		ctx, err := fakeContext(dockerfile1, nil)
  2504  		if err != nil {
  2505  			c.Fatal(err)
  2506  		}
  2507  		defer ctx.Close()
  2508  
  2509  		out1, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", name1, ".")
  2510  		if err != nil {
  2511  			c.Fatalf("build failed to complete: %s, %v", out1, err)
  2512  		}
  2513  	}
  2514  	{
  2515  		name2 := "testonbuildtrigger2"
  2516  		dockerfile2 := `
  2517  		FROM testonbuildtrigger1
  2518  		`
  2519  		ctx, err := fakeContext(dockerfile2, nil)
  2520  		if err != nil {
  2521  			c.Fatal(err)
  2522  		}
  2523  		defer ctx.Close()
  2524  
  2525  		out2, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name2, ".")
  2526  		if err != nil {
  2527  			c.Fatalf("build failed to complete: %s, %v", out2, err)
  2528  		}
  2529  	}
  2530  	{
  2531  		name3 := "testonbuildtrigger3"
  2532  		dockerfile3 := `
  2533  		FROM testonbuildtrigger2
  2534  		`
  2535  		ctx, err := fakeContext(dockerfile3, nil)
  2536  		if err != nil {
  2537  			c.Fatal(err)
  2538  		}
  2539  		defer ctx.Close()
  2540  
  2541  		out3, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name3, ".")
  2542  		if err != nil {
  2543  			c.Fatalf("build failed to complete: %s, %v", out3, err)
  2544  		}
  2545  
  2546  	}
  2547  
  2548  	// ONBUILD should be run in second build.
  2549  	if !strings.Contains(out2, "ONBUILD PARENT") {
  2550  		c.Fatalf("ONBUILD instruction did not run in child of ONBUILD parent")
  2551  	}
  2552  
  2553  	// ONBUILD should *not* be run in third build.
  2554  	if strings.Contains(out3, "ONBUILD PARENT") {
  2555  		c.Fatalf("ONBUILD instruction ran in grandchild of ONBUILD parent")
  2556  	}
  2557  
  2558  }
  2559  
  2560  func (s *DockerSuite) TestBuildWithCache(c *check.C) {
  2561  	name := "testbuildwithcache"
  2562  	id1, err := buildImage(name,
  2563  		`FROM scratch
  2564  		MAINTAINER dockerio
  2565  		EXPOSE 5432
  2566          ENTRYPOINT ["/bin/echo"]`,
  2567  		true)
  2568  	if err != nil {
  2569  		c.Fatal(err)
  2570  	}
  2571  	id2, err := buildImage(name,
  2572  		`FROM scratch
  2573  		MAINTAINER dockerio
  2574  		EXPOSE 5432
  2575          ENTRYPOINT ["/bin/echo"]`,
  2576  		true)
  2577  	if err != nil {
  2578  		c.Fatal(err)
  2579  	}
  2580  	if id1 != id2 {
  2581  		c.Fatal("The cache should have been used but hasn't.")
  2582  	}
  2583  }
  2584  
  2585  func (s *DockerSuite) TestBuildWithoutCache(c *check.C) {
  2586  	name := "testbuildwithoutcache"
  2587  	name2 := "testbuildwithoutcache2"
  2588  	id1, err := buildImage(name,
  2589  		`FROM scratch
  2590  		MAINTAINER dockerio
  2591  		EXPOSE 5432
  2592          ENTRYPOINT ["/bin/echo"]`,
  2593  		true)
  2594  	if err != nil {
  2595  		c.Fatal(err)
  2596  	}
  2597  
  2598  	id2, err := buildImage(name2,
  2599  		`FROM scratch
  2600  		MAINTAINER dockerio
  2601  		EXPOSE 5432
  2602          ENTRYPOINT ["/bin/echo"]`,
  2603  		false)
  2604  	if err != nil {
  2605  		c.Fatal(err)
  2606  	}
  2607  	if id1 == id2 {
  2608  		c.Fatal("The cache should have been invalided but hasn't.")
  2609  	}
  2610  }
  2611  
  2612  func (s *DockerSuite) TestBuildConditionalCache(c *check.C) {
  2613  	name := "testbuildconditionalcache"
  2614  
  2615  	dockerfile := `
  2616  		FROM busybox
  2617          ADD foo /tmp/`
  2618  	ctx, err := fakeContext(dockerfile, map[string]string{
  2619  		"foo": "hello",
  2620  	})
  2621  	if err != nil {
  2622  		c.Fatal(err)
  2623  	}
  2624  	defer ctx.Close()
  2625  
  2626  	id1, err := buildImageFromContext(name, ctx, true)
  2627  	if err != nil {
  2628  		c.Fatalf("Error building #1: %s", err)
  2629  	}
  2630  
  2631  	if err := ctx.Add("foo", "bye"); err != nil {
  2632  		c.Fatalf("Error modifying foo: %s", err)
  2633  	}
  2634  
  2635  	id2, err := buildImageFromContext(name, ctx, false)
  2636  	if err != nil {
  2637  		c.Fatalf("Error building #2: %s", err)
  2638  	}
  2639  	if id2 == id1 {
  2640  		c.Fatal("Should not have used the cache")
  2641  	}
  2642  
  2643  	id3, err := buildImageFromContext(name, ctx, true)
  2644  	if err != nil {
  2645  		c.Fatalf("Error building #3: %s", err)
  2646  	}
  2647  	if id3 != id2 {
  2648  		c.Fatal("Should have used the cache")
  2649  	}
  2650  }
  2651  
  2652  func (s *DockerSuite) TestBuildAddLocalFileWithCache(c *check.C) {
  2653  	name := "testbuildaddlocalfilewithcache"
  2654  	name2 := "testbuildaddlocalfilewithcache2"
  2655  	dockerfile := `
  2656  		FROM busybox
  2657          MAINTAINER dockerio
  2658          ADD foo /usr/lib/bla/bar
  2659  		RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2660  	ctx, err := fakeContext(dockerfile, map[string]string{
  2661  		"foo": "hello",
  2662  	})
  2663  	defer ctx.Close()
  2664  	if err != nil {
  2665  		c.Fatal(err)
  2666  	}
  2667  	id1, err := buildImageFromContext(name, ctx, true)
  2668  	if err != nil {
  2669  		c.Fatal(err)
  2670  	}
  2671  	id2, err := buildImageFromContext(name2, ctx, true)
  2672  	if err != nil {
  2673  		c.Fatal(err)
  2674  	}
  2675  	if id1 != id2 {
  2676  		c.Fatal("The cache should have been used but hasn't.")
  2677  	}
  2678  }
  2679  
  2680  func (s *DockerSuite) TestBuildAddMultipleLocalFileWithCache(c *check.C) {
  2681  	name := "testbuildaddmultiplelocalfilewithcache"
  2682  	name2 := "testbuildaddmultiplelocalfilewithcache2"
  2683  	dockerfile := `
  2684  		FROM busybox
  2685          MAINTAINER dockerio
  2686          ADD foo Dockerfile /usr/lib/bla/
  2687  		RUN [ "$(cat /usr/lib/bla/foo)" = "hello" ]`
  2688  	ctx, err := fakeContext(dockerfile, map[string]string{
  2689  		"foo": "hello",
  2690  	})
  2691  	defer ctx.Close()
  2692  	if err != nil {
  2693  		c.Fatal(err)
  2694  	}
  2695  	id1, err := buildImageFromContext(name, ctx, true)
  2696  	if err != nil {
  2697  		c.Fatal(err)
  2698  	}
  2699  	id2, err := buildImageFromContext(name2, ctx, true)
  2700  	if err != nil {
  2701  		c.Fatal(err)
  2702  	}
  2703  	if id1 != id2 {
  2704  		c.Fatal("The cache should have been used but hasn't.")
  2705  	}
  2706  }
  2707  
  2708  func (s *DockerSuite) TestBuildAddLocalFileWithoutCache(c *check.C) {
  2709  	name := "testbuildaddlocalfilewithoutcache"
  2710  	name2 := "testbuildaddlocalfilewithoutcache2"
  2711  	dockerfile := `
  2712  		FROM busybox
  2713          MAINTAINER dockerio
  2714          ADD foo /usr/lib/bla/bar
  2715  		RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2716  	ctx, err := fakeContext(dockerfile, map[string]string{
  2717  		"foo": "hello",
  2718  	})
  2719  	defer ctx.Close()
  2720  	if err != nil {
  2721  		c.Fatal(err)
  2722  	}
  2723  	id1, err := buildImageFromContext(name, ctx, true)
  2724  	if err != nil {
  2725  		c.Fatal(err)
  2726  	}
  2727  	id2, err := buildImageFromContext(name2, ctx, false)
  2728  	if err != nil {
  2729  		c.Fatal(err)
  2730  	}
  2731  	if id1 == id2 {
  2732  		c.Fatal("The cache should have been invalided but hasn't.")
  2733  	}
  2734  }
  2735  
  2736  func (s *DockerSuite) TestBuildCopyDirButNotFile(c *check.C) {
  2737  	name := "testbuildcopydirbutnotfile"
  2738  	name2 := "testbuildcopydirbutnotfile2"
  2739  	dockerfile := `
  2740          FROM scratch
  2741          COPY dir /tmp/`
  2742  	ctx, err := fakeContext(dockerfile, map[string]string{
  2743  		"dir/foo": "hello",
  2744  	})
  2745  	defer ctx.Close()
  2746  	if err != nil {
  2747  		c.Fatal(err)
  2748  	}
  2749  	id1, err := buildImageFromContext(name, ctx, true)
  2750  	if err != nil {
  2751  		c.Fatal(err)
  2752  	}
  2753  	// Check that adding file with similar name doesn't mess with cache
  2754  	if err := ctx.Add("dir_file", "hello2"); err != nil {
  2755  		c.Fatal(err)
  2756  	}
  2757  	id2, err := buildImageFromContext(name2, ctx, true)
  2758  	if err != nil {
  2759  		c.Fatal(err)
  2760  	}
  2761  	if id1 != id2 {
  2762  		c.Fatal("The cache should have been used but wasn't")
  2763  	}
  2764  }
  2765  
  2766  func (s *DockerSuite) TestBuildAddCurrentDirWithCache(c *check.C) {
  2767  	name := "testbuildaddcurrentdirwithcache"
  2768  	name2 := name + "2"
  2769  	name3 := name + "3"
  2770  	name4 := name + "4"
  2771  	dockerfile := `
  2772          FROM scratch
  2773          MAINTAINER dockerio
  2774          ADD . /usr/lib/bla`
  2775  	ctx, err := fakeContext(dockerfile, map[string]string{
  2776  		"foo": "hello",
  2777  	})
  2778  	defer ctx.Close()
  2779  	if err != nil {
  2780  		c.Fatal(err)
  2781  	}
  2782  	id1, err := buildImageFromContext(name, ctx, true)
  2783  	if err != nil {
  2784  		c.Fatal(err)
  2785  	}
  2786  	// Check that adding file invalidate cache of "ADD ."
  2787  	if err := ctx.Add("bar", "hello2"); err != nil {
  2788  		c.Fatal(err)
  2789  	}
  2790  	id2, err := buildImageFromContext(name2, ctx, true)
  2791  	if err != nil {
  2792  		c.Fatal(err)
  2793  	}
  2794  	if id1 == id2 {
  2795  		c.Fatal("The cache should have been invalided but hasn't.")
  2796  	}
  2797  	// Check that changing file invalidate cache of "ADD ."
  2798  	if err := ctx.Add("foo", "hello1"); err != nil {
  2799  		c.Fatal(err)
  2800  	}
  2801  	id3, err := buildImageFromContext(name3, ctx, true)
  2802  	if err != nil {
  2803  		c.Fatal(err)
  2804  	}
  2805  	if id2 == id3 {
  2806  		c.Fatal("The cache should have been invalided but hasn't.")
  2807  	}
  2808  	// Check that changing file to same content with different mtime does not
  2809  	// invalidate cache of "ADD ."
  2810  	time.Sleep(1 * time.Second) // wait second because of mtime precision
  2811  	if err := ctx.Add("foo", "hello1"); err != nil {
  2812  		c.Fatal(err)
  2813  	}
  2814  	id4, err := buildImageFromContext(name4, ctx, true)
  2815  	if err != nil {
  2816  		c.Fatal(err)
  2817  	}
  2818  	if id3 != id4 {
  2819  		c.Fatal("The cache should have been used but hasn't.")
  2820  	}
  2821  }
  2822  
  2823  func (s *DockerSuite) TestBuildAddCurrentDirWithoutCache(c *check.C) {
  2824  	name := "testbuildaddcurrentdirwithoutcache"
  2825  	name2 := "testbuildaddcurrentdirwithoutcache2"
  2826  	dockerfile := `
  2827          FROM scratch
  2828          MAINTAINER dockerio
  2829          ADD . /usr/lib/bla`
  2830  	ctx, err := fakeContext(dockerfile, map[string]string{
  2831  		"foo": "hello",
  2832  	})
  2833  	defer ctx.Close()
  2834  	if err != nil {
  2835  		c.Fatal(err)
  2836  	}
  2837  	id1, err := buildImageFromContext(name, ctx, true)
  2838  	if err != nil {
  2839  		c.Fatal(err)
  2840  	}
  2841  	id2, err := buildImageFromContext(name2, ctx, false)
  2842  	if err != nil {
  2843  		c.Fatal(err)
  2844  	}
  2845  	if id1 == id2 {
  2846  		c.Fatal("The cache should have been invalided but hasn't.")
  2847  	}
  2848  }
  2849  
  2850  func (s *DockerSuite) TestBuildAddRemoteFileWithCache(c *check.C) {
  2851  	name := "testbuildaddremotefilewithcache"
  2852  	server, err := fakeStorage(map[string]string{
  2853  		"baz": "hello",
  2854  	})
  2855  	if err != nil {
  2856  		c.Fatal(err)
  2857  	}
  2858  	defer server.Close()
  2859  
  2860  	id1, err := buildImage(name,
  2861  		fmt.Sprintf(`FROM scratch
  2862          MAINTAINER dockerio
  2863          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2864  		true)
  2865  	if err != nil {
  2866  		c.Fatal(err)
  2867  	}
  2868  	id2, err := buildImage(name,
  2869  		fmt.Sprintf(`FROM scratch
  2870          MAINTAINER dockerio
  2871          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2872  		true)
  2873  	if err != nil {
  2874  		c.Fatal(err)
  2875  	}
  2876  	if id1 != id2 {
  2877  		c.Fatal("The cache should have been used but hasn't.")
  2878  	}
  2879  }
  2880  
  2881  func (s *DockerSuite) TestBuildAddRemoteFileWithoutCache(c *check.C) {
  2882  	name := "testbuildaddremotefilewithoutcache"
  2883  	name2 := "testbuildaddremotefilewithoutcache2"
  2884  	server, err := fakeStorage(map[string]string{
  2885  		"baz": "hello",
  2886  	})
  2887  	if err != nil {
  2888  		c.Fatal(err)
  2889  	}
  2890  	defer server.Close()
  2891  
  2892  	id1, err := buildImage(name,
  2893  		fmt.Sprintf(`FROM scratch
  2894          MAINTAINER dockerio
  2895          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2896  		true)
  2897  	if err != nil {
  2898  		c.Fatal(err)
  2899  	}
  2900  	id2, err := buildImage(name2,
  2901  		fmt.Sprintf(`FROM scratch
  2902          MAINTAINER dockerio
  2903          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2904  		false)
  2905  	if err != nil {
  2906  		c.Fatal(err)
  2907  	}
  2908  	if id1 == id2 {
  2909  		c.Fatal("The cache should have been invalided but hasn't.")
  2910  	}
  2911  }
  2912  
  2913  func (s *DockerSuite) TestBuildAddRemoteFileMTime(c *check.C) {
  2914  	name := "testbuildaddremotefilemtime"
  2915  	name2 := name + "2"
  2916  	name3 := name + "3"
  2917  
  2918  	files := map[string]string{"baz": "hello"}
  2919  	server, err := fakeStorage(files)
  2920  	if err != nil {
  2921  		c.Fatal(err)
  2922  	}
  2923  	defer server.Close()
  2924  
  2925  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2926          MAINTAINER dockerio
  2927          ADD %s/baz /usr/lib/baz/quux`, server.URL()), nil)
  2928  	if err != nil {
  2929  		c.Fatal(err)
  2930  	}
  2931  	defer ctx.Close()
  2932  
  2933  	id1, err := buildImageFromContext(name, ctx, true)
  2934  	if err != nil {
  2935  		c.Fatal(err)
  2936  	}
  2937  
  2938  	id2, err := buildImageFromContext(name2, ctx, true)
  2939  	if err != nil {
  2940  		c.Fatal(err)
  2941  	}
  2942  	if id1 != id2 {
  2943  		c.Fatal("The cache should have been used but wasn't - #1")
  2944  	}
  2945  
  2946  	// Now create a different server with same contents (causes different mtime)
  2947  	// The cache should still be used
  2948  
  2949  	// allow some time for clock to pass as mtime precision is only 1s
  2950  	time.Sleep(2 * time.Second)
  2951  
  2952  	server2, err := fakeStorage(files)
  2953  	if err != nil {
  2954  		c.Fatal(err)
  2955  	}
  2956  	defer server2.Close()
  2957  
  2958  	ctx2, err := fakeContext(fmt.Sprintf(`FROM scratch
  2959          MAINTAINER dockerio
  2960          ADD %s/baz /usr/lib/baz/quux`, server2.URL()), nil)
  2961  	if err != nil {
  2962  		c.Fatal(err)
  2963  	}
  2964  	defer ctx2.Close()
  2965  	id3, err := buildImageFromContext(name3, ctx2, true)
  2966  	if err != nil {
  2967  		c.Fatal(err)
  2968  	}
  2969  	if id1 != id3 {
  2970  		c.Fatal("The cache should have been used but wasn't")
  2971  	}
  2972  }
  2973  
  2974  func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithCache(c *check.C) {
  2975  	name := "testbuildaddlocalandremotefilewithcache"
  2976  	server, err := fakeStorage(map[string]string{
  2977  		"baz": "hello",
  2978  	})
  2979  	if err != nil {
  2980  		c.Fatal(err)
  2981  	}
  2982  	defer server.Close()
  2983  
  2984  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2985          MAINTAINER dockerio
  2986          ADD foo /usr/lib/bla/bar
  2987          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2988  		map[string]string{
  2989  			"foo": "hello world",
  2990  		})
  2991  	if err != nil {
  2992  		c.Fatal(err)
  2993  	}
  2994  	defer ctx.Close()
  2995  	id1, err := buildImageFromContext(name, ctx, true)
  2996  	if err != nil {
  2997  		c.Fatal(err)
  2998  	}
  2999  	id2, err := buildImageFromContext(name, ctx, true)
  3000  	if err != nil {
  3001  		c.Fatal(err)
  3002  	}
  3003  	if id1 != id2 {
  3004  		c.Fatal("The cache should have been used but hasn't.")
  3005  	}
  3006  }
  3007  
  3008  func testContextTar(c *check.C, compression archive.Compression) {
  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  	defer ctx.Close()
  3018  	if err != nil {
  3019  		c.Fatal(err)
  3020  	}
  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  	buildCmd := exec.Command(dockerBinary, "build", "-t", "nocontext", "-")
  3044  	buildCmd.Stdin = strings.NewReader("FROM busybox\nCMD echo ok\n")
  3045  
  3046  	if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  3047  		c.Fatalf("build failed to complete: %v %v", out, err)
  3048  	}
  3049  
  3050  	if out, _ := dockerCmd(c, "run", "--rm", "nocontext"); out != "ok\n" {
  3051  		c.Fatalf("run produced invalid output: %q, expected %q", out, "ok")
  3052  	}
  3053  }
  3054  
  3055  // TODO: TestCaching
  3056  func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithoutCache(c *check.C) {
  3057  	name := "testbuildaddlocalandremotefilewithoutcache"
  3058  	name2 := "testbuildaddlocalandremotefilewithoutcache2"
  3059  	server, err := fakeStorage(map[string]string{
  3060  		"baz": "hello",
  3061  	})
  3062  	if err != nil {
  3063  		c.Fatal(err)
  3064  	}
  3065  	defer server.Close()
  3066  
  3067  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  3068          MAINTAINER dockerio
  3069          ADD foo /usr/lib/bla/bar
  3070          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  3071  		map[string]string{
  3072  			"foo": "hello world",
  3073  		})
  3074  	if err != nil {
  3075  		c.Fatal(err)
  3076  	}
  3077  	defer ctx.Close()
  3078  	id1, err := buildImageFromContext(name, ctx, true)
  3079  	if err != nil {
  3080  		c.Fatal(err)
  3081  	}
  3082  	id2, err := buildImageFromContext(name2, ctx, false)
  3083  	if err != nil {
  3084  		c.Fatal(err)
  3085  	}
  3086  	if id1 == id2 {
  3087  		c.Fatal("The cache should have been invalided but hasn't.")
  3088  	}
  3089  }
  3090  
  3091  func (s *DockerSuite) TestBuildWithVolumeOwnership(c *check.C) {
  3092  	name := "testbuildimg"
  3093  
  3094  	_, err := buildImage(name,
  3095  		`FROM busybox:latest
  3096          RUN mkdir /test && chown daemon:daemon /test && chmod 0600 /test
  3097          VOLUME /test`,
  3098  		true)
  3099  
  3100  	if err != nil {
  3101  		c.Fatal(err)
  3102  	}
  3103  
  3104  	cmd := exec.Command(dockerBinary, "run", "--rm", "testbuildimg", "ls", "-la", "/test")
  3105  	out, _, err := runCommandWithOutput(cmd)
  3106  	if err != nil {
  3107  		c.Fatal(out, err)
  3108  	}
  3109  
  3110  	if expected := "drw-------"; !strings.Contains(out, expected) {
  3111  		c.Fatalf("expected %s received %s", expected, out)
  3112  	}
  3113  
  3114  	if expected := "daemon   daemon"; !strings.Contains(out, expected) {
  3115  		c.Fatalf("expected %s received %s", expected, out)
  3116  	}
  3117  
  3118  }
  3119  
  3120  // testing #1405 - config.Cmd does not get cleaned up if
  3121  // utilizing cache
  3122  func (s *DockerSuite) TestBuildEntrypointRunCleanup(c *check.C) {
  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  	defer ctx.Close()
  3139  	if err != nil {
  3140  		c.Fatal(err)
  3141  	}
  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  	name := "testbuildforbidpath"
  3157  	ctx, err := fakeContext(`FROM scratch
  3158          ADD ../../ test/
  3159          `,
  3160  		map[string]string{
  3161  			"test.txt":  "test1",
  3162  			"other.txt": "other",
  3163  		})
  3164  	defer ctx.Close()
  3165  	if err != nil {
  3166  		c.Fatal(err)
  3167  	}
  3168  
  3169  	expected := "Forbidden path outside the build context: ../../ "
  3170  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  3171  		c.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
  3172  	}
  3173  
  3174  }
  3175  
  3176  func (s *DockerSuite) TestBuildAddFileNotFound(c *check.C) {
  3177  	name := "testbuildaddnotfound"
  3178  	ctx, err := fakeContext(`FROM scratch
  3179          ADD foo /usr/local/bar`,
  3180  		map[string]string{"bar": "hello"})
  3181  	defer ctx.Close()
  3182  	if err != nil {
  3183  		c.Fatal(err)
  3184  	}
  3185  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3186  		if !strings.Contains(err.Error(), "foo: no such file or directory") {
  3187  			c.Fatalf("Wrong error %v, must be about missing foo file or directory", err)
  3188  		}
  3189  	} else {
  3190  		c.Fatal("Error must not be nil")
  3191  	}
  3192  }
  3193  
  3194  func (s *DockerSuite) TestBuildInheritance(c *check.C) {
  3195  	name := "testbuildinheritance"
  3196  
  3197  	_, err := buildImage(name,
  3198  		`FROM scratch
  3199  		EXPOSE 2375`,
  3200  		true)
  3201  	if err != nil {
  3202  		c.Fatal(err)
  3203  	}
  3204  	ports1, err := inspectField(name, "Config.ExposedPorts")
  3205  	if err != nil {
  3206  		c.Fatal(err)
  3207  	}
  3208  
  3209  	_, err = buildImage(name,
  3210  		fmt.Sprintf(`FROM %s
  3211  		ENTRYPOINT ["/bin/echo"]`, name),
  3212  		true)
  3213  	if err != nil {
  3214  		c.Fatal(err)
  3215  	}
  3216  
  3217  	res, err := inspectField(name, "Config.Entrypoint")
  3218  	if err != nil {
  3219  		c.Fatal(err)
  3220  	}
  3221  	if expected := "{[/bin/echo]}"; res != expected {
  3222  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  3223  	}
  3224  	ports2, err := inspectField(name, "Config.ExposedPorts")
  3225  	if err != nil {
  3226  		c.Fatal(err)
  3227  	}
  3228  	if ports1 != ports2 {
  3229  		c.Fatalf("Ports must be same: %s != %s", ports1, ports2)
  3230  	}
  3231  }
  3232  
  3233  func (s *DockerSuite) TestBuildFails(c *check.C) {
  3234  	name := "testbuildfails"
  3235  	_, err := buildImage(name,
  3236  		`FROM busybox
  3237  		RUN sh -c "exit 23"`,
  3238  		true)
  3239  	if err != nil {
  3240  		if !strings.Contains(err.Error(), "returned a non-zero code: 23") {
  3241  			c.Fatalf("Wrong error %v, must be about non-zero code 23", err)
  3242  		}
  3243  	} else {
  3244  		c.Fatal("Error must not be nil")
  3245  	}
  3246  }
  3247  
  3248  func (s *DockerSuite) TestBuildFailsDockerfileEmpty(c *check.C) {
  3249  	name := "testbuildfails"
  3250  	_, err := buildImage(name, ``, true)
  3251  	if err != nil {
  3252  		if !strings.Contains(err.Error(), "The Dockerfile (Dockerfile) cannot be empty") {
  3253  			c.Fatalf("Wrong error %v, must be about empty Dockerfile", err)
  3254  		}
  3255  	} else {
  3256  		c.Fatal("Error must not be nil")
  3257  	}
  3258  }
  3259  
  3260  func (s *DockerSuite) TestBuildOnBuild(c *check.C) {
  3261  	name := "testbuildonbuild"
  3262  	_, err := buildImage(name,
  3263  		`FROM busybox
  3264  		ONBUILD RUN touch foobar`,
  3265  		true)
  3266  	if err != nil {
  3267  		c.Fatal(err)
  3268  	}
  3269  	_, err = buildImage(name,
  3270  		fmt.Sprintf(`FROM %s
  3271  		RUN [ -f foobar ]`, name),
  3272  		true)
  3273  	if err != nil {
  3274  		c.Fatal(err)
  3275  	}
  3276  }
  3277  
  3278  func (s *DockerSuite) TestBuildOnBuildForbiddenChained(c *check.C) {
  3279  	name := "testbuildonbuildforbiddenchained"
  3280  	_, err := buildImage(name,
  3281  		`FROM busybox
  3282  		ONBUILD ONBUILD RUN touch foobar`,
  3283  		true)
  3284  	if err != nil {
  3285  		if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
  3286  			c.Fatalf("Wrong error %v, must be about chaining ONBUILD", err)
  3287  		}
  3288  	} else {
  3289  		c.Fatal("Error must not be nil")
  3290  	}
  3291  }
  3292  
  3293  func (s *DockerSuite) TestBuildOnBuildForbiddenFrom(c *check.C) {
  3294  	name := "testbuildonbuildforbiddenfrom"
  3295  	_, err := buildImage(name,
  3296  		`FROM busybox
  3297  		ONBUILD FROM scratch`,
  3298  		true)
  3299  	if err != nil {
  3300  		if !strings.Contains(err.Error(), "FROM isn't allowed as an ONBUILD trigger") {
  3301  			c.Fatalf("Wrong error %v, must be about FROM forbidden", err)
  3302  		}
  3303  	} else {
  3304  		c.Fatal("Error must not be nil")
  3305  	}
  3306  }
  3307  
  3308  func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainer(c *check.C) {
  3309  	name := "testbuildonbuildforbiddenmaintainer"
  3310  	_, err := buildImage(name,
  3311  		`FROM busybox
  3312  		ONBUILD MAINTAINER docker.io`,
  3313  		true)
  3314  	if err != nil {
  3315  		if !strings.Contains(err.Error(), "MAINTAINER isn't allowed as an ONBUILD trigger") {
  3316  			c.Fatalf("Wrong error %v, must be about MAINTAINER forbidden", err)
  3317  		}
  3318  	} else {
  3319  		c.Fatal("Error must not be nil")
  3320  	}
  3321  }
  3322  
  3323  // gh #2446
  3324  func (s *DockerSuite) TestBuildAddToSymlinkDest(c *check.C) {
  3325  	name := "testbuildaddtosymlinkdest"
  3326  	ctx, err := fakeContext(`FROM busybox
  3327          RUN mkdir /foo
  3328          RUN ln -s /foo /bar
  3329          ADD foo /bar/
  3330          RUN [ -f /bar/foo ]
  3331          RUN [ -f /foo/foo ]`,
  3332  		map[string]string{
  3333  			"foo": "hello",
  3334  		})
  3335  	if err != nil {
  3336  		c.Fatal(err)
  3337  	}
  3338  	defer ctx.Close()
  3339  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3340  		c.Fatal(err)
  3341  	}
  3342  }
  3343  
  3344  func (s *DockerSuite) TestBuildEscapeWhitespace(c *check.C) {
  3345  	name := "testbuildescaping"
  3346  
  3347  	_, err := buildImage(name, `
  3348    FROM busybox
  3349    MAINTAINER "Docker \
  3350  IO <io@\
  3351  docker.com>"
  3352    `, true)
  3353  
  3354  	res, err := inspectField(name, "Author")
  3355  
  3356  	if err != nil {
  3357  		c.Fatal(err)
  3358  	}
  3359  
  3360  	if res != "\"Docker IO <io@docker.com>\"" {
  3361  		c.Fatalf("Parsed string did not match the escaped string. Got: %q", res)
  3362  	}
  3363  
  3364  }
  3365  
  3366  func (s *DockerSuite) TestBuildVerifyIntString(c *check.C) {
  3367  	// Verify that strings that look like ints are still passed as strings
  3368  	name := "testbuildstringing"
  3369  
  3370  	_, err := buildImage(name, `
  3371    FROM busybox
  3372    MAINTAINER 123
  3373    `, true)
  3374  
  3375  	out, rc, err := runCommandWithOutput(exec.Command(dockerBinary, "inspect", name))
  3376  	if rc != 0 || err != nil {
  3377  		c.Fatalf("Unexpected error from inspect: rc: %v  err: %v", rc, err)
  3378  	}
  3379  
  3380  	if !strings.Contains(out, "\"123\"") {
  3381  		c.Fatalf("Output does not contain the int as a string:\n%s", out)
  3382  	}
  3383  
  3384  }
  3385  
  3386  func (s *DockerSuite) TestBuildDockerignore(c *check.C) {
  3387  	name := "testbuilddockerignore"
  3388  	dockerfile := `
  3389          FROM busybox
  3390          ADD . /bla
  3391  		RUN [[ -f /bla/src/x.go ]]
  3392  		RUN [[ -f /bla/Makefile ]]
  3393  		RUN [[ ! -e /bla/src/_vendor ]]
  3394  		RUN [[ ! -e /bla/.gitignore ]]
  3395  		RUN [[ ! -e /bla/README.md ]]
  3396  		RUN [[ ! -e /bla/dir/foo ]]
  3397  		RUN [[ ! -e /bla/foo ]]
  3398  		RUN [[ ! -e /bla/.git ]]`
  3399  	ctx, err := fakeContext(dockerfile, map[string]string{
  3400  		"Makefile":         "all:",
  3401  		".git/HEAD":        "ref: foo",
  3402  		"src/x.go":         "package main",
  3403  		"src/_vendor/v.go": "package main",
  3404  		"dir/foo":          "",
  3405  		".gitignore":       "",
  3406  		"README.md":        "readme",
  3407  		".dockerignore": `
  3408  .git
  3409  pkg
  3410  .gitignore
  3411  src/_vendor
  3412  *.md
  3413  dir`,
  3414  	})
  3415  	if err != nil {
  3416  		c.Fatal(err)
  3417  	}
  3418  	defer ctx.Close()
  3419  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3420  		c.Fatal(err)
  3421  	}
  3422  }
  3423  
  3424  func (s *DockerSuite) TestBuildDockerignoreCleanPaths(c *check.C) {
  3425  	name := "testbuilddockerignorecleanpaths"
  3426  	dockerfile := `
  3427          FROM busybox
  3428          ADD . /tmp/
  3429          RUN (! ls /tmp/foo) && (! ls /tmp/foo2) && (! ls /tmp/dir1/foo)`
  3430  	ctx, err := fakeContext(dockerfile, map[string]string{
  3431  		"foo":           "foo",
  3432  		"foo2":          "foo2",
  3433  		"dir1/foo":      "foo in dir1",
  3434  		".dockerignore": "./foo\ndir1//foo\n./dir1/../foo2",
  3435  	})
  3436  	if err != nil {
  3437  		c.Fatal(err)
  3438  	}
  3439  	defer ctx.Close()
  3440  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3441  		c.Fatal(err)
  3442  	}
  3443  }
  3444  
  3445  func (s *DockerSuite) TestBuildDockerignoreExceptions(c *check.C) {
  3446  	name := "testbuilddockerignoreexceptions"
  3447  	defer deleteImages(name)
  3448  	dockerfile := `
  3449          FROM busybox
  3450          ADD . /bla
  3451  		RUN [[ -f /bla/src/x.go ]]
  3452  		RUN [[ -f /bla/Makefile ]]
  3453  		RUN [[ ! -e /bla/src/_vendor ]]
  3454  		RUN [[ ! -e /bla/.gitignore ]]
  3455  		RUN [[ ! -e /bla/README.md ]]
  3456  		RUN [[  -e /bla/dir/dir/foo ]]
  3457  		RUN [[ ! -e /bla/dir/foo1 ]]
  3458  		RUN [[ -f /bla/dir/e ]]
  3459  		RUN [[ -f /bla/dir/e-dir/foo ]]
  3460  		RUN [[ ! -e /bla/foo ]]
  3461  		RUN [[ ! -e /bla/.git ]]`
  3462  	ctx, err := fakeContext(dockerfile, map[string]string{
  3463  		"Makefile":         "all:",
  3464  		".git/HEAD":        "ref: foo",
  3465  		"src/x.go":         "package main",
  3466  		"src/_vendor/v.go": "package main",
  3467  		"dir/foo":          "",
  3468  		"dir/foo1":         "",
  3469  		"dir/dir/f1":       "",
  3470  		"dir/dir/foo":      "",
  3471  		"dir/e":            "",
  3472  		"dir/e-dir/foo":    "",
  3473  		".gitignore":       "",
  3474  		"README.md":        "readme",
  3475  		".dockerignore": `
  3476  .git
  3477  pkg
  3478  .gitignore
  3479  src/_vendor
  3480  *.md
  3481  dir
  3482  !dir/e*
  3483  !dir/dir/foo`,
  3484  	})
  3485  	if err != nil {
  3486  		c.Fatal(err)
  3487  	}
  3488  	defer ctx.Close()
  3489  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3490  		c.Fatal(err)
  3491  	}
  3492  }
  3493  
  3494  func (s *DockerSuite) TestBuildDockerignoringDockerfile(c *check.C) {
  3495  	name := "testbuilddockerignoredockerfile"
  3496  	dockerfile := `
  3497          FROM busybox
  3498  		ADD . /tmp/
  3499  		RUN ! ls /tmp/Dockerfile
  3500  		RUN ls /tmp/.dockerignore`
  3501  	ctx, err := fakeContext(dockerfile, map[string]string{
  3502  		"Dockerfile":    dockerfile,
  3503  		".dockerignore": "Dockerfile\n",
  3504  	})
  3505  	if err != nil {
  3506  		c.Fatal(err)
  3507  	}
  3508  	defer ctx.Close()
  3509  
  3510  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3511  		c.Fatalf("Didn't ignore Dockerfile correctly:%s", err)
  3512  	}
  3513  
  3514  	// now try it with ./Dockerfile
  3515  	ctx.Add(".dockerignore", "./Dockerfile\n")
  3516  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3517  		c.Fatalf("Didn't ignore ./Dockerfile correctly:%s", err)
  3518  	}
  3519  
  3520  }
  3521  
  3522  func (s *DockerSuite) TestBuildDockerignoringRenamedDockerfile(c *check.C) {
  3523  	name := "testbuilddockerignoredockerfile"
  3524  	dockerfile := `
  3525          FROM busybox
  3526  		ADD . /tmp/
  3527  		RUN ls /tmp/Dockerfile
  3528  		RUN ! ls /tmp/MyDockerfile
  3529  		RUN ls /tmp/.dockerignore`
  3530  	ctx, err := fakeContext(dockerfile, map[string]string{
  3531  		"Dockerfile":    "Should not use me",
  3532  		"MyDockerfile":  dockerfile,
  3533  		".dockerignore": "MyDockerfile\n",
  3534  	})
  3535  	if err != nil {
  3536  		c.Fatal(err)
  3537  	}
  3538  	defer ctx.Close()
  3539  
  3540  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3541  		c.Fatalf("Didn't ignore MyDockerfile correctly:%s", err)
  3542  	}
  3543  
  3544  	// now try it with ./MyDockerfile
  3545  	ctx.Add(".dockerignore", "./MyDockerfile\n")
  3546  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3547  		c.Fatalf("Didn't ignore ./MyDockerfile correctly:%s", err)
  3548  	}
  3549  
  3550  }
  3551  
  3552  func (s *DockerSuite) TestBuildDockerignoringDockerignore(c *check.C) {
  3553  	name := "testbuilddockerignoredockerignore"
  3554  	dockerfile := `
  3555          FROM busybox
  3556  		ADD . /tmp/
  3557  		RUN ! ls /tmp/.dockerignore
  3558  		RUN ls /tmp/Dockerfile`
  3559  	ctx, err := fakeContext(dockerfile, map[string]string{
  3560  		"Dockerfile":    dockerfile,
  3561  		".dockerignore": ".dockerignore\n",
  3562  	})
  3563  	defer ctx.Close()
  3564  	if err != nil {
  3565  		c.Fatal(err)
  3566  	}
  3567  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3568  		c.Fatalf("Didn't ignore .dockerignore correctly:%s", err)
  3569  	}
  3570  }
  3571  
  3572  func (s *DockerSuite) TestBuildDockerignoreTouchDockerfile(c *check.C) {
  3573  	var id1 string
  3574  	var id2 string
  3575  
  3576  	name := "testbuilddockerignoretouchdockerfile"
  3577  	dockerfile := `
  3578          FROM busybox
  3579  		ADD . /tmp/`
  3580  	ctx, err := fakeContext(dockerfile, map[string]string{
  3581  		"Dockerfile":    dockerfile,
  3582  		".dockerignore": "Dockerfile\n",
  3583  	})
  3584  	defer ctx.Close()
  3585  	if err != nil {
  3586  		c.Fatal(err)
  3587  	}
  3588  
  3589  	if id1, err = buildImageFromContext(name, ctx, true); err != nil {
  3590  		c.Fatalf("Didn't build it correctly:%s", err)
  3591  	}
  3592  
  3593  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3594  		c.Fatalf("Didn't build it correctly:%s", err)
  3595  	}
  3596  	if id1 != id2 {
  3597  		c.Fatalf("Didn't use the cache - 1")
  3598  	}
  3599  
  3600  	// Now make sure touching Dockerfile doesn't invalidate the cache
  3601  	if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3602  		c.Fatalf("Didn't add Dockerfile: %s", err)
  3603  	}
  3604  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3605  		c.Fatalf("Didn't build it correctly:%s", err)
  3606  	}
  3607  	if id1 != id2 {
  3608  		c.Fatalf("Didn't use the cache - 2")
  3609  	}
  3610  
  3611  	// One more time but just 'touch' it instead of changing the content
  3612  	if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3613  		c.Fatalf("Didn't add Dockerfile: %s", err)
  3614  	}
  3615  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3616  		c.Fatalf("Didn't build it correctly:%s", err)
  3617  	}
  3618  	if id1 != id2 {
  3619  		c.Fatalf("Didn't use the cache - 3")
  3620  	}
  3621  
  3622  }
  3623  
  3624  func (s *DockerSuite) TestBuildDockerignoringWholeDir(c *check.C) {
  3625  	name := "testbuilddockerignorewholedir"
  3626  	dockerfile := `
  3627          FROM busybox
  3628  		COPY . /
  3629  		RUN [[ ! -e /.gitignore ]]
  3630  		RUN [[ -f /Makefile ]]`
  3631  	ctx, err := fakeContext(dockerfile, map[string]string{
  3632  		"Dockerfile":    "FROM scratch",
  3633  		"Makefile":      "all:",
  3634  		".gitignore":    "",
  3635  		".dockerignore": ".*\n",
  3636  	})
  3637  	c.Assert(err, check.IsNil)
  3638  	defer ctx.Close()
  3639  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3640  		c.Fatal(err)
  3641  	}
  3642  
  3643  	c.Assert(ctx.Add(".dockerfile", "*"), check.IsNil)
  3644  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3645  		c.Fatal(err)
  3646  	}
  3647  
  3648  	c.Assert(ctx.Add(".dockerfile", "."), check.IsNil)
  3649  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3650  		c.Fatal(err)
  3651  	}
  3652  
  3653  	c.Assert(ctx.Add(".dockerfile", "?"), check.IsNil)
  3654  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3655  		c.Fatal(err)
  3656  	}
  3657  }
  3658  
  3659  func (s *DockerSuite) TestBuildDockerignoringBadExclusion(c *check.C) {
  3660  	name := "testbuilddockerignorewholedir"
  3661  	dockerfile := `
  3662          FROM busybox
  3663  		COPY . /
  3664  		RUN [[ ! -e /.gitignore ]]
  3665  		RUN [[ -f /Makefile ]]`
  3666  	ctx, err := fakeContext(dockerfile, map[string]string{
  3667  		"Dockerfile":    "FROM scratch",
  3668  		"Makefile":      "all:",
  3669  		".gitignore":    "",
  3670  		".dockerignore": "!\n",
  3671  	})
  3672  	c.Assert(err, check.IsNil)
  3673  	defer ctx.Close()
  3674  	if _, err = buildImageFromContext(name, ctx, true); err == nil {
  3675  		c.Fatalf("Build was supposed to fail but didn't")
  3676  	}
  3677  
  3678  	if err.Error() != "failed to build the image: Error checking context: 'Illegal exclusion pattern: !'.\n" {
  3679  		c.Fatalf("Incorrect output, got:%q", err.Error())
  3680  	}
  3681  }
  3682  
  3683  func (s *DockerSuite) TestBuildLineBreak(c *check.C) {
  3684  	name := "testbuildlinebreak"
  3685  	_, err := buildImage(name,
  3686  		`FROM  busybox
  3687  RUN    sh -c 'echo root:testpass \
  3688  	> /tmp/passwd'
  3689  RUN    mkdir -p /var/run/sshd
  3690  RUN    [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3691  RUN    [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3692  		true)
  3693  	if err != nil {
  3694  		c.Fatal(err)
  3695  	}
  3696  }
  3697  
  3698  func (s *DockerSuite) TestBuildEOLInLine(c *check.C) {
  3699  	name := "testbuildeolinline"
  3700  	_, err := buildImage(name,
  3701  		`FROM   busybox
  3702  RUN    sh -c 'echo root:testpass > /tmp/passwd'
  3703  RUN    echo "foo \n bar"; echo "baz"
  3704  RUN    mkdir -p /var/run/sshd
  3705  RUN    [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3706  RUN    [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3707  		true)
  3708  	if err != nil {
  3709  		c.Fatal(err)
  3710  	}
  3711  }
  3712  
  3713  func (s *DockerSuite) TestBuildCommentsShebangs(c *check.C) {
  3714  	name := "testbuildcomments"
  3715  	_, err := buildImage(name,
  3716  		`FROM busybox
  3717  # This is an ordinary comment.
  3718  RUN { echo '#!/bin/sh'; echo 'echo hello world'; } > /hello.sh
  3719  RUN [ ! -x /hello.sh ]
  3720  # comment with line break \
  3721  RUN chmod +x /hello.sh
  3722  RUN [ -x /hello.sh ]
  3723  RUN [ "$(cat /hello.sh)" = $'#!/bin/sh\necho hello world' ]
  3724  RUN [ "$(/hello.sh)" = "hello world" ]`,
  3725  		true)
  3726  	if err != nil {
  3727  		c.Fatal(err)
  3728  	}
  3729  }
  3730  
  3731  func (s *DockerSuite) TestBuildUsersAndGroups(c *check.C) {
  3732  	name := "testbuildusers"
  3733  	_, err := buildImage(name,
  3734  		`FROM busybox
  3735  
  3736  # Make sure our defaults work
  3737  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)" = '0:0/root:root' ]
  3738  
  3739  # 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)
  3740  USER root
  3741  RUN [ "$(id -G):$(id -Gn)" = '0 10:root wheel' ]
  3742  
  3743  # Setup dockerio user and group
  3744  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  3745  RUN echo 'dockerio:x:1001:' >> /etc/group
  3746  
  3747  # Make sure we can switch to our user and all the information is exactly as we expect it to be
  3748  USER dockerio
  3749  RUN id -G
  3750  RUN id -Gn
  3751  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3752  
  3753  # Switch back to root and double check that worked exactly as we might expect it to
  3754  USER root
  3755  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '0:0/root:root/0 10:root wheel' ]
  3756  
  3757  # Add a "supplementary" group for our dockerio user
  3758  RUN echo 'supplementary:x:1002:dockerio' >> /etc/group
  3759  
  3760  # ... and then go verify that we get it like we expect
  3761  USER dockerio
  3762  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3763  USER 1001
  3764  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3765  
  3766  # super test the new "user:group" syntax
  3767  USER dockerio:dockerio
  3768  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3769  USER 1001:dockerio
  3770  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3771  USER dockerio:1001
  3772  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3773  USER 1001:1001
  3774  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3775  USER dockerio:supplementary
  3776  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3777  USER dockerio:1002
  3778  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3779  USER 1001:supplementary
  3780  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3781  USER 1001:1002
  3782  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3783  
  3784  # make sure unknown uid/gid still works properly
  3785  USER 1042:1043
  3786  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1042:1043/1042:1043/1043:1043' ]`,
  3787  		true)
  3788  	if err != nil {
  3789  		c.Fatal(err)
  3790  	}
  3791  }
  3792  
  3793  func (s *DockerSuite) TestBuildEnvUsage(c *check.C) {
  3794  	name := "testbuildenvusage"
  3795  	dockerfile := `FROM busybox
  3796  ENV    HOME /root
  3797  ENV    PATH $HOME/bin:$PATH
  3798  ENV    PATH /tmp:$PATH
  3799  RUN    [ "$PATH" = "/tmp:$HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ]
  3800  ENV    FOO /foo/baz
  3801  ENV    BAR /bar
  3802  ENV    BAZ $BAR
  3803  ENV    FOOPATH $PATH:$FOO
  3804  RUN    [ "$BAR" = "$BAZ" ]
  3805  RUN    [ "$FOOPATH" = "$PATH:/foo/baz" ]
  3806  ENV	   FROM hello/docker/world
  3807  ENV    TO /docker/world/hello
  3808  ADD    $FROM $TO
  3809  RUN    [ "$(cat $TO)" = "hello" ]
  3810  ENV    abc=def
  3811  ENV    ghi=$abc
  3812  RUN    [ "$ghi" = "def" ]
  3813  `
  3814  	ctx, err := fakeContext(dockerfile, map[string]string{
  3815  		"hello/docker/world": "hello",
  3816  	})
  3817  	if err != nil {
  3818  		c.Fatal(err)
  3819  	}
  3820  	defer ctx.Close()
  3821  
  3822  	_, err = buildImageFromContext(name, ctx, true)
  3823  	if err != nil {
  3824  		c.Fatal(err)
  3825  	}
  3826  }
  3827  
  3828  func (s *DockerSuite) TestBuildEnvUsage2(c *check.C) {
  3829  	name := "testbuildenvusage2"
  3830  	dockerfile := `FROM busybox
  3831  ENV    abc=def
  3832  RUN    [ "$abc" = "def" ]
  3833  ENV    def="hello world"
  3834  RUN    [ "$def" = "hello world" ]
  3835  ENV    def=hello\ world
  3836  RUN    [ "$def" = "hello world" ]
  3837  ENV    v1=abc v2="hi there"
  3838  RUN    [ "$v1" = "abc" ]
  3839  RUN    [ "$v2" = "hi there" ]
  3840  ENV    v3='boogie nights' v4="with'quotes too"
  3841  RUN    [ "$v3" = "boogie nights" ]
  3842  RUN    [ "$v4" = "with'quotes too" ]
  3843  ENV    abc=zzz FROM=hello/docker/world
  3844  ENV    abc=zzz TO=/docker/world/hello
  3845  ADD    $FROM $TO
  3846  RUN    [ "$(cat $TO)" = "hello" ]
  3847  ENV    abc "zzz"
  3848  RUN    [ $abc = "zzz" ]
  3849  ENV    abc 'yyy'
  3850  RUN    [ $abc = 'yyy' ]
  3851  ENV    abc=
  3852  RUN    [ "$abc" = "" ]
  3853  
  3854  # use grep to make sure if the builder substitutes \$foo by mistake
  3855  # we don't get a false positive
  3856  ENV    abc=\$foo
  3857  RUN    [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  3858  ENV    abc \$foo
  3859  RUN    [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  3860  
  3861  ENV    abc=\'foo\'
  3862  RUN    [ "$abc" = "'foo'" ]
  3863  ENV    abc=\"foo\"
  3864  RUN    [ "$abc" = "\"foo\"" ]
  3865  ENV    abc "foo"
  3866  RUN    [ "$abc" = "foo" ]
  3867  ENV    abc 'foo'
  3868  RUN    [ "$abc" = 'foo' ]
  3869  ENV    abc \'foo\'
  3870  RUN    [ "$abc" = "'foo'" ]
  3871  ENV    abc \"foo\"
  3872  RUN    [ "$abc" = '"foo"' ]
  3873  
  3874  ENV    abc=ABC
  3875  RUN    [ "$abc" = "ABC" ]
  3876  ENV    def=${abc:-DEF}
  3877  RUN    [ "$def" = "ABC" ]
  3878  ENV    def=${ccc:-DEF}
  3879  RUN    [ "$def" = "DEF" ]
  3880  ENV    def=${ccc:-${def}xx}
  3881  RUN    [ "$def" = "DEFxx" ]
  3882  ENV    def=${def:+ALT}
  3883  RUN    [ "$def" = "ALT" ]
  3884  ENV    def=${def:+${abc}:}
  3885  RUN    [ "$def" = "ABC:" ]
  3886  ENV    def=${ccc:-\$abc:}
  3887  RUN    [ "$def" = '$abc:' ]
  3888  ENV    def=${ccc:-\${abc}:}
  3889  RUN    [ "$def" = '${abc:}' ]
  3890  ENV    mypath=${mypath:+$mypath:}/home
  3891  RUN    [ "$mypath" = '/home' ]
  3892  ENV    mypath=${mypath:+$mypath:}/away
  3893  RUN    [ "$mypath" = '/home:/away' ]
  3894  
  3895  ENV    e1=bar
  3896  ENV    e2=$e1
  3897  ENV    e3=$e11
  3898  ENV    e4=\$e1
  3899  ENV    e5=\$e11
  3900  RUN    [ "$e0,$e1,$e2,$e3,$e4,$e5" = ',bar,bar,,$e1,$e11' ]
  3901  
  3902  ENV    ee1 bar
  3903  ENV    ee2 $ee1
  3904  ENV    ee3 $ee11
  3905  ENV    ee4 \$ee1
  3906  ENV    ee5 \$ee11
  3907  RUN    [ "$ee1,$ee2,$ee3,$ee4,$ee5" = 'bar,bar,,$ee1,$ee11' ]
  3908  
  3909  ENV    eee1="foo"
  3910  ENV    eee2='foo'
  3911  ENV    eee3 "foo"
  3912  ENV    eee4 'foo'
  3913  RUN    [ "$eee1,$eee2,$eee3,$eee4" = 'foo,foo,foo,foo' ]
  3914  
  3915  `
  3916  	ctx, err := fakeContext(dockerfile, map[string]string{
  3917  		"hello/docker/world": "hello",
  3918  	})
  3919  	if err != nil {
  3920  		c.Fatal(err)
  3921  	}
  3922  	defer ctx.Close()
  3923  
  3924  	_, err = buildImageFromContext(name, ctx, true)
  3925  	if err != nil {
  3926  		c.Fatal(err)
  3927  	}
  3928  }
  3929  
  3930  func (s *DockerSuite) TestBuildAddScript(c *check.C) {
  3931  	name := "testbuildaddscript"
  3932  	dockerfile := `
  3933  FROM busybox
  3934  ADD test /test
  3935  RUN ["chmod","+x","/test"]
  3936  RUN ["/test"]
  3937  RUN [ "$(cat /testfile)" = 'test!' ]`
  3938  	ctx, err := fakeContext(dockerfile, map[string]string{
  3939  		"test": "#!/bin/sh\necho 'test!' > /testfile",
  3940  	})
  3941  	if err != nil {
  3942  		c.Fatal(err)
  3943  	}
  3944  	defer ctx.Close()
  3945  
  3946  	_, err = buildImageFromContext(name, ctx, true)
  3947  	if err != nil {
  3948  		c.Fatal(err)
  3949  	}
  3950  }
  3951  
  3952  func (s *DockerSuite) TestBuildAddTar(c *check.C) {
  3953  	name := "testbuildaddtar"
  3954  
  3955  	ctx := func() *FakeContext {
  3956  		dockerfile := `
  3957  FROM busybox
  3958  ADD test.tar /
  3959  RUN cat /test/foo | grep Hi
  3960  ADD test.tar /test.tar
  3961  RUN cat /test.tar/test/foo | grep Hi
  3962  ADD test.tar /unlikely-to-exist
  3963  RUN cat /unlikely-to-exist/test/foo | grep Hi
  3964  ADD test.tar /unlikely-to-exist-trailing-slash/
  3965  RUN cat /unlikely-to-exist-trailing-slash/test/foo | grep Hi
  3966  RUN mkdir /existing-directory
  3967  ADD test.tar /existing-directory
  3968  RUN cat /existing-directory/test/foo | grep Hi
  3969  ADD test.tar /existing-directory-trailing-slash/
  3970  RUN cat /existing-directory-trailing-slash/test/foo | grep Hi`
  3971  		tmpDir, err := ioutil.TempDir("", "fake-context")
  3972  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3973  		if err != nil {
  3974  			c.Fatalf("failed to create test.tar archive: %v", err)
  3975  		}
  3976  		defer testTar.Close()
  3977  
  3978  		tw := tar.NewWriter(testTar)
  3979  
  3980  		if err := tw.WriteHeader(&tar.Header{
  3981  			Name: "test/foo",
  3982  			Size: 2,
  3983  		}); err != nil {
  3984  			c.Fatalf("failed to write tar file header: %v", err)
  3985  		}
  3986  		if _, err := tw.Write([]byte("Hi")); err != nil {
  3987  			c.Fatalf("failed to write tar file content: %v", err)
  3988  		}
  3989  		if err := tw.Close(); err != nil {
  3990  			c.Fatalf("failed to close tar archive: %v", err)
  3991  		}
  3992  
  3993  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3994  			c.Fatalf("failed to open destination dockerfile: %v", err)
  3995  		}
  3996  		return fakeContextFromDir(tmpDir)
  3997  	}()
  3998  	defer ctx.Close()
  3999  
  4000  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4001  		c.Fatalf("build failed to complete for TestBuildAddTar: %v", err)
  4002  	}
  4003  
  4004  }
  4005  
  4006  func (s *DockerSuite) TestBuildAddTarXz(c *check.C) {
  4007  	name := "testbuildaddtarxz"
  4008  
  4009  	ctx := func() *FakeContext {
  4010  		dockerfile := `
  4011  			FROM busybox
  4012  			ADD test.tar.xz /
  4013  			RUN cat /test/foo | grep Hi`
  4014  		tmpDir, err := ioutil.TempDir("", "fake-context")
  4015  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  4016  		if err != nil {
  4017  			c.Fatalf("failed to create test.tar archive: %v", err)
  4018  		}
  4019  		defer testTar.Close()
  4020  
  4021  		tw := tar.NewWriter(testTar)
  4022  
  4023  		if err := tw.WriteHeader(&tar.Header{
  4024  			Name: "test/foo",
  4025  			Size: 2,
  4026  		}); err != nil {
  4027  			c.Fatalf("failed to write tar file header: %v", err)
  4028  		}
  4029  		if _, err := tw.Write([]byte("Hi")); err != nil {
  4030  			c.Fatalf("failed to write tar file content: %v", err)
  4031  		}
  4032  		if err := tw.Close(); err != nil {
  4033  			c.Fatalf("failed to close tar archive: %v", err)
  4034  		}
  4035  		xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  4036  		xzCompressCmd.Dir = tmpDir
  4037  		out, _, err := runCommandWithOutput(xzCompressCmd)
  4038  		if err != nil {
  4039  			c.Fatal(err, out)
  4040  		}
  4041  
  4042  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  4043  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4044  		}
  4045  		return fakeContextFromDir(tmpDir)
  4046  	}()
  4047  
  4048  	defer ctx.Close()
  4049  
  4050  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4051  		c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  4052  	}
  4053  
  4054  }
  4055  
  4056  func (s *DockerSuite) TestBuildAddTarXzGz(c *check.C) {
  4057  	name := "testbuildaddtarxzgz"
  4058  
  4059  	ctx := func() *FakeContext {
  4060  		dockerfile := `
  4061  			FROM busybox
  4062  			ADD test.tar.xz.gz /
  4063  			RUN ls /test.tar.xz.gz`
  4064  		tmpDir, err := ioutil.TempDir("", "fake-context")
  4065  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  4066  		if err != nil {
  4067  			c.Fatalf("failed to create test.tar archive: %v", err)
  4068  		}
  4069  		defer testTar.Close()
  4070  
  4071  		tw := tar.NewWriter(testTar)
  4072  
  4073  		if err := tw.WriteHeader(&tar.Header{
  4074  			Name: "test/foo",
  4075  			Size: 2,
  4076  		}); err != nil {
  4077  			c.Fatalf("failed to write tar file header: %v", err)
  4078  		}
  4079  		if _, err := tw.Write([]byte("Hi")); err != nil {
  4080  			c.Fatalf("failed to write tar file content: %v", err)
  4081  		}
  4082  		if err := tw.Close(); err != nil {
  4083  			c.Fatalf("failed to close tar archive: %v", err)
  4084  		}
  4085  
  4086  		xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  4087  		xzCompressCmd.Dir = tmpDir
  4088  		out, _, err := runCommandWithOutput(xzCompressCmd)
  4089  		if err != nil {
  4090  			c.Fatal(err, out)
  4091  		}
  4092  
  4093  		gzipCompressCmd := exec.Command("gzip", "test.tar.xz")
  4094  		gzipCompressCmd.Dir = tmpDir
  4095  		out, _, err = runCommandWithOutput(gzipCompressCmd)
  4096  		if err != nil {
  4097  			c.Fatal(err, out)
  4098  		}
  4099  
  4100  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  4101  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4102  		}
  4103  		return fakeContextFromDir(tmpDir)
  4104  	}()
  4105  
  4106  	defer ctx.Close()
  4107  
  4108  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4109  		c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  4110  	}
  4111  
  4112  }
  4113  
  4114  func (s *DockerSuite) TestBuildFromGIT(c *check.C) {
  4115  	name := "testbuildfromgit"
  4116  	git, err := fakeGIT("repo", map[string]string{
  4117  		"Dockerfile": `FROM busybox
  4118  					ADD first /first
  4119  					RUN [ -f /first ]
  4120  					MAINTAINER docker`,
  4121  		"first": "test git data",
  4122  	}, true)
  4123  	if err != nil {
  4124  		c.Fatal(err)
  4125  	}
  4126  	defer git.Close()
  4127  
  4128  	_, err = buildImageFromPath(name, git.RepoURL, true)
  4129  	if err != nil {
  4130  		c.Fatal(err)
  4131  	}
  4132  	res, err := inspectField(name, "Author")
  4133  	if err != nil {
  4134  		c.Fatal(err)
  4135  	}
  4136  	if res != "docker" {
  4137  		c.Fatalf("Maintainer should be docker, got %s", res)
  4138  	}
  4139  }
  4140  
  4141  func (s *DockerSuite) TestBuildFromGITWithContext(c *check.C) {
  4142  	name := "testbuildfromgit"
  4143  	defer deleteImages(name)
  4144  	git, err := fakeGIT("repo", map[string]string{
  4145  		"docker/Dockerfile": `FROM busybox
  4146  					ADD first /first
  4147  					RUN [ -f /first ]
  4148  					MAINTAINER docker`,
  4149  		"docker/first": "test git data",
  4150  	}, true)
  4151  	if err != nil {
  4152  		c.Fatal(err)
  4153  	}
  4154  	defer git.Close()
  4155  
  4156  	u := fmt.Sprintf("%s#master:docker", git.RepoURL)
  4157  	_, err = buildImageFromPath(name, u, true)
  4158  	if err != nil {
  4159  		c.Fatal(err)
  4160  	}
  4161  	res, err := inspectField(name, "Author")
  4162  	if err != nil {
  4163  		c.Fatal(err)
  4164  	}
  4165  	if res != "docker" {
  4166  		c.Fatalf("Maintainer should be docker, got %s", res)
  4167  	}
  4168  }
  4169  
  4170  func (s *DockerSuite) TestBuildFromRemoteTarball(c *check.C) {
  4171  	name := "testbuildfromremotetarball"
  4172  
  4173  	buffer := new(bytes.Buffer)
  4174  	tw := tar.NewWriter(buffer)
  4175  	defer tw.Close()
  4176  
  4177  	dockerfile := []byte(`FROM busybox
  4178  					MAINTAINER docker`)
  4179  	if err := tw.WriteHeader(&tar.Header{
  4180  		Name: "Dockerfile",
  4181  		Size: int64(len(dockerfile)),
  4182  	}); err != nil {
  4183  		c.Fatalf("failed to write tar file header: %v", err)
  4184  	}
  4185  	if _, err := tw.Write(dockerfile); err != nil {
  4186  		c.Fatalf("failed to write tar file content: %v", err)
  4187  	}
  4188  	if err := tw.Close(); err != nil {
  4189  		c.Fatalf("failed to close tar archive: %v", err)
  4190  	}
  4191  
  4192  	server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
  4193  		"testT.tar": buffer,
  4194  	})
  4195  	c.Assert(err, check.IsNil)
  4196  
  4197  	defer server.Close()
  4198  
  4199  	_, err = buildImageFromPath(name, server.URL()+"/testT.tar", true)
  4200  	c.Assert(err, check.IsNil)
  4201  
  4202  	res, err := inspectField(name, "Author")
  4203  	c.Assert(err, check.IsNil)
  4204  
  4205  	if res != "docker" {
  4206  		c.Fatalf("Maintainer should be docker, got %s", res)
  4207  	}
  4208  }
  4209  
  4210  func (s *DockerSuite) TestBuildCleanupCmdOnEntrypoint(c *check.C) {
  4211  	name := "testbuildcmdcleanuponentrypoint"
  4212  	if _, err := buildImage(name,
  4213  		`FROM scratch
  4214          CMD ["test"]
  4215  		ENTRYPOINT ["echo"]`,
  4216  		true); err != nil {
  4217  		c.Fatal(err)
  4218  	}
  4219  	if _, err := buildImage(name,
  4220  		fmt.Sprintf(`FROM %s
  4221  		ENTRYPOINT ["cat"]`, name),
  4222  		true); err != nil {
  4223  		c.Fatal(err)
  4224  	}
  4225  	res, err := inspectField(name, "Config.Cmd")
  4226  	if err != nil {
  4227  		c.Fatal(err)
  4228  	}
  4229  	if res != "<nil>" {
  4230  		c.Fatalf("Cmd %s, expected nil", res)
  4231  	}
  4232  
  4233  	res, err = inspectField(name, "Config.Entrypoint")
  4234  	if err != nil {
  4235  		c.Fatal(err)
  4236  	}
  4237  	if expected := "{[cat]}"; res != expected {
  4238  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  4239  	}
  4240  }
  4241  
  4242  func (s *DockerSuite) TestBuildClearCmd(c *check.C) {
  4243  	name := "testbuildclearcmd"
  4244  	_, err := buildImage(name,
  4245  		`From scratch
  4246     ENTRYPOINT ["/bin/bash"]
  4247     CMD []`,
  4248  		true)
  4249  	if err != nil {
  4250  		c.Fatal(err)
  4251  	}
  4252  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4253  	if err != nil {
  4254  		c.Fatal(err)
  4255  	}
  4256  	if res != "[]" {
  4257  		c.Fatalf("Cmd %s, expected %s", res, "[]")
  4258  	}
  4259  }
  4260  
  4261  func (s *DockerSuite) TestBuildEmptyCmd(c *check.C) {
  4262  	name := "testbuildemptycmd"
  4263  	if _, err := buildImage(name, "FROM scratch\nMAINTAINER quux\n", true); err != nil {
  4264  		c.Fatal(err)
  4265  	}
  4266  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4267  	if err != nil {
  4268  		c.Fatal(err)
  4269  	}
  4270  	if res != "null" {
  4271  		c.Fatalf("Cmd %s, expected %s", res, "null")
  4272  	}
  4273  }
  4274  
  4275  func (s *DockerSuite) TestBuildOnBuildOutput(c *check.C) {
  4276  	name := "testbuildonbuildparent"
  4277  	if _, err := buildImage(name, "FROM busybox\nONBUILD RUN echo foo\n", true); err != nil {
  4278  		c.Fatal(err)
  4279  	}
  4280  
  4281  	_, out, err := buildImageWithOut(name, "FROM "+name+"\nMAINTAINER quux\n", true)
  4282  	if err != nil {
  4283  		c.Fatal(err)
  4284  	}
  4285  
  4286  	if !strings.Contains(out, "Trigger 0, RUN echo foo") {
  4287  		c.Fatal("failed to find the ONBUILD output", out)
  4288  	}
  4289  
  4290  }
  4291  
  4292  func (s *DockerSuite) TestBuildInvalidTag(c *check.C) {
  4293  	name := "abcd:" + stringutils.GenerateRandomAlphaOnlyString(200)
  4294  	_, out, err := buildImageWithOut(name, "FROM scratch\nMAINTAINER quux\n", true)
  4295  	// if the error doesnt check for illegal tag name, or the image is built
  4296  	// then this should fail
  4297  	if !strings.Contains(out, "Illegal tag name") || strings.Contains(out, "Sending build context to Docker daemon") {
  4298  		c.Fatalf("failed to stop before building. Error: %s, Output: %s", err, out)
  4299  	}
  4300  }
  4301  
  4302  func (s *DockerSuite) TestBuildCmdShDashC(c *check.C) {
  4303  	name := "testbuildcmdshc"
  4304  	if _, err := buildImage(name, "FROM busybox\nCMD echo cmd\n", true); err != nil {
  4305  		c.Fatal(err)
  4306  	}
  4307  
  4308  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4309  	if err != nil {
  4310  		c.Fatal(err, res)
  4311  	}
  4312  
  4313  	expected := `["/bin/sh","-c","echo cmd"]`
  4314  
  4315  	if res != expected {
  4316  		c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  4317  	}
  4318  
  4319  }
  4320  
  4321  func (s *DockerSuite) TestBuildCmdSpaces(c *check.C) {
  4322  	// Test to make sure that when we strcat arrays we take into account
  4323  	// the arg separator to make sure ["echo","hi"] and ["echo hi"] don't
  4324  	// look the same
  4325  	name := "testbuildcmdspaces"
  4326  	var id1 string
  4327  	var id2 string
  4328  	var err error
  4329  
  4330  	if id1, err = buildImage(name, "FROM busybox\nCMD [\"echo hi\"]\n", true); err != nil {
  4331  		c.Fatal(err)
  4332  	}
  4333  
  4334  	if id2, err = buildImage(name, "FROM busybox\nCMD [\"echo\", \"hi\"]\n", true); err != nil {
  4335  		c.Fatal(err)
  4336  	}
  4337  
  4338  	if id1 == id2 {
  4339  		c.Fatal("Should not have resulted in the same CMD")
  4340  	}
  4341  
  4342  	// Now do the same with ENTRYPOINT
  4343  	if id1, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo hi\"]\n", true); err != nil {
  4344  		c.Fatal(err)
  4345  	}
  4346  
  4347  	if id2, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo\", \"hi\"]\n", true); err != nil {
  4348  		c.Fatal(err)
  4349  	}
  4350  
  4351  	if id1 == id2 {
  4352  		c.Fatal("Should not have resulted in the same ENTRYPOINT")
  4353  	}
  4354  
  4355  }
  4356  
  4357  func (s *DockerSuite) TestBuildCmdJSONNoShDashC(c *check.C) {
  4358  	name := "testbuildcmdjson"
  4359  	if _, err := buildImage(name, "FROM busybox\nCMD [\"echo\", \"cmd\"]", true); err != nil {
  4360  		c.Fatal(err)
  4361  	}
  4362  
  4363  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4364  	if err != nil {
  4365  		c.Fatal(err, res)
  4366  	}
  4367  
  4368  	expected := `["echo","cmd"]`
  4369  
  4370  	if res != expected {
  4371  		c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  4372  	}
  4373  
  4374  }
  4375  
  4376  func (s *DockerSuite) TestBuildErrorInvalidInstruction(c *check.C) {
  4377  	name := "testbuildignoreinvalidinstruction"
  4378  
  4379  	out, _, err := buildImageWithOut(name, "FROM busybox\nfoo bar", true)
  4380  	if err == nil {
  4381  		c.Fatalf("Should have failed: %s", out)
  4382  	}
  4383  
  4384  }
  4385  
  4386  func (s *DockerSuite) TestBuildEntrypointInheritance(c *check.C) {
  4387  
  4388  	if _, err := buildImage("parent", `
  4389      FROM busybox
  4390      ENTRYPOINT exit 130
  4391      `, true); err != nil {
  4392  		c.Fatal(err)
  4393  	}
  4394  
  4395  	status, _ := runCommand(exec.Command(dockerBinary, "run", "parent"))
  4396  
  4397  	if status != 130 {
  4398  		c.Fatalf("expected exit code 130 but received %d", status)
  4399  	}
  4400  
  4401  	if _, err := buildImage("child", `
  4402      FROM parent
  4403      ENTRYPOINT exit 5
  4404      `, true); err != nil {
  4405  		c.Fatal(err)
  4406  	}
  4407  
  4408  	status, _ = runCommand(exec.Command(dockerBinary, "run", "child"))
  4409  
  4410  	if status != 5 {
  4411  		c.Fatalf("expected exit code 5 but received %d", status)
  4412  	}
  4413  
  4414  }
  4415  
  4416  func (s *DockerSuite) TestBuildEntrypointInheritanceInspect(c *check.C) {
  4417  	var (
  4418  		name     = "testbuildepinherit"
  4419  		name2    = "testbuildepinherit2"
  4420  		expected = `["/bin/sh","-c","echo quux"]`
  4421  	)
  4422  
  4423  	if _, err := buildImage(name, "FROM busybox\nENTRYPOINT /foo/bar", true); err != nil {
  4424  		c.Fatal(err)
  4425  	}
  4426  
  4427  	if _, err := buildImage(name2, fmt.Sprintf("FROM %s\nENTRYPOINT echo quux", name), true); err != nil {
  4428  		c.Fatal(err)
  4429  	}
  4430  
  4431  	res, err := inspectFieldJSON(name2, "Config.Entrypoint")
  4432  	if err != nil {
  4433  		c.Fatal(err, res)
  4434  	}
  4435  
  4436  	if res != expected {
  4437  		c.Fatalf("Expected value %s not in Config.Entrypoint: %s", expected, res)
  4438  	}
  4439  
  4440  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name2))
  4441  	if err != nil {
  4442  		c.Fatal(err, out)
  4443  	}
  4444  
  4445  	expected = "quux"
  4446  
  4447  	if strings.TrimSpace(out) != expected {
  4448  		c.Fatalf("Expected output is %s, got %s", expected, out)
  4449  	}
  4450  
  4451  }
  4452  
  4453  func (s *DockerSuite) TestBuildRunShEntrypoint(c *check.C) {
  4454  	name := "testbuildentrypoint"
  4455  	_, err := buildImage(name,
  4456  		`FROM busybox
  4457                                  ENTRYPOINT /bin/echo`,
  4458  		true)
  4459  	if err != nil {
  4460  		c.Fatal(err)
  4461  	}
  4462  
  4463  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", name))
  4464  
  4465  	if err != nil {
  4466  		c.Fatal(err, out)
  4467  	}
  4468  
  4469  }
  4470  
  4471  func (s *DockerSuite) TestBuildExoticShellInterpolation(c *check.C) {
  4472  	name := "testbuildexoticshellinterpolation"
  4473  
  4474  	_, err := buildImage(name, `
  4475  		FROM busybox
  4476  
  4477  		ENV SOME_VAR a.b.c
  4478  
  4479  		RUN [ "$SOME_VAR"       = 'a.b.c' ]
  4480  		RUN [ "${SOME_VAR}"     = 'a.b.c' ]
  4481  		RUN [ "${SOME_VAR%.*}"  = 'a.b'   ]
  4482  		RUN [ "${SOME_VAR%%.*}" = 'a'     ]
  4483  		RUN [ "${SOME_VAR#*.}"  = 'b.c'   ]
  4484  		RUN [ "${SOME_VAR##*.}" = 'c'     ]
  4485  		RUN [ "${SOME_VAR/c/d}" = 'a.b.d' ]
  4486  		RUN [ "${#SOME_VAR}"    = '5'     ]
  4487  
  4488  		RUN [ "${SOME_UNSET_VAR:-$SOME_VAR}" = 'a.b.c' ]
  4489  		RUN [ "${SOME_VAR:+Version: ${SOME_VAR}}" = 'Version: a.b.c' ]
  4490  		RUN [ "${SOME_UNSET_VAR:+${SOME_VAR}}" = '' ]
  4491  		RUN [ "${SOME_UNSET_VAR:-${SOME_VAR:-d.e.f}}" = 'a.b.c' ]
  4492  	`, false)
  4493  	if err != nil {
  4494  		c.Fatal(err)
  4495  	}
  4496  
  4497  }
  4498  
  4499  func (s *DockerSuite) TestBuildVerifySingleQuoteFails(c *check.C) {
  4500  	// This testcase is supposed to generate an error because the
  4501  	// JSON array we're passing in on the CMD uses single quotes instead
  4502  	// of double quotes (per the JSON spec). This means we interpret it
  4503  	// as a "string" insead of "JSON array" and pass it on to "sh -c" and
  4504  	// it should barf on it.
  4505  	name := "testbuildsinglequotefails"
  4506  
  4507  	_, err := buildImage(name,
  4508  		`FROM busybox
  4509  		CMD [ '/bin/sh', '-c', 'echo hi' ]`,
  4510  		true)
  4511  	_, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", name))
  4512  
  4513  	if err == nil {
  4514  		c.Fatal("The image was not supposed to be able to run")
  4515  	}
  4516  
  4517  }
  4518  
  4519  func (s *DockerSuite) TestBuildVerboseOut(c *check.C) {
  4520  	name := "testbuildverboseout"
  4521  
  4522  	_, out, err := buildImageWithOut(name,
  4523  		`FROM busybox
  4524  RUN echo 123`,
  4525  		false)
  4526  
  4527  	if err != nil {
  4528  		c.Fatal(err)
  4529  	}
  4530  	if !strings.Contains(out, "\n123\n") {
  4531  		c.Fatalf("Output should contain %q: %q", "123", out)
  4532  	}
  4533  
  4534  }
  4535  
  4536  func (s *DockerSuite) TestBuildWithTabs(c *check.C) {
  4537  	name := "testbuildwithtabs"
  4538  	_, err := buildImage(name,
  4539  		"FROM busybox\nRUN echo\tone\t\ttwo", true)
  4540  	if err != nil {
  4541  		c.Fatal(err)
  4542  	}
  4543  	res, err := inspectFieldJSON(name, "ContainerConfig.Cmd")
  4544  	if err != nil {
  4545  		c.Fatal(err)
  4546  	}
  4547  	expected1 := `["/bin/sh","-c","echo\tone\t\ttwo"]`
  4548  	expected2 := `["/bin/sh","-c","echo\u0009one\u0009\u0009two"]` // syntactically equivalent, and what Go 1.3 generates
  4549  	if res != expected1 && res != expected2 {
  4550  		c.Fatalf("Missing tabs.\nGot: %s\nExp: %s or %s", res, expected1, expected2)
  4551  	}
  4552  }
  4553  
  4554  func (s *DockerSuite) TestBuildLabels(c *check.C) {
  4555  	name := "testbuildlabel"
  4556  	expected := `{"License":"GPL","Vendor":"Acme"}`
  4557  	_, err := buildImage(name,
  4558  		`FROM busybox
  4559  		LABEL Vendor=Acme
  4560                  LABEL License GPL`,
  4561  		true)
  4562  	if err != nil {
  4563  		c.Fatal(err)
  4564  	}
  4565  	res, err := inspectFieldJSON(name, "Config.Labels")
  4566  	if err != nil {
  4567  		c.Fatal(err)
  4568  	}
  4569  	if res != expected {
  4570  		c.Fatalf("Labels %s, expected %s", res, expected)
  4571  	}
  4572  }
  4573  
  4574  func (s *DockerSuite) TestBuildLabelsCache(c *check.C) {
  4575  	name := "testbuildlabelcache"
  4576  
  4577  	id1, err := buildImage(name,
  4578  		`FROM busybox
  4579  		LABEL Vendor=Acme`, false)
  4580  	if err != nil {
  4581  		c.Fatalf("Build 1 should have worked: %v", err)
  4582  	}
  4583  
  4584  	id2, err := buildImage(name,
  4585  		`FROM busybox
  4586  		LABEL Vendor=Acme`, true)
  4587  	if err != nil || id1 != id2 {
  4588  		c.Fatalf("Build 2 should have worked & used cache(%s,%s): %v", id1, id2, err)
  4589  	}
  4590  
  4591  	id2, err = buildImage(name,
  4592  		`FROM busybox
  4593  		LABEL Vendor=Acme1`, true)
  4594  	if err != nil || id1 == id2 {
  4595  		c.Fatalf("Build 3 should have worked & NOT used cache(%s,%s): %v", id1, id2, err)
  4596  	}
  4597  
  4598  	id2, err = buildImage(name,
  4599  		`FROM busybox
  4600  		LABEL Vendor Acme`, true) // Note: " " and "=" should be same
  4601  	if err != nil || id1 != id2 {
  4602  		c.Fatalf("Build 4 should have worked & used cache(%s,%s): %v", id1, id2, err)
  4603  	}
  4604  
  4605  	// Now make sure the cache isn't used by mistake
  4606  	id1, err = buildImage(name,
  4607  		`FROM busybox
  4608         LABEL f1=b1 f2=b2`, false)
  4609  	if err != nil {
  4610  		c.Fatalf("Build 5 should have worked: %q", err)
  4611  	}
  4612  
  4613  	id2, err = buildImage(name,
  4614  		`FROM busybox
  4615         LABEL f1="b1 f2=b2"`, true)
  4616  	if err != nil || id1 == id2 {
  4617  		c.Fatalf("Build 6 should have worked & NOT used the cache(%s,%s): %q", id1, id2, err)
  4618  	}
  4619  
  4620  }
  4621  
  4622  func (s *DockerSuite) TestBuildStderr(c *check.C) {
  4623  	// This test just makes sure that no non-error output goes
  4624  	// to stderr
  4625  	name := "testbuildstderr"
  4626  	_, _, stderr, err := buildImageWithStdoutStderr(name,
  4627  		"FROM busybox\nRUN echo one", true)
  4628  	if err != nil {
  4629  		c.Fatal(err)
  4630  	}
  4631  
  4632  	if runtime.GOOS == "windows" {
  4633  		// stderr might contain a security warning on windows
  4634  		lines := strings.Split(stderr, "\n")
  4635  		for _, v := range lines {
  4636  			if v != "" && !strings.Contains(v, "SECURITY WARNING:") {
  4637  				c.Fatalf("Stderr contains unexpected output line: %q", v)
  4638  			}
  4639  		}
  4640  	} else {
  4641  		if stderr != "" {
  4642  			c.Fatalf("Stderr should have been empty, instead its: %q", stderr)
  4643  		}
  4644  	}
  4645  }
  4646  
  4647  func (s *DockerSuite) TestBuildChownSingleFile(c *check.C) {
  4648  	testRequires(c, UnixCli) // test uses chown: not available on windows
  4649  
  4650  	name := "testbuildchownsinglefile"
  4651  
  4652  	ctx, err := fakeContext(`
  4653  FROM busybox
  4654  COPY test /
  4655  RUN ls -l /test
  4656  RUN [ $(ls -l /test | awk '{print $3":"$4}') = 'root:root' ]
  4657  `, map[string]string{
  4658  		"test": "test",
  4659  	})
  4660  	if err != nil {
  4661  		c.Fatal(err)
  4662  	}
  4663  	defer ctx.Close()
  4664  
  4665  	if err := os.Chown(filepath.Join(ctx.Dir, "test"), 4242, 4242); err != nil {
  4666  		c.Fatal(err)
  4667  	}
  4668  
  4669  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4670  		c.Fatal(err)
  4671  	}
  4672  
  4673  }
  4674  
  4675  func (s *DockerSuite) TestBuildSymlinkBreakout(c *check.C) {
  4676  	name := "testbuildsymlinkbreakout"
  4677  	tmpdir, err := ioutil.TempDir("", name)
  4678  	if err != nil {
  4679  		c.Fatal(err)
  4680  	}
  4681  	defer os.RemoveAll(tmpdir)
  4682  	ctx := filepath.Join(tmpdir, "context")
  4683  	if err := os.MkdirAll(ctx, 0755); err != nil {
  4684  		c.Fatal(err)
  4685  	}
  4686  	if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte(`
  4687  	from busybox
  4688  	add symlink.tar /
  4689  	add inject /symlink/
  4690  	`), 0644); err != nil {
  4691  		c.Fatal(err)
  4692  	}
  4693  	inject := filepath.Join(ctx, "inject")
  4694  	if err := ioutil.WriteFile(inject, nil, 0644); err != nil {
  4695  		c.Fatal(err)
  4696  	}
  4697  	f, err := os.Create(filepath.Join(ctx, "symlink.tar"))
  4698  	if err != nil {
  4699  		c.Fatal(err)
  4700  	}
  4701  	w := tar.NewWriter(f)
  4702  	w.WriteHeader(&tar.Header{
  4703  		Name:     "symlink2",
  4704  		Typeflag: tar.TypeSymlink,
  4705  		Linkname: "/../../../../../../../../../../../../../../",
  4706  		Uid:      os.Getuid(),
  4707  		Gid:      os.Getgid(),
  4708  	})
  4709  	w.WriteHeader(&tar.Header{
  4710  		Name:     "symlink",
  4711  		Typeflag: tar.TypeSymlink,
  4712  		Linkname: filepath.Join("symlink2", tmpdir),
  4713  		Uid:      os.Getuid(),
  4714  		Gid:      os.Getgid(),
  4715  	})
  4716  	w.Close()
  4717  	f.Close()
  4718  	if _, err := buildImageFromContext(name, fakeContextFromDir(ctx), false); err != nil {
  4719  		c.Fatal(err)
  4720  	}
  4721  	if _, err := os.Lstat(filepath.Join(tmpdir, "inject")); err == nil {
  4722  		c.Fatal("symlink breakout - inject")
  4723  	} else if !os.IsNotExist(err) {
  4724  		c.Fatalf("unexpected error: %v", err)
  4725  	}
  4726  }
  4727  
  4728  func (s *DockerSuite) TestBuildXZHost(c *check.C) {
  4729  	name := "testbuildxzhost"
  4730  
  4731  	ctx, err := fakeContext(`
  4732  FROM busybox
  4733  ADD xz /usr/local/sbin/
  4734  RUN chmod 755 /usr/local/sbin/xz
  4735  ADD test.xz /
  4736  RUN [ ! -e /injected ]`,
  4737  		map[string]string{
  4738  			"test.xz": "\xfd\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00" +
  4739  				"\x21\x01\x16\x00\x00\x00\x74\x2f\xe5\xa3\x01\x00\x3f\xfd" +
  4740  				"\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00\x21",
  4741  			"xz": "#!/bin/sh\ntouch /injected",
  4742  		})
  4743  
  4744  	if err != nil {
  4745  		c.Fatal(err)
  4746  	}
  4747  	defer ctx.Close()
  4748  
  4749  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4750  		c.Fatal(err)
  4751  	}
  4752  
  4753  }
  4754  
  4755  func (s *DockerSuite) TestBuildVolumesRetainContents(c *check.C) {
  4756  	var (
  4757  		name     = "testbuildvolumescontent"
  4758  		expected = "some text"
  4759  	)
  4760  	ctx, err := fakeContext(`
  4761  FROM busybox
  4762  COPY content /foo/file
  4763  VOLUME /foo
  4764  CMD cat /foo/file`,
  4765  		map[string]string{
  4766  			"content": expected,
  4767  		})
  4768  	if err != nil {
  4769  		c.Fatal(err)
  4770  	}
  4771  	defer ctx.Close()
  4772  
  4773  	if _, err := buildImageFromContext(name, ctx, false); err != nil {
  4774  		c.Fatal(err)
  4775  	}
  4776  
  4777  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", name))
  4778  	if err != nil {
  4779  		c.Fatal(err)
  4780  	}
  4781  	if out != expected {
  4782  		c.Fatalf("expected file contents for /foo/file to be %q but received %q", expected, out)
  4783  	}
  4784  
  4785  }
  4786  
  4787  func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) {
  4788  
  4789  	ctx, err := fakeContext(`FROM busybox
  4790  	RUN echo from Dockerfile`,
  4791  		map[string]string{
  4792  			"Dockerfile":       "FROM busybox\nRUN echo from Dockerfile",
  4793  			"files/Dockerfile": "FROM busybox\nRUN echo from files/Dockerfile",
  4794  			"files/dFile":      "FROM busybox\nRUN echo from files/dFile",
  4795  			"dFile":            "FROM busybox\nRUN echo from dFile",
  4796  			"files/dFile2":     "FROM busybox\nRUN echo from files/dFile2",
  4797  		})
  4798  	defer ctx.Close()
  4799  	if err != nil {
  4800  		c.Fatal(err)
  4801  	}
  4802  
  4803  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4804  	if err != nil {
  4805  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4806  	}
  4807  	if !strings.Contains(out, "from Dockerfile") {
  4808  		c.Fatalf("test1 should have used Dockerfile, output:%s", out)
  4809  	}
  4810  
  4811  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-f", filepath.Join("files", "Dockerfile"), "-t", "test2", ".")
  4812  	if err != nil {
  4813  		c.Fatal(err)
  4814  	}
  4815  	if !strings.Contains(out, "from files/Dockerfile") {
  4816  		c.Fatalf("test2 should have used files/Dockerfile, output:%s", out)
  4817  	}
  4818  
  4819  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", filepath.Join("files", "dFile")), "-t", "test3", ".")
  4820  	if err != nil {
  4821  		c.Fatal(err)
  4822  	}
  4823  	if !strings.Contains(out, "from files/dFile") {
  4824  		c.Fatalf("test3 should have used files/dFile, output:%s", out)
  4825  	}
  4826  
  4827  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "--file=dFile", "-t", "test4", ".")
  4828  	if err != nil {
  4829  		c.Fatal(err)
  4830  	}
  4831  	if !strings.Contains(out, "from dFile") {
  4832  		c.Fatalf("test4 should have used dFile, output:%s", out)
  4833  	}
  4834  
  4835  	dirWithNoDockerfile, _ := ioutil.TempDir(os.TempDir(), "test5")
  4836  	nonDockerfileFile := filepath.Join(dirWithNoDockerfile, "notDockerfile")
  4837  	if _, err = os.Create(nonDockerfileFile); err != nil {
  4838  		c.Fatal(err)
  4839  	}
  4840  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", nonDockerfileFile), "-t", "test5", ".")
  4841  
  4842  	if err == nil {
  4843  		c.Fatalf("test5 was supposed to fail to find passwd")
  4844  	}
  4845  
  4846  	if expected := fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", nonDockerfileFile); !strings.Contains(out, expected) {
  4847  		c.Fatalf("wrong error messsage:%v\nexpected to contain=%v", out, expected)
  4848  	}
  4849  
  4850  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test6", "..")
  4851  	if err != nil {
  4852  		c.Fatalf("test6 failed: %s", err)
  4853  	}
  4854  	if !strings.Contains(out, "from Dockerfile") {
  4855  		c.Fatalf("test6 should have used root Dockerfile, output:%s", out)
  4856  	}
  4857  
  4858  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join(ctx.Dir, "files", "Dockerfile"), "-t", "test7", "..")
  4859  	if err != nil {
  4860  		c.Fatalf("test7 failed: %s", err)
  4861  	}
  4862  	if !strings.Contains(out, "from files/Dockerfile") {
  4863  		c.Fatalf("test7 should have used files Dockerfile, output:%s", out)
  4864  	}
  4865  
  4866  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test8", ".")
  4867  	if err == nil || !strings.Contains(out, "must be within the build context") {
  4868  		c.Fatalf("test8 should have failed with Dockerfile out of context: %s", err)
  4869  	}
  4870  
  4871  	tmpDir := os.TempDir()
  4872  	out, _, err = dockerCmdInDir(c, tmpDir, "build", "-t", "test9", ctx.Dir)
  4873  	if err != nil {
  4874  		c.Fatalf("test9 - failed: %s", err)
  4875  	}
  4876  	if !strings.Contains(out, "from Dockerfile") {
  4877  		c.Fatalf("test9 should have used root Dockerfile, output:%s", out)
  4878  	}
  4879  
  4880  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", "dFile2", "-t", "test10", ".")
  4881  	if err != nil {
  4882  		c.Fatalf("test10 should have worked: %s", err)
  4883  	}
  4884  	if !strings.Contains(out, "from files/dFile2") {
  4885  		c.Fatalf("test10 should have used files/dFile2, output:%s", out)
  4886  	}
  4887  
  4888  }
  4889  
  4890  func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) {
  4891  	testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  4892  
  4893  	ctx, err := fakeContext(`FROM busybox
  4894  	RUN echo from dockerfile`,
  4895  		map[string]string{
  4896  			"dockerfile": "FROM busybox\nRUN echo from dockerfile",
  4897  		})
  4898  	defer ctx.Close()
  4899  	if err != nil {
  4900  		c.Fatal(err)
  4901  	}
  4902  
  4903  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4904  	if err != nil {
  4905  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4906  	}
  4907  
  4908  	if !strings.Contains(out, "from dockerfile") {
  4909  		c.Fatalf("Missing proper output: %s", out)
  4910  	}
  4911  
  4912  }
  4913  
  4914  func (s *DockerSuite) TestBuildWithTwoDockerfiles(c *check.C) {
  4915  	testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  4916  
  4917  	ctx, err := fakeContext(`FROM busybox
  4918  RUN echo from Dockerfile`,
  4919  		map[string]string{
  4920  			"dockerfile": "FROM busybox\nRUN echo from dockerfile",
  4921  		})
  4922  	defer ctx.Close()
  4923  	if err != nil {
  4924  		c.Fatal(err)
  4925  	}
  4926  
  4927  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4928  	if err != nil {
  4929  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4930  	}
  4931  
  4932  	if !strings.Contains(out, "from Dockerfile") {
  4933  		c.Fatalf("Missing proper output: %s", out)
  4934  	}
  4935  
  4936  }
  4937  
  4938  func (s *DockerSuite) TestBuildFromURLWithF(c *check.C) {
  4939  
  4940  	server, err := fakeStorage(map[string]string{"baz": `FROM busybox
  4941  RUN echo from baz
  4942  COPY * /tmp/
  4943  RUN find /tmp/`})
  4944  	if err != nil {
  4945  		c.Fatal(err)
  4946  	}
  4947  	defer server.Close()
  4948  
  4949  	ctx, err := fakeContext(`FROM busybox
  4950  RUN echo from Dockerfile`,
  4951  		map[string]string{})
  4952  	defer ctx.Close()
  4953  	if err != nil {
  4954  		c.Fatal(err)
  4955  	}
  4956  
  4957  	// Make sure that -f is ignored and that we don't use the Dockerfile
  4958  	// that's in the current dir
  4959  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-f", "baz", "-t", "test1", server.URL()+"/baz")
  4960  	if err != nil {
  4961  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4962  	}
  4963  
  4964  	if !strings.Contains(out, "from baz") ||
  4965  		strings.Contains(out, "/tmp/baz") ||
  4966  		!strings.Contains(out, "/tmp/Dockerfile") {
  4967  		c.Fatalf("Missing proper output: %s", out)
  4968  	}
  4969  
  4970  }
  4971  
  4972  func (s *DockerSuite) TestBuildFromStdinWithF(c *check.C) {
  4973  
  4974  	ctx, err := fakeContext(`FROM busybox
  4975  RUN echo from Dockerfile`,
  4976  		map[string]string{})
  4977  	defer ctx.Close()
  4978  	if err != nil {
  4979  		c.Fatal(err)
  4980  	}
  4981  
  4982  	// Make sure that -f is ignored and that we don't use the Dockerfile
  4983  	// that's in the current dir
  4984  	dockerCommand := exec.Command(dockerBinary, "build", "-f", "baz", "-t", "test1", "-")
  4985  	dockerCommand.Dir = ctx.Dir
  4986  	dockerCommand.Stdin = strings.NewReader(`FROM busybox
  4987  RUN echo from baz
  4988  COPY * /tmp/
  4989  RUN find /tmp/`)
  4990  	out, status, err := runCommandWithOutput(dockerCommand)
  4991  	if err != nil || status != 0 {
  4992  		c.Fatalf("Error building: %s", err)
  4993  	}
  4994  
  4995  	if !strings.Contains(out, "from baz") ||
  4996  		strings.Contains(out, "/tmp/baz") ||
  4997  		!strings.Contains(out, "/tmp/Dockerfile") {
  4998  		c.Fatalf("Missing proper output: %s", out)
  4999  	}
  5000  
  5001  }
  5002  
  5003  func (s *DockerSuite) TestBuildFromOfficialNames(c *check.C) {
  5004  	name := "testbuildfromofficial"
  5005  	fromNames := []string{
  5006  		"busybox",
  5007  		"docker.io/busybox",
  5008  		"index.docker.io/busybox",
  5009  		"library/busybox",
  5010  		"docker.io/library/busybox",
  5011  		"index.docker.io/library/busybox",
  5012  	}
  5013  	for idx, fromName := range fromNames {
  5014  		imgName := fmt.Sprintf("%s%d", name, idx)
  5015  		_, err := buildImage(imgName, "FROM "+fromName, true)
  5016  		if err != nil {
  5017  			c.Errorf("Build failed using FROM %s: %s", fromName, err)
  5018  		}
  5019  		deleteImages(imgName)
  5020  	}
  5021  }
  5022  
  5023  func (s *DockerSuite) TestBuildDockerfileOutsideContext(c *check.C) {
  5024  	testRequires(c, UnixCli) // uses os.Symlink: not implemented in windows at the time of writing (go-1.4.2)
  5025  
  5026  	name := "testbuilddockerfileoutsidecontext"
  5027  	tmpdir, err := ioutil.TempDir("", name)
  5028  	if err != nil {
  5029  		c.Fatal(err)
  5030  	}
  5031  	defer os.RemoveAll(tmpdir)
  5032  	ctx := filepath.Join(tmpdir, "context")
  5033  	if err := os.MkdirAll(ctx, 0755); err != nil {
  5034  		c.Fatal(err)
  5035  	}
  5036  	if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte("FROM scratch\nENV X Y"), 0644); err != nil {
  5037  		c.Fatal(err)
  5038  	}
  5039  	wd, err := os.Getwd()
  5040  	if err != nil {
  5041  		c.Fatal(err)
  5042  	}
  5043  	defer os.Chdir(wd)
  5044  	if err := os.Chdir(ctx); err != nil {
  5045  		c.Fatal(err)
  5046  	}
  5047  	if err := ioutil.WriteFile(filepath.Join(tmpdir, "outsideDockerfile"), []byte("FROM scratch\nENV x y"), 0644); err != nil {
  5048  		c.Fatal(err)
  5049  	}
  5050  	if err := os.Symlink(filepath.Join("..", "outsideDockerfile"), filepath.Join(ctx, "dockerfile1")); err != nil {
  5051  		c.Fatal(err)
  5052  	}
  5053  	if err := os.Symlink(filepath.Join(tmpdir, "outsideDockerfile"), filepath.Join(ctx, "dockerfile2")); err != nil {
  5054  		c.Fatal(err)
  5055  	}
  5056  
  5057  	for _, dockerfilePath := range []string{
  5058  		filepath.Join("..", "outsideDockerfile"),
  5059  		filepath.Join(ctx, "dockerfile1"),
  5060  		filepath.Join(ctx, "dockerfile2"),
  5061  	} {
  5062  		out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "build", "-t", name, "--no-cache", "-f", dockerfilePath, "."))
  5063  		if err == nil {
  5064  			c.Fatalf("Expected error with %s. Out: %s", dockerfilePath, out)
  5065  		}
  5066  		if !strings.Contains(out, "must be within the build context") && !strings.Contains(out, "Cannot locate Dockerfile") {
  5067  			c.Fatalf("Unexpected error with %s. Out: %s", dockerfilePath, out)
  5068  		}
  5069  		deleteImages(name)
  5070  	}
  5071  
  5072  	os.Chdir(tmpdir)
  5073  
  5074  	// Path to Dockerfile should be resolved relative to working directory, not relative to context.
  5075  	// There is a Dockerfile in the context, but since there is no Dockerfile in the current directory, the following should fail
  5076  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "build", "-t", name, "--no-cache", "-f", "Dockerfile", ctx))
  5077  	if err == nil {
  5078  		c.Fatalf("Expected error. Out: %s", out)
  5079  	}
  5080  }
  5081  
  5082  func (s *DockerSuite) TestBuildSpaces(c *check.C) {
  5083  	// Test to make sure that leading/trailing spaces on a command
  5084  	// doesn't change the error msg we get
  5085  	var (
  5086  		err1 error
  5087  		err2 error
  5088  	)
  5089  
  5090  	name := "testspaces"
  5091  	ctx, err := fakeContext("FROM busybox\nCOPY\n",
  5092  		map[string]string{
  5093  			"Dockerfile": "FROM busybox\nCOPY\n",
  5094  		})
  5095  	if err != nil {
  5096  		c.Fatal(err)
  5097  	}
  5098  	defer ctx.Close()
  5099  
  5100  	if _, err1 = buildImageFromContext(name, ctx, false); err1 == nil {
  5101  		c.Fatal("Build 1 was supposed to fail, but didn't")
  5102  	}
  5103  
  5104  	ctx.Add("Dockerfile", "FROM busybox\nCOPY    ")
  5105  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5106  		c.Fatal("Build 2 was supposed to fail, but didn't")
  5107  	}
  5108  
  5109  	removeLogTimestamps := func(s string) string {
  5110  		return regexp.MustCompile(`time="(.*?)"`).ReplaceAllString(s, `time=[TIMESTAMP]`)
  5111  	}
  5112  
  5113  	// Skip over the times
  5114  	e1 := removeLogTimestamps(err1.Error())
  5115  	e2 := removeLogTimestamps(err2.Error())
  5116  
  5117  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5118  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5119  		c.Fatalf("Build 2's error wasn't the same as build 1's\n1:%s\n2:%s", err1, err2)
  5120  	}
  5121  
  5122  	ctx.Add("Dockerfile", "FROM busybox\n   COPY")
  5123  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5124  		c.Fatal("Build 3 was supposed to fail, but didn't")
  5125  	}
  5126  
  5127  	// Skip over the times
  5128  	e1 = removeLogTimestamps(err1.Error())
  5129  	e2 = removeLogTimestamps(err2.Error())
  5130  
  5131  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5132  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5133  		c.Fatalf("Build 3's error wasn't the same as build 1's\n1:%s\n3:%s", err1, err2)
  5134  	}
  5135  
  5136  	ctx.Add("Dockerfile", "FROM busybox\n   COPY    ")
  5137  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5138  		c.Fatal("Build 4 was supposed to fail, but didn't")
  5139  	}
  5140  
  5141  	// Skip over the times
  5142  	e1 = removeLogTimestamps(err1.Error())
  5143  	e2 = removeLogTimestamps(err2.Error())
  5144  
  5145  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5146  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5147  		c.Fatalf("Build 4's error wasn't the same as build 1's\n1:%s\n4:%s", err1, err2)
  5148  	}
  5149  
  5150  }
  5151  
  5152  func (s *DockerSuite) TestBuildSpacesWithQuotes(c *check.C) {
  5153  	// Test to make sure that spaces in quotes aren't lost
  5154  	name := "testspacesquotes"
  5155  
  5156  	dockerfile := `FROM busybox
  5157  RUN echo "  \
  5158    foo  "`
  5159  
  5160  	_, out, err := buildImageWithOut(name, dockerfile, false)
  5161  	if err != nil {
  5162  		c.Fatal("Build failed:", err)
  5163  	}
  5164  
  5165  	expecting := "\n    foo  \n"
  5166  	if !strings.Contains(out, expecting) {
  5167  		c.Fatalf("Bad output: %q expecting to contain %q", out, expecting)
  5168  	}
  5169  
  5170  }
  5171  
  5172  // #4393
  5173  func (s *DockerSuite) TestBuildVolumeFileExistsinContainer(c *check.C) {
  5174  	buildCmd := exec.Command(dockerBinary, "build", "-t", "docker-test-errcreatevolumewithfile", "-")
  5175  	buildCmd.Stdin = strings.NewReader(`
  5176  	FROM busybox
  5177  	RUN touch /foo
  5178  	VOLUME /foo
  5179  	`)
  5180  
  5181  	out, _, err := runCommandWithOutput(buildCmd)
  5182  	if err == nil || !strings.Contains(out, "file exists") {
  5183  		c.Fatalf("expected build to fail when file exists in container at requested volume path")
  5184  	}
  5185  
  5186  }
  5187  
  5188  func (s *DockerSuite) TestBuildMissingArgs(c *check.C) {
  5189  	// Test to make sure that all Dockerfile commands (except the ones listed
  5190  	// in skipCmds) will generate an error if no args are provided.
  5191  	// Note: INSERT is deprecated so we exclude it because of that.
  5192  	skipCmds := map[string]struct{}{
  5193  		"CMD":        {},
  5194  		"RUN":        {},
  5195  		"ENTRYPOINT": {},
  5196  		"INSERT":     {},
  5197  	}
  5198  
  5199  	for cmd := range command.Commands {
  5200  		cmd = strings.ToUpper(cmd)
  5201  		if _, ok := skipCmds[cmd]; ok {
  5202  			continue
  5203  		}
  5204  
  5205  		var dockerfile string
  5206  		if cmd == "FROM" {
  5207  			dockerfile = cmd
  5208  		} else {
  5209  			// Add FROM to make sure we don't complain about it missing
  5210  			dockerfile = "FROM busybox\n" + cmd
  5211  		}
  5212  
  5213  		ctx, err := fakeContext(dockerfile, map[string]string{})
  5214  		if err != nil {
  5215  			c.Fatal(err)
  5216  		}
  5217  		defer ctx.Close()
  5218  		var out string
  5219  		if out, err = buildImageFromContext("args", ctx, true); err == nil {
  5220  			c.Fatalf("%s was supposed to fail. Out:%s", cmd, out)
  5221  		}
  5222  		if !strings.Contains(err.Error(), cmd+" requires") {
  5223  			c.Fatalf("%s returned the wrong type of error:%s", cmd, err)
  5224  		}
  5225  	}
  5226  
  5227  }
  5228  
  5229  func (s *DockerSuite) TestBuildEmptyScratch(c *check.C) {
  5230  	_, out, err := buildImageWithOut("sc", "FROM scratch", true)
  5231  	if err == nil {
  5232  		c.Fatalf("Build was supposed to fail")
  5233  	}
  5234  	if !strings.Contains(out, "No image was generated") {
  5235  		c.Fatalf("Wrong error message: %v", out)
  5236  	}
  5237  }
  5238  
  5239  func (s *DockerSuite) TestBuildDotDotFile(c *check.C) {
  5240  	ctx, err := fakeContext("FROM busybox\n",
  5241  		map[string]string{
  5242  			"..gitme": "",
  5243  		})
  5244  	if err != nil {
  5245  		c.Fatal(err)
  5246  	}
  5247  	defer ctx.Close()
  5248  
  5249  	if _, err = buildImageFromContext("sc", ctx, false); err != nil {
  5250  		c.Fatalf("Build was supposed to work: %s", err)
  5251  	}
  5252  }
  5253  
  5254  func (s *DockerSuite) TestBuildNotVerbose(c *check.C) {
  5255  
  5256  	ctx, err := fakeContext("FROM busybox\nENV abc=hi\nRUN echo $abc there", map[string]string{})
  5257  	if err != nil {
  5258  		c.Fatal(err)
  5259  	}
  5260  	defer ctx.Close()
  5261  
  5262  	// First do it w/verbose - baseline
  5263  	buildCmd := exec.Command(dockerBinary, "build", "--no-cache", "-t", "verbose", ".")
  5264  	buildCmd.Dir = ctx.Dir
  5265  	out, _, err := runCommandWithOutput(buildCmd)
  5266  	if err != nil {
  5267  		c.Fatalf("failed to build the image w/o -q: %s, %v", out, err)
  5268  	}
  5269  	if !strings.Contains(out, "hi there") {
  5270  		c.Fatalf("missing output:%s\n", out)
  5271  	}
  5272  
  5273  	// Now do it w/o verbose
  5274  	buildCmd = exec.Command(dockerBinary, "build", "--no-cache", "-q", "-t", "verbose", ".")
  5275  	buildCmd.Dir = ctx.Dir
  5276  	out, _, err = runCommandWithOutput(buildCmd)
  5277  	if err != nil {
  5278  		c.Fatalf("failed to build the image w/ -q: %s, %v", out, err)
  5279  	}
  5280  	if strings.Contains(out, "hi there") {
  5281  		c.Fatalf("Bad output, should not contain 'hi there':%s", out)
  5282  	}
  5283  
  5284  }
  5285  
  5286  func (s *DockerSuite) TestBuildRUNoneJSON(c *check.C) {
  5287  	name := "testbuildrunonejson"
  5288  
  5289  	ctx, err := fakeContext(`FROM hello-world:frozen
  5290  RUN [ "/hello" ]`, map[string]string{})
  5291  	if err != nil {
  5292  		c.Fatal(err)
  5293  	}
  5294  	defer ctx.Close()
  5295  
  5296  	buildCmd := exec.Command(dockerBinary, "build", "--no-cache", "-t", name, ".")
  5297  	buildCmd.Dir = ctx.Dir
  5298  	out, _, err := runCommandWithOutput(buildCmd)
  5299  	if err != nil {
  5300  		c.Fatalf("failed to build the image: %s, %v", out, err)
  5301  	}
  5302  
  5303  	if !strings.Contains(out, "Hello from Docker") {
  5304  		c.Fatalf("bad output: %s", out)
  5305  	}
  5306  
  5307  }
  5308  
  5309  func (s *DockerSuite) TestBuildEmptyStringVolume(c *check.C) {
  5310  	name := "testbuildemptystringvolume"
  5311  
  5312  	_, err := buildImage(name, `
  5313    FROM busybox
  5314    ENV foo=""
  5315    VOLUME $foo
  5316    `, false)
  5317  	if err == nil {
  5318  		c.Fatal("Should have failed to build")
  5319  	}
  5320  
  5321  }
  5322  
  5323  func (s *DockerSuite) TestBuildContainerWithCgroupParent(c *check.C) {
  5324  	testRequires(c, NativeExecDriver)
  5325  	testRequires(c, SameHostDaemon)
  5326  	defer deleteImages()
  5327  
  5328  	cgroupParent := "test"
  5329  	data, err := ioutil.ReadFile("/proc/self/cgroup")
  5330  	if err != nil {
  5331  		c.Fatalf("failed to read '/proc/self/cgroup - %v", err)
  5332  	}
  5333  	selfCgroupPaths := parseCgroupPaths(string(data))
  5334  	_, found := selfCgroupPaths["memory"]
  5335  	if !found {
  5336  		c.Fatalf("unable to find self cpu cgroup path. CgroupsPath: %v", selfCgroupPaths)
  5337  	}
  5338  	cmd := exec.Command(dockerBinary, "build", "--cgroup-parent", cgroupParent, "-")
  5339  	cmd.Stdin = strings.NewReader(`
  5340  FROM busybox
  5341  RUN cat /proc/self/cgroup
  5342  `)
  5343  
  5344  	out, _, err := runCommandWithOutput(cmd)
  5345  	if err != nil {
  5346  		c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
  5347  	}
  5348  }
  5349  
  5350  func (s *DockerSuite) TestBuildNoDupOutput(c *check.C) {
  5351  	// Check to make sure our build output prints the Dockerfile cmd
  5352  	// property - there was a bug that caused it to be duplicated on the
  5353  	// Step X  line
  5354  	name := "testbuildnodupoutput"
  5355  
  5356  	_, out, err := buildImageWithOut(name, `
  5357    FROM busybox
  5358    RUN env`, false)
  5359  	if err != nil {
  5360  		c.Fatalf("Build should have worked: %q", err)
  5361  	}
  5362  
  5363  	exp := "\nStep 1 : RUN env\n"
  5364  	if !strings.Contains(out, exp) {
  5365  		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  5366  	}
  5367  }
  5368  
  5369  func (s *DockerSuite) TestBuildBadCmdFlag(c *check.C) {
  5370  	name := "testbuildbadcmdflag"
  5371  
  5372  	_, out, err := buildImageWithOut(name, `
  5373    FROM busybox
  5374    MAINTAINER --boo joe@example.com`, false)
  5375  	if err == nil {
  5376  		c.Fatal("Build should have failed")
  5377  	}
  5378  
  5379  	exp := "\nUnknown flag: boo\n"
  5380  	if !strings.Contains(out, exp) {
  5381  		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  5382  	}
  5383  }
  5384  
  5385  func (s *DockerSuite) TestBuildRUNErrMsg(c *check.C) {
  5386  	// Test to make sure the bad command is quoted with just "s and
  5387  	// not as a Go []string
  5388  	name := "testbuildbadrunerrmsg"
  5389  	_, out, err := buildImageWithOut(name, `
  5390    FROM busybox
  5391    RUN badEXE a1 \& a2	a3`, false) // tab between a2 and a3
  5392  	if err == nil {
  5393  		c.Fatal("Should have failed to build")
  5394  	}
  5395  
  5396  	exp := `The command '/bin/sh -c badEXE a1 \& a2	a3' returned a non-zero code: 127`
  5397  	if !strings.Contains(out, exp) {
  5398  		c.Fatalf("RUN doesn't have the correct output:\nGot:%s\nExpected:%s", out, exp)
  5399  	}
  5400  }