diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8a65f40915..acff2706d8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,7 @@ jobs: pack_bin: pack.exe - config: windows-wcow os: windows - runner: windows-latest + runner: [self-hosted, windows, wcow] no_docker: "false" pack_bin: pack.exe runs-on: ${{ matrix.runner }} @@ -52,6 +52,12 @@ jobs: PACK_BIN: ${{ matrix.pack_bin }} NO_DOCKER: ${{ matrix.no_docker }} steps: + - name: Set git to use LF and symlinks + if: matrix.os == 'windows' + run: | + git config --global core.autocrlf false + git config --global core.eol lf + git config --global core.symlinks true - uses: actions/checkout@v2 - name: Derive pack version from branch name run: | @@ -67,8 +73,6 @@ jobs: echo "::set-env name=GOPATH::$(go env GOPATH)" echo "::add-path::$(go env GOPATH)/bin" - name: Verify - # disabled for windows due to format verification failing - if: matrix.os != 'windows' run: make verify - name: Test env: diff --git a/Makefile b/Makefile index 00ec4f45da..67b4b78dc1 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,34 @@ +ifeq ($(OS),Windows_NT) +SHELL:=cmd.exe + +# Need BLANK due to makefile parsing of `\` +# (see: https://stackoverflow.com/questions/54733231/how-to-escape-a-backslash-in-the-end-to-mean-literal-backslash-in-makefile/54733416#54733416) +BLANK:= + +# Define variable named `/` to represent OS path separator (usable as `$/` in this file) +/:=\$(BLANK) +CAT=type +RMRF=rmdir /q /s +SRC=$(shell dir /q /s /b *.go | findstr /v $/out$/) +GOIMPORTS_DIFF_OPTION="-l" # Windows can't do diff-mode because it's missing the "diff" binary +PACK_BIN?=pack.exe +else +/:=/ +CAT=cat +RMRF=rm -rf +SRC=$(shell find . -type f -name '*.go' -not -path "*/out/*") +GOIMPORTS_DIFF_OPTION:="-d" +PACK_BIN?=pack +endif + ACCEPTANCE_TIMEOUT?=$(TEST_TIMEOUT) ARCHIVE_NAME=pack-$(PACK_VERSION) GOCMD?=go GOFLAGS?= GOTESTFLAGS?=-v -count=1 -parallel=1 PACKAGE_BASE=github.com/buildpacks/pack -PACK_BIN?=pack PACK_GITSHA1=$(shell git rev-parse --short=7 HEAD) PACK_VERSION?=0.0.0 -SRC=$(shell find . -type f -name '*.go' -not -path "*/out/*") TEST_TIMEOUT?=900s UNIT_TIMEOUT?=$(TEST_TIMEOUT) @@ -30,7 +51,7 @@ all: clean verify test build mod-tidy: $(GOCMD) mod tidy - cd tools; $(GOCMD) mod tidy + cd tools && $(GOCMD) mod tidy tidy: mod-tidy format @@ -39,15 +60,15 @@ build: out $(GOCMD) build -ldflags "-s -w -X 'github.com/buildpacks/pack.Version=${PACK_VERSION}' -extldflags ${LDFLAGS}" -trimpath -o ./out/$(PACK_BIN) -a ./cmd/pack package: out - tar czf ./out/$(ARCHIVE_NAME).tgz -C out/ pack + tar czf .$/out$/$(ARCHIVE_NAME).tgz -C .$/out$/ $(PACK_BIN) install-mockgen: @echo "> Installing mockgen..." - cd tools; $(GOCMD) install github.com/golang/mock/mockgen + cd tools && $(GOCMD) install github.com/golang/mock/mockgen install-goimports: @echo "> Installing goimports..." - cd tools; $(GOCMD) install golang.org/x/tools/cmd/goimports + cd tools && $(GOCMD) install golang.org/x/tools/cmd/goimports format: install-goimports @echo "> Formating code..." @@ -56,7 +77,7 @@ format: install-goimports install-golangci-lint: @echo "> Installing golangci-lint..." - cd tools; $(GOCMD) install github.com/golangci/golangci-lint/cmd/golangci-lint + cd tools && $(GOCMD) install github.com/golangci/golangci-lint/cmd/golangci-lint lint: install-golangci-lint @echo "> Linting code..." @@ -76,14 +97,14 @@ acceptance: out @echo "> Running acceptance tests..." $(GOCMD) test $(GOTESTFLAGS) -timeout=$(ACCEPTANCE_TIMEOUT) -tags=acceptance ./acceptance -acceptance-all: export ACCEPTANCE_SUITE_CONFIG:=$(shell cat ./acceptance/testconfig/all.json) +acceptance-all: export ACCEPTANCE_SUITE_CONFIG:=$(shell $(CAT) .$/acceptance$/testconfig$/all.json) acceptance-all: @echo "> Running acceptance tests..." $(GOCMD) test $(GOTESTFLAGS) -timeout=$(ACCEPTANCE_TIMEOUT) -tags=acceptance ./acceptance clean: @echo "> Cleaning workspace..." - rm -rf ./out + @$(RMRF) .$/out || (exit 0) verify: verify-format lint @@ -93,28 +114,22 @@ generate: install-mockgen verify-format: install-goimports @echo "> Verifying format..." - @test -z "$(shell goimports -l -local ${PACKAGE_BASE} ${SRC})"; _err=$$?;\ - [ $$_err -ne 0 ] &&\ - echo "ERROR: Format verification failed!\n" &&\ - goimports -d -local ${PACKAGE_BASE} ${SRC} &&\ - exit $$_err;\ - exit 0; + $(if $(shell goimports -l -local ${PACKAGE_BASE} ${SRC}), @echo ERROR: Format verification failed! && goimports ${GOIMPORTS_DIFF_OPTION} -local ${PACKAGE_BASE} ${SRC} && exit 1) prepare-for-pr: tidy verify test - @git diff-index --quiet HEAD --; _err=$$?;\ - [ $$_err -ne 0 ] &&\ - echo "-----------------" &&\ + @git diff-index --quiet HEAD -- ||\ + (echo "-----------------" &&\ echo "NOTICE: There are some files that have not been committed." &&\ echo "-----------------\n" &&\ git status &&\ echo "\n-----------------" &&\ echo "NOTICE: There are some files that have not been committed." &&\ echo "-----------------\n" &&\ - exit 0; + exit 0) +# NOTE: Windows doesn't support `-p` out: - # NOTE: Windows doesn't support `-p` - mkdir out - mkdir out/tests + @mkdir out + mkdir out$/tests -.PHONY: clean build format imports lint test unit acceptance verify verify-format +.PHONY: clean build format imports lint test unit acceptance prepare-for-pr verify verify-format diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index ad79598324..72777cfa9e 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -503,7 +503,9 @@ func testAcceptance( it.Before(func() { pack = invoke.NewPackInvoker(t, assert, subjectPackConfig, registryConfig.DockerConfigDir) + pack.EnableExperimental() createBuilderPack = invoke.NewPackInvoker(t, assert, createBuilderPackConfig, registryConfig.DockerConfigDir) + createBuilderPack.EnableExperimental() }) it.After(func() { @@ -536,38 +538,6 @@ func testAcceptance( runImageMirror = value }) - when("creating a windows builder", func() { - it.Before(func() { - h.SkipIf(t, dockerHostOS() != "windows", "The current Docker daemon does not support Windows-based containers") - }) - - when("experimental is disabled", func() { - it("fails", func() { - builderName, err := createBuilder(t, assert, createBuilderPack, lifecycle, runImageMirror) - - if err != nil { - defer h.DockerRmi(dockerCli, builderName) - h.AssertError(t, err, "Windows containers support is currently experimental") - } - }) - }) - - when("experimental is enabled", func() { - it("succeeds", func() { - createBuilderPack.EnableExperimental() - - builderName, err := createBuilder(t, assert, createBuilderPack, lifecycle, runImageMirror) - assert.Nil(err) - defer h.DockerRmi(dockerCli, builderName) - - inspect, _, err := dockerCli.ImageInspectWithRaw(context.TODO(), builderName) - assert.Nil(err) - - assert.Equal(inspect.Os, "windows") - }) - }) - }) - when("builder is created", func() { var ( builderName string @@ -575,8 +545,6 @@ func testAcceptance( ) it.Before(func() { - h.SkipIf(t, dockerHostOS() == "windows", "These tests are not yet compatible with Windows-based containers") - var err error tmpDir, err = ioutil.TempDir("", "package-buildpack-tests") assert.Nil(err) @@ -646,6 +614,8 @@ func testAcceptance( var untrustedBuilderName string it.Before(func() { + h.SkipIf(t, dockerHostOS() == "windows", "untrusted builders are not yet supported for windows builds") + var err error untrustedBuilderName, err = createBuilder( t, @@ -658,6 +628,9 @@ func testAcceptance( }) it.After(func() { + if dockerHostOS() == "windows" { + return + } h.DockerRmi(dockerCli, untrustedBuilderName) }) @@ -788,6 +761,21 @@ func testAcceptance( t.Log("inspect-image") output = pack.RunSuccessfully("inspect-image", repoName) + var ( + webCommand string + helloCommand string + helloArgs string + ) + if dockerHostOS() == "windows" { + webCommand = ".\\run" + helloCommand = "cmd" + helloArgs = " /c echo hello world" + } else { + webCommand = "./run" + helloCommand = "echo" + helloArgs = "hello world" + } + expectedOutput := pack.FixtureManager().TemplateFixture( "inspect_image_local_output.txt", map[string]interface{}{ @@ -796,6 +784,9 @@ func testAcceptance( "base_image_top_layer": h.TopLayerDiffID(t, runImageMirror), "run_image_local_mirror": localRunImageMirror, "run_image_mirror": runImageMirror, + "web_command": webCommand, + "hello_command": helloCommand, + "hello_args": helloArgs, }, ) @@ -907,14 +898,22 @@ func testAcceptance( readBuildpackTgz, readWriteBuildpackTgz, tmpVolumeSrc string + volumeRoot = "/" + slash = "/" ) it.Before(func() { + h.SkipIf(t, os.Getenv("DOCKER_HOST") != "", "cannot mount volume when DOCKER_HOST is set") + h.SkipUnless(t, pack.SupportsFeature(invoke.ReadWriteVolumeMounts), "pack version does not support read/write volume mounts", ) + if dockerHostOS() == "windows" { + volumeRoot = `c:\` + slash = `\` + } readBuildpackTgz = h.CreateTGZ(t, filepath.Join(bpDir, "read-volume-buildpack"), "./", 0755) readWriteBuildpackTgz = h.CreateTGZ(t, filepath.Join(bpDir, "read-write-volume-buildpack"), "./", 0755) @@ -941,51 +940,59 @@ func testAcceptance( when("volume is read-only", func() { it("mounts the provided volume in the detect and build phases", func() { + volumeDest := volumeRoot + "platform" + slash + "volume-mount-target" + testFilePath := volumeDest + slash + "some-file" output := pack.RunSuccessfully( "build", repoName, "-p", filepath.Join("testdata", "mock_app"), - "--volume", fmt.Sprintf("%s:/platform/volume-mount-target", tmpVolumeSrc), + "--volume", fmt.Sprintf("%s:%s", tmpVolumeSrc, volumeDest), "--buildpack", readBuildpackTgz, - "--env", "TEST_FILE_PATH=/platform/volume-mount-target/some-file", + "--env", "TEST_FILE_PATH="+testFilePath, ) bpOutputAsserts := assertions.NewTestBuildpackOutputAssertionManager(t, output) - bpOutputAsserts.ReportsReadingFileContents("Detect", "/platform/volume-mount-target/some-file", "some-content") - bpOutputAsserts.ReportsReadingFileContents("Build", "/platform/volume-mount-target/some-file", "some-content") + bpOutputAsserts.ReportsReadingFileContents("Detect", testFilePath, "some-content") + bpOutputAsserts.ReportsReadingFileContents("Build", testFilePath, "some-content") }) it("should fail to write", func() { + volumeDest := volumeRoot + "platform" + slash + "volume-mount-target" + testDetectFilePath := volumeDest + slash + "detect-file" + testBuildFilePath := volumeDest + slash + "build-file" output := pack.RunSuccessfully( "build", repoName, "-p", filepath.Join("testdata", "mock_app"), - "--volume", fmt.Sprintf("%s:/platform/volume-mount-target", tmpVolumeSrc), + "--volume", fmt.Sprintf("%s:%s", tmpVolumeSrc, volumeDest), "--buildpack", readWriteBuildpackTgz, - "--env", "DETECT_TEST_FILE_PATH=/platform/volume-mount-target/detect-file", - "--env", "BUILD_TEST_FILE_PATH=/platform/volume-mount-target/build-file", + "--env", "DETECT_TEST_FILE_PATH="+testDetectFilePath, + "--env", "BUILD_TEST_FILE_PATH="+testBuildFilePath, ) bpOutputAsserts := assertions.NewTestBuildpackOutputAssertionManager(t, output) - bpOutputAsserts.ReportsFailingToWriteFileContents("Detect", "/platform/volume-mount-target/detect-file") - bpOutputAsserts.ReportsFailingToWriteFileContents("Build", "/platform/volume-mount-target/build-file") + bpOutputAsserts.ReportsFailingToWriteFileContents("Detect", testDetectFilePath) + bpOutputAsserts.ReportsFailingToWriteFileContents("Build", testBuildFilePath) }) }) when("volume is read-write", func() { it("can be written to", func() { + volumeDest := volumeRoot + "volume-mount-target" + testDetectFilePath := volumeDest + slash + "detect-file" + testBuildFilePath := volumeDest + slash + "build-file" output := pack.RunSuccessfully( "build", repoName, "-p", filepath.Join("testdata", "mock_app"), - "--volume", fmt.Sprintf("%s:/volume-mount-target:rw", tmpVolumeSrc), + "--volume", fmt.Sprintf("%s:%s:rw", tmpVolumeSrc, volumeDest), "--buildpack", readWriteBuildpackTgz, - "--env", "DETECT_TEST_FILE_PATH=/volume-mount-target/detect-file", - "--env", "BUILD_TEST_FILE_PATH=/volume-mount-target/build-file", + "--env", "DETECT_TEST_FILE_PATH="+testDetectFilePath, + "--env", "BUILD_TEST_FILE_PATH="+testBuildFilePath, ) bpOutputAsserts := assertions.NewTestBuildpackOutputAssertionManager(t, output) - bpOutputAsserts.ReportsWritingFileContents("Detect", "/volume-mount-target/detect-file") - bpOutputAsserts.ReportsReadingFileContents("Detect", "/volume-mount-target/detect-file", "some-content") - bpOutputAsserts.ReportsWritingFileContents("Build", "/volume-mount-target/build-file") - bpOutputAsserts.ReportsReadingFileContents("Build", "/volume-mount-target/build-file", "some-content") + bpOutputAsserts.ReportsWritingFileContents("Detect", testDetectFilePath) + bpOutputAsserts.ReportsReadingFileContents("Detect", testDetectFilePath, "some-content") + bpOutputAsserts.ReportsWritingFileContents("Build", testBuildFilePath) + bpOutputAsserts.ReportsReadingFileContents("Build", testBuildFilePath, "some-content") }) }) }) @@ -1083,6 +1090,7 @@ func testAcceptance( !pack.Supports("package-buildpack"), "--buildpack does not accept buildpackage unless package-buildpack is supported", ) + h.SkipIf(t, dockerHostOS() == "windows", "These tests are not yet compatible with Windows-based containers") packageImageName = packageBuildpackAsImage(t, assert, @@ -1127,6 +1135,7 @@ func testAcceptance( !pack.Supports("package-buildpack --format"), "--buildpack does not accept buildpackage file unless package-buildpack with --format is supported", ) + h.SkipIf(t, dockerHostOS() == "windows", "These tests are not yet compatible with Windows-based containers") var err error tmpDir, err = ioutil.TempDir("", "package-file") @@ -1206,8 +1215,8 @@ func testAcceptance( err = os.Setenv("ENV2_CONTENTS", "Env2 Layer Contents From Environment") assert.Nil(err) envfile.WriteString(` - DETECT_ENV_BUILDPACK="true" - ENV1_CONTENTS="Env1 Layer Contents From File" + DETECT_ENV_BUILDPACK=true + ENV1_CONTENTS=Env1 Layer Contents From File ENV2_CONTENTS `) envPath = envfile.Name() @@ -1268,12 +1277,20 @@ func testAcceptance( when("the run-image has the correct stack ID", func() { it.Before(func() { + user := func() string { + if dockerHostOS() == "windows" { + return "ContainerAdministrator" + } + + return "root" + } + runImageName = h.CreateImageOnRemote(t, dockerCli, registryConfig, "custom-run-image"+h.RandString(10), fmt.Sprintf(` FROM %s - USER root + USER %s RUN echo "custom-run" > /custom-run.txt USER pack - `, runImage)) + `, runImage, user())) }) it.After(func() { @@ -1336,12 +1353,16 @@ func testAcceptance( when("--publish", func() { it("creates image on the registry", func() { - output := pack.RunSuccessfully( - "build", repoName, + buildArgs := []string{ + repoName, "-p", filepath.Join("testdata", "mock_app"), "--publish", - "--network", "host", - ) + } + if dockerHostOS() != "windows" { + buildArgs = append(buildArgs, "--network", "host") + } + + output := pack.RunSuccessfully("build", buildArgs...) assertions.NewOutputAssertionManager(t, output).ReportsSuccessfulImageBuild(repoName) t.Log("checking that registry has contents") @@ -1366,6 +1387,21 @@ func testAcceptance( t.Log("inspect-image") output = pack.RunSuccessfully("inspect-image", repoName) + var ( + webCommand string + helloCommand string + helloArgs string + ) + if dockerHostOS() == "windows" { + webCommand = ".\\run" + helloCommand = "cmd" + helloArgs = " /c echo hello world" + } else { + webCommand = "./run" + helloCommand = "echo" + helloArgs = "hello world" + } + expectedOutput := pack.FixtureManager().TemplateFixture( "inspect_image_published_output.txt", map[string]interface{}{ @@ -1373,6 +1409,9 @@ func testAcceptance( "base_image_ref": strings.Join([]string{runImageMirror, h.Digest(t, runImageMirror)}, "@"), "base_image_top_layer": h.TopLayerDiffID(t, runImageMirror), "run_image_mirror": runImageMirror, + "web_command": webCommand, + "hello_command": helloCommand, + "hello_args": helloArgs, }, ) @@ -1594,18 +1633,29 @@ include = [ "*.jar", "media/mountain.jpg", "media/person.png" ] var buildRunImage func(string, string, string) it.Before(func() { + pack.JustRunSuccessfully("trust-builder", builderName) + repoName = registryConfig.RepoName("some-org/" + h.RandString(10)) runBefore = registryConfig.RepoName("run-before/" + h.RandString(10)) buildRunImage = func(newRunImage, contents1, contents2 string) { + user := func() string { + if dockerHostOS() == "windows" { + return "ContainerAdministrator" + } + + return "root" + } + h.CreateImage(t, dockerCli, newRunImage, fmt.Sprintf(` FROM %s - USER root + USER %s RUN echo %s > /contents1.txt RUN echo %s > /contents2.txt USER pack - `, runImage, contents1, contents2)) + `, runImage, user(), contents1, contents2)) } + buildRunImage(runBefore, "contents-before-1", "contents-before-2") // TODO: Replace --no-pull with pull-policy never. See https://github.com/buildpacks/pack/issues/775 pack.RunSuccessfully( @@ -1790,6 +1840,12 @@ func createBuilder( "read-env-buildpack", } + // NOTE: Windows-based packages are not yet supported, so we'll add this buildpack in the usual way for now. + // Remove this block once Windows-based packages are supported. + if dockerHostOS() == "windows" { + buildpacks = append(buildpacks, "simple-layers-buildpack") + } + for _, v := range buildpacks { tgz := h.CreateTGZ(t, filepath.Join(buildpacksDir, v), "./", 0755) err := os.Rename(tgz, filepath.Join(tmpDir, v+".tgz")) @@ -1800,6 +1856,9 @@ func createBuilder( var packageImageName string var packageId string + + // NOTE: Windows-based packages are not yet supported, so we'll add this buildpack in the usual way for now (see above). + // Remove this guard once Windows-based packages are supported. if dockerHostOS() != "windows" { // CREATE PACKAGE packageImageName = packageBuildpackAsImage(t, @@ -1825,13 +1884,20 @@ func createBuilder( } // RENDER builder.toml + configFileName := "builder.toml" + + // NOTE: Remove when Windows-based packages are supported (can use same toml at that point) + if dockerHostOS() == "windows" { + configFileName = "builder-windows.toml" + } + builderConfigFile, err := ioutil.TempFile(tmpDir, "builder.toml") if err != nil { return "", err } pack.FixtureManager().TemplateFixtureToFile( - "builder.toml", + configFileName, builderConfigFile, map[string]interface{}{ "package_image_name": packageImageName, @@ -1859,7 +1925,6 @@ func createBuilder( if err != nil { return "", errors.Wrapf(err, "pack failed with output %s", output) } - assert.Contains(output, fmt.Sprintf("Successfully created builder image '%s'", bldr)) assert.Nil(h.PushImage(dockerCli, bldr, registryConfig)) @@ -2080,7 +2145,6 @@ func runDockerImageExposePort(t *testing.T, assert h.AssertionManager, container ctr, err := dockerCli.ContainerCreate(ctx, &container.Config{ Image: repoName, - Env: []string{"PORT=8080"}, ExposedPorts: map[nat.Port]struct{}{"8080/tcp": {}}, Healthcheck: nil, }, &container.HostConfig{ @@ -2106,7 +2170,7 @@ func waitForResponse(t *testing.T, port string, timeout time.Duration) string { for { select { case <-ticker.C: - resp, err := h.HTTPGetE("http://localhost:"+port, map[string]string{}) + resp, err := h.HTTPGetE("http://"+h.RegistryHost(h.DockerHostname(t), port), map[string]string{}) if err != nil { break } diff --git a/acceptance/testdata/mock_app/run b/acceptance/testdata/mock_app/run index d4f6530b70..a1653205f5 100755 --- a/acceptance/testdata/mock_app/run +++ b/acceptance/testdata/mock_app/run @@ -4,7 +4,7 @@ set -x port="${1-8080}" -echo "listening on port 8080" +echo "listening on port $port" resp=$(echo "HTTP/1.1 200 OK\n" && cat "$PWD"/*-dep /contents*.txt) while true; do diff --git a/acceptance/testdata/mock_app/run.bat b/acceptance/testdata/mock_app/run.bat new file mode 100644 index 0000000000..1183af17ec --- /dev/null +++ b/acceptance/testdata/mock_app/run.bat @@ -0,0 +1,8 @@ +@echo off + +set port=8080 +if [%1] neq [] set port=%1 + +C:\util\server.exe -p %port% -g "%cd%\*-dep, c:\contents*.txt" + + diff --git a/acceptance/testdata/mock_buildpacks/0.2/descriptor-buildpack/bin/build.bat b/acceptance/testdata/mock_buildpacks/0.2/descriptor-buildpack/bin/build.bat new file mode 100644 index 0000000000..f8ef0f5b90 --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/descriptor-buildpack/bin/build.bat @@ -0,0 +1,7 @@ +@echo off + +echo ---- Build: Descriptor Buildpack + +dir /s + +echo ---- Done diff --git a/acceptance/testdata/mock_buildpacks/0.2/descriptor-buildpack/bin/detect.bat b/acceptance/testdata/mock_buildpacks/0.2/descriptor-buildpack/bin/detect.bat new file mode 100644 index 0000000000..bc2391088c --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/descriptor-buildpack/bin/detect.bat @@ -0,0 +1,5 @@ +@echo off + +echo ---- Detect: Descriptor Buildpack + +echo ---- Done diff --git a/acceptance/testdata/mock_buildpacks/0.2/internet-capable-buildpack/bin/build.bat b/acceptance/testdata/mock_buildpacks/0.2/internet-capable-buildpack/bin/build.bat new file mode 100644 index 0000000000..c7cd1f7e40 --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/internet-capable-buildpack/bin/build.bat @@ -0,0 +1,13 @@ +@echo off + +echo ---- Build: Internet capable buildpack + +ping -n 1 google.com + +if %ERRORLEVEL% equ 0 ( + echo RESULT: Connected to the internet +) else ( + echo RESULT: Disconnected from the internet +) + +echo ---- Done diff --git a/acceptance/testdata/mock_buildpacks/0.2/internet-capable-buildpack/bin/detect.bat b/acceptance/testdata/mock_buildpacks/0.2/internet-capable-buildpack/bin/detect.bat new file mode 100644 index 0000000000..75cd7d5902 --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/internet-capable-buildpack/bin/detect.bat @@ -0,0 +1,13 @@ +@echo off + +echo ---- Detect: Internet capable buildpack + +ping -n 1 google.com + +if %ERRORLEVEL% equ 0 ( + echo RESULT: Connected to the internet +) else ( + echo RESULT: Disconnected from the internet +) + +echo ---- Done diff --git a/acceptance/testdata/mock_buildpacks/0.2/noop-buildpack/bin/build.bat b/acceptance/testdata/mock_buildpacks/0.2/noop-buildpack/bin/build.bat new file mode 100644 index 0000000000..39731e4422 --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/noop-buildpack/bin/build.bat @@ -0,0 +1,3 @@ +@echo off + +echo ---- Build: NOOP Buildpack diff --git a/acceptance/testdata/mock_buildpacks/0.2/noop-buildpack/bin/detect.bat b/acceptance/testdata/mock_buildpacks/0.2/noop-buildpack/bin/detect.bat new file mode 100644 index 0000000000..15823e73f1 --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/noop-buildpack/bin/detect.bat @@ -0,0 +1,2 @@ +@echo off +:: always detect diff --git a/acceptance/testdata/mock_buildpacks/0.2/not-in-builder-buildpack/bin/build.bat b/acceptance/testdata/mock_buildpacks/0.2/not-in-builder-buildpack/bin/build.bat new file mode 100644 index 0000000000..9f3ccb78e8 --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/not-in-builder-buildpack/bin/build.bat @@ -0,0 +1,3 @@ +@echo off + +echo ---- Build: Local Buildpack diff --git a/acceptance/testdata/mock_buildpacks/0.2/not-in-builder-buildpack/bin/detect.bat b/acceptance/testdata/mock_buildpacks/0.2/not-in-builder-buildpack/bin/detect.bat new file mode 100644 index 0000000000..15823e73f1 --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/not-in-builder-buildpack/bin/detect.bat @@ -0,0 +1,2 @@ +@echo off +:: always detect diff --git a/acceptance/testdata/mock_buildpacks/0.2/read-env-buildpack/bin/build.bat b/acceptance/testdata/mock_buildpacks/0.2/read-env-buildpack/bin/build.bat new file mode 100644 index 0000000000..bc0b4f0717 --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/read-env-buildpack/bin/build.bat @@ -0,0 +1,27 @@ +@echo off +setlocal EnableDelayedExpansion + +set launch_dir=%1 +set platform_dir=%2 + +:: makes a launch layer +if exist %platform_dir%\env\ENV1_CONTENTS ( + echo making env1 layer + mkdir %launch_dir%\env1-launch-layer + set /p contents=<%platform_dir%\env\ENV1_CONTENTS + echo !contents!> %launch_dir%\env1-launch-layer\env1-launch-dep + mklink env1-launch-dep %launch_dir%\env1-launch-layer\env1-launch-dep + echo launch = true> %launch_dir%\env1-launch-layer.toml +) + +:: makes a launch layer +if exist %platform_dir%\env\ENV2_CONTENTS ( + echo making env2 layer + mkdir %launch_dir%\env2-launch-layer + set /p contents=<%platform_dir%\env\ENV2_CONTENTS + echo !contents!> %launch_dir%\env2-launch-layer\env2-launch-dep + mklink env2-launch-dep %launch_dir%\env2-launch-layer\env2-launch-dep + echo launch = true> %launch_dir%\env2-launch-layer.toml +) + +echo --- Done diff --git a/acceptance/testdata/mock_buildpacks/0.2/read-env-buildpack/bin/detect.bat b/acceptance/testdata/mock_buildpacks/0.2/read-env-buildpack/bin/detect.bat new file mode 100644 index 0000000000..c3316af236 --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/read-env-buildpack/bin/detect.bat @@ -0,0 +1,9 @@ +@echo off + +echo DETECT: Printenv buildpack + +set platform_dir=%1 + +if not exist %platform_dir%\env\DETECT_ENV_BUILDPACK ( + exit 1 +) diff --git a/acceptance/testdata/mock_buildpacks/0.2/read-volume-buildpack/bin/build.bat b/acceptance/testdata/mock_buildpacks/0.2/read-volume-buildpack/bin/build.bat new file mode 100644 index 0000000000..e7dab884bc --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/read-volume-buildpack/bin/build.bat @@ -0,0 +1,8 @@ +@echo off + +echo --- Build: Volume Buildpack + +set /p content=<%TEST_FILE_PATH% +echo Build: Reading file '%TEST_FILE_PATH%': %content% + +echo --- Done diff --git a/acceptance/testdata/mock_buildpacks/0.2/read-volume-buildpack/bin/detect.bat b/acceptance/testdata/mock_buildpacks/0.2/read-volume-buildpack/bin/detect.bat new file mode 100644 index 0000000000..f63f457fca --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/read-volume-buildpack/bin/detect.bat @@ -0,0 +1,8 @@ +@echo off + +echo --- Detect: Volume Buildpack + +set /p content=<%TEST_FILE_PATH% +echo Detect: Reading file '%TEST_FILE_PATH%': %content% + +echo --- Done diff --git a/acceptance/testdata/mock_buildpacks/0.2/read-write-volume-buildpack/bin/build.bat b/acceptance/testdata/mock_buildpacks/0.2/read-write-volume-buildpack/bin/build.bat new file mode 100644 index 0000000000..61630f38a6 --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/read-write-volume-buildpack/bin/build.bat @@ -0,0 +1,17 @@ +@echo off + +set TEST_FILE_PATH=%BUILD_TEST_FILE_PATH% + +echo --- Build: Read/Write Volume Buildpack + +echo some-content> %TEST_FILE_PATH% +if exist %TEST_FILE_PATH% ( + echo Build: Writing file '%TEST_FILE_PATH%': written +) else ( + echo Build: Writing file '%TEST_FILE_PATH%': failed +) + +set /p content=<%TEST_FILE_PATH% +echo Build: Reading file '%TEST_FILE_PATH%': %content% + +echo --- Done diff --git a/acceptance/testdata/mock_buildpacks/0.2/read-write-volume-buildpack/bin/detect.bat b/acceptance/testdata/mock_buildpacks/0.2/read-write-volume-buildpack/bin/detect.bat new file mode 100755 index 0000000000..9d6928b6e4 --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/read-write-volume-buildpack/bin/detect.bat @@ -0,0 +1,17 @@ +@echo off + +set TEST_FILE_PATH=%DETECT_TEST_FILE_PATH% + +echo --- Detect: Read/Write Volume Buildpack + +echo some-content> %TEST_FILE_PATH% +if exist %TEST_FILE_PATH% ( + echo Detect: Writing file '%TEST_FILE_PATH%': written +) else ( + echo Detect: Writing file '%TEST_FILE_PATH%': failed +) + +set /p content=<%TEST_FILE_PATH% +echo Detect: Reading file '%TEST_FILE_PATH%': %content% + +echo --- Done diff --git a/acceptance/testdata/mock_buildpacks/0.2/simple-layers-buildpack/bin/build.bat b/acceptance/testdata/mock_buildpacks/0.2/simple-layers-buildpack/bin/build.bat new file mode 100644 index 0000000000..8da9e3ec6c --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/simple-layers-buildpack/bin/build.bat @@ -0,0 +1,40 @@ +@echo off +echo --- Build: Simple Layers Buildpack + +set launch_dir=%1 + +:: makes a launch layer +echo making launch layer +mkdir %launch_dir%\launch-layer +echo Launch Dep Contents > "%launch_dir%\launch-layer\launch-dep +mklink launch-dep %launch_dir%\launch-layer\launch-dep +echo launch = true > %launch_dir%\launch-layer.toml + +:: makes a cached launch layer +if not exist %launch_dir%\cached-launch-layer.toml ( + echo making cached launch layer + mkdir %launch_dir%\cached-launch-layer + echo Cached Dep Contents > %launch_dir%\cached-launch-layer\cached-dep + mklink cached-dep %launch_dir%\cached-launch-layer\cached-dep + echo launch = true > %launch_dir%\cached-launch-layer.toml + echo cache = true >> %launch_dir%\cached-launch-layer.toml +) else ( + echo reusing cached launch layer + mklink cached-dep %launch_dir%\cached-launch-layer\cached-dep +) + +:: adds a process +( +echo [[processes]] +echo type = "web" +echo command = '.\run' +echo args = ["8080"] +echo. +echo [[processes]] +echo type = "hello" +echo command = "cmd" +echo args = ["/c", "echo hello world"] +echo direct = true +) > %launch_dir%\launch.toml + +echo --- Done diff --git a/acceptance/testdata/mock_buildpacks/0.2/simple-layers-buildpack/bin/detect.bat b/acceptance/testdata/mock_buildpacks/0.2/simple-layers-buildpack/bin/detect.bat new file mode 100644 index 0000000000..15823e73f1 --- /dev/null +++ b/acceptance/testdata/mock_buildpacks/0.2/simple-layers-buildpack/bin/detect.bat @@ -0,0 +1,2 @@ +@echo off +:: always detect diff --git a/acceptance/testdata/mock_stack/windows/run/Dockerfile b/acceptance/testdata/mock_stack/windows/run/Dockerfile index be4328aa4e..11384e015f 100644 --- a/acceptance/testdata/mock_stack/windows/run/Dockerfile +++ b/acceptance/testdata/mock_stack/windows/run/Dockerfile @@ -1,5 +1,14 @@ +FROM golang:1.14-nanoserver-1809 AS gobuild + +# bake in a simple server util +WORKDIR /util +COPY server.go /util/server.go +RUN go build /util/server.go + FROM mcr.microsoft.com/windows/nanoserver:1809 +COPY --from=gobuild /util/server.exe /util/server.exe + # placeholder values until correct values are deteremined ENV CNB_USER_ID=0 ENV CNB_GROUP_ID=0 diff --git a/acceptance/testdata/mock_stack/windows/run/server.go b/acceptance/testdata/mock_stack/windows/run/server.go new file mode 100644 index 0000000000..97ba02e361 --- /dev/null +++ b/acceptance/testdata/mock_stack/windows/run/server.go @@ -0,0 +1,46 @@ +/* +-p="8080": port to expose +-g: file globs to read (comma-separated) +*/ +package main + +import ( + "flag" + "io/ioutil" + "log" + "net/http" + "path/filepath" + "strings" +) + +func main() { + port := flag.String("p", "8080", "port to expose") + glob := flag.String("g", "", "file globs to read") + flag.Parse() + + var resp []string + + globs := strings.Split(*glob, ",") + for _, glob := range globs { + paths, err := filepath.Glob(strings.TrimSpace(glob)) + if err != nil { + panic(err.Error()) + } + + for _, path := range paths { + contents, err := ioutil.ReadFile(path) + if err != nil { + panic(err.Error()) + } + + resp = append(resp, string(contents)) + } + } + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(strings.Join(resp, "\n"))) + }) + + log.Printf("Serving %s on HTTP port: %s\n", *glob, *port) + log.Fatal(http.ListenAndServe(":"+*port, nil)) +} diff --git a/acceptance/testdata/pack_fixtures/builder-windows.toml b/acceptance/testdata/pack_fixtures/builder-windows.toml new file mode 100644 index 0000000000..94a9919811 --- /dev/null +++ b/acceptance/testdata/pack_fixtures/builder-windows.toml @@ -0,0 +1,40 @@ +[[buildpacks]] + id = "read/env" + version = "read-env-version" + uri = "read-env-buildpack.tgz" + +[[buildpacks]] + # intentionally missing id/version as they are optional + uri = "noop-buildpack.tgz" + +[[buildpacks]] + # noop-buildpack-2 has the same id but a different version compared to noop-buildpack + uri = "noop-buildpack-2.tgz" + +[[buildpacks]] + uri = "simple-layers-buildpack.tgz" + +[[order]] + +[[order.group]] + id = "simple/layers" + # intentionlly missing version to test support + +[[order.group]] + id = "read/env" + version = "read-env-version" + optional = true + +[stack] + id = "pack.test.stack" + build-image = "pack-test/build" + run-image = "pack-test/run" + run-image-mirrors = ["{{.run_image_mirror}}"] + +[lifecycle] +{{- if .lifecycle_uri}} + uri = "{{.lifecycle_uri}}" +{{- end}} +{{- if .lifecycle_version}} + version = "{{.lifecycle_version}}" +{{- end}} diff --git a/acceptance/testdata/pack_fixtures/inspect_image_local_output.txt b/acceptance/testdata/pack_fixtures/inspect_image_local_output.txt index bc5af8b4b4..92b127076a 100644 --- a/acceptance/testdata/pack_fixtures/inspect_image_local_output.txt +++ b/acceptance/testdata/pack_fixtures/inspect_image_local_output.txt @@ -22,6 +22,6 @@ Buildpacks: Processes: TYPE SHELL COMMAND ARGS - web (default) bash ./run 8080 - hello echo hello world + web (default) bash {{.web_command}} 8080 + hello {{.hello_command}} {{.hello_args}} diff --git a/acceptance/testdata/pack_fixtures/inspect_image_published_output.txt b/acceptance/testdata/pack_fixtures/inspect_image_published_output.txt index 98fe4909cf..1a54ada045 100644 --- a/acceptance/testdata/pack_fixtures/inspect_image_published_output.txt +++ b/acceptance/testdata/pack_fixtures/inspect_image_published_output.txt @@ -18,8 +18,8 @@ Buildpacks: Processes: TYPE SHELL COMMAND ARGS - web (default) bash ./run 8080 - hello echo hello world + web (default) bash {{.web_command}} 8080 + hello {{.hello_command}} {{.hello_args}} LOCAL: @@ -40,6 +40,6 @@ Buildpacks: Processes: TYPE SHELL COMMAND ARGS - web (default) bash ./run 8080 - hello echo hello world + web (default) bash {{.web_command}} 8080 + hello {{.hello_command}} {{.hello_args}} diff --git a/build.go b/build.go index a1426a6343..6f171bc158 100644 --- a/build.go +++ b/build.go @@ -139,11 +139,15 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error { return errors.Errorf("Builder %s is incompatible with this version of pack", style.Symbol(opts.Builder)) } - processedVolumes, warnings, err := processVolumes(opts.ContainerConfig.Volumes) + imgOS, err := rawBuilderImage.OS() if err != nil { - return err + return errors.Wrapf(err, "getting builder OS") } + processedVolumes, warnings, err := processVolumes(imgOS, opts.ContainerConfig.Volumes) + if err != nil { + return err + } for _, warning := range warnings { c.logger.Warn(warning) } @@ -178,11 +182,8 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error { return c.lifecycle.Execute(ctx, lifecycleOpts) } - lifecycleImageSupported := lifecycleVersion.Equal(builder.VersionMustParse(prevLifecycleVersionSupportingImage)) || !lifecycleVersion.LessThan(semver.MustParse(minLifecycleVersionSupportingImage)) - if !opts.TrustBuilder { - switch lifecycleImageSupported { - case true: + if lifecycleImageSupported(imgOS, lifecycleVersion) { lifecycleImage, err := c.imageFetcher.Fetch( ctx, fmt.Sprintf("%s:%s", lifecycleImageRepo, lifecycleVersion.String()), @@ -194,7 +195,7 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error { } lifecycleOpts.LifecycleImage = lifecycleImage.Name() - default: + } else { return errors.Errorf("Lifecycle %s does not have an associated lifecycle image. Builder must be trusted.", lifecycleVersion.String()) } } @@ -206,6 +207,15 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error { return nil } +func lifecycleImageSupported(builderOS string, lifecycleVersion *builder.Version) bool { + if builderOS == "windows" { + return false + } + + return lifecycleVersion.Equal(builder.VersionMustParse(prevLifecycleVersionSupportingImage)) || + !lifecycleVersion.LessThan(semver.MustParse(minLifecycleVersionSupportingImage)) +} + // supportsPlatformAPI determines whether pack can build using the builder based on the builder's supported Platform API versions. func supportsPlatformAPI(builderPlatformAPIs builder.APISet) bool { for _, packSupportedAPI := range build.SupportedPlatformAPIVersions { @@ -643,17 +653,24 @@ func randString(n int) string { return string(b) } -func processVolumes(volumes []string) (processed []string, warnings []string, err error) { - // Assume a linux container - parser := mounts.NewParser(mounts.OSLinux) +func processVolumes(imgOS string, volumes []string) (processed []string, warnings []string, err error) { + parserOS := mounts.OSLinux + if imgOS == "windows" { + parserOS = mounts.OSWindows + } + parser := mounts.NewParser(parserOS) for _, v := range volumes { volume, err := parser.ParseMountRaw(v, "") if err != nil { return nil, nil, errors.Wrapf(err, "platform volume %q has invalid format", v) } - for _, p := range [...]string{"/cnb", "/layers"} { - if strings.HasPrefix(volume.Spec.Target, p) { + sensitiveDirs := []string{"/cnb", "/layers"} + if imgOS == "windows" { + sensitiveDirs = []string{`c:/cnb`, `c:\cnb`, `c:/layers`, `c:\layers`} + } + for _, p := range sensitiveDirs { + if strings.HasPrefix(strings.ToLower(volume.Spec.Target), p) { warnings = append(warnings, fmt.Sprintf("Mounting to a sensitive directory %s", style.Symbol(volume.Spec.Target))) } } diff --git a/build_test.go b/build_test.go index d58b03d69b..38a2f89af6 100644 --- a/build_test.go +++ b/build_test.go @@ -1344,6 +1344,18 @@ func testBuild(t *testing.T, when spec.G, it spec.S) { }) when("builder is untrusted", func() { + when("building Windows containers", func() { + it("errors and mentions that builder must be trusted", func() { + defaultBuilderImage.SetPlatform("windows", "", "") + h.AssertError(t, subject.Build(context.TODO(), BuildOptions{ + Image: "some/app", + Builder: defaultBuilderName, + Publish: true, + TrustBuilder: false, + }), "does not have an associated lifecycle image. Builder must be trusted.") + }) + }) + when("lifecycle image is available", func() { it("uses the 5 phases with the lifecycle image", func() { h.AssertNil(t, subject.Build(context.TODO(), BuildOptions{ diff --git a/client.go b/client.go index 6f3f175747..c785c2e6b4 100644 --- a/client.go +++ b/client.go @@ -18,6 +18,8 @@ import ( "github.com/buildpacks/pack/logging" ) +//go:generate mockgen -package testmocks -destination testmocks/mock_docker_client.go github.com/docker/docker/client CommonAPIClient + //go:generate mockgen -package testmocks -destination testmocks/mock_image_fetcher.go github.com/buildpacks/pack ImageFetcher type ImageFetcher interface { // Fetch fetches an image by resolving it both remotely and locally depending on provided parameters. diff --git a/go.mod b/go.mod index 337b024d05..109190bf1d 100644 --- a/go.mod +++ b/go.mod @@ -5,18 +5,17 @@ require ( github.com/Masterminds/semver v1.5.0 github.com/Microsoft/hcsshim v0.8.7 // indirect github.com/apex/log v1.1.2 - github.com/buildpacks/imgutil v0.0.0-20200424215026-dfdc82949704 + github.com/buildpacks/imgutil v0.0.0-20200805143852-1844b230530d github.com/buildpacks/lifecycle v0.7.2 github.com/containerd/containerd v1.3.3 // indirect github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41 // indirect - github.com/dgodd/dockerdial v1.0.1 github.com/docker/cli v0.0.0-20200312141509-ef2f64abbd37 // indirect github.com/docker/docker v1.4.2-0.20200221181110-62bd5a33f707 github.com/docker/go-connections v0.4.0 github.com/gogo/protobuf v1.3.1 // indirect github.com/golang/mock v1.4.1 github.com/golang/protobuf v1.3.5 // indirect - github.com/google/go-cmp v0.4.0 + github.com/google/go-cmp v0.5.1 github.com/google/go-containerregistry v0.0.0-20200313165449-955bf358a3d8 github.com/google/go-github/v30 v30.1.0 github.com/heroku/color v0.0.6 diff --git a/go.sum b/go.sum index 6867094197..e287d35a2c 100644 --- a/go.sum +++ b/go.sum @@ -27,14 +27,12 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= github.com/Microsoft/hcsshim v0.8.7 h1:ptnOoufxGSzauVTsdE+wMYnCWA301PdoN4xg5oRdZpg= github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -66,8 +64,12 @@ github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/buildpacks/imgutil v0.0.0-20200313170640-a02052f47d62 h1:jo6zuwPgCWD/V5YQEgaRKeW/uxy4fhFO9FsFWmKCtdQ= github.com/buildpacks/imgutil v0.0.0-20200313170640-a02052f47d62/go.mod h1:TjPmM78urjQIiMal4T7en6iBekAPv6z1yVMZobc4Kd8= -github.com/buildpacks/imgutil v0.0.0-20200424215026-dfdc82949704 h1:ppE+Fdjl4fAHb2Ik+iUPPV5mbSu2M8IM8Cz7M37Vlu0= -github.com/buildpacks/imgutil v0.0.0-20200424215026-dfdc82949704/go.mod h1:5AWk59DdFQopBvOPhpx0tRum31cIjO1Ln/kABKFOzKQ= +github.com/buildpacks/imgutil v0.0.0-20200528211046-5c4cfa56bb24 h1:5JJD0uW/I2yfYyFqZZdZ4upgonr6q20WWvR1R53c7ec= +github.com/buildpacks/imgutil v0.0.0-20200528211046-5c4cfa56bb24/go.mod h1:rkRDOGpntpFhgj0gIUhQnEt5DYvi7xUTHkZWSxbWJP0= +github.com/buildpacks/imgutil v0.0.0-20200625161542-2281cd9b1414 h1:p0JTQSapoTcxDG8pMgeXJ5Z9sYhYiFSVc/+0GM2RiTA= +github.com/buildpacks/imgutil v0.0.0-20200625161542-2281cd9b1414/go.mod h1:0MWMP1K2tA1fJnQOzGZDq8NHaWH+r7YUuyYLCEqYCx8= +github.com/buildpacks/imgutil v0.0.0-20200805143852-1844b230530d h1:uVTFIiev3f7fi5BSv1RtM5W5lcqQodqLRBG5AdoDe2U= +github.com/buildpacks/imgutil v0.0.0-20200805143852-1844b230530d/go.mod h1:uVv0fNwOEBNgyM9ZvwV0g2Dvzk31q5TtSeoC1GGmW+k= github.com/buildpacks/lifecycle v0.7.2 h1:FO7i2cokLNc7lcuThq/LYt1jmkB8HBrjpK+2GWWsaLI= github.com/buildpacks/lifecycle v0.7.2/go.mod h1:k41tT3XOt7ufaMGAvOpEsXyuJpUPoo4F686Z652lU3E= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -107,18 +109,14 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgodd/dockerdial v1.0.1 h1:6XixGQxeytsIdVsbI4y+EHuv8QcxxH6ySJZLkm3jk5o= -github.com/dgodd/dockerdial v1.0.1/go.mod h1:MJmK56eTylC3KU7DR6bc3k9jmbpURO8rDOsGbfj+c6o= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v0.0.0-20200312141509-ef2f64abbd37 h1:MKHpi6ibJ9V5iuyUABEppUcvP0idDC1klY+UuiSFSPc= github.com/docker/cli v0.0.0-20200312141509-ef2f64abbd37/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v0.0.0-20180327202408-83389a148052/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.7.3-0.20181027010111-b8e87cfdad8d/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20200221181110-62bd5a33f707 h1:sF5ALylAtPbpvthO6EMyjXZfvZuVIYoJLPgSWkGZJjo= @@ -127,7 +125,6 @@ github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGl github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= @@ -178,7 +175,6 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= @@ -196,8 +192,11 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-containerregistry v0.0.0-20200311163244-4b1985e5ea21/go.mod h1:m8YvHwSOuBCq25yrj1DaX/fIMrv6ec3CNg8jY8+5PEA= github.com/google/go-containerregistry v0.0.0-20200313165449-955bf358a3d8 h1:S7U1nPK3fi2xjZkMrQKcRayVtMmqMFJs9UtXQW3GPzM= github.com/google/go-containerregistry v0.0.0-20200313165449-955bf358a3d8/go.mod h1:pD1UFYs7MCAx+ZLShBdttcaOSbyc8F9Na/9IZLNwJeA= @@ -216,8 +215,6 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -234,8 +231,6 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= -github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/heroku/color v0.0.6 h1:UTFFMrmMLFcL3OweqP1lAdp8i1y/9oHqkeHjQ/b/Ny0= github.com/heroku/color v0.0.6/go.mod h1:ZBvOcx7cTF2QKOv4LbmoBtNl5uB17qWxGuzZrsi1wLU= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= @@ -261,7 +256,6 @@ github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -381,7 +375,6 @@ github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= @@ -468,7 +461,6 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -485,7 +477,6 @@ golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -520,7 +511,6 @@ golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181025063200-d989b31c8746/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -559,7 +549,6 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -603,7 +592,6 @@ google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200313141609-30c55424f95d h1:pyQjO6BnPvrPMldYxgDlXq9PLahtc0EKnUTYX1pWwXU= google.golang.org/genproto v0.0.0-20200313141609-30c55424f95d/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -648,12 +636,10 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/archive/archive.go b/internal/archive/archive.go index ef68b957f5..5c5933bdc5 100644 --- a/internal/archive/archive.go +++ b/internal/archive/archive.go @@ -81,7 +81,12 @@ func GenerateTarWithWriter(genFn func(TarWriter) error, twf TarWriterFactory) io errChan <- closeErr }() + closed := false return ioutils.NewReadCloserWrapper(pr, func() error { + if closed { + return errors.New("reader already closed") + } + var completeErr error // closing the reader ensures that if anything attempts @@ -95,6 +100,7 @@ func GenerateTarWithWriter(genFn func(TarWriter) error, twf TarWriterFactory) io completeErr = aggregateError(completeErr, err) } + closed = true return completeErr }) } diff --git a/internal/build/build.go b/internal/build/build.go index 6f1cb454c5..83fdf1cf05 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -3,8 +3,10 @@ package build import ( "context" "math/rand" + "strings" "time" + "github.com/buildpacks/imgutil" "github.com/buildpacks/lifecycle/api" "github.com/docker/docker/client" "github.com/google/go-containerregistry/pkg/name" @@ -12,6 +14,7 @@ import ( "github.com/buildpacks/pack/internal/builder" "github.com/buildpacks/pack/internal/cache" + "github.com/buildpacks/pack/internal/paths" "github.com/buildpacks/pack/internal/style" "github.com/buildpacks/pack/logging" ) @@ -27,6 +30,7 @@ type Builder interface { GID() int LifecycleDescriptor() builder.LifecycleDescriptor Stack() builder.StackMetadata + Image() imgutil.Image } type Lifecycle struct { @@ -44,6 +48,8 @@ type Lifecycle struct { appVolume string defaultProcessType string fileFilter func(string) bool + os string + mountPaths mountPaths } func (l *Lifecycle) Builder() Builder { @@ -97,12 +103,16 @@ type LifecycleOptions struct { } func (l *Lifecycle) Execute(ctx context.Context, opts LifecycleOptions) error { - l.Setup(opts) + err := l.Setup(opts) + if err != nil { + return err + } defer l.Cleanup() phaseFactory := NewDefaultPhaseFactory(l) buildCache := cache.NewVolumeCache(opts.Image, "build", l.docker) + l.logger.Debugf("Using build cache volume %s", style.Symbol(buildCache.Name())) if opts.ClearCache { if err := buildCache.Clear(ctx); err != nil { @@ -155,9 +165,9 @@ func (l *Lifecycle) Execute(ctx context.Context, opts LifecycleOptions) error { ) } -func (l *Lifecycle) Setup(opts LifecycleOptions) { - l.layersVolume = "pack-layers-" + randString(10) - l.appVolume = "pack-app-" + randString(10) +func (l *Lifecycle) Setup(opts LifecycleOptions) error { + l.layersVolume = paths.FilterReservedNames("pack-layers-" + randString(10)) + l.appVolume = paths.FilterReservedNames("pack-app-" + randString(10)) l.appPath = opts.AppPath l.builder = opts.Builder l.lifecycleImage = opts.LifecycleImage @@ -168,6 +178,14 @@ func (l *Lifecycle) Setup(opts LifecycleOptions) { l.platformAPIVersion = opts.Builder.LifecycleDescriptor().APIs.Platform.Supported.Latest().String() l.defaultProcessType = opts.DefaultProcessType l.fileFilter = opts.FileFilter + + os, err := l.builder.Image().OS() + if err != nil { + return err + } + l.os = os + l.mountPaths = mountPathsForOS(l.os) + return nil } func (l *Lifecycle) Cleanup() error { @@ -188,3 +206,53 @@ func randString(n int) string { } return string(b) } + +type mountPaths struct { + volume string + separator string +} + +func mountPathsForOS(os string) mountPaths { + if os == "windows" { + return mountPaths{ + volume: `c:`, + separator: `\`, + } + } + return mountPaths{ + volume: "", + separator: "/", + } +} + +func (m mountPaths) join(parts ...string) string { + return strings.Join(parts, m.separator) +} + +func (m mountPaths) layersDir() string { + return m.join(m.volume, "layers") +} + +func (m mountPaths) stackPath() string { + return m.join(m.layersDir(), "stack.toml") +} + +func (m mountPaths) appDirName() string { + return "workspace" +} + +func (m mountPaths) appDir() string { + return m.join(m.volume, m.appDirName()) +} + +func (m mountPaths) cacheDir() string { + return m.join(m.volume, "cache") +} + +func (m mountPaths) launchCacheDir() string { + return m.join(m.volume, "launch-cache") +} + +func (m mountPaths) platformDir() string { + return m.join(m.volume, "platform") +} diff --git a/internal/build/container_ops.go b/internal/build/container_ops.go index 98eb08eb63..aa659f4990 100644 --- a/internal/build/container_ops.go +++ b/internal/build/container_ops.go @@ -3,57 +3,145 @@ package build import ( "bytes" "context" + "fmt" "io" + "io/ioutil" "os" "runtime" + "strings" "github.com/BurntSushi/toml" "github.com/docker/docker/api/types" + dcontainer "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" "github.com/pkg/errors" "github.com/buildpacks/pack/internal/archive" "github.com/buildpacks/pack/internal/builder" + "github.com/buildpacks/pack/internal/container" + "github.com/buildpacks/pack/internal/style" ) -type ContainerOperation func(ctrClient client.CommonAPIClient, ctx context.Context, containerID string) error +type ContainerOperation func(ctrClient client.CommonAPIClient, ctx context.Context, containerID string, stdout, stderr io.Writer) error // CopyDir copies a local directory (src) to the destination on the container while filtering files and changing it's UID/GID. func CopyDir(src, dst string, uid, gid int, fileFilter func(string) bool) ContainerOperation { - return func(ctrClient client.CommonAPIClient, ctx context.Context, containerID string) error { - var ( - reader io.ReadCloser - clientErr error - ) + return func(ctrClient client.CommonAPIClient, ctx context.Context, containerID string, stdout, stderr io.Writer) error { + info, err := ctrClient.Info(ctx) + if err != nil { + return err + } + if info.OSType == "windows" { + readerDst := strings.ReplaceAll(dst, `\`, "/")[2:] // Strip volume, convert slashes to conform to TAR format + reader, err := createReader(src, readerDst, uid, gid, fileFilter) + if err != nil { + return errors.Wrapf(err, "create tar archive from '%s'", src) + } + defer reader.Close() + return copyDirWindows(ctx, ctrClient, containerID, reader, dst, stdout, stderr) + } reader, err := createReader(src, dst, uid, gid, fileFilter) if err != nil { return errors.Wrapf(err, "create tar archive from '%s'", src) } defer reader.Close() + return copyDir(ctx, ctrClient, containerID, reader) + } +} - doneChan := make(chan interface{}) - pr, pw := io.Pipe() - go func() { - clientErr = ctrClient.CopyToContainer(ctx, containerID, "/", pr, types.CopyToContainerOptions{}) - close(doneChan) - }() - func() { - defer pw.Close() - _, err = io.Copy(pw, reader) - }() - - <-doneChan - if err == nil { - err = clientErr - } +func copyDir(ctx context.Context, ctrClient client.CommonAPIClient, containerID string, appReader io.Reader) error { + var clientErr, err error + doneChan := make(chan interface{}) + pr, pw := io.Pipe() + go func() { + clientErr = ctrClient.CopyToContainer(ctx, containerID, "/", pr, types.CopyToContainerOptions{}) + close(doneChan) + }() + func() { + defer pw.Close() + _, err = io.Copy(pw, appReader) + }() + + <-doneChan + if err == nil { + err = clientErr + } + + return err +} + +// copyDirWindows provides an alternate, Windows container-specific implementation of copyDir. +// This implementation is needed because copying directly to a mounted volume is currently buggy +// for Windows containers and does not work. Instead, we perform the copy from inside a container +// using xcopy. +// See: https://github.com/moby/moby/issues/40771 +func copyDirWindows(ctx context.Context, ctrClient client.CommonAPIClient, containerID string, appReader io.Reader, dst string, stdout, stderr io.Writer) error { + info, err := ctrClient.ContainerInspect(ctx, containerID) + if err != nil { return err } + + pathElements := strings.Split(dst, `\`) + if len(pathElements) < 1 { + return fmt.Errorf("cannot determine base name for destination path: %s", style.Symbol(dst)) + } + baseName := pathElements[len(pathElements)-1] + + mnt, err := findMount(info, dst) + if err != nil { + return err + } + + ctr, err := ctrClient.ContainerCreate(ctx, + &dcontainer.Config{ + Image: info.Image, + Cmd: []string{ + "xcopy", + fmt.Sprintf(`c:\windows\%s`, baseName), + dst, + "/e", "/h", "/y", "/c", "/b", + }, + WorkingDir: "/", + User: windowsContainerAdmin, + }, + &dcontainer.HostConfig{ + Binds: []string{fmt.Sprintf("%s:%s", mnt.Name, mnt.Destination)}, + Isolation: dcontainer.IsolationProcess, + }, + nil, "", + ) + if err != nil { + return errors.Wrapf(err, "creating prep container") + } + defer ctrClient.ContainerRemove(context.Background(), ctr.ID, types.ContainerRemoveOptions{Force: true}) + + err = ctrClient.CopyToContainer(ctx, ctr.ID, "/windows", appReader, types.CopyToContainerOptions{}) + if err != nil { + return errors.Wrap(err, "copy app to container") + } + + return container.Run( + ctx, + ctrClient, + ctr.ID, + ioutil.Discard, // Suppress xcopy output + stderr, + ) +} + +func findMount(info types.ContainerJSON, dst string) (types.MountPoint, error) { + for _, m := range info.Mounts { + if m.Destination == dst { + return m, nil + } + } + return types.MountPoint{}, errors.New("no matching mount found") } // WriteStackToml writes a `stack.toml` based on the StackMetadata provided to the destination path. func WriteStackToml(dstPath string, stack builder.StackMetadata) ContainerOperation { - return func(ctrClient client.CommonAPIClient, ctx context.Context, containerID string) error { + return func(ctrClient client.CommonAPIClient, ctx context.Context, containerID string, stdout, stderr io.Writer) error { buf := &bytes.Buffer{} err := toml.NewEncoder(buf).Encode(stack) if err != nil { diff --git a/internal/build/container_ops_test.go b/internal/build/container_ops_test.go index 58d646d399..61abcfe0e2 100644 --- a/internal/build/container_ops_test.go +++ b/internal/build/container_ops_test.go @@ -65,7 +65,7 @@ func testContainerOps(t *testing.T, when spec.G, it spec.S) { ctr, err := createContainer(ctx, imageName, "ls", "-al", "/some-location") h.AssertNil(t, err) - err = copyDirOp(ctrClient, ctx, ctr.ID) + err = copyDirOp(ctrClient, ctx, ctr.ID, &outBuf, &errBuf) h.AssertNil(t, err) err = container.Run(ctx, ctrClient, ctr.ID, &outBuf, &errBuf) @@ -92,7 +92,7 @@ func testContainerOps(t *testing.T, when spec.G, it spec.S) { ctr, err := createContainer(ctx, imageName, "ls", "-al", "/some-location") h.AssertNil(t, err) - err = copyDirOp(ctrClient, ctx, ctr.ID) + err = copyDirOp(ctrClient, ctx, ctr.ID, &outBuf, &errBuf) h.AssertNil(t, err) err = container.Run(ctx, ctrClient, ctr.ID, &outBuf, &errBuf) @@ -109,7 +109,7 @@ func testContainerOps(t *testing.T, when spec.G, it spec.S) { ctr, err := createContainer(ctx, imageName, "ls", "-al", "/some-location") h.AssertNil(t, err) - err = copyDirOp(ctrClient, ctx, ctr.ID) + err = copyDirOp(ctrClient, ctx, ctr.ID, &outBuf, &errBuf) h.AssertNil(t, err) err = container.Run(ctx, ctrClient, ctr.ID, &outBuf, &errBuf) @@ -137,7 +137,7 @@ func testContainerOps(t *testing.T, when spec.G, it spec.S) { ctr, err := createContainer(ctx, imageName, "ls", "-al", "/some/stack.toml") h.AssertNil(t, err) - err = writeOp(ctrClient, ctx, ctr.ID) + err = writeOp(ctrClient, ctx, ctr.ID, &outBuf, &errBuf) h.AssertNil(t, err) err = container.Run(ctx, ctrClient, ctr.ID, &outBuf, &errBuf) @@ -161,7 +161,7 @@ func testContainerOps(t *testing.T, when spec.G, it spec.S) { ctr, err := createContainer(ctx, imageName, "cat", "/some/stack.toml") h.AssertNil(t, err) - err = writeOp(ctrClient, ctx, ctr.ID) + err = writeOp(ctrClient, ctx, ctr.ID, &outBuf, &errBuf) h.AssertNil(t, err) err = container.Run(ctx, ctrClient, ctr.ID, &outBuf, &errBuf) diff --git a/internal/build/fakes/fake_builder.go b/internal/build/fakes/fake_builder.go index 81e1eb5944..7b748ec5ec 100644 --- a/internal/build/fakes/fake_builder.go +++ b/internal/build/fakes/fake_builder.go @@ -2,6 +2,8 @@ package fakes import ( "github.com/Masterminds/semver" + "github.com/buildpacks/imgutil" + ifakes "github.com/buildpacks/imgutil/fakes" "github.com/buildpacks/lifecycle/api" "github.com/buildpacks/pack/internal/build" @@ -9,7 +11,7 @@ import ( ) type FakeBuilder struct { - ReturnForName string + ReturnForImage *ifakes.Image ReturnForUID int ReturnForGID int ReturnForLifecycleDescriptor builder.LifecycleDescriptor @@ -33,9 +35,9 @@ func NewFakeBuilder(ops ...func(*FakeBuilder)) (*FakeBuilder, error) { } fakeBuilder := &FakeBuilder{ - ReturnForName: "some-builder-name", - ReturnForUID: 99, - ReturnForGID: 99, + ReturnForImage: ifakes.NewImage("some-builder-name", "", nil), + ReturnForUID: 99, + ReturnForGID: 99, ReturnForLifecycleDescriptor: builder.LifecycleDescriptor{ APIs: builder.LifecycleAPIs{ Buildpack: builder.APIVersions{ @@ -59,9 +61,9 @@ func NewFakeBuilder(ops ...func(*FakeBuilder)) (*FakeBuilder, error) { return fakeBuilder, nil } -func WithName(name string) func(*FakeBuilder) { +func WithImage(image *ifakes.Image) func(*FakeBuilder) { return func(builder *FakeBuilder) { - builder.ReturnForName = name + builder.ReturnForImage = image } } @@ -78,7 +80,11 @@ func WithGID(gid int) func(*FakeBuilder) { } func (b *FakeBuilder) Name() string { - return b.ReturnForName + return b.ReturnForImage.Name() +} + +func (b *FakeBuilder) Image() imgutil.Image { + return b.ReturnForImage } func (b *FakeBuilder) UID() int { diff --git a/internal/build/phase.go b/internal/build/phase.go index 1b55bcf4f1..d8255f2d89 100644 --- a/internal/build/phase.go +++ b/internal/build/phase.go @@ -28,14 +28,13 @@ type Phase struct { func (p *Phase) Run(ctx context.Context) error { var err error - p.ctr, err = p.docker.ContainerCreate(ctx, p.ctrConf, p.hostConf, nil, "") if err != nil { return errors.Wrapf(err, "failed to create '%s' container", p.name) } for _, containerOp := range p.containerOps { - if err := containerOp(p.docker, ctx, p.ctr.ID); err != nil { + if err := containerOp(p.docker, ctx, p.ctr.ID, p.infoWriter, p.errorWriter); err != nil { return err } } diff --git a/internal/build/phase_config_provider.go b/internal/build/phase_config_provider.go index 96ac3b7943..f20d17f33e 100644 --- a/internal/build/phase_config_provider.go +++ b/internal/build/phase_config_provider.go @@ -9,12 +9,18 @@ import ( "github.com/buildpacks/pack/logging" ) +const ( + linuxContainerAdmin = "root" + windowsContainerAdmin = "ContainerAdministrator" +) + type PhaseConfigProviderOperation func(*PhaseConfigProvider) type PhaseConfigProvider struct { ctrConf *container.Config hostConf *container.HostConfig name string + os string containerOps []ContainerOperation infoWriter io.Writer errorWriter io.Writer @@ -25,6 +31,7 @@ func NewPhaseConfigProvider(name string, lifecycle *Lifecycle, ops ...PhaseConfi ctrConf: new(container.Config), hostConf: new(container.HostConfig), name: name, + os: lifecycle.os, infoWriter: logging.GetWriterForLevel(lifecycle.logger, logging.InfoLevel), errorWriter: logging.GetWriterForLevel(lifecycle.logger, logging.ErrorLevel), } @@ -32,11 +39,15 @@ func NewPhaseConfigProvider(name string, lifecycle *Lifecycle, ops ...PhaseConfi provider.ctrConf.Image = lifecycle.builder.Name() provider.ctrConf.Labels = map[string]string{"author": "pack"} + if lifecycle.os == "windows" { + provider.hostConf.Isolation = container.IsolationProcess + } + ops = append(ops, WithLifecycleProxy(lifecycle), WithBinds([]string{ - fmt.Sprintf("%s:%s", lifecycle.layersVolume, layersDir), - fmt.Sprintf("%s:%s", lifecycle.appVolume, appDir), + fmt.Sprintf("%s:%s", lifecycle.layersVolume, lifecycle.mountPaths.layersDir()), + fmt.Sprintf("%s:%s", lifecycle.appVolume, lifecycle.mountPaths.appDir()), }...), ) @@ -94,8 +105,12 @@ func WithBinds(binds ...string) PhaseConfigProviderOperation { func WithDaemonAccess() PhaseConfigProviderOperation { return func(provider *PhaseConfigProvider) { - provider.ctrConf.User = "root" - provider.hostConf.Binds = append(provider.hostConf.Binds, "/var/run/docker.sock:/var/run/docker.sock") + WithRoot()(provider) + bind := "/var/run/docker.sock:/var/run/docker.sock" + if provider.os == "windows" { + bind = `\\.\pipe\docker_engine:\\.\pipe\docker_engine` + } + provider.hostConf.Binds = append(provider.hostConf.Binds, bind) } } @@ -154,7 +169,11 @@ func WithRegistryAccess(authConfig string) PhaseConfigProviderOperation { func WithRoot() PhaseConfigProviderOperation { return func(provider *PhaseConfigProvider) { - provider.ctrConf.User = "root" + if provider.os == "windows" { + provider.ctrConf.User = windowsContainerAdmin + } else { + provider.ctrConf.User = linuxContainerAdmin + } } } diff --git a/internal/build/phase_config_provider_test.go b/internal/build/phase_config_provider_test.go index 3a2dba8119..add8806d74 100644 --- a/internal/build/phase_config_provider_test.go +++ b/internal/build/phase_config_provider_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + ifakes "github.com/buildpacks/imgutil/fakes" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/strslice" "github.com/heroku/color" @@ -29,8 +30,8 @@ func TestPhaseConfigProvider(t *testing.T) { func testPhaseConfigProvider(t *testing.T, when spec.G, it spec.S) { when("#NewPhaseConfigProvider", func() { it("returns a phase config provider with defaults", func() { - expectedBuilderName := "some-builder-name" - fakeBuilder, err := fakes.NewFakeBuilder(fakes.WithName(expectedBuilderName)) + expectedBuilderImage := ifakes.NewImage("some-builder-name", "", nil) + fakeBuilder, err := fakes.NewFakeBuilder(fakes.WithImage(expectedBuilderImage)) h.AssertNil(t, err) lifecycle := newTestLifecycle(t, false, fakes.WithBuilder(fakeBuilder)) expectedPhaseName := "some-name" @@ -40,7 +41,7 @@ func testPhaseConfigProvider(t *testing.T, when spec.G, it spec.S) { h.AssertEq(t, phaseConfigProvider.Name(), expectedPhaseName) h.AssertEq(t, phaseConfigProvider.ContainerConfig().Cmd, expectedCmd) - h.AssertEq(t, phaseConfigProvider.ContainerConfig().Image, expectedBuilderName) + h.AssertEq(t, phaseConfigProvider.ContainerConfig().Image, expectedBuilderImage.Name()) h.AssertEq(t, phaseConfigProvider.ContainerConfig().Labels, map[string]string{"author": "pack"}) // CreateFakeLifecycle sets the following: @@ -53,6 +54,22 @@ func testPhaseConfigProvider(t *testing.T, when spec.G, it spec.S) { h.AssertSliceContainsMatch(t, phaseConfigProvider.HostConfig().Binds, "pack-layers-.*:/layers") h.AssertSliceContainsMatch(t, phaseConfigProvider.HostConfig().Binds, "pack-app-.*:/workspace") + + h.AssertEq(t, phaseConfigProvider.HostConfig().Isolation, container.IsolationEmpty) + }) + + when("building for Windows", func() { + it("sets process isolation", func() { + fakeBuilderImage := ifakes.NewImage("fake-builder", "", nil) + fakeBuilderImage.SetPlatform("windows", "", "") + fakeBuilder, err := fakes.NewFakeBuilder(fakes.WithImage(fakeBuilderImage)) + h.AssertNil(t, err) + lifecycle := newTestLifecycle(t, false, fakes.WithBuilder(fakeBuilder)) + + phaseConfigProvider := build.NewPhaseConfigProvider("some-name", lifecycle) + + h.AssertEq(t, phaseConfigProvider.HostConfig().Isolation, container.IsolationProcess) + }) }) when("called with WithArgs", func() { @@ -103,17 +120,38 @@ func testPhaseConfigProvider(t *testing.T, when spec.G, it spec.S) { }) when("called with WithDaemonAccess", func() { - it("sets daemon access on the config", func() { - lifecycle := newTestLifecycle(t, false) - - phaseConfigProvider := build.NewPhaseConfigProvider( - "some-name", - lifecycle, - build.WithDaemonAccess(), - ) + when("building for non-Windows", func() { + it("sets daemon access on the config", func() { + lifecycle := newTestLifecycle(t, false) + + phaseConfigProvider := build.NewPhaseConfigProvider( + "some-name", + lifecycle, + build.WithDaemonAccess(), + ) + + h.AssertEq(t, phaseConfigProvider.ContainerConfig().User, "root") + h.AssertSliceContains(t, phaseConfigProvider.HostConfig().Binds, "/var/run/docker.sock:/var/run/docker.sock") + }) + }) - h.AssertEq(t, phaseConfigProvider.ContainerConfig().User, "root") - h.AssertSliceContains(t, phaseConfigProvider.HostConfig().Binds, "/var/run/docker.sock:/var/run/docker.sock") + when("building for Windows", func() { + it("sets daemon access on the config", func() { + fakeBuilderImage := ifakes.NewImage("fake-builder", "", nil) + fakeBuilderImage.SetPlatform("windows", "", "") + fakeBuilder, err := fakes.NewFakeBuilder(fakes.WithImage(fakeBuilderImage)) + h.AssertNil(t, err) + lifecycle := newTestLifecycle(t, false, fakes.WithBuilder(fakeBuilder)) + + phaseConfigProvider := build.NewPhaseConfigProvider( + "some-name", + lifecycle, + build.WithDaemonAccess(), + ) + + h.AssertEq(t, phaseConfigProvider.ContainerConfig().User, "ContainerAdministrator") + h.AssertSliceContains(t, phaseConfigProvider.HostConfig().Binds, `\\.\pipe\docker_engine:\\.\pipe\docker_engine`) + }) }) }) @@ -184,16 +222,36 @@ func testPhaseConfigProvider(t *testing.T, when spec.G, it spec.S) { }) when("called with WithRoot", func() { - it("sets root user on the config", func() { - lifecycle := newTestLifecycle(t, false) - - phaseConfigProvider := build.NewPhaseConfigProvider( - "some-name", - lifecycle, - build.WithRoot(), - ) + when("building for non-Windows", func() { + it("sets root user on the config", func() { + lifecycle := newTestLifecycle(t, false) + + phaseConfigProvider := build.NewPhaseConfigProvider( + "some-name", + lifecycle, + build.WithRoot(), + ) + + h.AssertEq(t, phaseConfigProvider.ContainerConfig().User, "root") + }) + }) - h.AssertEq(t, phaseConfigProvider.ContainerConfig().User, "root") + when("building for Windows", func() { + it("sets root user on the config", func() { + fakeBuilderImage := ifakes.NewImage("fake-builder", "", nil) + fakeBuilderImage.SetPlatform("windows", "", "") + fakeBuilder, err := fakes.NewFakeBuilder(fakes.WithImage(fakeBuilderImage)) + h.AssertNil(t, err) + lifecycle := newTestLifecycle(t, false, fakes.WithBuilder(fakeBuilder)) + + phaseConfigProvider := build.NewPhaseConfigProvider( + "some-name", + lifecycle, + build.WithRoot(), + ) + + h.AssertEq(t, phaseConfigProvider.ContainerConfig().User, "ContainerAdministrator") + }) }) }) diff --git a/internal/build/phase_test.go b/internal/build/phase_test.go index 62c5142319..abb52cac85 100644 --- a/internal/build/phase_test.go +++ b/internal/build/phase_test.go @@ -404,12 +404,16 @@ func CreateFakeLifecycle(docker client.CommonAPIClient, logger logging.Logger, a return nil, err } - subject.Setup(build.LifecycleOptions{ + err = subject.Setup(build.LifecycleOptions{ AppPath: appDir, Builder: bldr, HTTPProxy: "some-http-proxy", HTTPSProxy: "some-https-proxy", NoProxy: "some-no-proxy", }) + if err != nil { + return nil, err + } + return subject, nil } diff --git a/internal/build/phases.go b/internal/build/phases.go index 587ab16a14..a3918464e8 100644 --- a/internal/build/phases.go +++ b/internal/build/phases.go @@ -11,15 +11,7 @@ import ( "github.com/buildpacks/pack/internal/builder" ) -const ( - layersDir = "/layers" - appDir = "/workspace" - cacheDir = "/cache" - launchCacheDir = "/launch-cache" - platformDir = "/platform" - stackPath = layersDir + "/stack.toml" - defaultProcessPlatformAPI = "0.3" -) +const defaultProcessPlatformAPI = "0.3" type RunnerCleaner interface { Run(ctx context.Context) error @@ -38,7 +30,7 @@ func (l *Lifecycle) Create( phaseFactory PhaseFactory, ) error { flags := []string{ - "-cache-dir", cacheDir, + "-cache-dir", l.mountPaths.cacheDir(), "-run-image", runImage, } @@ -58,8 +50,8 @@ func (l *Lifecycle) Create( WithFlags(l.withLogLevel(flags...)...), WithArgs(repoName), WithNetwork(networkMode), - WithBinds(append(volumes, fmt.Sprintf("%s:%s", cacheName, cacheDir))...), - WithContainerOperations(CopyDir(l.appPath, appDir, l.builder.UID(), l.builder.GID(), l.fileFilter)), + WithBinds(append(volumes, fmt.Sprintf("%s:%s", cacheName, l.mountPaths.cacheDir()))...), + WithContainerOperations(CopyDir(l.appPath, l.mountPaths.appDir(), l.builder.UID(), l.builder.GID(), l.fileFilter)), } if publish { @@ -72,8 +64,8 @@ func (l *Lifecycle) Create( } else { opts = append(opts, WithDaemonAccess(), - WithFlags("-daemon", "-launch-cache", launchCacheDir), - WithBinds(fmt.Sprintf("%s:%s", launchCacheName, launchCacheDir)), + WithFlags("-daemon", "-launch-cache", l.mountPaths.launchCacheDir()), + WithBinds(fmt.Sprintf("%s:%s", launchCacheName, l.mountPaths.launchCacheDir())), ) } @@ -89,13 +81,13 @@ func (l *Lifecycle) Detect(ctx context.Context, networkMode string, volumes []st WithLogPrefix("detector"), WithArgs( l.withLogLevel( - "-app", appDir, - "-platform", platformDir, + "-app", l.mountPaths.appDir(), + "-platform", l.mountPaths.platformDir(), )..., ), WithNetwork(networkMode), WithBinds(volumes...), - WithContainerOperations(CopyDir(l.appPath, appDir, l.builder.UID(), l.builder.GID(), l.fileFilter)), + WithContainerOperations(CopyDir(l.appPath, l.mountPaths.appDir(), l.builder.UID(), l.builder.GID(), l.fileFilter)), ) detect := phaseFactory.New(configProvider) @@ -113,12 +105,12 @@ func (l *Lifecycle) Restore(ctx context.Context, cacheName, networkMode string, WithRoot(), // remove after platform API 0.2 is no longer supported WithArgs( l.withLogLevel( - "-cache-dir", cacheDir, - "-layers", layersDir, + "-cache-dir", l.mountPaths.cacheDir(), + "-layers", l.mountPaths.layersDir(), )..., ), WithNetwork(networkMode), - WithBinds(fmt.Sprintf("%s:%s", cacheName, cacheDir)), + WithBinds(fmt.Sprintf("%s:%s", cacheName, l.mountPaths.cacheDir())), ) restore := phaseFactory.New(configProvider) @@ -137,13 +129,13 @@ func (l *Lifecycle) Analyze(ctx context.Context, repoName, cacheName, networkMod func (l *Lifecycle) newAnalyze(repoName, cacheName, networkMode string, publish, clearCache bool, phaseFactory PhaseFactory) (RunnerCleaner, error) { args := []string{ - "-layers", layersDir, + "-layers", l.mountPaths.layersDir(), repoName, } if clearCache { args = prependArg("-skip-layers", args) } else { - args = append([]string{"-cache-dir", cacheDir}, args...) + args = append([]string{"-cache-dir", l.mountPaths.cacheDir()}, args...) } if publish { @@ -162,7 +154,7 @@ func (l *Lifecycle) newAnalyze(repoName, cacheName, networkMode string, publish, WithRoot(), WithArgs(l.withLogLevel(args...)...), WithNetwork(networkMode), - WithBinds(fmt.Sprintf("%s:%s", cacheName, cacheDir)), + WithBinds(fmt.Sprintf("%s:%s", cacheName, l.mountPaths.cacheDir())), ) return phaseFactory.New(configProvider), nil @@ -188,7 +180,7 @@ func (l *Lifecycle) newAnalyze(repoName, cacheName, networkMode string, publish, )..., ), WithNetwork(networkMode), - WithBinds(fmt.Sprintf("%s:%s", cacheName, cacheDir)), + WithBinds(fmt.Sprintf("%s:%s", cacheName, l.mountPaths.cacheDir())), ) return phaseFactory.New(configProvider), nil @@ -200,9 +192,9 @@ func prependArg(arg string, args []string) []string { func (l *Lifecycle) Build(ctx context.Context, networkMode string, volumes []string, phaseFactory PhaseFactory) error { args := []string{ - "-layers", layersDir, - "-app", appDir, - "-platform", platformDir, + "-layers", l.mountPaths.layersDir(), + "-app", l.mountPaths.appDir(), + "-platform", l.mountPaths.platformDir(), } platformAPIVersion := semver.MustParse(l.platformAPIVersion) @@ -236,10 +228,10 @@ func (l *Lifecycle) Export(ctx context.Context, repoName string, runImage string func (l *Lifecycle) newExport(repoName, runImage string, publish bool, launchCacheName, cacheName, networkMode string, phaseFactory PhaseFactory) (RunnerCleaner, error) { flags := l.exportImageFlags(runImage) flags = append(flags, []string{ - "-cache-dir", cacheDir, - "-layers", layersDir, - "-stack", stackPath, - "-app", appDir, + "-cache-dir", l.mountPaths.cacheDir(), + "-layers", l.mountPaths.layersDir(), + "-stack", l.mountPaths.stackPath(), + "-app", l.mountPaths.appDir(), }...) if l.defaultProcessType != "" { @@ -263,8 +255,8 @@ func (l *Lifecycle) newExport(repoName, runImage string, publish bool, launchCac WithArgs(repoName), WithRoot(), WithNetwork(networkMode), - WithBinds(fmt.Sprintf("%s:%s", cacheName, cacheDir)), - WithContainerOperations(WriteStackToml(stackPath, l.builder.Stack())), + WithBinds(fmt.Sprintf("%s:%s", cacheName, l.mountPaths.cacheDir())), + WithContainerOperations(WriteStackToml(l.mountPaths.stackPath(), l.builder.Stack())), } if publish { @@ -282,8 +274,8 @@ func (l *Lifecycle) newExport(repoName, runImage string, publish bool, launchCac opts = append( opts, WithDaemonAccess(), - WithFlags("-daemon", "-launch-cache", launchCacheDir), - WithBinds(fmt.Sprintf("%s:%s", launchCacheName, launchCacheDir)), + WithFlags("-daemon", "-launch-cache", l.mountPaths.launchCacheDir()), + WithBinds(fmt.Sprintf("%s:%s", launchCacheName, l.mountPaths.launchCacheDir())), ) } diff --git a/internal/cache/volume_cache.go b/internal/cache/volume_cache.go index 9cc1893cc7..9d73f0fd06 100644 --- a/internal/cache/volume_cache.go +++ b/internal/cache/volume_cache.go @@ -7,6 +7,8 @@ import ( "github.com/docker/docker/client" "github.com/google/go-containerregistry/pkg/name" + + "github.com/buildpacks/pack/internal/paths" ) type VolumeCache struct { @@ -16,8 +18,10 @@ type VolumeCache struct { func NewVolumeCache(imageRef name.Reference, suffix string, dockerClient client.CommonAPIClient) *VolumeCache { sum := sha256.Sum256([]byte(imageRef.Name())) + + vol := paths.FilterReservedNames(fmt.Sprintf("%x", sum[:6])) return &VolumeCache{ - volume: fmt.Sprintf("pack-cache-%x.%s", sum[:6], suffix), + volume: fmt.Sprintf("pack-cache-%s.%s", vol, suffix), docker: dockerClient, } } diff --git a/internal/cache/volume_cache_test.go b/internal/cache/volume_cache_test.go index 2238133e52..aca95d2198 100644 --- a/internal/cache/volume_cache_test.go +++ b/internal/cache/volume_cache_test.go @@ -50,6 +50,7 @@ func testCache(t *testing.T, when spec.G, it spec.S) { it("reusing the same cache for the same repo name", func() { ref, err := name.ParseReference("my/repo", name.WeakValidation) h.AssertNil(t, err) + subject := cache.NewVolumeCache(ref, "some-suffix", dockerClient) expected := cache.NewVolumeCache(ref, "some-suffix", dockerClient) if subject.Name() != expected.Name() { @@ -60,7 +61,9 @@ func testCache(t *testing.T, when spec.G, it spec.S) { it("supplies different volumes for different tags", func() { ref, err := name.ParseReference("my/repo:other-tag", name.WeakValidation) h.AssertNil(t, err) + subject := cache.NewVolumeCache(ref, "some-suffix", dockerClient) + ref, err = name.ParseReference("my/repo", name.WeakValidation) h.AssertNil(t, err) notExpected := cache.NewVolumeCache(ref, "some-suffix", dockerClient) @@ -72,7 +75,9 @@ func testCache(t *testing.T, when spec.G, it spec.S) { it("supplies different volumes for different registries", func() { ref, err := name.ParseReference("registry.com/my/repo:other-tag", name.WeakValidation) h.AssertNil(t, err) + subject := cache.NewVolumeCache(ref, "some-suffix", dockerClient) + ref, err = name.ParseReference("my/repo", name.WeakValidation) h.AssertNil(t, err) notExpected := cache.NewVolumeCache(ref, "some-suffix", dockerClient) @@ -84,23 +89,24 @@ func testCache(t *testing.T, when spec.G, it spec.S) { it("resolves implied tag", func() { ref, err := name.ParseReference("my/repo:latest", name.WeakValidation) h.AssertNil(t, err) + subject := cache.NewVolumeCache(ref, "some-suffix", dockerClient) ref, err = name.ParseReference("my/repo", name.WeakValidation) h.AssertNil(t, err) expected := cache.NewVolumeCache(ref, "some-suffix", dockerClient) - h.AssertEq(t, subject.Name(), expected.Name()) }) it("resolves implied registry", func() { ref, err := name.ParseReference("index.docker.io/my/repo", name.WeakValidation) h.AssertNil(t, err) + subject := cache.NewVolumeCache(ref, "some-suffix", dockerClient) + ref, err = name.ParseReference("my/repo", name.WeakValidation) h.AssertNil(t, err) expected := cache.NewVolumeCache(ref, "some-suffix", dockerClient) - h.AssertEq(t, subject.Name(), expected.Name()) }) }) @@ -121,8 +127,8 @@ func testCache(t *testing.T, when spec.G, it spec.S) { ref, err := name.ParseReference(h.RandString(10), name.WeakValidation) h.AssertNil(t, err) + subject = cache.NewVolumeCache(ref, "some-suffix", dockerClient) - h.AssertNil(t, err) volumeName = subject.Name() }) @@ -136,6 +142,7 @@ func testCache(t *testing.T, when spec.G, it spec.S) { it("removes the volume", func() { err := subject.Clear(ctx) h.AssertNil(t, err) + volumes, err := dockerClient.VolumeList(context.TODO(), filters.NewArgs(filters.KeyValuePair{ Key: "name", Value: volumeName, diff --git a/internal/paths/paths.go b/internal/paths/paths.go index b9be2634be..813e22b21c 100644 --- a/internal/paths/paths.go +++ b/internal/paths/paths.go @@ -86,3 +86,21 @@ func ToAbsolute(uri, relativeTo string) (string, error) { return uri, nil } + +func FilterReservedNames(path string) string { + // The following keys are reserved on Windows + // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#win32-file-namespaces + reservedNameConversions := map[string]string{ + "aux": "a_u_x", + "com": "c_o_m", + "con": "c_o_n", + "lpt": "l_p_t", + "nul": "n_u_l", + "prn": "p_r_n", + } + for k, v := range reservedNameConversions { + path = strings.Replace(path, k, v, -1) + } + + return path +} diff --git a/internal/paths/paths_test.go b/internal/paths/paths_test.go index 096c3c34cc..e9e240f599 100644 --- a/internal/paths/paths_test.go +++ b/internal/paths/paths_test.go @@ -18,6 +18,28 @@ func TestPaths(t *testing.T) { } func testPaths(t *testing.T, when spec.G, it spec.S) { + when("#FilterReservedNames", func() { + when("volume contains a reserved name", func() { + it("modifies the volume name", func() { + volumeName := "auxauxaux" + subject := FilterReservedNames(volumeName) + expected := "a_u_xa_u_xa_u_x" + if subject != expected { + t.Fatalf("The volume should not contain reserved names") + } + }) + }) + + when("volume does not contain reserved names", func() { + it("does not modify the volume name", func() { + volumeName := "lbtlbtlbt" + subject := FilterReservedNames(volumeName) + if subject != volumeName { + t.Fatalf("The volume should not be modified") + } + }) + }) + }) when("#FilePathToURI", func() { when("is windows", func() { it.Before(func() { diff --git a/testhelpers/registry.go b/testhelpers/registry.go index 9522e787da..1182b9d69c 100644 --- a/testhelpers/registry.go +++ b/testhelpers/registry.go @@ -6,35 +6,41 @@ import ( "fmt" "io" "io/ioutil" + "net" + "net/url" "os" "path/filepath" "testing" "time" - "gopkg.in/src-d/go-git.v4" - "gopkg.in/src-d/go-git.v4/plumbing/object" - dockertypes "github.com/docker/docker/api/types" dockercontainer "github.com/docker/docker/api/types/container" "github.com/docker/go-connections/nat" "golang.org/x/crypto/bcrypt" + "gopkg.in/src-d/go-git.v4" + "gopkg.in/src-d/go-git.v4/plumbing/object" "github.com/buildpacks/pack/internal/archive" ) var registryContainerNames = map[string]string{ "linux": "library/registry:2", - "windows": "stefanscherer/registry-windows:2.6.2", + "windows": "micahyoung/registry:latest", } type TestRegistryConfig struct { runRegistryName string + RunRegistryHost string RunRegistryPort string DockerConfigDir string username string password string } +func RegistryHost(host, port string) string { + return fmt.Sprintf("%s:%s", host, port) +} + func CreateRegistryFixture(t *testing.T, tmpDir, fixturePath string) string { // copy fixture to temp dir registryFixtureCopy := filepath.Join(tmpDir, "registryCopy") @@ -76,11 +82,12 @@ func RunRegistry(t *testing.T) *TestRegistryConfig { username := RandString(10) password := RandString(10) - runRegistryPort := startRegistry(t, runRegistryName, username, password) - dockerConfigDir := setupDockerConfigWithAuth(t, username, password, runRegistryPort) + runRegistryHost, runRegistryPort := startRegistry(t, runRegistryName, username, password) + dockerConfigDir := setupDockerConfigWithAuth(t, username, password, runRegistryHost, runRegistryPort) registryConfig := &TestRegistryConfig{ runRegistryName: runRegistryName, + RunRegistryHost: runRegistryHost, RunRegistryPort: runRegistryPort, DockerConfigDir: dockerConfigDir, username: username, @@ -114,7 +121,8 @@ func (rc *TestRegistryConfig) AuthConfig() dockertypes.AuthConfig { return dockertypes.AuthConfig{ Username: rc.username, Password: rc.password, - ServerAddress: fmt.Sprintf("localhost:%s", rc.RunRegistryPort)} + ServerAddress: RegistryHost(rc.RunRegistryHost, rc.RunRegistryPort), + } } func (rc *TestRegistryConfig) Login(t *testing.T, username string, password string) { @@ -122,12 +130,13 @@ func (rc *TestRegistryConfig) Login(t *testing.T, username string, password stri _, err := dockerCli(t).RegistryLogin(context.Background(), dockertypes.AuthConfig{ Username: username, Password: password, - ServerAddress: fmt.Sprintf("localhost:%s", rc.RunRegistryPort)}) + ServerAddress: RegistryHost(rc.RunRegistryHost, rc.RunRegistryPort), + }) return err == nil }, 100*time.Millisecond, 10*time.Second) } -func startRegistry(t *testing.T, runRegistryName, username, password string) string { +func startRegistry(t *testing.T, runRegistryName, username, password string) (string, string) { ctx := context.Background() daemonInfo, err := dockerCli(t).Info(ctx) @@ -163,12 +172,50 @@ func startRegistry(t *testing.T, runRegistryName, username, password string) str AssertNil(t, err) runRegistryPort := inspect.NetworkSettings.Ports["5000/tcp"][0].HostPort - if os.Getenv("DOCKER_HOST") != "" { - err := proxyDockerHostPort(runRegistryPort) - AssertNil(t, err) + runRegistryHost := DockerHostname(t) + + return runRegistryHost, runRegistryPort +} + +func DockerHostname(t *testing.T) string { + dockerCli := dockerCli(t) + + daemonHost := dockerCli.DaemonHost() + u, err := url.Parse(daemonHost) + if err != nil { + t.Fatalf("unable to parse URI client.DaemonHost: %s", err) } - return runRegistryPort + switch u.Scheme { + // DOCKER_HOST is usually remote so always use its hostname/IP + // Note: requires "insecure-registries" CIDR entry on Daemon config + case "tcp": + return u.Hostname() + + // if DOCKER_HOST is non-tcp, we assume that we are + // talking to the daemon over a local pipe. + default: + daemonInfo, err := dockerCli.Info(context.TODO()) + if err != nil { + t.Fatalf("unable to fetch client.DockerInfo: %s", err) + } + + if daemonInfo.OSType == "windows" { + // try to lookup the host IP by helper domain name (https://docs.docker.com/docker-for-windows/networking/#use-cases-and-workarounds) + // Note: pack appears to not support /etc/hosts-based insecure-registries + addrs, err := net.LookupHost("host.docker.internal") + if err != nil { + t.Fatalf("unknown address response: %+v %s", addrs, err) + } + if len(addrs) != 1 { + t.Fatalf("ambiguous address response: %v", addrs) + } + return addrs[0] + } + + // Linux can use --network=host so always use "localhost" + return "localhost" + } } func generateHtpasswd(t *testing.T, username string, password string) io.ReadCloser { @@ -179,18 +226,18 @@ func generateHtpasswd(t *testing.T, username string, password string) io.ReadClo return reader } -func setupDockerConfigWithAuth(t *testing.T, username string, password string, runRegistryPort string) string { +func setupDockerConfigWithAuth(t *testing.T, username string, password string, runRegistryHost string, runRegistryPort string) string { dockerConfigDir, err := ioutil.TempDir("", "pack.test.docker.config.dir") AssertNil(t, err) AssertNil(t, ioutil.WriteFile(filepath.Join(dockerConfigDir, "config.json"), []byte(fmt.Sprintf(`{ "auths": { - "localhost:%s": { + "%s": { "auth": "%s" } } } - `, runRegistryPort, encodedUserPass(username, password))), 0666)) + `, RegistryHost(runRegistryHost, runRegistryPort), encodedUserPass(username, password))), 0666)) return dockerConfigDir } @@ -209,7 +256,7 @@ func (rc *TestRegistryConfig) StopRegistry(t *testing.T) { } func (rc *TestRegistryConfig) RepoName(name string) string { - return "localhost:" + rc.RunRegistryPort + "/" + name + return RegistryHost(rc.RunRegistryHost, rc.RunRegistryPort) + "/" + name } func (rc *TestRegistryConfig) RegistryAuth() string { @@ -217,7 +264,7 @@ func (rc *TestRegistryConfig) RegistryAuth() string { } func (rc *TestRegistryConfig) RegistryCatalog() (string, error) { - return HTTPGetE(fmt.Sprintf("http://localhost:%s/v2/_catalog", rc.RunRegistryPort), map[string]string{ + return HTTPGetE(fmt.Sprintf("http://%s/v2/_catalog", RegistryHost(rc.RunRegistryHost, rc.RunRegistryPort)), map[string]string{ "Authorization": "Basic " + encodedUserPass(rc.username, rc.password), }) } diff --git a/testhelpers/testhelpers.go b/testhelpers/testhelpers.go index bea7566345..67c35ddde5 100644 --- a/testhelpers/testhelpers.go +++ b/testhelpers/testhelpers.go @@ -9,9 +9,7 @@ import ( "fmt" "io" "io/ioutil" - "log" "math/rand" - "net" "net/http" "os" "os/exec" @@ -24,7 +22,6 @@ import ( "testing" "time" - "github.com/dgodd/dockerdial" dockertypes "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" @@ -310,36 +307,6 @@ func dockerCli(t *testing.T) client.CommonAPIClient { return dockerCliVal } -func proxyDockerHostPort(port string) error { - ln, err := net.Listen("tcp", ":"+port) - if err != nil { - return err - } - - go func() { - for { - conn, err := ln.Accept() - if err != nil { - log.Println(err) - continue - } - go func(conn net.Conn) { - defer conn.Close() - c, err := dockerdial.Dial("tcp", "localhost:"+port) - if err != nil { - log.Println(err) - return - } - defer c.Close() - - go io.Copy(c, conn) - io.Copy(conn, c) - }(conn) - } - }() - return nil -} - func Eventually(t *testing.T, test func() bool, every time.Duration, timeout time.Duration) { t.Helper() @@ -466,13 +433,7 @@ func PushImage(dockerCli client.CommonAPIClient, ref string, registryConfig *Tes } func HTTPGetE(url string, headers map[string]string) (string, error) { - var client *http.Client - if os.Getenv("DOCKER_HOST") == "" { - client = http.DefaultClient - } else { - tr := &http.Transport{Dial: dockerdial.Dial} - client = &http.Client{Transport: tr} - } + client := http.DefaultClient request, err := http.NewRequest("GET", url, nil) if err != nil { @@ -622,6 +583,16 @@ func RunContainer(ctx context.Context, dockerCli client.CommonAPIClient, id stri if err := dockerCli.ContainerStart(ctx, id, dockertypes.ContainerStartOptions{}); err != nil { return errors.Wrap(err, "container start") } + + info, err := dockerCli.Info(ctx) + if err != nil { + return errors.Wrap(err, "getting docker info") + } + if info.OSType == "windows" { + // wait for logs to show + time.Sleep(time.Second) + } + logs, err := dockerCli.ContainerLogs(ctx, id, dockertypes.ContainerLogsOptions{ ShowStdout: true, ShowStderr: true, diff --git a/testmocks/mock_docker_client.go b/testmocks/mock_docker_client.go new file mode 100644 index 0000000000..021365bf7f --- /dev/null +++ b/testmocks/mock_docker_client.go @@ -0,0 +1,1754 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/docker/docker/client (interfaces: CommonAPIClient) + +// Package testmocks is a generated GoMock package. +package testmocks + +import ( + context "context" + io "io" + net "net" + http "net/http" + reflect "reflect" + time "time" + + types "github.com/docker/docker/api/types" + container "github.com/docker/docker/api/types/container" + events "github.com/docker/docker/api/types/events" + filters "github.com/docker/docker/api/types/filters" + image "github.com/docker/docker/api/types/image" + network "github.com/docker/docker/api/types/network" + registry "github.com/docker/docker/api/types/registry" + swarm "github.com/docker/docker/api/types/swarm" + volume "github.com/docker/docker/api/types/volume" + gomock "github.com/golang/mock/gomock" +) + +// MockCommonAPIClient is a mock of CommonAPIClient interface +type MockCommonAPIClient struct { + ctrl *gomock.Controller + recorder *MockCommonAPIClientMockRecorder +} + +// MockCommonAPIClientMockRecorder is the mock recorder for MockCommonAPIClient +type MockCommonAPIClientMockRecorder struct { + mock *MockCommonAPIClient +} + +// NewMockCommonAPIClient creates a new mock instance +func NewMockCommonAPIClient(ctrl *gomock.Controller) *MockCommonAPIClient { + mock := &MockCommonAPIClient{ctrl: ctrl} + mock.recorder = &MockCommonAPIClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockCommonAPIClient) EXPECT() *MockCommonAPIClientMockRecorder { + return m.recorder +} + +// BuildCachePrune mocks base method +func (m *MockCommonAPIClient) BuildCachePrune(arg0 context.Context, arg1 types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BuildCachePrune", arg0, arg1) + ret0, _ := ret[0].(*types.BuildCachePruneReport) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BuildCachePrune indicates an expected call of BuildCachePrune +func (mr *MockCommonAPIClientMockRecorder) BuildCachePrune(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildCachePrune", reflect.TypeOf((*MockCommonAPIClient)(nil).BuildCachePrune), arg0, arg1) +} + +// BuildCancel mocks base method +func (m *MockCommonAPIClient) BuildCancel(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BuildCancel", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// BuildCancel indicates an expected call of BuildCancel +func (mr *MockCommonAPIClientMockRecorder) BuildCancel(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildCancel", reflect.TypeOf((*MockCommonAPIClient)(nil).BuildCancel), arg0, arg1) +} + +// ClientVersion mocks base method +func (m *MockCommonAPIClient) ClientVersion() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientVersion") + ret0, _ := ret[0].(string) + return ret0 +} + +// ClientVersion indicates an expected call of ClientVersion +func (mr *MockCommonAPIClientMockRecorder) ClientVersion() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientVersion", reflect.TypeOf((*MockCommonAPIClient)(nil).ClientVersion)) +} + +// Close mocks base method +func (m *MockCommonAPIClient) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close +func (mr *MockCommonAPIClientMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockCommonAPIClient)(nil).Close)) +} + +// ConfigCreate mocks base method +func (m *MockCommonAPIClient) ConfigCreate(arg0 context.Context, arg1 swarm.ConfigSpec) (types.ConfigCreateResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ConfigCreate", arg0, arg1) + ret0, _ := ret[0].(types.ConfigCreateResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ConfigCreate indicates an expected call of ConfigCreate +func (mr *MockCommonAPIClientMockRecorder) ConfigCreate(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConfigCreate", reflect.TypeOf((*MockCommonAPIClient)(nil).ConfigCreate), arg0, arg1) +} + +// ConfigInspectWithRaw mocks base method +func (m *MockCommonAPIClient) ConfigInspectWithRaw(arg0 context.Context, arg1 string) (swarm.Config, []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ConfigInspectWithRaw", arg0, arg1) + ret0, _ := ret[0].(swarm.Config) + ret1, _ := ret[1].([]byte) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// ConfigInspectWithRaw indicates an expected call of ConfigInspectWithRaw +func (mr *MockCommonAPIClientMockRecorder) ConfigInspectWithRaw(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConfigInspectWithRaw", reflect.TypeOf((*MockCommonAPIClient)(nil).ConfigInspectWithRaw), arg0, arg1) +} + +// ConfigList mocks base method +func (m *MockCommonAPIClient) ConfigList(arg0 context.Context, arg1 types.ConfigListOptions) ([]swarm.Config, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ConfigList", arg0, arg1) + ret0, _ := ret[0].([]swarm.Config) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ConfigList indicates an expected call of ConfigList +func (mr *MockCommonAPIClientMockRecorder) ConfigList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConfigList", reflect.TypeOf((*MockCommonAPIClient)(nil).ConfigList), arg0, arg1) +} + +// ConfigRemove mocks base method +func (m *MockCommonAPIClient) ConfigRemove(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ConfigRemove", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ConfigRemove indicates an expected call of ConfigRemove +func (mr *MockCommonAPIClientMockRecorder) ConfigRemove(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConfigRemove", reflect.TypeOf((*MockCommonAPIClient)(nil).ConfigRemove), arg0, arg1) +} + +// ConfigUpdate mocks base method +func (m *MockCommonAPIClient) ConfigUpdate(arg0 context.Context, arg1 string, arg2 swarm.Version, arg3 swarm.ConfigSpec) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ConfigUpdate", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// ConfigUpdate indicates an expected call of ConfigUpdate +func (mr *MockCommonAPIClientMockRecorder) ConfigUpdate(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConfigUpdate", reflect.TypeOf((*MockCommonAPIClient)(nil).ConfigUpdate), arg0, arg1, arg2, arg3) +} + +// ContainerAttach mocks base method +func (m *MockCommonAPIClient) ContainerAttach(arg0 context.Context, arg1 string, arg2 types.ContainerAttachOptions) (types.HijackedResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerAttach", arg0, arg1, arg2) + ret0, _ := ret[0].(types.HijackedResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerAttach indicates an expected call of ContainerAttach +func (mr *MockCommonAPIClientMockRecorder) ContainerAttach(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerAttach", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerAttach), arg0, arg1, arg2) +} + +// ContainerCommit mocks base method +func (m *MockCommonAPIClient) ContainerCommit(arg0 context.Context, arg1 string, arg2 types.ContainerCommitOptions) (types.IDResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerCommit", arg0, arg1, arg2) + ret0, _ := ret[0].(types.IDResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerCommit indicates an expected call of ContainerCommit +func (mr *MockCommonAPIClientMockRecorder) ContainerCommit(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerCommit", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerCommit), arg0, arg1, arg2) +} + +// ContainerCreate mocks base method +func (m *MockCommonAPIClient) ContainerCreate(arg0 context.Context, arg1 *container.Config, arg2 *container.HostConfig, arg3 *network.NetworkingConfig, arg4 string) (container.ContainerCreateCreatedBody, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerCreate", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(container.ContainerCreateCreatedBody) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerCreate indicates an expected call of ContainerCreate +func (mr *MockCommonAPIClientMockRecorder) ContainerCreate(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerCreate", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerCreate), arg0, arg1, arg2, arg3, arg4) +} + +// ContainerDiff mocks base method +func (m *MockCommonAPIClient) ContainerDiff(arg0 context.Context, arg1 string) ([]container.ContainerChangeResponseItem, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerDiff", arg0, arg1) + ret0, _ := ret[0].([]container.ContainerChangeResponseItem) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerDiff indicates an expected call of ContainerDiff +func (mr *MockCommonAPIClientMockRecorder) ContainerDiff(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerDiff", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerDiff), arg0, arg1) +} + +// ContainerExecAttach mocks base method +func (m *MockCommonAPIClient) ContainerExecAttach(arg0 context.Context, arg1 string, arg2 types.ExecStartCheck) (types.HijackedResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerExecAttach", arg0, arg1, arg2) + ret0, _ := ret[0].(types.HijackedResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerExecAttach indicates an expected call of ContainerExecAttach +func (mr *MockCommonAPIClientMockRecorder) ContainerExecAttach(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerExecAttach", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerExecAttach), arg0, arg1, arg2) +} + +// ContainerExecCreate mocks base method +func (m *MockCommonAPIClient) ContainerExecCreate(arg0 context.Context, arg1 string, arg2 types.ExecConfig) (types.IDResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerExecCreate", arg0, arg1, arg2) + ret0, _ := ret[0].(types.IDResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerExecCreate indicates an expected call of ContainerExecCreate +func (mr *MockCommonAPIClientMockRecorder) ContainerExecCreate(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerExecCreate", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerExecCreate), arg0, arg1, arg2) +} + +// ContainerExecInspect mocks base method +func (m *MockCommonAPIClient) ContainerExecInspect(arg0 context.Context, arg1 string) (types.ContainerExecInspect, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerExecInspect", arg0, arg1) + ret0, _ := ret[0].(types.ContainerExecInspect) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerExecInspect indicates an expected call of ContainerExecInspect +func (mr *MockCommonAPIClientMockRecorder) ContainerExecInspect(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerExecInspect", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerExecInspect), arg0, arg1) +} + +// ContainerExecResize mocks base method +func (m *MockCommonAPIClient) ContainerExecResize(arg0 context.Context, arg1 string, arg2 types.ResizeOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerExecResize", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ContainerExecResize indicates an expected call of ContainerExecResize +func (mr *MockCommonAPIClientMockRecorder) ContainerExecResize(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerExecResize", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerExecResize), arg0, arg1, arg2) +} + +// ContainerExecStart mocks base method +func (m *MockCommonAPIClient) ContainerExecStart(arg0 context.Context, arg1 string, arg2 types.ExecStartCheck) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerExecStart", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ContainerExecStart indicates an expected call of ContainerExecStart +func (mr *MockCommonAPIClientMockRecorder) ContainerExecStart(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerExecStart", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerExecStart), arg0, arg1, arg2) +} + +// ContainerExport mocks base method +func (m *MockCommonAPIClient) ContainerExport(arg0 context.Context, arg1 string) (io.ReadCloser, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerExport", arg0, arg1) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerExport indicates an expected call of ContainerExport +func (mr *MockCommonAPIClientMockRecorder) ContainerExport(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerExport", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerExport), arg0, arg1) +} + +// ContainerInspect mocks base method +func (m *MockCommonAPIClient) ContainerInspect(arg0 context.Context, arg1 string) (types.ContainerJSON, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerInspect", arg0, arg1) + ret0, _ := ret[0].(types.ContainerJSON) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerInspect indicates an expected call of ContainerInspect +func (mr *MockCommonAPIClientMockRecorder) ContainerInspect(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerInspect", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerInspect), arg0, arg1) +} + +// ContainerInspectWithRaw mocks base method +func (m *MockCommonAPIClient) ContainerInspectWithRaw(arg0 context.Context, arg1 string, arg2 bool) (types.ContainerJSON, []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerInspectWithRaw", arg0, arg1, arg2) + ret0, _ := ret[0].(types.ContainerJSON) + ret1, _ := ret[1].([]byte) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// ContainerInspectWithRaw indicates an expected call of ContainerInspectWithRaw +func (mr *MockCommonAPIClientMockRecorder) ContainerInspectWithRaw(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerInspectWithRaw", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerInspectWithRaw), arg0, arg1, arg2) +} + +// ContainerKill mocks base method +func (m *MockCommonAPIClient) ContainerKill(arg0 context.Context, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerKill", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ContainerKill indicates an expected call of ContainerKill +func (mr *MockCommonAPIClientMockRecorder) ContainerKill(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerKill", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerKill), arg0, arg1, arg2) +} + +// ContainerList mocks base method +func (m *MockCommonAPIClient) ContainerList(arg0 context.Context, arg1 types.ContainerListOptions) ([]types.Container, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerList", arg0, arg1) + ret0, _ := ret[0].([]types.Container) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerList indicates an expected call of ContainerList +func (mr *MockCommonAPIClientMockRecorder) ContainerList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerList", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerList), arg0, arg1) +} + +// ContainerLogs mocks base method +func (m *MockCommonAPIClient) ContainerLogs(arg0 context.Context, arg1 string, arg2 types.ContainerLogsOptions) (io.ReadCloser, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerLogs", arg0, arg1, arg2) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerLogs indicates an expected call of ContainerLogs +func (mr *MockCommonAPIClientMockRecorder) ContainerLogs(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerLogs", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerLogs), arg0, arg1, arg2) +} + +// ContainerPause mocks base method +func (m *MockCommonAPIClient) ContainerPause(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerPause", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ContainerPause indicates an expected call of ContainerPause +func (mr *MockCommonAPIClientMockRecorder) ContainerPause(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerPause", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerPause), arg0, arg1) +} + +// ContainerRemove mocks base method +func (m *MockCommonAPIClient) ContainerRemove(arg0 context.Context, arg1 string, arg2 types.ContainerRemoveOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerRemove", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ContainerRemove indicates an expected call of ContainerRemove +func (mr *MockCommonAPIClientMockRecorder) ContainerRemove(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerRemove", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerRemove), arg0, arg1, arg2) +} + +// ContainerRename mocks base method +func (m *MockCommonAPIClient) ContainerRename(arg0 context.Context, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerRename", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ContainerRename indicates an expected call of ContainerRename +func (mr *MockCommonAPIClientMockRecorder) ContainerRename(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerRename", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerRename), arg0, arg1, arg2) +} + +// ContainerResize mocks base method +func (m *MockCommonAPIClient) ContainerResize(arg0 context.Context, arg1 string, arg2 types.ResizeOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerResize", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ContainerResize indicates an expected call of ContainerResize +func (mr *MockCommonAPIClientMockRecorder) ContainerResize(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerResize", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerResize), arg0, arg1, arg2) +} + +// ContainerRestart mocks base method +func (m *MockCommonAPIClient) ContainerRestart(arg0 context.Context, arg1 string, arg2 *time.Duration) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerRestart", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ContainerRestart indicates an expected call of ContainerRestart +func (mr *MockCommonAPIClientMockRecorder) ContainerRestart(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerRestart", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerRestart), arg0, arg1, arg2) +} + +// ContainerStart mocks base method +func (m *MockCommonAPIClient) ContainerStart(arg0 context.Context, arg1 string, arg2 types.ContainerStartOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerStart", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ContainerStart indicates an expected call of ContainerStart +func (mr *MockCommonAPIClientMockRecorder) ContainerStart(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerStart", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerStart), arg0, arg1, arg2) +} + +// ContainerStatPath mocks base method +func (m *MockCommonAPIClient) ContainerStatPath(arg0 context.Context, arg1, arg2 string) (types.ContainerPathStat, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerStatPath", arg0, arg1, arg2) + ret0, _ := ret[0].(types.ContainerPathStat) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerStatPath indicates an expected call of ContainerStatPath +func (mr *MockCommonAPIClientMockRecorder) ContainerStatPath(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerStatPath", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerStatPath), arg0, arg1, arg2) +} + +// ContainerStats mocks base method +func (m *MockCommonAPIClient) ContainerStats(arg0 context.Context, arg1 string, arg2 bool) (types.ContainerStats, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerStats", arg0, arg1, arg2) + ret0, _ := ret[0].(types.ContainerStats) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerStats indicates an expected call of ContainerStats +func (mr *MockCommonAPIClientMockRecorder) ContainerStats(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerStats", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerStats), arg0, arg1, arg2) +} + +// ContainerStop mocks base method +func (m *MockCommonAPIClient) ContainerStop(arg0 context.Context, arg1 string, arg2 *time.Duration) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerStop", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ContainerStop indicates an expected call of ContainerStop +func (mr *MockCommonAPIClientMockRecorder) ContainerStop(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerStop", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerStop), arg0, arg1, arg2) +} + +// ContainerTop mocks base method +func (m *MockCommonAPIClient) ContainerTop(arg0 context.Context, arg1 string, arg2 []string) (container.ContainerTopOKBody, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerTop", arg0, arg1, arg2) + ret0, _ := ret[0].(container.ContainerTopOKBody) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerTop indicates an expected call of ContainerTop +func (mr *MockCommonAPIClientMockRecorder) ContainerTop(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerTop", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerTop), arg0, arg1, arg2) +} + +// ContainerUnpause mocks base method +func (m *MockCommonAPIClient) ContainerUnpause(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerUnpause", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ContainerUnpause indicates an expected call of ContainerUnpause +func (mr *MockCommonAPIClientMockRecorder) ContainerUnpause(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerUnpause", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerUnpause), arg0, arg1) +} + +// ContainerUpdate mocks base method +func (m *MockCommonAPIClient) ContainerUpdate(arg0 context.Context, arg1 string, arg2 container.UpdateConfig) (container.ContainerUpdateOKBody, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerUpdate", arg0, arg1, arg2) + ret0, _ := ret[0].(container.ContainerUpdateOKBody) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainerUpdate indicates an expected call of ContainerUpdate +func (mr *MockCommonAPIClientMockRecorder) ContainerUpdate(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerUpdate", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerUpdate), arg0, arg1, arg2) +} + +// ContainerWait mocks base method +func (m *MockCommonAPIClient) ContainerWait(arg0 context.Context, arg1 string, arg2 container.WaitCondition) (<-chan container.ContainerWaitOKBody, <-chan error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainerWait", arg0, arg1, arg2) + ret0, _ := ret[0].(<-chan container.ContainerWaitOKBody) + ret1, _ := ret[1].(<-chan error) + return ret0, ret1 +} + +// ContainerWait indicates an expected call of ContainerWait +func (mr *MockCommonAPIClientMockRecorder) ContainerWait(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainerWait", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainerWait), arg0, arg1, arg2) +} + +// ContainersPrune mocks base method +func (m *MockCommonAPIClient) ContainersPrune(arg0 context.Context, arg1 filters.Args) (types.ContainersPruneReport, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ContainersPrune", arg0, arg1) + ret0, _ := ret[0].(types.ContainersPruneReport) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ContainersPrune indicates an expected call of ContainersPrune +func (mr *MockCommonAPIClientMockRecorder) ContainersPrune(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContainersPrune", reflect.TypeOf((*MockCommonAPIClient)(nil).ContainersPrune), arg0, arg1) +} + +// CopyFromContainer mocks base method +func (m *MockCommonAPIClient) CopyFromContainer(arg0 context.Context, arg1, arg2 string) (io.ReadCloser, types.ContainerPathStat, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CopyFromContainer", arg0, arg1, arg2) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(types.ContainerPathStat) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// CopyFromContainer indicates an expected call of CopyFromContainer +func (mr *MockCommonAPIClientMockRecorder) CopyFromContainer(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CopyFromContainer", reflect.TypeOf((*MockCommonAPIClient)(nil).CopyFromContainer), arg0, arg1, arg2) +} + +// CopyToContainer mocks base method +func (m *MockCommonAPIClient) CopyToContainer(arg0 context.Context, arg1, arg2 string, arg3 io.Reader, arg4 types.CopyToContainerOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CopyToContainer", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(error) + return ret0 +} + +// CopyToContainer indicates an expected call of CopyToContainer +func (mr *MockCommonAPIClientMockRecorder) CopyToContainer(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CopyToContainer", reflect.TypeOf((*MockCommonAPIClient)(nil).CopyToContainer), arg0, arg1, arg2, arg3, arg4) +} + +// DaemonHost mocks base method +func (m *MockCommonAPIClient) DaemonHost() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DaemonHost") + ret0, _ := ret[0].(string) + return ret0 +} + +// DaemonHost indicates an expected call of DaemonHost +func (mr *MockCommonAPIClientMockRecorder) DaemonHost() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DaemonHost", reflect.TypeOf((*MockCommonAPIClient)(nil).DaemonHost)) +} + +// DialHijack mocks base method +func (m *MockCommonAPIClient) DialHijack(arg0 context.Context, arg1, arg2 string, arg3 map[string][]string) (net.Conn, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DialHijack", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(net.Conn) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DialHijack indicates an expected call of DialHijack +func (mr *MockCommonAPIClientMockRecorder) DialHijack(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DialHijack", reflect.TypeOf((*MockCommonAPIClient)(nil).DialHijack), arg0, arg1, arg2, arg3) +} + +// Dialer mocks base method +func (m *MockCommonAPIClient) Dialer() func(context.Context) (net.Conn, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Dialer") + ret0, _ := ret[0].(func(context.Context) (net.Conn, error)) + return ret0 +} + +// Dialer indicates an expected call of Dialer +func (mr *MockCommonAPIClientMockRecorder) Dialer() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Dialer", reflect.TypeOf((*MockCommonAPIClient)(nil).Dialer)) +} + +// DiskUsage mocks base method +func (m *MockCommonAPIClient) DiskUsage(arg0 context.Context) (types.DiskUsage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DiskUsage", arg0) + ret0, _ := ret[0].(types.DiskUsage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DiskUsage indicates an expected call of DiskUsage +func (mr *MockCommonAPIClientMockRecorder) DiskUsage(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DiskUsage", reflect.TypeOf((*MockCommonAPIClient)(nil).DiskUsage), arg0) +} + +// DistributionInspect mocks base method +func (m *MockCommonAPIClient) DistributionInspect(arg0 context.Context, arg1, arg2 string) (registry.DistributionInspect, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DistributionInspect", arg0, arg1, arg2) + ret0, _ := ret[0].(registry.DistributionInspect) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DistributionInspect indicates an expected call of DistributionInspect +func (mr *MockCommonAPIClientMockRecorder) DistributionInspect(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DistributionInspect", reflect.TypeOf((*MockCommonAPIClient)(nil).DistributionInspect), arg0, arg1, arg2) +} + +// Events mocks base method +func (m *MockCommonAPIClient) Events(arg0 context.Context, arg1 types.EventsOptions) (<-chan events.Message, <-chan error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Events", arg0, arg1) + ret0, _ := ret[0].(<-chan events.Message) + ret1, _ := ret[1].(<-chan error) + return ret0, ret1 +} + +// Events indicates an expected call of Events +func (mr *MockCommonAPIClientMockRecorder) Events(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Events", reflect.TypeOf((*MockCommonAPIClient)(nil).Events), arg0, arg1) +} + +// HTTPClient mocks base method +func (m *MockCommonAPIClient) HTTPClient() *http.Client { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HTTPClient") + ret0, _ := ret[0].(*http.Client) + return ret0 +} + +// HTTPClient indicates an expected call of HTTPClient +func (mr *MockCommonAPIClientMockRecorder) HTTPClient() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HTTPClient", reflect.TypeOf((*MockCommonAPIClient)(nil).HTTPClient)) +} + +// ImageBuild mocks base method +func (m *MockCommonAPIClient) ImageBuild(arg0 context.Context, arg1 io.Reader, arg2 types.ImageBuildOptions) (types.ImageBuildResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImageBuild", arg0, arg1, arg2) + ret0, _ := ret[0].(types.ImageBuildResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImageBuild indicates an expected call of ImageBuild +func (mr *MockCommonAPIClientMockRecorder) ImageBuild(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageBuild", reflect.TypeOf((*MockCommonAPIClient)(nil).ImageBuild), arg0, arg1, arg2) +} + +// ImageCreate mocks base method +func (m *MockCommonAPIClient) ImageCreate(arg0 context.Context, arg1 string, arg2 types.ImageCreateOptions) (io.ReadCloser, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImageCreate", arg0, arg1, arg2) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImageCreate indicates an expected call of ImageCreate +func (mr *MockCommonAPIClientMockRecorder) ImageCreate(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageCreate", reflect.TypeOf((*MockCommonAPIClient)(nil).ImageCreate), arg0, arg1, arg2) +} + +// ImageHistory mocks base method +func (m *MockCommonAPIClient) ImageHistory(arg0 context.Context, arg1 string) ([]image.HistoryResponseItem, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImageHistory", arg0, arg1) + ret0, _ := ret[0].([]image.HistoryResponseItem) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImageHistory indicates an expected call of ImageHistory +func (mr *MockCommonAPIClientMockRecorder) ImageHistory(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageHistory", reflect.TypeOf((*MockCommonAPIClient)(nil).ImageHistory), arg0, arg1) +} + +// ImageImport mocks base method +func (m *MockCommonAPIClient) ImageImport(arg0 context.Context, arg1 types.ImageImportSource, arg2 string, arg3 types.ImageImportOptions) (io.ReadCloser, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImageImport", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImageImport indicates an expected call of ImageImport +func (mr *MockCommonAPIClientMockRecorder) ImageImport(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageImport", reflect.TypeOf((*MockCommonAPIClient)(nil).ImageImport), arg0, arg1, arg2, arg3) +} + +// ImageInspectWithRaw mocks base method +func (m *MockCommonAPIClient) ImageInspectWithRaw(arg0 context.Context, arg1 string) (types.ImageInspect, []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImageInspectWithRaw", arg0, arg1) + ret0, _ := ret[0].(types.ImageInspect) + ret1, _ := ret[1].([]byte) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// ImageInspectWithRaw indicates an expected call of ImageInspectWithRaw +func (mr *MockCommonAPIClientMockRecorder) ImageInspectWithRaw(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageInspectWithRaw", reflect.TypeOf((*MockCommonAPIClient)(nil).ImageInspectWithRaw), arg0, arg1) +} + +// ImageList mocks base method +func (m *MockCommonAPIClient) ImageList(arg0 context.Context, arg1 types.ImageListOptions) ([]types.ImageSummary, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImageList", arg0, arg1) + ret0, _ := ret[0].([]types.ImageSummary) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImageList indicates an expected call of ImageList +func (mr *MockCommonAPIClientMockRecorder) ImageList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageList", reflect.TypeOf((*MockCommonAPIClient)(nil).ImageList), arg0, arg1) +} + +// ImageLoad mocks base method +func (m *MockCommonAPIClient) ImageLoad(arg0 context.Context, arg1 io.Reader, arg2 bool) (types.ImageLoadResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImageLoad", arg0, arg1, arg2) + ret0, _ := ret[0].(types.ImageLoadResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImageLoad indicates an expected call of ImageLoad +func (mr *MockCommonAPIClientMockRecorder) ImageLoad(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageLoad", reflect.TypeOf((*MockCommonAPIClient)(nil).ImageLoad), arg0, arg1, arg2) +} + +// ImagePull mocks base method +func (m *MockCommonAPIClient) ImagePull(arg0 context.Context, arg1 string, arg2 types.ImagePullOptions) (io.ReadCloser, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImagePull", arg0, arg1, arg2) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImagePull indicates an expected call of ImagePull +func (mr *MockCommonAPIClientMockRecorder) ImagePull(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImagePull", reflect.TypeOf((*MockCommonAPIClient)(nil).ImagePull), arg0, arg1, arg2) +} + +// ImagePush mocks base method +func (m *MockCommonAPIClient) ImagePush(arg0 context.Context, arg1 string, arg2 types.ImagePushOptions) (io.ReadCloser, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImagePush", arg0, arg1, arg2) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImagePush indicates an expected call of ImagePush +func (mr *MockCommonAPIClientMockRecorder) ImagePush(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImagePush", reflect.TypeOf((*MockCommonAPIClient)(nil).ImagePush), arg0, arg1, arg2) +} + +// ImageRemove mocks base method +func (m *MockCommonAPIClient) ImageRemove(arg0 context.Context, arg1 string, arg2 types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImageRemove", arg0, arg1, arg2) + ret0, _ := ret[0].([]types.ImageDeleteResponseItem) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImageRemove indicates an expected call of ImageRemove +func (mr *MockCommonAPIClientMockRecorder) ImageRemove(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageRemove", reflect.TypeOf((*MockCommonAPIClient)(nil).ImageRemove), arg0, arg1, arg2) +} + +// ImageSave mocks base method +func (m *MockCommonAPIClient) ImageSave(arg0 context.Context, arg1 []string) (io.ReadCloser, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImageSave", arg0, arg1) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImageSave indicates an expected call of ImageSave +func (mr *MockCommonAPIClientMockRecorder) ImageSave(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageSave", reflect.TypeOf((*MockCommonAPIClient)(nil).ImageSave), arg0, arg1) +} + +// ImageSearch mocks base method +func (m *MockCommonAPIClient) ImageSearch(arg0 context.Context, arg1 string, arg2 types.ImageSearchOptions) ([]registry.SearchResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImageSearch", arg0, arg1, arg2) + ret0, _ := ret[0].([]registry.SearchResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImageSearch indicates an expected call of ImageSearch +func (mr *MockCommonAPIClientMockRecorder) ImageSearch(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageSearch", reflect.TypeOf((*MockCommonAPIClient)(nil).ImageSearch), arg0, arg1, arg2) +} + +// ImageTag mocks base method +func (m *MockCommonAPIClient) ImageTag(arg0 context.Context, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImageTag", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ImageTag indicates an expected call of ImageTag +func (mr *MockCommonAPIClientMockRecorder) ImageTag(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageTag", reflect.TypeOf((*MockCommonAPIClient)(nil).ImageTag), arg0, arg1, arg2) +} + +// ImagesPrune mocks base method +func (m *MockCommonAPIClient) ImagesPrune(arg0 context.Context, arg1 filters.Args) (types.ImagesPruneReport, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ImagesPrune", arg0, arg1) + ret0, _ := ret[0].(types.ImagesPruneReport) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImagesPrune indicates an expected call of ImagesPrune +func (mr *MockCommonAPIClientMockRecorder) ImagesPrune(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImagesPrune", reflect.TypeOf((*MockCommonAPIClient)(nil).ImagesPrune), arg0, arg1) +} + +// Info mocks base method +func (m *MockCommonAPIClient) Info(arg0 context.Context) (types.Info, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Info", arg0) + ret0, _ := ret[0].(types.Info) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Info indicates an expected call of Info +func (mr *MockCommonAPIClientMockRecorder) Info(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Info", reflect.TypeOf((*MockCommonAPIClient)(nil).Info), arg0) +} + +// NegotiateAPIVersion mocks base method +func (m *MockCommonAPIClient) NegotiateAPIVersion(arg0 context.Context) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "NegotiateAPIVersion", arg0) +} + +// NegotiateAPIVersion indicates an expected call of NegotiateAPIVersion +func (mr *MockCommonAPIClientMockRecorder) NegotiateAPIVersion(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NegotiateAPIVersion", reflect.TypeOf((*MockCommonAPIClient)(nil).NegotiateAPIVersion), arg0) +} + +// NegotiateAPIVersionPing mocks base method +func (m *MockCommonAPIClient) NegotiateAPIVersionPing(arg0 types.Ping) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "NegotiateAPIVersionPing", arg0) +} + +// NegotiateAPIVersionPing indicates an expected call of NegotiateAPIVersionPing +func (mr *MockCommonAPIClientMockRecorder) NegotiateAPIVersionPing(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NegotiateAPIVersionPing", reflect.TypeOf((*MockCommonAPIClient)(nil).NegotiateAPIVersionPing), arg0) +} + +// NetworkConnect mocks base method +func (m *MockCommonAPIClient) NetworkConnect(arg0 context.Context, arg1, arg2 string, arg3 *network.EndpointSettings) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworkConnect", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// NetworkConnect indicates an expected call of NetworkConnect +func (mr *MockCommonAPIClientMockRecorder) NetworkConnect(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkConnect", reflect.TypeOf((*MockCommonAPIClient)(nil).NetworkConnect), arg0, arg1, arg2, arg3) +} + +// NetworkCreate mocks base method +func (m *MockCommonAPIClient) NetworkCreate(arg0 context.Context, arg1 string, arg2 types.NetworkCreate) (types.NetworkCreateResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworkCreate", arg0, arg1, arg2) + ret0, _ := ret[0].(types.NetworkCreateResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetworkCreate indicates an expected call of NetworkCreate +func (mr *MockCommonAPIClientMockRecorder) NetworkCreate(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkCreate", reflect.TypeOf((*MockCommonAPIClient)(nil).NetworkCreate), arg0, arg1, arg2) +} + +// NetworkDisconnect mocks base method +func (m *MockCommonAPIClient) NetworkDisconnect(arg0 context.Context, arg1, arg2 string, arg3 bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworkDisconnect", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// NetworkDisconnect indicates an expected call of NetworkDisconnect +func (mr *MockCommonAPIClientMockRecorder) NetworkDisconnect(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkDisconnect", reflect.TypeOf((*MockCommonAPIClient)(nil).NetworkDisconnect), arg0, arg1, arg2, arg3) +} + +// NetworkInspect mocks base method +func (m *MockCommonAPIClient) NetworkInspect(arg0 context.Context, arg1 string, arg2 types.NetworkInspectOptions) (types.NetworkResource, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworkInspect", arg0, arg1, arg2) + ret0, _ := ret[0].(types.NetworkResource) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetworkInspect indicates an expected call of NetworkInspect +func (mr *MockCommonAPIClientMockRecorder) NetworkInspect(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkInspect", reflect.TypeOf((*MockCommonAPIClient)(nil).NetworkInspect), arg0, arg1, arg2) +} + +// NetworkInspectWithRaw mocks base method +func (m *MockCommonAPIClient) NetworkInspectWithRaw(arg0 context.Context, arg1 string, arg2 types.NetworkInspectOptions) (types.NetworkResource, []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworkInspectWithRaw", arg0, arg1, arg2) + ret0, _ := ret[0].(types.NetworkResource) + ret1, _ := ret[1].([]byte) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// NetworkInspectWithRaw indicates an expected call of NetworkInspectWithRaw +func (mr *MockCommonAPIClientMockRecorder) NetworkInspectWithRaw(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkInspectWithRaw", reflect.TypeOf((*MockCommonAPIClient)(nil).NetworkInspectWithRaw), arg0, arg1, arg2) +} + +// NetworkList mocks base method +func (m *MockCommonAPIClient) NetworkList(arg0 context.Context, arg1 types.NetworkListOptions) ([]types.NetworkResource, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworkList", arg0, arg1) + ret0, _ := ret[0].([]types.NetworkResource) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetworkList indicates an expected call of NetworkList +func (mr *MockCommonAPIClientMockRecorder) NetworkList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkList", reflect.TypeOf((*MockCommonAPIClient)(nil).NetworkList), arg0, arg1) +} + +// NetworkRemove mocks base method +func (m *MockCommonAPIClient) NetworkRemove(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworkRemove", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// NetworkRemove indicates an expected call of NetworkRemove +func (mr *MockCommonAPIClientMockRecorder) NetworkRemove(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkRemove", reflect.TypeOf((*MockCommonAPIClient)(nil).NetworkRemove), arg0, arg1) +} + +// NetworksPrune mocks base method +func (m *MockCommonAPIClient) NetworksPrune(arg0 context.Context, arg1 filters.Args) (types.NetworksPruneReport, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NetworksPrune", arg0, arg1) + ret0, _ := ret[0].(types.NetworksPruneReport) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NetworksPrune indicates an expected call of NetworksPrune +func (mr *MockCommonAPIClientMockRecorder) NetworksPrune(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworksPrune", reflect.TypeOf((*MockCommonAPIClient)(nil).NetworksPrune), arg0, arg1) +} + +// NodeInspectWithRaw mocks base method +func (m *MockCommonAPIClient) NodeInspectWithRaw(arg0 context.Context, arg1 string) (swarm.Node, []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeInspectWithRaw", arg0, arg1) + ret0, _ := ret[0].(swarm.Node) + ret1, _ := ret[1].([]byte) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// NodeInspectWithRaw indicates an expected call of NodeInspectWithRaw +func (mr *MockCommonAPIClientMockRecorder) NodeInspectWithRaw(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeInspectWithRaw", reflect.TypeOf((*MockCommonAPIClient)(nil).NodeInspectWithRaw), arg0, arg1) +} + +// NodeList mocks base method +func (m *MockCommonAPIClient) NodeList(arg0 context.Context, arg1 types.NodeListOptions) ([]swarm.Node, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeList", arg0, arg1) + ret0, _ := ret[0].([]swarm.Node) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NodeList indicates an expected call of NodeList +func (mr *MockCommonAPIClientMockRecorder) NodeList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeList", reflect.TypeOf((*MockCommonAPIClient)(nil).NodeList), arg0, arg1) +} + +// NodeRemove mocks base method +func (m *MockCommonAPIClient) NodeRemove(arg0 context.Context, arg1 string, arg2 types.NodeRemoveOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeRemove", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// NodeRemove indicates an expected call of NodeRemove +func (mr *MockCommonAPIClientMockRecorder) NodeRemove(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeRemove", reflect.TypeOf((*MockCommonAPIClient)(nil).NodeRemove), arg0, arg1, arg2) +} + +// NodeUpdate mocks base method +func (m *MockCommonAPIClient) NodeUpdate(arg0 context.Context, arg1 string, arg2 swarm.Version, arg3 swarm.NodeSpec) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeUpdate", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// NodeUpdate indicates an expected call of NodeUpdate +func (mr *MockCommonAPIClientMockRecorder) NodeUpdate(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeUpdate", reflect.TypeOf((*MockCommonAPIClient)(nil).NodeUpdate), arg0, arg1, arg2, arg3) +} + +// Ping mocks base method +func (m *MockCommonAPIClient) Ping(arg0 context.Context) (types.Ping, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Ping", arg0) + ret0, _ := ret[0].(types.Ping) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Ping indicates an expected call of Ping +func (mr *MockCommonAPIClientMockRecorder) Ping(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*MockCommonAPIClient)(nil).Ping), arg0) +} + +// PluginCreate mocks base method +func (m *MockCommonAPIClient) PluginCreate(arg0 context.Context, arg1 io.Reader, arg2 types.PluginCreateOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PluginCreate", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// PluginCreate indicates an expected call of PluginCreate +func (mr *MockCommonAPIClientMockRecorder) PluginCreate(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PluginCreate", reflect.TypeOf((*MockCommonAPIClient)(nil).PluginCreate), arg0, arg1, arg2) +} + +// PluginDisable mocks base method +func (m *MockCommonAPIClient) PluginDisable(arg0 context.Context, arg1 string, arg2 types.PluginDisableOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PluginDisable", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// PluginDisable indicates an expected call of PluginDisable +func (mr *MockCommonAPIClientMockRecorder) PluginDisable(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PluginDisable", reflect.TypeOf((*MockCommonAPIClient)(nil).PluginDisable), arg0, arg1, arg2) +} + +// PluginEnable mocks base method +func (m *MockCommonAPIClient) PluginEnable(arg0 context.Context, arg1 string, arg2 types.PluginEnableOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PluginEnable", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// PluginEnable indicates an expected call of PluginEnable +func (mr *MockCommonAPIClientMockRecorder) PluginEnable(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PluginEnable", reflect.TypeOf((*MockCommonAPIClient)(nil).PluginEnable), arg0, arg1, arg2) +} + +// PluginInspectWithRaw mocks base method +func (m *MockCommonAPIClient) PluginInspectWithRaw(arg0 context.Context, arg1 string) (*types.Plugin, []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PluginInspectWithRaw", arg0, arg1) + ret0, _ := ret[0].(*types.Plugin) + ret1, _ := ret[1].([]byte) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// PluginInspectWithRaw indicates an expected call of PluginInspectWithRaw +func (mr *MockCommonAPIClientMockRecorder) PluginInspectWithRaw(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PluginInspectWithRaw", reflect.TypeOf((*MockCommonAPIClient)(nil).PluginInspectWithRaw), arg0, arg1) +} + +// PluginInstall mocks base method +func (m *MockCommonAPIClient) PluginInstall(arg0 context.Context, arg1 string, arg2 types.PluginInstallOptions) (io.ReadCloser, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PluginInstall", arg0, arg1, arg2) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PluginInstall indicates an expected call of PluginInstall +func (mr *MockCommonAPIClientMockRecorder) PluginInstall(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PluginInstall", reflect.TypeOf((*MockCommonAPIClient)(nil).PluginInstall), arg0, arg1, arg2) +} + +// PluginList mocks base method +func (m *MockCommonAPIClient) PluginList(arg0 context.Context, arg1 filters.Args) (types.PluginsListResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PluginList", arg0, arg1) + ret0, _ := ret[0].(types.PluginsListResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PluginList indicates an expected call of PluginList +func (mr *MockCommonAPIClientMockRecorder) PluginList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PluginList", reflect.TypeOf((*MockCommonAPIClient)(nil).PluginList), arg0, arg1) +} + +// PluginPush mocks base method +func (m *MockCommonAPIClient) PluginPush(arg0 context.Context, arg1, arg2 string) (io.ReadCloser, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PluginPush", arg0, arg1, arg2) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PluginPush indicates an expected call of PluginPush +func (mr *MockCommonAPIClientMockRecorder) PluginPush(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PluginPush", reflect.TypeOf((*MockCommonAPIClient)(nil).PluginPush), arg0, arg1, arg2) +} + +// PluginRemove mocks base method +func (m *MockCommonAPIClient) PluginRemove(arg0 context.Context, arg1 string, arg2 types.PluginRemoveOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PluginRemove", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// PluginRemove indicates an expected call of PluginRemove +func (mr *MockCommonAPIClientMockRecorder) PluginRemove(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PluginRemove", reflect.TypeOf((*MockCommonAPIClient)(nil).PluginRemove), arg0, arg1, arg2) +} + +// PluginSet mocks base method +func (m *MockCommonAPIClient) PluginSet(arg0 context.Context, arg1 string, arg2 []string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PluginSet", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// PluginSet indicates an expected call of PluginSet +func (mr *MockCommonAPIClientMockRecorder) PluginSet(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PluginSet", reflect.TypeOf((*MockCommonAPIClient)(nil).PluginSet), arg0, arg1, arg2) +} + +// PluginUpgrade mocks base method +func (m *MockCommonAPIClient) PluginUpgrade(arg0 context.Context, arg1 string, arg2 types.PluginInstallOptions) (io.ReadCloser, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PluginUpgrade", arg0, arg1, arg2) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PluginUpgrade indicates an expected call of PluginUpgrade +func (mr *MockCommonAPIClientMockRecorder) PluginUpgrade(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PluginUpgrade", reflect.TypeOf((*MockCommonAPIClient)(nil).PluginUpgrade), arg0, arg1, arg2) +} + +// RegistryLogin mocks base method +func (m *MockCommonAPIClient) RegistryLogin(arg0 context.Context, arg1 types.AuthConfig) (registry.AuthenticateOKBody, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RegistryLogin", arg0, arg1) + ret0, _ := ret[0].(registry.AuthenticateOKBody) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RegistryLogin indicates an expected call of RegistryLogin +func (mr *MockCommonAPIClientMockRecorder) RegistryLogin(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegistryLogin", reflect.TypeOf((*MockCommonAPIClient)(nil).RegistryLogin), arg0, arg1) +} + +// SecretCreate mocks base method +func (m *MockCommonAPIClient) SecretCreate(arg0 context.Context, arg1 swarm.SecretSpec) (types.SecretCreateResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SecretCreate", arg0, arg1) + ret0, _ := ret[0].(types.SecretCreateResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SecretCreate indicates an expected call of SecretCreate +func (mr *MockCommonAPIClientMockRecorder) SecretCreate(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SecretCreate", reflect.TypeOf((*MockCommonAPIClient)(nil).SecretCreate), arg0, arg1) +} + +// SecretInspectWithRaw mocks base method +func (m *MockCommonAPIClient) SecretInspectWithRaw(arg0 context.Context, arg1 string) (swarm.Secret, []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SecretInspectWithRaw", arg0, arg1) + ret0, _ := ret[0].(swarm.Secret) + ret1, _ := ret[1].([]byte) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// SecretInspectWithRaw indicates an expected call of SecretInspectWithRaw +func (mr *MockCommonAPIClientMockRecorder) SecretInspectWithRaw(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SecretInspectWithRaw", reflect.TypeOf((*MockCommonAPIClient)(nil).SecretInspectWithRaw), arg0, arg1) +} + +// SecretList mocks base method +func (m *MockCommonAPIClient) SecretList(arg0 context.Context, arg1 types.SecretListOptions) ([]swarm.Secret, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SecretList", arg0, arg1) + ret0, _ := ret[0].([]swarm.Secret) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SecretList indicates an expected call of SecretList +func (mr *MockCommonAPIClientMockRecorder) SecretList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SecretList", reflect.TypeOf((*MockCommonAPIClient)(nil).SecretList), arg0, arg1) +} + +// SecretRemove mocks base method +func (m *MockCommonAPIClient) SecretRemove(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SecretRemove", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SecretRemove indicates an expected call of SecretRemove +func (mr *MockCommonAPIClientMockRecorder) SecretRemove(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SecretRemove", reflect.TypeOf((*MockCommonAPIClient)(nil).SecretRemove), arg0, arg1) +} + +// SecretUpdate mocks base method +func (m *MockCommonAPIClient) SecretUpdate(arg0 context.Context, arg1 string, arg2 swarm.Version, arg3 swarm.SecretSpec) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SecretUpdate", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// SecretUpdate indicates an expected call of SecretUpdate +func (mr *MockCommonAPIClientMockRecorder) SecretUpdate(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SecretUpdate", reflect.TypeOf((*MockCommonAPIClient)(nil).SecretUpdate), arg0, arg1, arg2, arg3) +} + +// ServerVersion mocks base method +func (m *MockCommonAPIClient) ServerVersion(arg0 context.Context) (types.Version, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ServerVersion", arg0) + ret0, _ := ret[0].(types.Version) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ServerVersion indicates an expected call of ServerVersion +func (mr *MockCommonAPIClientMockRecorder) ServerVersion(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerVersion", reflect.TypeOf((*MockCommonAPIClient)(nil).ServerVersion), arg0) +} + +// ServiceCreate mocks base method +func (m *MockCommonAPIClient) ServiceCreate(arg0 context.Context, arg1 swarm.ServiceSpec, arg2 types.ServiceCreateOptions) (types.ServiceCreateResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ServiceCreate", arg0, arg1, arg2) + ret0, _ := ret[0].(types.ServiceCreateResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ServiceCreate indicates an expected call of ServiceCreate +func (mr *MockCommonAPIClientMockRecorder) ServiceCreate(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServiceCreate", reflect.TypeOf((*MockCommonAPIClient)(nil).ServiceCreate), arg0, arg1, arg2) +} + +// ServiceInspectWithRaw mocks base method +func (m *MockCommonAPIClient) ServiceInspectWithRaw(arg0 context.Context, arg1 string, arg2 types.ServiceInspectOptions) (swarm.Service, []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ServiceInspectWithRaw", arg0, arg1, arg2) + ret0, _ := ret[0].(swarm.Service) + ret1, _ := ret[1].([]byte) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// ServiceInspectWithRaw indicates an expected call of ServiceInspectWithRaw +func (mr *MockCommonAPIClientMockRecorder) ServiceInspectWithRaw(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServiceInspectWithRaw", reflect.TypeOf((*MockCommonAPIClient)(nil).ServiceInspectWithRaw), arg0, arg1, arg2) +} + +// ServiceList mocks base method +func (m *MockCommonAPIClient) ServiceList(arg0 context.Context, arg1 types.ServiceListOptions) ([]swarm.Service, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ServiceList", arg0, arg1) + ret0, _ := ret[0].([]swarm.Service) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ServiceList indicates an expected call of ServiceList +func (mr *MockCommonAPIClientMockRecorder) ServiceList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServiceList", reflect.TypeOf((*MockCommonAPIClient)(nil).ServiceList), arg0, arg1) +} + +// ServiceLogs mocks base method +func (m *MockCommonAPIClient) ServiceLogs(arg0 context.Context, arg1 string, arg2 types.ContainerLogsOptions) (io.ReadCloser, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ServiceLogs", arg0, arg1, arg2) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ServiceLogs indicates an expected call of ServiceLogs +func (mr *MockCommonAPIClientMockRecorder) ServiceLogs(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServiceLogs", reflect.TypeOf((*MockCommonAPIClient)(nil).ServiceLogs), arg0, arg1, arg2) +} + +// ServiceRemove mocks base method +func (m *MockCommonAPIClient) ServiceRemove(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ServiceRemove", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ServiceRemove indicates an expected call of ServiceRemove +func (mr *MockCommonAPIClientMockRecorder) ServiceRemove(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServiceRemove", reflect.TypeOf((*MockCommonAPIClient)(nil).ServiceRemove), arg0, arg1) +} + +// ServiceUpdate mocks base method +func (m *MockCommonAPIClient) ServiceUpdate(arg0 context.Context, arg1 string, arg2 swarm.Version, arg3 swarm.ServiceSpec, arg4 types.ServiceUpdateOptions) (types.ServiceUpdateResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ServiceUpdate", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(types.ServiceUpdateResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ServiceUpdate indicates an expected call of ServiceUpdate +func (mr *MockCommonAPIClientMockRecorder) ServiceUpdate(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServiceUpdate", reflect.TypeOf((*MockCommonAPIClient)(nil).ServiceUpdate), arg0, arg1, arg2, arg3, arg4) +} + +// SwarmGetUnlockKey mocks base method +func (m *MockCommonAPIClient) SwarmGetUnlockKey(arg0 context.Context) (types.SwarmUnlockKeyResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SwarmGetUnlockKey", arg0) + ret0, _ := ret[0].(types.SwarmUnlockKeyResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SwarmGetUnlockKey indicates an expected call of SwarmGetUnlockKey +func (mr *MockCommonAPIClientMockRecorder) SwarmGetUnlockKey(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SwarmGetUnlockKey", reflect.TypeOf((*MockCommonAPIClient)(nil).SwarmGetUnlockKey), arg0) +} + +// SwarmInit mocks base method +func (m *MockCommonAPIClient) SwarmInit(arg0 context.Context, arg1 swarm.InitRequest) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SwarmInit", arg0, arg1) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SwarmInit indicates an expected call of SwarmInit +func (mr *MockCommonAPIClientMockRecorder) SwarmInit(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SwarmInit", reflect.TypeOf((*MockCommonAPIClient)(nil).SwarmInit), arg0, arg1) +} + +// SwarmInspect mocks base method +func (m *MockCommonAPIClient) SwarmInspect(arg0 context.Context) (swarm.Swarm, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SwarmInspect", arg0) + ret0, _ := ret[0].(swarm.Swarm) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SwarmInspect indicates an expected call of SwarmInspect +func (mr *MockCommonAPIClientMockRecorder) SwarmInspect(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SwarmInspect", reflect.TypeOf((*MockCommonAPIClient)(nil).SwarmInspect), arg0) +} + +// SwarmJoin mocks base method +func (m *MockCommonAPIClient) SwarmJoin(arg0 context.Context, arg1 swarm.JoinRequest) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SwarmJoin", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SwarmJoin indicates an expected call of SwarmJoin +func (mr *MockCommonAPIClientMockRecorder) SwarmJoin(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SwarmJoin", reflect.TypeOf((*MockCommonAPIClient)(nil).SwarmJoin), arg0, arg1) +} + +// SwarmLeave mocks base method +func (m *MockCommonAPIClient) SwarmLeave(arg0 context.Context, arg1 bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SwarmLeave", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SwarmLeave indicates an expected call of SwarmLeave +func (mr *MockCommonAPIClientMockRecorder) SwarmLeave(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SwarmLeave", reflect.TypeOf((*MockCommonAPIClient)(nil).SwarmLeave), arg0, arg1) +} + +// SwarmUnlock mocks base method +func (m *MockCommonAPIClient) SwarmUnlock(arg0 context.Context, arg1 swarm.UnlockRequest) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SwarmUnlock", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SwarmUnlock indicates an expected call of SwarmUnlock +func (mr *MockCommonAPIClientMockRecorder) SwarmUnlock(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SwarmUnlock", reflect.TypeOf((*MockCommonAPIClient)(nil).SwarmUnlock), arg0, arg1) +} + +// SwarmUpdate mocks base method +func (m *MockCommonAPIClient) SwarmUpdate(arg0 context.Context, arg1 swarm.Version, arg2 swarm.Spec, arg3 swarm.UpdateFlags) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SwarmUpdate", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// SwarmUpdate indicates an expected call of SwarmUpdate +func (mr *MockCommonAPIClientMockRecorder) SwarmUpdate(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SwarmUpdate", reflect.TypeOf((*MockCommonAPIClient)(nil).SwarmUpdate), arg0, arg1, arg2, arg3) +} + +// TaskInspectWithRaw mocks base method +func (m *MockCommonAPIClient) TaskInspectWithRaw(arg0 context.Context, arg1 string) (swarm.Task, []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TaskInspectWithRaw", arg0, arg1) + ret0, _ := ret[0].(swarm.Task) + ret1, _ := ret[1].([]byte) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// TaskInspectWithRaw indicates an expected call of TaskInspectWithRaw +func (mr *MockCommonAPIClientMockRecorder) TaskInspectWithRaw(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TaskInspectWithRaw", reflect.TypeOf((*MockCommonAPIClient)(nil).TaskInspectWithRaw), arg0, arg1) +} + +// TaskList mocks base method +func (m *MockCommonAPIClient) TaskList(arg0 context.Context, arg1 types.TaskListOptions) ([]swarm.Task, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TaskList", arg0, arg1) + ret0, _ := ret[0].([]swarm.Task) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TaskList indicates an expected call of TaskList +func (mr *MockCommonAPIClientMockRecorder) TaskList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TaskList", reflect.TypeOf((*MockCommonAPIClient)(nil).TaskList), arg0, arg1) +} + +// TaskLogs mocks base method +func (m *MockCommonAPIClient) TaskLogs(arg0 context.Context, arg1 string, arg2 types.ContainerLogsOptions) (io.ReadCloser, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TaskLogs", arg0, arg1, arg2) + ret0, _ := ret[0].(io.ReadCloser) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TaskLogs indicates an expected call of TaskLogs +func (mr *MockCommonAPIClientMockRecorder) TaskLogs(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TaskLogs", reflect.TypeOf((*MockCommonAPIClient)(nil).TaskLogs), arg0, arg1, arg2) +} + +// VolumeCreate mocks base method +func (m *MockCommonAPIClient) VolumeCreate(arg0 context.Context, arg1 volume.VolumeCreateBody) (types.Volume, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VolumeCreate", arg0, arg1) + ret0, _ := ret[0].(types.Volume) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// VolumeCreate indicates an expected call of VolumeCreate +func (mr *MockCommonAPIClientMockRecorder) VolumeCreate(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VolumeCreate", reflect.TypeOf((*MockCommonAPIClient)(nil).VolumeCreate), arg0, arg1) +} + +// VolumeInspect mocks base method +func (m *MockCommonAPIClient) VolumeInspect(arg0 context.Context, arg1 string) (types.Volume, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VolumeInspect", arg0, arg1) + ret0, _ := ret[0].(types.Volume) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// VolumeInspect indicates an expected call of VolumeInspect +func (mr *MockCommonAPIClientMockRecorder) VolumeInspect(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VolumeInspect", reflect.TypeOf((*MockCommonAPIClient)(nil).VolumeInspect), arg0, arg1) +} + +// VolumeInspectWithRaw mocks base method +func (m *MockCommonAPIClient) VolumeInspectWithRaw(arg0 context.Context, arg1 string) (types.Volume, []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VolumeInspectWithRaw", arg0, arg1) + ret0, _ := ret[0].(types.Volume) + ret1, _ := ret[1].([]byte) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// VolumeInspectWithRaw indicates an expected call of VolumeInspectWithRaw +func (mr *MockCommonAPIClientMockRecorder) VolumeInspectWithRaw(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VolumeInspectWithRaw", reflect.TypeOf((*MockCommonAPIClient)(nil).VolumeInspectWithRaw), arg0, arg1) +} + +// VolumeList mocks base method +func (m *MockCommonAPIClient) VolumeList(arg0 context.Context, arg1 filters.Args) (volume.VolumeListOKBody, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VolumeList", arg0, arg1) + ret0, _ := ret[0].(volume.VolumeListOKBody) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// VolumeList indicates an expected call of VolumeList +func (mr *MockCommonAPIClientMockRecorder) VolumeList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VolumeList", reflect.TypeOf((*MockCommonAPIClient)(nil).VolumeList), arg0, arg1) +} + +// VolumeRemove mocks base method +func (m *MockCommonAPIClient) VolumeRemove(arg0 context.Context, arg1 string, arg2 bool) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VolumeRemove", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// VolumeRemove indicates an expected call of VolumeRemove +func (mr *MockCommonAPIClientMockRecorder) VolumeRemove(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VolumeRemove", reflect.TypeOf((*MockCommonAPIClient)(nil).VolumeRemove), arg0, arg1, arg2) +} + +// VolumesPrune mocks base method +func (m *MockCommonAPIClient) VolumesPrune(arg0 context.Context, arg1 filters.Args) (types.VolumesPruneReport, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VolumesPrune", arg0, arg1) + ret0, _ := ret[0].(types.VolumesPruneReport) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// VolumesPrune indicates an expected call of VolumesPrune +func (mr *MockCommonAPIClientMockRecorder) VolumesPrune(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VolumesPrune", reflect.TypeOf((*MockCommonAPIClient)(nil).VolumesPrune), arg0, arg1) +}