From 7c8249c331e10e4ab5b7c21fc007ee1f5c79d457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= Date: Tue, 24 Sep 2024 21:10:50 +0200 Subject: [PATCH] WIP: Add oci/layout.PutBlobFromLocalFile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WIP: For this to actually make any sense, it should be able to avoid the copy. Signed-off-by: Miloslav Trmač --- oci/layout/oci_dest.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/oci/layout/oci_dest.go b/oci/layout/oci_dest.go index 906df78a8..dae019d16 100644 --- a/oci/layout/oci_dest.go +++ b/oci/layout/oci_dest.go @@ -305,6 +305,33 @@ func (d *ociImageDestination) Commit(context.Context, types.UnparsedImage) error return os.WriteFile(d.ref.indexPath(), indexJSON, 0644) } +// PutBlobFromLocalFile arranges the data from path to be used as blob with digest. +// It computes, and returns, the digest and size of the used file. +// +// This function can be used instead of dest.PutBlob() where the ImageDestination requires PutBlob() to be called. +func PutBlobFromLocalFile(ctx context.Context, dest types.ImageDestination, file string) (digest.Digest, int64, error) { + d, ok := dest.(*ociImageDestination) + if !ok { + return "", -1, errors.New("internal error: PutBlobFromLocalFile called with a non-oci: destination") + } + + reader, err := os.Open(file) + if err != nil { + return "", -1, fmt.Errorf("opening %q: %w", file, err) + } + defer reader.Close() + + // This makes a full copy; instead, if possible, we could only digest the file and reflink (hard link?) + uploaded, err := d.PutBlobWithOptions(ctx, reader, types.BlobInfo{ + Digest: "", + Size: -1, + }, private.PutBlobOptions{}) + if err != nil { + return "", -1, err + } + return uploaded.Digest, uploaded.Size, nil +} + func ensureDirectoryExists(path string) error { if err := fileutils.Exists(path); err != nil && errors.Is(err, fs.ErrNotExist) { if err := os.MkdirAll(path, 0755); err != nil {