diff --git a/fileutil/tarball_compressor.go b/fileutil/tarball_compressor.go index f7b35c97..970de01d 100644 --- a/fileutil/tarball_compressor.go +++ b/fileutil/tarball_compressor.go @@ -1,7 +1,6 @@ package fileutil import ( - bosherr "github.com/cloudfoundry/bosh-utils/errors" boshsys "github.com/cloudfoundry/bosh-utils/system" ) @@ -21,42 +20,6 @@ func (c tarballCompressor) CompressFilesInDir(dir string) (string, error) { return c.CompressSpecificFilesInDir(dir, []string{"."}) } -func (c tarballCompressor) CompressSpecificFilesInDir(dir string, files []string) (string, error) { - tarball, err := c.fs.TempFile("bosh-platform-disk-TarballCompressor-CompressSpecificFilesInDir") - if err != nil { - return "", bosherr.WrapError(err, "Creating temporary file for tarball") - } - - tarballPath := tarball.Name() - - args := []string{"czf", tarballPath, "-C", dir} - - for _, file := range files { - args = append(args, file) - } - - _, _, _, err = c.cmdRunner.RunCommand("tar", args...) - if err != nil { - return "", bosherr.WrapError(err, "Shelling out to tar") - } - - return tarballPath, nil -} - -func (c tarballCompressor) DecompressFileToDir(tarballPath string, dir string, options CompressorOptions) error { - sameOwnerOption := "--no-same-owner" - if options.SameOwner { - sameOwnerOption = "--same-owner" - } - - _, _, _, err := c.cmdRunner.RunCommand("tar", sameOwnerOption, "-xzvf", tarballPath, "-C", dir) - if err != nil { - return bosherr.WrapError(err, "Shelling out to tar") - } - - return nil -} - func (c tarballCompressor) CleanUp(tarballPath string) error { return c.fs.RemoveAll(tarballPath) } diff --git a/fileutil/tarball_compressor_test.go b/fileutil/tarball_compressor_test.go index d17e7ea9..118f2199 100644 --- a/fileutil/tarball_compressor_test.go +++ b/fileutil/tarball_compressor_test.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "path/filepath" + "runtime" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -29,6 +30,13 @@ func fixtureSrcTgz() string { return filepath.Join(pwd, "test_assets", "compressor-decompress-file-to-dir.tgz") } +func makePathTarCompatible(path string) string { + if runtime.GOOS == "windows" { + path = strings.Replace("/"+string(path[0])+string(path[2:]), "\\", "/", -1) + } + return path +} + func createTestSymlink() (string, error) { srcDir := fixtureSrcDir() symlinkPath := filepath.Join(srcDir, "symlink_dir") @@ -112,7 +120,7 @@ var _ = Describe("tarballCompressor", func() { Expect(err).ToNot(HaveOccurred()) defer os.Remove(tgzName) - tarballContents, _, _, err := cmdRunner.RunCommand("tar", "-tf", tgzName) + tarballContents, _, _, err := cmdRunner.RunCommand("tar", "-tf", makePathTarCompatible(tgzName)) Expect(err).ToNot(HaveOccurred()) contentElements := strings.Fields(strings.TrimSpace(tarballContents)) @@ -133,7 +141,7 @@ var _ = Describe("tarballCompressor", func() { "./other_logs/more_logs/more.stdout.log", )) - _, _, _, err = cmdRunner.RunCommand("tar", "-xzpf", tgzName, "-C", dstDir) + _, _, _, err = cmdRunner.RunCommand("tar", "-xzpf", makePathTarCompatible(tgzName), "-C", makePathTarCompatible(dstDir)) Expect(err).ToNot(HaveOccurred()) content, err := fs.ReadFileString(dstDir + "/app.stdout.log") @@ -162,7 +170,7 @@ var _ = Describe("tarballCompressor", func() { Expect(err).ToNot(HaveOccurred()) defer os.Remove(tgzName) - tarballContents, _, _, err := cmdRunner.RunCommand("tar", "-tf", tgzName) + tarballContents, _, _, err := cmdRunner.RunCommand("tar", "-tf", makePathTarCompatible(tgzName)) Expect(err).ToNot(HaveOccurred()) contentElements := strings.Fields(strings.TrimSpace(tarballContents)) @@ -178,7 +186,7 @@ var _ = Describe("tarballCompressor", func() { _, _, _, err = cmdRunner.RunCommand("cp", tgzName, "/tmp") - _, _, _, err = cmdRunner.RunCommand("tar", "-xzpf", tgzName, "-C", dstDir) + _, _, _, err = cmdRunner.RunCommand("tar", "-xzpf", makePathTarCompatible(tgzName), "-C", makePathTarCompatible(dstDir)) Expect(err).ToNot(HaveOccurred()) content, err := fs.ReadFileString(dstDir + "/app.stdout.log") @@ -221,7 +229,7 @@ var _ = Describe("tarballCompressor", func() { err := compressor.DecompressFileToDir(fixtureSrcTgz(), dstDir, CompressorOptions{}) Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring(dstDir)) + Expect(err.Error()).To(ContainSubstring(makePathTarCompatible(dstDir))) }) It("uses no same owner option", func() { @@ -236,8 +244,8 @@ var _ = Describe("tarballCompressor", func() { Expect(cmdRunner.RunCommands[0]).To(Equal( []string{ "tar", "--no-same-owner", - "-xzvf", tarballPath, - "-C", dstDir, + "-xzvf", makePathTarCompatible(tarballPath), + "-C", makePathTarCompatible(dstDir), }, )) }) @@ -258,8 +266,8 @@ var _ = Describe("tarballCompressor", func() { Expect(cmdRunner.RunCommands[0]).To(Equal( []string{ "tar", "--same-owner", - "-xzvf", tarballPath, - "-C", dstDir, + "-xzvf", makePathTarCompatible(tarballPath), + "-C", makePathTarCompatible(dstDir), }, )) }) diff --git a/fileutil/tarball_compressor_unix.go b/fileutil/tarball_compressor_unix.go new file mode 100644 index 00000000..36ffba05 --- /dev/null +++ b/fileutil/tarball_compressor_unix.go @@ -0,0 +1,45 @@ +// +build !windows + +package fileutil + +import ( + bosherr "github.com/cloudfoundry/bosh-utils/errors" +) + +func (c tarballCompressor) CompressSpecificFilesInDir(dir string, files []string) (string, error) { + tarball, err := c.fs.TempFile("bosh-platform-disk-TarballCompressor-CompressSpecificFilesInDir") + if err != nil { + return "", bosherr.WrapError(err, "Creating temporary file for tarball") + } + + defer tarball.Close() + + tarballPath := tarball.Name() + + args := []string{"czf", tarballPath, "-C", dir} + + for _, file := range files { + args = append(args, file) + } + + _, _, _, err = c.cmdRunner.RunCommand("tar", args...) + if err != nil { + return "", bosherr.WrapError(err, "Shelling out to tar") + } + + return tarballPath, nil +} + +func (c tarballCompressor) DecompressFileToDir(tarballPath string, dir string, options CompressorOptions) error { + sameOwnerOption := "--no-same-owner" + if options.SameOwner { + sameOwnerOption = "--same-owner" + } + + _, _, _, err := c.cmdRunner.RunCommand("tar", sameOwnerOption, "-xzvf", tarballPath, "-C", dir) + if err != nil { + return bosherr.WrapError(err, "Shelling out to tar") + } + + return nil +} diff --git a/fileutil/tarball_compressor_windows.go b/fileutil/tarball_compressor_windows.go new file mode 100644 index 00000000..1c1de3bc --- /dev/null +++ b/fileutil/tarball_compressor_windows.go @@ -0,0 +1,79 @@ +// +build windows + +package fileutil + +import ( + "regexp" + "strings" + + bosherr "github.com/cloudfoundry/bosh-utils/errors" +) + +func (c tarballCompressor) CompressSpecificFilesInDir(dir string, files []string) (string, error) { + tarball, err := c.fs.TempFile("bosh-platform-disk-TarballCompressor-CompressSpecificFilesInDir") + if err != nil { + return "", bosherr.WrapError(err, "Creating temporary file for tarball") + } + + defer tarball.Close() + + tarballPath := tarball.Name() + + tarballPathForTar, err := makePathTarCompatible(tarballPath) + if err != nil { + return "", bosherr.WrapError(err, "Converting tarballPath path failed") + } + dir, err = makePathTarCompatible(dir) + if err != nil { + return "", bosherr.WrapError(err, "Converting dir path failed") + } + + args := []string{"czf", tarballPathForTar, "-C", dir} + + for _, file := range files { + args = append(args, file) + } + + _, _, _, err = c.cmdRunner.RunCommand("tar", args...) + if err != nil { + return "", bosherr.WrapError(err, "Shelling out to tar") + } + + return tarballPath, nil +} + +func (c tarballCompressor) DecompressFileToDir(tarballPath string, dir string, options CompressorOptions) error { + sameOwnerOption := "--no-same-owner" + if options.SameOwner { + sameOwnerOption = "--same-owner" + } + + tarballPath, err := makePathTarCompatible(tarballPath) + if err != nil { + return bosherr.WrapError(err, "Converting tarballPath path failed") + } + dir, err = makePathTarCompatible(dir) + if err != nil { + return bosherr.WrapError(err, "Converting dir path failed") + } + + _, _, _, err = c.cmdRunner.RunCommand("tar", sameOwnerOption, "-xzf", tarballPath, "-C", dir) + if err != nil { + return bosherr.WrapError(err, "Shelling out to tar") + } + + return nil +} + +func makePathTarCompatible(path string) (string, error) { + doesPathContainDrive, err := regexp.MatchString("^[a-zA-Z]:", path) + if err != nil { + return "", bosherr.WrapError(err, "Test for drive in path failed") + } + if doesPathContainDrive { + path = "/" + string(path[0]) + string(path[2:]) + } + path = strings.Replace(path, "\\", "/", -1) + + return path, nil +}