Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/gallery/backends.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func InstallBackend(basePath string, config *GalleryBackend, downloadStatus func
return fmt.Errorf("failed to create backend path %q: %v", backendPath, err)
}

if err := oci.ExtractOCIImage(img, backendPath); err != nil {
if err := oci.ExtractOCIImage(img, backendPath, downloadStatus); err != nil {
return fmt.Errorf("failed to extract image %q: %v", config.URI, err)
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/downloader/uri.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ func (uri URI) DownloadFile(filePath, sha string, fileN, total int, downloadStat
return fmt.Errorf("failed to get image %q: %v", url, err)
}

return oci.ExtractOCIImage(img, filepath.Dir(filePath))
return oci.ExtractOCIImage(img, filepath.Dir(filePath), downloadStatus)
}

// Check if the file already exists
Expand Down
60 changes: 57 additions & 3 deletions pkg/oci/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"net/http"
"runtime"
"strconv"
"strings"
"syscall"
"time"
Expand Down Expand Up @@ -59,11 +60,64 @@ var defaultRetryPredicate = func(err error) bool {
return false
}

type progressWriter struct {
written int64
total int64
fileName string
downloadStatus func(string, string, string, float64)
}

func formatBytes(bytes int64) string {
const unit = 1024
if bytes < unit {
return strconv.FormatInt(bytes, 10) + " B"
}
div, exp := int64(unit), 0
for n := bytes / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.1f %ciB", float64(bytes)/float64(div), "KMGTPE"[exp])
}

func (pw *progressWriter) Write(p []byte) (int, error) {
n := len(p)
pw.written += int64(n)
if pw.total > 0 {
percentage := float64(pw.written) / float64(pw.total) * 100
//log.Debug().Msgf("Downloading %s: %s/%s (%.2f%%)", pw.fileName, formatBytes(pw.written), formatBytes(pw.total), percentage)
pw.downloadStatus(pw.fileName, formatBytes(pw.written), formatBytes(pw.total), percentage)
} else {
pw.downloadStatus(pw.fileName, formatBytes(pw.written), "", 0)
}

return n, nil
}

// ExtractOCIImage will extract a given targetImage into a given targetDestination
func ExtractOCIImage(img v1.Image, targetDestination string) error {
reader := mutate.Extract(img)
func ExtractOCIImage(img v1.Image, targetDestination string, downloadStatus func(string, string, string, float64)) error {
var reader io.Reader
reader = mutate.Extract(img)

if downloadStatus != nil {
var totalSize int64
layers, err := img.Layers()
if err != nil {
return err
}
for _, layer := range layers {
size, err := layer.Size()
if err != nil {
return err
}
totalSize += size
}
reader = io.TeeReader(reader, &progressWriter{total: totalSize, downloadStatus: downloadStatus})
}

_, err := archive.Apply(context.Background(), targetDestination, reader, archive.WithNoSameOwner())
_, err := archive.Apply(context.Background(),
targetDestination, reader,
archive.WithNoSameOwner())

return err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/oci/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ var _ = Describe("OCI", func() {
Expect(err).NotTo(HaveOccurred())
defer os.RemoveAll(dir)

err = ExtractOCIImage(img, dir)
err = ExtractOCIImage(img, dir, nil)
Expect(err).NotTo(HaveOccurred())
})
})
Expand Down
Loading