diff --git a/fileutil/tarball_compressor.go b/fileutil/tarball_compressor.go index 4a789f04..3d2f4201 100644 --- a/fileutil/tarball_compressor.go +++ b/fileutil/tarball_compressor.go @@ -162,6 +162,11 @@ func (c tarballCompressor) DecompressFileToDir(tarballPath string, dir string, o } case tar.TypeReg: + directoryPath := filepath.Dir(fullName) + if err := c.fs.MkdirAll(directoryPath, fs.FileMode(0755)); err != nil { + return bosherr.WrapError(err, "Creating directory for decompressed file") + } + outFile, err := c.fs.OpenFile(fullName, os.O_CREATE|os.O_WRONLY, fs.FileMode(header.Mode)) if err != nil { return bosherr.WrapError(err, "Creating decompressed file") diff --git a/fileutil/tarball_compressor_test.go b/fileutil/tarball_compressor_test.go index c7f59a5f..e5f1869f 100644 --- a/fileutil/tarball_compressor_test.go +++ b/fileutil/tarball_compressor_test.go @@ -245,6 +245,27 @@ var _ = Describe("tarballCompressor", func() { Expect(err.Error()).To(ContainSubstring(dstDir)) }) + It("creates sub-directories even if the tarball does not have a header entry for the directory", func() { + compressor := NewTarballCompressor(fs) + + // The contents of this tarball does not contain entries for the dir/ or dir/nested-dir/ directories. The tar executable + // automatically creates these directories when extracting files listed under the directories. + tarballPath := filepath.Join(fixtureSrcDir(), filepath.FromSlash("../compressor-decompress-missing-directory-header.tgz")) + err := compressor.DecompressFileToDir(tarballPath, dstDir, CompressorOptions{}) + Expect(err).ToNot(HaveOccurred()) + + dstElements, err := pathsInDir(dstDir) + Expect(err).ToNot(HaveOccurred()) + Expect(dstElements).To(Equal([]string{ + "./", + "dir/", + "dir/file1", + "dir/file2", + "dir/nested-dir/", + "dir/nested-dir/file3", + })) + }) + Context("with tarball contents owned by root", func() { var ( diff --git a/fileutil/test_assets/compressor-decompress-missing-directory-header.tgz b/fileutil/test_assets/compressor-decompress-missing-directory-header.tgz new file mode 100644 index 00000000..50130f99 Binary files /dev/null and b/fileutil/test_assets/compressor-decompress-missing-directory-header.tgz differ