diff --git a/pkg/machine/compression/decompress.go b/pkg/machine/compression/decompress.go index 3aa8f3dccb..fb37d99b13 100644 --- a/pkg/machine/compression/decompress.go +++ b/pkg/machine/compression/decompress.go @@ -61,12 +61,12 @@ func newDecompressor(compressedFilePath string, compressedFileContent []byte) (d return newZipDecompressor(compressedFilePath) case compressionType == archive.Uncompressed: return newUncompressedDecompressor(compressedFilePath) - // macOS gzipped VM images are sparse. As a result a - // special decompressor is required: it uses crc os.CopySparse - // instead of io.Copy and std lib gzip instead of klauspost/pgzip - // (even if it's slower). + // Using special compressors on MacOS because default ones + // in c/image/pkg/compression are slow with sparse files. case compressionType == archive.Gzip && os == macOs: return newGzipDecompressor(compressedFilePath) + case compressionType == archive.Zstd && os == macOs: + return newZstdDecompressor(compressedFilePath) default: return newGenericDecompressor(compressedFilePath) } diff --git a/pkg/machine/compression/uncompressed.go b/pkg/machine/compression/uncompressed.go index 847c59d343..03ebfb4a41 100644 --- a/pkg/machine/compression/uncompressed.go +++ b/pkg/machine/compression/uncompressed.go @@ -2,8 +2,6 @@ package compression import ( "io" - - crcOs "github.com/crc-org/crc/v2/pkg/os" ) type uncompressedDecompressor struct { @@ -15,7 +13,8 @@ func newUncompressedDecompressor(compressedFilePath string) (*uncompressedDecomp return &uncompressedDecompressor{*d}, err } -func (*uncompressedDecompressor) decompress(w WriteSeekCloser, r io.Reader) error { - _, err := crcOs.CopySparse(w, r) +func (d *uncompressedDecompressor) decompress(w WriteSeekCloser, r io.Reader) error { + sparseWriter := NewSparseWriter(w) + _, err := io.Copy(sparseWriter, r) return err } diff --git a/pkg/machine/compression/zstd.go b/pkg/machine/compression/zstd.go new file mode 100644 index 0000000000..bf234961ea --- /dev/null +++ b/pkg/machine/compression/zstd.go @@ -0,0 +1,34 @@ +package compression + +import ( + "io" + + "github.com/klauspost/compress/zstd" +) + +type zstdDecompressor struct { + genericDecompressor + zstdReader *zstd.Decoder +} + +func newZstdDecompressor(compressedFilePath string) (*zstdDecompressor, error) { + d, err := newGenericDecompressor(compressedFilePath) + return &zstdDecompressor{*d, nil}, err +} + +func (d *zstdDecompressor) decompress(w WriteSeekCloser, r io.Reader) error { + zstdReader, err := zstd.NewReader(r) + if err != nil { + return err + } + d.zstdReader = zstdReader + + sparseWriter := NewSparseWriter(w) + _, err = io.Copy(sparseWriter, zstdReader) + return err +} + +func (d *zstdDecompressor) close() { + d.zstdReader.Close() + d.genericDecompressor.close() +}