File: stream_digest.go

package info (click to toggle)
golang-github-containers-image 5.28.0-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 5,104 kB
  • sloc: sh: 194; makefile: 73
file content (40 lines) | stat: -rw-r--r-- 1,371 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package streamdigest

import (
	"fmt"
	"io"
	"os"

	"github.com/containers/image/v5/internal/putblobdigest"
	"github.com/containers/image/v5/internal/tmpdir"
	"github.com/containers/image/v5/types"
)

// ComputeBlobInfo streams a blob to a temporary file and populates Digest and Size in inputInfo.
// The temporary file is returned as an io.Reader along with a cleanup function.
// It is the caller's responsibility to call the cleanup function, which closes and removes the temporary file.
// If an error occurs, inputInfo is not modified.
func ComputeBlobInfo(sys *types.SystemContext, stream io.Reader, inputInfo *types.BlobInfo) (io.Reader, func(), error) {
	diskBlob, err := tmpdir.CreateBigFileTemp(sys, "stream-blob")
	if err != nil {
		return nil, nil, fmt.Errorf("creating temporary on-disk layer: %w", err)
	}
	cleanup := func() {
		diskBlob.Close()
		os.Remove(diskBlob.Name())
	}
	digester, stream := putblobdigest.DigestIfCanonicalUnknown(stream, *inputInfo)
	written, err := io.Copy(diskBlob, stream)
	if err != nil {
		cleanup()
		return nil, nil, fmt.Errorf("writing to temporary on-disk layer: %w", err)
	}
	_, err = diskBlob.Seek(0, io.SeekStart)
	if err != nil {
		cleanup()
		return nil, nil, fmt.Errorf("rewinding temporary on-disk layer: %w", err)
	}
	inputInfo.Digest = digester.Digest()
	inputInfo.Size = written
	return diskBlob, cleanup, nil
}