podman
87 строк · 2.0 Кб
1package compression2
3import (4"io"5"io/fs"6"os"7"runtime"8
9"github.com/containers/image/v5/pkg/compression"10"github.com/sirupsen/logrus"11)
12
13type genericDecompressor struct {14compressedFilePath string15compressedFile *os.File16compressedFileInfo os.FileInfo17}
18
19func newGenericDecompressor(compressedFilePath string) (*genericDecompressor, error) {20d := &genericDecompressor{}21d.compressedFilePath = compressedFilePath22stat, err := os.Stat(d.compressedFilePath)23if err != nil {24return nil, err25}26d.compressedFileInfo = stat27return d, nil28}
29
30func (d *genericDecompressor) compressedFileSize() int64 {31return d.compressedFileInfo.Size()32}
33
34func (d *genericDecompressor) compressedFileMode() fs.FileMode {35return d.compressedFileInfo.Mode()36}
37
38func (d *genericDecompressor) compressedFileReader() (io.ReadCloser, error) {39compressedFile, err := os.Open(d.compressedFilePath)40if err != nil {41return nil, err42}43d.compressedFile = compressedFile44return compressedFile, nil45}
46
47func (d *genericDecompressor) decompress(w io.WriteSeeker, r io.Reader) error {48decompressedFileReader, _, err := compression.AutoDecompress(r)49if err != nil {50return err51}52defer func() {53if err := decompressedFileReader.Close(); err != nil {54logrus.Errorf("Unable to close gz file: %q", err)55}56}()57
58// Use sparse-optimized copy for macOS as applehv,59// macOS native hypervisor, uses large raw VM disk60// files mostly empty (~2GB of content ~8GB empty).61if runtime.GOOS == macOs {62err = d.sparseOptimizedCopy(w, decompressedFileReader)63} else {64_, err = io.Copy(w, decompressedFileReader)65}66
67return err68}
69
70func (d *genericDecompressor) close() {71if err := d.compressedFile.Close(); err != nil {72logrus.Errorf("Unable to close compressed file: %q", err)73}74}
75
76func (d *genericDecompressor) sparseOptimizedCopy(w io.WriteSeeker, r io.Reader) error {77var err error78sparseWriter := NewSparseWriter(w)79defer func() {80e := sparseWriter.Close()81if e != nil && err == nil {82err = e83}84}()85_, err = io.Copy(sparseWriter, r)86return err87}
88