func (s *ostreeImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) {

	blob := info.Digest.Hex()

	// Ensure s.compressed is initialized.  It is build by LayerInfosForCopy.
	if s.compressed == nil {
		_, err := s.LayerInfosForCopy(ctx)
		if err != nil {
			return nil, -1, err
		}

	}
	compressedBlob, found := s.compressed[info.Digest]
	if found {
		blob = compressedBlob.Hex()
	}
	branch := fmt.Sprintf("ociimage/%s", blob)

	if s.repo == nil {
		repo, err := openRepo(s.ref.repo)
		if err != nil {
			return nil, 0, err
		}
		s.repo = repo
	}

	layerSize, err := s.getLayerSize(blob)
	if err != nil {
		return nil, 0, err
	}

	tarsplit, err := s.getTarSplitData(blob)
	if err != nil {
		return nil, 0, err
	}

	// if tarsplit is nil we are looking at the manifest.  Return directly the file in /content
	if tarsplit == nil {
		file, err := s.readSingleFile(branch, "/content")
		if err != nil {
			return nil, 0, err
		}
		return file, layerSize, nil
	}

	mf := bytes.NewReader(tarsplit)
	mfz, err := pgzip.NewReader(mf)
	if err != nil {
		return nil, 0, err
	}
	metaUnpacker := storage.NewJSONUnpacker(mfz)

	getter, err := newOSTreePathFileGetter(s.repo, branch)
	if err != nil {
		mfz.Close()
		return nil, 0, err
	}

	ots := asm.NewOutputTarStream(getter, metaUnpacker)

	rc := ioutils.NewReadCloserWrapper(ots, func() error {
		getter.Close()
		mfz.Close()
		return ots.Close()
	})
	return rc, layerSize, nil
}
func (s *ostreeImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) {

	blob := info.Digest.Hex()

	
	if s.compressed == nil {
		_, err := s.LayerInfosForCopy(ctx)
		if err != nil {
			return nil, -1, err
		}

	}
	compressedBlob, found := s.compressed[info.Digest]
	if found {
		blob = compressedBlob.Hex()
	}
	branch := fmt.Sprintf("ociimage/%s", blob)

	if s.repo == nil {
		repo, err := openRepo(s.ref.repo)
		if err != nil {
			return nil, 0, err
		}
		s.repo = repo
	}

	layerSize, err := s.getLayerSize(blob)
	if err != nil {
		return nil, 0, err
	}

	tarsplit, err := s.getTarSplitData(blob)
	if err != nil {
		return nil, 0, err
	}

	
	if tarsplit == nil {
		file, err := s.readSingleFile(branch, "/content")
		if err != nil {
			return nil, 0, err
		}
		return file, layerSize, nil
	}

	mf := bytes.NewReader(tarsplit)
	mfz, err := pgzip.NewReader(mf)
	if err != nil {
		return nil, 0, err
	}
	metaUnpacker := storage.NewJSONUnpacker(mfz)

	getter, err := newOSTreePathFileGetter(s.repo, branch)
	if err != nil {
		mfz.Close()
		return nil, 0, err
	}

	ots := asm.NewOutputTarStream(getter, metaUnpacker)

	rc := ioutils.NewReadCloserWrapper(ots, func() error {
		getter.Close()
		mfz.Close()
		return ots.Close()
	})
	return rc, layerSize, nil
}
func ( s * ostreeImageSource ) GetBlob ( ctx context . Context , info types . BlobInfo , cache types . BlobInfoCache ) ( io . ReadCloser , int64 , error ) { blob := info . Digest . Hex ( ) // Ensure s.compressed is initialized.  It is build by LayerInfosForCopy. if s . compressed == nil { _ , err := s . LayerInfosForCopy ( ctx ) if err != nil { return nil , - 1 , err } } compressedBlob , found := s . compressed [ info . Digest ] if found { blob = compressedBlob . Hex ( ) } branch := fmt . Sprintf ( " " , blob ) if s . repo == nil { repo , err := openRepo ( s . ref . repo ) if err != nil { return nil , 0 , err } s . repo = repo } layerSize , err := s . getLayerSize ( blob ) if err != nil { return nil , 0 , err } tarsplit , err := s . getTarSplitData ( blob ) if err != nil { return nil , 0 , err } // if tarsplit is nil we are looking at the manifest.  Return directly the file in /content if tarsplit == nil { file , err := s . readSingleFile ( branch , " " ) if err != nil { return nil , 0 , err } return file , layerSize , nil } mf := bytes . NewReader ( tarsplit ) mfz , err := pgzip . NewReader ( mf ) if err != nil { return nil , 0 , err } metaUnpacker := storage . NewJSONUnpacker ( mfz ) getter , err := newOSTreePathFileGetter ( s . repo , branch ) if err != nil { mfz . Close ( ) return nil , 0 , err } ots := asm . NewOutputTarStream ( getter , metaUnpacker ) rc := ioutils . NewReadCloserWrapper ( ots , func ( ) error { getter . Close ( ) mfz . Close ( ) return ots . Close ( ) } ) return rc , layerSize , nil }
// 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.
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 .