diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 000000000..15c2e1f9a --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,14 @@ + +tasks: + - init: make build +github: + prebuilds: + master: true + branches: true + pullRequests: true + pullRequestsFromForks: true + addCheck: true + +vscode: + extensions: + - golang.go \ No newline at end of file diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 5d4b71768..16e3e3548 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -17,6 +17,11 @@ * `choco install cygwin make -y` * `[Environment]::SetEnvironmentVariable("PATH", "C:\tools\cygwin\bin;$ENV:PATH", "MACHINE")` +Alternatively, you can use Gitpod to run pre-configured dev envrionment in the cloud right from your browser + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/buildpacks/pack) + + ### Windows Caveats * Symlinks - Some of our tests attempt to create symlinks. On Windows, this requires the [permission to be provided](https://stackoverflow.com/a/24353758). diff --git a/README.md b/README.md index a57d021e0..495172845 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ [![GitHub license](https://img.shields.io/github/license/buildpacks/pack)](https://github.com/buildpacks/pack/blob/main/LICENSE) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4748/badge)](https://bestpractices.coreinfrastructure.org/projects/4748) [![Slack](https://img.shields.io/badge/slack-join-ff69b4.svg?logo=slack)](https://slack.buildpacks.io/) +[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/buildpacks/pack) `pack` makes it easy for... - [**App Developers**][app-dev] to use buildpacks to convert code into runnable images. diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index d4c73f7a0..b1c845c1e 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -2762,7 +2762,7 @@ func createStackImage(dockerCli client.CommonAPIClient, repoName string, dir str defaultFilterFunc := func(file string) bool { return true } ctx := context.Background() - buildContext := archive.ReadDirAsTar(dir, "/", 0, 0, -1, true, defaultFilterFunc) + buildContext := archive.ReadDirAsTar(dir, "/", 0, 0, -1, true, false, defaultFilterFunc) res, err := dockerCli.ImageBuild(ctx, buildContext, dockertypes.ImageBuildOptions{ Tags: []string{repoName}, diff --git a/acceptance/buildpacks/archive_buildpack.go b/acceptance/buildpacks/archive_buildpack.go index 311e274b5..3f1f4c2b1 100644 --- a/acceptance/buildpacks/archive_buildpack.go +++ b/acceptance/buildpacks/archive_buildpack.go @@ -74,6 +74,7 @@ func (a archiveBuildpack) createTgz(sourceDir string) (string, error) { defaultGid, defaultMode, true, + false, nil, ) if err != nil { diff --git a/acceptance/testdata/mock_stack/windows/run/server.go b/acceptance/testdata/mock_stack/windows/run/server.go index 97ba02e36..4eb1a8b5f 100644 --- a/acceptance/testdata/mock_stack/windows/run/server.go +++ b/acceptance/testdata/mock_stack/windows/run/server.go @@ -28,7 +28,7 @@ func main() { } for _, path := range paths { - contents, err := ioutil.ReadFile(path) + contents, err := ioutil.ReadFile(filepath.Clean(path)) if err != nil { panic(err.Error()) } diff --git a/build.go b/build.go index 0ee80d047..cb04938c7 100644 --- a/build.go +++ b/build.go @@ -542,7 +542,7 @@ func (c *Client) processAppPath(appPath string) (string, error) { } if !fi.IsDir() { - fh, err := os.Open(resolvedAppPath) + fh, err := os.Open(filepath.Clean(resolvedAppPath)) if err != nil { return "", errors.Wrap(err, "read file") } diff --git a/build_test.go b/build_test.go index b6aa73a3a..86e6ac4fa 100644 --- a/build_test.go +++ b/build_test.go @@ -132,12 +132,12 @@ func testBuild(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - defaultBuilderImage.Cleanup() - fakeDefaultRunImage.Cleanup() - fakeMirror1.Cleanup() - fakeMirror2.Cleanup() + h.AssertNilE(t, defaultBuilderImage.Cleanup()) + h.AssertNilE(t, fakeDefaultRunImage.Cleanup()) + h.AssertNilE(t, fakeMirror1.Cleanup()) + h.AssertNilE(t, fakeMirror2.Cleanup()) os.RemoveAll(tmpDir) - fakeLifecycleImage.Cleanup() + h.AssertNilE(t, fakeLifecycleImage.Cleanup()) }) when("#Build", func() { @@ -226,9 +226,9 @@ func testBuild(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - remoteRunImage.Cleanup() - builderWithoutLifecycleImageOrCreator.Cleanup() - h.AssertNil(t, builtImage.Cleanup()) + h.AssertNilE(t, remoteRunImage.Cleanup()) + h.AssertNilE(t, builderWithoutLifecycleImageOrCreator.Cleanup()) + h.AssertNilE(t, builtImage.Cleanup()) }) it("only prints app name and sha", func() { @@ -254,7 +254,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - builtImage.Cleanup() + h.AssertNilE(t, builtImage.Cleanup()) }) it("only prints app name and sha", func() { @@ -462,8 +462,8 @@ func testBuild(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - customBuilderImage.Cleanup() - fakeRunImage.Cleanup() + h.AssertNilE(t, customBuilderImage.Cleanup()) + h.AssertNilE(t, fakeRunImage.Cleanup()) }) it("it uses the provided builder", func() { @@ -489,7 +489,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - fakeRunImage.Cleanup() + h.AssertNilE(t, fakeRunImage.Cleanup()) }) when("run image stack matches the builder stack", func() { @@ -588,8 +588,8 @@ func testBuild(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - fakeLocalMirror.Cleanup() - fakeLocalMirror1.Cleanup() + h.AssertNilE(t, fakeLocalMirror.Cleanup()) + h.AssertNilE(t, fakeLocalMirror1.Cleanup()) }) when("Publish is true", func() { @@ -1147,7 +1147,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - h.AssertNil(t, os.Remove(buildpackTgz)) + h.AssertNilE(t, os.Remove(buildpackTgz)) }) it("buildpacks are added to ephemeral builder", func() { @@ -1331,8 +1331,7 @@ func testBuild(t *testing.T, when spec.G, it spec.S) { it.After(func() { os.Unsetenv("PACK_HOME") - err := os.RemoveAll(tmpDir) - h.AssertNil(t, err) + h.AssertNil(t, os.RemoveAll(tmpDir)) }) it("all buildpacks are added to ephemeral builder", func() { @@ -1644,9 +1643,9 @@ func testBuild(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - h.AssertNil(t, os.Unsetenv("HTTP_PROXY")) - h.AssertNil(t, os.Unsetenv("HTTPS_PROXY")) - h.AssertNil(t, os.Unsetenv("NO_PROXY")) + h.AssertNilE(t, os.Unsetenv("HTTP_PROXY")) + h.AssertNilE(t, os.Unsetenv("HTTPS_PROXY")) + h.AssertNilE(t, os.Unsetenv("NO_PROXY")) }) it("defaults to the *_PROXY environment variables", func() { diff --git a/builder/config_reader.go b/builder/config_reader.go index c125384dd..6b0120ec8 100644 --- a/builder/config_reader.go +++ b/builder/config_reader.go @@ -3,6 +3,7 @@ package builder import ( "fmt" "os" + "path/filepath" "github.com/BurntSushi/toml" "github.com/pkg/errors" @@ -55,7 +56,7 @@ type LifecycleConfig struct { // ReadConfig reads a builder configuration from the file path provided and returns the // configuration along with any warnings encountered while parsing func ReadConfig(path string) (config Config, warnings []string, err error) { - file, err := os.Open(path) + file, err := os.Open(filepath.Clean(path)) if err != nil { return Config{}, nil, errors.Wrap(err, "opening config file") } diff --git a/go.mod b/go.mod index 6df6d1cb5..2a8782fad 100644 --- a/go.mod +++ b/go.mod @@ -14,18 +14,18 @@ require ( github.com/ghodss/yaml v1.0.0 github.com/golang/mock v1.5.0 github.com/google/go-cmp v0.5.5 - github.com/google/go-containerregistry v0.4.1 + github.com/google/go-containerregistry v0.5.1 github.com/google/go-github/v30 v30.1.0 github.com/heroku/color v0.0.6 github.com/mattn/go-colorable v0.1.8 // indirect github.com/mitchellh/ioprogress v0.0.0-20180201004757-6a23b12fa88e github.com/moby/sys/mount v0.2.0 // indirect github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf // indirect - github.com/onsi/gomega v1.11.0 + github.com/onsi/gomega v1.12.0 github.com/opencontainers/image-spec v1.0.1 github.com/opencontainers/runc v0.1.1 // indirect github.com/opencontainers/selinux v1.6.0 // indirect - github.com/pelletier/go-toml v1.9.0 + github.com/pelletier/go-toml v1.9.1 github.com/pkg/errors v0.9.1 github.com/sabhiram/go-gitignore v0.0.0-20201211074657-223ce5d391b0 github.com/sclevine/spec v1.4.0 @@ -37,10 +37,8 @@ require ( golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 golang.org/x/mod v0.4.2 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d - golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 // indirect google.golang.org/genproto v0.0.0-20201022181438-0ff5f38871d5 // indirect google.golang.org/grpc v1.33.1 // indirect - google.golang.org/protobuf v1.25.0 // indirect gopkg.in/src-d/go-git.v4 v4.13.1 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 ) diff --git a/go.sum b/go.sum index 5649628f0..144e146ac 100644 --- a/go.sum +++ b/go.sum @@ -214,6 +214,7 @@ github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -246,8 +247,9 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -255,7 +257,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 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/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= @@ -263,8 +264,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-containerregistry v0.2.1/go.mod h1:Ts3Wioz1r5ayWx8sS6vLcWltWcM1aqFjd/eVrkFhrWM= github.com/google/go-containerregistry v0.3.0/go.mod h1:BJ7VxR1hAhdiZBGGnvGETHEmFs1hzXc4VM1xjOPO9wA= github.com/google/go-containerregistry v0.4.0/go.mod h1:TX4KwzBRckt63iM22ZNHzUGqXMdLE1UFJuEQnC/14fE= -github.com/google/go-containerregistry v0.4.1 h1:Lrcj2AOoZ7WKawsoKAh2O0dH0tBqMW2lTEmozmK4Z3k= -github.com/google/go-containerregistry v0.4.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= +github.com/google/go-containerregistry v0.5.1 h1:/+mFTs4AlwsJ/mJe8NDtKb7BxLtbZFpcn8vDsneEkwQ= +github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-github/v30 v30.1.0 h1:VLDx+UolQICEOKu2m4uAoMti1SxuEBAl7RSEG16L+Oo= github.com/google/go-github/v30 v30.1.0/go.mod h1:n8jBpHl45a/rlBUtRJMOG4GhNADUQFEufcolZ95JfU8= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= @@ -415,8 +416,9 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -425,15 +427,17 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.2 h1:HFB2fbVIlhIfCfOW81bZFbiC/RvnpXSdhbF2/DJr134= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug= -github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.12.0 h1:p4oGGk2M2UJc0wWN4lHFvIB71lxsh0T/UiKCCgFADY8= +github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -449,8 +453,8 @@ github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqi github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.9.0 h1:NOd0BRdOKpPf0SxkL3HxSQOG7rNh+4kl6PHcBPFs7Q0= -github.com/pelletier/go-toml v1.9.0/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.1 h1:a6qW1EVNZWH9WGI6CsYdD8WAylkoXBS5yv0XHlh17Tc= +github.com/pelletier/go-toml v1.9.1/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -656,10 +660,12 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -674,6 +680,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -723,16 +730,20 @@ golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 h1:SgQ6LNaYJU0JIuEHv9+s6EbhSCwYeAf5Yvj6lpYlqAE= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -783,6 +794,7 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -853,8 +865,9 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/inspect_buildpack_test.go b/inspect_buildpack_test.go index 6d93d373a..f832f2e46 100644 --- a/inspect_buildpack_test.go +++ b/inspect_buildpack_test.go @@ -652,5 +652,5 @@ func writeBuildpackArchive(buildpackPath, tmpDir string, assert h.AssertionManag tw := tar.NewWriter(buildpackWriter) defer tw.Close() - assert.Nil(archive.WriteDirToTar(tw, layoutDir, "/", 0, 0, 0755, true, nil)) + assert.Nil(archive.WriteDirToTar(tw, layoutDir, "/", 0, 0, 0755, true, false, nil)) } diff --git a/internal/blob/blob.go b/internal/blob/blob.go index c32f669fb..1846435c4 100644 --- a/internal/blob/blob.go +++ b/internal/blob/blob.go @@ -31,7 +31,7 @@ func (b blob) Open() (r io.ReadCloser, err error) { return nil, errors.Wrapf(err, "read blob at path '%s'", b.path) } if fi.IsDir() { - return archive.ReadDirAsTar(b.path, ".", 0, 0, -1, true, nil), nil + return archive.ReadDirAsTar(b.path, ".", 0, 0, -1, true, false, nil), nil } fh, err := os.Open(b.path) diff --git a/internal/blob/downloader.go b/internal/blob/downloader.go index f786ce3d7..6f538f968 100644 --- a/internal/blob/downloader.go +++ b/internal/blob/downloader.go @@ -90,7 +90,7 @@ func (d *downloader) handleHTTP(ctx context.Context, uri string) (string, error) etag := "" if etagExists { - bytes, err := ioutil.ReadFile(etagFile) + bytes, err := ioutil.ReadFile(filepath.Clean(etagFile)) if err != nil { return "", err } diff --git a/internal/build/container_ops.go b/internal/build/container_ops.go index d0ae10f44..fdc842e71 100644 --- a/internal/build/container_ops.go +++ b/internal/build/container_ops.go @@ -25,14 +25,15 @@ import ( 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, os string, fileFilter func(string) bool) ContainerOperation { +// if includeRoot is set the UID/GID will be set on the dst directory. +func CopyDir(src, dst string, uid, gid int, os string, includeRoot bool, fileFilter func(string) bool) ContainerOperation { return func(ctrClient client.CommonAPIClient, ctx context.Context, containerID string, stdout, stderr io.Writer) error { tarPath := dst if os == "windows" { tarPath = paths.WindowsToSlash(dst) } - reader, err := createReader(src, tarPath, uid, gid, fileFilter) + reader, err := createReader(src, tarPath, uid, gid, includeRoot, fileFilter) if err != nil { return errors.Wrapf(err, "create tar archive from '%s'", src) } @@ -166,7 +167,7 @@ func WriteStackToml(dstPath string, stack builder.StackMetadata, os string) Cont } } -func createReader(src, dst string, uid, gid int, fileFilter func(string) bool) (io.ReadCloser, error) { +func createReader(src, dst string, uid, gid int, includeRoot bool, fileFilter func(string) bool) (io.ReadCloser, error) { fi, err := os.Stat(src) if err != nil { return nil, err @@ -178,7 +179,7 @@ func createReader(src, dst string, uid, gid int, fileFilter func(string) bool) ( mode = 0777 } - return archive.ReadDirAsTar(src, dst, uid, gid, mode, false, fileFilter), nil + return archive.ReadDirAsTar(src, dst, uid, gid, mode, false, includeRoot, fileFilter), nil } return archive.ReadZipAsTar(src, dst, uid, gid, -1, false, fileFilter), nil diff --git a/internal/build/container_ops_test.go b/internal/build/container_ops_test.go index 629de273c..12a07a226 100644 --- a/internal/build/container_ops_test.go +++ b/internal/build/container_ops_test.go @@ -86,7 +86,7 @@ func testContainerOps(t *testing.T, when spec.G, it spec.S) { h.AssertNil(t, err) defer cleanupContainer(ctx, ctr.ID) - copyDirOp := build.CopyDir(filepath.Join("testdata", "fake-app"), containerDir, 123, 456, osType, nil) + copyDirOp := build.CopyDir(filepath.Join("testdata", "fake-app"), containerDir, 123, 456, osType, false, nil) var outBuf, errBuf bytes.Buffer err = copyDirOp(ctrClient, ctx, ctr.ID, &outBuf, &errBuf) @@ -124,6 +124,54 @@ lrwxrwxrwx 1 123 456 (.*) fake-app-symlink -> fake-app-file } }) + when("includeRoot", func() { + it("copies root dir with new GID, UID and permissions", func() { + containerDir := "/some-vol" + if osType == "windows" { + containerDir = `c:\some-vol` + } + + ctrCmd := []string{"ls", "-al", "/"} + if osType == "windows" { + ctrCmd = []string{"cmd", "/c", `dir /q c:`} + } + + ctx := context.Background() + ctr, err := createContainer(ctx, imageName, containerDir, osType, ctrCmd...) + h.AssertNil(t, err) + defer cleanupContainer(ctx, ctr.ID) + + copyDirOp := build.CopyDir(filepath.Join("testdata", "fake-app"), containerDir, 123, 456, osType, true, nil) + + var outBuf, errBuf bytes.Buffer + err = copyDirOp(ctrClient, ctx, ctr.ID, &outBuf, &errBuf) + h.AssertNil(t, err) + + err = container.Run(ctx, ctrClient, ctr.ID, &outBuf, &errBuf) + h.AssertNil(t, err) + + h.AssertEq(t, errBuf.String(), "") + if osType == "windows" { + // Expected WCOW results + h.AssertContainsMatch(t, strings.ReplaceAll(outBuf.String(), "\r", ""), ` +(.*) ... some-vol +`) + } else { + if runtime.GOOS == "windows" { + // Expected LCOW results + h.AssertContainsMatch(t, outBuf.String(), ` +drwxrwxrwx 2 123 456 (.*) some-vol +`) + } else { + // Expected results + h.AssertContainsMatch(t, outBuf.String(), ` +drwsrwsrwt 2 123 456 (.*) some-vol +`) + } + } + }) + }) + it("writes contents ignoring from file filter", func() { containerDir := "/some-vol" if osType == "windows" { @@ -140,7 +188,7 @@ lrwxrwxrwx 1 123 456 (.*) fake-app-symlink -> fake-app-file h.AssertNil(t, err) defer cleanupContainer(ctx, ctr.ID) - copyDirOp := build.CopyDir(filepath.Join("testdata", "fake-app"), containerDir, 123, 456, osType, func(filename string) bool { + copyDirOp := build.CopyDir(filepath.Join("testdata", "fake-app"), containerDir, 123, 456, osType, false, func(filename string) bool { return filepath.Base(filename) != "file-to-ignore" }) @@ -172,7 +220,7 @@ lrwxrwxrwx 1 123 456 (.*) fake-app-symlink -> fake-app-file h.AssertNil(t, err) defer cleanupContainer(ctx, ctr.ID) - copyDirOp := build.CopyDir(filepath.Join("testdata", "fake-app.zip"), containerDir, 123, 456, osType, nil) + copyDirOp := build.CopyDir(filepath.Join("testdata", "fake-app.zip"), containerDir, 123, 456, osType, false, nil) var outBuf, errBuf bytes.Buffer err = copyDirOp(ctrClient, ctx, ctr.ID, &outBuf, &errBuf) @@ -352,12 +400,18 @@ func cleanupContainer(ctx context.Context, ctrID string) { } // remove container - ctrClient.ContainerRemove(ctx, ctrID, types.ContainerRemoveOptions{}) + err = ctrClient.ContainerRemove(ctx, ctrID, types.ContainerRemoveOptions{}) + if err != nil { + return + } // remove volumes for _, m := range inspect.Mounts { if m.Type == mount.TypeVolume { - ctrClient.VolumeRemove(ctx, m.Name, true) + err = ctrClient.VolumeRemove(ctx, m.Name, true) + if err != nil { + return + } } } } diff --git a/internal/build/lifecycle_execution.go b/internal/build/lifecycle_execution.go index e0d96ebc0..acb6c665d 100644 --- a/internal/build/lifecycle_execution.go +++ b/internal/build/lifecycle_execution.go @@ -173,6 +173,7 @@ func (l *LifecycleExecution) Cleanup() error { func (l *LifecycleExecution) Create(ctx context.Context, publish bool, dockerHost string, clearCache bool, runImage, repoName, networkMode string, buildCache, launchCache Cache, additionalTags, volumes []string, phaseFactory PhaseFactory) error { flags := addTags([]string{ + "-app", l.mountPaths.appDir(), "-cache-dir", l.mountPaths.cacheDir(), "-run-image", runImage, }, additionalTags) @@ -200,7 +201,7 @@ func (l *LifecycleExecution) Create(ctx context.Context, publish bool, dockerHos WithArgs(repoName), WithNetwork(networkMode), cacheOpts, - WithContainerOperations(CopyDir(l.opts.AppPath, l.mountPaths.appDir(), l.opts.Builder.UID(), l.opts.Builder.GID(), l.os, l.opts.FileFilter)), + WithContainerOperations(CopyDir(l.opts.AppPath, l.mountPaths.appDir(), l.opts.Builder.UID(), l.opts.Builder.GID(), l.os, true, l.opts.FileFilter)), } if publish { @@ -224,6 +225,7 @@ func (l *LifecycleExecution) Create(ctx context.Context, publish bool, dockerHos } func (l *LifecycleExecution) Detect(ctx context.Context, networkMode string, volumes []string, phaseFactory PhaseFactory) error { + flags := []string{"-app", l.mountPaths.appDir()} configProvider := NewPhaseConfigProvider( "detector", l, @@ -235,8 +237,9 @@ func (l *LifecycleExecution) Detect(ctx context.Context, networkMode string, vol WithBinds(volumes...), WithContainerOperations( EnsureVolumeAccess(l.opts.Builder.UID(), l.opts.Builder.GID(), l.os, l.layersVolume, l.appVolume), - CopyDir(l.opts.AppPath, l.mountPaths.appDir(), l.opts.Builder.UID(), l.opts.Builder.GID(), l.os, l.opts.FileFilter), + CopyDir(l.opts.AppPath, l.mountPaths.appDir(), l.opts.Builder.UID(), l.opts.Builder.GID(), l.os, true, l.opts.FileFilter), ), + WithFlags(flags...), ) detect := phaseFactory.New(configProvider) @@ -357,6 +360,7 @@ func (l *LifecycleExecution) newAnalyze(repoName, networkMode string, publish bo } func (l *LifecycleExecution) Build(ctx context.Context, networkMode string, volumes []string, phaseFactory PhaseFactory) error { + flags := []string{"-app", l.mountPaths.appDir()} configProvider := NewPhaseConfigProvider( "builder", l, @@ -364,6 +368,7 @@ func (l *LifecycleExecution) Build(ctx context.Context, networkMode string, volu WithArgs(l.withLogLevel()...), WithNetwork(networkMode), WithBinds(volumes...), + WithFlags(flags...), ) build := phaseFactory.New(configProvider) @@ -382,6 +387,7 @@ func determineDefaultProcessType(platformAPI *api.Version, providedValue string) func (l *LifecycleExecution) newExport(repoName, runImage string, publish bool, dockerHost, networkMode string, buildCache, launchCache Cache, additionalTags []string, phaseFactory PhaseFactory) (RunnerCleaner, error) { flags := []string{ + "-app", l.mountPaths.appDir(), "-cache-dir", l.mountPaths.cacheDir(), "-stack", l.mountPaths.stackPath(), "-run-image", runImage, diff --git a/internal/build/lifecycle_execution_test.go b/internal/build/lifecycle_execution_test.go index ea26c0a6d..8fa5be5b5 100644 --- a/internal/build/lifecycle_execution_test.go +++ b/internal/build/lifecycle_execution_test.go @@ -151,6 +151,37 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) { } } }) + when("Run with workspace dir", func() { + it("succeeds", func() { + opts := build.LifecycleOptions{ + Publish: false, + ClearCache: false, + RunImage: "test", + Image: imageName, + Builder: fakeBuilder, + TrustBuilder: true, + Workspace: "app", + UseCreator: true, + } + + lifecycle, err := build.NewLifecycleExecution(logger, docker, opts) + h.AssertNil(t, err) + + err = lifecycle.Run(context.Background(), func(execution *build.LifecycleExecution) build.PhaseFactory { + return fakePhaseFactory + }) + h.AssertNil(t, err) + + h.AssertEq(t, len(fakePhaseFactory.NewCalledWithProvider), 1) + + for _, entry := range fakePhaseFactory.NewCalledWithProvider { + if entry.Name() == "creator" { + h.AssertSliceContainsInOrder(t, entry.ContainerConfig().Cmd, "-app", "/app") + h.AssertSliceContains(t, entry.ContainerConfig().Cmd, "/some/image") + } + } + }) + }) }) when("Run without using creator", func() { it("succeeds", func() { @@ -183,29 +214,40 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) { } } }) - }) + when("Run with workspace dir", func() { + it("succeeds", func() { + opts := build.LifecycleOptions{ + Publish: false, + ClearCache: false, + RunImage: "test", + Image: imageName, + Builder: fakeBuilder, + TrustBuilder: false, + Workspace: "app", + UseCreator: false, + } - when("Run with workspace dir", func() { - it("succeeds", func() { - opts := build.LifecycleOptions{ - Publish: false, - ClearCache: false, - RunImage: "test", - Image: imageName, - Builder: fakeBuilder, - TrustBuilder: false, - Workspace: "app", - UseCreator: true, - } + lifecycle, err := build.NewLifecycleExecution(logger, docker, opts) + h.AssertNil(t, err) + h.AssertEq(t, filepath.Base(lifecycle.AppDir()), "app") - lifecycle, err := build.NewLifecycleExecution(logger, docker, opts) - h.AssertNil(t, err) - h.AssertEq(t, filepath.Base(lifecycle.AppDir()), "app") + err = lifecycle.Run(context.Background(), func(execution *build.LifecycleExecution) build.PhaseFactory { + return fakePhaseFactory + }) + h.AssertNil(t, err) - err = lifecycle.Run(context.Background(), func(execution *build.LifecycleExecution) build.PhaseFactory { - return fakePhaseFactory + h.AssertEq(t, len(fakePhaseFactory.NewCalledWithProvider), 5) + + appCount := 0 + for _, entry := range fakePhaseFactory.NewCalledWithProvider { + switch entry.Name() { + case "detector", "builder", "exporter": + h.AssertSliceContainsInOrder(t, entry.ContainerConfig().Cmd, "-app", "/app") + appCount++ + } + } + h.AssertEq(t, appCount, 3) }) - h.AssertNil(t, err) }) }) diff --git a/internal/build/phase_test.go b/internal/build/phase_test.go index 6b02b95a6..3c00d8b19 100644 --- a/internal/build/phase_test.go +++ b/internal/build/phase_test.go @@ -94,7 +94,7 @@ func testPhase(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - h.AssertNil(t, lifecycleExec.Cleanup()) + h.AssertNilE(t, lifecycleExec.Cleanup()) }) when("Phase", func() { @@ -150,6 +150,7 @@ func testPhase(t *testing.T, when spec.G, it spec.S) { lifecycleExec.Builder().UID(), lifecycleExec.Builder().GID(), osType, + false, nil, ), ), @@ -167,7 +168,7 @@ func testPhase(t *testing.T, when spec.G, it spec.S) { configProvider = build.NewPhaseConfigProvider(phaseName, lifecycleExec, build.WithArgs("read", "/workspace/fake-app-file")) readPhase2 := phaseFactory.New(configProvider) err := readPhase2.Run(context.TODO()) - readPhase2.Cleanup() + h.AssertNil(t, readPhase2.Cleanup()) h.AssertNotNil(t, err) h.AssertContains(t, outBuf.String(), "failed to read file") }) @@ -212,7 +213,7 @@ func testPhase(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - h.AssertNil(t, os.RemoveAll(tmpFakeAppDir)) + h.AssertNilE(t, os.RemoveAll(tmpFakeAppDir)) }) it("returns an error", func() { @@ -225,7 +226,7 @@ func testPhase(t *testing.T, when spec.G, it spec.S) { lifecycleExec, build.WithArgs("read", "/workspace/fake-app-file"), build.WithContainerOperations( - build.CopyDir(lifecycleExec.AppPath(), "/workspace", 0, 0, osType, nil), + build.CopyDir(lifecycleExec.AppPath(), "/workspace", 0, 0, osType, false, nil), ), )) h.AssertNil(t, err) @@ -335,7 +336,7 @@ func testPhase(t *testing.T, when spec.G, it spec.S) { when("#WithBinds", func() { it.After(func() { - docker.VolumeRemove(context.TODO(), "some-volume", true) + h.AssertNilE(t, docker.VolumeRemove(context.TODO(), "some-volume", true)) }) it("mounts volumes inside container", func() { @@ -364,7 +365,7 @@ func testPhase(t *testing.T, when spec.G, it spec.S) { if registry != nil { registry.StopRegistry(t) } - h.AssertNil(t, os.Unsetenv("DOCKER_CONFIG")) + h.AssertNilE(t, os.Unsetenv("DOCKER_CONFIG")) }) it("provides auth for registry in the container", func() { @@ -437,7 +438,7 @@ func assertAppModTimePreserved(t *testing.T, lifecycle *build.LifecycleExecution lifecycle, build.WithArgs("read", "/workspace/fake-app-file"), build.WithContainerOperations( - build.CopyDir(lifecycle.AppPath(), "/workspace", 0, 0, osType, nil), + build.CopyDir(lifecycle.AppPath(), "/workspace", 0, 0, osType, false, nil), ), )) assertRunSucceeds(t, readPhase, outBuf, errBuf) diff --git a/internal/build/testdata/fake-lifecycle/phase.go b/internal/build/testdata/fake-lifecycle/phase.go index 3c75756ad..33871f428 100644 --- a/internal/build/testdata/fake-lifecycle/phase.go +++ b/internal/build/testdata/fake-lifecycle/phase.go @@ -102,7 +102,7 @@ func testRegistryAccess(repoName string) { func testRead(filename string) { fmt.Println("read test") - contents, err := ioutil.ReadFile(filename) + contents, err := ioutil.ReadFile(filepath.Clean(filename)) if err != nil { fmt.Printf("failed to read file '%s'\n", filename) os.Exit(1) diff --git a/internal/builder/builder_test.go b/internal/builder/builder_test.go index 16bb56adb..2c8f8f10c 100644 --- a/internal/builder/builder_test.go +++ b/internal/builder/builder_test.go @@ -61,7 +61,7 @@ func testBuilder(t *testing.T, when spec.G, it spec.S) { lifecycleTarReader := archive.ReadDirAsTar( filepath.Join("testdata", "lifecycle", "platform-0.4"), - ".", 0, 0, 0755, true, nil, + ".", 0, 0, 0755, true, false, nil, ) descriptorContents, err := ioutil.ReadFile(filepath.Join("testdata", "lifecycle", "platform-0.4", "lifecycle.toml")) @@ -136,7 +136,7 @@ func testBuilder(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - baseImage.Cleanup() + h.AssertNilE(t, baseImage.Cleanup()) mockController.Finish() }) @@ -266,7 +266,7 @@ func testBuilder(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - baseImage.Cleanup() + h.AssertNilE(t, baseImage.Cleanup()) }) when("#Save", func() { @@ -405,7 +405,7 @@ func testBuilder(t *testing.T, when spec.G, it spec.S) { h.AssertNil(t, err) h.AssertNil(t, baseImage.AddLayer(layerFile)) - baseImage.Save() + h.AssertNil(t, baseImage.Save()) h.AssertNil(t, subject.Save(logger, builder.CreatorMetadata{})) h.AssertEq(t, baseImage.IsSaved(), true) diff --git a/internal/buildpackage/builder.go b/internal/buildpackage/builder.go index 2de28113e..95e29a94e 100644 --- a/internal/buildpackage/builder.go +++ b/internal/buildpackage/builder.go @@ -246,7 +246,7 @@ func (b *PackageBuilder) SaveAsFile(path, imageOS string) error { tw := tar.NewWriter(outputFile) defer tw.Close() - return archive.WriteDirToTar(tw, layoutDir, "/", 0, 0, 0755, true, nil) + return archive.WriteDirToTar(tw, layoutDir, "/", 0, 0, 0755, true, false, nil) } func (b *PackageBuilder) SaveAsImage(repoName string, publish bool, imageOS string) (imgutil.Image, error) { diff --git a/internal/buildpackage/builder_test.go b/internal/buildpackage/builder_test.go index 71cec12e1..dc2db38a1 100644 --- a/internal/buildpackage/builder_test.go +++ b/internal/buildpackage/builder_test.go @@ -59,7 +59,7 @@ func testPackageBuilder(t *testing.T, when spec.G, it spec.S) { }) it.After(func() { - h.AssertNil(t, os.RemoveAll(tmpDir)) + h.AssertNilE(t, os.RemoveAll(tmpDir)) mockController.Finish() }) diff --git a/internal/commands/build.go b/internal/commands/build.go index 5ac3e713a..3a45864bc 100644 --- a/internal/commands/build.go +++ b/internal/commands/build.go @@ -219,7 +219,7 @@ func parseEnv(envFiles []string, envVars []string) (map[string]string, error) { func parseEnvFile(filename string) (map[string]string, error) { out := make(map[string]string) - f, err := ioutil.ReadFile(filename) + f, err := ioutil.ReadFile(filepath.Clean(filename)) if err != nil { return nil, errors.Wrapf(err, "open %s", filename) } diff --git a/internal/commands/report.go b/internal/commands/report.go index 7083d6696..55ac13632 100644 --- a/internal/commands/report.go +++ b/internal/commands/report.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "io/ioutil" + "path/filepath" "regexp" "runtime" "strings" @@ -56,7 +57,7 @@ Config: {{ .Config -}}`)) configData := "" - if data, err := ioutil.ReadFile(cfgPath); err != nil { + if data, err := ioutil.ReadFile(filepath.Clean(cfgPath)); err != nil { configData = fmt.Sprintf("(no config file found at %s)", cfgPath) } else { var padded strings.Builder diff --git a/internal/dist/layers.go b/internal/dist/layers.go index 514b748d0..3609ef36b 100644 --- a/internal/dist/layers.go +++ b/internal/dist/layers.go @@ -34,7 +34,7 @@ func BuildpackToLayerTar(dest string, bp Buildpack) (string, error) { } func LayerDiffID(layerTarPath string) (v1.Hash, error) { - fh, err := os.Open(layerTarPath) + fh, err := os.Open(filepath.Clean(layerTarPath)) if err != nil { return v1.Hash{}, errors.Wrap(err, "opening tar file") } diff --git a/internal/fakes/fake_package.go b/internal/fakes/fake_package.go index dd40909cf..1b6e1702e 100644 --- a/internal/fakes/fake_package.go +++ b/internal/fakes/fake_package.go @@ -4,6 +4,7 @@ import ( "errors" "io" "os" + "path/filepath" "github.com/google/go-containerregistry/pkg/v1/tarball" @@ -76,5 +77,5 @@ func (f *fakePackage) GetLayer(diffID string) (io.ReadCloser, error) { return nil, errors.New("no layer found") } - return os.Open(tarFile) + return os.Open(filepath.Clean(tarFile)) } diff --git a/internal/registry/registry_cache.go b/internal/registry/registry_cache.go index 36435b817..e317fd288 100644 --- a/internal/registry/registry_cache.go +++ b/internal/registry/registry_cache.go @@ -170,7 +170,7 @@ func (r *Cache) Initialize() error { func (r *Cache) CreateCache() error { r.logger.Debugf("Creating registry cache for %s/%s", r.url.Host, r.url.Path) - root, err := ioutil.TempDir("", "registry") + root, err := ioutil.TempDir(filepath.Dir(r.Root), "registry") if err != nil { return err } @@ -286,7 +286,7 @@ func (r *Cache) writeEntry(b Buildpack) (string, error) { } } - f, err := os.OpenFile(index, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644) + f, err := os.OpenFile(filepath.Clean(index), os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644) if err != nil { return "", errors.Wrapf(err, "creating buildpack file: %s/%s", ns, name) } @@ -320,7 +320,7 @@ func (r *Cache) readEntry(ns, name string) (Entry, error) { return Entry{}, errors.Wrapf(err, "finding buildpack: %s/%s", ns, name) } - file, err := os.Open(index) + file, err := os.Open(filepath.Clean(index)) if err != nil { return Entry{}, errors.Wrapf(err, "opening index for buildpack: %s/%s", ns, name) } diff --git a/pkg/archive/archive.go b/pkg/archive/archive.go index 2c95e4875..4ae235eae 100644 --- a/pkg/archive/archive.go +++ b/pkg/archive/archive.go @@ -42,9 +42,9 @@ func (defaultTarWriterFactory) NewWriter(w io.Writer) TarWriter { return tar.NewWriter(w) } -func ReadDirAsTar(srcDir, basePath string, uid, gid int, mode int64, normalizeModTime bool, fileFilter func(string) bool) io.ReadCloser { +func ReadDirAsTar(srcDir, basePath string, uid, gid int, mode int64, normalizeModTime, includeRoot bool, fileFilter func(string) bool) io.ReadCloser { return GenerateTar(func(tw TarWriter) error { - return WriteDirToTar(tw, srcDir, basePath, uid, gid, mode, normalizeModTime, fileFilter) + return WriteDirToTar(tw, srcDir, basePath, uid, gid, mode, normalizeModTime, includeRoot, fileFilter) }) } @@ -164,8 +164,20 @@ func ReadTarEntry(rc io.Reader, entryPath string) (*tar.Header, []byte, error) { } // WriteDirToTar writes the contents of a directory to a tar writer. `basePath` is the "location" in the tar the -// contents will be placed. -func WriteDirToTar(tw TarWriter, srcDir, basePath string, uid, gid int, mode int64, normalizeModTime bool, fileFilter func(string) bool) error { +// contents will be placed. The includeRoot param sets the permissions and metadata on the root file. +func WriteDirToTar(tw TarWriter, srcDir, basePath string, uid, gid int, mode int64, normalizeModTime, includeRoot bool, fileFilter func(string) bool) error { + if includeRoot { + rootHeader := &tar.Header{ + Typeflag: tar.TypeDir, + Name: basePath, + Mode: mode, + } + finalizeHeader(rootHeader, uid, gid, mode, normalizeModTime) + if err := tw.WriteHeader(rootHeader); err != nil { + return err + } + } + return filepath.Walk(srcDir, func(file string, fi os.FileInfo, err error) error { var relPath string if fileFilter != nil { @@ -222,7 +234,7 @@ func WriteDirToTar(tw TarWriter, srcDir, basePath string, uid, gid int, mode int } if fi.Mode().IsRegular() { - f, err := os.Open(file) + f, err := os.Open(filepath.Clean(file)) if err != nil { return err } diff --git a/pkg/archive/archive_test.go b/pkg/archive/archive_test.go index 100550e35..79d73f69f 100644 --- a/pkg/archive/archive_test.go +++ b/pkg/archive/archive_test.go @@ -55,7 +55,7 @@ func testArchive(t *testing.T, when spec.G, it spec.S) { }) it("returns a TarReader of the dir", func() { - rc := archive.ReadDirAsTar(src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, nil) + rc := archive.ReadDirAsTar(src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, false, nil) tr := tar.NewReader(rc) verify := h.NewTarVerifier(t, tr, 1234, 2345) @@ -67,9 +67,17 @@ func testArchive(t *testing.T, when spec.G, it spec.S) { h.AssertNil(t, rc.Close()) } }) + when("includeRoot", func() { + it("includes a modified root entry", func() { + rc := archive.ReadDirAsTar(src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, true, nil) + tr := tar.NewReader(rc) + verify := h.NewTarVerifier(t, tr, 1234, 2345) + verify.NextDirectory("/nested/dir/dir-in-archive", int64(os.ModePerm)) + }) + }) it("returns error if closed multiple times", func() { - rc := archive.ReadDirAsTar(src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, func(s string) bool { return false }) + rc := archive.ReadDirAsTar(src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, false, func(s string) bool { return false }) tr := tar.NewReader(rc) verify := h.NewTarVerifier(t, tr, 1234, 2345) verify.NoMoreFilesExist() @@ -189,7 +197,7 @@ func testArchive(t *testing.T, when spec.G, it spec.S) { tw := tar.NewWriter(fh) - err = archive.WriteDirToTar(tw, src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, nil) + err = archive.WriteDirToTar(tw, src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, false, nil) h.AssertNil(t, err) h.AssertNil(t, tw.Close()) h.AssertNil(t, fh.Close()) @@ -209,6 +217,29 @@ func testArchive(t *testing.T, when spec.G, it spec.S) { }) }) + when("includeRoot is true", func() { + it("sets metadata on base dest file", func() { + fh, err := os.Create(filepath.Join(tmpDir, "some.tar")) + h.AssertNil(t, err) + + tw := tar.NewWriter(fh) + + err = archive.WriteDirToTar(tw, src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, true, nil) + h.AssertNil(t, err) + h.AssertNil(t, tw.Close()) + h.AssertNil(t, fh.Close()) + + file, err := os.Open(filepath.Join(tmpDir, "some.tar")) + h.AssertNil(t, err) + defer file.Close() + + tr := tar.NewReader(file) + + verify := h.NewTarVerifier(t, tr, 1234, 2345) + verify.NextDirectory("/nested/dir/dir-in-archive", int64(os.ModePerm)) + }) + }) + when("mode is set to -1", func() { it("writes a tar to the dest dir with preexisting file mode", func() { fh, err := os.Create(filepath.Join(tmpDir, "some.tar")) @@ -216,7 +247,7 @@ func testArchive(t *testing.T, when spec.G, it spec.S) { tw := tar.NewWriter(fh) - err = archive.WriteDirToTar(tw, src, "/nested/dir/dir-in-archive", 1234, 2345, -1, true, nil) + err = archive.WriteDirToTar(tw, src, "/nested/dir/dir-in-archive", 1234, 2345, -1, true, false, nil) h.AssertNil(t, err) h.AssertNil(t, tw.Close()) h.AssertNil(t, fh.Close()) @@ -244,7 +275,7 @@ func testArchive(t *testing.T, when spec.G, it spec.S) { tw := tar.NewWriter(fh) - err = archive.WriteDirToTar(tw, src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, func(path string) bool { + err = archive.WriteDirToTar(tw, src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, false, func(path string) bool { return !strings.Contains(path, "some-file.txt") }) h.AssertNil(t, err) @@ -271,7 +302,7 @@ func testArchive(t *testing.T, when spec.G, it spec.S) { tw := tar.NewWriter(fh) - err = archive.WriteDirToTar(tw, src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, func(path string) bool { + err = archive.WriteDirToTar(tw, src, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, false, func(path string) bool { return !strings.Contains(path, "dir-to-tar") }) h.AssertNil(t, err) @@ -301,7 +332,7 @@ func testArchive(t *testing.T, when spec.G, it spec.S) { tw := tar.NewWriter(fh) - err = archive.WriteDirToTar(tw, src, "/foo", 1234, 2345, 0777, false, nil) + err = archive.WriteDirToTar(tw, src, "/foo", 1234, 2345, 0777, false, false, nil) h.AssertNil(t, err) h.AssertNil(t, tw.Close()) h.AssertNil(t, fh.Close()) @@ -320,7 +351,7 @@ func testArchive(t *testing.T, when spec.G, it spec.S) { tw := tar.NewWriter(fh) - err = archive.WriteDirToTar(tw, src, "/foo", 1234, 2345, 0777, true, nil) + err = archive.WriteDirToTar(tw, src, "/foo", 1234, 2345, 0777, true, false, nil) h.AssertNil(t, err) h.AssertNil(t, tw.Close()) h.AssertNil(t, fh.Close()) @@ -367,7 +398,7 @@ func testArchive(t *testing.T, when spec.G, it spec.S) { tw := tar.NewWriter(fh) - err = archive.WriteDirToTar(tw, tmpSrcDir, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, nil) + err = archive.WriteDirToTar(tw, tmpSrcDir, "/nested/dir/dir-in-archive", 1234, 2345, 0777, true, false, nil) h.AssertNil(t, err) h.AssertNil(t, tw.Close()) h.AssertNil(t, fh.Close()) diff --git a/project/project.go b/project/project.go index 7efa1afa7..41f6a1517 100644 --- a/project/project.go +++ b/project/project.go @@ -2,6 +2,7 @@ package project import ( "io/ioutil" + "path/filepath" "github.com/BurntSushi/toml" "github.com/pkg/errors" @@ -40,7 +41,7 @@ type Descriptor struct { } func ReadProjectDescriptor(pathToFile string) (Descriptor, error) { - projectTomlContents, err := ioutil.ReadFile(pathToFile) + projectTomlContents, err := ioutil.ReadFile(filepath.Clean(pathToFile)) if err != nil { return Descriptor{}, err } diff --git a/testhelpers/registry.go b/testhelpers/registry.go index 6bbe6615c..cd2d3efb8 100644 --- a/testhelpers/registry.go +++ b/testhelpers/registry.go @@ -43,6 +43,7 @@ func RegistryHost(host, port string) string { } func CreateRegistryFixture(t *testing.T, tmpDir, fixturePath string) string { + t.Helper() // copy fixture to temp dir registryFixtureCopy := filepath.Join(tmpDir, "registryCopy") @@ -161,7 +162,7 @@ func startRegistry(t *testing.T, runRegistryName, username, password string) (st }, &dockercontainer.HostConfig{ AutoRemove: true, PortBindings: nat.PortMap{ - "5000/tcp": []nat.PortBinding{{}}, + "5000/tcp": []nat.PortBinding{{HostPort: "0"}}, }, }, nil, nil, runRegistryName) AssertNil(t, err) diff --git a/testhelpers/tar_assertions.go b/testhelpers/tar_assertions.go index ae01d4031..2ebce6ab4 100644 --- a/testhelpers/tar_assertions.go +++ b/testhelpers/tar_assertions.go @@ -7,6 +7,7 @@ import ( "encoding/json" "io" "os" + "path/filepath" "testing" "time" @@ -22,7 +23,7 @@ type TarEntryAssertion func(t *testing.T, header *tar.Header, data []byte) func AssertOnTarEntry(t *testing.T, tarPath, entryPath string, assertFns ...TarEntryAssertion) { t.Helper() - tarFile, err := os.Open(tarPath) + tarFile, err := os.Open(filepath.Clean(tarPath)) AssertNil(t, err) defer tarFile.Close() diff --git a/testhelpers/testhelpers.go b/testhelpers/testhelpers.go index b4aa34705..d574b0ca6 100644 --- a/testhelpers/testhelpers.go +++ b/testhelpers/testhelpers.go @@ -284,7 +284,7 @@ func AssertNotNil(t *testing.T, actual interface{}) { func AssertTarball(t *testing.T, path string) { t.Helper() - f, err := os.Open(path) + f, err := os.Open(filepath.Clean(path)) AssertNil(t, err) defer f.Close() @@ -357,7 +357,7 @@ func CreateImage(t *testing.T, dockerCli client.CommonAPIClient, repoName, docke func CreateImageFromDir(t *testing.T, dockerCli client.CommonAPIClient, repoName string, dir string) { t.Helper() - buildContext := archive.ReadDirAsTar(dir, "/", 0, 0, -1, true, nil) + buildContext := archive.ReadDirAsTar(dir, "/", 0, 0, -1, true, false, nil) resp, err := dockerCli.ImageBuild(context.Background(), buildContext, dockertypes.ImageBuildOptions{ Tags: []string{repoName}, Remove: true, @@ -538,13 +538,13 @@ func CopyFileE(src, dst string) error { return err } - srcFile, err := os.Open(src) + srcFile, err := os.Open(filepath.Clean(src)) if err != nil { return err } defer srcFile.Close() - dstFile, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, fi.Mode()) + dstFile, err := os.OpenFile(filepath.Clean(dst), os.O_RDWR|os.O_CREATE|os.O_TRUNC, fi.Mode()) if err != nil { return err } @@ -684,7 +684,7 @@ func writeTAR(t *testing.T, srcDir, tarDir string, mode int64, w io.Writer) { tw := tar.NewWriter(w) defer tw.Close() - err := archive.WriteDirToTar(tw, srcDir, tarDir, 0, 0, mode, true, nil) + err := archive.WriteDirToTar(tw, srcDir, tarDir, 0, 0, mode, true, false, nil) AssertNil(t, err) } @@ -697,7 +697,7 @@ func RecursiveCopyNow(t *testing.T, src, dst string) { AssertNil(t, err) for _, fi := range fis { if fi.Mode().IsRegular() { - srcFile, err := os.Open(filepath.Join(src, fi.Name())) + srcFile, err := os.Open(filepath.Join(filepath.Clean(src), fi.Name())) AssertNil(t, err) dstFile, err := os.Create(filepath.Join(dst, fi.Name())) AssertNil(t, err) @@ -733,7 +733,7 @@ func AssertTarFileContents(t *testing.T, tarfile, path, expected string) { func tarFileContents(t *testing.T, tarfile, path string) (exist bool, contents string) { t.Helper() - r, err := os.Open(tarfile) + r, err := os.Open(filepath.Clean(tarfile)) AssertNil(t, err) defer r.Close() @@ -766,7 +766,7 @@ func AssertTarHasFile(t *testing.T, tarFile, path string) { func tarHasFile(t *testing.T, tarFile, path string) (exist bool) { t.Helper() - r, err := os.Open(tarFile) + r, err := os.Open(filepath.Clean(tarFile)) AssertNil(t, err) defer r.Close() diff --git a/tools/pedantic_imports/main.go b/tools/pedantic_imports/main.go index bd4fb61ac..15b5a2ed5 100644 --- a/tools/pedantic_imports/main.go +++ b/tools/pedantic_imports/main.go @@ -66,7 +66,7 @@ func isIgnoredDir(name string) bool { } func checkImports(path, basePackage string) ([]string, error) { - file, err := os.Open(path) + file, err := os.Open(filepath.Clean(path)) if err != nil { return nil, err }