github.com/damirazo/docker@v1.9.0/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/dockerfile/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  	if err != nil {
   822  		c.Fatal(err)
   823  	}
   824  	defer ctx.Close()
   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  	if err != nil {
   842  		c.Fatal(err)
   843  	}
   844  	defer ctx.Close()
   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  	if err != nil {
   864  		c.Fatal(err)
   865  	}
   866  	defer ctx.Close()
   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  	if err != nil {
   886  		c.Fatal(err)
   887  	}
   888  	defer ctx.Close()
   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  	if err != nil {
   908  		c.Fatal(err)
   909  	}
   910  	defer ctx.Close()
   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  	if err != nil {
   930  		c.Fatal(err)
   931  	}
   932  	defer ctx.Close()
   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  	if err != nil {
   952  		c.Fatal(err)
   953  	}
   954  	defer ctx.Close()
   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  	if err != nil {
   990  		c.Fatal(err)
   991  	}
   992  	defer ctx.Close()
   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  	if err != nil {
  1026  		c.Fatal(err)
  1027  	}
  1028  	defer ctx.Close()
  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  	if err != nil {
  1046  		c.Fatal(err)
  1047  	}
  1048  	defer ctx.Close()
  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  	if err != nil {
  1068  		c.Fatal(err)
  1069  	}
  1070  	defer ctx.Close()
  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  	if err != nil {
  1137  		c.Fatal(err)
  1138  	}
  1139  	defer ctx.Close()
  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  	if err != nil {
  1185  		c.Fatal(err)
  1186  	}
  1187  	defer ctx.Close()
  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  	// cat /test1/test2/foo gets permission denied for the user
  2187  	testRequires(c, NotUserNamespace)
  2188  	testRequires(c, DaemonIsLinux)
  2189  	name := "testbuildrelativecopy"
  2190  	dockerfile := `
  2191  		FROM busybox
  2192  			WORKDIR /test1
  2193  			WORKDIR test2
  2194  			RUN [ "$PWD" = '/test1/test2' ]
  2195  			COPY foo ./
  2196  			RUN [ "$(cat /test1/test2/foo)" = 'hello' ]
  2197  			ADD foo ./bar/baz
  2198  			RUN [ "$(cat /test1/test2/bar/baz)" = 'hello' ]
  2199  			COPY foo ./bar/baz2
  2200  			RUN [ "$(cat /test1/test2/bar/baz2)" = 'hello' ]
  2201  			WORKDIR ..
  2202  			COPY foo ./
  2203  			RUN [ "$(cat /test1/foo)" = 'hello' ]
  2204  			COPY foo /test3/
  2205  			RUN [ "$(cat /test3/foo)" = 'hello' ]
  2206  			WORKDIR /test4
  2207  			COPY . .
  2208  			RUN [ "$(cat /test4/foo)" = 'hello' ]
  2209  			WORKDIR /test5/test6
  2210  			COPY foo ../
  2211  			RUN [ "$(cat /test5/foo)" = 'hello' ]
  2212  			`
  2213  	ctx, err := fakeContext(dockerfile, map[string]string{
  2214  		"foo": "hello",
  2215  	})
  2216  	if err != nil {
  2217  		c.Fatal(err)
  2218  	}
  2219  	defer ctx.Close()
  2220  	_, err = buildImageFromContext(name, ctx, false)
  2221  	if err != nil {
  2222  		c.Fatal(err)
  2223  	}
  2224  }
  2225  
  2226  func (s *DockerSuite) TestBuildEnv(c *check.C) {
  2227  	testRequires(c, DaemonIsLinux)
  2228  	name := "testbuildenv"
  2229  	expected := "[PATH=/test:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PORT=2375]"
  2230  	_, err := buildImage(name,
  2231  		`FROM busybox
  2232  		ENV PATH /test:$PATH
  2233          ENV PORT 2375
  2234  		RUN [ $(env | grep PORT) = 'PORT=2375' ]`,
  2235  		true)
  2236  	if err != nil {
  2237  		c.Fatal(err)
  2238  	}
  2239  	res, err := inspectField(name, "Config.Env")
  2240  	if err != nil {
  2241  		c.Fatal(err)
  2242  	}
  2243  	if res != expected {
  2244  		c.Fatalf("Env %s, expected %s", res, expected)
  2245  	}
  2246  }
  2247  
  2248  func (s *DockerSuite) TestBuildContextCleanup(c *check.C) {
  2249  	testRequires(c, DaemonIsLinux)
  2250  	testRequires(c, SameHostDaemon)
  2251  
  2252  	name := "testbuildcontextcleanup"
  2253  	entries, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  2254  	if err != nil {
  2255  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2256  	}
  2257  	_, err = buildImage(name,
  2258  		`FROM scratch
  2259          ENTRYPOINT ["/bin/echo"]`,
  2260  		true)
  2261  	if err != nil {
  2262  		c.Fatal(err)
  2263  	}
  2264  	entriesFinal, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  2265  	if err != nil {
  2266  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2267  	}
  2268  	if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  2269  		c.Fatalf("context should have been deleted, but wasn't")
  2270  	}
  2271  
  2272  }
  2273  
  2274  func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *check.C) {
  2275  	testRequires(c, DaemonIsLinux)
  2276  	testRequires(c, SameHostDaemon)
  2277  
  2278  	name := "testbuildcontextcleanup"
  2279  	entries, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  2280  	if err != nil {
  2281  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2282  	}
  2283  	_, err = buildImage(name,
  2284  		`FROM scratch
  2285  	RUN /non/existing/command`,
  2286  		true)
  2287  	if err == nil {
  2288  		c.Fatalf("expected build to fail, but it didn't")
  2289  	}
  2290  	entriesFinal, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  2291  	if err != nil {
  2292  		c.Fatalf("failed to list contents of tmp dir: %s", err)
  2293  	}
  2294  	if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  2295  		c.Fatalf("context should have been deleted, but wasn't")
  2296  	}
  2297  
  2298  }
  2299  
  2300  func (s *DockerSuite) TestBuildCmd(c *check.C) {
  2301  	testRequires(c, DaemonIsLinux)
  2302  	name := "testbuildcmd"
  2303  	expected := "{[/bin/echo Hello World]}"
  2304  	_, err := buildImage(name,
  2305  		`FROM scratch
  2306          CMD ["/bin/echo", "Hello World"]`,
  2307  		true)
  2308  	if err != nil {
  2309  		c.Fatal(err)
  2310  	}
  2311  	res, err := inspectField(name, "Config.Cmd")
  2312  	if err != nil {
  2313  		c.Fatal(err)
  2314  	}
  2315  	if res != expected {
  2316  		c.Fatalf("Cmd %s, expected %s", res, expected)
  2317  	}
  2318  }
  2319  
  2320  func (s *DockerSuite) TestBuildExpose(c *check.C) {
  2321  	testRequires(c, DaemonIsLinux)
  2322  	name := "testbuildexpose"
  2323  	expected := "map[2375/tcp:{}]"
  2324  	_, err := buildImage(name,
  2325  		`FROM scratch
  2326          EXPOSE 2375`,
  2327  		true)
  2328  	if err != nil {
  2329  		c.Fatal(err)
  2330  	}
  2331  	res, err := inspectField(name, "Config.ExposedPorts")
  2332  	if err != nil {
  2333  		c.Fatal(err)
  2334  	}
  2335  	if res != expected {
  2336  		c.Fatalf("Exposed ports %s, expected %s", res, expected)
  2337  	}
  2338  }
  2339  
  2340  func (s *DockerSuite) TestBuildExposeMorePorts(c *check.C) {
  2341  	testRequires(c, DaemonIsLinux)
  2342  	// start building docker file with a large number of ports
  2343  	portList := make([]string, 50)
  2344  	line := make([]string, 100)
  2345  	expectedPorts := make([]int, len(portList)*len(line))
  2346  	for i := 0; i < len(portList); i++ {
  2347  		for j := 0; j < len(line); j++ {
  2348  			p := i*len(line) + j + 1
  2349  			line[j] = strconv.Itoa(p)
  2350  			expectedPorts[p-1] = p
  2351  		}
  2352  		if i == len(portList)-1 {
  2353  			portList[i] = strings.Join(line, " ")
  2354  		} else {
  2355  			portList[i] = strings.Join(line, " ") + ` \`
  2356  		}
  2357  	}
  2358  
  2359  	dockerfile := `FROM scratch
  2360  	EXPOSE {{range .}} {{.}}
  2361  	{{end}}`
  2362  	tmpl := template.Must(template.New("dockerfile").Parse(dockerfile))
  2363  	buf := bytes.NewBuffer(nil)
  2364  	tmpl.Execute(buf, portList)
  2365  
  2366  	name := "testbuildexpose"
  2367  	_, err := buildImage(name, buf.String(), true)
  2368  	if err != nil {
  2369  		c.Fatal(err)
  2370  	}
  2371  
  2372  	// check if all the ports are saved inside Config.ExposedPorts
  2373  	res, err := inspectFieldJSON(name, "Config.ExposedPorts")
  2374  	if err != nil {
  2375  		c.Fatal(err)
  2376  	}
  2377  	var exposedPorts map[string]interface{}
  2378  	if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
  2379  		c.Fatal(err)
  2380  	}
  2381  
  2382  	for _, p := range expectedPorts {
  2383  		ep := fmt.Sprintf("%d/tcp", p)
  2384  		if _, ok := exposedPorts[ep]; !ok {
  2385  			c.Errorf("Port(%s) is not exposed", ep)
  2386  		} else {
  2387  			delete(exposedPorts, ep)
  2388  		}
  2389  	}
  2390  	if len(exposedPorts) != 0 {
  2391  		c.Errorf("Unexpected extra exposed ports %v", exposedPorts)
  2392  	}
  2393  }
  2394  
  2395  func (s *DockerSuite) TestBuildExposeOrder(c *check.C) {
  2396  	testRequires(c, DaemonIsLinux)
  2397  	buildID := func(name, exposed string) string {
  2398  		_, err := buildImage(name, fmt.Sprintf(`FROM scratch
  2399  		EXPOSE %s`, exposed), true)
  2400  		if err != nil {
  2401  			c.Fatal(err)
  2402  		}
  2403  		id, err := inspectField(name, "Id")
  2404  		if err != nil {
  2405  			c.Fatal(err)
  2406  		}
  2407  		return id
  2408  	}
  2409  
  2410  	id1 := buildID("testbuildexpose1", "80 2375")
  2411  	id2 := buildID("testbuildexpose2", "2375 80")
  2412  	if id1 != id2 {
  2413  		c.Errorf("EXPOSE should invalidate the cache only when ports actually changed")
  2414  	}
  2415  }
  2416  
  2417  func (s *DockerSuite) TestBuildExposeUpperCaseProto(c *check.C) {
  2418  	testRequires(c, DaemonIsLinux)
  2419  	name := "testbuildexposeuppercaseproto"
  2420  	expected := "map[5678/udp:{}]"
  2421  	_, err := buildImage(name,
  2422  		`FROM scratch
  2423          EXPOSE 5678/UDP`,
  2424  		true)
  2425  	if err != nil {
  2426  		c.Fatal(err)
  2427  	}
  2428  	res, err := inspectField(name, "Config.ExposedPorts")
  2429  	if err != nil {
  2430  		c.Fatal(err)
  2431  	}
  2432  	if res != expected {
  2433  		c.Fatalf("Exposed ports %s, expected %s", res, expected)
  2434  	}
  2435  }
  2436  
  2437  func (s *DockerSuite) TestBuildEmptyEntrypointInheritance(c *check.C) {
  2438  	testRequires(c, DaemonIsLinux)
  2439  	name := "testbuildentrypointinheritance"
  2440  	name2 := "testbuildentrypointinheritance2"
  2441  
  2442  	_, err := buildImage(name,
  2443  		`FROM busybox
  2444          ENTRYPOINT ["/bin/echo"]`,
  2445  		true)
  2446  	if err != nil {
  2447  		c.Fatal(err)
  2448  	}
  2449  	res, err := inspectField(name, "Config.Entrypoint")
  2450  	if err != nil {
  2451  		c.Fatal(err)
  2452  	}
  2453  
  2454  	expected := "{[/bin/echo]}"
  2455  	if res != expected {
  2456  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2457  	}
  2458  
  2459  	_, err = buildImage(name2,
  2460  		fmt.Sprintf(`FROM %s
  2461          ENTRYPOINT []`, name),
  2462  		true)
  2463  	if err != nil {
  2464  		c.Fatal(err)
  2465  	}
  2466  	res, err = inspectField(name2, "Config.Entrypoint")
  2467  	if err != nil {
  2468  		c.Fatal(err)
  2469  	}
  2470  
  2471  	expected = "{[]}"
  2472  
  2473  	if res != expected {
  2474  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2475  	}
  2476  
  2477  }
  2478  
  2479  func (s *DockerSuite) TestBuildEmptyEntrypoint(c *check.C) {
  2480  	testRequires(c, DaemonIsLinux)
  2481  	name := "testbuildentrypoint"
  2482  	expected := "{[]}"
  2483  
  2484  	_, err := buildImage(name,
  2485  		`FROM busybox
  2486          ENTRYPOINT []`,
  2487  		true)
  2488  	if err != nil {
  2489  		c.Fatal(err)
  2490  	}
  2491  	res, err := inspectField(name, "Config.Entrypoint")
  2492  	if err != nil {
  2493  		c.Fatal(err)
  2494  	}
  2495  	if res != expected {
  2496  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2497  	}
  2498  
  2499  }
  2500  
  2501  func (s *DockerSuite) TestBuildEntrypoint(c *check.C) {
  2502  	testRequires(c, DaemonIsLinux)
  2503  	name := "testbuildentrypoint"
  2504  	expected := "{[/bin/echo]}"
  2505  	_, err := buildImage(name,
  2506  		`FROM scratch
  2507          ENTRYPOINT ["/bin/echo"]`,
  2508  		true)
  2509  	if err != nil {
  2510  		c.Fatal(err)
  2511  	}
  2512  	res, err := inspectField(name, "Config.Entrypoint")
  2513  	if err != nil {
  2514  		c.Fatal(err)
  2515  	}
  2516  	if res != expected {
  2517  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2518  	}
  2519  
  2520  }
  2521  
  2522  // #6445 ensure ONBUILD triggers aren't committed to grandchildren
  2523  func (s *DockerSuite) TestBuildOnBuildLimitedInheritence(c *check.C) {
  2524  	testRequires(c, DaemonIsLinux)
  2525  	var (
  2526  		out2, out3 string
  2527  	)
  2528  	{
  2529  		name1 := "testonbuildtrigger1"
  2530  		dockerfile1 := `
  2531  		FROM busybox
  2532  		RUN echo "GRANDPARENT"
  2533  		ONBUILD RUN echo "ONBUILD PARENT"
  2534  		`
  2535  		ctx, err := fakeContext(dockerfile1, nil)
  2536  		if err != nil {
  2537  			c.Fatal(err)
  2538  		}
  2539  		defer ctx.Close()
  2540  
  2541  		out1, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", name1, ".")
  2542  		if err != nil {
  2543  			c.Fatalf("build failed to complete: %s, %v", out1, err)
  2544  		}
  2545  	}
  2546  	{
  2547  		name2 := "testonbuildtrigger2"
  2548  		dockerfile2 := `
  2549  		FROM testonbuildtrigger1
  2550  		`
  2551  		ctx, err := fakeContext(dockerfile2, nil)
  2552  		if err != nil {
  2553  			c.Fatal(err)
  2554  		}
  2555  		defer ctx.Close()
  2556  
  2557  		out2, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name2, ".")
  2558  		if err != nil {
  2559  			c.Fatalf("build failed to complete: %s, %v", out2, err)
  2560  		}
  2561  	}
  2562  	{
  2563  		name3 := "testonbuildtrigger3"
  2564  		dockerfile3 := `
  2565  		FROM testonbuildtrigger2
  2566  		`
  2567  		ctx, err := fakeContext(dockerfile3, nil)
  2568  		if err != nil {
  2569  			c.Fatal(err)
  2570  		}
  2571  		defer ctx.Close()
  2572  
  2573  		out3, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name3, ".")
  2574  		if err != nil {
  2575  			c.Fatalf("build failed to complete: %s, %v", out3, err)
  2576  		}
  2577  
  2578  	}
  2579  
  2580  	// ONBUILD should be run in second build.
  2581  	if !strings.Contains(out2, "ONBUILD PARENT") {
  2582  		c.Fatalf("ONBUILD instruction did not run in child of ONBUILD parent")
  2583  	}
  2584  
  2585  	// ONBUILD should *not* be run in third build.
  2586  	if strings.Contains(out3, "ONBUILD PARENT") {
  2587  		c.Fatalf("ONBUILD instruction ran in grandchild of ONBUILD parent")
  2588  	}
  2589  
  2590  }
  2591  
  2592  func (s *DockerSuite) TestBuildWithCache(c *check.C) {
  2593  	testRequires(c, DaemonIsLinux)
  2594  	name := "testbuildwithcache"
  2595  	id1, err := buildImage(name,
  2596  		`FROM scratch
  2597  		MAINTAINER dockerio
  2598  		EXPOSE 5432
  2599          ENTRYPOINT ["/bin/echo"]`,
  2600  		true)
  2601  	if err != nil {
  2602  		c.Fatal(err)
  2603  	}
  2604  	id2, err := buildImage(name,
  2605  		`FROM scratch
  2606  		MAINTAINER dockerio
  2607  		EXPOSE 5432
  2608          ENTRYPOINT ["/bin/echo"]`,
  2609  		true)
  2610  	if err != nil {
  2611  		c.Fatal(err)
  2612  	}
  2613  	if id1 != id2 {
  2614  		c.Fatal("The cache should have been used but hasn't.")
  2615  	}
  2616  }
  2617  
  2618  func (s *DockerSuite) TestBuildWithoutCache(c *check.C) {
  2619  	testRequires(c, DaemonIsLinux)
  2620  	name := "testbuildwithoutcache"
  2621  	name2 := "testbuildwithoutcache2"
  2622  	id1, err := buildImage(name,
  2623  		`FROM scratch
  2624  		MAINTAINER dockerio
  2625  		EXPOSE 5432
  2626          ENTRYPOINT ["/bin/echo"]`,
  2627  		true)
  2628  	if err != nil {
  2629  		c.Fatal(err)
  2630  	}
  2631  
  2632  	id2, err := buildImage(name2,
  2633  		`FROM scratch
  2634  		MAINTAINER dockerio
  2635  		EXPOSE 5432
  2636          ENTRYPOINT ["/bin/echo"]`,
  2637  		false)
  2638  	if err != nil {
  2639  		c.Fatal(err)
  2640  	}
  2641  	if id1 == id2 {
  2642  		c.Fatal("The cache should have been invalided but hasn't.")
  2643  	}
  2644  }
  2645  
  2646  func (s *DockerSuite) TestBuildConditionalCache(c *check.C) {
  2647  	testRequires(c, DaemonIsLinux)
  2648  	name := "testbuildconditionalcache"
  2649  
  2650  	dockerfile := `
  2651  		FROM busybox
  2652          ADD foo /tmp/`
  2653  	ctx, err := fakeContext(dockerfile, map[string]string{
  2654  		"foo": "hello",
  2655  	})
  2656  	if err != nil {
  2657  		c.Fatal(err)
  2658  	}
  2659  	defer ctx.Close()
  2660  
  2661  	id1, err := buildImageFromContext(name, ctx, true)
  2662  	if err != nil {
  2663  		c.Fatalf("Error building #1: %s", err)
  2664  	}
  2665  
  2666  	if err := ctx.Add("foo", "bye"); err != nil {
  2667  		c.Fatalf("Error modifying foo: %s", err)
  2668  	}
  2669  
  2670  	id2, err := buildImageFromContext(name, ctx, false)
  2671  	if err != nil {
  2672  		c.Fatalf("Error building #2: %s", err)
  2673  	}
  2674  	if id2 == id1 {
  2675  		c.Fatal("Should not have used the cache")
  2676  	}
  2677  
  2678  	id3, err := buildImageFromContext(name, ctx, true)
  2679  	if err != nil {
  2680  		c.Fatalf("Error building #3: %s", err)
  2681  	}
  2682  	if id3 != id2 {
  2683  		c.Fatal("Should have used the cache")
  2684  	}
  2685  }
  2686  
  2687  func (s *DockerSuite) TestBuildAddLocalFileWithCache(c *check.C) {
  2688  	// local files are not owned by the correct user
  2689  	testRequires(c, NotUserNamespace)
  2690  	testRequires(c, DaemonIsLinux)
  2691  	name := "testbuildaddlocalfilewithcache"
  2692  	name2 := "testbuildaddlocalfilewithcache2"
  2693  	dockerfile := `
  2694  		FROM busybox
  2695          MAINTAINER dockerio
  2696          ADD foo /usr/lib/bla/bar
  2697  		RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2698  	ctx, err := fakeContext(dockerfile, map[string]string{
  2699  		"foo": "hello",
  2700  	})
  2701  	if err != nil {
  2702  		c.Fatal(err)
  2703  	}
  2704  	defer ctx.Close()
  2705  	id1, err := buildImageFromContext(name, ctx, true)
  2706  	if err != nil {
  2707  		c.Fatal(err)
  2708  	}
  2709  	id2, err := buildImageFromContext(name2, ctx, true)
  2710  	if err != nil {
  2711  		c.Fatal(err)
  2712  	}
  2713  	if id1 != id2 {
  2714  		c.Fatal("The cache should have been used but hasn't.")
  2715  	}
  2716  }
  2717  
  2718  func (s *DockerSuite) TestBuildAddMultipleLocalFileWithCache(c *check.C) {
  2719  	testRequires(c, DaemonIsLinux)
  2720  	name := "testbuildaddmultiplelocalfilewithcache"
  2721  	name2 := "testbuildaddmultiplelocalfilewithcache2"
  2722  	dockerfile := `
  2723  		FROM busybox
  2724          MAINTAINER dockerio
  2725          ADD foo Dockerfile /usr/lib/bla/
  2726  		RUN [ "$(cat /usr/lib/bla/foo)" = "hello" ]`
  2727  	ctx, err := fakeContext(dockerfile, map[string]string{
  2728  		"foo": "hello",
  2729  	})
  2730  	if err != nil {
  2731  		c.Fatal(err)
  2732  	}
  2733  	defer ctx.Close()
  2734  	id1, err := buildImageFromContext(name, ctx, true)
  2735  	if err != nil {
  2736  		c.Fatal(err)
  2737  	}
  2738  	id2, err := buildImageFromContext(name2, ctx, true)
  2739  	if err != nil {
  2740  		c.Fatal(err)
  2741  	}
  2742  	if id1 != id2 {
  2743  		c.Fatal("The cache should have been used but hasn't.")
  2744  	}
  2745  }
  2746  
  2747  func (s *DockerSuite) TestBuildAddLocalFileWithoutCache(c *check.C) {
  2748  	// local files are not owned by the correct user
  2749  	testRequires(c, NotUserNamespace)
  2750  	testRequires(c, DaemonIsLinux)
  2751  	name := "testbuildaddlocalfilewithoutcache"
  2752  	name2 := "testbuildaddlocalfilewithoutcache2"
  2753  	dockerfile := `
  2754  		FROM busybox
  2755          MAINTAINER dockerio
  2756          ADD foo /usr/lib/bla/bar
  2757  		RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2758  	ctx, err := fakeContext(dockerfile, map[string]string{
  2759  		"foo": "hello",
  2760  	})
  2761  	if err != nil {
  2762  		c.Fatal(err)
  2763  	}
  2764  	defer ctx.Close()
  2765  	id1, err := buildImageFromContext(name, ctx, true)
  2766  	if err != nil {
  2767  		c.Fatal(err)
  2768  	}
  2769  	id2, err := buildImageFromContext(name2, ctx, false)
  2770  	if err != nil {
  2771  		c.Fatal(err)
  2772  	}
  2773  	if id1 == id2 {
  2774  		c.Fatal("The cache should have been invalided but hasn't.")
  2775  	}
  2776  }
  2777  
  2778  func (s *DockerSuite) TestBuildCopyDirButNotFile(c *check.C) {
  2779  	testRequires(c, DaemonIsLinux)
  2780  	name := "testbuildcopydirbutnotfile"
  2781  	name2 := "testbuildcopydirbutnotfile2"
  2782  	dockerfile := `
  2783          FROM scratch
  2784          COPY dir /tmp/`
  2785  	ctx, err := fakeContext(dockerfile, map[string]string{
  2786  		"dir/foo": "hello",
  2787  	})
  2788  	if err != nil {
  2789  		c.Fatal(err)
  2790  	}
  2791  	defer ctx.Close()
  2792  	id1, err := buildImageFromContext(name, ctx, true)
  2793  	if err != nil {
  2794  		c.Fatal(err)
  2795  	}
  2796  	// Check that adding file with similar name doesn't mess with cache
  2797  	if err := ctx.Add("dir_file", "hello2"); err != nil {
  2798  		c.Fatal(err)
  2799  	}
  2800  	id2, err := buildImageFromContext(name2, ctx, true)
  2801  	if err != nil {
  2802  		c.Fatal(err)
  2803  	}
  2804  	if id1 != id2 {
  2805  		c.Fatal("The cache should have been used but wasn't")
  2806  	}
  2807  }
  2808  
  2809  func (s *DockerSuite) TestBuildAddCurrentDirWithCache(c *check.C) {
  2810  	testRequires(c, DaemonIsLinux)
  2811  	name := "testbuildaddcurrentdirwithcache"
  2812  	name2 := name + "2"
  2813  	name3 := name + "3"
  2814  	name4 := name + "4"
  2815  	dockerfile := `
  2816          FROM scratch
  2817          MAINTAINER dockerio
  2818          ADD . /usr/lib/bla`
  2819  	ctx, err := fakeContext(dockerfile, map[string]string{
  2820  		"foo": "hello",
  2821  	})
  2822  	if err != nil {
  2823  		c.Fatal(err)
  2824  	}
  2825  	defer ctx.Close()
  2826  	id1, err := buildImageFromContext(name, ctx, true)
  2827  	if err != nil {
  2828  		c.Fatal(err)
  2829  	}
  2830  	// Check that adding file invalidate cache of "ADD ."
  2831  	if err := ctx.Add("bar", "hello2"); err != nil {
  2832  		c.Fatal(err)
  2833  	}
  2834  	id2, err := buildImageFromContext(name2, ctx, true)
  2835  	if err != nil {
  2836  		c.Fatal(err)
  2837  	}
  2838  	if id1 == id2 {
  2839  		c.Fatal("The cache should have been invalided but hasn't.")
  2840  	}
  2841  	// Check that changing file invalidate cache of "ADD ."
  2842  	if err := ctx.Add("foo", "hello1"); err != nil {
  2843  		c.Fatal(err)
  2844  	}
  2845  	id3, err := buildImageFromContext(name3, ctx, true)
  2846  	if err != nil {
  2847  		c.Fatal(err)
  2848  	}
  2849  	if id2 == id3 {
  2850  		c.Fatal("The cache should have been invalided but hasn't.")
  2851  	}
  2852  	// Check that changing file to same content with different mtime does not
  2853  	// invalidate cache of "ADD ."
  2854  	time.Sleep(1 * time.Second) // wait second because of mtime precision
  2855  	if err := ctx.Add("foo", "hello1"); err != nil {
  2856  		c.Fatal(err)
  2857  	}
  2858  	id4, err := buildImageFromContext(name4, ctx, true)
  2859  	if err != nil {
  2860  		c.Fatal(err)
  2861  	}
  2862  	if id3 != id4 {
  2863  		c.Fatal("The cache should have been used but hasn't.")
  2864  	}
  2865  }
  2866  
  2867  func (s *DockerSuite) TestBuildAddCurrentDirWithoutCache(c *check.C) {
  2868  	testRequires(c, DaemonIsLinux)
  2869  	name := "testbuildaddcurrentdirwithoutcache"
  2870  	name2 := "testbuildaddcurrentdirwithoutcache2"
  2871  	dockerfile := `
  2872          FROM scratch
  2873          MAINTAINER dockerio
  2874          ADD . /usr/lib/bla`
  2875  	ctx, err := fakeContext(dockerfile, map[string]string{
  2876  		"foo": "hello",
  2877  	})
  2878  	if err != nil {
  2879  		c.Fatal(err)
  2880  	}
  2881  	defer ctx.Close()
  2882  	id1, err := buildImageFromContext(name, ctx, true)
  2883  	if err != nil {
  2884  		c.Fatal(err)
  2885  	}
  2886  	id2, err := buildImageFromContext(name2, ctx, false)
  2887  	if err != nil {
  2888  		c.Fatal(err)
  2889  	}
  2890  	if id1 == id2 {
  2891  		c.Fatal("The cache should have been invalided but hasn't.")
  2892  	}
  2893  }
  2894  
  2895  func (s *DockerSuite) TestBuildAddRemoteFileWithCache(c *check.C) {
  2896  	testRequires(c, DaemonIsLinux)
  2897  	name := "testbuildaddremotefilewithcache"
  2898  	server, err := fakeStorage(map[string]string{
  2899  		"baz": "hello",
  2900  	})
  2901  	if err != nil {
  2902  		c.Fatal(err)
  2903  	}
  2904  	defer server.Close()
  2905  
  2906  	id1, err := buildImage(name,
  2907  		fmt.Sprintf(`FROM scratch
  2908          MAINTAINER dockerio
  2909          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2910  		true)
  2911  	if err != nil {
  2912  		c.Fatal(err)
  2913  	}
  2914  	id2, err := buildImage(name,
  2915  		fmt.Sprintf(`FROM scratch
  2916          MAINTAINER dockerio
  2917          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2918  		true)
  2919  	if err != nil {
  2920  		c.Fatal(err)
  2921  	}
  2922  	if id1 != id2 {
  2923  		c.Fatal("The cache should have been used but hasn't.")
  2924  	}
  2925  }
  2926  
  2927  func (s *DockerSuite) TestBuildAddRemoteFileWithoutCache(c *check.C) {
  2928  	testRequires(c, DaemonIsLinux)
  2929  	name := "testbuildaddremotefilewithoutcache"
  2930  	name2 := "testbuildaddremotefilewithoutcache2"
  2931  	server, err := fakeStorage(map[string]string{
  2932  		"baz": "hello",
  2933  	})
  2934  	if err != nil {
  2935  		c.Fatal(err)
  2936  	}
  2937  	defer server.Close()
  2938  
  2939  	id1, err := buildImage(name,
  2940  		fmt.Sprintf(`FROM scratch
  2941          MAINTAINER dockerio
  2942          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2943  		true)
  2944  	if err != nil {
  2945  		c.Fatal(err)
  2946  	}
  2947  	id2, err := buildImage(name2,
  2948  		fmt.Sprintf(`FROM scratch
  2949          MAINTAINER dockerio
  2950          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2951  		false)
  2952  	if err != nil {
  2953  		c.Fatal(err)
  2954  	}
  2955  	if id1 == id2 {
  2956  		c.Fatal("The cache should have been invalided but hasn't.")
  2957  	}
  2958  }
  2959  
  2960  func (s *DockerSuite) TestBuildAddRemoteFileMTime(c *check.C) {
  2961  	testRequires(c, DaemonIsLinux)
  2962  	name := "testbuildaddremotefilemtime"
  2963  	name2 := name + "2"
  2964  	name3 := name + "3"
  2965  
  2966  	files := map[string]string{"baz": "hello"}
  2967  	server, err := fakeStorage(files)
  2968  	if err != nil {
  2969  		c.Fatal(err)
  2970  	}
  2971  	defer server.Close()
  2972  
  2973  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2974          MAINTAINER dockerio
  2975          ADD %s/baz /usr/lib/baz/quux`, server.URL()), nil)
  2976  	if err != nil {
  2977  		c.Fatal(err)
  2978  	}
  2979  	defer ctx.Close()
  2980  
  2981  	id1, err := buildImageFromContext(name, ctx, true)
  2982  	if err != nil {
  2983  		c.Fatal(err)
  2984  	}
  2985  
  2986  	id2, err := buildImageFromContext(name2, ctx, true)
  2987  	if err != nil {
  2988  		c.Fatal(err)
  2989  	}
  2990  	if id1 != id2 {
  2991  		c.Fatal("The cache should have been used but wasn't - #1")
  2992  	}
  2993  
  2994  	// Now create a different server with same contents (causes different mtime)
  2995  	// The cache should still be used
  2996  
  2997  	// allow some time for clock to pass as mtime precision is only 1s
  2998  	time.Sleep(2 * time.Second)
  2999  
  3000  	server2, err := fakeStorage(files)
  3001  	if err != nil {
  3002  		c.Fatal(err)
  3003  	}
  3004  	defer server2.Close()
  3005  
  3006  	ctx2, err := fakeContext(fmt.Sprintf(`FROM scratch
  3007          MAINTAINER dockerio
  3008          ADD %s/baz /usr/lib/baz/quux`, server2.URL()), nil)
  3009  	if err != nil {
  3010  		c.Fatal(err)
  3011  	}
  3012  	defer ctx2.Close()
  3013  	id3, err := buildImageFromContext(name3, ctx2, true)
  3014  	if err != nil {
  3015  		c.Fatal(err)
  3016  	}
  3017  	if id1 != id3 {
  3018  		c.Fatal("The cache should have been used but wasn't")
  3019  	}
  3020  }
  3021  
  3022  func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithCache(c *check.C) {
  3023  	testRequires(c, DaemonIsLinux)
  3024  	name := "testbuildaddlocalandremotefilewithcache"
  3025  	server, err := fakeStorage(map[string]string{
  3026  		"baz": "hello",
  3027  	})
  3028  	if err != nil {
  3029  		c.Fatal(err)
  3030  	}
  3031  	defer server.Close()
  3032  
  3033  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  3034          MAINTAINER dockerio
  3035          ADD foo /usr/lib/bla/bar
  3036          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  3037  		map[string]string{
  3038  			"foo": "hello world",
  3039  		})
  3040  	if err != nil {
  3041  		c.Fatal(err)
  3042  	}
  3043  	defer ctx.Close()
  3044  	id1, err := buildImageFromContext(name, ctx, true)
  3045  	if err != nil {
  3046  		c.Fatal(err)
  3047  	}
  3048  	id2, err := buildImageFromContext(name, ctx, true)
  3049  	if err != nil {
  3050  		c.Fatal(err)
  3051  	}
  3052  	if id1 != id2 {
  3053  		c.Fatal("The cache should have been used but hasn't.")
  3054  	}
  3055  }
  3056  
  3057  func testContextTar(c *check.C, compression archive.Compression) {
  3058  	testRequires(c, DaemonIsLinux)
  3059  	ctx, err := fakeContext(
  3060  		`FROM busybox
  3061  ADD foo /foo
  3062  CMD ["cat", "/foo"]`,
  3063  		map[string]string{
  3064  			"foo": "bar",
  3065  		},
  3066  	)
  3067  	if err != nil {
  3068  		c.Fatal(err)
  3069  	}
  3070  	defer ctx.Close()
  3071  	context, err := archive.Tar(ctx.Dir, compression)
  3072  	if err != nil {
  3073  		c.Fatalf("failed to build context tar: %v", err)
  3074  	}
  3075  	name := "contexttar"
  3076  	buildCmd := exec.Command(dockerBinary, "build", "-t", name, "-")
  3077  	buildCmd.Stdin = context
  3078  
  3079  	if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  3080  		c.Fatalf("build failed to complete: %v %v", out, err)
  3081  	}
  3082  }
  3083  
  3084  func (s *DockerSuite) TestBuildContextTarGzip(c *check.C) {
  3085  	testContextTar(c, archive.Gzip)
  3086  }
  3087  
  3088  func (s *DockerSuite) TestBuildContextTarNoCompression(c *check.C) {
  3089  	testContextTar(c, archive.Uncompressed)
  3090  }
  3091  
  3092  func (s *DockerSuite) TestBuildNoContext(c *check.C) {
  3093  	testRequires(c, DaemonIsLinux)
  3094  	buildCmd := exec.Command(dockerBinary, "build", "-t", "nocontext", "-")
  3095  	buildCmd.Stdin = strings.NewReader("FROM busybox\nCMD echo ok\n")
  3096  
  3097  	if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  3098  		c.Fatalf("build failed to complete: %v %v", out, err)
  3099  	}
  3100  
  3101  	if out, _ := dockerCmd(c, "run", "--rm", "nocontext"); out != "ok\n" {
  3102  		c.Fatalf("run produced invalid output: %q, expected %q", out, "ok")
  3103  	}
  3104  }
  3105  
  3106  // TODO: TestCaching
  3107  func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithoutCache(c *check.C) {
  3108  	testRequires(c, DaemonIsLinux)
  3109  	name := "testbuildaddlocalandremotefilewithoutcache"
  3110  	name2 := "testbuildaddlocalandremotefilewithoutcache2"
  3111  	server, err := fakeStorage(map[string]string{
  3112  		"baz": "hello",
  3113  	})
  3114  	if err != nil {
  3115  		c.Fatal(err)
  3116  	}
  3117  	defer server.Close()
  3118  
  3119  	ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  3120          MAINTAINER dockerio
  3121          ADD foo /usr/lib/bla/bar
  3122          ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  3123  		map[string]string{
  3124  			"foo": "hello world",
  3125  		})
  3126  	if err != nil {
  3127  		c.Fatal(err)
  3128  	}
  3129  	defer ctx.Close()
  3130  	id1, err := buildImageFromContext(name, ctx, true)
  3131  	if err != nil {
  3132  		c.Fatal(err)
  3133  	}
  3134  	id2, err := buildImageFromContext(name2, ctx, false)
  3135  	if err != nil {
  3136  		c.Fatal(err)
  3137  	}
  3138  	if id1 == id2 {
  3139  		c.Fatal("The cache should have been invalided but hasn't.")
  3140  	}
  3141  }
  3142  
  3143  func (s *DockerSuite) TestBuildWithVolumeOwnership(c *check.C) {
  3144  	testRequires(c, DaemonIsLinux)
  3145  	name := "testbuildimg"
  3146  
  3147  	_, err := buildImage(name,
  3148  		`FROM busybox:latest
  3149          RUN mkdir /test && chown daemon:daemon /test && chmod 0600 /test
  3150          VOLUME /test`,
  3151  		true)
  3152  
  3153  	if err != nil {
  3154  		c.Fatal(err)
  3155  	}
  3156  
  3157  	out, _ := dockerCmd(c, "run", "--rm", "testbuildimg", "ls", "-la", "/test")
  3158  
  3159  	if expected := "drw-------"; !strings.Contains(out, expected) {
  3160  		c.Fatalf("expected %s received %s", expected, out)
  3161  	}
  3162  
  3163  	if expected := "daemon   daemon"; !strings.Contains(out, expected) {
  3164  		c.Fatalf("expected %s received %s", expected, out)
  3165  	}
  3166  
  3167  }
  3168  
  3169  // testing #1405 - config.Cmd does not get cleaned up if
  3170  // utilizing cache
  3171  func (s *DockerSuite) TestBuildEntrypointRunCleanup(c *check.C) {
  3172  	testRequires(c, DaemonIsLinux)
  3173  	name := "testbuildcmdcleanup"
  3174  	if _, err := buildImage(name,
  3175  		`FROM busybox
  3176          RUN echo "hello"`,
  3177  		true); err != nil {
  3178  		c.Fatal(err)
  3179  	}
  3180  
  3181  	ctx, err := fakeContext(`FROM busybox
  3182          RUN echo "hello"
  3183          ADD foo /foo
  3184          ENTRYPOINT ["/bin/echo"]`,
  3185  		map[string]string{
  3186  			"foo": "hello",
  3187  		})
  3188  	if err != nil {
  3189  		c.Fatal(err)
  3190  	}
  3191  	defer ctx.Close()
  3192  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3193  		c.Fatal(err)
  3194  	}
  3195  	res, err := inspectField(name, "Config.Cmd")
  3196  	if err != nil {
  3197  		c.Fatal(err)
  3198  	}
  3199  	// Cmd must be cleaned up
  3200  	if res != "<nil>" {
  3201  		c.Fatalf("Cmd %s, expected nil", res)
  3202  	}
  3203  }
  3204  
  3205  func (s *DockerSuite) TestBuildForbiddenContextPath(c *check.C) {
  3206  	testRequires(c, DaemonIsLinux)
  3207  	name := "testbuildforbidpath"
  3208  	ctx, err := fakeContext(`FROM scratch
  3209          ADD ../../ test/
  3210          `,
  3211  		map[string]string{
  3212  			"test.txt":  "test1",
  3213  			"other.txt": "other",
  3214  		})
  3215  	if err != nil {
  3216  		c.Fatal(err)
  3217  	}
  3218  	defer ctx.Close()
  3219  
  3220  	expected := "Forbidden path outside the build context: ../../ "
  3221  	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  3222  		c.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
  3223  	}
  3224  
  3225  }
  3226  
  3227  func (s *DockerSuite) TestBuildAddFileNotFound(c *check.C) {
  3228  	testRequires(c, DaemonIsLinux)
  3229  	name := "testbuildaddnotfound"
  3230  	ctx, err := fakeContext(`FROM scratch
  3231          ADD foo /usr/local/bar`,
  3232  		map[string]string{"bar": "hello"})
  3233  	if err != nil {
  3234  		c.Fatal(err)
  3235  	}
  3236  	defer ctx.Close()
  3237  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3238  		if !strings.Contains(err.Error(), "foo: no such file or directory") {
  3239  			c.Fatalf("Wrong error %v, must be about missing foo file or directory", err)
  3240  		}
  3241  	} else {
  3242  		c.Fatal("Error must not be nil")
  3243  	}
  3244  }
  3245  
  3246  func (s *DockerSuite) TestBuildInheritance(c *check.C) {
  3247  	testRequires(c, DaemonIsLinux)
  3248  	name := "testbuildinheritance"
  3249  
  3250  	_, err := buildImage(name,
  3251  		`FROM scratch
  3252  		EXPOSE 2375`,
  3253  		true)
  3254  	if err != nil {
  3255  		c.Fatal(err)
  3256  	}
  3257  	ports1, err := inspectField(name, "Config.ExposedPorts")
  3258  	if err != nil {
  3259  		c.Fatal(err)
  3260  	}
  3261  
  3262  	_, err = buildImage(name,
  3263  		fmt.Sprintf(`FROM %s
  3264  		ENTRYPOINT ["/bin/echo"]`, name),
  3265  		true)
  3266  	if err != nil {
  3267  		c.Fatal(err)
  3268  	}
  3269  
  3270  	res, err := inspectField(name, "Config.Entrypoint")
  3271  	if err != nil {
  3272  		c.Fatal(err)
  3273  	}
  3274  	if expected := "{[/bin/echo]}"; res != expected {
  3275  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  3276  	}
  3277  	ports2, err := inspectField(name, "Config.ExposedPorts")
  3278  	if err != nil {
  3279  		c.Fatal(err)
  3280  	}
  3281  	if ports1 != ports2 {
  3282  		c.Fatalf("Ports must be same: %s != %s", ports1, ports2)
  3283  	}
  3284  }
  3285  
  3286  func (s *DockerSuite) TestBuildFails(c *check.C) {
  3287  	testRequires(c, DaemonIsLinux)
  3288  	name := "testbuildfails"
  3289  	_, err := buildImage(name,
  3290  		`FROM busybox
  3291  		RUN sh -c "exit 23"`,
  3292  		true)
  3293  	if err != nil {
  3294  		if !strings.Contains(err.Error(), "returned a non-zero code: 23") {
  3295  			c.Fatalf("Wrong error %v, must be about non-zero code 23", err)
  3296  		}
  3297  	} else {
  3298  		c.Fatal("Error must not be nil")
  3299  	}
  3300  }
  3301  
  3302  func (s *DockerSuite) TestBuildFailsDockerfileEmpty(c *check.C) {
  3303  	name := "testbuildfails"
  3304  	_, err := buildImage(name, ``, true)
  3305  	if err != nil {
  3306  		if !strings.Contains(err.Error(), "The Dockerfile (Dockerfile) cannot be empty") {
  3307  			c.Fatalf("Wrong error %v, must be about empty Dockerfile", err)
  3308  		}
  3309  	} else {
  3310  		c.Fatal("Error must not be nil")
  3311  	}
  3312  }
  3313  
  3314  func (s *DockerSuite) TestBuildOnBuild(c *check.C) {
  3315  	testRequires(c, DaemonIsLinux)
  3316  	name := "testbuildonbuild"
  3317  	_, err := buildImage(name,
  3318  		`FROM busybox
  3319  		ONBUILD RUN touch foobar`,
  3320  		true)
  3321  	if err != nil {
  3322  		c.Fatal(err)
  3323  	}
  3324  	_, err = buildImage(name,
  3325  		fmt.Sprintf(`FROM %s
  3326  		RUN [ -f foobar ]`, name),
  3327  		true)
  3328  	if err != nil {
  3329  		c.Fatal(err)
  3330  	}
  3331  }
  3332  
  3333  func (s *DockerSuite) TestBuildOnBuildForbiddenChained(c *check.C) {
  3334  	testRequires(c, DaemonIsLinux)
  3335  	name := "testbuildonbuildforbiddenchained"
  3336  	_, err := buildImage(name,
  3337  		`FROM busybox
  3338  		ONBUILD ONBUILD RUN touch foobar`,
  3339  		true)
  3340  	if err != nil {
  3341  		if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
  3342  			c.Fatalf("Wrong error %v, must be about chaining ONBUILD", err)
  3343  		}
  3344  	} else {
  3345  		c.Fatal("Error must not be nil")
  3346  	}
  3347  }
  3348  
  3349  func (s *DockerSuite) TestBuildOnBuildForbiddenFrom(c *check.C) {
  3350  	testRequires(c, DaemonIsLinux)
  3351  	name := "testbuildonbuildforbiddenfrom"
  3352  	_, err := buildImage(name,
  3353  		`FROM busybox
  3354  		ONBUILD FROM scratch`,
  3355  		true)
  3356  	if err != nil {
  3357  		if !strings.Contains(err.Error(), "FROM isn't allowed as an ONBUILD trigger") {
  3358  			c.Fatalf("Wrong error %v, must be about FROM forbidden", err)
  3359  		}
  3360  	} else {
  3361  		c.Fatal("Error must not be nil")
  3362  	}
  3363  }
  3364  
  3365  func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainer(c *check.C) {
  3366  	testRequires(c, DaemonIsLinux)
  3367  	name := "testbuildonbuildforbiddenmaintainer"
  3368  	_, err := buildImage(name,
  3369  		`FROM busybox
  3370  		ONBUILD MAINTAINER docker.io`,
  3371  		true)
  3372  	if err != nil {
  3373  		if !strings.Contains(err.Error(), "MAINTAINER isn't allowed as an ONBUILD trigger") {
  3374  			c.Fatalf("Wrong error %v, must be about MAINTAINER forbidden", err)
  3375  		}
  3376  	} else {
  3377  		c.Fatal("Error must not be nil")
  3378  	}
  3379  }
  3380  
  3381  // gh #2446
  3382  func (s *DockerSuite) TestBuildAddToSymlinkDest(c *check.C) {
  3383  	testRequires(c, DaemonIsLinux)
  3384  	name := "testbuildaddtosymlinkdest"
  3385  	ctx, err := fakeContext(`FROM busybox
  3386          RUN mkdir /foo
  3387          RUN ln -s /foo /bar
  3388          ADD foo /bar/
  3389          RUN [ -f /bar/foo ]
  3390          RUN [ -f /foo/foo ]`,
  3391  		map[string]string{
  3392  			"foo": "hello",
  3393  		})
  3394  	if err != nil {
  3395  		c.Fatal(err)
  3396  	}
  3397  	defer ctx.Close()
  3398  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3399  		c.Fatal(err)
  3400  	}
  3401  }
  3402  
  3403  func (s *DockerSuite) TestBuildEscapeWhitespace(c *check.C) {
  3404  	testRequires(c, DaemonIsLinux)
  3405  	name := "testbuildescaping"
  3406  
  3407  	_, err := buildImage(name, `
  3408    FROM busybox
  3409    MAINTAINER "Docker \
  3410  IO <io@\
  3411  docker.com>"
  3412    `, true)
  3413  	if err != nil {
  3414  		c.Fatal(err)
  3415  	}
  3416  
  3417  	res, err := inspectField(name, "Author")
  3418  
  3419  	if err != nil {
  3420  		c.Fatal(err)
  3421  	}
  3422  
  3423  	if res != "\"Docker IO <io@docker.com>\"" {
  3424  		c.Fatalf("Parsed string did not match the escaped string. Got: %q", res)
  3425  	}
  3426  
  3427  }
  3428  
  3429  func (s *DockerSuite) TestBuildVerifyIntString(c *check.C) {
  3430  	testRequires(c, DaemonIsLinux)
  3431  	// Verify that strings that look like ints are still passed as strings
  3432  	name := "testbuildstringing"
  3433  
  3434  	_, err := buildImage(name, `
  3435    FROM busybox
  3436    MAINTAINER 123
  3437    `, true)
  3438  
  3439  	if err != nil {
  3440  		c.Fatal(err)
  3441  	}
  3442  
  3443  	out, _ := dockerCmd(c, "inspect", name)
  3444  
  3445  	if !strings.Contains(out, "\"123\"") {
  3446  		c.Fatalf("Output does not contain the int as a string:\n%s", out)
  3447  	}
  3448  
  3449  }
  3450  
  3451  func (s *DockerSuite) TestBuildDockerignore(c *check.C) {
  3452  	testRequires(c, DaemonIsLinux)
  3453  	name := "testbuilddockerignore"
  3454  	dockerfile := `
  3455          FROM busybox
  3456          ADD . /bla
  3457  		RUN [[ -f /bla/src/x.go ]]
  3458  		RUN [[ -f /bla/Makefile ]]
  3459  		RUN [[ ! -e /bla/src/_vendor ]]
  3460  		RUN [[ ! -e /bla/.gitignore ]]
  3461  		RUN [[ ! -e /bla/README.md ]]
  3462  		RUN [[ ! -e /bla/dir/foo ]]
  3463  		RUN [[ ! -e /bla/foo ]]
  3464  		RUN [[ ! -e /bla/.git ]]`
  3465  	ctx, err := fakeContext(dockerfile, map[string]string{
  3466  		"Makefile":         "all:",
  3467  		".git/HEAD":        "ref: foo",
  3468  		"src/x.go":         "package main",
  3469  		"src/_vendor/v.go": "package main",
  3470  		"dir/foo":          "",
  3471  		".gitignore":       "",
  3472  		"README.md":        "readme",
  3473  		".dockerignore": `
  3474  .git
  3475  pkg
  3476  .gitignore
  3477  src/_vendor
  3478  *.md
  3479  dir`,
  3480  	})
  3481  	if err != nil {
  3482  		c.Fatal(err)
  3483  	}
  3484  	defer ctx.Close()
  3485  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3486  		c.Fatal(err)
  3487  	}
  3488  }
  3489  
  3490  func (s *DockerSuite) TestBuildDockerignoreCleanPaths(c *check.C) {
  3491  	testRequires(c, DaemonIsLinux)
  3492  	name := "testbuilddockerignorecleanpaths"
  3493  	dockerfile := `
  3494          FROM busybox
  3495          ADD . /tmp/
  3496          RUN (! ls /tmp/foo) && (! ls /tmp/foo2) && (! ls /tmp/dir1/foo)`
  3497  	ctx, err := fakeContext(dockerfile, map[string]string{
  3498  		"foo":           "foo",
  3499  		"foo2":          "foo2",
  3500  		"dir1/foo":      "foo in dir1",
  3501  		".dockerignore": "./foo\ndir1//foo\n./dir1/../foo2",
  3502  	})
  3503  	if err != nil {
  3504  		c.Fatal(err)
  3505  	}
  3506  	defer ctx.Close()
  3507  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3508  		c.Fatal(err)
  3509  	}
  3510  }
  3511  
  3512  func (s *DockerSuite) TestBuildDockerignoreExceptions(c *check.C) {
  3513  	testRequires(c, DaemonIsLinux)
  3514  	name := "testbuilddockerignoreexceptions"
  3515  	dockerfile := `
  3516          FROM busybox
  3517          ADD . /bla
  3518  		RUN [[ -f /bla/src/x.go ]]
  3519  		RUN [[ -f /bla/Makefile ]]
  3520  		RUN [[ ! -e /bla/src/_vendor ]]
  3521  		RUN [[ ! -e /bla/.gitignore ]]
  3522  		RUN [[ ! -e /bla/README.md ]]
  3523  		RUN [[  -e /bla/dir/dir/foo ]]
  3524  		RUN [[ ! -e /bla/dir/foo1 ]]
  3525  		RUN [[ -f /bla/dir/e ]]
  3526  		RUN [[ -f /bla/dir/e-dir/foo ]]
  3527  		RUN [[ ! -e /bla/foo ]]
  3528  		RUN [[ ! -e /bla/.git ]]`
  3529  	ctx, err := fakeContext(dockerfile, map[string]string{
  3530  		"Makefile":         "all:",
  3531  		".git/HEAD":        "ref: foo",
  3532  		"src/x.go":         "package main",
  3533  		"src/_vendor/v.go": "package main",
  3534  		"dir/foo":          "",
  3535  		"dir/foo1":         "",
  3536  		"dir/dir/f1":       "",
  3537  		"dir/dir/foo":      "",
  3538  		"dir/e":            "",
  3539  		"dir/e-dir/foo":    "",
  3540  		".gitignore":       "",
  3541  		"README.md":        "readme",
  3542  		".dockerignore": `
  3543  .git
  3544  pkg
  3545  .gitignore
  3546  src/_vendor
  3547  *.md
  3548  dir
  3549  !dir/e*
  3550  !dir/dir/foo`,
  3551  	})
  3552  	if err != nil {
  3553  		c.Fatal(err)
  3554  	}
  3555  	defer ctx.Close()
  3556  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3557  		c.Fatal(err)
  3558  	}
  3559  }
  3560  
  3561  func (s *DockerSuite) TestBuildDockerignoringDockerfile(c *check.C) {
  3562  	testRequires(c, DaemonIsLinux)
  3563  	name := "testbuilddockerignoredockerfile"
  3564  	dockerfile := `
  3565          FROM busybox
  3566  		ADD . /tmp/
  3567  		RUN ! ls /tmp/Dockerfile
  3568  		RUN ls /tmp/.dockerignore`
  3569  	ctx, err := fakeContext(dockerfile, map[string]string{
  3570  		"Dockerfile":    dockerfile,
  3571  		".dockerignore": "Dockerfile\n",
  3572  	})
  3573  	if err != nil {
  3574  		c.Fatal(err)
  3575  	}
  3576  	defer ctx.Close()
  3577  
  3578  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3579  		c.Fatalf("Didn't ignore Dockerfile correctly:%s", err)
  3580  	}
  3581  
  3582  	// now try it with ./Dockerfile
  3583  	ctx.Add(".dockerignore", "./Dockerfile\n")
  3584  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3585  		c.Fatalf("Didn't ignore ./Dockerfile correctly:%s", err)
  3586  	}
  3587  
  3588  }
  3589  
  3590  func (s *DockerSuite) TestBuildDockerignoringRenamedDockerfile(c *check.C) {
  3591  	testRequires(c, DaemonIsLinux)
  3592  	name := "testbuilddockerignoredockerfile"
  3593  	dockerfile := `
  3594          FROM busybox
  3595  		ADD . /tmp/
  3596  		RUN ls /tmp/Dockerfile
  3597  		RUN ! ls /tmp/MyDockerfile
  3598  		RUN ls /tmp/.dockerignore`
  3599  	ctx, err := fakeContext(dockerfile, map[string]string{
  3600  		"Dockerfile":    "Should not use me",
  3601  		"MyDockerfile":  dockerfile,
  3602  		".dockerignore": "MyDockerfile\n",
  3603  	})
  3604  	if err != nil {
  3605  		c.Fatal(err)
  3606  	}
  3607  	defer ctx.Close()
  3608  
  3609  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3610  		c.Fatalf("Didn't ignore MyDockerfile correctly:%s", err)
  3611  	}
  3612  
  3613  	// now try it with ./MyDockerfile
  3614  	ctx.Add(".dockerignore", "./MyDockerfile\n")
  3615  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3616  		c.Fatalf("Didn't ignore ./MyDockerfile correctly:%s", err)
  3617  	}
  3618  
  3619  }
  3620  
  3621  func (s *DockerSuite) TestBuildDockerignoringDockerignore(c *check.C) {
  3622  	testRequires(c, DaemonIsLinux)
  3623  	name := "testbuilddockerignoredockerignore"
  3624  	dockerfile := `
  3625          FROM busybox
  3626  		ADD . /tmp/
  3627  		RUN ! ls /tmp/.dockerignore
  3628  		RUN ls /tmp/Dockerfile`
  3629  	ctx, err := fakeContext(dockerfile, map[string]string{
  3630  		"Dockerfile":    dockerfile,
  3631  		".dockerignore": ".dockerignore\n",
  3632  	})
  3633  	if err != nil {
  3634  		c.Fatal(err)
  3635  	}
  3636  	defer ctx.Close()
  3637  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3638  		c.Fatalf("Didn't ignore .dockerignore correctly:%s", err)
  3639  	}
  3640  }
  3641  
  3642  func (s *DockerSuite) TestBuildDockerignoreTouchDockerfile(c *check.C) {
  3643  	testRequires(c, DaemonIsLinux)
  3644  	var id1 string
  3645  	var id2 string
  3646  
  3647  	name := "testbuilddockerignoretouchdockerfile"
  3648  	dockerfile := `
  3649          FROM busybox
  3650  		ADD . /tmp/`
  3651  	ctx, err := fakeContext(dockerfile, map[string]string{
  3652  		"Dockerfile":    dockerfile,
  3653  		".dockerignore": "Dockerfile\n",
  3654  	})
  3655  	if err != nil {
  3656  		c.Fatal(err)
  3657  	}
  3658  	defer ctx.Close()
  3659  
  3660  	if id1, err = buildImageFromContext(name, ctx, true); err != nil {
  3661  		c.Fatalf("Didn't build it correctly:%s", err)
  3662  	}
  3663  
  3664  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3665  		c.Fatalf("Didn't build it correctly:%s", err)
  3666  	}
  3667  	if id1 != id2 {
  3668  		c.Fatalf("Didn't use the cache - 1")
  3669  	}
  3670  
  3671  	// Now make sure touching Dockerfile doesn't invalidate the cache
  3672  	if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3673  		c.Fatalf("Didn't add Dockerfile: %s", err)
  3674  	}
  3675  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3676  		c.Fatalf("Didn't build it correctly:%s", err)
  3677  	}
  3678  	if id1 != id2 {
  3679  		c.Fatalf("Didn't use the cache - 2")
  3680  	}
  3681  
  3682  	// One more time but just 'touch' it instead of changing the content
  3683  	if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3684  		c.Fatalf("Didn't add Dockerfile: %s", err)
  3685  	}
  3686  	if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3687  		c.Fatalf("Didn't build it correctly:%s", err)
  3688  	}
  3689  	if id1 != id2 {
  3690  		c.Fatalf("Didn't use the cache - 3")
  3691  	}
  3692  
  3693  }
  3694  
  3695  func (s *DockerSuite) TestBuildDockerignoringWholeDir(c *check.C) {
  3696  	testRequires(c, DaemonIsLinux)
  3697  	name := "testbuilddockerignorewholedir"
  3698  	dockerfile := `
  3699          FROM busybox
  3700  		COPY . /
  3701  		RUN [[ ! -e /.gitignore ]]
  3702  		RUN [[ -f /Makefile ]]`
  3703  	ctx, err := fakeContext(dockerfile, map[string]string{
  3704  		"Dockerfile":    "FROM scratch",
  3705  		"Makefile":      "all:",
  3706  		".gitignore":    "",
  3707  		".dockerignore": ".*\n",
  3708  	})
  3709  	c.Assert(err, check.IsNil)
  3710  	defer ctx.Close()
  3711  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3712  		c.Fatal(err)
  3713  	}
  3714  
  3715  	c.Assert(ctx.Add(".dockerfile", "*"), check.IsNil)
  3716  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3717  		c.Fatal(err)
  3718  	}
  3719  
  3720  	c.Assert(ctx.Add(".dockerfile", "."), check.IsNil)
  3721  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3722  		c.Fatal(err)
  3723  	}
  3724  
  3725  	c.Assert(ctx.Add(".dockerfile", "?"), check.IsNil)
  3726  	if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3727  		c.Fatal(err)
  3728  	}
  3729  }
  3730  
  3731  func (s *DockerSuite) TestBuildDockerignoringBadExclusion(c *check.C) {
  3732  	testRequires(c, DaemonIsLinux)
  3733  	name := "testbuilddockerignorewholedir"
  3734  	dockerfile := `
  3735          FROM busybox
  3736  		COPY . /
  3737  		RUN [[ ! -e /.gitignore ]]
  3738  		RUN [[ -f /Makefile ]]`
  3739  	ctx, err := fakeContext(dockerfile, map[string]string{
  3740  		"Dockerfile":    "FROM scratch",
  3741  		"Makefile":      "all:",
  3742  		".gitignore":    "",
  3743  		".dockerignore": "!\n",
  3744  	})
  3745  	c.Assert(err, check.IsNil)
  3746  	defer ctx.Close()
  3747  	if _, err = buildImageFromContext(name, ctx, true); err == nil {
  3748  		c.Fatalf("Build was supposed to fail but didn't")
  3749  	}
  3750  
  3751  	if err.Error() != "failed to build the image: Error checking context: 'Illegal exclusion pattern: !'.\n" {
  3752  		c.Fatalf("Incorrect output, got:%q", err.Error())
  3753  	}
  3754  }
  3755  
  3756  func (s *DockerSuite) TestBuildLineBreak(c *check.C) {
  3757  	testRequires(c, DaemonIsLinux)
  3758  	name := "testbuildlinebreak"
  3759  	_, err := buildImage(name,
  3760  		`FROM  busybox
  3761  RUN    sh -c 'echo root:testpass \
  3762  	> /tmp/passwd'
  3763  RUN    mkdir -p /var/run/sshd
  3764  RUN    [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3765  RUN    [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3766  		true)
  3767  	if err != nil {
  3768  		c.Fatal(err)
  3769  	}
  3770  }
  3771  
  3772  func (s *DockerSuite) TestBuildEOLInLine(c *check.C) {
  3773  	testRequires(c, DaemonIsLinux)
  3774  	name := "testbuildeolinline"
  3775  	_, err := buildImage(name,
  3776  		`FROM   busybox
  3777  RUN    sh -c 'echo root:testpass > /tmp/passwd'
  3778  RUN    echo "foo \n bar"; echo "baz"
  3779  RUN    mkdir -p /var/run/sshd
  3780  RUN    [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3781  RUN    [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3782  		true)
  3783  	if err != nil {
  3784  		c.Fatal(err)
  3785  	}
  3786  }
  3787  
  3788  func (s *DockerSuite) TestBuildCommentsShebangs(c *check.C) {
  3789  	testRequires(c, DaemonIsLinux)
  3790  	name := "testbuildcomments"
  3791  	_, err := buildImage(name,
  3792  		`FROM busybox
  3793  # This is an ordinary comment.
  3794  RUN { echo '#!/bin/sh'; echo 'echo hello world'; } > /hello.sh
  3795  RUN [ ! -x /hello.sh ]
  3796  # comment with line break \
  3797  RUN chmod +x /hello.sh
  3798  RUN [ -x /hello.sh ]
  3799  RUN [ "$(cat /hello.sh)" = $'#!/bin/sh\necho hello world' ]
  3800  RUN [ "$(/hello.sh)" = "hello world" ]`,
  3801  		true)
  3802  	if err != nil {
  3803  		c.Fatal(err)
  3804  	}
  3805  }
  3806  
  3807  func (s *DockerSuite) TestBuildUsersAndGroups(c *check.C) {
  3808  	testRequires(c, DaemonIsLinux)
  3809  	name := "testbuildusers"
  3810  	_, err := buildImage(name,
  3811  		`FROM busybox
  3812  
  3813  # Make sure our defaults work
  3814  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)" = '0:0/root:root' ]
  3815  
  3816  # 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)
  3817  USER root
  3818  RUN [ "$(id -G):$(id -Gn)" = '0 10:root wheel' ]
  3819  
  3820  # Setup dockerio user and group
  3821  RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  3822  RUN echo 'dockerio:x:1001:' >> /etc/group
  3823  
  3824  # Make sure we can switch to our user and all the information is exactly as we expect it to be
  3825  USER dockerio
  3826  RUN id -G
  3827  RUN id -Gn
  3828  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3829  
  3830  # Switch back to root and double check that worked exactly as we might expect it to
  3831  USER root
  3832  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '0:0/root:root/0 10:root wheel' ]
  3833  
  3834  # Add a "supplementary" group for our dockerio user
  3835  RUN echo 'supplementary:x:1002:dockerio' >> /etc/group
  3836  
  3837  # ... and then go verify that we get it like we expect
  3838  USER dockerio
  3839  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3840  USER 1001
  3841  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3842  
  3843  # super test the new "user:group" syntax
  3844  USER dockerio:dockerio
  3845  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3846  USER 1001:dockerio
  3847  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3848  USER dockerio:1001
  3849  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3850  USER 1001:1001
  3851  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3852  USER dockerio:supplementary
  3853  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3854  USER dockerio:1002
  3855  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3856  USER 1001:supplementary
  3857  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3858  USER 1001:1002
  3859  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3860  
  3861  # make sure unknown uid/gid still works properly
  3862  USER 1042:1043
  3863  RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1042:1043/1042:1043/1043:1043' ]`,
  3864  		true)
  3865  	if err != nil {
  3866  		c.Fatal(err)
  3867  	}
  3868  }
  3869  
  3870  func (s *DockerSuite) TestBuildEnvUsage(c *check.C) {
  3871  	// /docker/world/hello is not owned by the correct user
  3872  	testRequires(c, NotUserNamespace)
  3873  	testRequires(c, DaemonIsLinux)
  3874  	name := "testbuildenvusage"
  3875  	dockerfile := `FROM busybox
  3876  ENV    HOME /root
  3877  ENV    PATH $HOME/bin:$PATH
  3878  ENV    PATH /tmp:$PATH
  3879  RUN    [ "$PATH" = "/tmp:$HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ]
  3880  ENV    FOO /foo/baz
  3881  ENV    BAR /bar
  3882  ENV    BAZ $BAR
  3883  ENV    FOOPATH $PATH:$FOO
  3884  RUN    [ "$BAR" = "$BAZ" ]
  3885  RUN    [ "$FOOPATH" = "$PATH:/foo/baz" ]
  3886  ENV	   FROM hello/docker/world
  3887  ENV    TO /docker/world/hello
  3888  ADD    $FROM $TO
  3889  RUN    [ "$(cat $TO)" = "hello" ]
  3890  ENV    abc=def
  3891  ENV    ghi=$abc
  3892  RUN    [ "$ghi" = "def" ]
  3893  `
  3894  	ctx, err := fakeContext(dockerfile, map[string]string{
  3895  		"hello/docker/world": "hello",
  3896  	})
  3897  	if err != nil {
  3898  		c.Fatal(err)
  3899  	}
  3900  	defer ctx.Close()
  3901  
  3902  	_, err = buildImageFromContext(name, ctx, true)
  3903  	if err != nil {
  3904  		c.Fatal(err)
  3905  	}
  3906  }
  3907  
  3908  func (s *DockerSuite) TestBuildEnvUsage2(c *check.C) {
  3909  	// /docker/world/hello is not owned by the correct user
  3910  	testRequires(c, NotUserNamespace)
  3911  	testRequires(c, DaemonIsLinux)
  3912  	name := "testbuildenvusage2"
  3913  	dockerfile := `FROM busybox
  3914  ENV    abc=def
  3915  RUN    [ "$abc" = "def" ]
  3916  ENV    def="hello world"
  3917  RUN    [ "$def" = "hello world" ]
  3918  ENV    def=hello\ world
  3919  RUN    [ "$def" = "hello world" ]
  3920  ENV    v1=abc v2="hi there"
  3921  RUN    [ "$v1" = "abc" ]
  3922  RUN    [ "$v2" = "hi there" ]
  3923  ENV    v3='boogie nights' v4="with'quotes too"
  3924  RUN    [ "$v3" = "boogie nights" ]
  3925  RUN    [ "$v4" = "with'quotes too" ]
  3926  ENV    abc=zzz FROM=hello/docker/world
  3927  ENV    abc=zzz TO=/docker/world/hello
  3928  ADD    $FROM $TO
  3929  RUN    [ "$(cat $TO)" = "hello" ]
  3930  ENV    abc "zzz"
  3931  RUN    [ $abc = "zzz" ]
  3932  ENV    abc 'yyy'
  3933  RUN    [ $abc = 'yyy' ]
  3934  ENV    abc=
  3935  RUN    [ "$abc" = "" ]
  3936  
  3937  # use grep to make sure if the builder substitutes \$foo by mistake
  3938  # we don't get a false positive
  3939  ENV    abc=\$foo
  3940  RUN    [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  3941  ENV    abc \$foo
  3942  RUN    [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  3943  
  3944  ENV    abc=\'foo\'
  3945  RUN    [ "$abc" = "'foo'" ]
  3946  ENV    abc=\"foo\"
  3947  RUN    [ "$abc" = "\"foo\"" ]
  3948  ENV    abc "foo"
  3949  RUN    [ "$abc" = "foo" ]
  3950  ENV    abc 'foo'
  3951  RUN    [ "$abc" = 'foo' ]
  3952  ENV    abc \'foo\'
  3953  RUN    [ "$abc" = "'foo'" ]
  3954  ENV    abc \"foo\"
  3955  RUN    [ "$abc" = '"foo"' ]
  3956  
  3957  ENV    abc=ABC
  3958  RUN    [ "$abc" = "ABC" ]
  3959  ENV    def=${abc:-DEF}
  3960  RUN    [ "$def" = "ABC" ]
  3961  ENV    def=${ccc:-DEF}
  3962  RUN    [ "$def" = "DEF" ]
  3963  ENV    def=${ccc:-${def}xx}
  3964  RUN    [ "$def" = "DEFxx" ]
  3965  ENV    def=${def:+ALT}
  3966  RUN    [ "$def" = "ALT" ]
  3967  ENV    def=${def:+${abc}:}
  3968  RUN    [ "$def" = "ABC:" ]
  3969  ENV    def=${ccc:-\$abc:}
  3970  RUN    [ "$def" = '$abc:' ]
  3971  ENV    def=${ccc:-\${abc}:}
  3972  RUN    [ "$def" = '${abc:}' ]
  3973  ENV    mypath=${mypath:+$mypath:}/home
  3974  RUN    [ "$mypath" = '/home' ]
  3975  ENV    mypath=${mypath:+$mypath:}/away
  3976  RUN    [ "$mypath" = '/home:/away' ]
  3977  
  3978  ENV    e1=bar
  3979  ENV    e2=$e1
  3980  ENV    e3=$e11
  3981  ENV    e4=\$e1
  3982  ENV    e5=\$e11
  3983  RUN    [ "$e0,$e1,$e2,$e3,$e4,$e5" = ',bar,bar,,$e1,$e11' ]
  3984  
  3985  ENV    ee1 bar
  3986  ENV    ee2 $ee1
  3987  ENV    ee3 $ee11
  3988  ENV    ee4 \$ee1
  3989  ENV    ee5 \$ee11
  3990  RUN    [ "$ee1,$ee2,$ee3,$ee4,$ee5" = 'bar,bar,,$ee1,$ee11' ]
  3991  
  3992  ENV    eee1="foo"
  3993  ENV    eee2='foo'
  3994  ENV    eee3 "foo"
  3995  ENV    eee4 'foo'
  3996  RUN    [ "$eee1,$eee2,$eee3,$eee4" = 'foo,foo,foo,foo' ]
  3997  
  3998  `
  3999  	ctx, err := fakeContext(dockerfile, map[string]string{
  4000  		"hello/docker/world": "hello",
  4001  	})
  4002  	if err != nil {
  4003  		c.Fatal(err)
  4004  	}
  4005  	defer ctx.Close()
  4006  
  4007  	_, err = buildImageFromContext(name, ctx, true)
  4008  	if err != nil {
  4009  		c.Fatal(err)
  4010  	}
  4011  }
  4012  
  4013  func (s *DockerSuite) TestBuildAddScript(c *check.C) {
  4014  	testRequires(c, DaemonIsLinux)
  4015  	name := "testbuildaddscript"
  4016  	dockerfile := `
  4017  FROM busybox
  4018  ADD test /test
  4019  RUN ["chmod","+x","/test"]
  4020  RUN ["/test"]
  4021  RUN [ "$(cat /testfile)" = 'test!' ]`
  4022  	ctx, err := fakeContext(dockerfile, map[string]string{
  4023  		"test": "#!/bin/sh\necho 'test!' > /testfile",
  4024  	})
  4025  	if err != nil {
  4026  		c.Fatal(err)
  4027  	}
  4028  	defer ctx.Close()
  4029  
  4030  	_, err = buildImageFromContext(name, ctx, true)
  4031  	if err != nil {
  4032  		c.Fatal(err)
  4033  	}
  4034  }
  4035  
  4036  func (s *DockerSuite) TestBuildAddTar(c *check.C) {
  4037  	// /test/foo is not owned by the correct user
  4038  	testRequires(c, NotUserNamespace)
  4039  	testRequires(c, DaemonIsLinux)
  4040  	name := "testbuildaddtar"
  4041  
  4042  	ctx := func() *FakeContext {
  4043  		dockerfile := `
  4044  FROM busybox
  4045  ADD test.tar /
  4046  RUN cat /test/foo | grep Hi
  4047  ADD test.tar /test.tar
  4048  RUN cat /test.tar/test/foo | grep Hi
  4049  ADD test.tar /unlikely-to-exist
  4050  RUN cat /unlikely-to-exist/test/foo | grep Hi
  4051  ADD test.tar /unlikely-to-exist-trailing-slash/
  4052  RUN cat /unlikely-to-exist-trailing-slash/test/foo | grep Hi
  4053  RUN mkdir /existing-directory
  4054  ADD test.tar /existing-directory
  4055  RUN cat /existing-directory/test/foo | grep Hi
  4056  ADD test.tar /existing-directory-trailing-slash/
  4057  RUN cat /existing-directory-trailing-slash/test/foo | grep Hi`
  4058  		tmpDir, err := ioutil.TempDir("", "fake-context")
  4059  		c.Assert(err, check.IsNil)
  4060  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  4061  		if err != nil {
  4062  			c.Fatalf("failed to create test.tar archive: %v", err)
  4063  		}
  4064  		defer testTar.Close()
  4065  
  4066  		tw := tar.NewWriter(testTar)
  4067  
  4068  		if err := tw.WriteHeader(&tar.Header{
  4069  			Name: "test/foo",
  4070  			Size: 2,
  4071  		}); err != nil {
  4072  			c.Fatalf("failed to write tar file header: %v", err)
  4073  		}
  4074  		if _, err := tw.Write([]byte("Hi")); err != nil {
  4075  			c.Fatalf("failed to write tar file content: %v", err)
  4076  		}
  4077  		if err := tw.Close(); err != nil {
  4078  			c.Fatalf("failed to close tar archive: %v", err)
  4079  		}
  4080  
  4081  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  4082  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4083  		}
  4084  		return fakeContextFromDir(tmpDir)
  4085  	}()
  4086  	defer ctx.Close()
  4087  
  4088  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4089  		c.Fatalf("build failed to complete for TestBuildAddTar: %v", err)
  4090  	}
  4091  
  4092  }
  4093  
  4094  func (s *DockerSuite) TestBuildAddTarXz(c *check.C) {
  4095  	// /test/foo is not owned by the correct user
  4096  	testRequires(c, NotUserNamespace)
  4097  	testRequires(c, DaemonIsLinux)
  4098  	name := "testbuildaddtarxz"
  4099  
  4100  	ctx := func() *FakeContext {
  4101  		dockerfile := `
  4102  			FROM busybox
  4103  			ADD test.tar.xz /
  4104  			RUN cat /test/foo | grep Hi`
  4105  		tmpDir, err := ioutil.TempDir("", "fake-context")
  4106  		c.Assert(err, check.IsNil)
  4107  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  4108  		if err != nil {
  4109  			c.Fatalf("failed to create test.tar archive: %v", err)
  4110  		}
  4111  		defer testTar.Close()
  4112  
  4113  		tw := tar.NewWriter(testTar)
  4114  
  4115  		if err := tw.WriteHeader(&tar.Header{
  4116  			Name: "test/foo",
  4117  			Size: 2,
  4118  		}); err != nil {
  4119  			c.Fatalf("failed to write tar file header: %v", err)
  4120  		}
  4121  		if _, err := tw.Write([]byte("Hi")); err != nil {
  4122  			c.Fatalf("failed to write tar file content: %v", err)
  4123  		}
  4124  		if err := tw.Close(); err != nil {
  4125  			c.Fatalf("failed to close tar archive: %v", err)
  4126  		}
  4127  
  4128  		xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  4129  		xzCompressCmd.Dir = tmpDir
  4130  		out, _, err := runCommandWithOutput(xzCompressCmd)
  4131  		if err != nil {
  4132  			c.Fatal(err, out)
  4133  		}
  4134  
  4135  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  4136  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4137  		}
  4138  		return fakeContextFromDir(tmpDir)
  4139  	}()
  4140  
  4141  	defer ctx.Close()
  4142  
  4143  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4144  		c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  4145  	}
  4146  
  4147  }
  4148  
  4149  func (s *DockerSuite) TestBuildAddTarXzGz(c *check.C) {
  4150  	testRequires(c, DaemonIsLinux)
  4151  	name := "testbuildaddtarxzgz"
  4152  
  4153  	ctx := func() *FakeContext {
  4154  		dockerfile := `
  4155  			FROM busybox
  4156  			ADD test.tar.xz.gz /
  4157  			RUN ls /test.tar.xz.gz`
  4158  		tmpDir, err := ioutil.TempDir("", "fake-context")
  4159  		c.Assert(err, check.IsNil)
  4160  		testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  4161  		if err != nil {
  4162  			c.Fatalf("failed to create test.tar archive: %v", err)
  4163  		}
  4164  		defer testTar.Close()
  4165  
  4166  		tw := tar.NewWriter(testTar)
  4167  
  4168  		if err := tw.WriteHeader(&tar.Header{
  4169  			Name: "test/foo",
  4170  			Size: 2,
  4171  		}); err != nil {
  4172  			c.Fatalf("failed to write tar file header: %v", err)
  4173  		}
  4174  		if _, err := tw.Write([]byte("Hi")); err != nil {
  4175  			c.Fatalf("failed to write tar file content: %v", err)
  4176  		}
  4177  		if err := tw.Close(); err != nil {
  4178  			c.Fatalf("failed to close tar archive: %v", err)
  4179  		}
  4180  
  4181  		xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  4182  		xzCompressCmd.Dir = tmpDir
  4183  		out, _, err := runCommandWithOutput(xzCompressCmd)
  4184  		if err != nil {
  4185  			c.Fatal(err, out)
  4186  		}
  4187  
  4188  		gzipCompressCmd := exec.Command("gzip", "test.tar.xz")
  4189  		gzipCompressCmd.Dir = tmpDir
  4190  		out, _, err = runCommandWithOutput(gzipCompressCmd)
  4191  		if err != nil {
  4192  			c.Fatal(err, out)
  4193  		}
  4194  
  4195  		if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  4196  			c.Fatalf("failed to open destination dockerfile: %v", err)
  4197  		}
  4198  		return fakeContextFromDir(tmpDir)
  4199  	}()
  4200  
  4201  	defer ctx.Close()
  4202  
  4203  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4204  		c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  4205  	}
  4206  
  4207  }
  4208  
  4209  func (s *DockerSuite) TestBuildFromGIT(c *check.C) {
  4210  	testRequires(c, DaemonIsLinux)
  4211  	name := "testbuildfromgit"
  4212  	git, err := newFakeGit("repo", map[string]string{
  4213  		"Dockerfile": `FROM busybox
  4214  					ADD first /first
  4215  					RUN [ -f /first ]
  4216  					MAINTAINER docker`,
  4217  		"first": "test git data",
  4218  	}, true)
  4219  	if err != nil {
  4220  		c.Fatal(err)
  4221  	}
  4222  	defer git.Close()
  4223  
  4224  	_, err = buildImageFromPath(name, git.RepoURL, true)
  4225  	if err != nil {
  4226  		c.Fatal(err)
  4227  	}
  4228  	res, err := inspectField(name, "Author")
  4229  	if err != nil {
  4230  		c.Fatal(err)
  4231  	}
  4232  	if res != "docker" {
  4233  		c.Fatalf("Maintainer should be docker, got %s", res)
  4234  	}
  4235  }
  4236  
  4237  func (s *DockerSuite) TestBuildFromGITWithContext(c *check.C) {
  4238  	testRequires(c, DaemonIsLinux)
  4239  	name := "testbuildfromgit"
  4240  	git, err := newFakeGit("repo", map[string]string{
  4241  		"docker/Dockerfile": `FROM busybox
  4242  					ADD first /first
  4243  					RUN [ -f /first ]
  4244  					MAINTAINER docker`,
  4245  		"docker/first": "test git data",
  4246  	}, true)
  4247  	if err != nil {
  4248  		c.Fatal(err)
  4249  	}
  4250  	defer git.Close()
  4251  
  4252  	u := fmt.Sprintf("%s#master:docker", git.RepoURL)
  4253  	_, err = buildImageFromPath(name, u, true)
  4254  	if err != nil {
  4255  		c.Fatal(err)
  4256  	}
  4257  	res, err := inspectField(name, "Author")
  4258  	if err != nil {
  4259  		c.Fatal(err)
  4260  	}
  4261  	if res != "docker" {
  4262  		c.Fatalf("Maintainer should be docker, got %s", res)
  4263  	}
  4264  }
  4265  
  4266  func (s *DockerSuite) TestBuildFromGITwithF(c *check.C) {
  4267  	testRequires(c, DaemonIsLinux)
  4268  	name := "testbuildfromgitwithf"
  4269  	git, err := newFakeGit("repo", map[string]string{
  4270  		"myApp/myDockerfile": `FROM busybox
  4271  					RUN echo hi from Dockerfile`,
  4272  	}, true)
  4273  	if err != nil {
  4274  		c.Fatal(err)
  4275  	}
  4276  	defer git.Close()
  4277  
  4278  	out, _, err := dockerCmdWithError("build", "-t", name, "--no-cache", "-f", "myApp/myDockerfile", git.RepoURL)
  4279  	if err != nil {
  4280  		c.Fatalf("Error on build. Out: %s\nErr: %v", out, err)
  4281  	}
  4282  
  4283  	if !strings.Contains(out, "hi from Dockerfile") {
  4284  		c.Fatalf("Missing expected output, got:\n%s", out)
  4285  	}
  4286  }
  4287  
  4288  func (s *DockerSuite) TestBuildFromRemoteTarball(c *check.C) {
  4289  	testRequires(c, DaemonIsLinux)
  4290  	name := "testbuildfromremotetarball"
  4291  
  4292  	buffer := new(bytes.Buffer)
  4293  	tw := tar.NewWriter(buffer)
  4294  	defer tw.Close()
  4295  
  4296  	dockerfile := []byte(`FROM busybox
  4297  					MAINTAINER docker`)
  4298  	if err := tw.WriteHeader(&tar.Header{
  4299  		Name: "Dockerfile",
  4300  		Size: int64(len(dockerfile)),
  4301  	}); err != nil {
  4302  		c.Fatalf("failed to write tar file header: %v", err)
  4303  	}
  4304  	if _, err := tw.Write(dockerfile); err != nil {
  4305  		c.Fatalf("failed to write tar file content: %v", err)
  4306  	}
  4307  	if err := tw.Close(); err != nil {
  4308  		c.Fatalf("failed to close tar archive: %v", err)
  4309  	}
  4310  
  4311  	server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
  4312  		"testT.tar": buffer,
  4313  	})
  4314  	c.Assert(err, check.IsNil)
  4315  
  4316  	defer server.Close()
  4317  
  4318  	_, err = buildImageFromPath(name, server.URL()+"/testT.tar", true)
  4319  	c.Assert(err, check.IsNil)
  4320  
  4321  	res, err := inspectField(name, "Author")
  4322  	c.Assert(err, check.IsNil)
  4323  
  4324  	if res != "docker" {
  4325  		c.Fatalf("Maintainer should be docker, got %s", res)
  4326  	}
  4327  }
  4328  
  4329  func (s *DockerSuite) TestBuildCleanupCmdOnEntrypoint(c *check.C) {
  4330  	testRequires(c, DaemonIsLinux)
  4331  	name := "testbuildcmdcleanuponentrypoint"
  4332  	if _, err := buildImage(name,
  4333  		`FROM scratch
  4334          CMD ["test"]
  4335  		ENTRYPOINT ["echo"]`,
  4336  		true); err != nil {
  4337  		c.Fatal(err)
  4338  	}
  4339  	if _, err := buildImage(name,
  4340  		fmt.Sprintf(`FROM %s
  4341  		ENTRYPOINT ["cat"]`, name),
  4342  		true); err != nil {
  4343  		c.Fatal(err)
  4344  	}
  4345  	res, err := inspectField(name, "Config.Cmd")
  4346  	if err != nil {
  4347  		c.Fatal(err)
  4348  	}
  4349  	if res != "<nil>" {
  4350  		c.Fatalf("Cmd %s, expected nil", res)
  4351  	}
  4352  
  4353  	res, err = inspectField(name, "Config.Entrypoint")
  4354  	if err != nil {
  4355  		c.Fatal(err)
  4356  	}
  4357  	if expected := "{[cat]}"; res != expected {
  4358  		c.Fatalf("Entrypoint %s, expected %s", res, expected)
  4359  	}
  4360  }
  4361  
  4362  func (s *DockerSuite) TestBuildClearCmd(c *check.C) {
  4363  	testRequires(c, DaemonIsLinux)
  4364  	name := "testbuildclearcmd"
  4365  	_, err := buildImage(name,
  4366  		`From scratch
  4367     ENTRYPOINT ["/bin/bash"]
  4368     CMD []`,
  4369  		true)
  4370  	if err != nil {
  4371  		c.Fatal(err)
  4372  	}
  4373  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4374  	if err != nil {
  4375  		c.Fatal(err)
  4376  	}
  4377  	if res != "[]" {
  4378  		c.Fatalf("Cmd %s, expected %s", res, "[]")
  4379  	}
  4380  }
  4381  
  4382  func (s *DockerSuite) TestBuildEmptyCmd(c *check.C) {
  4383  	testRequires(c, DaemonIsLinux)
  4384  	name := "testbuildemptycmd"
  4385  	if _, err := buildImage(name, "FROM scratch\nMAINTAINER quux\n", true); err != nil {
  4386  		c.Fatal(err)
  4387  	}
  4388  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4389  	if err != nil {
  4390  		c.Fatal(err)
  4391  	}
  4392  	if res != "null" {
  4393  		c.Fatalf("Cmd %s, expected %s", res, "null")
  4394  	}
  4395  }
  4396  
  4397  func (s *DockerSuite) TestBuildOnBuildOutput(c *check.C) {
  4398  	testRequires(c, DaemonIsLinux)
  4399  	name := "testbuildonbuildparent"
  4400  	if _, err := buildImage(name, "FROM busybox\nONBUILD RUN echo foo\n", true); err != nil {
  4401  		c.Fatal(err)
  4402  	}
  4403  
  4404  	_, out, err := buildImageWithOut(name, "FROM "+name+"\nMAINTAINER quux\n", true)
  4405  	if err != nil {
  4406  		c.Fatal(err)
  4407  	}
  4408  
  4409  	if !strings.Contains(out, "# Executing 1 build trigger") {
  4410  		c.Fatal("failed to find the build trigger output", out)
  4411  	}
  4412  }
  4413  
  4414  func (s *DockerSuite) TestBuildInvalidTag(c *check.C) {
  4415  	testRequires(c, DaemonIsLinux)
  4416  	name := "abcd:" + stringutils.GenerateRandomAlphaOnlyString(200)
  4417  	_, out, err := buildImageWithOut(name, "FROM scratch\nMAINTAINER quux\n", true)
  4418  	// if the error doesnt check for illegal tag name, or the image is built
  4419  	// then this should fail
  4420  	if !strings.Contains(out, "Illegal tag name") || strings.Contains(out, "Sending build context to Docker daemon") {
  4421  		c.Fatalf("failed to stop before building. Error: %s, Output: %s", err, out)
  4422  	}
  4423  }
  4424  
  4425  func (s *DockerSuite) TestBuildCmdShDashC(c *check.C) {
  4426  	testRequires(c, DaemonIsLinux)
  4427  	name := "testbuildcmdshc"
  4428  	if _, err := buildImage(name, "FROM busybox\nCMD echo cmd\n", true); err != nil {
  4429  		c.Fatal(err)
  4430  	}
  4431  
  4432  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4433  	if err != nil {
  4434  		c.Fatal(err, res)
  4435  	}
  4436  
  4437  	expected := `["/bin/sh","-c","echo cmd"]`
  4438  
  4439  	if res != expected {
  4440  		c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  4441  	}
  4442  
  4443  }
  4444  
  4445  func (s *DockerSuite) TestBuildCmdSpaces(c *check.C) {
  4446  	testRequires(c, DaemonIsLinux)
  4447  	// Test to make sure that when we strcat arrays we take into account
  4448  	// the arg separator to make sure ["echo","hi"] and ["echo hi"] don't
  4449  	// look the same
  4450  	name := "testbuildcmdspaces"
  4451  	var id1 string
  4452  	var id2 string
  4453  	var err error
  4454  
  4455  	if id1, err = buildImage(name, "FROM busybox\nCMD [\"echo hi\"]\n", true); err != nil {
  4456  		c.Fatal(err)
  4457  	}
  4458  
  4459  	if id2, err = buildImage(name, "FROM busybox\nCMD [\"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 CMD")
  4465  	}
  4466  
  4467  	// Now do the same with ENTRYPOINT
  4468  	if id1, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo hi\"]\n", true); err != nil {
  4469  		c.Fatal(err)
  4470  	}
  4471  
  4472  	if id2, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo\", \"hi\"]\n", true); err != nil {
  4473  		c.Fatal(err)
  4474  	}
  4475  
  4476  	if id1 == id2 {
  4477  		c.Fatal("Should not have resulted in the same ENTRYPOINT")
  4478  	}
  4479  
  4480  }
  4481  
  4482  func (s *DockerSuite) TestBuildCmdJSONNoShDashC(c *check.C) {
  4483  	testRequires(c, DaemonIsLinux)
  4484  	name := "testbuildcmdjson"
  4485  	if _, err := buildImage(name, "FROM busybox\nCMD [\"echo\", \"cmd\"]", true); err != nil {
  4486  		c.Fatal(err)
  4487  	}
  4488  
  4489  	res, err := inspectFieldJSON(name, "Config.Cmd")
  4490  	if err != nil {
  4491  		c.Fatal(err, res)
  4492  	}
  4493  
  4494  	expected := `["echo","cmd"]`
  4495  
  4496  	if res != expected {
  4497  		c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  4498  	}
  4499  
  4500  }
  4501  
  4502  func (s *DockerSuite) TestBuildErrorInvalidInstruction(c *check.C) {
  4503  	testRequires(c, DaemonIsLinux)
  4504  	name := "testbuildignoreinvalidinstruction"
  4505  
  4506  	out, _, err := buildImageWithOut(name, "FROM busybox\nfoo bar", true)
  4507  	if err == nil {
  4508  		c.Fatalf("Should have failed: %s", out)
  4509  	}
  4510  
  4511  }
  4512  
  4513  func (s *DockerSuite) TestBuildEntrypointInheritance(c *check.C) {
  4514  	testRequires(c, DaemonIsLinux)
  4515  
  4516  	if _, err := buildImage("parent", `
  4517      FROM busybox
  4518      ENTRYPOINT exit 130
  4519      `, true); err != nil {
  4520  		c.Fatal(err)
  4521  	}
  4522  
  4523  	if _, status, _ := dockerCmdWithError("run", "parent"); status != 130 {
  4524  		c.Fatalf("expected exit code 130 but received %d", status)
  4525  	}
  4526  
  4527  	if _, err := buildImage("child", `
  4528      FROM parent
  4529      ENTRYPOINT exit 5
  4530      `, true); err != nil {
  4531  		c.Fatal(err)
  4532  	}
  4533  
  4534  	if _, status, _ := dockerCmdWithError("run", "child"); status != 5 {
  4535  		c.Fatalf("expected exit code 5 but received %d", status)
  4536  	}
  4537  
  4538  }
  4539  
  4540  func (s *DockerSuite) TestBuildEntrypointInheritanceInspect(c *check.C) {
  4541  	testRequires(c, DaemonIsLinux)
  4542  	var (
  4543  		name     = "testbuildepinherit"
  4544  		name2    = "testbuildepinherit2"
  4545  		expected = `["/bin/sh","-c","echo quux"]`
  4546  	)
  4547  
  4548  	if _, err := buildImage(name, "FROM busybox\nENTRYPOINT /foo/bar", true); err != nil {
  4549  		c.Fatal(err)
  4550  	}
  4551  
  4552  	if _, err := buildImage(name2, fmt.Sprintf("FROM %s\nENTRYPOINT echo quux", name), true); err != nil {
  4553  		c.Fatal(err)
  4554  	}
  4555  
  4556  	res, err := inspectFieldJSON(name2, "Config.Entrypoint")
  4557  	if err != nil {
  4558  		c.Fatal(err, res)
  4559  	}
  4560  
  4561  	if res != expected {
  4562  		c.Fatalf("Expected value %s not in Config.Entrypoint: %s", expected, res)
  4563  	}
  4564  
  4565  	out, _ := dockerCmd(c, "run", "-t", name2)
  4566  
  4567  	expected = "quux"
  4568  
  4569  	if strings.TrimSpace(out) != expected {
  4570  		c.Fatalf("Expected output is %s, got %s", expected, out)
  4571  	}
  4572  
  4573  }
  4574  
  4575  func (s *DockerSuite) TestBuildRunShEntrypoint(c *check.C) {
  4576  	testRequires(c, DaemonIsLinux)
  4577  	name := "testbuildentrypoint"
  4578  	_, err := buildImage(name,
  4579  		`FROM busybox
  4580                                  ENTRYPOINT /bin/echo`,
  4581  		true)
  4582  	if err != nil {
  4583  		c.Fatal(err)
  4584  	}
  4585  
  4586  	dockerCmd(c, "run", "--rm", name)
  4587  }
  4588  
  4589  func (s *DockerSuite) TestBuildExoticShellInterpolation(c *check.C) {
  4590  	testRequires(c, DaemonIsLinux)
  4591  	name := "testbuildexoticshellinterpolation"
  4592  
  4593  	_, err := buildImage(name, `
  4594  		FROM busybox
  4595  
  4596  		ENV SOME_VAR a.b.c
  4597  
  4598  		RUN [ "$SOME_VAR"       = 'a.b.c' ]
  4599  		RUN [ "${SOME_VAR}"     = 'a.b.c' ]
  4600  		RUN [ "${SOME_VAR%.*}"  = 'a.b'   ]
  4601  		RUN [ "${SOME_VAR%%.*}" = 'a'     ]
  4602  		RUN [ "${SOME_VAR#*.}"  = 'b.c'   ]
  4603  		RUN [ "${SOME_VAR##*.}" = 'c'     ]
  4604  		RUN [ "${SOME_VAR/c/d}" = 'a.b.d' ]
  4605  		RUN [ "${#SOME_VAR}"    = '5'     ]
  4606  
  4607  		RUN [ "${SOME_UNSET_VAR:-$SOME_VAR}" = 'a.b.c' ]
  4608  		RUN [ "${SOME_VAR:+Version: ${SOME_VAR}}" = 'Version: a.b.c' ]
  4609  		RUN [ "${SOME_UNSET_VAR:+${SOME_VAR}}" = '' ]
  4610  		RUN [ "${SOME_UNSET_VAR:-${SOME_VAR:-d.e.f}}" = 'a.b.c' ]
  4611  	`, false)
  4612  	if err != nil {
  4613  		c.Fatal(err)
  4614  	}
  4615  
  4616  }
  4617  
  4618  func (s *DockerSuite) TestBuildVerifySingleQuoteFails(c *check.C) {
  4619  	testRequires(c, DaemonIsLinux)
  4620  	// This testcase is supposed to generate an error because the
  4621  	// JSON array we're passing in on the CMD uses single quotes instead
  4622  	// of double quotes (per the JSON spec). This means we interpret it
  4623  	// as a "string" insead of "JSON array" and pass it on to "sh -c" and
  4624  	// it should barf on it.
  4625  	name := "testbuildsinglequotefails"
  4626  
  4627  	if _, err := buildImage(name,
  4628  		`FROM busybox
  4629  		CMD [ '/bin/sh', '-c', 'echo hi' ]`,
  4630  		true); err != nil {
  4631  		c.Fatal(err)
  4632  	}
  4633  
  4634  	if _, _, err := dockerCmdWithError("run", "--rm", name); err == nil {
  4635  		c.Fatal("The image was not supposed to be able to run")
  4636  	}
  4637  
  4638  }
  4639  
  4640  func (s *DockerSuite) TestBuildVerboseOut(c *check.C) {
  4641  	testRequires(c, DaemonIsLinux)
  4642  	name := "testbuildverboseout"
  4643  
  4644  	_, out, err := buildImageWithOut(name,
  4645  		`FROM busybox
  4646  RUN echo 123`,
  4647  		false)
  4648  
  4649  	if err != nil {
  4650  		c.Fatal(err)
  4651  	}
  4652  	if !strings.Contains(out, "\n123\n") {
  4653  		c.Fatalf("Output should contain %q: %q", "123", out)
  4654  	}
  4655  
  4656  }
  4657  
  4658  func (s *DockerSuite) TestBuildWithTabs(c *check.C) {
  4659  	testRequires(c, DaemonIsLinux)
  4660  	name := "testbuildwithtabs"
  4661  	_, err := buildImage(name,
  4662  		"FROM busybox\nRUN echo\tone\t\ttwo", true)
  4663  	if err != nil {
  4664  		c.Fatal(err)
  4665  	}
  4666  	res, err := inspectFieldJSON(name, "ContainerConfig.Cmd")
  4667  	if err != nil {
  4668  		c.Fatal(err)
  4669  	}
  4670  	expected1 := `["/bin/sh","-c","echo\tone\t\ttwo"]`
  4671  	expected2 := `["/bin/sh","-c","echo\u0009one\u0009\u0009two"]` // syntactically equivalent, and what Go 1.3 generates
  4672  	if res != expected1 && res != expected2 {
  4673  		c.Fatalf("Missing tabs.\nGot: %s\nExp: %s or %s", res, expected1, expected2)
  4674  	}
  4675  }
  4676  
  4677  func (s *DockerSuite) TestBuildLabels(c *check.C) {
  4678  	testRequires(c, DaemonIsLinux)
  4679  	name := "testbuildlabel"
  4680  	expected := `{"License":"GPL","Vendor":"Acme"}`
  4681  	_, err := buildImage(name,
  4682  		`FROM busybox
  4683  		LABEL Vendor=Acme
  4684                  LABEL License GPL`,
  4685  		true)
  4686  	if err != nil {
  4687  		c.Fatal(err)
  4688  	}
  4689  	res, err := inspectFieldJSON(name, "Config.Labels")
  4690  	if err != nil {
  4691  		c.Fatal(err)
  4692  	}
  4693  	if res != expected {
  4694  		c.Fatalf("Labels %s, expected %s", res, expected)
  4695  	}
  4696  }
  4697  
  4698  func (s *DockerSuite) TestBuildLabelsCache(c *check.C) {
  4699  	testRequires(c, DaemonIsLinux)
  4700  	name := "testbuildlabelcache"
  4701  
  4702  	id1, err := buildImage(name,
  4703  		`FROM busybox
  4704  		LABEL Vendor=Acme`, false)
  4705  	if err != nil {
  4706  		c.Fatalf("Build 1 should have worked: %v", err)
  4707  	}
  4708  
  4709  	id2, err := buildImage(name,
  4710  		`FROM busybox
  4711  		LABEL Vendor=Acme`, true)
  4712  	if err != nil || id1 != id2 {
  4713  		c.Fatalf("Build 2 should have worked & used cache(%s,%s): %v", id1, id2, err)
  4714  	}
  4715  
  4716  	id2, err = buildImage(name,
  4717  		`FROM busybox
  4718  		LABEL Vendor=Acme1`, true)
  4719  	if err != nil || id1 == id2 {
  4720  		c.Fatalf("Build 3 should have worked & NOT used cache(%s,%s): %v", id1, id2, err)
  4721  	}
  4722  
  4723  	id2, err = buildImage(name,
  4724  		`FROM busybox
  4725  		LABEL Vendor Acme`, true) // Note: " " and "=" should be same
  4726  	if err != nil || id1 != id2 {
  4727  		c.Fatalf("Build 4 should have worked & used cache(%s,%s): %v", id1, id2, err)
  4728  	}
  4729  
  4730  	// Now make sure the cache isn't used by mistake
  4731  	id1, err = buildImage(name,
  4732  		`FROM busybox
  4733         LABEL f1=b1 f2=b2`, false)
  4734  	if err != nil {
  4735  		c.Fatalf("Build 5 should have worked: %q", err)
  4736  	}
  4737  
  4738  	id2, err = buildImage(name,
  4739  		`FROM busybox
  4740         LABEL f1="b1 f2=b2"`, true)
  4741  	if err != nil || id1 == id2 {
  4742  		c.Fatalf("Build 6 should have worked & NOT used the cache(%s,%s): %q", id1, id2, err)
  4743  	}
  4744  
  4745  }
  4746  
  4747  func (s *DockerSuite) TestBuildStderr(c *check.C) {
  4748  	testRequires(c, DaemonIsLinux)
  4749  	// This test just makes sure that no non-error output goes
  4750  	// to stderr
  4751  	name := "testbuildstderr"
  4752  	_, _, stderr, err := buildImageWithStdoutStderr(name,
  4753  		"FROM busybox\nRUN echo one", true)
  4754  	if err != nil {
  4755  		c.Fatal(err)
  4756  	}
  4757  
  4758  	if runtime.GOOS == "windows" {
  4759  		// stderr might contain a security warning on windows
  4760  		lines := strings.Split(stderr, "\n")
  4761  		for _, v := range lines {
  4762  			if v != "" && !strings.Contains(v, "SECURITY WARNING:") {
  4763  				c.Fatalf("Stderr contains unexpected output line: %q", v)
  4764  			}
  4765  		}
  4766  	} else {
  4767  		if stderr != "" {
  4768  			c.Fatalf("Stderr should have been empty, instead its: %q", stderr)
  4769  		}
  4770  	}
  4771  }
  4772  
  4773  func (s *DockerSuite) TestBuildChownSingleFile(c *check.C) {
  4774  	testRequires(c, UnixCli) // test uses chown: not available on windows
  4775  	testRequires(c, DaemonIsLinux)
  4776  
  4777  	name := "testbuildchownsinglefile"
  4778  
  4779  	ctx, err := fakeContext(`
  4780  FROM busybox
  4781  COPY test /
  4782  RUN ls -l /test
  4783  RUN [ $(ls -l /test | awk '{print $3":"$4}') = 'root:root' ]
  4784  `, map[string]string{
  4785  		"test": "test",
  4786  	})
  4787  	if err != nil {
  4788  		c.Fatal(err)
  4789  	}
  4790  	defer ctx.Close()
  4791  
  4792  	if err := os.Chown(filepath.Join(ctx.Dir, "test"), 4242, 4242); err != nil {
  4793  		c.Fatal(err)
  4794  	}
  4795  
  4796  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4797  		c.Fatal(err)
  4798  	}
  4799  
  4800  }
  4801  
  4802  func (s *DockerSuite) TestBuildSymlinkBreakout(c *check.C) {
  4803  	testRequires(c, DaemonIsLinux)
  4804  	name := "testbuildsymlinkbreakout"
  4805  	tmpdir, err := ioutil.TempDir("", name)
  4806  	c.Assert(err, check.IsNil)
  4807  	defer os.RemoveAll(tmpdir)
  4808  	ctx := filepath.Join(tmpdir, "context")
  4809  	if err := os.MkdirAll(ctx, 0755); err != nil {
  4810  		c.Fatal(err)
  4811  	}
  4812  	if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte(`
  4813  	from busybox
  4814  	add symlink.tar /
  4815  	add inject /symlink/
  4816  	`), 0644); err != nil {
  4817  		c.Fatal(err)
  4818  	}
  4819  	inject := filepath.Join(ctx, "inject")
  4820  	if err := ioutil.WriteFile(inject, nil, 0644); err != nil {
  4821  		c.Fatal(err)
  4822  	}
  4823  	f, err := os.Create(filepath.Join(ctx, "symlink.tar"))
  4824  	if err != nil {
  4825  		c.Fatal(err)
  4826  	}
  4827  	w := tar.NewWriter(f)
  4828  	w.WriteHeader(&tar.Header{
  4829  		Name:     "symlink2",
  4830  		Typeflag: tar.TypeSymlink,
  4831  		Linkname: "/../../../../../../../../../../../../../../",
  4832  		Uid:      os.Getuid(),
  4833  		Gid:      os.Getgid(),
  4834  	})
  4835  	w.WriteHeader(&tar.Header{
  4836  		Name:     "symlink",
  4837  		Typeflag: tar.TypeSymlink,
  4838  		Linkname: filepath.Join("symlink2", tmpdir),
  4839  		Uid:      os.Getuid(),
  4840  		Gid:      os.Getgid(),
  4841  	})
  4842  	w.Close()
  4843  	f.Close()
  4844  	if _, err := buildImageFromContext(name, fakeContextFromDir(ctx), false); err != nil {
  4845  		c.Fatal(err)
  4846  	}
  4847  	if _, err := os.Lstat(filepath.Join(tmpdir, "inject")); err == nil {
  4848  		c.Fatal("symlink breakout - inject")
  4849  	} else if !os.IsNotExist(err) {
  4850  		c.Fatalf("unexpected error: %v", err)
  4851  	}
  4852  }
  4853  
  4854  func (s *DockerSuite) TestBuildXZHost(c *check.C) {
  4855  	// /usr/local/sbin/xz gets permission denied for the user
  4856  	testRequires(c, NotUserNamespace)
  4857  	testRequires(c, DaemonIsLinux)
  4858  	name := "testbuildxzhost"
  4859  
  4860  	ctx, err := fakeContext(`
  4861  FROM busybox
  4862  ADD xz /usr/local/sbin/
  4863  RUN chmod 755 /usr/local/sbin/xz
  4864  ADD test.xz /
  4865  RUN [ ! -e /injected ]`,
  4866  		map[string]string{
  4867  			"test.xz": "\xfd\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00" +
  4868  				"\x21\x01\x16\x00\x00\x00\x74\x2f\xe5\xa3\x01\x00\x3f\xfd" +
  4869  				"\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00\x21",
  4870  			"xz": "#!/bin/sh\ntouch /injected",
  4871  		})
  4872  
  4873  	if err != nil {
  4874  		c.Fatal(err)
  4875  	}
  4876  	defer ctx.Close()
  4877  
  4878  	if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4879  		c.Fatal(err)
  4880  	}
  4881  
  4882  }
  4883  
  4884  func (s *DockerSuite) TestBuildVolumesRetainContents(c *check.C) {
  4885  	// /foo/file gets permission denied for the user
  4886  	testRequires(c, NotUserNamespace)
  4887  	testRequires(c, DaemonIsLinux)
  4888  	var (
  4889  		name     = "testbuildvolumescontent"
  4890  		expected = "some text"
  4891  	)
  4892  	ctx, err := fakeContext(`
  4893  FROM busybox
  4894  COPY content /foo/file
  4895  VOLUME /foo
  4896  CMD cat /foo/file`,
  4897  		map[string]string{
  4898  			"content": expected,
  4899  		})
  4900  	if err != nil {
  4901  		c.Fatal(err)
  4902  	}
  4903  	defer ctx.Close()
  4904  
  4905  	if _, err := buildImageFromContext(name, ctx, false); err != nil {
  4906  		c.Fatal(err)
  4907  	}
  4908  
  4909  	out, _ := dockerCmd(c, "run", "--rm", name)
  4910  	if out != expected {
  4911  		c.Fatalf("expected file contents for /foo/file to be %q but received %q", expected, out)
  4912  	}
  4913  
  4914  }
  4915  
  4916  func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) {
  4917  	testRequires(c, DaemonIsLinux)
  4918  
  4919  	ctx, err := fakeContext(`FROM busybox
  4920  	RUN echo from Dockerfile`,
  4921  		map[string]string{
  4922  			"Dockerfile":       "FROM busybox\nRUN echo from Dockerfile",
  4923  			"files/Dockerfile": "FROM busybox\nRUN echo from files/Dockerfile",
  4924  			"files/dFile":      "FROM busybox\nRUN echo from files/dFile",
  4925  			"dFile":            "FROM busybox\nRUN echo from dFile",
  4926  			"files/dFile2":     "FROM busybox\nRUN echo from files/dFile2",
  4927  		})
  4928  	if err != nil {
  4929  		c.Fatal(err)
  4930  	}
  4931  	defer ctx.Close()
  4932  
  4933  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4934  	if err != nil {
  4935  		c.Fatalf("Failed to build: %s\n%s", out, err)
  4936  	}
  4937  	if !strings.Contains(out, "from Dockerfile") {
  4938  		c.Fatalf("test1 should have used Dockerfile, output:%s", out)
  4939  	}
  4940  
  4941  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-f", filepath.Join("files", "Dockerfile"), "-t", "test2", ".")
  4942  	if err != nil {
  4943  		c.Fatal(err)
  4944  	}
  4945  	if !strings.Contains(out, "from files/Dockerfile") {
  4946  		c.Fatalf("test2 should have used files/Dockerfile, output:%s", out)
  4947  	}
  4948  
  4949  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", filepath.Join("files", "dFile")), "-t", "test3", ".")
  4950  	if err != nil {
  4951  		c.Fatal(err)
  4952  	}
  4953  	if !strings.Contains(out, "from files/dFile") {
  4954  		c.Fatalf("test3 should have used files/dFile, output:%s", out)
  4955  	}
  4956  
  4957  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "--file=dFile", "-t", "test4", ".")
  4958  	if err != nil {
  4959  		c.Fatal(err)
  4960  	}
  4961  	if !strings.Contains(out, "from dFile") {
  4962  		c.Fatalf("test4 should have used dFile, output:%s", out)
  4963  	}
  4964  
  4965  	dirWithNoDockerfile, err := ioutil.TempDir(os.TempDir(), "test5")
  4966  	c.Assert(err, check.IsNil)
  4967  	nonDockerfileFile := filepath.Join(dirWithNoDockerfile, "notDockerfile")
  4968  	if _, err = os.Create(nonDockerfileFile); err != nil {
  4969  		c.Fatal(err)
  4970  	}
  4971  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", nonDockerfileFile), "-t", "test5", ".")
  4972  
  4973  	if err == nil {
  4974  		c.Fatalf("test5 was supposed to fail to find passwd")
  4975  	}
  4976  
  4977  	if expected := fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", nonDockerfileFile); !strings.Contains(out, expected) {
  4978  		c.Fatalf("wrong error messsage:%v\nexpected to contain=%v", out, expected)
  4979  	}
  4980  
  4981  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test6", "..")
  4982  	if err != nil {
  4983  		c.Fatalf("test6 failed: %s", err)
  4984  	}
  4985  	if !strings.Contains(out, "from Dockerfile") {
  4986  		c.Fatalf("test6 should have used root Dockerfile, output:%s", out)
  4987  	}
  4988  
  4989  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join(ctx.Dir, "files", "Dockerfile"), "-t", "test7", "..")
  4990  	if err != nil {
  4991  		c.Fatalf("test7 failed: %s", err)
  4992  	}
  4993  	if !strings.Contains(out, "from files/Dockerfile") {
  4994  		c.Fatalf("test7 should have used files Dockerfile, output:%s", out)
  4995  	}
  4996  
  4997  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test8", ".")
  4998  	if err == nil || !strings.Contains(out, "must be within the build context") {
  4999  		c.Fatalf("test8 should have failed with Dockerfile out of context: %s", err)
  5000  	}
  5001  
  5002  	tmpDir := os.TempDir()
  5003  	out, _, err = dockerCmdInDir(c, tmpDir, "build", "-t", "test9", ctx.Dir)
  5004  	if err != nil {
  5005  		c.Fatalf("test9 - failed: %s", err)
  5006  	}
  5007  	if !strings.Contains(out, "from Dockerfile") {
  5008  		c.Fatalf("test9 should have used root Dockerfile, output:%s", out)
  5009  	}
  5010  
  5011  	out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", "dFile2", "-t", "test10", ".")
  5012  	if err != nil {
  5013  		c.Fatalf("test10 should have worked: %s", err)
  5014  	}
  5015  	if !strings.Contains(out, "from files/dFile2") {
  5016  		c.Fatalf("test10 should have used files/dFile2, output:%s", out)
  5017  	}
  5018  
  5019  }
  5020  
  5021  func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) {
  5022  	testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  5023  	testRequires(c, DaemonIsLinux)
  5024  
  5025  	ctx, err := fakeContext(`FROM busybox
  5026  	RUN echo from dockerfile`,
  5027  		map[string]string{
  5028  			"dockerfile": "FROM busybox\nRUN echo from dockerfile",
  5029  		})
  5030  	if err != nil {
  5031  		c.Fatal(err)
  5032  	}
  5033  	defer ctx.Close()
  5034  
  5035  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  5036  	if err != nil {
  5037  		c.Fatalf("Failed to build: %s\n%s", out, err)
  5038  	}
  5039  
  5040  	if !strings.Contains(out, "from dockerfile") {
  5041  		c.Fatalf("Missing proper output: %s", out)
  5042  	}
  5043  
  5044  }
  5045  
  5046  func (s *DockerSuite) TestBuildWithTwoDockerfiles(c *check.C) {
  5047  	testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  5048  	testRequires(c, DaemonIsLinux)
  5049  
  5050  	ctx, err := fakeContext(`FROM busybox
  5051  RUN echo from Dockerfile`,
  5052  		map[string]string{
  5053  			"dockerfile": "FROM busybox\nRUN echo from dockerfile",
  5054  		})
  5055  	if err != nil {
  5056  		c.Fatal(err)
  5057  	}
  5058  	defer ctx.Close()
  5059  
  5060  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  5061  	if err != nil {
  5062  		c.Fatalf("Failed to build: %s\n%s", out, err)
  5063  	}
  5064  
  5065  	if !strings.Contains(out, "from Dockerfile") {
  5066  		c.Fatalf("Missing proper output: %s", out)
  5067  	}
  5068  
  5069  }
  5070  
  5071  func (s *DockerSuite) TestBuildFromURLWithF(c *check.C) {
  5072  	testRequires(c, DaemonIsLinux)
  5073  
  5074  	server, err := fakeStorage(map[string]string{"baz": `FROM busybox
  5075  RUN echo from baz
  5076  COPY * /tmp/
  5077  RUN find /tmp/`})
  5078  	if err != nil {
  5079  		c.Fatal(err)
  5080  	}
  5081  	defer server.Close()
  5082  
  5083  	ctx, err := fakeContext(`FROM busybox
  5084  RUN echo from Dockerfile`,
  5085  		map[string]string{})
  5086  	if err != nil {
  5087  		c.Fatal(err)
  5088  	}
  5089  	defer ctx.Close()
  5090  
  5091  	// Make sure that -f is ignored and that we don't use the Dockerfile
  5092  	// that's in the current dir
  5093  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-f", "baz", "-t", "test1", server.URL()+"/baz")
  5094  	if err != nil {
  5095  		c.Fatalf("Failed to build: %s\n%s", out, err)
  5096  	}
  5097  
  5098  	if !strings.Contains(out, "from baz") ||
  5099  		strings.Contains(out, "/tmp/baz") ||
  5100  		!strings.Contains(out, "/tmp/Dockerfile") {
  5101  		c.Fatalf("Missing proper output: %s", out)
  5102  	}
  5103  
  5104  }
  5105  
  5106  func (s *DockerSuite) TestBuildFromStdinWithF(c *check.C) {
  5107  	testRequires(c, DaemonIsLinux)
  5108  	ctx, err := fakeContext(`FROM busybox
  5109  RUN echo from Dockerfile`,
  5110  		map[string]string{})
  5111  	if err != nil {
  5112  		c.Fatal(err)
  5113  	}
  5114  	defer ctx.Close()
  5115  
  5116  	// Make sure that -f is ignored and that we don't use the Dockerfile
  5117  	// that's in the current dir
  5118  	dockerCommand := exec.Command(dockerBinary, "build", "-f", "baz", "-t", "test1", "-")
  5119  	dockerCommand.Dir = ctx.Dir
  5120  	dockerCommand.Stdin = strings.NewReader(`FROM busybox
  5121  RUN echo from baz
  5122  COPY * /tmp/
  5123  RUN find /tmp/`)
  5124  	out, status, err := runCommandWithOutput(dockerCommand)
  5125  	if err != nil || status != 0 {
  5126  		c.Fatalf("Error building: %s", err)
  5127  	}
  5128  
  5129  	if !strings.Contains(out, "from baz") ||
  5130  		strings.Contains(out, "/tmp/baz") ||
  5131  		!strings.Contains(out, "/tmp/Dockerfile") {
  5132  		c.Fatalf("Missing proper output: %s", out)
  5133  	}
  5134  
  5135  }
  5136  
  5137  func (s *DockerSuite) TestBuildFromOfficialNames(c *check.C) {
  5138  	testRequires(c, DaemonIsLinux)
  5139  	name := "testbuildfromofficial"
  5140  	fromNames := []string{
  5141  		"busybox",
  5142  		"docker.io/busybox",
  5143  		"index.docker.io/busybox",
  5144  		"library/busybox",
  5145  		"docker.io/library/busybox",
  5146  		"index.docker.io/library/busybox",
  5147  	}
  5148  	for idx, fromName := range fromNames {
  5149  		imgName := fmt.Sprintf("%s%d", name, idx)
  5150  		_, err := buildImage(imgName, "FROM "+fromName, true)
  5151  		if err != nil {
  5152  			c.Errorf("Build failed using FROM %s: %s", fromName, err)
  5153  		}
  5154  		deleteImages(imgName)
  5155  	}
  5156  }
  5157  
  5158  func (s *DockerSuite) TestBuildDockerfileOutsideContext(c *check.C) {
  5159  	testRequires(c, UnixCli) // uses os.Symlink: not implemented in windows at the time of writing (go-1.4.2)
  5160  	testRequires(c, DaemonIsLinux)
  5161  
  5162  	name := "testbuilddockerfileoutsidecontext"
  5163  	tmpdir, err := ioutil.TempDir("", name)
  5164  	c.Assert(err, check.IsNil)
  5165  	defer os.RemoveAll(tmpdir)
  5166  	ctx := filepath.Join(tmpdir, "context")
  5167  	if err := os.MkdirAll(ctx, 0755); err != nil {
  5168  		c.Fatal(err)
  5169  	}
  5170  	if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte("FROM scratch\nENV X Y"), 0644); err != nil {
  5171  		c.Fatal(err)
  5172  	}
  5173  	wd, err := os.Getwd()
  5174  	if err != nil {
  5175  		c.Fatal(err)
  5176  	}
  5177  	defer os.Chdir(wd)
  5178  	if err := os.Chdir(ctx); err != nil {
  5179  		c.Fatal(err)
  5180  	}
  5181  	if err := ioutil.WriteFile(filepath.Join(tmpdir, "outsideDockerfile"), []byte("FROM scratch\nENV x y"), 0644); err != nil {
  5182  		c.Fatal(err)
  5183  	}
  5184  	if err := os.Symlink(filepath.Join("..", "outsideDockerfile"), filepath.Join(ctx, "dockerfile1")); err != nil {
  5185  		c.Fatal(err)
  5186  	}
  5187  	if err := os.Symlink(filepath.Join(tmpdir, "outsideDockerfile"), filepath.Join(ctx, "dockerfile2")); err != nil {
  5188  		c.Fatal(err)
  5189  	}
  5190  
  5191  	for _, dockerfilePath := range []string{
  5192  		filepath.Join("..", "outsideDockerfile"),
  5193  		filepath.Join(ctx, "dockerfile1"),
  5194  		filepath.Join(ctx, "dockerfile2"),
  5195  	} {
  5196  		out, _, err := dockerCmdWithError("build", "-t", name, "--no-cache", "-f", dockerfilePath, ".")
  5197  		if err == nil {
  5198  			c.Fatalf("Expected error with %s. Out: %s", dockerfilePath, out)
  5199  		}
  5200  		if !strings.Contains(out, "must be within the build context") && !strings.Contains(out, "Cannot locate Dockerfile") {
  5201  			c.Fatalf("Unexpected error with %s. Out: %s", dockerfilePath, out)
  5202  		}
  5203  		deleteImages(name)
  5204  	}
  5205  
  5206  	os.Chdir(tmpdir)
  5207  
  5208  	// Path to Dockerfile should be resolved relative to working directory, not relative to context.
  5209  	// There is a Dockerfile in the context, but since there is no Dockerfile in the current directory, the following should fail
  5210  	out, _, err := dockerCmdWithError("build", "-t", name, "--no-cache", "-f", "Dockerfile", ctx)
  5211  	if err == nil {
  5212  		c.Fatalf("Expected error. Out: %s", out)
  5213  	}
  5214  }
  5215  
  5216  func (s *DockerSuite) TestBuildSpaces(c *check.C) {
  5217  	testRequires(c, DaemonIsLinux)
  5218  	// Test to make sure that leading/trailing spaces on a command
  5219  	// doesn't change the error msg we get
  5220  	var (
  5221  		err1 error
  5222  		err2 error
  5223  	)
  5224  
  5225  	name := "testspaces"
  5226  	ctx, err := fakeContext("FROM busybox\nCOPY\n",
  5227  		map[string]string{
  5228  			"Dockerfile": "FROM busybox\nCOPY\n",
  5229  		})
  5230  	if err != nil {
  5231  		c.Fatal(err)
  5232  	}
  5233  	defer ctx.Close()
  5234  
  5235  	if _, err1 = buildImageFromContext(name, ctx, false); err1 == nil {
  5236  		c.Fatal("Build 1 was supposed to fail, but didn't")
  5237  	}
  5238  
  5239  	ctx.Add("Dockerfile", "FROM busybox\nCOPY    ")
  5240  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5241  		c.Fatal("Build 2 was supposed to fail, but didn't")
  5242  	}
  5243  
  5244  	removeLogTimestamps := func(s string) string {
  5245  		return regexp.MustCompile(`time="(.*?)"`).ReplaceAllString(s, `time=[TIMESTAMP]`)
  5246  	}
  5247  
  5248  	// Skip over the times
  5249  	e1 := removeLogTimestamps(err1.Error())
  5250  	e2 := removeLogTimestamps(err2.Error())
  5251  
  5252  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5253  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5254  		c.Fatalf("Build 2's error wasn't the same as build 1's\n1:%s\n2:%s", err1, err2)
  5255  	}
  5256  
  5257  	ctx.Add("Dockerfile", "FROM busybox\n   COPY")
  5258  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5259  		c.Fatal("Build 3 was supposed to fail, but didn't")
  5260  	}
  5261  
  5262  	// Skip over the times
  5263  	e1 = removeLogTimestamps(err1.Error())
  5264  	e2 = removeLogTimestamps(err2.Error())
  5265  
  5266  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5267  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5268  		c.Fatalf("Build 3's error wasn't the same as build 1's\n1:%s\n3:%s", err1, err2)
  5269  	}
  5270  
  5271  	ctx.Add("Dockerfile", "FROM busybox\n   COPY    ")
  5272  	if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  5273  		c.Fatal("Build 4 was supposed to fail, but didn't")
  5274  	}
  5275  
  5276  	// Skip over the times
  5277  	e1 = removeLogTimestamps(err1.Error())
  5278  	e2 = removeLogTimestamps(err2.Error())
  5279  
  5280  	// Ignore whitespace since that's what were verifying doesn't change stuff
  5281  	if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  5282  		c.Fatalf("Build 4's error wasn't the same as build 1's\n1:%s\n4:%s", err1, err2)
  5283  	}
  5284  
  5285  }
  5286  
  5287  func (s *DockerSuite) TestBuildSpacesWithQuotes(c *check.C) {
  5288  	testRequires(c, DaemonIsLinux)
  5289  	// Test to make sure that spaces in quotes aren't lost
  5290  	name := "testspacesquotes"
  5291  
  5292  	dockerfile := `FROM busybox
  5293  RUN echo "  \
  5294    foo  "`
  5295  
  5296  	_, out, err := buildImageWithOut(name, dockerfile, false)
  5297  	if err != nil {
  5298  		c.Fatal("Build failed:", err)
  5299  	}
  5300  
  5301  	expecting := "\n    foo  \n"
  5302  	if !strings.Contains(out, expecting) {
  5303  		c.Fatalf("Bad output: %q expecting to contain %q", out, expecting)
  5304  	}
  5305  
  5306  }
  5307  
  5308  // #4393
  5309  func (s *DockerSuite) TestBuildVolumeFileExistsinContainer(c *check.C) {
  5310  	testRequires(c, DaemonIsLinux)
  5311  	buildCmd := exec.Command(dockerBinary, "build", "-t", "docker-test-errcreatevolumewithfile", "-")
  5312  	buildCmd.Stdin = strings.NewReader(`
  5313  	FROM busybox
  5314  	RUN touch /foo
  5315  	VOLUME /foo
  5316  	`)
  5317  
  5318  	out, _, err := runCommandWithOutput(buildCmd)
  5319  	if err == nil || !strings.Contains(out, "file exists") {
  5320  		c.Fatalf("expected build to fail when file exists in container at requested volume path")
  5321  	}
  5322  
  5323  }
  5324  
  5325  func (s *DockerSuite) TestBuildMissingArgs(c *check.C) {
  5326  	testRequires(c, DaemonIsLinux)
  5327  	// Test to make sure that all Dockerfile commands (except the ones listed
  5328  	// in skipCmds) will generate an error if no args are provided.
  5329  	// Note: INSERT is deprecated so we exclude it because of that.
  5330  	skipCmds := map[string]struct{}{
  5331  		"CMD":        {},
  5332  		"RUN":        {},
  5333  		"ENTRYPOINT": {},
  5334  		"INSERT":     {},
  5335  	}
  5336  
  5337  	for cmd := range command.Commands {
  5338  		cmd = strings.ToUpper(cmd)
  5339  		if _, ok := skipCmds[cmd]; ok {
  5340  			continue
  5341  		}
  5342  
  5343  		var dockerfile string
  5344  		if cmd == "FROM" {
  5345  			dockerfile = cmd
  5346  		} else {
  5347  			// Add FROM to make sure we don't complain about it missing
  5348  			dockerfile = "FROM busybox\n" + cmd
  5349  		}
  5350  
  5351  		ctx, err := fakeContext(dockerfile, map[string]string{})
  5352  		if err != nil {
  5353  			c.Fatal(err)
  5354  		}
  5355  		defer ctx.Close()
  5356  		var out string
  5357  		if out, err = buildImageFromContext("args", ctx, true); err == nil {
  5358  			c.Fatalf("%s was supposed to fail. Out:%s", cmd, out)
  5359  		}
  5360  		if !strings.Contains(err.Error(), cmd+" requires") {
  5361  			c.Fatalf("%s returned the wrong type of error:%s", cmd, err)
  5362  		}
  5363  	}
  5364  
  5365  }
  5366  
  5367  func (s *DockerSuite) TestBuildEmptyScratch(c *check.C) {
  5368  	testRequires(c, DaemonIsLinux)
  5369  	_, out, err := buildImageWithOut("sc", "FROM scratch", true)
  5370  	if err == nil {
  5371  		c.Fatalf("Build was supposed to fail")
  5372  	}
  5373  	if !strings.Contains(out, "No image was generated") {
  5374  		c.Fatalf("Wrong error message: %v", out)
  5375  	}
  5376  }
  5377  
  5378  func (s *DockerSuite) TestBuildDotDotFile(c *check.C) {
  5379  	testRequires(c, DaemonIsLinux)
  5380  
  5381  	ctx, err := fakeContext("FROM busybox\n",
  5382  		map[string]string{
  5383  			"..gitme": "",
  5384  		})
  5385  	if err != nil {
  5386  		c.Fatal(err)
  5387  	}
  5388  	defer ctx.Close()
  5389  
  5390  	if _, err = buildImageFromContext("sc", ctx, false); err != nil {
  5391  		c.Fatalf("Build was supposed to work: %s", err)
  5392  	}
  5393  }
  5394  
  5395  func (s *DockerSuite) TestBuildNotVerbose(c *check.C) {
  5396  	testRequires(c, DaemonIsLinux)
  5397  	ctx, err := fakeContext("FROM busybox\nENV abc=hi\nRUN echo $abc there", map[string]string{})
  5398  	if err != nil {
  5399  		c.Fatal(err)
  5400  	}
  5401  	defer ctx.Close()
  5402  
  5403  	// First do it w/verbose - baseline
  5404  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--no-cache", "-t", "verbose", ".")
  5405  	if err != nil {
  5406  		c.Fatalf("failed to build the image w/o -q: %s, %v", out, err)
  5407  	}
  5408  	if !strings.Contains(out, "hi there") {
  5409  		c.Fatalf("missing output:%s\n", out)
  5410  	}
  5411  
  5412  	// Now do it w/o verbose
  5413  	out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "--no-cache", "-q", "-t", "verbose", ".")
  5414  	if err != nil {
  5415  		c.Fatalf("failed to build the image w/ -q: %s, %v", out, err)
  5416  	}
  5417  	if strings.Contains(out, "hi there") {
  5418  		c.Fatalf("Bad output, should not contain 'hi there':%s", out)
  5419  	}
  5420  
  5421  }
  5422  
  5423  func (s *DockerSuite) TestBuildRUNoneJSON(c *check.C) {
  5424  	testRequires(c, DaemonIsLinux)
  5425  	name := "testbuildrunonejson"
  5426  
  5427  	ctx, err := fakeContext(`FROM hello-world:frozen
  5428  RUN [ "/hello" ]`, map[string]string{})
  5429  	if err != nil {
  5430  		c.Fatal(err)
  5431  	}
  5432  	defer ctx.Close()
  5433  
  5434  	out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--no-cache", "-t", name, ".")
  5435  	if err != nil {
  5436  		c.Fatalf("failed to build the image: %s, %v", out, err)
  5437  	}
  5438  
  5439  	if !strings.Contains(out, "Hello from Docker") {
  5440  		c.Fatalf("bad output: %s", out)
  5441  	}
  5442  
  5443  }
  5444  
  5445  func (s *DockerSuite) TestBuildEmptyStringVolume(c *check.C) {
  5446  	testRequires(c, DaemonIsLinux)
  5447  	name := "testbuildemptystringvolume"
  5448  
  5449  	_, err := buildImage(name, `
  5450    FROM busybox
  5451    ENV foo=""
  5452    VOLUME $foo
  5453    `, false)
  5454  	if err == nil {
  5455  		c.Fatal("Should have failed to build")
  5456  	}
  5457  
  5458  }
  5459  
  5460  func (s *DockerSuite) TestBuildContainerWithCgroupParent(c *check.C) {
  5461  	testRequires(c, NativeExecDriver)
  5462  	testRequires(c, SameHostDaemon)
  5463  	testRequires(c, DaemonIsLinux)
  5464  
  5465  	cgroupParent := "test"
  5466  	data, err := ioutil.ReadFile("/proc/self/cgroup")
  5467  	if err != nil {
  5468  		c.Fatalf("failed to read '/proc/self/cgroup - %v", err)
  5469  	}
  5470  	selfCgroupPaths := parseCgroupPaths(string(data))
  5471  	_, found := selfCgroupPaths["memory"]
  5472  	if !found {
  5473  		c.Fatalf("unable to find self memory cgroup path. CgroupsPath: %v", selfCgroupPaths)
  5474  	}
  5475  	cmd := exec.Command(dockerBinary, "build", "--cgroup-parent", cgroupParent, "-")
  5476  	cmd.Stdin = strings.NewReader(`
  5477  FROM busybox
  5478  RUN cat /proc/self/cgroup
  5479  `)
  5480  
  5481  	out, _, err := runCommandWithOutput(cmd)
  5482  	if err != nil {
  5483  		c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
  5484  	}
  5485  	m, err := regexp.MatchString(fmt.Sprintf("memory:.*/%s/.*", cgroupParent), out)
  5486  	c.Assert(err, check.IsNil)
  5487  	if !m {
  5488  		c.Fatalf("There is no expected memory cgroup with parent /%s/: %s", cgroupParent, out)
  5489  	}
  5490  }
  5491  
  5492  func (s *DockerSuite) TestBuildNoDupOutput(c *check.C) {
  5493  	testRequires(c, DaemonIsLinux)
  5494  	// Check to make sure our build output prints the Dockerfile cmd
  5495  	// property - there was a bug that caused it to be duplicated on the
  5496  	// Step X  line
  5497  	name := "testbuildnodupoutput"
  5498  
  5499  	_, out, err := buildImageWithOut(name, `
  5500    FROM busybox
  5501    RUN env`, false)
  5502  	if err != nil {
  5503  		c.Fatalf("Build should have worked: %q", err)
  5504  	}
  5505  
  5506  	exp := "\nStep 2 : RUN env\n"
  5507  	if !strings.Contains(out, exp) {
  5508  		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  5509  	}
  5510  }
  5511  
  5512  // GH15826
  5513  func (s *DockerSuite) TestBuildStartsFromOne(c *check.C) {
  5514  	testRequires(c, DaemonIsLinux)
  5515  	// Explicit check to ensure that build starts from step 1 rather than 0
  5516  	name := "testbuildstartsfromone"
  5517  
  5518  	_, out, err := buildImageWithOut(name, `
  5519    FROM busybox`, false)
  5520  	if err != nil {
  5521  		c.Fatalf("Build should have worked: %q", err)
  5522  	}
  5523  
  5524  	exp := "\nStep 1 : FROM busybox\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) TestBuildBadCmdFlag(c *check.C) {
  5531  	testRequires(c, DaemonIsLinux)
  5532  	name := "testbuildbadcmdflag"
  5533  
  5534  	_, out, err := buildImageWithOut(name, `
  5535    FROM busybox
  5536    MAINTAINER --boo joe@example.com`, false)
  5537  	if err == nil {
  5538  		c.Fatal("Build should have failed")
  5539  	}
  5540  
  5541  	exp := "\nUnknown flag: boo\n"
  5542  	if !strings.Contains(out, exp) {
  5543  		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  5544  	}
  5545  }
  5546  
  5547  func (s *DockerSuite) TestBuildRUNErrMsg(c *check.C) {
  5548  	testRequires(c, DaemonIsLinux)
  5549  	// Test to make sure the bad command is quoted with just "s and
  5550  	// not as a Go []string
  5551  	name := "testbuildbadrunerrmsg"
  5552  	_, out, err := buildImageWithOut(name, `
  5553    FROM busybox
  5554    RUN badEXE a1 \& a2	a3`, false) // tab between a2 and a3
  5555  	if err == nil {
  5556  		c.Fatal("Should have failed to build")
  5557  	}
  5558  
  5559  	exp := `The command '/bin/sh -c badEXE a1 \& a2	a3' returned a non-zero code: 127`
  5560  	if !strings.Contains(out, exp) {
  5561  		c.Fatalf("RUN doesn't have the correct output:\nGot:%s\nExpected:%s", out, exp)
  5562  	}
  5563  }
  5564  
  5565  func (s *DockerTrustSuite) TestTrustedBuild(c *check.C) {
  5566  	repoName := s.setupTrustedImage(c, "trusted-build")
  5567  	dockerFile := fmt.Sprintf(`
  5568    FROM %s
  5569    RUN []
  5570      `, repoName)
  5571  
  5572  	name := "testtrustedbuild"
  5573  
  5574  	buildCmd := buildImageCmd(name, dockerFile, true)
  5575  	s.trustedCmd(buildCmd)
  5576  	out, _, err := runCommandWithOutput(buildCmd)
  5577  	if err != nil {
  5578  		c.Fatalf("Error running trusted build: %s\n%s", err, out)
  5579  	}
  5580  
  5581  	if !strings.Contains(out, fmt.Sprintf("FROM %s@sha", repoName[:len(repoName)-7])) {
  5582  		c.Fatalf("Unexpected output on trusted build:\n%s", out)
  5583  	}
  5584  
  5585  	// We should also have a tag reference for the image.
  5586  	if out, exitCode := dockerCmd(c, "inspect", repoName); exitCode != 0 {
  5587  		c.Fatalf("unexpected exit code inspecting image %q: %d: %s", repoName, exitCode, out)
  5588  	}
  5589  
  5590  	// We should now be able to remove the tag reference.
  5591  	if out, exitCode := dockerCmd(c, "rmi", repoName); exitCode != 0 {
  5592  		c.Fatalf("unexpected exit code inspecting image %q: %d: %s", repoName, exitCode, out)
  5593  	}
  5594  }
  5595  
  5596  func (s *DockerTrustSuite) TestTrustedBuildUntrustedTag(c *check.C) {
  5597  	repoName := fmt.Sprintf("%v/dockercli/build-untrusted-tag:latest", privateRegistryURL)
  5598  	dockerFile := fmt.Sprintf(`
  5599    FROM %s
  5600    RUN []
  5601      `, repoName)
  5602  
  5603  	name := "testtrustedbuilduntrustedtag"
  5604  
  5605  	buildCmd := buildImageCmd(name, dockerFile, true)
  5606  	s.trustedCmd(buildCmd)
  5607  	out, _, err := runCommandWithOutput(buildCmd)
  5608  	if err == nil {
  5609  		c.Fatalf("Expected error on trusted build with untrusted tag: %s\n%s", err, out)
  5610  	}
  5611  
  5612  	if !strings.Contains(out, fmt.Sprintf("no trust data available")) {
  5613  		c.Fatalf("Unexpected output on trusted build with untrusted tag:\n%s", out)
  5614  	}
  5615  }
  5616  
  5617  func (s *DockerTrustSuite) TestBuildContextDirIsSymlink(c *check.C) {
  5618  	testRequires(c, DaemonIsLinux)
  5619  	tempDir, err := ioutil.TempDir("", "test-build-dir-is-symlink-")
  5620  	c.Assert(err, check.IsNil)
  5621  	defer os.RemoveAll(tempDir)
  5622  
  5623  	// Make a real context directory in this temp directory with a simple
  5624  	// Dockerfile.
  5625  	realContextDirname := filepath.Join(tempDir, "context")
  5626  	if err := os.Mkdir(realContextDirname, os.FileMode(0755)); err != nil {
  5627  		c.Fatal(err)
  5628  	}
  5629  
  5630  	if err = ioutil.WriteFile(
  5631  		filepath.Join(realContextDirname, "Dockerfile"),
  5632  		[]byte(`
  5633  			FROM busybox
  5634  			RUN echo hello world
  5635  		`),
  5636  		os.FileMode(0644),
  5637  	); err != nil {
  5638  		c.Fatal(err)
  5639  	}
  5640  
  5641  	// Make a symlink to the real context directory.
  5642  	contextSymlinkName := filepath.Join(tempDir, "context_link")
  5643  	if err := os.Symlink(realContextDirname, contextSymlinkName); err != nil {
  5644  		c.Fatal(err)
  5645  	}
  5646  
  5647  	// Executing the build with the symlink as the specified context should
  5648  	// *not* fail.
  5649  	if out, exitStatus := dockerCmd(c, "build", contextSymlinkName); exitStatus != 0 {
  5650  		c.Fatalf("build failed with exit status %d: %s", exitStatus, out)
  5651  	}
  5652  }
  5653  
  5654  // Issue #15634: COPY fails when path starts with "null"
  5655  func (s *DockerSuite) TestBuildNullStringInAddCopyVolume(c *check.C) {
  5656  	testRequires(c, DaemonIsLinux)
  5657  	name := "testbuildnullstringinaddcopyvolume"
  5658  
  5659  	ctx, err := fakeContext(`
  5660  		FROM busybox
  5661  
  5662  		ADD null /
  5663  		COPY nullfile /
  5664  		VOLUME nullvolume
  5665  		`,
  5666  		map[string]string{
  5667  			"null":     "test1",
  5668  			"nullfile": "test2",
  5669  		},
  5670  	)
  5671  	c.Assert(err, check.IsNil)
  5672  	defer ctx.Close()
  5673  
  5674  	_, err = buildImageFromContext(name, ctx, true)
  5675  	c.Assert(err, check.IsNil)
  5676  }
  5677  
  5678  func (s *DockerSuite) TestBuildStopSignal(c *check.C) {
  5679  	testRequires(c, DaemonIsLinux)
  5680  	name := "test_build_stop_signal"
  5681  	_, err := buildImage(name,
  5682  		`FROM busybox
  5683  		 STOPSIGNAL SIGKILL`,
  5684  		true)
  5685  	c.Assert(err, check.IsNil)
  5686  	res, err := inspectFieldJSON(name, "Config.StopSignal")
  5687  	c.Assert(err, check.IsNil)
  5688  
  5689  	if res != `"SIGKILL"` {
  5690  		c.Fatalf("Signal %s, expected SIGKILL", res)
  5691  	}
  5692  }
  5693  
  5694  func (s *DockerSuite) TestBuildBuildTimeArg(c *check.C) {
  5695  	testRequires(c, DaemonIsLinux)
  5696  	imgName := "bldargtest"
  5697  	envKey := "foo"
  5698  	envVal := "bar"
  5699  	args := []string{
  5700  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5701  	}
  5702  	dockerfile := fmt.Sprintf(`FROM busybox
  5703  		ARG %s
  5704  		RUN echo $%s
  5705  		CMD echo $%s`, envKey, envKey, envKey)
  5706  
  5707  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || !strings.Contains(out, envVal) {
  5708  		if err != nil {
  5709  			c.Fatalf("build failed to complete: %q %q", out, err)
  5710  		}
  5711  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envVal)
  5712  	}
  5713  
  5714  	containerName := "bldargCont"
  5715  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); out != "\n" {
  5716  		c.Fatalf("run produced invalid output: %q, expected empty string", out)
  5717  	}
  5718  }
  5719  
  5720  func (s *DockerSuite) TestBuildBuildTimeArgHistory(c *check.C) {
  5721  	testRequires(c, DaemonIsLinux)
  5722  	imgName := "bldargtest"
  5723  	envKey := "foo"
  5724  	envVal := "bar"
  5725  	envDef := "bar1"
  5726  	args := []string{
  5727  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5728  	}
  5729  	dockerfile := fmt.Sprintf(`FROM busybox
  5730  		ARG %s=%s`, envKey, envDef)
  5731  
  5732  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || !strings.Contains(out, envVal) {
  5733  		if err != nil {
  5734  			c.Fatalf("build failed to complete: %q %q", out, err)
  5735  		}
  5736  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envVal)
  5737  	}
  5738  
  5739  	out, _ := dockerCmd(c, "history", "--no-trunc", imgName)
  5740  	outputTabs := strings.Split(out, "\n")[1]
  5741  	if !strings.Contains(outputTabs, envDef) {
  5742  		c.Fatalf("failed to find arg default in image history output: %q expected: %q", outputTabs, envDef)
  5743  	}
  5744  }
  5745  
  5746  func (s *DockerSuite) TestBuildBuildTimeArgCacheHit(c *check.C) {
  5747  	testRequires(c, DaemonIsLinux)
  5748  	imgName := "bldargtest"
  5749  	envKey := "foo"
  5750  	envVal := "bar"
  5751  	args := []string{
  5752  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5753  	}
  5754  	dockerfile := fmt.Sprintf(`FROM busybox
  5755  		ARG %s
  5756  		RUN echo $%s`, envKey, envKey)
  5757  
  5758  	origImgID := ""
  5759  	var err error
  5760  	if origImgID, err = buildImage(imgName, dockerfile, true, args...); err != nil {
  5761  		c.Fatal(err)
  5762  	}
  5763  
  5764  	imgNameCache := "bldargtestcachehit"
  5765  	if newImgID, err := buildImage(imgNameCache, dockerfile, true, args...); err != nil || newImgID != origImgID {
  5766  		if err != nil {
  5767  			c.Fatal(err)
  5768  		}
  5769  		c.Fatalf("build didn't use cache! expected image id: %q built image id: %q", origImgID, newImgID)
  5770  	}
  5771  }
  5772  
  5773  func (s *DockerSuite) TestBuildBuildTimeArgCacheMissExtraArg(c *check.C) {
  5774  	testRequires(c, DaemonIsLinux)
  5775  	imgName := "bldargtest"
  5776  	envKey := "foo"
  5777  	envVal := "bar"
  5778  	extraEnvKey := "foo1"
  5779  	extraEnvVal := "bar1"
  5780  	args := []string{
  5781  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5782  	}
  5783  
  5784  	dockerfile := fmt.Sprintf(`FROM busybox
  5785  		ARG %s
  5786  		ARG %s
  5787  		RUN echo $%s`, envKey, extraEnvKey, envKey)
  5788  
  5789  	origImgID := ""
  5790  	var err error
  5791  	if origImgID, err = buildImage(imgName, dockerfile, true, args...); err != nil {
  5792  		c.Fatal(err)
  5793  	}
  5794  
  5795  	imgNameCache := "bldargtestcachemiss"
  5796  	args = append(args, "--build-arg", fmt.Sprintf("%s=%s", extraEnvKey, extraEnvVal))
  5797  	if newImgID, err := buildImage(imgNameCache, dockerfile, true, args...); err != nil || newImgID == origImgID {
  5798  		if err != nil {
  5799  			c.Fatal(err)
  5800  		}
  5801  		c.Fatalf("build used cache, expected a miss!")
  5802  	}
  5803  }
  5804  
  5805  func (s *DockerSuite) TestBuildBuildTimeArgCacheMissSameArgDiffVal(c *check.C) {
  5806  	testRequires(c, DaemonIsLinux)
  5807  	imgName := "bldargtest"
  5808  	envKey := "foo"
  5809  	envVal := "bar"
  5810  	newEnvVal := "bar1"
  5811  	args := []string{
  5812  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5813  	}
  5814  
  5815  	dockerfile := fmt.Sprintf(`FROM busybox
  5816  		ARG %s
  5817  		RUN echo $%s`, envKey, envKey)
  5818  
  5819  	origImgID := ""
  5820  	var err error
  5821  	if origImgID, err = buildImage(imgName, dockerfile, true, args...); err != nil {
  5822  		c.Fatal(err)
  5823  	}
  5824  
  5825  	imgNameCache := "bldargtestcachemiss"
  5826  	args = []string{
  5827  		"--build-arg", fmt.Sprintf("%s=%s", envKey, newEnvVal),
  5828  	}
  5829  	if newImgID, err := buildImage(imgNameCache, dockerfile, true, args...); err != nil || newImgID == origImgID {
  5830  		if err != nil {
  5831  			c.Fatal(err)
  5832  		}
  5833  		c.Fatalf("build used cache, expected a miss!")
  5834  	}
  5835  }
  5836  
  5837  func (s *DockerSuite) TestBuildBuildTimeArgOverrideArgDefinedBeforeEnv(c *check.C) {
  5838  	testRequires(c, DaemonIsLinux)
  5839  	imgName := "bldargtest"
  5840  	envKey := "foo"
  5841  	envVal := "bar"
  5842  	envValOveride := "barOverride"
  5843  	args := []string{
  5844  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5845  	}
  5846  	dockerfile := fmt.Sprintf(`FROM busybox
  5847  		ARG %s
  5848  		ENV %s %s
  5849  		RUN echo $%s
  5850  		CMD echo $%s
  5851          `, envKey, envKey, envValOveride, envKey, envKey)
  5852  
  5853  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 2 {
  5854  		if err != nil {
  5855  			c.Fatalf("build failed to complete: %q %q", out, err)
  5856  		}
  5857  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  5858  	}
  5859  
  5860  	containerName := "bldargCont"
  5861  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  5862  		c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  5863  	}
  5864  }
  5865  
  5866  func (s *DockerSuite) TestBuildBuildTimeArgOverrideEnvDefinedBeforeArg(c *check.C) {
  5867  	testRequires(c, DaemonIsLinux)
  5868  	imgName := "bldargtest"
  5869  	envKey := "foo"
  5870  	envVal := "bar"
  5871  	envValOveride := "barOverride"
  5872  	args := []string{
  5873  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5874  	}
  5875  	dockerfile := fmt.Sprintf(`FROM busybox
  5876  		ENV %s %s
  5877  		ARG %s
  5878  		RUN echo $%s
  5879  		CMD echo $%s
  5880          `, envKey, envValOveride, envKey, envKey, envKey)
  5881  
  5882  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 2 {
  5883  		if err != nil {
  5884  			c.Fatalf("build failed to complete: %q %q", out, err)
  5885  		}
  5886  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  5887  	}
  5888  
  5889  	containerName := "bldargCont"
  5890  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  5891  		c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  5892  	}
  5893  }
  5894  
  5895  func (s *DockerSuite) TestBuildBuildTimeArgExpansion(c *check.C) {
  5896  	testRequires(c, DaemonIsLinux)
  5897  	imgName := "bldvarstest"
  5898  
  5899  	wdVar := "WDIR"
  5900  	wdVal := "/tmp/"
  5901  	addVar := "AFILE"
  5902  	addVal := "addFile"
  5903  	copyVar := "CFILE"
  5904  	copyVal := "copyFile"
  5905  	envVar := "foo"
  5906  	envVal := "bar"
  5907  	exposeVar := "EPORT"
  5908  	exposeVal := "9999"
  5909  	userVar := "USER"
  5910  	userVal := "testUser"
  5911  	volVar := "VOL"
  5912  	volVal := "/testVol/"
  5913  	args := []string{
  5914  		"--build-arg", fmt.Sprintf("%s=%s", wdVar, wdVal),
  5915  		"--build-arg", fmt.Sprintf("%s=%s", addVar, addVal),
  5916  		"--build-arg", fmt.Sprintf("%s=%s", copyVar, copyVal),
  5917  		"--build-arg", fmt.Sprintf("%s=%s", envVar, envVal),
  5918  		"--build-arg", fmt.Sprintf("%s=%s", exposeVar, exposeVal),
  5919  		"--build-arg", fmt.Sprintf("%s=%s", userVar, userVal),
  5920  		"--build-arg", fmt.Sprintf("%s=%s", volVar, volVal),
  5921  	}
  5922  	ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  5923  		ARG %s
  5924  		WORKDIR ${%s}
  5925  		ARG %s
  5926  		ADD ${%s} testDir/
  5927  		ARG %s
  5928  		COPY $%s testDir/
  5929  		ARG %s
  5930  		ENV %s=${%s}
  5931  		ARG %s
  5932  		EXPOSE $%s
  5933  		ARG %s
  5934  		USER $%s
  5935  		ARG %s
  5936  		VOLUME ${%s}`,
  5937  		wdVar, wdVar, addVar, addVar, copyVar, copyVar, envVar, envVar,
  5938  		envVar, exposeVar, exposeVar, userVar, userVar, volVar, volVar),
  5939  		map[string]string{
  5940  			addVal:  "some stuff",
  5941  			copyVal: "some stuff",
  5942  		})
  5943  	if err != nil {
  5944  		c.Fatal(err)
  5945  	}
  5946  	defer ctx.Close()
  5947  
  5948  	if _, err := buildImageFromContext(imgName, ctx, true, args...); err != nil {
  5949  		c.Fatal(err)
  5950  	}
  5951  
  5952  	var resMap map[string]interface{}
  5953  	var resArr []string
  5954  	res := ""
  5955  	res, err = inspectField(imgName, "Config.WorkingDir")
  5956  	if err != nil {
  5957  		c.Fatal(err)
  5958  	}
  5959  	if res != wdVal {
  5960  		c.Fatalf("Config.WorkingDir value mismatch. Expected: %s, got: %s", wdVal, res)
  5961  	}
  5962  
  5963  	err = inspectFieldAndMarshall(imgName, "Config.Env", &resArr)
  5964  	if err != nil {
  5965  		c.Fatal(err)
  5966  	}
  5967  
  5968  	found := false
  5969  	for _, v := range resArr {
  5970  		if fmt.Sprintf("%s=%s", envVar, envVal) == v {
  5971  			found = true
  5972  			break
  5973  		}
  5974  	}
  5975  	if !found {
  5976  		c.Fatalf("Config.Env value mismatch. Expected <key=value> to exist: %s=%s, got: %v",
  5977  			envVar, envVal, resArr)
  5978  	}
  5979  
  5980  	err = inspectFieldAndMarshall(imgName, "Config.ExposedPorts", &resMap)
  5981  	if err != nil {
  5982  		c.Fatal(err)
  5983  	}
  5984  	if _, ok := resMap[fmt.Sprintf("%s/tcp", exposeVal)]; !ok {
  5985  		c.Fatalf("Config.ExposedPorts value mismatch. Expected exposed port: %s/tcp, got: %v", exposeVal, resMap)
  5986  	}
  5987  
  5988  	res, err = inspectField(imgName, "Config.User")
  5989  	if err != nil {
  5990  		c.Fatal(err)
  5991  	}
  5992  	if res != userVal {
  5993  		c.Fatalf("Config.User value mismatch. Expected: %s, got: %s", userVal, res)
  5994  	}
  5995  
  5996  	err = inspectFieldAndMarshall(imgName, "Config.Volumes", &resMap)
  5997  	if err != nil {
  5998  		c.Fatal(err)
  5999  	}
  6000  	if _, ok := resMap[volVal]; !ok {
  6001  		c.Fatalf("Config.Volumes value mismatch. Expected volume: %s, got: %v", volVal, resMap)
  6002  	}
  6003  }
  6004  
  6005  func (s *DockerSuite) TestBuildBuildTimeArgExpansionOverride(c *check.C) {
  6006  	testRequires(c, DaemonIsLinux)
  6007  	imgName := "bldvarstest"
  6008  	envKey := "foo"
  6009  	envVal := "bar"
  6010  	envKey1 := "foo1"
  6011  	envValOveride := "barOverride"
  6012  	args := []string{
  6013  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6014  	}
  6015  	dockerfile := fmt.Sprintf(`FROM busybox
  6016  		ARG %s
  6017  		ENV %s %s
  6018  		ENV %s ${%s}
  6019  		RUN echo $%s
  6020  		CMD echo $%s`, envKey, envKey, envValOveride, envKey1, envKey, envKey1, envKey1)
  6021  
  6022  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 2 {
  6023  		if err != nil {
  6024  			c.Fatalf("build failed to complete: %q %q", out, err)
  6025  		}
  6026  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  6027  	}
  6028  
  6029  	containerName := "bldargCont"
  6030  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  6031  		c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  6032  	}
  6033  }
  6034  
  6035  func (s *DockerSuite) TestBuildBuildTimeArgUntrustedDefinedAfterUse(c *check.C) {
  6036  	testRequires(c, DaemonIsLinux)
  6037  	imgName := "bldargtest"
  6038  	envKey := "foo"
  6039  	envVal := "bar"
  6040  	args := []string{
  6041  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6042  	}
  6043  	dockerfile := fmt.Sprintf(`FROM busybox
  6044  		RUN echo $%s
  6045  		ARG %s
  6046  		CMD echo $%s`, envKey, envKey, envKey)
  6047  
  6048  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Contains(out, envVal) {
  6049  		if err != nil {
  6050  			c.Fatalf("build failed to complete: %q %q", out, err)
  6051  		}
  6052  		c.Fatalf("able to access environment variable in output: %q expected to be missing", out)
  6053  	}
  6054  
  6055  	containerName := "bldargCont"
  6056  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); out != "\n" {
  6057  		c.Fatalf("run produced invalid output: %q, expected empty string", out)
  6058  	}
  6059  }
  6060  
  6061  func (s *DockerSuite) TestBuildBuildTimeArgBuiltinArg(c *check.C) {
  6062  	testRequires(c, DaemonIsLinux)
  6063  	imgName := "bldargtest"
  6064  	envKey := "HTTP_PROXY"
  6065  	envVal := "bar"
  6066  	args := []string{
  6067  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6068  	}
  6069  	dockerfile := fmt.Sprintf(`FROM busybox
  6070  		RUN echo $%s
  6071  		CMD echo $%s`, envKey, envKey)
  6072  
  6073  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || !strings.Contains(out, envVal) {
  6074  		if err != nil {
  6075  			c.Fatalf("build failed to complete: %q %q", out, err)
  6076  		}
  6077  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envVal)
  6078  	}
  6079  
  6080  	containerName := "bldargCont"
  6081  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); out != "\n" {
  6082  		c.Fatalf("run produced invalid output: %q, expected empty string", out)
  6083  	}
  6084  }
  6085  
  6086  func (s *DockerSuite) TestBuildBuildTimeArgDefaultOverride(c *check.C) {
  6087  	testRequires(c, DaemonIsLinux)
  6088  	imgName := "bldargtest"
  6089  	envKey := "foo"
  6090  	envVal := "bar"
  6091  	envValOveride := "barOverride"
  6092  	args := []string{
  6093  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envValOveride),
  6094  	}
  6095  	dockerfile := fmt.Sprintf(`FROM busybox
  6096  		ARG %s=%s
  6097  		ENV %s $%s
  6098  		RUN echo $%s
  6099  		CMD echo $%s`, envKey, envVal, envKey, envKey, envKey, envKey)
  6100  
  6101  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 1 {
  6102  		if err != nil {
  6103  			c.Fatalf("build failed to complete: %q %q", out, err)
  6104  		}
  6105  		c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  6106  	}
  6107  
  6108  	containerName := "bldargCont"
  6109  	if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  6110  		c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  6111  	}
  6112  }
  6113  
  6114  func (s *DockerSuite) TestBuildBuildTimeArgMultiArgsSameLine(c *check.C) {
  6115  	testRequires(c, DaemonIsLinux)
  6116  	imgName := "bldargtest"
  6117  	envKey := "foo"
  6118  	envKey1 := "foo1"
  6119  	args := []string{}
  6120  	dockerfile := fmt.Sprintf(`FROM busybox
  6121  		ARG %s %s`, envKey, envKey1)
  6122  
  6123  	errStr := "ARG requires exactly one argument definition"
  6124  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err == nil {
  6125  		c.Fatalf("build succeeded, expected to fail. Output: %v", out)
  6126  	} else if !strings.Contains(out, errStr) {
  6127  		c.Fatalf("Unexpected error. output: %q, expected error: %q", out, errStr)
  6128  	}
  6129  }
  6130  
  6131  func (s *DockerSuite) TestBuildBuildTimeArgUnconsumedArg(c *check.C) {
  6132  	testRequires(c, DaemonIsLinux)
  6133  	imgName := "bldargtest"
  6134  	envKey := "foo"
  6135  	envVal := "bar"
  6136  	args := []string{
  6137  		"--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  6138  	}
  6139  	dockerfile := fmt.Sprintf(`FROM busybox
  6140  		RUN echo $%s
  6141  		CMD echo $%s`, envKey, envKey)
  6142  
  6143  	errStr := "One or more build-args"
  6144  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err == nil {
  6145  		c.Fatalf("build succeeded, expected to fail. Output: %v", out)
  6146  	} else if !strings.Contains(out, errStr) {
  6147  		c.Fatalf("Unexpected error. output: %q, expected error: %q", out, errStr)
  6148  	}
  6149  
  6150  }
  6151  
  6152  func (s *DockerSuite) TestBuildBuildTimeArgQuotedValVariants(c *check.C) {
  6153  	testRequires(c, DaemonIsLinux)
  6154  	imgName := "bldargtest"
  6155  	envKey := "foo"
  6156  	envKey1 := "foo1"
  6157  	envKey2 := "foo2"
  6158  	envKey3 := "foo3"
  6159  	args := []string{}
  6160  	dockerfile := fmt.Sprintf(`FROM busybox
  6161  		ARG %s=""
  6162  		ARG %s=''
  6163  		ARG %s="''"
  6164  		ARG %s='""'
  6165  		RUN [ "$%s" != "$%s" ]
  6166  		RUN [ "$%s" != "$%s" ]
  6167  		RUN [ "$%s" != "$%s" ]
  6168  		RUN [ "$%s" != "$%s" ]
  6169  		RUN [ "$%s" != "$%s" ]`, envKey, envKey1, envKey2, envKey3,
  6170  		envKey, envKey2, envKey, envKey3, envKey1, envKey2, envKey1, envKey3,
  6171  		envKey2, envKey3)
  6172  
  6173  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil {
  6174  		c.Fatalf("build failed to complete: %q %q", out, err)
  6175  	}
  6176  }
  6177  
  6178  func (s *DockerSuite) TestBuildBuildTimeArgEmptyValVariants(c *check.C) {
  6179  	testRequires(c, DaemonIsLinux)
  6180  	imgName := "bldargtest"
  6181  	envKey := "foo"
  6182  	envKey1 := "foo1"
  6183  	envKey2 := "foo2"
  6184  	args := []string{}
  6185  	dockerfile := fmt.Sprintf(`FROM busybox
  6186  		ARG %s=
  6187  		ARG %s=""
  6188  		ARG %s=''
  6189  		RUN [ "$%s" == "$%s" ]
  6190  		RUN [ "$%s" == "$%s" ]
  6191  		RUN [ "$%s" == "$%s" ]`, envKey, envKey1, envKey2, envKey, envKey1, envKey1, envKey2, envKey, envKey2)
  6192  
  6193  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil {
  6194  		c.Fatalf("build failed to complete: %q %q", out, err)
  6195  	}
  6196  }
  6197  
  6198  func (s *DockerSuite) TestBuildBuildTimeArgDefintionWithNoEnvInjection(c *check.C) {
  6199  	testRequires(c, DaemonIsLinux)
  6200  	imgName := "bldargtest"
  6201  	envKey := "foo"
  6202  	args := []string{}
  6203  	dockerfile := fmt.Sprintf(`FROM busybox
  6204  		ARG %s
  6205  		RUN env`, envKey)
  6206  
  6207  	if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envKey) != 1 {
  6208  		if err != nil {
  6209  			c.Fatalf("build failed to complete: %q %q", out, err)
  6210  		}
  6211  		c.Fatalf("unexpected number of occurrences of the arg in output: %q expected: 1", out)
  6212  	}
  6213  }
  6214  
  6215  func (s *DockerSuite) TestBuildNoNamedVolume(c *check.C) {
  6216  	testRequires(c, DaemonIsLinux)
  6217  	dockerCmd(c, "run", "-v", "testname:/foo", "busybox", "sh", "-c", "touch /foo/oops")
  6218  
  6219  	dockerFile := `FROM busybox
  6220  	VOLUME testname:/foo
  6221  	RUN ls /foo/oops
  6222  	`
  6223  	_, err := buildImage("test", dockerFile, false)
  6224  	c.Assert(err, check.NotNil, check.Commentf("image build should have failed"))
  6225  }