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