github.com/slowteetoe/docker@v1.7.1-rc3/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 is accessible") {
  1726  			c.Fatalf("output should've contained the string: Error checking context is accessible")
  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 is accessible") {
  1763  			c.Fatalf("output should've contained the string: Error checking context is accessible")
  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) TestBuildExposeHostPort(c *check.C) {
  2410  	// start building docker file with ip:hostPort:containerPort
  2411  	name := "testbuildexpose"
  2412  	expected := "map[5678/tcp:{}]"
  2413  	_, out, err := buildImageWithOut(name,
  2414  		`FROM scratch
  2415          EXPOSE 192.168.1.2:2375:5678`,
  2416  		true)
  2417  	if err != nil {
  2418  		c.Fatal(err)
  2419  	}
  2420  
  2421  	if !strings.Contains(out, "to map host ports to container ports (ip:hostPort:containerPort) is deprecated.") {
  2422  		c.Fatal("Missing warning message")
  2423  	}
  2424  
  2425  	res, err := inspectField(name, "Config.ExposedPorts")
  2426  	if err != nil {
  2427  		c.Fatal(err)
  2428  	}
  2429  	if res != expected {
  2430  		c.Fatalf("Exposed ports %s, expected %s", res, expected)
  2431  	}
  2432  }
  2433  
  2434  func (s *DockerSuite) TestBuildEmptyEntrypointInheritance(c *check.C) {
  2435  	name := "testbuildentrypointinheritance"
  2436  	name2 := "testbuildentrypointinheritance2"
  2437  
  2438  	_, err := buildImage(name,
  2439  		`FROM busybox
  2440          ENTRYPOINT ["/bin/echo"]`,
  2441  		true)
  2442  	if err != nil {
  2443  		c.Fatal(err)
  2444  	}
  2445  	res, err := inspectField(name, "Config.Entrypoint")
  2446  	if err != nil {
  2447  		c.Fatal(err)
  2448  	}
  2449  
  2450  	expected := "{[/bin/echo]}"
  2451  	if res != expected {
  2452  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2453  	}
  2454  
  2455  	_, err = buildImage(name2,
  2456  		fmt.Sprintf(`FROM %s
  2457          ENTRYPOINT []`, name),
  2458  		true)
  2459  	if err != nil {
  2460  		c.Fatal(err)
  2461  	}
  2462  	res, err = inspectField(name2, "Config.Entrypoint")
  2463  	if err != nil {
  2464  		c.Fatal(err)
  2465  	}
  2466  
  2467  	expected = "{[]}"
  2468  
  2469  	if res != expected {
  2470  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2471  	}
  2472  
  2473  }
  2474  
  2475  func (s *DockerSuite) TestBuildEmptyEntrypoint(c *check.C) {
  2476  	name := "testbuildentrypoint"
  2477  	expected := "{[]}"
  2478  
  2479  	_, err := buildImage(name,
  2480  		`FROM busybox
  2481          ENTRYPOINT []`,
  2482  		true)
  2483  	if err != nil {
  2484  		c.Fatal(err)
  2485  	}
  2486  	res, err := inspectField(name, "Config.Entrypoint")
  2487  	if err != nil {
  2488  		c.Fatal(err)
  2489  	}
  2490  	if res != expected {
  2491  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2492  	}
  2493  
  2494  }
  2495  
  2496  func (s *DockerSuite) TestBuildEntrypoint(c *check.C) {
  2497  	name := "testbuildentrypoint"
  2498  	expected := "{[/bin/echo]}"
  2499  	_, err := buildImage(name,
  2500  		`FROM scratch
  2501          ENTRYPOINT ["/bin/echo"]`,
  2502  		true)
  2503  	if err != nil {
  2504  		c.Fatal(err)
  2505  	}
  2506  	res, err := inspectField(name, "Config.Entrypoint")
  2507  	if err != nil {
  2508  		c.Fatal(err)
  2509  	}
  2510  	if res != expected {
  2511  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2512  	}
  2513  
  2514  }
  2515  
  2516  // #6445 ensure ONBUILD triggers aren't committed to grandchildren
  2517  func (s *DockerSuite) TestBuildOnBuildLimitedInheritence(c *check.C) {
  2518  	var (
  2519  		out2, out3 string
  2520  	)
  2521  	{
  2522  		name1 := "testonbuildtrigger1"
  2523  		dockerfile1 := `
  2524  		FROM busybox
  2525  		RUN echo "GRANDPARENT"
  2526  		ONBUILD RUN echo "ONBUILD PARENT"
  2527  		`
  2528  		ctx, err := fakeContext(dockerfile1, nil)
  2529  		if err != nil {
  2530  			c.Fatal(err)
  2531  		}
  2532  		defer ctx.Close()
  2533  
  2534  		out1, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", name1, ".")
  2535  		if err != nil {
  2536  			c.Fatalf("build failed to complete: %s, %v", out1, err)
  2537  		}
  2538  	}
  2539  	{
  2540  		name2 := "testonbuildtrigger2"
  2541  		dockerfile2 := `
  2542  		FROM testonbuildtrigger1
  2543  		`
  2544  		ctx, err := fakeContext(dockerfile2, nil)
  2545  		if err != nil {
  2546  			c.Fatal(err)
  2547  		}
  2548  		defer ctx.Close()
  2549  
  2550  		out2, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name2, ".")
  2551  		if err != nil {
  2552  			c.Fatalf("build failed to complete: %s, %v", out2, err)
  2553  		}
  2554  	}
  2555  	{
  2556  		name3 := "testonbuildtrigger3"
  2557  		dockerfile3 := `
  2558  		FROM testonbuildtrigger2
  2559  		`
  2560  		ctx, err := fakeContext(dockerfile3, nil)
  2561  		if err != nil {
  2562  			c.Fatal(err)
  2563  		}
  2564  		defer ctx.Close()
  2565  
  2566  		out3, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name3, ".")
  2567  		if err != nil {
  2568  			c.Fatalf("build failed to complete: %s, %v", out3, err)
  2569  		}
  2570  
  2571  	}
  2572  
  2573  	// ONBUILD should be run in second build.
  2574  	if !strings.Contains(out2, "ONBUILD PARENT") {
  2575  		c.Fatalf("ONBUILD instruction did not run in child of ONBUILD parent")
  2576  	}
  2577  
  2578  	// ONBUILD should *not* be run in third build.
  2579  	if strings.Contains(out3, "ONBUILD PARENT") {
  2580  		c.Fatalf("ONBUILD instruction ran in grandchild of ONBUILD parent")
  2581  	}
  2582  
  2583  }
  2584  
  2585  func (s *DockerSuite) TestBuildWithCache(c *check.C) {
  2586  	name := "testbuildwithcache"
  2587  	id1, err := buildImage(name,
  2588  		`FROM scratch
  2589  		MAINTAINER dockerio
  2590  		EXPOSE 5432
  2591          ENTRYPOINT ["/bin/echo"]`,
  2592  		true)
  2593  	if err != nil {
  2594  		c.Fatal(err)
  2595  	}
  2596  	id2, err := buildImage(name,
  2597  		`FROM scratch
  2598  		MAINTAINER dockerio
  2599  		EXPOSE 5432
  2600          ENTRYPOINT ["/bin/echo"]`,
  2601  		true)
  2602  	if err != nil {
  2603  		c.Fatal(err)
  2604  	}
  2605  	if id1 != id2 {
  2606  		c.Fatal("The cache should have been used but hasn't.")
  2607  	}
  2608  }
  2609  
  2610  func (s *DockerSuite) TestBuildWithoutCache(c *check.C) {
  2611  	name := "testbuildwithoutcache"
  2612  	name2 := "testbuildwithoutcache2"
  2613  	id1, err := buildImage(name,
  2614  		`FROM scratch
  2615  		MAINTAINER dockerio
  2616  		EXPOSE 5432
  2617          ENTRYPOINT ["/bin/echo"]`,
  2618  		true)
  2619  	if err != nil {
  2620  		c.Fatal(err)
  2621  	}
  2622  
  2623  	id2, err := buildImage(name2,
  2624  		`FROM scratch
  2625  		MAINTAINER dockerio
  2626  		EXPOSE 5432
  2627          ENTRYPOINT ["/bin/echo"]`,
  2628  		false)
  2629  	if err != nil {
  2630  		c.Fatal(err)
  2631  	}
  2632  	if id1 == id2 {
  2633  		c.Fatal("The cache should have been invalided but hasn't.")
  2634  	}
  2635  }
  2636  
  2637  func (s *DockerSuite) TestBuildConditionalCache(c *check.C) {
  2638  	name := "testbuildconditionalcache"
  2639  
  2640  	dockerfile := `
  2641  		FROM busybox
  2642          ADD foo /tmp/`
  2643  	ctx, err := fakeContext(dockerfile, map[string]string{
  2644  		"foo": "hello",
  2645  	})
  2646  	if err != nil {
  2647  		c.Fatal(err)
  2648  	}
  2649  	defer ctx.Close()
  2650  
  2651  	id1, err := buildImageFromContext(name, ctx, true)
  2652  	if err != nil {
  2653  		c.Fatalf("Error building #1: %s", err)
  2654  	}
  2655  
  2656  	if err := ctx.Add("foo", "bye"); err != nil {
  2657  		c.Fatalf("Error modifying foo: %s", err)
  2658  	}
  2659  
  2660  	id2, err := buildImageFromContext(name, ctx, false)
  2661  	if err != nil {
  2662  		c.Fatalf("Error building #2: %s", err)
  2663  	}
  2664  	if id2 == id1 {
  2665  		c.Fatal("Should not have used the cache")
  2666  	}
  2667  
  2668  	id3, err := buildImageFromContext(name, ctx, true)
  2669  	if err != nil {
  2670  		c.Fatalf("Error building #3: %s", err)
  2671  	}
  2672  	if id3 != id2 {
  2673  		c.Fatal("Should have used the cache")
  2674  	}
  2675  }
  2676  
  2677  func (s *DockerSuite) TestBuildAddLocalFileWithCache(c *check.C) {
  2678  	name := "testbuildaddlocalfilewithcache"
  2679  	name2 := "testbuildaddlocalfilewithcache2"
  2680  	dockerfile := `
  2681  		FROM busybox
  2682          MAINTAINER dockerio
  2683          ADD foo /usr/lib/bla/bar
  2684  		RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2685  	ctx, err := fakeContext(dockerfile, map[string]string{
  2686  		"foo": "hello",
  2687  	})
  2688  	defer ctx.Close()
  2689  	if err != nil {
  2690  		c.Fatal(err)
  2691  	}
  2692  	id1, err := buildImageFromContext(name, ctx, true)
  2693  	if err != nil {
  2694  		c.Fatal(err)
  2695  	}
  2696  	id2, err := buildImageFromContext(name2, ctx, true)
  2697  	if err != nil {
  2698  		c.Fatal(err)
  2699  	}
  2700  	if id1 != id2 {
  2701  		c.Fatal("The cache should have been used but hasn't.")
  2702  	}
  2703  }
  2704  
  2705  func (s *DockerSuite) TestBuildAddMultipleLocalFileWithCache(c *check.C) {
  2706  	name := "testbuildaddmultiplelocalfilewithcache"
  2707  	name2 := "testbuildaddmultiplelocalfilewithcache2"
  2708  	dockerfile := `
  2709  		FROM busybox
  2710          MAINTAINER dockerio
  2711          ADD foo Dockerfile /usr/lib/bla/
  2712  		RUN [ "$(cat /usr/lib/bla/foo)" = "hello" ]`
  2713  	ctx, err := fakeContext(dockerfile, map[string]string{
  2714  		"foo": "hello",
  2715  	})
  2716  	defer ctx.Close()
  2717  	if err != nil {
  2718  		c.Fatal(err)
  2719  	}
  2720  	id1, err := buildImageFromContext(name, ctx, true)
  2721  	if err != nil {
  2722  		c.Fatal(err)
  2723  	}
  2724  	id2, err := buildImageFromContext(name2, ctx, true)
  2725  	if err != nil {
  2726  		c.Fatal(err)
  2727  	}
  2728  	if id1 != id2 {
  2729  		c.Fatal("The cache should have been used but hasn't.")
  2730  	}
  2731  }
  2732  
  2733  func (s *DockerSuite) TestBuildAddLocalFileWithoutCache(c *check.C) {
  2734  	name := "testbuildaddlocalfilewithoutcache"
  2735  	name2 := "testbuildaddlocalfilewithoutcache2"
  2736  	dockerfile := `
  2737  		FROM busybox
  2738          MAINTAINER dockerio
  2739          ADD foo /usr/lib/bla/bar
  2740  		RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2741  	ctx, err := fakeContext(dockerfile, map[string]string{
  2742  		"foo": "hello",
  2743  	})
  2744  	defer ctx.Close()
  2745  	if err != nil {
  2746  		c.Fatal(err)
  2747  	}
  2748  	id1, err := buildImageFromContext(name, ctx, true)
  2749  	if err != nil {
  2750  		c.Fatal(err)
  2751  	}
  2752  	id2, err := buildImageFromContext(name2, ctx, false)
  2753  	if err != nil {
  2754  		c.Fatal(err)
  2755  	}
  2756  	if id1 == id2 {
  2757  		c.Fatal("The cache should have been invalided but hasn't.")
  2758  	}
  2759  }
  2760  
  2761  func (s *DockerSuite) TestBuildCopyDirButNotFile(c *check.C) {
  2762  	name := "testbuildcopydirbutnotfile"
  2763  	name2 := "testbuildcopydirbutnotfile2"
  2764  	dockerfile := `
  2765          FROM scratch
  2766          COPY dir /tmp/`
  2767  	ctx, err := fakeContext(dockerfile, map[string]string{
  2768  		"dir/foo": "hello",
  2769  	})
  2770  	defer ctx.Close()
  2771  	if err != nil {
  2772  		c.Fatal(err)
  2773  	}
  2774  	id1, err := buildImageFromContext(name, ctx, true)
  2775  	if err != nil {
  2776  		c.Fatal(err)
  2777  	}
  2778  	// Check that adding file with similar name doesn't mess with cache
  2779  	if err := ctx.Add("dir_file", "hello2"); err != nil {
  2780  		c.Fatal(err)
  2781  	}
  2782  	id2, err := buildImageFromContext(name2, ctx, true)
  2783  	if err != nil {
  2784  		c.Fatal(err)
  2785  	}
  2786  	if id1 != id2 {
  2787  		c.Fatal("The cache should have been used but wasn't")
  2788  	}
  2789  }
  2790  
  2791  func (s *DockerSuite) TestBuildAddCurrentDirWithCache(c *check.C) {
  2792  	name := "testbuildaddcurrentdirwithcache"
  2793  	name2 := name + "2"
  2794  	name3 := name + "3"
  2795  	name4 := name + "4"
  2796  	name5 := name + "5"
  2797  	dockerfile := `
  2798          FROM scratch
  2799          MAINTAINER dockerio
  2800          ADD . /usr/lib/bla`
  2801  	ctx, err := fakeContext(dockerfile, map[string]string{
  2802  		"foo": "hello",
  2803  	})
  2804  	defer ctx.Close()
  2805  	if err != nil {
  2806  		c.Fatal(err)
  2807  	}
  2808  	id1, err := buildImageFromContext(name, ctx, true)
  2809  	if err != nil {
  2810  		c.Fatal(err)
  2811  	}
  2812  	// Check that adding file invalidate cache of "ADD ."
  2813  	if err := ctx.Add("bar", "hello2"); err != nil {
  2814  		c.Fatal(err)
  2815  	}
  2816  	id2, err := buildImageFromContext(name2, ctx, true)
  2817  	if err != nil {
  2818  		c.Fatal(err)
  2819  	}
  2820  	if id1 == id2 {
  2821  		c.Fatal("The cache should have been invalided but hasn't.")
  2822  	}
  2823  	// Check that changing file invalidate cache of "ADD ."
  2824  	if err := ctx.Add("foo", "hello1"); err != nil {
  2825  		c.Fatal(err)
  2826  	}
  2827  	id3, err := buildImageFromContext(name3, ctx, true)
  2828  	if err != nil {
  2829  		c.Fatal(err)
  2830  	}
  2831  	if id2 == id3 {
  2832  		c.Fatal("The cache should have been invalided but hasn't.")
  2833  	}
  2834  	// Check that changing file to same content invalidate cache of "ADD ."
  2835  	time.Sleep(1 * time.Second) // wait second because of mtime precision
  2836  	if err := ctx.Add("foo", "hello1"); err != nil {
  2837  		c.Fatal(err)
  2838  	}
  2839  	id4, err := buildImageFromContext(name4, ctx, true)
  2840  	if err != nil {
  2841  		c.Fatal(err)
  2842  	}
  2843  	if id3 == id4 {
  2844  		c.Fatal("The cache should have been invalided but hasn't.")
  2845  	}
  2846  	id5, err := buildImageFromContext(name5, ctx, true)
  2847  	if err != nil {
  2848  		c.Fatal(err)
  2849  	}
  2850  	if id4 != id5 {
  2851  		c.Fatal("The cache should have been used but hasn't.")
  2852  	}
  2853  }
  2854  
  2855  func (s *DockerSuite) TestBuildAddCurrentDirWithoutCache(c *check.C) {
  2856  	name := "testbuildaddcurrentdirwithoutcache"
  2857  	name2 := "testbuildaddcurrentdirwithoutcache2"
  2858  	dockerfile := `
  2859          FROM scratch
  2860          MAINTAINER dockerio
  2861          ADD . /usr/lib/bla`
  2862  	ctx, err := fakeContext(dockerfile, map[string]string{
  2863  		"foo": "hello",
  2864  	})
  2865  	defer ctx.Close()
  2866  	if err != nil {
  2867  		c.Fatal(err)
  2868  	}
  2869  	id1, err := buildImageFromContext(name, ctx, true)
  2870  	if err != nil {
  2871  		c.Fatal(err)
  2872  	}
  2873  	id2, err := buildImageFromContext(name2, ctx, false)
  2874  	if err != nil {
  2875  		c.Fatal(err)
  2876  	}
  2877  	if id1 == id2 {
  2878  		c.Fatal("The cache should have been invalided but hasn't.")
  2879  	}
  2880  }
  2881  
  2882  func (s *DockerSuite) TestBuildAddRemoteFileWithCache(c *check.C) {
  2883  	name := "testbuildaddremotefilewithcache"
  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(name,
  2901  		fmt.Sprintf(`FROM scratch
  2902          MAINTAINER dockerio
  2903          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2904  		true)
  2905  	if err != nil {
  2906  		c.Fatal(err)
  2907  	}
  2908  	if id1 != id2 {
  2909  		c.Fatal("The cache should have been used but hasn't.")
  2910  	}
  2911  }
  2912  
  2913  func (s *DockerSuite) TestBuildAddRemoteFileWithoutCache(c *check.C) {
  2914  	name := "testbuildaddremotefilewithoutcache"
  2915  	name2 := "testbuildaddremotefilewithoutcache2"
  2916  	server, err := fakeStorage(map[string]string{
  2917  		"baz": "hello",
  2918  	})
  2919  	if err != nil {
  2920  		c.Fatal(err)
  2921  	}
  2922  	defer server.Close()
  2923  
  2924  	id1, err := buildImage(name,
  2925  		fmt.Sprintf(`FROM scratch
  2926          MAINTAINER dockerio
  2927          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2928  		true)
  2929  	if err != nil {
  2930  		c.Fatal(err)
  2931  	}
  2932  	id2, err := buildImage(name2,
  2933  		fmt.Sprintf(`FROM scratch
  2934          MAINTAINER dockerio
  2935          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2936  		false)
  2937  	if err != nil {
  2938  		c.Fatal(err)
  2939  	}
  2940  	if id1 == id2 {
  2941  		c.Fatal("The cache should have been invalided but hasn't.")
  2942  	}
  2943  }
  2944  
  2945  func (s *DockerSuite) TestBuildAddRemoteFileMTime(c *check.C) {
  2946  	name := "testbuildaddremotefilemtime"
  2947  	name2 := name + "2"
  2948  	name3 := name + "3"
  2949  	name4 := name + "4"
  2950  
  2951  	files := map[string]string{"baz": "hello"}
  2952  	server, err := fakeStorage(files)
  2953  	if err != nil {
  2954  		c.Fatal(err)
  2955  	}
  2956  	defer server.Close()
  2957  
  2958  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2959          MAINTAINER dockerio
  2960          ADD %s/baz /usr/lib/baz/quux`, server.URL()), nil)
  2961  	if err != nil {
  2962  		c.Fatal(err)
  2963  	}
  2964  	defer ctx.Close()
  2965  
  2966  	id1, err := buildImageFromContext(name, ctx, true)
  2967  	if err != nil {
  2968  		c.Fatal(err)
  2969  	}
  2970  
  2971  	id2, err := buildImageFromContext(name2, ctx, true)
  2972  	if err != nil {
  2973  		c.Fatal(err)
  2974  	}
  2975  	if id1 != id2 {
  2976  		c.Fatal("The cache should have been used but wasn't - #1")
  2977  	}
  2978  
  2979  	// Now create a different server withsame contents (causes different mtim)
  2980  	// This time the cache should not be used
  2981  
  2982  	// allow some time for clock to pass as mtime precision is only 1s
  2983  	time.Sleep(2 * time.Second)
  2984  
  2985  	server2, err := fakeStorage(files)
  2986  	if err != nil {
  2987  		c.Fatal(err)
  2988  	}
  2989  	defer server2.Close()
  2990  
  2991  	ctx2, err := fakeContext(fmt.Sprintf(`FROM scratch
  2992          MAINTAINER dockerio
  2993          ADD %s/baz /usr/lib/baz/quux`, server2.URL()), nil)
  2994  	if err != nil {
  2995  		c.Fatal(err)
  2996  	}
  2997  	defer ctx2.Close()
  2998  	id3, err := buildImageFromContext(name3, ctx2, true)
  2999  	if err != nil {
  3000  		c.Fatal(err)
  3001  	}
  3002  	if id1 == id3 {
  3003  		c.Fatal("The cache should not have been used but was")
  3004  	}
  3005  
  3006  	// And for good measure do it again and make sure cache is used this time
  3007  	id4, err := buildImageFromContext(name4, ctx2, true)
  3008  	if err != nil {
  3009  		c.Fatal(err)
  3010  	}
  3011  	if id3 != id4 {
  3012  		c.Fatal("The cache should have been used but wasn't - #2")
  3013  	}
  3014  }
  3015  
  3016  func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithCache(c *check.C) {
  3017  	name := "testbuildaddlocalandremotefilewithcache"
  3018  	server, err := fakeStorage(map[string]string{
  3019  		"baz": "hello",
  3020  	})
  3021  	if err != nil {
  3022  		c.Fatal(err)
  3023  	}
  3024  	defer server.Close()
  3025  
  3026  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  3027          MAINTAINER dockerio
  3028          ADD foo /usr/lib/bla/bar
  3029          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  3030  		map[string]string{
  3031  			"foo": "hello world",
  3032  		})
  3033  	if err != nil {
  3034  		c.Fatal(err)
  3035  	}
  3036  	defer ctx.Close()
  3037  	id1, err := buildImageFromContext(name, ctx, true)
  3038  	if err != nil {
  3039  		c.Fatal(err)
  3040  	}
  3041  	id2, err := buildImageFromContext(name, ctx, true)
  3042  	if err != nil {
  3043  		c.Fatal(err)
  3044  	}
  3045  	if id1 != id2 {
  3046  		c.Fatal("The cache should have been used but hasn't.")
  3047  	}
  3048  }
  3049  
  3050  func testContextTar(c *check.C, compression archive.Compression) {
  3051  	ctx, err := fakeContext(
  3052  		`FROM busybox
  3053  ADD foo /foo
  3054  CMD ["cat", "/foo"]`,
  3055  		map[string]string{
  3056  			"foo": "bar",
  3057  		},
  3058  	)
  3059  	defer ctx.Close()
  3060  	if err != nil {
  3061  		c.Fatal(err)
  3062  	}
  3063  	context, err := archive.Tar(ctx.Dir, compression)
  3064  	if err != nil {
  3065  		c.Fatalf("failed to build context tar: %v", err)
  3066  	}
  3067  	name := "contexttar"
  3068  	buildCmd := exec.Command(dockerBinary, "build", "-t", name, "-")
  3069  	buildCmd.Stdin = context
  3070  
  3071  	if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  3072  		c.Fatalf("build failed to complete: %v %v", out, err)
  3073  	}
  3074  }
  3075  
  3076  func (s *DockerSuite) TestBuildContextTarGzip(c *check.C) {
  3077  	testContextTar(c, archive.Gzip)
  3078  }
  3079  
  3080  func (s *DockerSuite) TestBuildContextTarNoCompression(c *check.C) {
  3081  	testContextTar(c, archive.Uncompressed)
  3082  }
  3083  
  3084  func (s *DockerSuite) TestBuildNoContext(c *check.C) {
  3085  	buildCmd := exec.Command(dockerBinary, "build", "-t", "nocontext", "-")
  3086  	buildCmd.Stdin = strings.NewReader("FROM busybox\nCMD echo ok\n")
  3087  
  3088  	if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  3089  		c.Fatalf("build failed to complete: %v %v", out, err)
  3090  	}
  3091  
  3092  	if out, _ := dockerCmd(c, "run", "--rm", "nocontext"); out != "ok\n" {
  3093  		c.Fatalf("run produced invalid output: %q, expected %q", out, "ok")
  3094  	}
  3095  }
  3096  
  3097  // TODO: TestCaching
  3098  func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithoutCache(c *check.C) {
  3099  	name := "testbuildaddlocalandremotefilewithoutcache"
  3100  	name2 := "testbuildaddlocalandremotefilewithoutcache2"
  3101  	server, err := fakeStorage(map[string]string{
  3102  		"baz": "hello",
  3103  	})
  3104  	if err != nil {
  3105  		c.Fatal(err)
  3106  	}
  3107  	defer server.Close()
  3108  
  3109  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  3110          MAINTAINER dockerio
  3111          ADD foo /usr/lib/bla/bar
  3112          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  3113  		map[string]string{
  3114  			"foo": "hello world",
  3115  		})
  3116  	if err != nil {
  3117  		c.Fatal(err)
  3118  	}
  3119  	defer ctx.Close()
  3120  	id1, err := buildImageFromContext(name, ctx, true)
  3121  	if err != nil {
  3122  		c.Fatal(err)
  3123  	}
  3124  	id2, err := buildImageFromContext(name2, ctx, false)
  3125  	if err != nil {
  3126  		c.Fatal(err)
  3127  	}
  3128  	if id1 == id2 {
  3129  		c.Fatal("The cache should have been invalided but hasn't.")
  3130  	}
  3131  }
  3132  
  3133  func (s *DockerSuite) TestBuildWithVolumeOwnership(c *check.C) {
  3134  	name := "testbuildimg"
  3135  
  3136  	_, err := buildImage(name,
  3137  		`FROM busybox:latest
  3138          RUN mkdir /test && chown daemon:daemon /test && chmod 0600 /test
  3139          VOLUME /test`,
  3140  		true)
  3141  
  3142  	if err != nil {
  3143  		c.Fatal(err)
  3144  	}
  3145  
  3146  	cmd := exec.Command(dockerBinary, "run", "--rm", "testbuildimg", "ls", "-la", "/test")
  3147  	out, _, err := runCommandWithOutput(cmd)
  3148  	if err != nil {
  3149  		c.Fatal(out, err)
  3150  	}
  3151  
  3152  	if expected := "drw-------"; !strings.Contains(out, expected) {
  3153  		c.Fatalf("expected %s received %s", expected, out)
  3154  	}
  3155  
  3156  	if expected := "daemon   daemon"; !strings.Contains(out, expected) {
  3157  		c.Fatalf("expected %s received %s", expected, out)
  3158  	}
  3159  
  3160  }
  3161  
  3162  // testing #1405 - config.Cmd does not get cleaned up if
  3163  // utilizing cache
  3164  func (s *DockerSuite) TestBuildEntrypointRunCleanup(c *check.C) {
  3165  	name := "testbuildcmdcleanup"
  3166  	if _, err := buildImage(name,
  3167  		`FROM busybox
  3168          RUN echo "hello"`,
  3169  		true); err != nil {
  3170  		c.Fatal(err)
  3171  	}
  3172  
  3173  	ctx, err := fakeContext(`FROM busybox
  3174          RUN echo "hello"
  3175          ADD foo /foo
  3176          ENTRYPOINT ["/bin/echo"]`,
  3177  		map[string]string{
  3178  			"foo": "hello",
  3179  		})
  3180  	defer ctx.Close()
  3181  	if err != nil {
  3182  		c.Fatal(err)
  3183  	}
  3184  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3185  		c.Fatal(err)
  3186  	}
  3187  	res, err := inspectField(name, "Config.Cmd")
  3188  	if err != nil {
  3189  		c.Fatal(err)
  3190  	}
  3191  	// Cmd must be cleaned up
  3192  	if res != "<nil>" {
  3193  		c.Fatalf("Cmd %s, expected nil", res)
  3194  	}
  3195  }
  3196  
  3197  func (s *DockerSuite) TestBuildForbiddenContextPath(c *check.C) {
  3198  	name := "testbuildforbidpath"
  3199  	ctx, err := fakeContext(`FROM scratch
  3200          ADD ../../ test/
  3201          `,
  3202  		map[string]string{
  3203  			"test.txt":  "test1",
  3204  			"other.txt": "other",
  3205  		})
  3206  	defer ctx.Close()
  3207  	if err != nil {
  3208  		c.Fatal(err)
  3209  	}
  3210  
  3211  	expected := "Forbidden path outside the build context: ../../ "
  3212  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  3213  		c.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
  3214  	}
  3215  
  3216  }
  3217  
  3218  func (s *DockerSuite) TestBuildAddFileNotFound(c *check.C) {
  3219  	name := "testbuildaddnotfound"
  3220  	ctx, err := fakeContext(`FROM scratch
  3221          ADD foo /usr/local/bar`,
  3222  		map[string]string{"bar": "hello"})
  3223  	defer ctx.Close()
  3224  	if err != nil {
  3225  		c.Fatal(err)
  3226  	}
  3227  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3228  		if !strings.Contains(err.Error(), "foo: no such file or directory") {
  3229  			c.Fatalf("Wrong error %v, must be about missing foo file or directory", err)
  3230  		}
  3231  	} else {
  3232  		c.Fatal("Error must not be nil")
  3233  	}
  3234  }
  3235  
  3236  func (s *DockerSuite) TestBuildInheritance(c *check.C) {
  3237  	name := "testbuildinheritance"
  3238  
  3239  	_, err := buildImage(name,
  3240  		`FROM scratch
  3241  		EXPOSE 2375`,
  3242  		true)
  3243  	if err != nil {
  3244  		c.Fatal(err)
  3245  	}
  3246  	ports1, err := inspectField(name, "Config.ExposedPorts")
  3247  	if err != nil {
  3248  		c.Fatal(err)
  3249  	}
  3250  
  3251  	_, err = buildImage(name,
  3252  		fmt.Sprintf(`FROM %s
  3253  		ENTRYPOINT ["/bin/echo"]`, name),
  3254  		true)
  3255  	if err != nil {
  3256  		c.Fatal(err)
  3257  	}
  3258  
  3259  	res, err := inspectField(name, "Config.Entrypoint")
  3260  	if err != nil {
  3261  		c.Fatal(err)
  3262  	}
  3263  	if expected := "{[/bin/echo]}"; res != expected {
  3264  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  3265  	}
  3266  	ports2, err := inspectField(name, "Config.ExposedPorts")
  3267  	if err != nil {
  3268  		c.Fatal(err)
  3269  	}
  3270  	if ports1 != ports2 {
  3271  		c.Fatalf("Ports must be same: %s != %s", ports1, ports2)
  3272  	}
  3273  }
  3274  
  3275  func (s *DockerSuite) TestBuildFails(c *check.C) {
  3276  	name := "testbuildfails"
  3277  	_, err := buildImage(name,
  3278  		`FROM busybox
  3279  		RUN sh -c "exit 23"`,
  3280  		true)
  3281  	if err != nil {
  3282  		if !strings.Contains(err.Error(), "returned a non-zero code: 23") {
  3283  			c.Fatalf("Wrong error %v, must be about non-zero code 23", err)
  3284  		}
  3285  	} else {
  3286  		c.Fatal("Error must not be nil")
  3287  	}
  3288  }
  3289  
  3290  func (s *DockerSuite) TestBuildFailsDockerfileEmpty(c *check.C) {
  3291  	name := "testbuildfails"
  3292  	_, err := buildImage(name, ``, true)
  3293  	if err != nil {
  3294  		if !strings.Contains(err.Error(), "The Dockerfile (Dockerfile) cannot be empty") {
  3295  			c.Fatalf("Wrong error %v, must be about empty Dockerfile", err)
  3296  		}
  3297  	} else {
  3298  		c.Fatal("Error must not be nil")
  3299  	}
  3300  }
  3301  
  3302  func (s *DockerSuite) TestBuildOnBuild(c *check.C) {
  3303  	name := "testbuildonbuild"
  3304  	_, err := buildImage(name,
  3305  		`FROM busybox
  3306  		ONBUILD RUN touch foobar`,
  3307  		true)
  3308  	if err != nil {
  3309  		c.Fatal(err)
  3310  	}
  3311  	_, err = buildImage(name,
  3312  		fmt.Sprintf(`FROM %s
  3313  		RUN [ -f foobar ]`, name),
  3314  		true)
  3315  	if err != nil {
  3316  		c.Fatal(err)
  3317  	}
  3318  }
  3319  
  3320  func (s *DockerSuite) TestBuildOnBuildForbiddenChained(c *check.C) {
  3321  	name := "testbuildonbuildforbiddenchained"
  3322  	_, err := buildImage(name,
  3323  		`FROM busybox
  3324  		ONBUILD ONBUILD RUN touch foobar`,
  3325  		true)
  3326  	if err != nil {
  3327  		if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
  3328  			c.Fatalf("Wrong error %v, must be about chaining ONBUILD", err)
  3329  		}
  3330  	} else {
  3331  		c.Fatal("Error must not be nil")
  3332  	}
  3333  }
  3334  
  3335  func (s *DockerSuite) TestBuildOnBuildForbiddenFrom(c *check.C) {
  3336  	name := "testbuildonbuildforbiddenfrom"
  3337  	_, err := buildImage(name,
  3338  		`FROM busybox
  3339  		ONBUILD FROM scratch`,
  3340  		true)
  3341  	if err != nil {
  3342  		if !strings.Contains(err.Error(), "FROM isn't allowed as an ONBUILD trigger") {
  3343  			c.Fatalf("Wrong error %v, must be about FROM forbidden", err)
  3344  		}
  3345  	} else {
  3346  		c.Fatal("Error must not be nil")
  3347  	}
  3348  }
  3349  
  3350  func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainer(c *check.C) {
  3351  	name := "testbuildonbuildforbiddenmaintainer"
  3352  	_, err := buildImage(name,
  3353  		`FROM busybox
  3354  		ONBUILD MAINTAINER docker.io`,
  3355  		true)
  3356  	if err != nil {
  3357  		if !strings.Contains(err.Error(), "MAINTAINER isn't allowed as an ONBUILD trigger") {
  3358  			c.Fatalf("Wrong error %v, must be about MAINTAINER forbidden", err)
  3359  		}
  3360  	} else {
  3361  		c.Fatal("Error must not be nil")
  3362  	}
  3363  }
  3364  
  3365  // gh #2446
  3366  func (s *DockerSuite) TestBuildAddToSymlinkDest(c *check.C) {
  3367  	name := "testbuildaddtosymlinkdest"
  3368  	ctx, err := fakeContext(`FROM busybox
  3369          RUN mkdir /foo
  3370          RUN ln -s /foo /bar
  3371          ADD foo /bar/
  3372          RUN [ -f /bar/foo ]
  3373          RUN [ -f /foo/foo ]`,
  3374  		map[string]string{
  3375  			"foo": "hello",
  3376  		})
  3377  	if err != nil {
  3378  		c.Fatal(err)
  3379  	}
  3380  	defer ctx.Close()
  3381  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3382  		c.Fatal(err)
  3383  	}
  3384  }
  3385  
  3386  func (s *DockerSuite) TestBuildEscapeWhitespace(c *check.C) {
  3387  	name := "testbuildescaping"
  3388  
  3389  	_, err := buildImage(name, `
  3390    FROM busybox
  3391    MAINTAINER "Docker \
  3392  IO <io@\
  3393  docker.com>"
  3394    `, true)
  3395  
  3396  	res, err := inspectField(name, "Author")
  3397  
  3398  	if err != nil {
  3399  		c.Fatal(err)
  3400  	}
  3401  
  3402  	if res != "\"Docker IO <io@docker.com>\"" {
  3403  		c.Fatalf("Parsed string did not match the escaped string. Got: %q", res)
  3404  	}
  3405  
  3406  }
  3407  
  3408  func (s *DockerSuite) TestBuildVerifyIntString(c *check.C) {
  3409  	// Verify that strings that look like ints are still passed as strings
  3410  	name := "testbuildstringing"
  3411  
  3412  	_, err := buildImage(name, `
  3413    FROM busybox
  3414    MAINTAINER 123
  3415    `, true)
  3416  
  3417  	out, rc, err := runCommandWithOutput(exec.Command(dockerBinary, "inspect", name))
  3418  	if rc != 0 || err != nil {
  3419  		c.Fatalf("Unexpected error from inspect: rc: %v  err: %v", rc, err)
  3420  	}
  3421  
  3422  	if !strings.Contains(out, "\"123\"") {
  3423  		c.Fatalf("Output does not contain the int as a string:\n%s", out)
  3424  	}
  3425  
  3426  }
  3427  
  3428  func (s *DockerSuite) TestBuildDockerignore(c *check.C) {
  3429  	name := "testbuilddockerignore"
  3430  	dockerfile := `
  3431          FROM busybox
  3432          ADD . /bla
  3433  		RUN [[ -f /bla/src/x.go ]]
  3434  		RUN [[ -f /bla/Makefile ]]
  3435  		RUN [[ ! -e /bla/src/_vendor ]]
  3436  		RUN [[ ! -e /bla/.gitignore ]]
  3437  		RUN [[ ! -e /bla/README.md ]]
  3438  		RUN [[ ! -e /bla/dir/foo ]]
  3439  		RUN [[ ! -e /bla/foo ]]
  3440  		RUN [[ ! -e /bla/.git ]]`
  3441  	ctx, err := fakeContext(dockerfile, map[string]string{
  3442  		"Makefile":         "all:",
  3443  		".git/HEAD":        "ref: foo",
  3444  		"src/x.go":         "package main",
  3445  		"src/_vendor/v.go": "package main",
  3446  		"dir/foo":          "",
  3447  		".gitignore":       "",
  3448  		"README.md":        "readme",
  3449  		".dockerignore": `
  3450  .git
  3451  pkg
  3452  .gitignore
  3453  src/_vendor
  3454  *.md
  3455  dir`,
  3456  	})
  3457  	if err != nil {
  3458  		c.Fatal(err)
  3459  	}
  3460  	defer ctx.Close()
  3461  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3462  		c.Fatal(err)
  3463  	}
  3464  }
  3465  
  3466  func (s *DockerSuite) TestBuildDockerignoreCleanPaths(c *check.C) {
  3467  	name := "testbuilddockerignorecleanpaths"
  3468  	dockerfile := `
  3469          FROM busybox
  3470          ADD . /tmp/
  3471          RUN (! ls /tmp/foo) && (! ls /tmp/foo2) && (! ls /tmp/dir1/foo)`
  3472  	ctx, err := fakeContext(dockerfile, map[string]string{
  3473  		"foo":           "foo",
  3474  		"foo2":          "foo2",
  3475  		"dir1/foo":      "foo in dir1",
  3476  		".dockerignore": "./foo\ndir1//foo\n./dir1/../foo2",
  3477  	})
  3478  	if err != nil {
  3479  		c.Fatal(err)
  3480  	}
  3481  	defer ctx.Close()
  3482  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3483  		c.Fatal(err)
  3484  	}
  3485  }
  3486  
  3487  func (s *DockerSuite) TestBuildDockerignoreExceptions(c *check.C) {
  3488  	name := "testbuilddockerignoreexceptions"
  3489  	defer deleteImages(name)
  3490  	dockerfile := `
  3491          FROM busybox
  3492          ADD . /bla
  3493  		RUN [[ -f /bla/src/x.go ]]
  3494  		RUN [[ -f /bla/Makefile ]]
  3495  		RUN [[ ! -e /bla/src/_vendor ]]
  3496  		RUN [[ ! -e /bla/.gitignore ]]
  3497  		RUN [[ ! -e /bla/README.md ]]
  3498  		RUN [[  -e /bla/dir/dir/foo ]]
  3499  		RUN [[ ! -e /bla/dir/foo1 ]]
  3500  		RUN [[ -f /bla/dir/e ]]
  3501  		RUN [[ -f /bla/dir/e-dir/foo ]]
  3502  		RUN [[ ! -e /bla/foo ]]
  3503  		RUN [[ ! -e /bla/.git ]]`
  3504  	ctx, err := fakeContext(dockerfile, map[string]string{
  3505  		"Makefile":         "all:",
  3506  		".git/HEAD":        "ref: foo",
  3507  		"src/x.go":         "package main",
  3508  		"src/_vendor/v.go": "package main",
  3509  		"dir/foo":          "",
  3510  		"dir/foo1":         "",
  3511  		"dir/dir/f1":       "",
  3512  		"dir/dir/foo":      "",
  3513  		"dir/e":            "",
  3514  		"dir/e-dir/foo":    "",
  3515  		".gitignore":       "",
  3516  		"README.md":        "readme",
  3517  		".dockerignore": `
  3518  .git
  3519  pkg
  3520  .gitignore
  3521  src/_vendor
  3522  *.md
  3523  dir
  3524  !dir/e*
  3525  !dir/dir/foo`,
  3526  	})
  3527  	if err != nil {
  3528  		c.Fatal(err)
  3529  	}
  3530  	defer ctx.Close()
  3531  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3532  		c.Fatal(err)
  3533  	}
  3534  }
  3535  
  3536  func (s *DockerSuite) TestBuildDockerignoringDockerfile(c *check.C) {
  3537  	name := "testbuilddockerignoredockerfile"
  3538  	dockerfile := `
  3539          FROM busybox
  3540  		ADD . /tmp/
  3541  		RUN ! ls /tmp/Dockerfile
  3542  		RUN ls /tmp/.dockerignore`
  3543  	ctx, err := fakeContext(dockerfile, map[string]string{
  3544  		"Dockerfile":    dockerfile,
  3545  		".dockerignore": "Dockerfile\n",
  3546  	})
  3547  	if err != nil {
  3548  		c.Fatal(err)
  3549  	}
  3550  	defer ctx.Close()
  3551  
  3552  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3553  		c.Fatalf("Didn't ignore Dockerfile correctly:%s", err)
  3554  	}
  3555  
  3556  	// now try it with ./Dockerfile
  3557  	ctx.Add(".dockerignore", "./Dockerfile\n")
  3558  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3559  		c.Fatalf("Didn't ignore ./Dockerfile correctly:%s", err)
  3560  	}
  3561  
  3562  }
  3563  
  3564  func (s *DockerSuite) TestBuildDockerignoringRenamedDockerfile(c *check.C) {
  3565  	name := "testbuilddockerignoredockerfile"
  3566  	dockerfile := `
  3567          FROM busybox
  3568  		ADD . /tmp/
  3569  		RUN ls /tmp/Dockerfile
  3570  		RUN ! ls /tmp/MyDockerfile
  3571  		RUN ls /tmp/.dockerignore`
  3572  	ctx, err := fakeContext(dockerfile, map[string]string{
  3573  		"Dockerfile":    "Should not use me",
  3574  		"MyDockerfile":  dockerfile,
  3575  		".dockerignore": "MyDockerfile\n",
  3576  	})
  3577  	if err != nil {
  3578  		c.Fatal(err)
  3579  	}
  3580  	defer ctx.Close()
  3581  
  3582  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3583  		c.Fatalf("Didn't ignore MyDockerfile correctly:%s", err)
  3584  	}
  3585  
  3586  	// now try it with ./MyDockerfile
  3587  	ctx.Add(".dockerignore", "./MyDockerfile\n")
  3588  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3589  		c.Fatalf("Didn't ignore ./MyDockerfile correctly:%s", err)
  3590  	}
  3591  
  3592  }
  3593  
  3594  func (s *DockerSuite) TestBuildDockerignoringDockerignore(c *check.C) {
  3595  	name := "testbuilddockerignoredockerignore"
  3596  	dockerfile := `
  3597          FROM busybox
  3598  		ADD . /tmp/
  3599  		RUN ! ls /tmp/.dockerignore
  3600  		RUN ls /tmp/Dockerfile`
  3601  	ctx, err := fakeContext(dockerfile, map[string]string{
  3602  		"Dockerfile":    dockerfile,
  3603  		".dockerignore": ".dockerignore\n",
  3604  	})
  3605  	defer ctx.Close()
  3606  	if err != nil {
  3607  		c.Fatal(err)
  3608  	}
  3609  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3610  		c.Fatalf("Didn't ignore .dockerignore correctly:%s", err)
  3611  	}
  3612  }
  3613  
  3614  func (s *DockerSuite) TestBuildDockerignoreTouchDockerfile(c *check.C) {
  3615  	var id1 string
  3616  	var id2 string
  3617  
  3618  	name := "testbuilddockerignoretouchdockerfile"
  3619  	dockerfile := `
  3620          FROM busybox
  3621  		ADD . /tmp/`
  3622  	ctx, err := fakeContext(dockerfile, map[string]string{
  3623  		"Dockerfile":    dockerfile,
  3624  		".dockerignore": "Dockerfile\n",
  3625  	})
  3626  	defer ctx.Close()
  3627  	if err != nil {
  3628  		c.Fatal(err)
  3629  	}
  3630  
  3631  	if id1, err = buildImageFromContext(name, ctx, true); err != nil {
  3632  		c.Fatalf("Didn't build it correctly:%s", err)
  3633  	}
  3634  
  3635  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3636  		c.Fatalf("Didn't build it correctly:%s", err)
  3637  	}
  3638  	if id1 != id2 {
  3639  		c.Fatalf("Didn't use the cache - 1")
  3640  	}
  3641  
  3642  	// Now make sure touching Dockerfile doesn't invalidate the cache
  3643  	if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3644  		c.Fatalf("Didn't add Dockerfile: %s", err)
  3645  	}
  3646  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3647  		c.Fatalf("Didn't build it correctly:%s", err)
  3648  	}
  3649  	if id1 != id2 {
  3650  		c.Fatalf("Didn't use the cache - 2")
  3651  	}
  3652  
  3653  	// One more time but just 'touch' it instead of changing the content
  3654  	if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3655  		c.Fatalf("Didn't add Dockerfile: %s", err)
  3656  	}
  3657  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3658  		c.Fatalf("Didn't build it correctly:%s", err)
  3659  	}
  3660  	if id1 != id2 {
  3661  		c.Fatalf("Didn't use the cache - 3")
  3662  	}
  3663  
  3664  }
  3665  
  3666  func (s *DockerSuite) TestBuildDockerignoringWholeDir(c *check.C) {
  3667  	name := "testbuilddockerignorewholedir"
  3668  	dockerfile := `
  3669          FROM busybox
  3670  		COPY . /
  3671  		RUN [[ ! -e /.gitignore ]]
  3672  		RUN [[ -f /Makefile ]]`
  3673  	ctx, err := fakeContext(dockerfile, map[string]string{
  3674  		"Dockerfile":    "FROM scratch",
  3675  		"Makefile":      "all:",
  3676  		".gitignore":    "",
  3677  		".dockerignore": ".*\n",
  3678  	})
  3679  	defer ctx.Close()
  3680  	if err != nil {
  3681  		c.Fatal(err)
  3682  	}
  3683  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3684  		c.Fatal(err)
  3685  	}
  3686  }
  3687  
  3688  func (s *DockerSuite) TestBuildLineBreak(c *check.C) {
  3689  	name := "testbuildlinebreak"
  3690  	_, err := buildImage(name,
  3691  		`FROM  busybox
  3692  RUN    sh -c 'echo root:testpass \
  3693  	> /tmp/passwd'
  3694  RUN    mkdir -p /var/run/sshd
  3695  RUN    [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3696  RUN    [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3697  		true)
  3698  	if err != nil {
  3699  		c.Fatal(err)
  3700  	}
  3701  }
  3702  
  3703  func (s *DockerSuite) TestBuildEOLInLine(c *check.C) {
  3704  	name := "testbuildeolinline"
  3705  	_, err := buildImage(name,
  3706  		`FROM   busybox
  3707  RUN    sh -c 'echo root:testpass > /tmp/passwd'
  3708  RUN    echo "foo \n bar"; echo "baz"
  3709  RUN    mkdir -p /var/run/sshd
  3710  RUN    [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3711  RUN    [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3712  		true)
  3713  	if err != nil {
  3714  		c.Fatal(err)
  3715  	}
  3716  }
  3717  
  3718  func (s *DockerSuite) TestBuildCommentsShebangs(c *check.C) {
  3719  	name := "testbuildcomments"
  3720  	_, err := buildImage(name,
  3721  		`FROM busybox
  3722  # This is an ordinary comment.
  3723  RUN { echo '#!/bin/sh'; echo 'echo hello world'; } > /hello.sh
  3724  RUN [ ! -x /hello.sh ]
  3725  # comment with line break \
  3726  RUN chmod +x /hello.sh
  3727  RUN [ -x /hello.sh ]
  3728  RUN [ "$(cat /hello.sh)" = $'#!/bin/sh\necho hello world' ]
  3729  RUN [ "$(/hello.sh)" = "hello world" ]`,
  3730  		true)
  3731  	if err != nil {
  3732  		c.Fatal(err)
  3733  	}
  3734  }
  3735  
  3736  func (s *DockerSuite) TestBuildUsersAndGroups(c *check.C) {
  3737  	name := "testbuildusers"
  3738  	_, err := buildImage(name,
  3739  		`FROM busybox
  3740  
  3741  # Make sure our defaults work
  3742  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)" = '0:0/root:root' ]
  3743  
  3744  # 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)
  3745  USER root
  3746  RUN [ "$(id -G):$(id -Gn)" = '0 10:root wheel' ]
  3747  
  3748  # Setup dockerio user and group
  3749  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  3750  RUN echo 'dockerio:x:1001:' >> /etc/group
  3751  
  3752  # Make sure we can switch to our user and all the information is exactly as we expect it to be
  3753  USER dockerio
  3754  RUN id -G
  3755  RUN id -Gn
  3756  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3757  
  3758  # Switch back to root and double check that worked exactly as we might expect it to
  3759  USER root
  3760  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '0:0/root:root/0 10:root wheel' ]
  3761  
  3762  # Add a "supplementary" group for our dockerio user
  3763  RUN echo 'supplementary:x:1002:dockerio' >> /etc/group
  3764  
  3765  # ... and then go verify that we get it like we expect
  3766  USER dockerio
  3767  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3768  USER 1001
  3769  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3770  
  3771  # super test the new "user:group" syntax
  3772  USER dockerio:dockerio
  3773  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3774  USER 1001:dockerio
  3775  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3776  USER dockerio:1001
  3777  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3778  USER 1001:1001
  3779  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3780  USER dockerio:supplementary
  3781  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3782  USER dockerio:1002
  3783  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3784  USER 1001:supplementary
  3785  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3786  USER 1001:1002
  3787  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3788  
  3789  # make sure unknown uid/gid still works properly
  3790  USER 1042:1043
  3791  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1042:1043/1042:1043/1043:1043' ]`,
  3792  		true)
  3793  	if err != nil {
  3794  		c.Fatal(err)
  3795  	}
  3796  }
  3797  
  3798  func (s *DockerSuite) TestBuildEnvUsage(c *check.C) {
  3799  	name := "testbuildenvusage"
  3800  	dockerfile := `FROM busybox
  3801  ENV    HOME /root
  3802  ENV    PATH $HOME/bin:$PATH
  3803  ENV    PATH /tmp:$PATH
  3804  RUN    [ "$PATH" = "/tmp:$HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ]
  3805  ENV    FOO /foo/baz
  3806  ENV    BAR /bar
  3807  ENV    BAZ $BAR
  3808  ENV    FOOPATH $PATH:$FOO
  3809  RUN    [ "$BAR" = "$BAZ" ]
  3810  RUN    [ "$FOOPATH" = "$PATH:/foo/baz" ]
  3811  ENV	   FROM hello/docker/world
  3812  ENV    TO /docker/world/hello
  3813  ADD    $FROM $TO
  3814  RUN    [ "$(cat $TO)" = "hello" ]
  3815  ENV    abc=def
  3816  ENV    ghi=$abc
  3817  RUN    [ "$ghi" = "def" ]
  3818  `
  3819  	ctx, err := fakeContext(dockerfile, map[string]string{
  3820  		"hello/docker/world": "hello",
  3821  	})
  3822  	if err != nil {
  3823  		c.Fatal(err)
  3824  	}
  3825  	defer ctx.Close()
  3826  
  3827  	_, err = buildImageFromContext(name, ctx, true)
  3828  	if err != nil {
  3829  		c.Fatal(err)
  3830  	}
  3831  }
  3832  
  3833  func (s *DockerSuite) TestBuildEnvUsage2(c *check.C) {
  3834  	name := "testbuildenvusage2"
  3835  	dockerfile := `FROM busybox
  3836  ENV    abc=def
  3837  RUN    [ "$abc" = "def" ]
  3838  ENV    def="hello world"
  3839  RUN    [ "$def" = "hello world" ]
  3840  ENV    def=hello\ world
  3841  RUN    [ "$def" = "hello world" ]
  3842  ENV    v1=abc v2="hi there"
  3843  RUN    [ "$v1" = "abc" ]
  3844  RUN    [ "$v2" = "hi there" ]
  3845  ENV    v3='boogie nights' v4="with'quotes too"
  3846  RUN    [ "$v3" = "boogie nights" ]
  3847  RUN    [ "$v4" = "with'quotes too" ]
  3848  ENV    abc=zzz FROM=hello/docker/world
  3849  ENV    abc=zzz TO=/docker/world/hello
  3850  ADD    $FROM $TO
  3851  RUN    [ "$(cat $TO)" = "hello" ]
  3852  ENV    abc "zzz"
  3853  RUN    [ $abc = "zzz" ]
  3854  ENV    abc 'yyy'
  3855  RUN    [ $abc = 'yyy' ]
  3856  ENV    abc=
  3857  RUN    [ "$abc" = "" ]
  3858  
  3859  # use grep to make sure if the builder substitutes \$foo by mistake
  3860  # we don't get a false positive
  3861  ENV    abc=\$foo
  3862  RUN    [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  3863  ENV    abc \$foo
  3864  RUN    [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  3865  
  3866  ENV    abc=\'foo\'
  3867  RUN    [ "$abc" = "'foo'" ]
  3868  ENV    abc=\"foo\"
  3869  RUN    [ "$abc" = "\"foo\"" ]
  3870  ENV    abc "foo"
  3871  RUN    [ "$abc" = "foo" ]
  3872  ENV    abc 'foo'
  3873  RUN    [ "$abc" = 'foo' ]
  3874  ENV    abc \'foo\'
  3875  RUN    [ "$abc" = "'foo'" ]
  3876  ENV    abc \"foo\"
  3877  RUN    [ "$abc" = '"foo"' ]
  3878  
  3879  ENV    abc=ABC
  3880  RUN    [ "$abc" = "ABC" ]
  3881  ENV    def=${abc:-DEF}
  3882  RUN    [ "$def" = "ABC" ]
  3883  ENV    def=${ccc:-DEF}
  3884  RUN    [ "$def" = "DEF" ]
  3885  ENV    def=${ccc:-${def}xx}
  3886  RUN    [ "$def" = "DEFxx" ]
  3887  ENV    def=${def:+ALT}
  3888  RUN    [ "$def" = "ALT" ]
  3889  ENV    def=${def:+${abc}:}
  3890  RUN    [ "$def" = "ABC:" ]
  3891  ENV    def=${ccc:-\$abc:}
  3892  RUN    [ "$def" = '$abc:' ]
  3893  ENV    def=${ccc:-\${abc}:}
  3894  RUN    [ "$def" = '${abc:}' ]
  3895  ENV    mypath=${mypath:+$mypath:}/home
  3896  RUN    [ "$mypath" = '/home' ]
  3897  ENV    mypath=${mypath:+$mypath:}/away
  3898  RUN    [ "$mypath" = '/home:/away' ]
  3899  
  3900  ENV    e1=bar
  3901  ENV    e2=$e1
  3902  ENV    e3=$e11
  3903  ENV    e4=\$e1
  3904  ENV    e5=\$e11
  3905  RUN    [ "$e0,$e1,$e2,$e3,$e4,$e5" = ',bar,bar,,$e1,$e11' ]
  3906  
  3907  ENV    ee1 bar
  3908  ENV    ee2 $ee1
  3909  ENV    ee3 $ee11
  3910  ENV    ee4 \$ee1
  3911  ENV    ee5 \$ee11
  3912  RUN    [ "$ee1,$ee2,$ee3,$ee4,$ee5" = 'bar,bar,,$ee1,$ee11' ]
  3913  
  3914  ENV    eee1="foo"
  3915  ENV    eee2='foo'
  3916  ENV    eee3 "foo"
  3917  ENV    eee4 'foo'
  3918  RUN    [ "$eee1,$eee2,$eee3,$eee4" = 'foo,foo,foo,foo' ]
  3919  
  3920  `
  3921  	ctx, err := fakeContext(dockerfile, map[string]string{
  3922  		"hello/docker/world": "hello",
  3923  	})
  3924  	if err != nil {
  3925  		c.Fatal(err)
  3926  	}
  3927  	defer ctx.Close()
  3928  
  3929  	_, err = buildImageFromContext(name, ctx, true)
  3930  	if err != nil {
  3931  		c.Fatal(err)
  3932  	}
  3933  }
  3934  
  3935  func (s *DockerSuite) TestBuildAddScript(c *check.C) {
  3936  	name := "testbuildaddscript"
  3937  	dockerfile := `
  3938  FROM busybox
  3939  ADD test /test
  3940  RUN ["chmod","+x","/test"]
  3941  RUN ["/test"]
  3942  RUN [ "$(cat /testfile)" = 'test!' ]`
  3943  	ctx, err := fakeContext(dockerfile, map[string]string{
  3944  		"test": "#!/bin/sh\necho 'test!' > /testfile",
  3945  	})
  3946  	if err != nil {
  3947  		c.Fatal(err)
  3948  	}
  3949  	defer ctx.Close()
  3950  
  3951  	_, err = buildImageFromContext(name, ctx, true)
  3952  	if err != nil {
  3953  		c.Fatal(err)
  3954  	}
  3955  }
  3956  
  3957  func (s *DockerSuite) TestBuildAddTar(c *check.C) {
  3958  	name := "testbuildaddtar"
  3959  
  3960  	ctx := func() *FakeContext {
  3961  		dockerfile := `
  3962  FROM busybox
  3963  ADD test.tar /
  3964  RUN cat /test/foo | grep Hi
  3965  ADD test.tar /test.tar
  3966  RUN cat /test.tar/test/foo | grep Hi
  3967  ADD test.tar /unlikely-to-exist
  3968  RUN cat /unlikely-to-exist/test/foo | grep Hi
  3969  ADD test.tar /unlikely-to-exist-trailing-slash/
  3970  RUN cat /unlikely-to-exist-trailing-slash/test/foo | grep Hi
  3971  RUN mkdir /existing-directory
  3972  ADD test.tar /existing-directory
  3973  RUN cat /existing-directory/test/foo | grep Hi
  3974  ADD test.tar /existing-directory-trailing-slash/
  3975  RUN cat /existing-directory-trailing-slash/test/foo | grep Hi`
  3976  		tmpDir, err := ioutil.TempDir("", "fake-context")
  3977  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3978  		if err != nil {
  3979  			c.Fatalf("failed to create test.tar archive: %v", err)
  3980  		}
  3981  		defer testTar.Close()
  3982  
  3983  		tw := tar.NewWriter(testTar)
  3984  
  3985  		if err := tw.WriteHeader(&tar.Header{
  3986  			Name: "test/foo",
  3987  			Size: 2,
  3988  		}); err != nil {
  3989  			c.Fatalf("failed to write tar file header: %v", err)
  3990  		}
  3991  		if _, err := tw.Write([]byte("Hi")); err != nil {
  3992  			c.Fatalf("failed to write tar file content: %v", err)
  3993  		}
  3994  		if err := tw.Close(); err != nil {
  3995  			c.Fatalf("failed to close tar archive: %v", err)
  3996  		}
  3997  
  3998  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3999  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4000  		}
  4001  		return fakeContextFromDir(tmpDir)
  4002  	}()
  4003  	defer ctx.Close()
  4004  
  4005  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4006  		c.Fatalf("build failed to complete for TestBuildAddTar: %v", err)
  4007  	}
  4008  
  4009  }
  4010  
  4011  func (s *DockerSuite) TestBuildAddTarXz(c *check.C) {
  4012  	name := "testbuildaddtarxz"
  4013  
  4014  	ctx := func() *FakeContext {
  4015  		dockerfile := `
  4016  			FROM busybox
  4017  			ADD test.tar.xz /
  4018  			RUN cat /test/foo | grep Hi`
  4019  		tmpDir, err := ioutil.TempDir("", "fake-context")
  4020  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  4021  		if err != nil {
  4022  			c.Fatalf("failed to create test.tar archive: %v", err)
  4023  		}
  4024  		defer testTar.Close()
  4025  
  4026  		tw := tar.NewWriter(testTar)
  4027  
  4028  		if err := tw.WriteHeader(&tar.Header{
  4029  			Name: "test/foo",
  4030  			Size: 2,
  4031  		}); err != nil {
  4032  			c.Fatalf("failed to write tar file header: %v", err)
  4033  		}
  4034  		if _, err := tw.Write([]byte("Hi")); err != nil {
  4035  			c.Fatalf("failed to write tar file content: %v", err)
  4036  		}
  4037  		if err := tw.Close(); err != nil {
  4038  			c.Fatalf("failed to close tar archive: %v", err)
  4039  		}
  4040  		xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  4041  		xzCompressCmd.Dir = tmpDir
  4042  		out, _, err := runCommandWithOutput(xzCompressCmd)
  4043  		if err != nil {
  4044  			c.Fatal(err, out)
  4045  		}
  4046  
  4047  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  4048  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4049  		}
  4050  		return fakeContextFromDir(tmpDir)
  4051  	}()
  4052  
  4053  	defer ctx.Close()
  4054  
  4055  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4056  		c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  4057  	}
  4058  
  4059  }
  4060  
  4061  func (s *DockerSuite) TestBuildAddTarXzGz(c *check.C) {
  4062  	name := "testbuildaddtarxzgz"
  4063  
  4064  	ctx := func() *FakeContext {
  4065  		dockerfile := `
  4066  			FROM busybox
  4067  			ADD test.tar.xz.gz /
  4068  			RUN ls /test.tar.xz.gz`
  4069  		tmpDir, err := ioutil.TempDir("", "fake-context")
  4070  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  4071  		if err != nil {
  4072  			c.Fatalf("failed to create test.tar archive: %v", err)
  4073  		}
  4074  		defer testTar.Close()
  4075  
  4076  		tw := tar.NewWriter(testTar)
  4077  
  4078  		if err := tw.WriteHeader(&tar.Header{
  4079  			Name: "test/foo",
  4080  			Size: 2,
  4081  		}); err != nil {
  4082  			c.Fatalf("failed to write tar file header: %v", err)
  4083  		}
  4084  		if _, err := tw.Write([]byte("Hi")); err != nil {
  4085  			c.Fatalf("failed to write tar file content: %v", err)
  4086  		}
  4087  		if err := tw.Close(); err != nil {
  4088  			c.Fatalf("failed to close tar archive: %v", err)
  4089  		}
  4090  
  4091  		xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  4092  		xzCompressCmd.Dir = tmpDir
  4093  		out, _, err := runCommandWithOutput(xzCompressCmd)
  4094  		if err != nil {
  4095  			c.Fatal(err, out)
  4096  		}
  4097  
  4098  		gzipCompressCmd := exec.Command("gzip", "test.tar.xz")
  4099  		gzipCompressCmd.Dir = tmpDir
  4100  		out, _, err = runCommandWithOutput(gzipCompressCmd)
  4101  		if err != nil {
  4102  			c.Fatal(err, out)
  4103  		}
  4104  
  4105  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  4106  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4107  		}
  4108  		return fakeContextFromDir(tmpDir)
  4109  	}()
  4110  
  4111  	defer ctx.Close()
  4112  
  4113  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4114  		c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  4115  	}
  4116  
  4117  }
  4118  
  4119  func (s *DockerSuite) TestBuildFromGIT(c *check.C) {
  4120  	name := "testbuildfromgit"
  4121  	git, err := fakeGIT("repo", map[string]string{
  4122  		"Dockerfile": `FROM busybox
  4123  					ADD first /first
  4124  					RUN [ -f /first ]
  4125  					MAINTAINER docker`,
  4126  		"first": "test git data",
  4127  	}, true)
  4128  	if err != nil {
  4129  		c.Fatal(err)
  4130  	}
  4131  	defer git.Close()
  4132  
  4133  	_, err = buildImageFromPath(name, git.RepoURL, true)
  4134  	if err != nil {
  4135  		c.Fatal(err)
  4136  	}
  4137  	res, err := inspectField(name, "Author")
  4138  	if err != nil {
  4139  		c.Fatal(err)
  4140  	}
  4141  	if res != "docker" {
  4142  		c.Fatalf("Maintainer should be docker, got %s", res)
  4143  	}
  4144  }
  4145  
  4146  func (s *DockerSuite) TestBuildFromGITWithContext(c *check.C) {
  4147  	name := "testbuildfromgit"
  4148  	defer deleteImages(name)
  4149  	git, err := fakeGIT("repo", map[string]string{
  4150  		"docker/Dockerfile": `FROM busybox
  4151  					ADD first /first
  4152  					RUN [ -f /first ]
  4153  					MAINTAINER docker`,
  4154  		"docker/first": "test git data",
  4155  	}, true)
  4156  	if err != nil {
  4157  		c.Fatal(err)
  4158  	}
  4159  	defer git.Close()
  4160  
  4161  	u := fmt.Sprintf("%s#master:docker", git.RepoURL)
  4162  	_, err = buildImageFromPath(name, u, true)
  4163  	if err != nil {
  4164  		c.Fatal(err)
  4165  	}
  4166  	res, err := inspectField(name, "Author")
  4167  	if err != nil {
  4168  		c.Fatal(err)
  4169  	}
  4170  	if res != "docker" {
  4171  		c.Fatalf("Maintainer should be docker, got %s", res)
  4172  	}
  4173  }
  4174  
  4175  func (s *DockerSuite) TestBuildCleanupCmdOnEntrypoint(c *check.C) {
  4176  	name := "testbuildcmdcleanuponentrypoint"
  4177  	if _, err := buildImage(name,
  4178  		`FROM scratch
  4179          CMD ["test"]
  4180  		ENTRYPOINT ["echo"]`,
  4181  		true); err != nil {
  4182  		c.Fatal(err)
  4183  	}
  4184  	if _, err := buildImage(name,
  4185  		fmt.Sprintf(`FROM %s
  4186  		ENTRYPOINT ["cat"]`, name),
  4187  		true); err != nil {
  4188  		c.Fatal(err)
  4189  	}
  4190  	res, err := inspectField(name, "Config.Cmd")
  4191  	if err != nil {
  4192  		c.Fatal(err)
  4193  	}
  4194  	if res != "<nil>" {
  4195  		c.Fatalf("Cmd %s, expected nil", res)
  4196  	}
  4197  
  4198  	res, err = inspectField(name, "Config.Entrypoint")
  4199  	if err != nil {
  4200  		c.Fatal(err)
  4201  	}
  4202  	if expected := "{[cat]}"; res != expected {
  4203  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  4204  	}
  4205  }
  4206  
  4207  func (s *DockerSuite) TestBuildClearCmd(c *check.C) {
  4208  	name := "testbuildclearcmd"
  4209  	_, err := buildImage(name,
  4210  		`From scratch
  4211     ENTRYPOINT ["/bin/bash"]
  4212     CMD []`,
  4213  		true)
  4214  	if err != nil {
  4215  		c.Fatal(err)
  4216  	}
  4217  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4218  	if err != nil {
  4219  		c.Fatal(err)
  4220  	}
  4221  	if res != "[]" {
  4222  		c.Fatalf("Cmd %s, expected %s", res, "[]")
  4223  	}
  4224  }
  4225  
  4226  func (s *DockerSuite) TestBuildEmptyCmd(c *check.C) {
  4227  	name := "testbuildemptycmd"
  4228  	if _, err := buildImage(name, "FROM scratch\nMAINTAINER quux\n", true); err != nil {
  4229  		c.Fatal(err)
  4230  	}
  4231  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4232  	if err != nil {
  4233  		c.Fatal(err)
  4234  	}
  4235  	if res != "null" {
  4236  		c.Fatalf("Cmd %s, expected %s", res, "null")
  4237  	}
  4238  }
  4239  
  4240  func (s *DockerSuite) TestBuildOnBuildOutput(c *check.C) {
  4241  	name := "testbuildonbuildparent"
  4242  	if _, err := buildImage(name, "FROM busybox\nONBUILD RUN echo foo\n", true); err != nil {
  4243  		c.Fatal(err)
  4244  	}
  4245  
  4246  	_, out, err := buildImageWithOut(name, "FROM "+name+"\nMAINTAINER quux\n", true)
  4247  	if err != nil {
  4248  		c.Fatal(err)
  4249  	}
  4250  
  4251  	if !strings.Contains(out, "Trigger 0, RUN echo foo") {
  4252  		c.Fatal("failed to find the ONBUILD output", out)
  4253  	}
  4254  
  4255  }
  4256  
  4257  func (s *DockerSuite) TestBuildInvalidTag(c *check.C) {
  4258  	name := "abcd:" + stringutils.GenerateRandomAlphaOnlyString(200)
  4259  	_, out, err := buildImageWithOut(name, "FROM scratch\nMAINTAINER quux\n", true)
  4260  	// if the error doesnt check for illegal tag name, or the image is built
  4261  	// then this should fail
  4262  	if !strings.Contains(out, "Illegal tag name") || strings.Contains(out, "Sending build context to Docker daemon") {
  4263  		c.Fatalf("failed to stop before building. Error: %s, Output: %s", err, out)
  4264  	}
  4265  }
  4266  
  4267  func (s *DockerSuite) TestBuildCmdShDashC(c *check.C) {
  4268  	name := "testbuildcmdshc"
  4269  	if _, err := buildImage(name, "FROM busybox\nCMD echo cmd\n", true); err != nil {
  4270  		c.Fatal(err)
  4271  	}
  4272  
  4273  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4274  	if err != nil {
  4275  		c.Fatal(err, res)
  4276  	}
  4277  
  4278  	expected := `["/bin/sh","-c","echo cmd"]`
  4279  
  4280  	if res != expected {
  4281  		c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  4282  	}
  4283  
  4284  }
  4285  
  4286  func (s *DockerSuite) TestBuildCmdSpaces(c *check.C) {
  4287  	// Test to make sure that when we strcat arrays we take into account
  4288  	// the arg separator to make sure ["echo","hi"] and ["echo hi"] don't
  4289  	// look the same
  4290  	name := "testbuildcmdspaces"
  4291  	var id1 string
  4292  	var id2 string
  4293  	var err error
  4294  
  4295  	if id1, err = buildImage(name, "FROM busybox\nCMD [\"echo hi\"]\n", true); err != nil {
  4296  		c.Fatal(err)
  4297  	}
  4298  
  4299  	if id2, err = buildImage(name, "FROM busybox\nCMD [\"echo\", \"hi\"]\n", true); err != nil {
  4300  		c.Fatal(err)
  4301  	}
  4302  
  4303  	if id1 == id2 {
  4304  		c.Fatal("Should not have resulted in the same CMD")
  4305  	}
  4306  
  4307  	// Now do the same with ENTRYPOINT
  4308  	if id1, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo hi\"]\n", true); err != nil {
  4309  		c.Fatal(err)
  4310  	}
  4311  
  4312  	if id2, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo\", \"hi\"]\n", true); err != nil {
  4313  		c.Fatal(err)
  4314  	}
  4315  
  4316  	if id1 == id2 {
  4317  		c.Fatal("Should not have resulted in the same ENTRYPOINT")
  4318  	}
  4319  
  4320  }
  4321  
  4322  func (s *DockerSuite) TestBuildCmdJSONNoShDashC(c *check.C) {
  4323  	name := "testbuildcmdjson"
  4324  	if _, err := buildImage(name, "FROM busybox\nCMD [\"echo\", \"cmd\"]", true); err != nil {
  4325  		c.Fatal(err)
  4326  	}
  4327  
  4328  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4329  	if err != nil {
  4330  		c.Fatal(err, res)
  4331  	}
  4332  
  4333  	expected := `["echo","cmd"]`
  4334  
  4335  	if res != expected {
  4336  		c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  4337  	}
  4338  
  4339  }
  4340  
  4341  func (s *DockerSuite) TestBuildErrorInvalidInstruction(c *check.C) {
  4342  	name := "testbuildignoreinvalidinstruction"
  4343  
  4344  	out, _, err := buildImageWithOut(name, "FROM busybox\nfoo bar", true)
  4345  	if err == nil {
  4346  		c.Fatalf("Should have failed: %s", out)
  4347  	}
  4348  
  4349  }
  4350  
  4351  func (s *DockerSuite) TestBuildEntrypointInheritance(c *check.C) {
  4352  
  4353  	if _, err := buildImage("parent", `
  4354      FROM busybox
  4355      ENTRYPOINT exit 130
  4356      `, true); err != nil {
  4357  		c.Fatal(err)
  4358  	}
  4359  
  4360  	status, _ := runCommand(exec.Command(dockerBinary, "run", "parent"))
  4361  
  4362  	if status != 130 {
  4363  		c.Fatalf("expected exit code 130 but received %d", status)
  4364  	}
  4365  
  4366  	if _, err := buildImage("child", `
  4367      FROM parent
  4368      ENTRYPOINT exit 5
  4369      `, true); err != nil {
  4370  		c.Fatal(err)
  4371  	}
  4372  
  4373  	status, _ = runCommand(exec.Command(dockerBinary, "run", "child"))
  4374  
  4375  	if status != 5 {
  4376  		c.Fatalf("expected exit code 5 but received %d", status)
  4377  	}
  4378  
  4379  }
  4380  
  4381  func (s *DockerSuite) TestBuildEntrypointInheritanceInspect(c *check.C) {
  4382  	var (
  4383  		name     = "testbuildepinherit"
  4384  		name2    = "testbuildepinherit2"
  4385  		expected = `["/bin/sh","-c","echo quux"]`
  4386  	)
  4387  
  4388  	if _, err := buildImage(name, "FROM busybox\nENTRYPOINT /foo/bar", true); err != nil {
  4389  		c.Fatal(err)
  4390  	}
  4391  
  4392  	if _, err := buildImage(name2, fmt.Sprintf("FROM %s\nENTRYPOINT echo quux", name), true); err != nil {
  4393  		c.Fatal(err)
  4394  	}
  4395  
  4396  	res, err := inspectFieldJSON(name2, "Config.Entrypoint")
  4397  	if err != nil {
  4398  		c.Fatal(err, res)
  4399  	}
  4400  
  4401  	if res != expected {
  4402  		c.Fatalf("Expected value %s not in Config.Entrypoint: %s", expected, res)
  4403  	}
  4404  
  4405  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name2))
  4406  	if err != nil {
  4407  		c.Fatal(err, out)
  4408  	}
  4409  
  4410  	expected = "quux"
  4411  
  4412  	if strings.TrimSpace(out) != expected {
  4413  		c.Fatalf("Expected output is %s, got %s", expected, out)
  4414  	}
  4415  
  4416  }
  4417  
  4418  func (s *DockerSuite) TestBuildRunShEntrypoint(c *check.C) {
  4419  	name := "testbuildentrypoint"
  4420  	_, err := buildImage(name,
  4421  		`FROM busybox
  4422                                  ENTRYPOINT /bin/echo`,
  4423  		true)
  4424  	if err != nil {
  4425  		c.Fatal(err)
  4426  	}
  4427  
  4428  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", name))
  4429  
  4430  	if err != nil {
  4431  		c.Fatal(err, out)
  4432  	}
  4433  
  4434  }
  4435  
  4436  func (s *DockerSuite) TestBuildExoticShellInterpolation(c *check.C) {
  4437  	name := "testbuildexoticshellinterpolation"
  4438  
  4439  	_, err := buildImage(name, `
  4440  		FROM busybox
  4441  
  4442  		ENV SOME_VAR a.b.c
  4443  
  4444  		RUN [ "$SOME_VAR"       = 'a.b.c' ]
  4445  		RUN [ "${SOME_VAR}"     = 'a.b.c' ]
  4446  		RUN [ "${SOME_VAR%.*}"  = 'a.b'   ]
  4447  		RUN [ "${SOME_VAR%%.*}" = 'a'     ]
  4448  		RUN [ "${SOME_VAR#*.}"  = 'b.c'   ]
  4449  		RUN [ "${SOME_VAR##*.}" = 'c'     ]
  4450  		RUN [ "${SOME_VAR/c/d}" = 'a.b.d' ]
  4451  		RUN [ "${#SOME_VAR}"    = '5'     ]
  4452  
  4453  		RUN [ "${SOME_UNSET_VAR:-$SOME_VAR}" = 'a.b.c' ]
  4454  		RUN [ "${SOME_VAR:+Version: ${SOME_VAR}}" = 'Version: a.b.c' ]
  4455  		RUN [ "${SOME_UNSET_VAR:+${SOME_VAR}}" = '' ]
  4456  		RUN [ "${SOME_UNSET_VAR:-${SOME_VAR:-d.e.f}}" = 'a.b.c' ]
  4457  	`, false)
  4458  	if err != nil {
  4459  		c.Fatal(err)
  4460  	}
  4461  
  4462  }
  4463  
  4464  func (s *DockerSuite) TestBuildVerifySingleQuoteFails(c *check.C) {
  4465  	// This testcase is supposed to generate an error because the
  4466  	// JSON array we're passing in on the CMD uses single quotes instead
  4467  	// of double quotes (per the JSON spec). This means we interpret it
  4468  	// as a "string" insead of "JSON array" and pass it on to "sh -c" and
  4469  	// it should barf on it.
  4470  	name := "testbuildsinglequotefails"
  4471  
  4472  	_, err := buildImage(name,
  4473  		`FROM busybox
  4474  		CMD [ '/bin/sh', '-c', 'echo hi' ]`,
  4475  		true)
  4476  	_, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", name))
  4477  
  4478  	if err == nil {
  4479  		c.Fatal("The image was not supposed to be able to run")
  4480  	}
  4481  
  4482  }
  4483  
  4484  func (s *DockerSuite) TestBuildVerboseOut(c *check.C) {
  4485  	name := "testbuildverboseout"
  4486  
  4487  	_, out, err := buildImageWithOut(name,
  4488  		`FROM busybox
  4489  RUN echo 123`,
  4490  		false)
  4491  
  4492  	if err != nil {
  4493  		c.Fatal(err)
  4494  	}
  4495  	if !strings.Contains(out, "\n123\n") {
  4496  		c.Fatalf("Output should contain %q: %q", "123", out)
  4497  	}
  4498  
  4499  }
  4500  
  4501  func (s *DockerSuite) TestBuildWithTabs(c *check.C) {
  4502  	name := "testbuildwithtabs"
  4503  	_, err := buildImage(name,
  4504  		"FROM busybox\nRUN echo\tone\t\ttwo", true)
  4505  	if err != nil {
  4506  		c.Fatal(err)
  4507  	}
  4508  	res, err := inspectFieldJSON(name, "ContainerConfig.Cmd")
  4509  	if err != nil {
  4510  		c.Fatal(err)
  4511  	}
  4512  	expected1 := `["/bin/sh","-c","echo\tone\t\ttwo"]`
  4513  	expected2 := `["/bin/sh","-c","echo\u0009one\u0009\u0009two"]` // syntactically equivalent, and what Go 1.3 generates
  4514  	if res != expected1 && res != expected2 {
  4515  		c.Fatalf("Missing tabs.\nGot: %s\nExp: %s or %s", res, expected1, expected2)
  4516  	}
  4517  }
  4518  
  4519  func (s *DockerSuite) TestBuildLabels(c *check.C) {
  4520  	name := "testbuildlabel"
  4521  	expected := `{"License":"GPL","Vendor":"Acme"}`
  4522  	_, err := buildImage(name,
  4523  		`FROM busybox
  4524  		LABEL Vendor=Acme
  4525                  LABEL License GPL`,
  4526  		true)
  4527  	if err != nil {
  4528  		c.Fatal(err)
  4529  	}
  4530  	res, err := inspectFieldJSON(name, "Config.Labels")
  4531  	if err != nil {
  4532  		c.Fatal(err)
  4533  	}
  4534  	if res != expected {
  4535  		c.Fatalf("Labels %s, expected %s", res, expected)
  4536  	}
  4537  }
  4538  
  4539  func (s *DockerSuite) TestBuildLabelsCache(c *check.C) {
  4540  	name := "testbuildlabelcache"
  4541  
  4542  	id1, err := buildImage(name,
  4543  		`FROM busybox
  4544  		LABEL Vendor=Acme`, false)
  4545  	if err != nil {
  4546  		c.Fatalf("Build 1 should have worked: %v", err)
  4547  	}
  4548  
  4549  	id2, err := buildImage(name,
  4550  		`FROM busybox
  4551  		LABEL Vendor=Acme`, true)
  4552  	if err != nil || id1 != id2 {
  4553  		c.Fatalf("Build 2 should have worked & used cache(%s,%s): %v", id1, id2, err)
  4554  	}
  4555  
  4556  	id2, err = buildImage(name,
  4557  		`FROM busybox
  4558  		LABEL Vendor=Acme1`, true)
  4559  	if err != nil || id1 == id2 {
  4560  		c.Fatalf("Build 3 should have worked & NOT used cache(%s,%s): %v", id1, id2, err)
  4561  	}
  4562  
  4563  	id2, err = buildImage(name,
  4564  		`FROM busybox
  4565  		LABEL Vendor Acme`, true) // Note: " " and "=" should be same
  4566  	if err != nil || id1 != id2 {
  4567  		c.Fatalf("Build 4 should have worked & used cache(%s,%s): %v", id1, id2, err)
  4568  	}
  4569  
  4570  	// Now make sure the cache isn't used by mistake
  4571  	id1, err = buildImage(name,
  4572  		`FROM busybox
  4573         LABEL f1=b1 f2=b2`, false)
  4574  	if err != nil {
  4575  		c.Fatalf("Build 5 should have worked: %q", err)
  4576  	}
  4577  
  4578  	id2, err = buildImage(name,
  4579  		`FROM busybox
  4580         LABEL f1="b1 f2=b2"`, true)
  4581  	if err != nil || id1 == id2 {
  4582  		c.Fatalf("Build 6 should have worked & NOT used the cache(%s,%s): %q", id1, id2, err)
  4583  	}
  4584  
  4585  }
  4586  
  4587  func (s *DockerSuite) TestBuildStderr(c *check.C) {
  4588  	// This test just makes sure that no non-error output goes
  4589  	// to stderr
  4590  	name := "testbuildstderr"
  4591  	_, _, stderr, err := buildImageWithStdoutStderr(name,
  4592  		"FROM busybox\nRUN echo one", true)
  4593  	if err != nil {
  4594  		c.Fatal(err)
  4595  	}
  4596  
  4597  	if runtime.GOOS == "windows" {
  4598  		// stderr might contain a security warning on windows
  4599  		lines := strings.Split(stderr, "\n")
  4600  		for _, v := range lines {
  4601  			if v != "" && !strings.Contains(v, "SECURITY WARNING:") {
  4602  				c.Fatalf("Stderr contains unexpected output line: %q", v)
  4603  			}
  4604  		}
  4605  	} else {
  4606  		if stderr != "" {
  4607  			c.Fatalf("Stderr should have been empty, instead its: %q", stderr)
  4608  		}
  4609  	}
  4610  }
  4611  
  4612  func (s *DockerSuite) TestBuildChownSingleFile(c *check.C) {
  4613  	testRequires(c, UnixCli) // test uses chown: not available on windows
  4614  
  4615  	name := "testbuildchownsinglefile"
  4616  
  4617  	ctx, err := fakeContext(`
  4618  FROM busybox
  4619  COPY test /
  4620  RUN ls -l /test
  4621  RUN [ $(ls -l /test | awk '{print $3":"$4}') = 'root:root' ]
  4622  `, map[string]string{
  4623  		"test": "test",
  4624  	})
  4625  	if err != nil {
  4626  		c.Fatal(err)
  4627  	}
  4628  	defer ctx.Close()
  4629  
  4630  	if err := os.Chown(filepath.Join(ctx.Dir, "test"), 4242, 4242); err != nil {
  4631  		c.Fatal(err)
  4632  	}
  4633  
  4634  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4635  		c.Fatal(err)
  4636  	}
  4637  
  4638  }
  4639  
  4640  func (s *DockerSuite) TestBuildSymlinkBreakout(c *check.C) {
  4641  	name := "testbuildsymlinkbreakout"
  4642  	tmpdir, err := ioutil.TempDir("", name)
  4643  	if err != nil {
  4644  		c.Fatal(err)
  4645  	}
  4646  	defer os.RemoveAll(tmpdir)
  4647  	ctx := filepath.Join(tmpdir, "context")
  4648  	if err := os.MkdirAll(ctx, 0755); err != nil {
  4649  		c.Fatal(err)
  4650  	}
  4651  	if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte(`
  4652  	from busybox
  4653  	add symlink.tar /
  4654  	add inject /symlink/
  4655  	`), 0644); err != nil {
  4656  		c.Fatal(err)
  4657  	}
  4658  	inject := filepath.Join(ctx, "inject")
  4659  	if err := ioutil.WriteFile(inject, nil, 0644); err != nil {
  4660  		c.Fatal(err)
  4661  	}
  4662  	f, err := os.Create(filepath.Join(ctx, "symlink.tar"))
  4663  	if err != nil {
  4664  		c.Fatal(err)
  4665  	}
  4666  	w := tar.NewWriter(f)
  4667  	w.WriteHeader(&tar.Header{
  4668  		Name:     "symlink2",
  4669  		Typeflag: tar.TypeSymlink,
  4670  		Linkname: "/../../../../../../../../../../../../../../",
  4671  		Uid:      os.Getuid(),
  4672  		Gid:      os.Getgid(),
  4673  	})
  4674  	w.WriteHeader(&tar.Header{
  4675  		Name:     "symlink",
  4676  		Typeflag: tar.TypeSymlink,
  4677  		Linkname: filepath.Join("symlink2", tmpdir),
  4678  		Uid:      os.Getuid(),
  4679  		Gid:      os.Getgid(),
  4680  	})
  4681  	w.Close()
  4682  	f.Close()
  4683  	if _, err := buildImageFromContext(name, fakeContextFromDir(ctx), false); err != nil {
  4684  		c.Fatal(err)
  4685  	}
  4686  	if _, err := os.Lstat(filepath.Join(tmpdir, "inject")); err == nil {
  4687  		c.Fatal("symlink breakout - inject")
  4688  	} else if !os.IsNotExist(err) {
  4689  		c.Fatalf("unexpected error: %v", err)
  4690  	}
  4691  }
  4692  
  4693  func (s *DockerSuite) TestBuildXZHost(c *check.C) {
  4694  	name := "testbuildxzhost"
  4695  
  4696  	ctx, err := fakeContext(`
  4697  FROM busybox
  4698  ADD xz /usr/local/sbin/
  4699  RUN chmod 755 /usr/local/sbin/xz
  4700  ADD test.xz /
  4701  RUN [ ! -e /injected ]`,
  4702  		map[string]string{
  4703  			"test.xz": "\xfd\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00" +
  4704  				"\x21\x01\x16\x00\x00\x00\x74\x2f\xe5\xa3\x01\x00\x3f\xfd" +
  4705  				"\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00\x21",
  4706  			"xz": "#!/bin/sh\ntouch /injected",
  4707  		})
  4708  
  4709  	if err != nil {
  4710  		c.Fatal(err)
  4711  	}
  4712  	defer ctx.Close()
  4713  
  4714  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4715  		c.Fatal(err)
  4716  	}
  4717  
  4718  }
  4719  
  4720  func (s *DockerSuite) TestBuildVolumesRetainContents(c *check.C) {
  4721  	var (
  4722  		name     = "testbuildvolumescontent"
  4723  		expected = "some text"
  4724  	)
  4725  	ctx, err := fakeContext(`
  4726  FROM busybox
  4727  COPY content /foo/file
  4728  VOLUME /foo
  4729  CMD cat /foo/file`,
  4730  		map[string]string{
  4731  			"content": expected,
  4732  		})
  4733  	if err != nil {
  4734  		c.Fatal(err)
  4735  	}
  4736  	defer ctx.Close()
  4737  
  4738  	if _, err := buildImageFromContext(name, ctx, false); err != nil {
  4739  		c.Fatal(err)
  4740  	}
  4741  
  4742  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", name))
  4743  	if err != nil {
  4744  		c.Fatal(err)
  4745  	}
  4746  	if out != expected {
  4747  		c.Fatalf("expected file contents for /foo/file to be %q but received %q", expected, out)
  4748  	}
  4749  
  4750  }
  4751  
  4752  func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) {
  4753  
  4754  	ctx, err := fakeContext(`FROM busybox
  4755  	RUN echo from Dockerfile`,
  4756  		map[string]string{
  4757  			"Dockerfile":       "FROM busybox\nRUN echo from Dockerfile",
  4758  			"files/Dockerfile": "FROM busybox\nRUN echo from files/Dockerfile",
  4759  			"files/dFile":      "FROM busybox\nRUN echo from files/dFile",
  4760  			"dFile":            "FROM busybox\nRUN echo from dFile",
  4761  			"files/dFile2":     "FROM busybox\nRUN echo from files/dFile2",
  4762  		})
  4763  	defer ctx.Close()
  4764  	if err != nil {
  4765  		c.Fatal(err)
  4766  	}
  4767  
  4768  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4769  	if err != nil {
  4770  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4771  	}
  4772  	if !strings.Contains(out, "from Dockerfile") {
  4773  		c.Fatalf("test1 should have used Dockerfile, output:%s", out)
  4774  	}
  4775  
  4776  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-f", filepath.Join("files", "Dockerfile"), "-t", "test2", ".")
  4777  	if err != nil {
  4778  		c.Fatal(err)
  4779  	}
  4780  	if !strings.Contains(out, "from files/Dockerfile") {
  4781  		c.Fatalf("test2 should have used files/Dockerfile, output:%s", out)
  4782  	}
  4783  
  4784  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", filepath.Join("files", "dFile")), "-t", "test3", ".")
  4785  	if err != nil {
  4786  		c.Fatal(err)
  4787  	}
  4788  	if !strings.Contains(out, "from files/dFile") {
  4789  		c.Fatalf("test3 should have used files/dFile, output:%s", out)
  4790  	}
  4791  
  4792  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "--file=dFile", "-t", "test4", ".")
  4793  	if err != nil {
  4794  		c.Fatal(err)
  4795  	}
  4796  	if !strings.Contains(out, "from dFile") {
  4797  		c.Fatalf("test4 should have used dFile, output:%s", out)
  4798  	}
  4799  
  4800  	dirWithNoDockerfile, _ := ioutil.TempDir(os.TempDir(), "test5")
  4801  	nonDockerfileFile := filepath.Join(dirWithNoDockerfile, "notDockerfile")
  4802  	if _, err = os.Create(nonDockerfileFile); err != nil {
  4803  		c.Fatal(err)
  4804  	}
  4805  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", nonDockerfileFile), "-t", "test5", ".")
  4806  
  4807  	if err == nil {
  4808  		c.Fatalf("test5 was supposed to fail to find passwd")
  4809  	}
  4810  
  4811  	if expected := fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", nonDockerfileFile); !strings.Contains(out, expected) {
  4812  		c.Fatalf("wrong error messsage:%v\nexpected to contain=%v", out, expected)
  4813  	}
  4814  
  4815  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test6", "..")
  4816  	if err != nil {
  4817  		c.Fatalf("test6 failed: %s", err)
  4818  	}
  4819  	if !strings.Contains(out, "from Dockerfile") {
  4820  		c.Fatalf("test6 should have used root Dockerfile, output:%s", out)
  4821  	}
  4822  
  4823  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join(ctx.Dir, "files", "Dockerfile"), "-t", "test7", "..")
  4824  	if err != nil {
  4825  		c.Fatalf("test7 failed: %s", err)
  4826  	}
  4827  	if !strings.Contains(out, "from files/Dockerfile") {
  4828  		c.Fatalf("test7 should have used files Dockerfile, output:%s", out)
  4829  	}
  4830  
  4831  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test8", ".")
  4832  	if err == nil || !strings.Contains(out, "must be within the build context") {
  4833  		c.Fatalf("test8 should have failed with Dockerfile out of context: %s", err)
  4834  	}
  4835  
  4836  	tmpDir := os.TempDir()
  4837  	out, _, err = dockerCmdInDir(c, tmpDir, "build", "-t", "test9", ctx.Dir)
  4838  	if err != nil {
  4839  		c.Fatalf("test9 - failed: %s", err)
  4840  	}
  4841  	if !strings.Contains(out, "from Dockerfile") {
  4842  		c.Fatalf("test9 should have used root Dockerfile, output:%s", out)
  4843  	}
  4844  
  4845  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", "dFile2", "-t", "test10", ".")
  4846  	if err != nil {
  4847  		c.Fatalf("test10 should have worked: %s", err)
  4848  	}
  4849  	if !strings.Contains(out, "from files/dFile2") {
  4850  		c.Fatalf("test10 should have used files/dFile2, output:%s", out)
  4851  	}
  4852  
  4853  }
  4854  
  4855  func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) {
  4856  	testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  4857  
  4858  	ctx, err := fakeContext(`FROM busybox
  4859  	RUN echo from dockerfile`,
  4860  		map[string]string{
  4861  			"dockerfile": "FROM busybox\nRUN echo from dockerfile",
  4862  		})
  4863  	defer ctx.Close()
  4864  	if err != nil {
  4865  		c.Fatal(err)
  4866  	}
  4867  
  4868  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4869  	if err != nil {
  4870  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4871  	}
  4872  
  4873  	if !strings.Contains(out, "from dockerfile") {
  4874  		c.Fatalf("Missing proper output: %s", out)
  4875  	}
  4876  
  4877  }
  4878  
  4879  func (s *DockerSuite) TestBuildWithTwoDockerfiles(c *check.C) {
  4880  	testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  4881  
  4882  	ctx, err := fakeContext(`FROM busybox
  4883  RUN echo from Dockerfile`,
  4884  		map[string]string{
  4885  			"dockerfile": "FROM busybox\nRUN echo from dockerfile",
  4886  		})
  4887  	defer ctx.Close()
  4888  	if err != nil {
  4889  		c.Fatal(err)
  4890  	}
  4891  
  4892  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4893  	if err != nil {
  4894  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4895  	}
  4896  
  4897  	if !strings.Contains(out, "from Dockerfile") {
  4898  		c.Fatalf("Missing proper output: %s", out)
  4899  	}
  4900  
  4901  }
  4902  
  4903  func (s *DockerSuite) TestBuildFromURLWithF(c *check.C) {
  4904  
  4905  	server, err := fakeStorage(map[string]string{"baz": `FROM busybox
  4906  RUN echo from baz
  4907  COPY * /tmp/
  4908  RUN find /tmp/`})
  4909  	if err != nil {
  4910  		c.Fatal(err)
  4911  	}
  4912  	defer server.Close()
  4913  
  4914  	ctx, err := fakeContext(`FROM busybox
  4915  RUN echo from Dockerfile`,
  4916  		map[string]string{})
  4917  	defer ctx.Close()
  4918  	if err != nil {
  4919  		c.Fatal(err)
  4920  	}
  4921  
  4922  	// Make sure that -f is ignored and that we don't use the Dockerfile
  4923  	// that's in the current dir
  4924  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-f", "baz", "-t", "test1", server.URL()+"/baz")
  4925  	if err != nil {
  4926  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4927  	}
  4928  
  4929  	if !strings.Contains(out, "from baz") ||
  4930  		strings.Contains(out, "/tmp/baz") ||
  4931  		!strings.Contains(out, "/tmp/Dockerfile") {
  4932  		c.Fatalf("Missing proper output: %s", out)
  4933  	}
  4934  
  4935  }
  4936  
  4937  func (s *DockerSuite) TestBuildFromStdinWithF(c *check.C) {
  4938  
  4939  	ctx, err := fakeContext(`FROM busybox
  4940  RUN echo from Dockerfile`,
  4941  		map[string]string{})
  4942  	defer ctx.Close()
  4943  	if err != nil {
  4944  		c.Fatal(err)
  4945  	}
  4946  
  4947  	// Make sure that -f is ignored and that we don't use the Dockerfile
  4948  	// that's in the current dir
  4949  	dockerCommand := exec.Command(dockerBinary, "build", "-f", "baz", "-t", "test1", "-")
  4950  	dockerCommand.Dir = ctx.Dir
  4951  	dockerCommand.Stdin = strings.NewReader(`FROM busybox
  4952  RUN echo from baz
  4953  COPY * /tmp/
  4954  RUN find /tmp/`)
  4955  	out, status, err := runCommandWithOutput(dockerCommand)
  4956  	if err != nil || status != 0 {
  4957  		c.Fatalf("Error building: %s", err)
  4958  	}
  4959  
  4960  	if !strings.Contains(out, "from baz") ||
  4961  		strings.Contains(out, "/tmp/baz") ||
  4962  		!strings.Contains(out, "/tmp/Dockerfile") {
  4963  		c.Fatalf("Missing proper output: %s", out)
  4964  	}
  4965  
  4966  }
  4967  
  4968  func (s *DockerSuite) TestBuildFromOfficialNames(c *check.C) {
  4969  	name := "testbuildfromofficial"
  4970  	fromNames := []string{
  4971  		"busybox",
  4972  		"docker.io/busybox",
  4973  		"index.docker.io/busybox",
  4974  		"library/busybox",
  4975  		"docker.io/library/busybox",
  4976  		"index.docker.io/library/busybox",
  4977  	}
  4978  	for idx, fromName := range fromNames {
  4979  		imgName := fmt.Sprintf("%s%d", name, idx)
  4980  		_, err := buildImage(imgName, "FROM "+fromName, true)
  4981  		if err != nil {
  4982  			c.Errorf("Build failed using FROM %s: %s", fromName, err)
  4983  		}
  4984  		deleteImages(imgName)
  4985  	}
  4986  }
  4987  
  4988  func (s *DockerSuite) TestBuildDockerfileOutsideContext(c *check.C) {
  4989  	testRequires(c, UnixCli) // uses os.Symlink: not implemented in windows at the time of writing (go-1.4.2)
  4990  
  4991  	name := "testbuilddockerfileoutsidecontext"
  4992  	tmpdir, err := ioutil.TempDir("", name)
  4993  	if err != nil {
  4994  		c.Fatal(err)
  4995  	}
  4996  	defer os.RemoveAll(tmpdir)
  4997  	ctx := filepath.Join(tmpdir, "context")
  4998  	if err := os.MkdirAll(ctx, 0755); err != nil {
  4999  		c.Fatal(err)
  5000  	}
  5001  	if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte("FROM scratch\nENV X Y"), 0644); err != nil {
  5002  		c.Fatal(err)
  5003  	}
  5004  	wd, err := os.Getwd()
  5005  	if err != nil {
  5006  		c.Fatal(err)
  5007  	}
  5008  	defer os.Chdir(wd)
  5009  	if err := os.Chdir(ctx); err != nil {
  5010  		c.Fatal(err)
  5011  	}
  5012  	if err := ioutil.WriteFile(filepath.Join(tmpdir, "outsideDockerfile"), []byte("FROM scratch\nENV x y"), 0644); err != nil {
  5013  		c.Fatal(err)
  5014  	}
  5015  	if err := os.Symlink(filepath.Join("..", "outsideDockerfile"), filepath.Join(ctx, "dockerfile1")); err != nil {
  5016  		c.Fatal(err)
  5017  	}
  5018  	if err := os.Symlink(filepath.Join(tmpdir, "outsideDockerfile"), filepath.Join(ctx, "dockerfile2")); err != nil {
  5019  		c.Fatal(err)
  5020  	}
  5021  
  5022  	for _, dockerfilePath := range []string{
  5023  		filepath.Join("..", "outsideDockerfile"),
  5024  		filepath.Join(ctx, "dockerfile1"),
  5025  		filepath.Join(ctx, "dockerfile2"),
  5026  	} {
  5027  		out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "build", "-t", name, "--no-cache", "-f", dockerfilePath, "."))
  5028  		if err == nil {
  5029  			c.Fatalf("Expected error with %s. Out: %s", dockerfilePath, out)
  5030  		}
  5031  		if !strings.Contains(out, "must be within the build context") && !strings.Contains(out, "Cannot locate Dockerfile") {
  5032  			c.Fatalf("Unexpected error with %s. Out: %s", dockerfilePath, out)
  5033  		}
  5034  		deleteImages(name)
  5035  	}
  5036  
  5037  	os.Chdir(tmpdir)
  5038  
  5039  	// Path to Dockerfile should be resolved relative to working directory, not relative to context.
  5040  	// There is a Dockerfile in the context, but since there is no Dockerfile in the current directory, the following should fail
  5041  	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "build", "-t", name, "--no-cache", "-f", "Dockerfile", ctx))
  5042  	if err == nil {
  5043  		c.Fatalf("Expected error. Out: %s", out)
  5044  	}
  5045  }
  5046  
  5047  func (s *DockerSuite) TestBuildSpaces(c *check.C) {
  5048  	// Test to make sure that leading/trailing spaces on a command
  5049  	// doesn't change the error msg we get
  5050  	var (
  5051  		err1 error
  5052  		err2 error
  5053  	)
  5054  
  5055  	name := "testspaces"
  5056  	ctx, err := fakeContext("FROM busybox\nCOPY\n",
  5057  		map[string]string{
  5058  			"Dockerfile": "FROM busybox\nCOPY\n",
  5059  		})
  5060  	if err != nil {
  5061  		c.Fatal(err)
  5062  	}
  5063  	defer ctx.Close()
  5064  
  5065  	if _, err1 = buildImageFromContext(name, ctx, false); err1 == nil {
  5066  		c.Fatal("Build 1 was supposed to fail, but didn't")
  5067  	}
  5068  
  5069  	ctx.Add("Dockerfile", "FROM busybox\nCOPY    ")
  5070  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5071  		c.Fatal("Build 2 was supposed to fail, but didn't")
  5072  	}
  5073  
  5074  	removeLogTimestamps := func(s string) string {
  5075  		return regexp.MustCompile(`time="(.*?)"`).ReplaceAllString(s, `time=[TIMESTAMP]`)
  5076  	}
  5077  
  5078  	// Skip over the times
  5079  	e1 := removeLogTimestamps(err1.Error())
  5080  	e2 := removeLogTimestamps(err2.Error())
  5081  
  5082  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5083  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5084  		c.Fatalf("Build 2's error wasn't the same as build 1's\n1:%s\n2:%s", err1, err2)
  5085  	}
  5086  
  5087  	ctx.Add("Dockerfile", "FROM busybox\n   COPY")
  5088  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5089  		c.Fatal("Build 3 was supposed to fail, but didn't")
  5090  	}
  5091  
  5092  	// Skip over the times
  5093  	e1 = removeLogTimestamps(err1.Error())
  5094  	e2 = removeLogTimestamps(err2.Error())
  5095  
  5096  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5097  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5098  		c.Fatalf("Build 3's error wasn't the same as build 1's\n1:%s\n3:%s", err1, err2)
  5099  	}
  5100  
  5101  	ctx.Add("Dockerfile", "FROM busybox\n   COPY    ")
  5102  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5103  		c.Fatal("Build 4 was supposed to fail, but didn't")
  5104  	}
  5105  
  5106  	// Skip over the times
  5107  	e1 = removeLogTimestamps(err1.Error())
  5108  	e2 = removeLogTimestamps(err2.Error())
  5109  
  5110  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5111  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5112  		c.Fatalf("Build 4's error wasn't the same as build 1's\n1:%s\n4:%s", err1, err2)
  5113  	}
  5114  
  5115  }
  5116  
  5117  func (s *DockerSuite) TestBuildSpacesWithQuotes(c *check.C) {
  5118  	// Test to make sure that spaces in quotes aren't lost
  5119  	name := "testspacesquotes"
  5120  
  5121  	dockerfile := `FROM busybox
  5122  RUN echo "  \
  5123    foo  "`
  5124  
  5125  	_, out, err := buildImageWithOut(name, dockerfile, false)
  5126  	if err != nil {
  5127  		c.Fatal("Build failed:", err)
  5128  	}
  5129  
  5130  	expecting := "\n    foo  \n"
  5131  	if !strings.Contains(out, expecting) {
  5132  		c.Fatalf("Bad output: %q expecting to contain %q", out, expecting)
  5133  	}
  5134  
  5135  }
  5136  
  5137  // #4393
  5138  func (s *DockerSuite) TestBuildVolumeFileExistsinContainer(c *check.C) {
  5139  	buildCmd := exec.Command(dockerBinary, "build", "-t", "docker-test-errcreatevolumewithfile", "-")
  5140  	buildCmd.Stdin = strings.NewReader(`
  5141  	FROM busybox
  5142  	RUN touch /foo
  5143  	VOLUME /foo
  5144  	`)
  5145  
  5146  	out, _, err := runCommandWithOutput(buildCmd)
  5147  	if err == nil || !strings.Contains(out, "file exists") {
  5148  		c.Fatalf("expected build to fail when file exists in container at requested volume path")
  5149  	}
  5150  
  5151  }
  5152  
  5153  func (s *DockerSuite) TestBuildMissingArgs(c *check.C) {
  5154  	// Test to make sure that all Dockerfile commands (except the ones listed
  5155  	// in skipCmds) will generate an error if no args are provided.
  5156  	// Note: INSERT is deprecated so we exclude it because of that.
  5157  	skipCmds := map[string]struct{}{
  5158  		"CMD":        {},
  5159  		"RUN":        {},
  5160  		"ENTRYPOINT": {},
  5161  		"INSERT":     {},
  5162  	}
  5163  
  5164  	for cmd := range command.Commands {
  5165  		cmd = strings.ToUpper(cmd)
  5166  		if _, ok := skipCmds[cmd]; ok {
  5167  			continue
  5168  		}
  5169  
  5170  		var dockerfile string
  5171  		if cmd == "FROM" {
  5172  			dockerfile = cmd
  5173  		} else {
  5174  			// Add FROM to make sure we don't complain about it missing
  5175  			dockerfile = "FROM busybox\n" + cmd
  5176  		}
  5177  
  5178  		ctx, err := fakeContext(dockerfile, map[string]string{})
  5179  		if err != nil {
  5180  			c.Fatal(err)
  5181  		}
  5182  		defer ctx.Close()
  5183  		var out string
  5184  		if out, err = buildImageFromContext("args", ctx, true); err == nil {
  5185  			c.Fatalf("%s was supposed to fail. Out:%s", cmd, out)
  5186  		}
  5187  		if !strings.Contains(err.Error(), cmd+" requires") {
  5188  			c.Fatalf("%s returned the wrong type of error:%s", cmd, err)
  5189  		}
  5190  	}
  5191  
  5192  }
  5193  
  5194  func (s *DockerSuite) TestBuildEmptyScratch(c *check.C) {
  5195  	_, out, err := buildImageWithOut("sc", "FROM scratch", true)
  5196  	if err == nil {
  5197  		c.Fatalf("Build was supposed to fail")
  5198  	}
  5199  	if !strings.Contains(out, "No image was generated") {
  5200  		c.Fatalf("Wrong error message: %v", out)
  5201  	}
  5202  }
  5203  
  5204  func (s *DockerSuite) TestBuildDotDotFile(c *check.C) {
  5205  	ctx, err := fakeContext("FROM busybox\n",
  5206  		map[string]string{
  5207  			"..gitme": "",
  5208  		})
  5209  	if err != nil {
  5210  		c.Fatal(err)
  5211  	}
  5212  	defer ctx.Close()
  5213  
  5214  	if _, err = buildImageFromContext("sc", ctx, false); err != nil {
  5215  		c.Fatalf("Build was supposed to work: %s", err)
  5216  	}
  5217  }
  5218  
  5219  func (s *DockerSuite) TestBuildNotVerbose(c *check.C) {
  5220  
  5221  	ctx, err := fakeContext("FROM busybox\nENV abc=hi\nRUN echo $abc there", map[string]string{})
  5222  	if err != nil {
  5223  		c.Fatal(err)
  5224  	}
  5225  	defer ctx.Close()
  5226  
  5227  	// First do it w/verbose - baseline
  5228  	buildCmd := exec.Command(dockerBinary, "build", "--no-cache", "-t", "verbose", ".")
  5229  	buildCmd.Dir = ctx.Dir
  5230  	out, _, err := runCommandWithOutput(buildCmd)
  5231  	if err != nil {
  5232  		c.Fatalf("failed to build the image w/o -q: %s, %v", out, err)
  5233  	}
  5234  	if !strings.Contains(out, "hi there") {
  5235  		c.Fatalf("missing output:%s\n", out)
  5236  	}
  5237  
  5238  	// Now do it w/o verbose
  5239  	buildCmd = exec.Command(dockerBinary, "build", "--no-cache", "-q", "-t", "verbose", ".")
  5240  	buildCmd.Dir = ctx.Dir
  5241  	out, _, err = runCommandWithOutput(buildCmd)
  5242  	if err != nil {
  5243  		c.Fatalf("failed to build the image w/ -q: %s, %v", out, err)
  5244  	}
  5245  	if strings.Contains(out, "hi there") {
  5246  		c.Fatalf("Bad output, should not contain 'hi there':%s", out)
  5247  	}
  5248  
  5249  }
  5250  
  5251  func (s *DockerSuite) TestBuildRUNoneJSON(c *check.C) {
  5252  	name := "testbuildrunonejson"
  5253  
  5254  	ctx, err := fakeContext(`FROM hello-world:frozen
  5255  RUN [ "/hello" ]`, map[string]string{})
  5256  	if err != nil {
  5257  		c.Fatal(err)
  5258  	}
  5259  	defer ctx.Close()
  5260  
  5261  	buildCmd := exec.Command(dockerBinary, "build", "--no-cache", "-t", name, ".")
  5262  	buildCmd.Dir = ctx.Dir
  5263  	out, _, err := runCommandWithOutput(buildCmd)
  5264  	if err != nil {
  5265  		c.Fatalf("failed to build the image: %s, %v", out, err)
  5266  	}
  5267  
  5268  	if !strings.Contains(out, "Hello from Docker") {
  5269  		c.Fatalf("bad output: %s", out)
  5270  	}
  5271  
  5272  }
  5273  
  5274  func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) {
  5275  	name := "testbuildresourceconstraints"
  5276  
  5277  	ctx, err := fakeContext(`
  5278  	FROM hello-world:frozen
  5279  	RUN ["/hello"]
  5280  	`, map[string]string{})
  5281  	if err != nil {
  5282  		c.Fatal(err)
  5283  	}
  5284  
  5285  	cmd := exec.Command(dockerBinary, "build", "--no-cache", "--rm=false", "--memory=64m", "--memory-swap=-1", "--cpuset-cpus=0", "--cpuset-mems=0", "--cpu-shares=100", "--cpu-quota=8000", "-t", name, ".")
  5286  	cmd.Dir = ctx.Dir
  5287  
  5288  	out, _, err := runCommandWithOutput(cmd)
  5289  	if err != nil {
  5290  		c.Fatal(err, out)
  5291  	}
  5292  	out, _ = dockerCmd(c, "ps", "-lq")
  5293  
  5294  	cID := strings.TrimSpace(out)
  5295  
  5296  	type hostConfig struct {
  5297  		Memory     int64
  5298  		MemorySwap int64
  5299  		CpusetCpus string
  5300  		CpusetMems string
  5301  		CpuShares  int64
  5302  		CpuQuota   int64
  5303  	}
  5304  
  5305  	cfg, err := inspectFieldJSON(cID, "HostConfig")
  5306  	if err != nil {
  5307  		c.Fatal(err)
  5308  	}
  5309  
  5310  	var c1 hostConfig
  5311  	if err := json.Unmarshal([]byte(cfg), &c1); err != nil {
  5312  		c.Fatal(err, cfg)
  5313  	}
  5314  	if c1.Memory != 67108864 || c1.MemorySwap != -1 || c1.CpusetCpus != "0" || c1.CpusetMems != "0" || c1.CpuShares != 100 || c1.CpuQuota != 8000 {
  5315  		c.Fatalf("resource constraints not set properly:\nMemory: %d, MemSwap: %d, CpusetCpus: %s, CpusetMems: %s, CpuShares: %d, CpuQuota: %d",
  5316  			c1.Memory, c1.MemorySwap, c1.CpusetCpus, c1.CpusetMems, c1.CpuShares, c1.CpuQuota)
  5317  	}
  5318  
  5319  	// Make sure constraints aren't saved to image
  5320  	_, _ = dockerCmd(c, "run", "--name=test", name)
  5321  
  5322  	cfg, err = inspectFieldJSON("test", "HostConfig")
  5323  	if err != nil {
  5324  		c.Fatal(err)
  5325  	}
  5326  	var c2 hostConfig
  5327  	if err := json.Unmarshal([]byte(cfg), &c2); err != nil {
  5328  		c.Fatal(err, cfg)
  5329  	}
  5330  	if c2.Memory == 67108864 || c2.MemorySwap == -1 || c2.CpusetCpus == "0" || c2.CpusetMems == "0" || c2.CpuShares == 100 || c2.CpuQuota == 8000 {
  5331  		c.Fatalf("resource constraints leaked from build:\nMemory: %d, MemSwap: %d, CpusetCpus: %s, CpusetMems: %s, CpuShares: %d, CpuQuota: %d",
  5332  			c2.Memory, c2.MemorySwap, c2.CpusetCpus, c2.CpusetMems, c2.CpuShares, c2.CpuQuota)
  5333  	}
  5334  
  5335  }
  5336  
  5337  func (s *DockerSuite) TestBuildEmptyStringVolume(c *check.C) {
  5338  	name := "testbuildemptystringvolume"
  5339  
  5340  	_, err := buildImage(name, `
  5341    FROM busybox
  5342    ENV foo=""
  5343    VOLUME $foo
  5344    `, false)
  5345  	if err == nil {
  5346  		c.Fatal("Should have failed to build")
  5347  	}
  5348  
  5349  }
  5350  
  5351  func (s *DockerSuite) TestBuildContainerWithCgroupParent(c *check.C) {
  5352  	testRequires(c, NativeExecDriver)
  5353  	testRequires(c, SameHostDaemon)
  5354  	defer deleteImages()
  5355  
  5356  	cgroupParent := "test"
  5357  	data, err := ioutil.ReadFile("/proc/self/cgroup")
  5358  	if err != nil {
  5359  		c.Fatalf("failed to read '/proc/self/cgroup - %v", err)
  5360  	}
  5361  	selfCgroupPaths := parseCgroupPaths(string(data))
  5362  	_, found := selfCgroupPaths["memory"]
  5363  	if !found {
  5364  		c.Fatalf("unable to find self cpu cgroup path. CgroupsPath: %v", selfCgroupPaths)
  5365  	}
  5366  	cmd := exec.Command(dockerBinary, "build", "--cgroup-parent", cgroupParent, "-")
  5367  	cmd.Stdin = strings.NewReader(`
  5368  FROM busybox
  5369  RUN cat /proc/self/cgroup
  5370  `)
  5371  
  5372  	out, _, err := runCommandWithOutput(cmd)
  5373  	if err != nil {
  5374  		c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
  5375  	}
  5376  }
  5377  
  5378  func (s *DockerSuite) TestBuildNoDupOutput(c *check.C) {
  5379  	// Check to make sure our build output prints the Dockerfile cmd
  5380  	// property - there was a bug that caused it to be duplicated on the
  5381  	// Step X  line
  5382  	name := "testbuildnodupoutput"
  5383  
  5384  	_, out, err := buildImageWithOut(name, `
  5385    FROM busybox
  5386    RUN env`, false)
  5387  	if err != nil {
  5388  		c.Fatalf("Build should have worked: %q", err)
  5389  	}
  5390  
  5391  	exp := "\nStep 1 : RUN env\n"
  5392  	if !strings.Contains(out, exp) {
  5393  		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  5394  	}
  5395  }
  5396  
  5397  func (s *DockerSuite) TestBuildBadCmdFlag(c *check.C) {
  5398  	name := "testbuildbadcmdflag"
  5399  
  5400  	_, out, err := buildImageWithOut(name, `
  5401    FROM busybox
  5402    MAINTAINER --boo joe@example.com`, false)
  5403  	if err == nil {
  5404  		c.Fatal("Build should have failed")
  5405  	}
  5406  
  5407  	exp := "\nUnknown flag: boo\n"
  5408  	if !strings.Contains(out, exp) {
  5409  		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  5410  	}
  5411  }
  5412  
  5413  func (s *DockerSuite) TestBuildRUNErrMsg(c *check.C) {
  5414  	// Test to make sure the bad command is quoted with just "s and
  5415  	// not as a Go []string
  5416  	name := "testbuildbadrunerrmsg"
  5417  	_, out, err := buildImageWithOut(name, `
  5418    FROM busybox
  5419    RUN badEXE a1 \& a2	a3`, false) // tab between a2 and a3
  5420  	if err == nil {
  5421  		c.Fatal("Should have failed to build")
  5422  	}
  5423  
  5424  	exp := `The command '/bin/sh -c badEXE a1 \& a2	a3' returned a non-zero code: 127`
  5425  	if !strings.Contains(out, exp) {
  5426  		c.Fatalf("RUN doesn't have the correct output:\nGot:%s\nExpected:%s", out, exp)
  5427  	}
  5428  }