From 56fb4653e8b867802d2a33121f933d164a4e6325 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Mon, 10 Apr 2017 14:42:21 +0200 Subject: [PATCH] =?UTF-8?q?Move=20FakeContext=20to=20`integration-cli/cli/?= =?UTF-8?q?build/context`=20package=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … and continue emptying `docker_utils_test.go` from build related function. Signed-off-by: Vincent Demeester --- integration-cli/check_test.go | 2 + integration-cli/cli/build/build.go | 52 + .../cli/build/fakecontext/context.go | 112 ++ .../build/fakestorage/fixtures.go} | 8 +- .../cli/build/fakestorage/storage.go | 176 +++ integration-cli/cli/cli.go | 1 + integration-cli/docker_api_build_test.go | 12 +- integration-cli/docker_cli_build_test.go | 1273 ++++++++--------- integration-cli/docker_cli_build_unix_test.go | 14 +- integration-cli/docker_cli_create_test.go | 16 +- integration-cli/docker_cli_run_test.go | 20 +- integration-cli/docker_utils_test.go | 254 +--- integration-cli/trust_server_test.go | 6 - 13 files changed, 1011 insertions(+), 935 deletions(-) create mode 100644 integration-cli/cli/build/fakecontext/context.go rename integration-cli/{fixtures_test.go => cli/build/fakestorage/fixtures.go} (88%) create mode 100644 integration-cli/cli/build/fakestorage/storage.go diff --git a/integration-cli/check_test.go b/integration-cli/check_test.go index 3b797b463a..f0f4892a38 100644 --- a/integration-cli/check_test.go +++ b/integration-cli/check_test.go @@ -14,6 +14,7 @@ import ( "github.com/docker/docker/api/types/swarm" cliconfig "github.com/docker/docker/cli/config" "github.com/docker/docker/integration-cli/cli" + "github.com/docker/docker/integration-cli/cli/build/fakestorage" "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration-cli/environment" "github.com/docker/docker/integration-cli/registry" @@ -65,6 +66,7 @@ func TestMain(m *testing.M) { func Test(t *testing.T) { cli.EnsureTestEnvIsLoaded(t) + fakestorage.EnsureTestEnvIsLoaded(t) cmd := exec.Command(dockerBinary, "images", "-f", "dangling=false", "--format", "{{.Repository}}:{{.Tag}}") cmd.Env = appendBaseEnv(true) out, err := cmd.CombinedOutput() diff --git a/integration-cli/cli/build/build.go b/integration-cli/cli/build/build.go index 4a186252f9..8ffaa35b4b 100644 --- a/integration-cli/cli/build/build.go +++ b/integration-cli/cli/build/build.go @@ -1,11 +1,30 @@ package build import ( + "io" "strings" + "github.com/docker/docker/integration-cli/cli/build/fakecontext" icmd "github.com/docker/docker/pkg/testutil/cmd" ) +type testingT interface { + Fatal(args ...interface{}) + Fatalf(string, ...interface{}) +} + +// WithStdinContext sets the build context from the standard input with the specified reader +func WithStdinContext(closer io.ReadCloser) func(*icmd.Cmd) func() { + return func(cmd *icmd.Cmd) func() { + cmd.Command = append(cmd.Command, "-") + cmd.Stdin = closer + return func() { + // FIXME(vdemeester) we should not ignore the error here… + closer.Close() + } + } +} + // WithDockerfile creates / returns a CmdOperator to set the Dockerfile for a build operation func WithDockerfile(dockerfile string) func(*icmd.Cmd) func() { return func(cmd *icmd.Cmd) func() { @@ -28,3 +47,36 @@ func WithContextPath(path string) func(*icmd.Cmd) func() { return nil } } + +// WithExternalBuildContext use the specified context as build context +func WithExternalBuildContext(ctx *fakecontext.Fake) func(*icmd.Cmd) func() { + return func(cmd *icmd.Cmd) func() { + cmd.Dir = ctx.Dir + cmd.Command = append(cmd.Command, ".") + return nil + } +} + +// WithBuildContext sets up the build context +func WithBuildContext(t testingT, contextOperators ...func(*fakecontext.Fake) error) func(*icmd.Cmd) func() { + // FIXME(vdemeester) de-duplicate that + ctx := fakecontext.New(t, "", contextOperators...) + return func(cmd *icmd.Cmd) func() { + cmd.Dir = ctx.Dir + cmd.Command = append(cmd.Command, ".") + return closeBuildContext(t, ctx) + } +} + +// WithFile adds the specified file (with content) in the build context +func WithFile(name, content string) func(*fakecontext.Fake) error { + return fakecontext.WithFile(name, content) +} + +func closeBuildContext(t testingT, ctx *fakecontext.Fake) func() { + return func() { + if err := ctx.Close(); err != nil { + t.Fatal(err) + } + } +} diff --git a/integration-cli/cli/build/fakecontext/context.go b/integration-cli/cli/build/fakecontext/context.go new file mode 100644 index 0000000000..94f05c3623 --- /dev/null +++ b/integration-cli/cli/build/fakecontext/context.go @@ -0,0 +1,112 @@ +package fakecontext + +import ( + "bytes" + "io/ioutil" + "os" + "path/filepath" +) + +type testingT interface { + Fatal(args ...interface{}) + Fatalf(string, ...interface{}) +} + +// New creates a fake build context +func New(t testingT, dir string, modifiers ...func(*Fake) error) *Fake { + fakeContext := &Fake{Dir: dir} + if dir == "" { + if err := newDir(fakeContext); err != nil { + t.Fatal(err) + } + } + + for _, modifier := range modifiers { + if err := modifier(fakeContext); err != nil { + t.Fatal(err) + } + } + + return fakeContext +} + +func newDir(fake *Fake) error { + tmp, err := ioutil.TempDir("", "fake-context") + if err != nil { + return err + } + if err := os.Chmod(tmp, 0755); err != nil { + return err + } + fake.Dir = tmp + return nil +} + +// WithFile adds the specified file (with content) in the build context +func WithFile(name, content string) func(*Fake) error { + return func(ctx *Fake) error { + return ctx.Add(name, content) + } +} + +// WithDockerfile adds the specified content as Dockerfile in the build context +func WithDockerfile(content string) func(*Fake) error { + return WithFile("Dockerfile", content) +} + +// WithFiles adds the specified files in the build context, content is a string +func WithFiles(files map[string]string) func(*Fake) error { + return func(fakeContext *Fake) error { + for file, content := range files { + if err := fakeContext.Add(file, content); err != nil { + return err + } + } + return nil + } +} + +// WithBinaryFiles adds the specified files in the build context, content is binary +func WithBinaryFiles(files map[string]*bytes.Buffer) func(*Fake) error { + return func(fakeContext *Fake) error { + for file, content := range files { + if err := fakeContext.Add(file, string(content.Bytes())); err != nil { + return err + } + } + return nil + } +} + +// Fake creates directories that can be used as a build context +type Fake struct { + Dir string +} + +// Add a file at a path, creating directories where necessary +func (f *Fake) Add(file, content string) error { + return f.addFile(file, []byte(content)) +} + +func (f *Fake) addFile(file string, content []byte) error { + fp := filepath.Join(f.Dir, filepath.FromSlash(file)) + dirpath := filepath.Dir(fp) + if dirpath != "." { + if err := os.MkdirAll(dirpath, 0755); err != nil { + return err + } + } + return ioutil.WriteFile(fp, content, 0644) + +} + +// Delete a file at a path +func (f *Fake) Delete(file string) error { + fp := filepath.Join(f.Dir, filepath.FromSlash(file)) + return os.RemoveAll(fp) +} + +// Close deletes the context +func (f *Fake) Close() error { + return os.RemoveAll(f.Dir) +} diff --git a/integration-cli/fixtures_test.go b/integration-cli/cli/build/fakestorage/fixtures.go similarity index 88% rename from integration-cli/fixtures_test.go rename to integration-cli/cli/build/fakestorage/fixtures.go index 9683e4a875..f6a63dcf03 100644 --- a/integration-cli/fixtures_test.go +++ b/integration-cli/cli/build/fakestorage/fixtures.go @@ -1,4 +1,4 @@ -package main +package fakestorage import ( "io/ioutil" @@ -6,6 +6,8 @@ import ( "os/exec" "path/filepath" "sync" + + "github.com/docker/docker/integration-cli/cli" ) var ensureHTTPServerOnce sync.Once @@ -61,7 +63,5 @@ func ensureHTTPServerImage(t testingT) { t.Fatalf("could not build http server: %v", string(out)) } - if out, err = exec.Command(dockerBinary, "build", "-q", "-t", "httpserver", tmp).CombinedOutput(); err != nil { - t.Fatalf("could not build http server: %v", string(out)) - } + cli.DockerCmd(t, "build", "-q", "-t", "httpserver", tmp) } diff --git a/integration-cli/cli/build/fakestorage/storage.go b/integration-cli/cli/build/fakestorage/storage.go new file mode 100644 index 0000000000..49f47e4368 --- /dev/null +++ b/integration-cli/cli/build/fakestorage/storage.go @@ -0,0 +1,176 @@ +package fakestorage + +import ( + "fmt" + "net" + "net/http" + "net/http/httptest" + "net/url" + "os" + "strings" + "sync" + + "github.com/docker/docker/integration-cli/cli" + "github.com/docker/docker/integration-cli/cli/build" + "github.com/docker/docker/integration-cli/cli/build/fakecontext" + "github.com/docker/docker/integration-cli/environment" + "github.com/docker/docker/integration-cli/request" + "github.com/docker/docker/pkg/stringutils" +) + +var ( + testEnv *environment.Execution + onlyOnce sync.Once +) + +// EnsureTestEnvIsLoaded make sure the test environment is loaded for this package +func EnsureTestEnvIsLoaded(t testingT) { + var doIt bool + var err error + onlyOnce.Do(func() { + doIt = true + }) + + if !doIt { + return + } + testEnv, err = environment.New() + if err != nil { + t.Fatalf("error loading testenv : %v", err) + } +} + +type testingT interface { + logT + Fatal(args ...interface{}) + Fatalf(string, ...interface{}) +} + +type logT interface { + Logf(string, ...interface{}) +} + +// Fake is a static file server. It might be running locally or remotely +// on test host. +type Fake interface { + Close() error + URL() string + CtxDir() string +} + +// New returns a static file server that will be use as build context. +func New(t testingT, dir string, modifiers ...func(*fakecontext.Fake) error) Fake { + ctx := fakecontext.New(t, dir, modifiers...) + if testEnv.LocalDaemon() { + return newLocalFakeStorage(t, ctx) + } + return newRemoteFileServer(t, ctx) +} + +// localFileStorage is a file storage on the running machine +type localFileStorage struct { + *fakecontext.Fake + *httptest.Server +} + +func (s *localFileStorage) URL() string { + return s.Server.URL +} + +func (s *localFileStorage) CtxDir() string { + return s.Fake.Dir +} + +func (s *localFileStorage) Close() error { + defer s.Server.Close() + return s.Fake.Close() +} + +func newLocalFakeStorage(t testingT, ctx *fakecontext.Fake) *localFileStorage { + handler := http.FileServer(http.Dir(ctx.Dir)) + server := httptest.NewServer(handler) + return &localFileStorage{ + Fake: ctx, + Server: server, + } +} + +// remoteFileServer is a containerized static file server started on the remote +// testing machine to be used in URL-accepting docker build functionality. +type remoteFileServer struct { + host string // hostname/port web server is listening to on docker host e.g. 0.0.0.0:43712 + container string + image string + ctx *fakecontext.Fake +} + +func (f *remoteFileServer) URL() string { + u := url.URL{ + Scheme: "http", + Host: f.host} + return u.String() +} + +func (f *remoteFileServer) CtxDir() string { + return f.ctx.Dir +} + +func (f *remoteFileServer) Close() error { + defer func() { + if f.ctx != nil { + f.ctx.Close() + } + if f.image != "" { + if err := cli.Docker(cli.Args("rmi", "-f", f.image)).Error; err != nil { + fmt.Fprintf(os.Stderr, "Error closing remote file server : %v\n", err) + } + } + }() + if f.container == "" { + return nil + } + return cli.Docker(cli.Args("rm", "-fv", f.container)).Error +} + +func newRemoteFileServer(t testingT, ctx *fakecontext.Fake) *remoteFileServer { + var ( + image = fmt.Sprintf("fileserver-img-%s", strings.ToLower(stringutils.GenerateRandomAlphaOnlyString(10))) + container = fmt.Sprintf("fileserver-cnt-%s", strings.ToLower(stringutils.GenerateRandomAlphaOnlyString(10))) + ) + + ensureHTTPServerImage(t) + + // Build the image + if err := ctx.Add("Dockerfile", `FROM httpserver +COPY . /static`); err != nil { + t.Fatal(err) + } + cli.BuildCmd(t, image, build.WithoutCache, build.WithExternalBuildContext(ctx)) + + // Start the container + cli.DockerCmd(t, "run", "-d", "-P", "--name", container, image) + + // Find out the system assigned port + out := cli.DockerCmd(t, "port", container, "80/tcp").Combined() + fileserverHostPort := strings.Trim(out, "\n") + _, port, err := net.SplitHostPort(fileserverHostPort) + if err != nil { + t.Fatalf("unable to parse file server host:port: %v", err) + } + + dockerHostURL, err := url.Parse(request.DaemonHost()) + if err != nil { + t.Fatalf("unable to parse daemon host URL: %v", err) + } + + host, _, err := net.SplitHostPort(dockerHostURL.Host) + if err != nil { + t.Fatalf("unable to parse docker daemon host:port: %v", err) + } + + return &remoteFileServer{ + container: container, + image: image, + host: fmt.Sprintf("%s:%s", host, port), + ctx: ctx} +} diff --git a/integration-cli/cli/cli.go b/integration-cli/cli/cli.go index b1f22dbfc7..ed920b5273 100644 --- a/integration-cli/cli/cli.go +++ b/integration-cli/cli/cli.go @@ -39,6 +39,7 @@ func EnsureTestEnvIsLoaded(t testingT) { type CmdOperator func(*icmd.Cmd) func() type testingT interface { + Fatal(args ...interface{}) Fatalf(string, ...interface{}) } diff --git a/integration-cli/docker_api_build_test.go b/integration-cli/docker_api_build_test.go index 0a1cd70dde..14071e4239 100644 --- a/integration-cli/docker_api_build_test.go +++ b/integration-cli/docker_api_build_test.go @@ -9,6 +9,8 @@ import ( "strings" "github.com/docker/docker/integration-cli/checker" + "github.com/docker/docker/integration-cli/cli/build/fakecontext" + "github.com/docker/docker/integration-cli/cli/build/fakestorage" "github.com/docker/docker/integration-cli/request" "github.com/docker/docker/pkg/testutil" "github.com/go-check/check" @@ -29,7 +31,7 @@ COPY * /tmp/ RUN find / -xdev -name ba* RUN find /tmp/` } - server := fakeStorage(c, map[string]string{"testD": testD}) + server := fakestorage.New(c, "", fakecontext.WithFiles(map[string]string{"testD": testD})) defer server.Close() res, body, err := request.Post("/build?dockerfile=baz&remote="+server.URL()+"/testD", request.JSON) @@ -66,9 +68,9 @@ func (s *DockerSuite) TestBuildAPIRemoteTarballContext(c *check.C) { // failed to close tar archive c.Assert(tw.Close(), checker.IsNil) - server := fakeBinaryStorage(c, map[string]*bytes.Buffer{ + server := fakestorage.New(c, "", fakecontext.WithBinaryFiles(map[string]*bytes.Buffer{ "testT.tar": buffer, - }) + })) defer server.Close() res, b, err := request.Post("/build?remote="+server.URL()+"/testT.tar", request.ContentType("application/tar")) @@ -113,9 +115,9 @@ RUN echo 'right' // failed to close tar archive c.Assert(tw.Close(), checker.IsNil) - server := fakeBinaryStorage(c, map[string]*bytes.Buffer{ + server := fakestorage.New(c, "", fakecontext.WithBinaryFiles(map[string]*bytes.Buffer{ "testT.tar": buffer, - }) + })) defer server.Close() url := "/build?dockerfile=custom&remote=" + server.URL() + "/testT.tar" diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index ea25959e44..7bfc2c07e2 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -20,6 +20,8 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli/build" + "github.com/docker/docker/integration-cli/cli/build/fakecontext" + "github.com/docker/docker/integration-cli/cli/build/fakestorage" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/stringutils" "github.com/docker/docker/pkg/testutil" @@ -143,8 +145,8 @@ func (s *DockerSuite) TestBuildEnvironmentReplacementWorkdir(c *check.C) { func (s *DockerSuite) TestBuildEnvironmentReplacementAddCopy(c *check.C) { name := "testbuildenvironmentreplacement" - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", ` + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", ` FROM `+minimalBaseImage()+` ENV baz foo ENV quux bar @@ -157,10 +159,10 @@ func (s *DockerSuite) TestBuildEnvironmentReplacementAddCopy(c *check.C) { ADD ${zzz:-${fee}} ${dot} COPY ${zzz:-${gee}} ${dot} `), - withFile("foo", "test1"), - withFile("bar", "test2"), - withFile("fff", "test3"), - withFile("ggg", "test4"), + build.WithFile("foo", "test1"), + build.WithFile("bar", "test2"), + build.WithFile("fff", "test3"), + build.WithFile("ggg", "test4"), )) } @@ -362,10 +364,10 @@ ONBUILD ENTRYPOINT ["echo"]`)) func (s *DockerSuite) TestBuildCacheAdd(c *check.C) { testRequires(c, DaemonIsLinux) // Windows doesn't have httpserver image yet name := "testbuildtwoimageswithadd" - server := fakeStorage(c, map[string]string{ + server := fakestorage.New(c, "", fakecontext.WithFiles(map[string]string{ "robots.txt": "hello", "index.html": "world", - }) + })) defer server.Close() cli.BuildCmd(c, name, build.WithDockerfile(fmt.Sprintf(`FROM scratch @@ -386,9 +388,9 @@ func (s *DockerSuite) TestBuildLastModified(c *check.C) { name := "testbuildlastmodified" - server := fakeStorage(c, map[string]string{ + server := fakestorage.New(c, "", fakecontext.WithFiles(map[string]string{ "file": "hello", - }) + })) defer server.Close() var out, out2 string @@ -397,15 +399,15 @@ func (s *DockerSuite) TestBuildLastModified(c *check.C) { ADD %s/file /` dockerfile := fmt.Sprintf(dFmt, server.URL()) - buildImageSuccessfully(c, name, build.WithoutCache, build.WithDockerfile(dockerfile)) - out, _ = dockerCmd(c, "run", name, "ls", "-le", "/file") + cli.BuildCmd(c, name, build.WithoutCache, build.WithDockerfile(dockerfile)) + out = cli.DockerCmd(c, "run", name, "ls", "-le", "/file").Combined() // Build it again and make sure the mtime of the file didn't change. // Wait a few seconds to make sure the time changed enough to notice time.Sleep(2 * time.Second) - buildImageSuccessfully(c, name, build.WithoutCache, build.WithDockerfile(dockerfile)) - out2, _ = dockerCmd(c, "run", name, "ls", "-le", "/file") + cli.BuildCmd(c, name, build.WithoutCache, build.WithDockerfile(dockerfile)) + out2 = cli.DockerCmd(c, "run", name, "ls", "-le", "/file").Combined() if out != out2 { c.Fatalf("MTime changed:\nOrigin:%s\nNew:%s", out, out2) @@ -413,14 +415,14 @@ ADD %s/file /` // Now 'touch' the file and make sure the timestamp DID change this time // Create a new fakeStorage instead of just using Add() to help windows - server = fakeStorage(c, map[string]string{ + server = fakestorage.New(c, "", fakecontext.WithFiles(map[string]string{ "file": "hello", - }) + })) defer server.Close() dockerfile = fmt.Sprintf(dFmt, server.URL()) - buildImageSuccessfully(c, name, build.WithoutCache, build.WithDockerfile(dockerfile)) - out2, _ = dockerCmd(c, "run", name, "ls", "-le", "/file") + cli.BuildCmd(c, name, build.WithoutCache, build.WithDockerfile(dockerfile)) + out2 = cli.DockerCmd(c, "run", name, "ls", "-le", "/file").Combined() if out == out2 { c.Fatalf("MTime didn't change:\nOrigin:%s\nNew:%s", out, out2) @@ -434,20 +436,19 @@ ADD %s/file /` func (s *DockerSuite) TestBuildModifyFileInFolder(c *check.C) { name := "testbuildmodifyfileinfolder" - ctx := fakeContext(c, `FROM busybox + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(`FROM busybox RUN ["mkdir", "/test"] -ADD folder/file /test/changetarget`, - map[string]string{}) +ADD folder/file /test/changetarget`)) defer ctx.Close() if err := ctx.Add("folder/file", "first"); err != nil { c.Fatal(err) } - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, name) if err := ctx.Add("folder/file", "second"); err != nil { c.Fatal(err) } - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, name) if id1 == id2 { c.Fatal("cache was used even though file contents in folder was changed") @@ -456,8 +457,8 @@ ADD folder/file /test/changetarget`, func (s *DockerSuite) TestBuildAddSingleFileToRoot(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - buildImageSuccessfully(c, "testaddimg", withBuildContext(c, - withFile("Dockerfile", fmt.Sprintf(`FROM busybox + buildImageSuccessfully(c, "testaddimg", build.WithBuildContext(c, + build.WithFile("Dockerfile", fmt.Sprintf(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN touch /exists @@ -466,22 +467,23 @@ ADD test_file / RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /test_file | awk '{print $1}') = '%s' ] RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod)), - withFile("test_file", "test1"))) + build.WithFile("test_file", "test1"))) } // Issue #3960: "ADD src ." hangs func (s *DockerSuite) TestBuildAddSingleFileToWorkdir(c *check.C) { name := "testaddsinglefiletoworkdir" - ctx := fakeContext(c, `FROM busybox -ADD test_file .`, - map[string]string{ + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile( + `FROM busybox + ADD test_file .`), + fakecontext.WithFiles(map[string]string{ "test_file": "test1", - }) + })) defer ctx.Close() errChan := make(chan error) go func() { - errChan <- buildImage(name, withExternalBuildContext(ctx)).Error + errChan <- buildImage(name, build.WithExternalBuildContext(ctx)).Error close(errChan) }() select { @@ -494,8 +496,8 @@ ADD test_file .`, func (s *DockerSuite) TestBuildAddSingleFileToExistDir(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - buildImageSuccessfully(c, "testaddsinglefiletoexistdir", withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, "testaddsinglefiletoexistdir", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN mkdir /exists @@ -505,18 +507,18 @@ ADD test_file /exists/ RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ] RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`), - withFile("test_file", "test1"))) + build.WithFile("test_file", "test1"))) } func (s *DockerSuite) TestBuildCopyAddMultipleFiles(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - server := fakeStorage(c, map[string]string{ + server := fakestorage.New(c, "", fakecontext.WithFiles(map[string]string{ "robots.txt": "hello", - }) + })) defer server.Close() - buildImageSuccessfully(c, "testcopymultiplefilestofile", withBuildContext(c, - withFile("Dockerfile", fmt.Sprintf(`FROM busybox + cli.BuildCmd(c, "testcopymultiplefilestofile", build.WithBuildContext(c, + build.WithFile("Dockerfile", fmt.Sprintf(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN mkdir /exists @@ -532,11 +534,11 @@ RUN [ $(ls -l /exists/test_file4 | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /exists/robots.txt | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ] `, server.URL())), - withFile("test_file1", "test1"), - withFile("test_file2", "test2"), - withFile("test_file3", "test3"), - withFile("test_file3", "test3"), - withFile("test_file4", "test4"))) + build.WithFile("test_file1", "test1"), + build.WithFile("test_file2", "test2"), + build.WithFile("test_file3", "test3"), + build.WithFile("test_file3", "test3"), + build.WithFile("test_file4", "test4"))) } // These tests are mainly for user namespaces to verify that new directories @@ -550,11 +552,11 @@ func (s *DockerSuite) TestBuildUsernamespaceValidateRemappedRoot(c *check.C) { } name := "testbuildusernamespacevalidateremappedroot" for _, tc := range testCases { - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", fmt.Sprintf(`FROM busybox + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", fmt.Sprintf(`FROM busybox %s RUN [ $(ls -l / | grep new_dir | awk '{print $3":"$4}') = 'root:root' ]`, tc)), - withFile("test_dir/test_file", "test file"))) + build.WithFile("test_dir/test_file", "test file"))) dockerCmd(c, "rmi", name) } @@ -565,8 +567,8 @@ func (s *DockerSuite) TestBuildAddAndCopyFileWithWhitespace(c *check.C) { name := "testaddfilewithwhitespace" for _, command := range []string{"ADD", "COPY"} { - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", fmt.Sprintf(`FROM busybox + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", fmt.Sprintf(`FROM busybox RUN mkdir "/test dir" RUN mkdir "/test_dir" %s [ "test file1", "/test_file1" ] @@ -581,12 +583,12 @@ RUN [ $(cat "/test file3") = 'test3' ] RUN [ $(cat "/test_dir/test_file4") = 'test4' ] RUN [ $(cat "/test dir/test_file5") = 'test5' ] RUN [ $(cat "/test dir/test_file6") = 'test6' ]`, command, command, command, command, command, command)), - withFile("test file1", "test1"), - withFile("test_file2", "test2"), - withFile("test file3", "test3"), - withFile("test dir/test_file4", "test4"), - withFile("test_dir/test_file5", "test5"), - withFile("test dir/test_file6", "test6"), + build.WithFile("test file1", "test1"), + build.WithFile("test_file2", "test2"), + build.WithFile("test file3", "test3"), + build.WithFile("test dir/test_file4", "test4"), + build.WithFile("test_dir/test_file5", "test5"), + build.WithFile("test dir/test_file6", "test6"), )) dockerCmd(c, "rmi", name) @@ -612,26 +614,26 @@ RUN find "test5" "C:/test dir/test_file5" RUN find "test6" "C:/test dir/test_file6"` name := "testcopyfilewithwhitespace" - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile("test file1", "test1"), - withFile("test_file2", "test2"), - withFile("test file3", "test3"), - withFile("test dir/test_file4", "test4"), - withFile("test_dir/test_file5", "test5"), - withFile("test dir/test_file6", "test6"), + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile("test file1", "test1"), + build.WithFile("test_file2", "test2"), + build.WithFile("test file3", "test3"), + build.WithFile("test dir/test_file4", "test4"), + build.WithFile("test_dir/test_file5", "test5"), + build.WithFile("test dir/test_file6", "test6"), )) } func (s *DockerSuite) TestBuildCopyWildcard(c *check.C) { name := "testcopywildcard" - server := fakeStorage(c, map[string]string{ + server := fakestorage.New(c, "", fakecontext.WithFiles(map[string]string{ "robots.txt": "hello", "index.html": "world", - }) + })) defer server.Close() - ctx := fakeContext(c, fmt.Sprintf(`FROM busybox + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(fmt.Sprintf(`FROM busybox COPY file*.txt /tmp/ RUN ls /tmp/file1.txt /tmp/file2.txt RUN [ "mkdir", "/tmp1" ] @@ -640,21 +642,21 @@ func (s *DockerSuite) TestBuildCopyWildcard(c *check.C) { RUN [ "mkdir", "/tmp2" ] ADD dir/*dir %s/robots.txt /tmp2/ RUN ls /tmp2/nest_nest_file /tmp2/robots.txt - `, server.URL()), - map[string]string{ + `, server.URL())), + fakecontext.WithFiles(map[string]string{ "file1.txt": "test1", "file2.txt": "test2", "dir/nested_file": "nested file", "dir/nested_dir/nest_nest_file": "2 times nested", "dirt": "dirty", - }) + })) defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, name) // Now make sure we use a cache the 2nd time - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, name) if id1 != id2 { @@ -674,25 +676,25 @@ func (s *DockerSuite) TestBuildCopyWildcardInName(c *check.C) { // say which OSs this works on or not. testRequires(c, DaemonIsLinux, UnixCli) - buildImageSuccessfully(c, "testcopywildcardinname", withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, "testcopywildcardinname", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox COPY *.txt /tmp/ RUN [ "$(cat /tmp/\*.txt)" = 'hi there' ] `), - withFile("*.txt", "hi there"), + build.WithFile("*.txt", "hi there"), )) } func (s *DockerSuite) TestBuildCopyWildcardCache(c *check.C) { name := "testcopywildcardcache" - ctx := fakeContext(c, `FROM busybox - COPY file1.txt /tmp/`, - map[string]string{ + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(`FROM busybox + COPY file1.txt /tmp/`), + fakecontext.WithFiles(map[string]string{ "file1.txt": "test1", - }) + })) defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, name) // Now make sure we use a cache the 2nd time even with wild cards. @@ -700,7 +702,7 @@ func (s *DockerSuite) TestBuildCopyWildcardCache(c *check.C) { ctx.Add("Dockerfile", `FROM busybox COPY file*.txt /tmp/`) - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, name) if id1 != id2 { @@ -711,8 +713,8 @@ func (s *DockerSuite) TestBuildCopyWildcardCache(c *check.C) { func (s *DockerSuite) TestBuildAddSingleFileToNonExistingDir(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - buildImageSuccessfully(c, "testaddsinglefiletononexistingdir", withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, "testaddsinglefiletononexistingdir", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN touch /exists @@ -721,13 +723,13 @@ ADD test_file /test_dir/ RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`), - withFile("test_file", "test1"))) + build.WithFile("test_file", "test1"))) } func (s *DockerSuite) TestBuildAddDirContentToRoot(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - buildImageSuccessfully(c, "testadddircontenttoroot", withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, "testadddircontenttoroot", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN touch /exists @@ -735,13 +737,13 @@ RUN chown dockerio.dockerio exists ADD test_dir / RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`), - withFile("test_dir/test_file", "test1"))) + build.WithFile("test_dir/test_file", "test1"))) } func (s *DockerSuite) TestBuildAddDirContentToExistingDir(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - buildImageSuccessfully(c, "testadddircontenttoexistingdir", withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, "testadddircontenttoexistingdir", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN mkdir /exists @@ -751,13 +753,13 @@ ADD test_dir/ /exists/ RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ] RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ] RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`), - withFile("test_dir/test_file", "test1"))) + build.WithFile("test_dir/test_file", "test1"))) } func (s *DockerSuite) TestBuildAddWholeDirToRoot(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - buildImageSuccessfully(c, "testaddwholedirtoroot", withBuildContext(c, - withFile("Dockerfile", fmt.Sprintf(`FROM busybox + buildImageSuccessfully(c, "testaddwholedirtoroot", build.WithBuildContext(c, + build.WithFile("Dockerfile", fmt.Sprintf(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN touch /exists @@ -768,39 +770,39 @@ RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ] RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '%s' ] RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod)), - withFile("test_dir/test_file", "test1"))) + build.WithFile("test_dir/test_file", "test1"))) } // Testing #5941 : Having an etc directory in context conflicts with the /etc/mtab func (s *DockerSuite) TestBuildAddOrCopyEtcToRootShouldNotConflict(c *check.C) { - buildImageSuccessfully(c, "testaddetctoroot", withBuildContext(c, - withFile("Dockerfile", `FROM `+minimalBaseImage()+` + buildImageSuccessfully(c, "testaddetctoroot", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM `+minimalBaseImage()+` ADD . /`), - withFile("etc/test_file", "test1"))) - buildImageSuccessfully(c, "testcopyetctoroot", withBuildContext(c, - withFile("Dockerfile", `FROM `+minimalBaseImage()+` + build.WithFile("etc/test_file", "test1"))) + buildImageSuccessfully(c, "testcopyetctoroot", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM `+minimalBaseImage()+` COPY . /`), - withFile("etc/test_file", "test1"))) + build.WithFile("etc/test_file", "test1"))) } // Testing #9401 : Losing setuid flag after a ADD func (s *DockerSuite) TestBuildAddPreservesFilesSpecialBits(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - buildImageSuccessfully(c, "testaddetctoroot", withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, "testaddetctoroot", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox ADD suidbin /usr/bin/suidbin RUN chmod 4755 /usr/bin/suidbin RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ] ADD ./data/ / RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ]`), - withFile("suidbin", "suidbin"), - withFile("/data/usr/test_file", "test1"))) + build.WithFile("suidbin", "suidbin"), + build.WithFile("/data/usr/test_file", "test1"))) } func (s *DockerSuite) TestBuildCopySingleFileToRoot(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - buildImageSuccessfully(c, "testcopysinglefiletoroot", withBuildContext(c, - withFile("Dockerfile", fmt.Sprintf(`FROM busybox + buildImageSuccessfully(c, "testcopysinglefiletoroot", build.WithBuildContext(c, + build.WithFile("Dockerfile", fmt.Sprintf(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN touch /exists @@ -809,22 +811,22 @@ COPY test_file / RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /test_file | awk '{print $1}') = '%s' ] RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod)), - withFile("test_file", "test1"))) + build.WithFile("test_file", "test1"))) } // Issue #3960: "ADD src ." hangs - adapted for COPY func (s *DockerSuite) TestBuildCopySingleFileToWorkdir(c *check.C) { name := "testcopysinglefiletoworkdir" - ctx := fakeContext(c, `FROM busybox -COPY test_file .`, - map[string]string{ + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(`FROM busybox +COPY test_file .`), + fakecontext.WithFiles(map[string]string{ "test_file": "test1", - }) + })) defer ctx.Close() errChan := make(chan error) go func() { - errChan <- buildImage(name, withExternalBuildContext(ctx)).Error + errChan <- buildImage(name, build.WithExternalBuildContext(ctx)).Error close(errChan) }() select { @@ -837,8 +839,8 @@ COPY test_file .`, func (s *DockerSuite) TestBuildCopySingleFileToExistDir(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - buildImageSuccessfully(c, "testcopysinglefiletoexistdir", withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, "testcopysinglefiletoexistdir", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN mkdir /exists @@ -848,13 +850,13 @@ COPY test_file /exists/ RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ] RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`), - withFile("test_file", "test1"))) + build.WithFile("test_file", "test1"))) } func (s *DockerSuite) TestBuildCopySingleFileToNonExistDir(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific - buildImageSuccessfully(c, "testcopysinglefiletononexistdir", withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, "testcopysinglefiletononexistdir", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN touch /exists @@ -863,13 +865,13 @@ COPY test_file /test_dir/ RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`), - withFile("test_file", "test1"))) + build.WithFile("test_file", "test1"))) } func (s *DockerSuite) TestBuildCopyDirContentToRoot(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - buildImageSuccessfully(c, "testcopydircontenttoroot", withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, "testcopydircontenttoroot", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN touch /exists @@ -877,13 +879,13 @@ RUN chown dockerio.dockerio exists COPY test_dir / RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`), - withFile("test_dir/test_file", "test1"))) + build.WithFile("test_dir/test_file", "test1"))) } func (s *DockerSuite) TestBuildCopyDirContentToExistDir(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - buildImageSuccessfully(c, "testcopydircontenttoexistdir", withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, "testcopydircontenttoexistdir", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN mkdir /exists @@ -893,13 +895,13 @@ COPY test_dir/ /exists/ RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ] RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ] RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`), - withFile("test_dir/test_file", "test1"))) + build.WithFile("test_dir/test_file", "test1"))) } func (s *DockerSuite) TestBuildCopyWholeDirToRoot(c *check.C) { testRequires(c, DaemonIsLinux) // Linux specific test - buildImageSuccessfully(c, "testcopywholedirtoroot", withBuildContext(c, - withFile("Dockerfile", fmt.Sprintf(`FROM busybox + buildImageSuccessfully(c, "testcopywholedirtoroot", build.WithBuildContext(c, + build.WithFile("Dockerfile", fmt.Sprintf(`FROM busybox RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd RUN echo 'dockerio:x:1001:' >> /etc/group RUN touch /exists @@ -910,7 +912,7 @@ RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ] RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ] RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '%s' ] RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod)), - withFile("test_dir/test_file", "test1"))) + build.WithFile("test_dir/test_file", "test1"))) } func (s *DockerSuite) TestBuildAddBadLinks(c *check.C) { @@ -925,7 +927,7 @@ func (s *DockerSuite) TestBuildAddBadLinks(c *check.C) { var ( name = "test-link-absolute" ) - ctx := fakeContext(c, dockerfile, nil) + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(dockerfile)) defer ctx.Close() tempDir, err := ioutil.TempDir("", "test-link-absolute-temp-") @@ -986,7 +988,7 @@ func (s *DockerSuite) TestBuildAddBadLinks(c *check.C) { c.Fatal(err) } - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) if _, err := os.Stat(nonExistingFile); err == nil || err != nil && !os.IsNotExist(err) { c.Fatalf("%s shouldn't have been written and it shouldn't exist", nonExistingFile) } @@ -1017,7 +1019,7 @@ func (s *DockerSuite) TestBuildAddBadLinksVolume(c *check.C) { dockerfile = fmt.Sprintf(dockerfileTemplate, tempDir) nonExistingFile := filepath.Join(tempDir, targetFile) - ctx := fakeContext(c, dockerfile, nil) + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(dockerfile)) defer ctx.Close() fooPath := filepath.Join(ctx.Dir, targetFile) @@ -1031,7 +1033,7 @@ func (s *DockerSuite) TestBuildAddBadLinksVolume(c *check.C) { c.Fatal(err) } - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) if _, err := os.Stat(nonExistingFile); err == nil || err != nil && !os.IsNotExist(err) { c.Fatalf("%s shouldn't have been written and it shouldn't exist", nonExistingFile) } @@ -1045,7 +1047,10 @@ func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) { { name := "testbuildinaccessiblefiles" - ctx := fakeContext(c, "FROM scratch\nADD . /foo/", map[string]string{"fileWithoutReadAccess": "foo"}) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile("FROM scratch\nADD . /foo/"), + fakecontext.WithFiles(map[string]string{"fileWithoutReadAccess": "foo"}), + ) defer ctx.Close() // This is used to ensure we detect inaccessible files early during build in the cli client pathToFileWithoutReadAccess := filepath.Join(ctx.Dir, "fileWithoutReadAccess") @@ -1075,7 +1080,10 @@ func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) { } { name := "testbuildinaccessibledirectory" - ctx := fakeContext(c, "FROM scratch\nADD . /foo/", map[string]string{"directoryWeCantStat/bar": "foo"}) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile("FROM scratch\nADD . /foo/"), + fakecontext.WithFiles(map[string]string{"directoryWeCantStat/bar": "foo"}), + ) defer ctx.Close() // This is used to ensure we detect inaccessible directories early during build in the cli client pathToDirectoryWithoutReadAccess := filepath.Join(ctx.Dir, "directoryWeCantStat") @@ -1111,7 +1119,7 @@ func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) { } { name := "testlinksok" - ctx := fakeContext(c, "FROM scratch\nADD . /foo/", nil) + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile("FROM scratch\nADD . /foo/")) defer ctx.Close() target := "../../../../../../../../../../../../../../../../../../../azA" @@ -1121,15 +1129,17 @@ func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) { defer os.Remove(target) // This is used to ensure we don't follow links when checking if everything in the context is accessible // This test doesn't require that we run commands as an unprivileged user - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) } { name := "testbuildignoredinaccessible" - ctx := fakeContext(c, "FROM scratch\nADD . /foo/", - map[string]string{ + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile("FROM scratch\nADD . /foo/"), + fakecontext.WithFiles(map[string]string{ "directoryWeCantStat/bar": "foo", ".dockerignore": "directoryWeCantStat", - }) + }), + ) defer ctx.Close() // This is used to ensure we don't try to add inaccessible files when they are ignored by a .dockerignore pattern pathToDirectoryWithoutReadAccess := filepath.Join(ctx.Dir, "directoryWeCantStat") @@ -1157,8 +1167,8 @@ func (s *DockerSuite) TestBuildForceRm(c *check.C) { containerCountBefore := getContainerCount(c) name := "testbuildforcerm" - buildImage(name, cli.WithFlags("--force-rm"), withBuildContext(c, - withFile("Dockerfile", `FROM `+minimalBaseImage()+` + buildImage(name, cli.WithFlags("--force-rm"), build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM `+minimalBaseImage()+` RUN true RUN thiswillfail`))).Assert(c, icmd.Expected{ ExitCode: 1, @@ -1335,8 +1345,8 @@ func (s *DockerSuite) TestBuildWindowsAddCopyPathProcessing(c *check.C) { // support backslash such as .\\ being equivalent to ./ and c:\\ being // equivalent to c:/. This is not currently (nor ever has been) supported // by docker on the Windows platform. - buildImageSuccessfully(c, "testbuildwindowsaddcopypathprocessing", withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, "testbuildwindowsaddcopypathprocessing", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox # No trailing slash on COPY/ADD # Results in dir being changed to a file WORKDIR /wc1 @@ -1355,10 +1365,10 @@ func (s *DockerSuite) TestBuildWindowsAddCopyPathProcessing(c *check.C) { RUN sh -c "[ $(cat c:/wd1/wd1) = 'hellowd1' ]" RUN sh -c "[ $(cat c:/wd2/wd2) = 'worldwd2' ]" `), - withFile("wc1", "hellowc1"), - withFile("wc2", "worldwc2"), - withFile("wd1", "hellowd1"), - withFile("wd2", "worldwd2"), + build.WithFile("wc1", "hellowc1"), + build.WithFile("wc2", "worldwc2"), + build.WithFile("wd1", "hellowd1"), + build.WithFile("wd2", "worldwd2"), )) } @@ -1394,8 +1404,8 @@ func (s *DockerSuite) TestBuildRelativeCopy(c *check.C) { expected = `/test1/test2` } - buildImageSuccessfully(c, "testbuildrelativecopy", withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, "testbuildrelativecopy", build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox WORKDIR /test1 WORKDIR test2 RUN sh -c "[ "$PWD" = '`+expected+`' ]" @@ -1417,7 +1427,7 @@ func (s *DockerSuite) TestBuildRelativeCopy(c *check.C) { COPY foo ../ RUN sh -c "[ $(cat /test5/foo) = 'hello' ]" `), - withFile("foo", "hello"), + build.WithFile("foo", "hello"), )) } @@ -1741,12 +1751,14 @@ func (s *DockerSuite) TestBuildConditionalCache(c *check.C) { dockerfile := ` FROM busybox ADD foo /tmp/` - ctx := fakeContext(c, dockerfile, map[string]string{ - "foo": "hello", - }) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + "foo": "hello", + })) defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, name) if err := ctx.Add("foo", "bye"); err != nil { @@ -1754,13 +1766,13 @@ func (s *DockerSuite) TestBuildConditionalCache(c *check.C) { } // Updating a file should invalidate the cache - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, name) if id2 == id1 { c.Fatal("Should not have used the cache") } - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id3 := getIDByName(c, name) if id3 != id2 { c.Fatal("Should have used the cache") @@ -1775,15 +1787,15 @@ func (s *DockerSuite) TestBuildAddMultipleLocalFileWithAndWithoutCache(c *check. MAINTAINER dockerio ADD foo Dockerfile /usr/lib/bla/ RUN sh -c "[ $(cat /usr/lib/bla/foo) = "hello" ]"` - ctx := fakeContext(c, dockerfile, map[string]string{ + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(dockerfile), fakecontext.WithFiles(map[string]string{ "foo": "hello", - }) + })) defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, name) - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, name) - buildImageSuccessfully(c, name, build.WithoutCache, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithoutCache, build.WithExternalBuildContext(ctx)) id3 := getIDByName(c, name) if id1 != id2 { c.Fatal("The cache should have been used but hasn't.") @@ -1800,17 +1812,17 @@ func (s *DockerSuite) TestBuildCopyDirButNotFile(c *check.C) { dockerfile := ` FROM ` + minimalBaseImage() + ` COPY dir /tmp/` - ctx := fakeContext(c, dockerfile, map[string]string{ + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(dockerfile), fakecontext.WithFiles(map[string]string{ "dir/foo": "hello", - }) + })) defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, name) // Check that adding file with similar name doesn't mess with cache if err := ctx.Add("dir_file", "hello2"); err != nil { c.Fatal(err) } - buildImageSuccessfully(c, name2, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name2, build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, name2) if id1 != id2 { c.Fatal("The cache should have been used but wasn't") @@ -1826,17 +1838,17 @@ func (s *DockerSuite) TestBuildAddCurrentDirWithCache(c *check.C) { FROM ` + minimalBaseImage() + ` MAINTAINER dockerio ADD . /usr/lib/bla` - ctx := fakeContext(c, dockerfile, map[string]string{ + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(dockerfile), fakecontext.WithFiles(map[string]string{ "foo": "hello", - }) + })) defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, name) // Check that adding file invalidate cache of "ADD ." if err := ctx.Add("bar", "hello2"); err != nil { c.Fatal(err) } - buildImageSuccessfully(c, name2, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name2, build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, name2) if id1 == id2 { c.Fatal("The cache should have been invalided but hasn't.") @@ -1845,7 +1857,7 @@ func (s *DockerSuite) TestBuildAddCurrentDirWithCache(c *check.C) { if err := ctx.Add("foo", "hello1"); err != nil { c.Fatal(err) } - buildImageSuccessfully(c, name3, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name3, build.WithExternalBuildContext(ctx)) id3 := getIDByName(c, name3) if id2 == id3 { c.Fatal("The cache should have been invalided but hasn't.") @@ -1856,7 +1868,7 @@ func (s *DockerSuite) TestBuildAddCurrentDirWithCache(c *check.C) { if err := ctx.Add("foo", "hello1"); err != nil { c.Fatal(err) } - buildImageSuccessfully(c, name4, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name4, build.WithExternalBuildContext(ctx)) id4 := getIDByName(c, name4) if id3 != id4 { c.Fatal("The cache should have been used but hasn't.") @@ -1870,13 +1882,13 @@ func (s *DockerSuite) TestBuildAddCurrentDirWithoutCache(c *check.C) { FROM ` + minimalBaseImage() + ` MAINTAINER dockerio ADD . /usr/lib/bla` - ctx := fakeContext(c, dockerfile, map[string]string{ + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(dockerfile), fakecontext.WithFiles(map[string]string{ "foo": "hello", - }) + })) defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, name) - buildImageSuccessfully(c, name, build.WithoutCache, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithoutCache, build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, name) if id1 == id2 { c.Fatal("The cache should have been invalided but hasn't.") @@ -1885,19 +1897,19 @@ func (s *DockerSuite) TestBuildAddCurrentDirWithoutCache(c *check.C) { func (s *DockerSuite) TestBuildAddRemoteFileWithAndWithoutCache(c *check.C) { name := "testbuildaddremotefilewithcache" - server := fakeStorage(c, map[string]string{ + server := fakestorage.New(c, "", fakecontext.WithFiles(map[string]string{ "baz": "hello", - }) + })) defer server.Close() dockerfile := fmt.Sprintf(`FROM `+minimalBaseImage()+` MAINTAINER dockerio ADD %s/baz /usr/lib/baz/quux`, server.URL()) - buildImageSuccessfully(c, name, build.WithDockerfile(dockerfile)) + cli.BuildCmd(c, name, build.WithDockerfile(dockerfile)) id1 := getIDByName(c, name) - buildImageSuccessfully(c, name, build.WithDockerfile(dockerfile)) + cli.BuildCmd(c, name, build.WithDockerfile(dockerfile)) id2 := getIDByName(c, name) - buildImageSuccessfully(c, name, build.WithoutCache, build.WithDockerfile(dockerfile)) + cli.BuildCmd(c, name, build.WithoutCache, build.WithDockerfile(dockerfile)) id3 := getIDByName(c, name) if id1 != id2 { @@ -1914,17 +1926,17 @@ func (s *DockerSuite) TestBuildAddRemoteFileMTime(c *check.C) { name3 := name + "3" files := map[string]string{"baz": "hello"} - server := fakeStorage(c, files) + server := fakestorage.New(c, "", fakecontext.WithFiles(files)) defer server.Close() - ctx := fakeContext(c, fmt.Sprintf(`FROM `+minimalBaseImage()+` + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(fmt.Sprintf(`FROM `+minimalBaseImage()+` MAINTAINER dockerio - ADD %s/baz /usr/lib/baz/quux`, server.URL()), nil) + ADD %s/baz /usr/lib/baz/quux`, server.URL()))) defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, name) - buildImageSuccessfully(c, name2, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name2, build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, name2) if id1 != id2 { c.Fatal("The cache should have been used but wasn't - #1") @@ -1936,14 +1948,14 @@ func (s *DockerSuite) TestBuildAddRemoteFileMTime(c *check.C) { // allow some time for clock to pass as mtime precision is only 1s time.Sleep(2 * time.Second) - server2 := fakeStorage(c, files) + server2 := fakestorage.New(c, "", fakecontext.WithFiles(files)) defer server2.Close() - ctx2 := fakeContext(c, fmt.Sprintf(`FROM `+minimalBaseImage()+` + ctx2 := fakecontext.New(c, "", fakecontext.WithDockerfile(fmt.Sprintf(`FROM `+minimalBaseImage()+` MAINTAINER dockerio - ADD %s/baz /usr/lib/baz/quux`, server2.URL()), nil) + ADD %s/baz /usr/lib/baz/quux`, server2.URL()))) defer ctx2.Close() - buildImageSuccessfully(c, name3, withExternalBuildContext(ctx2)) + cli.BuildCmd(c, name3, build.WithExternalBuildContext(ctx2)) id3 := getIDByName(c, name3) if id1 != id3 { c.Fatal("The cache should have been used but wasn't") @@ -1953,24 +1965,24 @@ func (s *DockerSuite) TestBuildAddRemoteFileMTime(c *check.C) { // FIXME(vdemeester) this really seems to test the same thing as before (combined) func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithAndWithoutCache(c *check.C) { name := "testbuildaddlocalandremotefilewithcache" - server := fakeStorage(c, map[string]string{ + server := fakestorage.New(c, "", fakecontext.WithFiles(map[string]string{ "baz": "hello", - }) + })) defer server.Close() - ctx := fakeContext(c, fmt.Sprintf(`FROM `+minimalBaseImage()+` + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(fmt.Sprintf(`FROM `+minimalBaseImage()+` MAINTAINER dockerio ADD foo /usr/lib/bla/bar - ADD %s/baz /usr/lib/baz/quux`, server.URL()), - map[string]string{ + ADD %s/baz /usr/lib/baz/quux`, server.URL())), + fakecontext.WithFiles(map[string]string{ "foo": "hello world", - }) + })) defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, name) - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, name) - buildImageSuccessfully(c, name, build.WithoutCache, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithoutCache, build.WithExternalBuildContext(ctx)) id3 := getIDByName(c, name) if id1 != id2 { c.Fatal("The cache should have been used but hasn't.") @@ -1981,13 +1993,13 @@ func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithAndWithoutCache(c *chec } func testContextTar(c *check.C, compression archive.Compression) { - ctx := fakeContext(c, - `FROM busybox + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(`FROM busybox ADD foo /foo -CMD ["cat", "/foo"]`, - map[string]string{ +CMD ["cat", "/foo"]`), + fakecontext.WithFiles(map[string]string{ "foo": "bar", - }, + }), ) defer ctx.Close() context, err := archive.Tar(ctx.Dir, compression) @@ -1996,10 +2008,7 @@ CMD ["cat", "/foo"]`, } name := "contexttar" - icmd.RunCmd(icmd.Cmd{ - Command: []string{dockerBinary, "build", "-t", name, "-"}, - Stdin: context, - }).Assert(c, icmd.Success) + cli.BuildCmd(c, name, build.WithStdinContext(context)) } func (s *DockerSuite) TestBuildContextTarGzip(c *check.C) { @@ -2130,12 +2139,12 @@ func (s *DockerSuite) TestBuildEntrypointRunCleanup(c *check.C) { buildImageSuccessfully(c, name, build.WithDockerfile(`FROM busybox RUN echo "hello"`)) - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox RUN echo "hello" ADD foo /foo ENTRYPOINT ["/bin/echo"]`), - withFile("foo", "hello"))) + build.WithFile("foo", "hello"))) res := inspectField(c, name, "Config.Cmd") // Cmd must be cleaned up @@ -2152,10 +2161,10 @@ func (s *DockerSuite) TestBuildAddFileNotFound(c *check.C) { expected = "foo: The system cannot find the file specified" } - buildImage(name, withBuildContext(c, - withFile("Dockerfile", `FROM `+minimalBaseImage()+` + buildImage(name, build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM `+minimalBaseImage()+` ADD foo /usr/local/bar`), - withFile("bar", "hello"))).Assert(c, icmd.Expected{ + build.WithFile("bar", "hello"))).Assert(c, icmd.Expected{ ExitCode: 1, Err: expected, }) @@ -2206,15 +2215,15 @@ func (s *DockerSuite) TestBuildAddToSymlinkDest(c *check.C) { makeLink = `mklink /D C:\bar C:\foo` } name := "testbuildaddtosymlinkdest" - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", ` + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", ` FROM busybox RUN sh -c "mkdir /foo" RUN `+makeLink+` ADD foo /bar/ RUN sh -c "[ -f /bar/foo ]" RUN sh -c "[ -f /foo/foo ]"`), - withFile("foo", "hello"), + build.WithFile("foo", "hello"), )) } @@ -2253,8 +2262,8 @@ func (s *DockerSuite) TestBuildVerifyIntString(c *check.C) { func (s *DockerSuite) TestBuildDockerignore(c *check.C) { name := "testbuilddockerignore" - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", ` + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", ` FROM busybox ADD . /bla RUN sh -c "[[ -f /bla/src/x.go ]]" @@ -2268,17 +2277,17 @@ func (s *DockerSuite) TestBuildDockerignore(c *check.C) { RUN sh -c "[[ ! -e v.cc ]]" RUN sh -c "[[ ! -e src/v.cc ]]" RUN sh -c "[[ ! -e src/_vendor/v.cc ]]"`), - withFile("Makefile", "all:"), - withFile(".git/HEAD", "ref: foo"), - withFile("src/x.go", "package main"), - withFile("src/_vendor/v.go", "package main"), - withFile("src/_vendor/v.cc", "package main"), - withFile("src/v.cc", "package main"), - withFile("v.cc", "package main"), - withFile("dir/foo", ""), - withFile(".gitignore", ""), - withFile("README.md", "readme"), - withFile(".dockerignore", ` + build.WithFile("Makefile", "all:"), + build.WithFile(".git/HEAD", "ref: foo"), + build.WithFile("src/x.go", "package main"), + build.WithFile("src/_vendor/v.go", "package main"), + build.WithFile("src/_vendor/v.cc", "package main"), + build.WithFile("src/v.cc", "package main"), + build.WithFile("v.cc", "package main"), + build.WithFile("dir/foo", ""), + build.WithFile(".gitignore", ""), + build.WithFile("README.md", "readme"), + build.WithFile(".dockerignore", ` .git pkg .gitignore @@ -2291,22 +2300,22 @@ dir`), func (s *DockerSuite) TestBuildDockerignoreCleanPaths(c *check.C) { name := "testbuilddockerignorecleanpaths" - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", ` + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", ` FROM busybox ADD . /tmp/ RUN sh -c "(! ls /tmp/foo) && (! ls /tmp/foo2) && (! ls /tmp/dir1/foo)"`), - withFile("foo", "foo"), - withFile("foo2", "foo2"), - withFile("dir1/foo", "foo in dir1"), - withFile(".dockerignore", "./foo\ndir1//foo\n./dir1/../foo2"), + build.WithFile("foo", "foo"), + build.WithFile("foo2", "foo2"), + build.WithFile("dir1/foo", "foo in dir1"), + build.WithFile(".dockerignore", "./foo\ndir1//foo\n./dir1/../foo2"), )) } func (s *DockerSuite) TestBuildDockerignoreExceptions(c *check.C) { name := "testbuilddockerignoreexceptions" - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", ` + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", ` FROM busybox ADD . /bla RUN sh -c "[[ -f /bla/src/x.go ]]" @@ -2321,20 +2330,20 @@ func (s *DockerSuite) TestBuildDockerignoreExceptions(c *check.C) { RUN sh -c "[[ ! -e /bla/foo ]]" RUN sh -c "[[ ! -e /bla/.git ]]" RUN sh -c "[[ -e /bla/dir/a.cc ]]"`), - withFile("Makefile", "all:"), - withFile(".git/HEAD", "ref: foo"), - withFile("src/x.go", "package main"), - withFile("src/_vendor/v.go", "package main"), - withFile("dir/foo", ""), - withFile("dir/foo1", ""), - withFile("dir/dir/f1", ""), - withFile("dir/dir/foo", ""), - withFile("dir/e", ""), - withFile("dir/e-dir/foo", ""), - withFile(".gitignore", ""), - withFile("README.md", "readme"), - withFile("dir/a.cc", "hello"), - withFile(".dockerignore", ` + build.WithFile("Makefile", "all:"), + build.WithFile(".git/HEAD", "ref: foo"), + build.WithFile("src/x.go", "package main"), + build.WithFile("src/_vendor/v.go", "package main"), + build.WithFile("dir/foo", ""), + build.WithFile("dir/foo1", ""), + build.WithFile("dir/dir/f1", ""), + build.WithFile("dir/dir/foo", ""), + build.WithFile("dir/e", ""), + build.WithFile("dir/e-dir/foo", ""), + build.WithFile(".gitignore", ""), + build.WithFile("README.md", "readme"), + build.WithFile("dir/a.cc", "hello"), + build.WithFile(".dockerignore", ` .git pkg .gitignore @@ -2355,13 +2364,13 @@ func (s *DockerSuite) TestBuildDockerignoringDockerfile(c *check.C) { ADD . /tmp/ RUN sh -c "! ls /tmp/Dockerfile" RUN ls /tmp/.dockerignore` - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile(".dockerignore", "Dockerfile\n"), + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile(".dockerignore", "Dockerfile\n"), )) - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile(".dockerignore", "./Dockerfile\n"), + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile(".dockerignore", "./Dockerfile\n"), )) } @@ -2373,15 +2382,15 @@ func (s *DockerSuite) TestBuildDockerignoringRenamedDockerfile(c *check.C) { RUN ls /tmp/Dockerfile RUN sh -c "! ls /tmp/MyDockerfile" RUN ls /tmp/.dockerignore` - buildImageSuccessfully(c, name, cli.WithFlags("-f", "MyDockerfile"), withBuildContext(c, - withFile("Dockerfile", "Should not use me"), - withFile("MyDockerfile", dockerfile), - withFile(".dockerignore", "MyDockerfile\n"), + buildImageSuccessfully(c, name, cli.WithFlags("-f", "MyDockerfile"), build.WithBuildContext(c, + build.WithFile("Dockerfile", "Should not use me"), + build.WithFile("MyDockerfile", dockerfile), + build.WithFile(".dockerignore", "MyDockerfile\n"), )) - buildImageSuccessfully(c, name, cli.WithFlags("-f", "MyDockerfile"), withBuildContext(c, - withFile("Dockerfile", "Should not use me"), - withFile("MyDockerfile", dockerfile), - withFile(".dockerignore", "./MyDockerfile\n"), + buildImageSuccessfully(c, name, cli.WithFlags("-f", "MyDockerfile"), build.WithBuildContext(c, + build.WithFile("Dockerfile", "Should not use me"), + build.WithFile("MyDockerfile", dockerfile), + build.WithFile(".dockerignore", "./MyDockerfile\n"), )) } @@ -2392,9 +2401,9 @@ func (s *DockerSuite) TestBuildDockerignoringDockerignore(c *check.C) { ADD . /tmp/ RUN sh -c "! ls /tmp/.dockerignore" RUN ls /tmp/Dockerfile` - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile(".dockerignore", ".dockerignore\n"), + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile(".dockerignore", ".dockerignore\n"), )) } @@ -2403,16 +2412,17 @@ func (s *DockerSuite) TestBuildDockerignoreTouchDockerfile(c *check.C) { dockerfile := ` FROM busybox ADD . /tmp/` - ctx := fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - ".dockerignore": "Dockerfile\n", - }) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + ".dockerignore": "Dockerfile\n", + })) defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, name) - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, name) if id1 != id2 { c.Fatalf("Didn't use the cache - 1") @@ -2422,7 +2432,7 @@ func (s *DockerSuite) TestBuildDockerignoreTouchDockerfile(c *check.C) { if err := ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil { c.Fatalf("Didn't add Dockerfile: %s", err) } - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id2 = getIDByName(c, name) if id1 != id2 { c.Fatalf("Didn't use the cache - 2") @@ -2432,7 +2442,7 @@ func (s *DockerSuite) TestBuildDockerignoreTouchDockerfile(c *check.C) { if err := ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil { c.Fatalf("Didn't add Dockerfile: %s", err) } - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) id2 = getIDByName(c, name) if id1 != id2 { c.Fatalf("Didn't use the cache - 3") @@ -2448,11 +2458,11 @@ func (s *DockerSuite) TestBuildDockerignoringWholeDir(c *check.C) { RUN sh -c "[[ ! -e /.gitignore ]]" RUN sh -c "[[ ! -e /Makefile ]]"` - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile(".dockerignore", "*\n"), - withFile("Makefile", "all:"), - withFile(".gitignore", ""), + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile(".dockerignore", "*\n"), + build.WithFile("Makefile", "all:"), + build.WithFile(".gitignore", ""), )) } @@ -2465,25 +2475,25 @@ func (s *DockerSuite) TestBuildDockerignoringOnlyDotfiles(c *check.C) { RUN sh -c "[[ ! -e /.gitignore ]]" RUN sh -c "[[ -f /Makefile ]]"` - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile(".dockerignore", ".*"), - withFile("Makefile", "all:"), - withFile(".gitignore", ""), + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile(".dockerignore", ".*"), + build.WithFile("Makefile", "all:"), + build.WithFile(".gitignore", ""), )) } func (s *DockerSuite) TestBuildDockerignoringBadExclusion(c *check.C) { name := "testbuilddockerignorebadexclusion" - buildImage(name, withBuildContext(c, - withFile("Dockerfile", ` + buildImage(name, build.WithBuildContext(c, + build.WithFile("Dockerfile", ` FROM busybox COPY . / RUN sh -c "[[ ! -e /.gitignore ]]" RUN sh -c "[[ -f /Makefile ]]"`), - withFile("Makefile", "all:"), - withFile(".gitignore", ""), - withFile(".dockerignore", "!\n"), + build.WithFile("Makefile", "all:"), + build.WithFile(".gitignore", ""), + build.WithFile(".dockerignore", "!\n"), )).Assert(c, icmd.Expected{ ExitCode: 1, Err: "Error checking context: 'illegal exclusion pattern: \"!\"", @@ -2501,11 +2511,11 @@ func (s *DockerSuite) TestBuildDockerignoringWildTopDir(c *check.C) { // All of these should result in ignoring all files for _, variant := range []string{"**", "**/", "**/**", "*"} { - buildImageSuccessfully(c, "noname", withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile("file1", ""), - withFile("dir/file1", ""), - withFile(".dockerignore", variant), + buildImageSuccessfully(c, "noname", build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile("file1", ""), + build.WithFile("dir/file1", ""), + build.WithFile(".dockerignore", variant), )) dockerCmd(c, "rmi", "noname") @@ -2553,25 +2563,25 @@ dir1/dir3/** **/dir5/file. ` - buildImageSuccessfully(c, "noname", withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile(".dockerignore", dockerignore), - withFile("dir1/file0", ""), - withFile("dir1/dir2/file0", ""), - withFile("file1", ""), - withFile("dir1/file1", ""), - withFile("dir1/dir2/file1", ""), - withFile("dir1/file2", ""), - withFile("dir1/dir2/file2", ""), // remains - withFile("dir1/dir2/file4", ""), - withFile("dir1/dir2/file5", ""), - withFile("dir1/dir2/file6", ""), - withFile("dir1/dir3/file7", ""), - withFile("dir1/dir3/file8", ""), - withFile("dir1/dir4/file9", ""), - withFile("dir1/dir5/fileAA", ""), - withFile("dir1/dir5/fileAB", ""), - withFile("dir1/dir5/fileB", ""), + buildImageSuccessfully(c, "noname", build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile(".dockerignore", dockerignore), + build.WithFile("dir1/file0", ""), + build.WithFile("dir1/dir2/file0", ""), + build.WithFile("file1", ""), + build.WithFile("dir1/file1", ""), + build.WithFile("dir1/dir2/file1", ""), + build.WithFile("dir1/file2", ""), + build.WithFile("dir1/dir2/file2", ""), // remains + build.WithFile("dir1/dir2/file4", ""), + build.WithFile("dir1/dir2/file5", ""), + build.WithFile("dir1/dir2/file6", ""), + build.WithFile("dir1/dir3/file7", ""), + build.WithFile("dir1/dir3/file8", ""), + build.WithFile("dir1/dir4/file9", ""), + build.WithFile("dir1/dir5/fileAA", ""), + build.WithFile("dir1/dir5/fileAB", ""), + build.WithFile("dir1/dir5/fileB", ""), )) } @@ -2691,9 +2701,9 @@ ENV abc=def ENV ghi=$abc RUN [ "$ghi" = "def" ] ` - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile("hello/docker/world", "hello"), + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile("hello/docker/world", "hello"), )) } @@ -2761,9 +2771,9 @@ ENV eee4 'foo' RUN [ "$eee1,$eee2,$eee3,$eee4" = 'foo,foo,foo,foo' ] ` - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile("hello/docker/world", "hello"), + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile("hello/docker/world", "hello"), )) } @@ -2777,9 +2787,9 @@ RUN ["chmod","+x","/test"] RUN ["/test"] RUN [ "$(cat /testfile)" = 'test!' ]` - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile("test", "#!/bin/sh\necho 'test!' > /testfile"), + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile("test", "#!/bin/sh\necho 'test!' > /testfile"), )) } @@ -2788,7 +2798,7 @@ func (s *DockerSuite) TestBuildAddTar(c *check.C) { testRequires(c, NotUserNamespace) name := "testbuildaddtar" - ctx := func() *FakeContext { + ctx := func() *fakecontext.Fake { dockerfile := ` FROM busybox ADD test.tar / @@ -2830,17 +2840,17 @@ RUN cat /existing-directory-trailing-slash/test/foo | grep Hi` if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { c.Fatalf("failed to open destination dockerfile: %v", err) } - return fakeContextFromDir(tmpDir) + return fakecontext.New(c, tmpDir) }() defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) } func (s *DockerSuite) TestBuildAddBrokenTar(c *check.C) { name := "testbuildaddbrokentar" - ctx := func() *FakeContext { + ctx := func() *fakecontext.Fake { dockerfile := ` FROM busybox ADD test.tar /` @@ -2879,11 +2889,11 @@ ADD test.tar /` if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { c.Fatalf("failed to open destination dockerfile: %v", err) } - return fakeContextFromDir(tmpDir) + return fakecontext.New(c, tmpDir) }() defer ctx.Close() - buildImage(name, withExternalBuildContext(ctx)).Assert(c, icmd.Expected{ + buildImage(name, build.WithExternalBuildContext(ctx)).Assert(c, icmd.Expected{ ExitCode: 1, }) } @@ -2892,12 +2902,12 @@ func (s *DockerSuite) TestBuildAddNonTar(c *check.C) { name := "testbuildaddnontar" // Should not try to extract test.tar - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", ` + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", ` FROM busybox ADD test.tar / RUN test -f /test.tar`), - withFile("test.tar", "not_a_tar_file"), + build.WithFile("test.tar", "not_a_tar_file"), )) } @@ -2907,7 +2917,7 @@ func (s *DockerSuite) TestBuildAddTarXz(c *check.C) { testRequires(c, DaemonIsLinux) name := "testbuildaddtarxz" - ctx := func() *FakeContext { + ctx := func() *fakecontext.Fake { dockerfile := ` FROM busybox ADD test.tar.xz / @@ -2942,19 +2952,19 @@ func (s *DockerSuite) TestBuildAddTarXz(c *check.C) { if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { c.Fatalf("failed to open destination dockerfile: %v", err) } - return fakeContextFromDir(tmpDir) + return fakecontext.New(c, tmpDir) }() defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) } func (s *DockerSuite) TestBuildAddTarXzGz(c *check.C) { testRequires(c, DaemonIsLinux) name := "testbuildaddtarxzgz" - ctx := func() *FakeContext { + ctx := func() *fakecontext.Fake { dockerfile := ` FROM busybox ADD test.tar.xz.gz / @@ -2994,12 +3004,12 @@ func (s *DockerSuite) TestBuildAddTarXzGz(c *check.C) { if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { c.Fatalf("failed to open destination dockerfile: %v", err) } - return fakeContextFromDir(tmpDir) + return fakecontext.New(c, tmpDir) }() defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) } func (s *DockerSuite) TestBuildFromGit(c *check.C) { @@ -3075,12 +3085,12 @@ func (s *DockerSuite) TestBuildFromRemoteTarball(c *check.C) { c.Fatalf("failed to close tar archive: %v", err) } - server := fakeBinaryStorage(c, map[string]*bytes.Buffer{ + server := fakestorage.New(c, "", fakecontext.WithBinaryFiles(map[string]*bytes.Buffer{ "testT.tar": buffer, - }) + })) defer server.Close() - buildImageSuccessfully(c, name, build.WithContextPath(server.URL()+"/testT.tar")) + cli.BuildCmd(c, name, build.WithContextPath(server.URL()+"/testT.tar")) res := inspectField(c, name, "Author") if res != "docker" { @@ -3398,9 +3408,9 @@ func (s *DockerSuite) TestBuildNotVerboseSuccess(c *check.C) { { Name: "quiet_build_ctx_success", BuildFunc: func(name string) *icmd.Result { - return buildImage(name, buildFlags, withBuildContext(c, - withFile("Dockerfile", "FROM busybox"), - withFile("quiet_build_success_fctx", "test"), + return buildImage(name, buildFlags, build.WithBuildContext(c, + build.WithFile("Dockerfile", "FROM busybox"), + build.WithFile("quiet_build_success_fctx", "test"), )) }, }, @@ -3518,21 +3528,23 @@ func (s *DockerSuite) TestBuildChownSingleFile(c *check.C) { name := "testbuildchownsinglefile" - ctx := fakeContext(c, ` + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(` FROM busybox COPY test / RUN ls -l /test RUN [ $(ls -l /test | awk '{print $3":"$4}') = 'root:root' ] -`, map[string]string{ - "test": "test", - }) +`), + fakecontext.WithFiles(map[string]string{ + "test": "test", + })) defer ctx.Close() if err := os.Chown(filepath.Join(ctx.Dir, "test"), 4242, 4242); err != nil { c.Fatal(err) } - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) } func (s *DockerSuite) TestBuildSymlinkBreakout(c *check.C) { @@ -3577,7 +3589,7 @@ func (s *DockerSuite) TestBuildSymlinkBreakout(c *check.C) { w.Close() f.Close() - buildImageSuccessfully(c, name, build.WithoutCache, withExternalBuildContext(fakeContextFromDir(ctx))) + buildImageSuccessfully(c, name, build.WithoutCache, build.WithExternalBuildContext(fakecontext.New(c, ctx))) if _, err := os.Lstat(filepath.Join(tmpdir, "inject")); err == nil { c.Fatal("symlink breakout - inject") } else if !os.IsNotExist(err) { @@ -3591,15 +3603,15 @@ func (s *DockerSuite) TestBuildXZHost(c *check.C) { testRequires(c, DaemonIsLinux) name := "testbuildxzhost" - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", ` + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", ` FROM busybox ADD xz /usr/local/sbin/ RUN chmod 755 /usr/local/sbin/xz ADD test.xz / RUN [ ! -e /injected ]`), - withFile("test.xz", "\xfd\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00"+"\x21\x01\x16\x00\x00\x00\x74\x2f\xe5\xa3\x01\x00\x3f\xfd"+"\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00\x21"), - withFile("xz", "#!/bin/sh\ntouch /injected"), + build.WithFile("test.xz", "\xfd\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00"+"\x21\x01\x16\x00\x00\x00\x74\x2f\xe5\xa3\x01\x00\x3f\xfd"+"\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00\x21"), + build.WithFile("xz", "#!/bin/sh\ntouch /injected"), )) } @@ -3617,13 +3629,13 @@ func (s *DockerSuite) TestBuildVolumesRetainContents(c *check.C) { volName = "C:/foo" } - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", ` + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", ` FROM busybox COPY content /foo/file VOLUME `+volName+` CMD cat /foo/file`), - withFile("content", expected), + build.WithFile("content", expected), )) out, _ := dockerCmd(c, "run", "--rm", name) @@ -3635,15 +3647,13 @@ CMD cat /foo/file`), // FIXME(vdemeester) part of this should be unit test, other part should be clearer func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) { - ctx := fakeContext(c, `FROM busybox - RUN echo from Dockerfile`, - map[string]string{ - "Dockerfile": "FROM busybox\nRUN echo from Dockerfile", - "files/Dockerfile": "FROM busybox\nRUN echo from files/Dockerfile", - "files/dFile": "FROM busybox\nRUN echo from files/dFile", - "dFile": "FROM busybox\nRUN echo from dFile", - "files/dFile2": "FROM busybox\nRUN echo from files/dFile2", - }) + ctx := fakecontext.New(c, "", fakecontext.WithFiles(map[string]string{ + "Dockerfile": "FROM busybox\nRUN echo from Dockerfile", + "files/Dockerfile": "FROM busybox\nRUN echo from files/Dockerfile", + "files/dFile": "FROM busybox\nRUN echo from files/dFile", + "dFile": "FROM busybox\nRUN echo from dFile", + "files/dFile2": "FROM busybox\nRUN echo from files/dFile2", + })) defer ctx.Close() cli.Docker(cli.Args("build", "-t", "test1", "."), cli.InDir(ctx.Dir)).Assert(c, icmd.Expected{ @@ -3701,18 +3711,18 @@ func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) { testRequires(c, DaemonIsLinux) // If Dockerfile is not present, use dockerfile - buildImage("test1", withBuildContext(c, - withFile("dockerfile", `FROM busybox + buildImage("test1", build.WithBuildContext(c, + build.WithFile("dockerfile", `FROM busybox RUN echo from dockerfile`), )).Assert(c, icmd.Expected{ Out: "from dockerfile", }) // Prefer Dockerfile in place of dockerfile - buildImage("test1", withBuildContext(c, - withFile("dockerfile", `FROM busybox + buildImage("test1", build.WithBuildContext(c, + build.WithFile("dockerfile", `FROM busybox RUN echo from dockerfile`), - withFile("Dockerfile", `FROM busybox + build.WithFile("Dockerfile", `FROM busybox RUN echo from Dockerfile`), )).Assert(c, icmd.Expected{ Out: "from Dockerfile", @@ -3720,24 +3730,22 @@ func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) { } func (s *DockerSuite) TestBuildFromURLWithF(c *check.C) { - server := fakeStorage(c, map[string]string{"baz": `FROM busybox + server := fakestorage.New(c, "", fakecontext.WithFiles(map[string]string{"baz": `FROM busybox RUN echo from baz COPY * /tmp/ -RUN find /tmp/`}) +RUN find /tmp/`})) defer server.Close() - ctx := fakeContext(c, `FROM busybox -RUN echo from Dockerfile`, - map[string]string{}) + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(`FROM busybox + RUN echo from Dockerfile`)) defer ctx.Close() // Make sure that -f is ignored and that we don't use the Dockerfile // that's in the current dir - result := buildImage("test1", cli.WithFlags("-f", "baz", server.URL()+"/baz"), func(cmd *icmd.Cmd) func() { + result := cli.BuildCmd(c, "test1", cli.WithFlags("-f", "baz", server.URL()+"/baz"), func(cmd *icmd.Cmd) func() { cmd.Dir = ctx.Dir return nil }) - result.Assert(c, icmd.Success) if !strings.Contains(result.Combined(), "from baz") || strings.Contains(result.Combined(), "/tmp/baz") || @@ -3749,14 +3757,13 @@ RUN echo from Dockerfile`, func (s *DockerSuite) TestBuildFromStdinWithF(c *check.C) { testRequires(c, DaemonIsLinux) // TODO Windows: This test is flaky; no idea why - ctx := fakeContext(c, `FROM busybox -RUN echo "from Dockerfile"`, - map[string]string{}) + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(`FROM busybox +RUN echo "from Dockerfile"`)) defer ctx.Close() // Make sure that -f is ignored and that we don't use the Dockerfile // that's in the current dir - result := buildImage("test1", cli.WithFlags("-f", "baz", "-"), func(cmd *icmd.Cmd) func() { + result := cli.BuildCmd(c, "test1", cli.WithFlags("-f", "baz", "-"), func(cmd *icmd.Cmd) func() { cmd.Dir = ctx.Dir cmd.Stdin = strings.NewReader(`FROM busybox RUN echo "from baz" @@ -3764,7 +3771,6 @@ COPY * /tmp/ RUN sh -c "find /tmp/" # sh -c is needed on Windows to use the correct find`) return nil }) - result.Assert(c, icmd.Success) if !strings.Contains(result.Combined(), "from baz") || strings.Contains(result.Combined(), "/tmp/baz") || @@ -3851,19 +3857,16 @@ func (s *DockerSuite) TestBuildSpaces(c *check.C) { // Test to make sure that leading/trailing spaces on a command // doesn't change the error msg we get name := "testspaces" - ctx := fakeContext(c, "FROM busybox\nCOPY\n", - map[string]string{ - "Dockerfile": "FROM busybox\nCOPY\n", - }) + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile("FROM busybox\nCOPY\n")) defer ctx.Close() - result1 := buildImage(name, withExternalBuildContext(ctx)) + result1 := cli.Docker(cli.Build(name), build.WithExternalBuildContext(ctx)) result1.Assert(c, icmd.Expected{ ExitCode: 1, }) ctx.Add("Dockerfile", "FROM busybox\nCOPY ") - result2 := buildImage(name, withExternalBuildContext(ctx)) + result2 := cli.Docker(cli.Build(name), build.WithExternalBuildContext(ctx)) result2.Assert(c, icmd.Expected{ ExitCode: 1, }) @@ -3882,7 +3885,7 @@ func (s *DockerSuite) TestBuildSpaces(c *check.C) { } ctx.Add("Dockerfile", "FROM busybox\n COPY") - result2 = buildImage(name, build.WithoutCache, withExternalBuildContext(ctx)) + result2 = cli.Docker(cli.Build(name), build.WithoutCache, build.WithExternalBuildContext(ctx)) result2.Assert(c, icmd.Expected{ ExitCode: 1, }) @@ -3897,7 +3900,7 @@ func (s *DockerSuite) TestBuildSpaces(c *check.C) { } ctx.Add("Dockerfile", "FROM busybox\n COPY ") - result2 = buildImage(name, build.WithoutCache, withExternalBuildContext(ctx)) + result2 = cli.Docker(cli.Build(name), build.WithoutCache, build.WithExternalBuildContext(ctx)) result2.Assert(c, icmd.Expected{ ExitCode: 1, }) @@ -4000,9 +4003,9 @@ func (s *DockerSuite) TestBuildEmptyScratch(c *check.C) { } func (s *DockerSuite) TestBuildDotDotFile(c *check.C) { - buildImageSuccessfully(c, "sc", withBuildContext(c, - withFile("Dockerfile", "FROM busybox\n"), - withFile("..gitme", ""), + buildImageSuccessfully(c, "sc", build.WithBuildContext(c, + build.WithFile("Dockerfile", "FROM busybox\n"), + build.WithFile("..gitme", ""), )) } @@ -4248,16 +4251,16 @@ func (s *DockerSuite) TestBuildNullStringInAddCopyVolume(c *check.C) { volName = `C:\\nullvolume` } - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", ` + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", ` FROM busybox ADD null / COPY nullfile / VOLUME `+volName+` `), - withFile("null", "test1"), - withFile("nullfile", "test2"), + build.WithFile("null", "test1"), + build.WithFile("nullfile", "test2"), )) } @@ -4528,8 +4531,8 @@ func (s *DockerSuite) TestBuildBuildTimeArgExpansion(c *check.C) { "--build-arg", fmt.Sprintf("%s=%s", userVar, userVal), "--build-arg", fmt.Sprintf("%s=%s", volVar, volVal), ), - withBuildContext(c, - withFile("Dockerfile", fmt.Sprintf(`FROM busybox + build.WithBuildContext(c, + build.WithFile("Dockerfile", fmt.Sprintf(`FROM busybox ARG %s WORKDIR ${%s} ARG %s @@ -4546,8 +4549,8 @@ func (s *DockerSuite) TestBuildBuildTimeArgExpansion(c *check.C) { VOLUME ${%s}`, wdVar, wdVar, addVar, addVar, copyVar, copyVar, envVar, envVar, envVar, exposeVar, exposeVar, userVar, userVar, volVar, volVar)), - withFile(addVal, "some stuff"), - withFile(copyVal, "some stuff"), + build.WithFile(addVal, "some stuff"), + build.WithFile(copyVal, "some stuff"), ), ) @@ -4745,8 +4748,8 @@ func (s *DockerSuite) TestBuildBuildTimeArgEnv(c *check.C) { "FOO1=fromenv", "FOO2=fromenv", "FOO3=fromenv")...), - withBuildContext(c, - withFile("Dockerfile", dockerfile), + build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), ), ) result.Assert(c, icmd.Success) @@ -4941,26 +4944,26 @@ func (s *DockerSuite) TestBuildMultipleTags(c *check.C) { // #17290 func (s *DockerSuite) TestBuildCacheBrokenSymlink(c *check.C) { name := "testbuildbrokensymlink" - ctx := fakeContext(c, ` + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(` FROM busybox - COPY . ./`, - map[string]string{ + COPY . ./`), + fakecontext.WithFiles(map[string]string{ "foo": "bar", - }) + })) defer ctx.Close() err := os.Symlink(filepath.Join(ctx.Dir, "nosuchfile"), filepath.Join(ctx.Dir, "asymlink")) c.Assert(err, checker.IsNil) // warm up cache - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) // add new file to context, should invalidate cache err = ioutil.WriteFile(filepath.Join(ctx.Dir, "newfile"), []byte("foo"), 0644) c.Assert(err, checker.IsNil) - result := buildImage(name, withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result := cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) if strings.Contains(result.Combined(), "Using cache") { c.Fatal("2nd build used cache on ADD, it shouldn't") } @@ -4968,62 +4971,62 @@ func (s *DockerSuite) TestBuildCacheBrokenSymlink(c *check.C) { func (s *DockerSuite) TestBuildFollowSymlinkToFile(c *check.C) { name := "testbuildbrokensymlink" - ctx := fakeContext(c, ` + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(` FROM busybox - COPY asymlink target`, - map[string]string{ + COPY asymlink target`), + fakecontext.WithFiles(map[string]string{ "foo": "bar", - }) + })) defer ctx.Close() err := os.Symlink("foo", filepath.Join(ctx.Dir, "asymlink")) c.Assert(err, checker.IsNil) - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) - out, _ := dockerCmd(c, "run", "--rm", name, "cat", "target") + out := cli.DockerCmd(c, "run", "--rm", name, "cat", "target").Combined() c.Assert(out, checker.Matches, "bar") // change target file should invalidate cache err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("baz"), 0644) c.Assert(err, checker.IsNil) - result := buildImage(name, withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result := cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) c.Assert(result.Combined(), checker.Not(checker.Contains), "Using cache") - out, _ = dockerCmd(c, "run", "--rm", name, "cat", "target") + out = cli.DockerCmd(c, "run", "--rm", name, "cat", "target").Combined() c.Assert(out, checker.Matches, "baz") } func (s *DockerSuite) TestBuildFollowSymlinkToDir(c *check.C) { name := "testbuildbrokensymlink" - ctx := fakeContext(c, ` + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(` FROM busybox - COPY asymlink /`, - map[string]string{ + COPY asymlink /`), + fakecontext.WithFiles(map[string]string{ "foo/abc": "bar", "foo/def": "baz", - }) + })) defer ctx.Close() err := os.Symlink("foo", filepath.Join(ctx.Dir, "asymlink")) c.Assert(err, checker.IsNil) - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) - out, _ := dockerCmd(c, "run", "--rm", name, "cat", "abc", "def") + out := cli.DockerCmd(c, "run", "--rm", name, "cat", "abc", "def").Combined() c.Assert(out, checker.Matches, "barbaz") // change target file should invalidate cache err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo/def"), []byte("bax"), 0644) c.Assert(err, checker.IsNil) - result := buildImage(name, withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result := cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) c.Assert(result.Combined(), checker.Not(checker.Contains), "Using cache") - out, _ = dockerCmd(c, "run", "--rm", name, "cat", "abc", "def") + out = cli.DockerCmd(c, "run", "--rm", name, "cat", "abc", "def").Combined() c.Assert(out, checker.Matches, "barbax") } @@ -5032,43 +5035,44 @@ func (s *DockerSuite) TestBuildFollowSymlinkToDir(c *check.C) { // not from the target file. func (s *DockerSuite) TestBuildSymlinkBasename(c *check.C) { name := "testbuildbrokensymlink" - ctx := fakeContext(c, ` + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(` FROM busybox - COPY asymlink /`, - map[string]string{ + COPY asymlink /`), + fakecontext.WithFiles(map[string]string{ "foo": "bar", - }) + })) defer ctx.Close() err := os.Symlink("foo", filepath.Join(ctx.Dir, "asymlink")) c.Assert(err, checker.IsNil) - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) - out, _ := dockerCmd(c, "run", "--rm", name, "cat", "asymlink") + out := cli.DockerCmd(c, "run", "--rm", name, "cat", "asymlink").Combined() c.Assert(out, checker.Matches, "bar") } // #17827 func (s *DockerSuite) TestBuildCacheRootSource(c *check.C) { name := "testbuildrootsource" - ctx := fakeContext(c, ` + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(` FROM busybox - COPY / /data`, - map[string]string{ + COPY / /data`), + fakecontext.WithFiles(map[string]string{ "foo": "bar", - }) + })) defer ctx.Close() // warm up cache - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) // change file, should invalidate cache err := ioutil.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("baz"), 0644) c.Assert(err, checker.IsNil) - result := buildImage(name, withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result := cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) c.Assert(result.Combined(), checker.Not(checker.Contains), "Using cache") } @@ -5340,14 +5344,14 @@ func (s *DockerSuite) TestBuildDockerignoreComment(c *check.C) { RUN sh -c "(ls -la /tmp/#1)" RUN sh -c "(! ls -la /tmp/#2)" RUN sh -c "(! ls /tmp/foo) && (! ls /tmp/foo2) && (ls /tmp/dir1/foo)"` - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile("foo", "foo"), - withFile("foo2", "foo2"), - withFile("dir1/foo", "foo in dir1"), - withFile("#1", "# file 1"), - withFile("#2", "# file 2"), - withFile(".dockerignore", `# Visual C++ cache files + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile("foo", "foo"), + build.WithFile("foo2", "foo2"), + build.WithFile("dir1/foo", "foo in dir1"), + build.WithFile("#1", "# file 1"), + build.WithFile("#2", "# file 2"), + build.WithFile(".dockerignore", `# Visual C++ cache files # because we have git ;-) # The above comment is from #20083 foo @@ -5365,8 +5369,8 @@ func (s *DockerSuite) TestBuildWithUTF8BOM(c *check.C) { name := "test-with-utf8-bom" dockerfile := []byte(`FROM busybox`) bomDockerfile := append([]byte{0xEF, 0xBB, 0xBF}, dockerfile...) - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", string(bomDockerfile)), + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", string(bomDockerfile)), )) } @@ -5381,9 +5385,9 @@ func (s *DockerSuite) TestBuildWithUTF8BOMDockerignore(c *check.C) { RUN ls /tmp/.dockerignore` dockerignore := []byte("./Dockerfile\n") bomDockerignore := append([]byte{0xEF, 0xBB, 0xBF}, dockerignore...) - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", dockerfile), - withFile(".dockerignore", string(bomDockerignore)), + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile(".dockerignore", string(bomDockerignore)), )) } @@ -5571,17 +5575,18 @@ func (s *DockerSuite) TestBuildCacheFromEqualDiffIDsLength(c *check.C) { FROM busybox RUN echo "test" ENTRYPOINT ["sh"]` - ctx := fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - }) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + "Dockerfile": dockerfile, + })) defer ctx.Close() - buildImageSuccessfully(c, "build1", withExternalBuildContext(ctx)) + cli.BuildCmd(c, "build1", build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, "build1") // rebuild with cache-from - result := buildImage("build2", cli.WithFlags("--cache-from=build1"), withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result := cli.BuildCmd(c, "build2", cli.WithFlags("--cache-from=build1"), build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, "build2") c.Assert(id1, checker.Equals, id2) c.Assert(strings.Count(result.Combined(), "Using cache"), checker.Equals, 2) @@ -5594,30 +5599,30 @@ func (s *DockerSuite) TestBuildCacheFrom(c *check.C) { ENV FOO=bar ADD baz / RUN touch bax` - ctx := fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "baz": "baz", - }) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + "Dockerfile": dockerfile, + "baz": "baz", + })) defer ctx.Close() - buildImageSuccessfully(c, "build1", withExternalBuildContext(ctx)) + cli.BuildCmd(c, "build1", build.WithExternalBuildContext(ctx)) id1 := getIDByName(c, "build1") // rebuild with cache-from - result := buildImage("build2", cli.WithFlags("--cache-from=build1"), withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result := cli.BuildCmd(c, "build2", cli.WithFlags("--cache-from=build1"), build.WithExternalBuildContext(ctx)) id2 := getIDByName(c, "build2") c.Assert(id1, checker.Equals, id2) c.Assert(strings.Count(result.Combined(), "Using cache"), checker.Equals, 3) - dockerCmd(c, "rmi", "build2") + cli.DockerCmd(c, "rmi", "build2") // no cache match with unknown source - result = buildImage("build2", cli.WithFlags("--cache-from=nosuchtag"), withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result = cli.BuildCmd(c, "build2", cli.WithFlags("--cache-from=nosuchtag"), build.WithExternalBuildContext(ctx)) id2 = getIDByName(c, "build2") c.Assert(id1, checker.Not(checker.Equals), id2) c.Assert(strings.Count(result.Combined(), "Using cache"), checker.Equals, 0) - dockerCmd(c, "rmi", "build2") + cli.DockerCmd(c, "rmi", "build2") // clear parent images tempDir, err := ioutil.TempDir("", "test-build-cache-from-") @@ -5626,33 +5631,31 @@ func (s *DockerSuite) TestBuildCacheFrom(c *check.C) { } defer os.RemoveAll(tempDir) tempFile := filepath.Join(tempDir, "img.tar") - dockerCmd(c, "save", "-o", tempFile, "build1") - dockerCmd(c, "rmi", "build1") - dockerCmd(c, "load", "-i", tempFile) - parentID, _ := dockerCmd(c, "inspect", "-f", "{{.Parent}}", "build1") + cli.DockerCmd(c, "save", "-o", tempFile, "build1") + cli.DockerCmd(c, "rmi", "build1") + cli.DockerCmd(c, "load", "-i", tempFile) + parentID := cli.DockerCmd(c, "inspect", "-f", "{{.Parent}}", "build1").Combined() c.Assert(strings.TrimSpace(parentID), checker.Equals, "") // cache still applies without parents - result = buildImage("build2", cli.WithFlags("--cache-from=build1"), withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result = cli.BuildCmd(c, "build2", cli.WithFlags("--cache-from=build1"), build.WithExternalBuildContext(ctx)) id2 = getIDByName(c, "build2") c.Assert(id1, checker.Equals, id2) c.Assert(strings.Count(result.Combined(), "Using cache"), checker.Equals, 3) - history1, _ := dockerCmd(c, "history", "-q", "build2") + history1 := cli.DockerCmd(c, "history", "-q", "build2").Combined() // Retry, no new intermediate images - result = buildImage("build3", cli.WithFlags("--cache-from=build1"), withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result = cli.BuildCmd(c, "build3", cli.WithFlags("--cache-from=build1"), build.WithExternalBuildContext(ctx)) id3 := getIDByName(c, "build3") c.Assert(id1, checker.Equals, id3) c.Assert(strings.Count(result.Combined(), "Using cache"), checker.Equals, 3) - history2, _ := dockerCmd(c, "history", "-q", "build3") + history2 := cli.DockerCmd(c, "history", "-q", "build3").Combined() c.Assert(history1, checker.Equals, history2) - dockerCmd(c, "rmi", "build2") - dockerCmd(c, "rmi", "build3") - dockerCmd(c, "rmi", "build1") - dockerCmd(c, "load", "-i", tempFile) + cli.DockerCmd(c, "rmi", "build2") + cli.DockerCmd(c, "rmi", "build3") + cli.DockerCmd(c, "rmi", "build1") + cli.DockerCmd(c, "load", "-i", tempFile) // Modify file, everything up to last command and layers are reused dockerfile = ` @@ -5663,14 +5666,13 @@ func (s *DockerSuite) TestBuildCacheFrom(c *check.C) { err = ioutil.WriteFile(filepath.Join(ctx.Dir, "Dockerfile"), []byte(dockerfile), 0644) c.Assert(err, checker.IsNil) - result = buildImage("build2", cli.WithFlags("--cache-from=build1"), withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result = cli.BuildCmd(c, "build2", cli.WithFlags("--cache-from=build1"), build.WithExternalBuildContext(ctx)) id2 = getIDByName(c, "build2") c.Assert(id1, checker.Not(checker.Equals), id2) c.Assert(strings.Count(result.Combined(), "Using cache"), checker.Equals, 2) - layers1Str, _ := dockerCmd(c, "inspect", "-f", "{{json .RootFS.Layers}}", "build1") - layers2Str, _ := dockerCmd(c, "inspect", "-f", "{{json .RootFS.Layers}}", "build2") + layers1Str := cli.DockerCmd(c, "inspect", "-f", "{{json .RootFS.Layers}}", "build1").Combined() + layers2Str := cli.DockerCmd(c, "inspect", "-f", "{{json .RootFS.Layers}}", "build2").Combined() var layers1 []string var layers2 []string @@ -5691,19 +5693,19 @@ func (s *DockerSuite) TestBuildCacheMultipleFrom(c *check.C) { ADD baz / FROM busybox ADD baz /` - ctx := fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "baz": "baz", - }) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + "Dockerfile": dockerfile, + "baz": "baz", + })) defer ctx.Close() - result := buildImage("build1", withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result := cli.BuildCmd(c, "build1", build.WithExternalBuildContext(ctx)) // second part of dockerfile was a repeat of first so should be cached c.Assert(strings.Count(result.Combined(), "Using cache"), checker.Equals, 1) - result = buildImage("build2", cli.WithFlags("--cache-from=build1"), withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result = cli.BuildCmd(c, "build2", cli.WithFlags("--cache-from=build1"), build.WithExternalBuildContext(ctx)) // now both parts of dockerfile should be cached c.Assert(strings.Count(result.Combined(), "Using cache"), checker.Equals, 2) } @@ -5859,31 +5861,30 @@ func (s *DockerSuite) TestBuildCopyFromPreviousRootFS(c *check.C) { COPY --from=0 bar baz COPY --from=first bar bay` - ctx := fakeContext(c, fmt.Sprintf(dockerfile, ""), map[string]string{ - "Dockerfile": dockerfile, - "foo": "abc", - "bar": "def", - "baz/aa": "ghi", - "baz/bb": "jkl", - }) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(fmt.Sprintf(dockerfile, "")), + fakecontext.WithFiles(map[string]string{ + "foo": "abc", + "bar": "def", + "baz/aa": "ghi", + "baz/bb": "jkl", + })) defer ctx.Close() - result := buildImage("build1", withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + cli.BuildCmd(c, "build1", build.WithExternalBuildContext(ctx)) - out, _ := dockerCmd(c, "run", "build1", "cat", "bar") + out := cli.DockerCmd(c, "run", "build1", "cat", "bar").Combined() c.Assert(strings.TrimSpace(out), check.Equals, "def") - out, _ = dockerCmd(c, "run", "build1", "cat", "sub/aa") + out = cli.DockerCmd(c, "run", "build1", "cat", "sub/aa").Combined() c.Assert(strings.TrimSpace(out), check.Equals, "ghi") - out, _ = dockerCmd(c, "run", "build1", "cat", "sub/cc") + out = cli.DockerCmd(c, "run", "build1", "cat", "sub/cc").Combined() c.Assert(strings.TrimSpace(out), check.Equals, "mno") - out, _ = dockerCmd(c, "run", "build1", "cat", "baz") + out = cli.DockerCmd(c, "run", "build1", "cat", "baz").Combined() c.Assert(strings.TrimSpace(out), check.Equals, "abc") - out, _ = dockerCmd(c, "run", "build1", "cat", "bay") + out = cli.DockerCmd(c, "run", "build1", "cat", "bay").Combined() c.Assert(strings.TrimSpace(out), check.Equals, "abc") - result = buildImage("build2", withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result := cli.BuildCmd(c, "build2", build.WithExternalBuildContext(ctx)) // all commands should be cached c.Assert(strings.Count(result.Combined(), "Using cache"), checker.Equals, 7) @@ -5892,8 +5893,7 @@ func (s *DockerSuite) TestBuildCopyFromPreviousRootFS(c *check.C) { c.Assert(err, checker.IsNil) // changing file in parent block should not affect last block - result = buildImage("build3", withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result = cli.BuildCmd(c, "build3", build.WithExternalBuildContext(ctx)) c.Assert(strings.Count(result.Combined(), "Using cache"), checker.Equals, 5) @@ -5903,108 +5903,92 @@ func (s *DockerSuite) TestBuildCopyFromPreviousRootFS(c *check.C) { c.Assert(err, checker.IsNil) // changing file in parent block should affect both first and last block - result = buildImage("build4", withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + result = cli.BuildCmd(c, "build4", build.WithExternalBuildContext(ctx)) c.Assert(strings.Count(result.Combined(), "Using cache"), checker.Equals, 5) - out, _ = dockerCmd(c, "run", "build4", "cat", "bay") + out = cli.DockerCmd(c, "run", "build4", "cat", "bay").Combined() c.Assert(strings.TrimSpace(out), check.Equals, "pqr") - out, _ = dockerCmd(c, "run", "build4", "cat", "baz") + out = cli.DockerCmd(c, "run", "build4", "cat", "baz").Combined() c.Assert(strings.TrimSpace(out), check.Equals, "pqr") } func (s *DockerSuite) TestBuildCopyFromPreviousRootFSErrors(c *check.C) { - dockerfile := ` + testCases := []struct { + dockerfile string + expectedError string + }{ + { + dockerfile: ` FROM busybox - COPY --from=foo foo bar` - - ctx := fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "foo": "abc", - }) - defer ctx.Close() - - buildImage("build1", withExternalBuildContext(ctx)).Assert(c, icmd.Expected{ - ExitCode: 1, - Err: "invalid from flag value foo", - }) - - dockerfile = ` + COPY --from=foo foo bar`, + expectedError: "invalid from flag value foo", + }, + { + dockerfile: ` FROM busybox - COPY --from=0 foo bar` - - ctx = fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "foo": "abc", - }) - defer ctx.Close() - - buildImage("build1", withExternalBuildContext(ctx)).Assert(c, icmd.Expected{ - ExitCode: 1, - Err: "invalid from flag value 0 refers current build block", - }) - - dockerfile = ` + COPY --from=0 foo bar`, + expectedError: "invalid from flag value 0 refers current build block", + }, + { + dockerfile: ` FROM busybox AS foo - COPY --from=bar foo bar` - - ctx = fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "foo": "abc", - }) - defer ctx.Close() - - buildImage("build1", withExternalBuildContext(ctx)).Assert(c, icmd.Expected{ - ExitCode: 1, - Err: "invalid from flag value bar", - }) - - dockerfile = ` + COPY --from=bar foo bar`, + expectedError: "invalid from flag value bar", + }, + { + dockerfile: ` FROM busybox AS 1 - COPY --from=1 foo bar` + COPY --from=1 foo bar`, + expectedError: "invalid name for build stage", + }, + } - ctx = fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "foo": "abc", - }) - defer ctx.Close() + for _, tc := range testCases { + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(tc.dockerfile), + fakecontext.WithFiles(map[string]string{ + "foo": "abc", + })) - buildImage("build1", withExternalBuildContext(ctx)).Assert(c, icmd.Expected{ - ExitCode: 1, - Err: "invalid name for build stage", - }) + cli.Docker(cli.Build("build1"), build.WithExternalBuildContext(ctx)).Assert(c, icmd.Expected{ + ExitCode: 1, + Err: tc.expectedError, + }) + + ctx.Close() + } } func (s *DockerSuite) TestBuildCopyFromPreviousFrom(c *check.C) { dockerfile := ` FROM busybox COPY foo bar` - ctx := fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "foo": "abc", - }) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + "foo": "abc", + })) defer ctx.Close() - result := buildImage("build1", withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + cli.BuildCmd(c, "build1", build.WithExternalBuildContext(ctx)) dockerfile = ` FROM build1:latest AS foo FROM busybox COPY --from=foo bar / COPY foo /` - ctx = fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "foo": "def", - }) + ctx = fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + "foo": "def", + })) defer ctx.Close() - result = buildImage("build2", withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + cli.BuildCmd(c, "build2", build.WithExternalBuildContext(ctx)) - out, _ := dockerCmd(c, "run", "build2", "cat", "bar") + out := cli.DockerCmd(c, "run", "build2", "cat", "bar").Combined() c.Assert(strings.TrimSpace(out), check.Equals, "abc") - out, _ = dockerCmd(c, "run", "build2", "cat", "foo") + out = cli.DockerCmd(c, "run", "build2", "cat", "foo").Combined() c.Assert(strings.TrimSpace(out), check.Equals, "def") } @@ -6020,18 +6004,17 @@ func (s *DockerSuite) TestBuildCopyFromImplicitFrom(c *check.C) { COPY --from=busybox License.txt foo` } - ctx := fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - }) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + ) defer ctx.Close() - result := buildImage("build1", withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + cli.BuildCmd(c, "build1", build.WithExternalBuildContext(ctx)) if DaemonIsWindows() { - out, _ := dockerCmd(c, "run", "build1", "cat", "License.txt") + out := cli.DockerCmd(c, "run", "build1", "cat", "License.txt").Combined() c.Assert(len(out), checker.GreaterThan, 10) - out2, _ := dockerCmd(c, "run", "build1", "cat", "foo") + out2 := cli.DockerCmd(c, "run", "build1", "cat", "foo").Combined() c.Assert(out, check.Equals, out2) } } @@ -6042,31 +6025,28 @@ func (s *DockerRegistrySuite) TestBuildCopyFromImplicitPullingFrom(c *check.C) { dockerfile := ` FROM busybox COPY foo bar` - ctx := fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "foo": "abc", - }) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + "foo": "abc", + })) defer ctx.Close() - result := buildImage(repoName, withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + cli.BuildCmd(c, repoName, build.WithExternalBuildContext(ctx)) - dockerCmd(c, "push", repoName) - dockerCmd(c, "rmi", repoName) + cli.DockerCmd(c, "push", repoName) + cli.DockerCmd(c, "rmi", repoName) dockerfile = ` FROM busybox COPY --from=%s bar baz` - ctx = fakeContext(c, fmt.Sprintf(dockerfile, repoName), map[string]string{ - "Dockerfile": dockerfile, - }) + ctx = fakecontext.New(c, "", fakecontext.WithDockerfile(fmt.Sprintf(dockerfile, repoName))) defer ctx.Close() - result = buildImage("build1", withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + cli.BuildCmd(c, "build1", build.WithExternalBuildContext(ctx)) - dockerCmdWithResult("run", "build1", "cat", "baz").Assert(c, icmd.Expected{Out: "abc"}) + cli.Docker(cli.Args("run", "build1", "cat", "baz")).Assert(c, icmd.Expected{Out: "abc"}) } func (s *DockerSuite) TestBuildFromPreviousBlock(c *check.C) { @@ -6081,20 +6061,17 @@ func (s *DockerSuite) TestBuildFromPreviousBlock(c *check.C) { COPY --from=foo1 foo f1 COPY --from=FOo2 foo f2 ` // foo2 case also tests that names are canse insensitive - ctx := fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "foo": "bar", - }) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + "foo": "bar", + })) defer ctx.Close() - result := buildImage("build1", withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) - - dockerCmdWithResult("run", "build1", "cat", "foo").Assert(c, icmd.Expected{Out: "bar"}) - - dockerCmdWithResult("run", "build1", "cat", "f1").Assert(c, icmd.Expected{Out: "bar1"}) - - dockerCmdWithResult("run", "build1", "cat", "f2").Assert(c, icmd.Expected{Out: "bar2"}) + cli.BuildCmd(c, "build1", build.WithExternalBuildContext(ctx)) + cli.Docker(cli.Args("run", "build1", "cat", "foo")).Assert(c, icmd.Expected{Out: "bar"}) + cli.Docker(cli.Args("run", "build1", "cat", "f1")).Assert(c, icmd.Expected{Out: "bar1"}) + cli.Docker(cli.Args("run", "build1", "cat", "f2")).Assert(c, icmd.Expected{Out: "bar2"}) } func (s *DockerTrustSuite) TestCopyFromTrustedBuild(c *check.C) { @@ -6124,32 +6101,32 @@ func (s *DockerSuite) TestBuildCopyFromPreviousFromWindows(c *check.C) { dockerfile := ` FROM ` + testEnv.MinimalBaseImage() + ` COPY foo c:\\bar` - ctx := fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "foo": "abc", - }) + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + "foo": "abc", + })) defer ctx.Close() - result := buildImage("build1", withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + cli.BuildCmd(c, "build1", build.WithExternalBuildContext(ctx)) dockerfile = ` FROM build1:latest FROM ` + testEnv.MinimalBaseImage() + ` COPY --from=0 c:\\bar / COPY foo /` - ctx = fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "foo": "def", - }) + ctx = fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + "foo": "def", + })) defer ctx.Close() - result = buildImage("build2", withExternalBuildContext(ctx)) - result.Assert(c, icmd.Success) + cli.BuildCmd(c, "build2", build.WithExternalBuildContext(ctx)) - out, _ := dockerCmd(c, "run", "build2", "cmd.exe", "/s", "/c", "type", "c:\\bar") + out := cli.DockerCmd(c, "run", "build2", "cmd.exe", "/s", "/c", "type", "c:\\bar").Combined() c.Assert(strings.TrimSpace(out), check.Equals, "abc") - out, _ = dockerCmd(c, "run", "build2", "cmd.exe", "/s", "/c", "type", "c:\\foo") + out = cli.DockerCmd(c, "run", "build2", "cmd.exe", "/s", "/c", "type", "c:\\foo").Combined() c.Assert(strings.TrimSpace(out), check.Equals, "def") } @@ -6197,17 +6174,13 @@ func (s *DockerSuite) TestBuildCopyFromWindowsIsCaseInsensitive(c *check.C) { COPY --from=0 c:\\fOo c:\\copied RUN type c:\\copied ` - ctx := fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - "foo": "hello world", - }) - defer ctx.Close() - exp := icmd.Expected{ + cli.Docker(cli.Build("copyfrom-windows-insensitive"), build.WithBuildContext(c, + build.WithFile("Dockerfile", dockerfile), + build.WithFile("foo", "hello world"), + )).Assert(c, icmd.Expected{ ExitCode: 0, Out: "hello world", - } - result := buildImage("copyfrom-windows-insensitive", withExternalBuildContext(ctx)) - result.Assert(c, exp) + }) } func (s *DockerSuite) TestBuildIntermediateTarget(c *check.C) { @@ -6217,19 +6190,17 @@ func (s *DockerSuite) TestBuildIntermediateTarget(c *check.C) { FROM busybox CMD ["/dist"] ` - ctx := fakeContext(c, dockerfile, map[string]string{ - "Dockerfile": dockerfile, - }) + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(dockerfile)) defer ctx.Close() - result := buildImage("build1", withExternalBuildContext(ctx), + cli.BuildCmd(c, "build1", build.WithExternalBuildContext(ctx), cli.WithFlags("--target", "build-env")) - result.Assert(c, icmd.Success) - res := inspectFieldJSON(c, "build1", "Config.Cmd") - c.Assert(res, checker.Equals, `["/dev"]`) + //res := inspectFieldJSON(c, "build1", "Config.Cmd") + res := cli.InspectCmd(c, "build1", cli.Format("json .Config.Cmd")).Combined() + c.Assert(strings.TrimSpace(res), checker.Equals, `["/dev"]`) - result = buildImage("build1", withExternalBuildContext(ctx), + result := cli.Docker(cli.Build("build1"), build.WithExternalBuildContext(ctx), cli.WithFlags("--target", "nosuchtarget")) result.Assert(c, icmd.Expected{ ExitCode: 1, @@ -6274,13 +6245,13 @@ func (s *DockerSuite) TestBuildWindowsUser(c *check.C) { // Note 27545 was reverted in 28505, but a new fix was added subsequently in 28514. func (s *DockerSuite) TestBuildCopyFileDotWithWorkdir(c *check.C) { name := "testbuildcopyfiledotwithworkdir" - buildImageSuccessfully(c, name, withBuildContext(c, - withFile("Dockerfile", `FROM busybox + buildImageSuccessfully(c, name, build.WithBuildContext(c, + build.WithFile("Dockerfile", `FROM busybox WORKDIR /foo COPY file . RUN ["cat", "/foo/file"] `), - withFile("file", "content"), + build.WithFile("file", "content"), )) } diff --git a/integration-cli/docker_cli_build_unix_test.go b/integration-cli/docker_cli_build_unix_test.go index d56f73a926..11c6823255 100644 --- a/integration-cli/docker_cli_build_unix_test.go +++ b/integration-cli/docker_cli_build_unix_test.go @@ -16,6 +16,8 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" + "github.com/docker/docker/integration-cli/cli/build" + "github.com/docker/docker/integration-cli/cli/build/fakecontext" "github.com/docker/docker/pkg/testutil" icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/docker/go-units" @@ -26,10 +28,10 @@ func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) { testRequires(c, cpuCfsQuota) name := "testbuildresourceconstraints" - ctx := fakeContext(c, ` + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(` FROM hello-world:frozen RUN ["/hello"] - `, map[string]string{}) + `)) cli.Docker( cli.Args("build", "--no-cache", "--rm=false", "--memory=64m", "--memory-swap=-1", "--cpuset-cpus=0", "--cpuset-mems=0", "--cpu-shares=100", "--cpu-quota=8000", "--ulimit", "nofile=42", "-t", name, "."), cli.InDir(ctx.Dir), @@ -85,7 +87,7 @@ func (s *DockerSuite) TestBuildAddChangeOwnership(c *check.C) { testRequires(c, DaemonIsLinux) name := "testbuildaddown" - ctx := func() *FakeContext { + ctx := func() *fakecontext.Fake { dockerfile := ` FROM busybox ADD foo /bar/ @@ -108,12 +110,12 @@ func (s *DockerSuite) TestBuildAddChangeOwnership(c *check.C) { if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil { c.Fatalf("failed to open destination dockerfile: %v", err) } - return fakeContextFromDir(tmpDir) + return fakecontext.New(c, tmpDir) }() defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + buildImageSuccessfully(c, name, build.WithExternalBuildContext(ctx)) } // Test that an infinite sleep during a build is killed if the client disconnects. @@ -134,7 +136,7 @@ func (s *DockerSuite) TestBuildCancellationKillsSleep(c *check.C) { defer observer.Stop() // (Note: one year, will never finish) - ctx := fakeContext(c, "FROM busybox\nRUN sleep 31536000", nil) + ctx := fakecontext.New(c, "", fakecontext.WithDockerfile("FROM busybox\nRUN sleep 31536000")) defer ctx.Close() buildCmd := exec.Command(dockerBinary, "build", "-t", name, ".") diff --git a/integration-cli/docker_cli_create_test.go b/integration-cli/docker_cli_create_test.go index 46ff4634a4..dc5fd14085 100644 --- a/integration-cli/docker_cli_create_test.go +++ b/integration-cli/docker_cli_create_test.go @@ -10,7 +10,9 @@ import ( "time" "github.com/docker/docker/integration-cli/checker" + "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli/build" + "github.com/docker/docker/integration-cli/cli/build/fakecontext" "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/testutil" icmd "github.com/docker/docker/pkg/testutil/cmd" @@ -438,19 +440,21 @@ RUN chmod 755 /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] CMD echo foobar` - ctx := fakeContext(c, dockerfile, map[string]string{ - "entrypoint.sh": `#!/bin/sh + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + "entrypoint.sh": `#!/bin/sh echo "I am an entrypoint" exec "$@"`, - }) + })) defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) - out, _ := dockerCmd(c, "create", "--entrypoint=", name, "echo", "foo") + out := cli.DockerCmd(c, "create", "--entrypoint=", name, "echo", "foo").Combined() id := strings.TrimSpace(out) c.Assert(id, check.Not(check.Equals), "") - out, _ = dockerCmd(c, "start", "-a", id) + out = cli.DockerCmd(c, "start", "-a", id).Combined() c.Assert(strings.TrimSpace(out), check.Equals, "foo") } diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index e903e1a937..b6e93aa262 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -24,6 +24,7 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli/build" + "github.com/docker/docker/integration-cli/cli/build/fakecontext" "github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/stringutils" @@ -4174,22 +4175,25 @@ RUN chmod 755 /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] CMD echo foobar` - ctx := fakeContext(c, dockerfile, map[string]string{ - "entrypoint.sh": `#!/bin/sh + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + fakecontext.WithFiles(map[string]string{ + "entrypoint.sh": `#!/bin/sh echo "I am an entrypoint" exec "$@"`, - }) + })) defer ctx.Close() - buildImageSuccessfully(c, name, withExternalBuildContext(ctx)) + cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx)) - out, _ := dockerCmd(c, "run", "--entrypoint=", "-t", name, "echo", "foo") + out := cli.DockerCmd(c, "run", "--entrypoint=", "-t", name, "echo", "foo").Combined() c.Assert(strings.TrimSpace(out), check.Equals, "foo") // CMD will be reset as well (the same as setting a custom entrypoint) - _, _, err := dockerCmdWithError("run", "--entrypoint=", "-t", name) - c.Assert(err, check.NotNil) - c.Assert(err.Error(), checker.Contains, "No command specified") + cli.Docker(cli.Args("run", "--entrypoint=", "-t", name)).Assert(c, icmd.Expected{ + ExitCode: 125, + Err: "No command specified", + }) } func (s *DockerDaemonSuite) TestRunWithUlimitAndDaemonDefault(c *check.C) { diff --git a/integration-cli/docker_utils_test.go b/integration-cli/docker_utils_test.go index 547aa181e7..69d951af48 100644 --- a/integration-cli/docker_utils_test.go +++ b/integration-cli/docker_utils_test.go @@ -1,16 +1,13 @@ package main import ( - "bytes" "encoding/json" "errors" "fmt" "io" "io/ioutil" - "net" "net/http" "net/http/httptest" - "net/url" "os" "os/exec" "path" @@ -22,11 +19,11 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" - "github.com/docker/docker/integration-cli/cli/build" + "github.com/docker/docker/integration-cli/cli/build/fakecontext" + "github.com/docker/docker/integration-cli/cli/build/fakestorage" "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration-cli/registry" "github.com/docker/docker/integration-cli/request" - "github.com/docker/docker/pkg/stringutils" icmd "github.com/docker/docker/pkg/testutil/cmd" "github.com/go-check/check" ) @@ -124,212 +121,6 @@ func getContainerCount(c *check.C) int { return 0 } -// FakeContext creates directories that can be used as a build context -type FakeContext struct { - Dir string -} - -// Add a file at a path, creating directories where necessary -func (f *FakeContext) Add(file, content string) error { - return f.addFile(file, []byte(content)) -} - -func (f *FakeContext) addFile(file string, content []byte) error { - fp := filepath.Join(f.Dir, filepath.FromSlash(file)) - dirpath := filepath.Dir(fp) - if dirpath != "." { - if err := os.MkdirAll(dirpath, 0755); err != nil { - return err - } - } - return ioutil.WriteFile(fp, content, 0644) - -} - -// Delete a file at a path -func (f *FakeContext) Delete(file string) error { - fp := filepath.Join(f.Dir, filepath.FromSlash(file)) - return os.RemoveAll(fp) -} - -// Close deletes the context -func (f *FakeContext) Close() error { - return os.RemoveAll(f.Dir) -} - -func fakeContextFromNewTempDir(c *check.C) *FakeContext { - tmp, err := ioutil.TempDir("", "fake-context") - c.Assert(err, checker.IsNil) - if err := os.Chmod(tmp, 0755); err != nil { - c.Fatal(err) - } - return fakeContextFromDir(tmp) -} - -func fakeContextFromDir(dir string) *FakeContext { - return &FakeContext{dir} -} - -func fakeContextWithFiles(c *check.C, files map[string]string) *FakeContext { - ctx := fakeContextFromNewTempDir(c) - for file, content := range files { - if err := ctx.Add(file, content); err != nil { - ctx.Close() - c.Fatal(err) - } - } - return ctx -} - -func fakeContextAddDockerfile(c *check.C, ctx *FakeContext, dockerfile string) { - if err := ctx.Add("Dockerfile", dockerfile); err != nil { - ctx.Close() - c.Fatal(err) - } -} - -func fakeContext(c *check.C, dockerfile string, files map[string]string) *FakeContext { - ctx := fakeContextWithFiles(c, files) - fakeContextAddDockerfile(c, ctx, dockerfile) - return ctx -} - -// FakeStorage is a static file server. It might be running locally or remotely -// on test host. -type FakeStorage interface { - Close() error - URL() string - CtxDir() string -} - -func fakeBinaryStorage(c *check.C, archives map[string]*bytes.Buffer) FakeStorage { - ctx := fakeContextFromNewTempDir(c) - for name, content := range archives { - if err := ctx.addFile(name, content.Bytes()); err != nil { - c.Fatal(err) - } - } - return fakeStorageWithContext(c, ctx) -} - -// fakeStorage returns either a local or remote (at daemon machine) file server -func fakeStorage(c *check.C, files map[string]string) FakeStorage { - ctx := fakeContextWithFiles(c, files) - return fakeStorageWithContext(c, ctx) -} - -// fakeStorageWithContext returns either a local or remote (at daemon machine) file server -func fakeStorageWithContext(c *check.C, ctx *FakeContext) FakeStorage { - if testEnv.LocalDaemon() { - return newLocalFakeStorage(c, ctx) - } - return newRemoteFileServer(c, ctx) -} - -// localFileStorage is a file storage on the running machine -type localFileStorage struct { - *FakeContext - *httptest.Server -} - -func (s *localFileStorage) URL() string { - return s.Server.URL -} - -func (s *localFileStorage) CtxDir() string { - return s.FakeContext.Dir -} - -func (s *localFileStorage) Close() error { - defer s.Server.Close() - return s.FakeContext.Close() -} - -func newLocalFakeStorage(c *check.C, ctx *FakeContext) *localFileStorage { - handler := http.FileServer(http.Dir(ctx.Dir)) - server := httptest.NewServer(handler) - return &localFileStorage{ - FakeContext: ctx, - Server: server, - } -} - -// remoteFileServer is a containerized static file server started on the remote -// testing machine to be used in URL-accepting docker build functionality. -type remoteFileServer struct { - host string // hostname/port web server is listening to on docker host e.g. 0.0.0.0:43712 - container string - image string - ctx *FakeContext -} - -func (f *remoteFileServer) URL() string { - u := url.URL{ - Scheme: "http", - Host: f.host} - return u.String() -} - -func (f *remoteFileServer) CtxDir() string { - return f.ctx.Dir -} - -func (f *remoteFileServer) Close() error { - defer func() { - if f.ctx != nil { - f.ctx.Close() - } - if f.image != "" { - deleteImages(f.image) - } - }() - if f.container == "" { - return nil - } - return deleteContainer(f.container) -} - -func newRemoteFileServer(c *check.C, ctx *FakeContext) *remoteFileServer { - var ( - image = fmt.Sprintf("fileserver-img-%s", strings.ToLower(stringutils.GenerateRandomAlphaOnlyString(10))) - container = fmt.Sprintf("fileserver-cnt-%s", strings.ToLower(stringutils.GenerateRandomAlphaOnlyString(10))) - ) - - ensureHTTPServerImage(c) - - // Build the image - fakeContextAddDockerfile(c, ctx, `FROM httpserver -COPY . /static`) - buildImageSuccessfully(c, image, build.WithoutCache, withExternalBuildContext(ctx)) - - // Start the container - dockerCmd(c, "run", "-d", "-P", "--name", container, image) - - // Find out the system assigned port - out, _ := dockerCmd(c, "port", container, "80/tcp") - fileserverHostPort := strings.Trim(out, "\n") - _, port, err := net.SplitHostPort(fileserverHostPort) - if err != nil { - c.Fatalf("unable to parse file server host:port: %v", err) - } - - dockerHostURL, err := url.Parse(daemonHost()) - if err != nil { - c.Fatalf("unable to parse daemon host URL: %v", err) - } - - host, _, err := net.SplitHostPort(dockerHostURL.Host) - if err != nil { - c.Fatalf("unable to parse docker daemon host:port: %v", err) - } - - return &remoteFileServer{ - container: container, - image: image, - host: fmt.Sprintf("%s:%s", host, port), - ctx: ctx} -} - func inspectFieldAndUnmarshall(c *check.C, name, field string, output interface{}) { str := inspectFieldJSON(c, name, field) err := json.Unmarshal([]byte(str), output) @@ -452,42 +243,7 @@ func buildImage(name string, cmdOperators ...cli.CmdOperator) *icmd.Result { return cli.Docker(cli.Build(name), cmdOperators...) } -func withExternalBuildContext(ctx *FakeContext) func(*icmd.Cmd) func() { - return func(cmd *icmd.Cmd) func() { - cmd.Dir = ctx.Dir - cmd.Command = append(cmd.Command, ".") - return nil - } -} - -func withBuildContext(c *check.C, contextOperators ...func(*FakeContext) error) func(*icmd.Cmd) func() { - ctx := fakeContextFromNewTempDir(c) - for _, op := range contextOperators { - if err := op(ctx); err != nil { - c.Fatal(err) - } - } - return func(cmd *icmd.Cmd) func() { - cmd.Dir = ctx.Dir - cmd.Command = append(cmd.Command, ".") - return closeBuildContext(c, ctx) - } -} - -func withFile(name, content string) func(*FakeContext) error { - return func(ctx *FakeContext) error { - return ctx.Add(name, content) - } -} - -func closeBuildContext(c *check.C, ctx *FakeContext) func() { - return func() { - if err := ctx.Close(); err != nil { - c.Fatal(err) - } - } -} - +// Deprecated: use trustedcmd func trustedBuild(cmd *icmd.Cmd) func() { trustedCmd(cmd) return nil @@ -523,7 +279,7 @@ func (g *fakeGit) Close() { } func newFakeGit(c *check.C, name string, files map[string]string, enforceLocalServer bool) *fakeGit { - ctx := fakeContextWithFiles(c, files) + ctx := fakecontext.New(c, "", fakecontext.WithFiles(files)) defer ctx.Close() curdir, err := os.Getwd() if err != nil { @@ -578,7 +334,7 @@ func newFakeGit(c *check.C, name string, files map[string]string, enforceLocalSe var server gitServer if !enforceLocalServer { // use fakeStorage server, which might be local or remote (at test daemon) - server = fakeStorageWithContext(c, fakeContextFromDir(root)) + server = fakestorage.New(c, root) } else { // always start a local http server on CLI test machine httpServer := httptest.NewServer(http.FileServer(http.Dir(root))) diff --git a/integration-cli/trust_server_test.go b/integration-cli/trust_server_test.go index ced1f43f52..ddfbefc61d 100644 --- a/integration-cli/trust_server_test.go +++ b/integration-cli/trust_server_test.go @@ -190,12 +190,6 @@ func (t *testNotary) Close() { os.RemoveAll(t.dir) } -// Deprecated: used trustedCmd instead -func trustedExecCmd(cmd *exec.Cmd) { - pwd := "12345678" - cmd.Env = append(cmd.Env, trustEnv(notaryURL, pwd, pwd)...) -} - func trustedCmd(cmd *icmd.Cmd) { pwd := "12345678" cmd.Env = append(cmd.Env, trustEnv(notaryURL, pwd, pwd)...)