tarball/tarball_src.go
func (is *tarballImageSource) GetBlob(ctx context.Context, blobinfo types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) {
	// We should only be asked about things in the manifest.  Maybe the configuration blob.
	if blobinfo.Digest == is.configID {
		return ioutil.NopCloser(bytes.NewBuffer(is.config)), is.configSize, nil
	}
	// Maybe one of the layer blobs.
	for i := range is.blobIDs {
		if blobinfo.Digest == is.blobIDs[i] {
			// We want to read that layer: open the file or memory block and hand it back.
			if is.filenames[i] == "-" {
				return ioutil.NopCloser(bytes.NewBuffer(is.reference.stdin)), int64(len(is.reference.stdin)), nil
			}
			reader, err := os.Open(is.filenames[i])
			if err != nil {
				return nil, -1, fmt.Errorf("error opening %q: %v", is.filenames[i], err)
			}
			return reader, is.blobSizes[i], nil
		}
	}
	return nil, -1, fmt.Errorf("no blob with digest %q found", blobinfo.Digest.String())
}
func (is *tarballImageSource) GetBlob(ctx context.Context, blobinfo types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) {
	// We should only be asked about things in the manifest.  Maybe the configuration blob.
	if blobinfo.Digest == is.configID {
		return ioutil.NopCloser(bytes.NewBuffer(is.config)), is.configSize, nil
	}
	// Maybe one of the layer blobs.
	for i := range is.blobIDs {
		if blobinfo.Digest == is.blobIDs[i] {
			// We want to read that layer: open the file or memory block and hand it back.
			if is.filenames[i] == "-" {
				return ioutil.NopCloser(bytes.NewBuffer(is.reference.stdin)), int64(len(is.reference.stdin)), nil
			}
			reader, err := os.Open(is.filenames[i])
			if err != nil {
				return nil, -1, fmt.Errorf("error opening %q: %v", is.filenames[i], err)
			}
			return reader, is.blobSizes[i], nil
		}
	}
	return nil, -1, fmt.Errorf("no blob with digest %q found", blobinfo.Digest.String())
}
// GetBlob returns a stream for the specified blob, and the blob’s size (or -1 if unknown).
// The Digest field in BlobInfo is guaranteed to be provided, Size may be -1 and MediaType may be optionally provided.
// May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location.