MCPcopy Create free account
hub / github.com/containers/image / copyLayerFromStream

Method copyLayerFromStream

copy/single.go:936–965  ·  view source on GitHub ↗

copyLayerFromStream is an implementation detail of copyLayer; mostly providing a separate “defer” scope. it copies a blob with srcInfo (with known Digest and Annotations and possibly known Size) from srcStream to dest, perhaps (de/re/)compressing the stream, and returns a complete blobInfo of the co

(ctx context.Context, srcStream io.Reader, srcInfo types.BlobInfo,
	diffIDIsNeeded bool, toEncrypt bool, bar *progressBar, layerIndex int, emptyLayer bool)

Source from the content-addressed store, hash-verified

934// perhaps (de/re/)compressing the stream,
935// and returns a complete blobInfo of the copied blob and perhaps a <-chan diffIDResult if diffIDIsNeeded, to be read by the caller.
936func (ic *imageCopier) copyLayerFromStream(ctx context.Context, srcStream io.Reader, srcInfo types.BlobInfo,
937 diffIDIsNeeded bool, toEncrypt bool, bar *progressBar, layerIndex int, emptyLayer bool) (types.BlobInfo, <-chan diffIDResult, error) {
938 var getDiffIDRecorder func(compressiontypes.DecompressorFunc) io.Writer // = nil
939 var diffIDChan chan diffIDResult
940
941 err := errors.New("Internal error: unexpected panic in copyLayer") // For pipeWriter.CloseWithbelow
942 if diffIDIsNeeded {
943 diffIDChan = make(chan diffIDResult, 1) // Buffered, so that sending a value after this or our caller has failed and exited does not block.
944 pipeReader, pipeWriter := io.Pipe()
945 defer func() { // Note that this is not the same as {defer pipeWriter.CloseWithError(err)}; we need err to be evaluated lazily.
946 _ = pipeWriter.CloseWithError(err) // CloseWithError(nil) is equivalent to Close(), always returns nil
947 }()
948
949 getDiffIDRecorder = func(decompressor compressiontypes.DecompressorFunc) io.Writer {
950 // If this fails, e.g. because we have exited and due to pipeWriter.CloseWithError() above further
951 // reading from the pipe has failed, we don’t really care.
952 // We only read from diffIDChan if the rest of the flow has succeeded, and when we do read from it,
953 // the return value includes an error indication, which we do check.
954 //
955 // If this gets never called, pipeReader will not be used anywhere, but pipeWriter will only be
956 // closed above, so we are happy enough with both pipeReader and pipeWriter to just get collected by GC.
957 go diffIDComputationGoroutine(diffIDChan, pipeReader, decompressor) // Closes pipeReader
958 return pipeWriter
959 }
960 }
961
962 blobInfo, err := ic.copyBlobFromStream(ctx, srcStream, srcInfo, getDiffIDRecorder, false, toEncrypt, bar, layerIndex, emptyLayer) // Sets err to nil on success
963 return blobInfo, diffIDChan, err
964 // We need the defer … pipeWriter.CloseWithError() to happen HERE so that the caller can block on reading from diffIDChan
965}
966
967// diffIDComputationGoroutine reads all input from layerStream, uncompresses using decompressor if necessary, and sends its digest, and status, if any, to dest.
968func diffIDComputationGoroutine(dest chan<- diffIDResult, layerStream io.ReadCloser, decompressor compressiontypes.DecompressorFunc) {

Callers 1

copyLayerMethod · 0.95

Calls 2

copyBlobFromStreamMethod · 0.95

Tested by

no test coverage detected