// copyContent attempts to load and serve the provided blob. If req != nil and writer is an instance of http.ResponseWriter, // response headers will be set and range requests honored. func (pbs *pullthroughBlobStore) copyContent(store distribution.BlobStore, ctx context.Context, dgst digest.Digest, writer io.Writer, req *http.Request) (distribution.Descriptor, error) { desc, err := store.Stat(ctx, dgst) if err != nil { return distribution.Descriptor{}, err } remoteReader, err := store.Open(ctx, dgst) if err != nil { return distribution.Descriptor{}, err } rw, ok := writer.(http.ResponseWriter) if ok { setResponseHeaders(rw, desc.Size, desc.MediaType, dgst) // serve range requests if req != nil { http.ServeContent(rw, req, desc.Digest.String(), time.Time{}, remoteReader) return desc, nil } } if _, err = io.CopyN(writer, remoteReader, desc.Size); err != nil { return distribution.Descriptor{}, err } return desc, nil }
func pushLayer(ctx context.Context, address, imageDir string, blobs distribution.BlobStore) (descriptor distribution.Descriptor, err error) { fmt.Printf("push layer: %s", address) layer, err := os.Open(filepath.Join(imageDir, address, "layer.tar")) if err != nil { log.Printf("Error reading embedded tar: %v", err) return } defer layer.Close() stat, err := layer.Stat() digester := digest.Canonical.New() bar := pb.New(int(stat.Size())).SetUnits(pb.U_BYTES) bar.Start() writer, err := blobs.Create(ctx) if err != nil { log.Printf("Error creating blob writer: %v", err) return } _, err = io.Copy(io.MultiWriter(writer, bar, digester.Hash()), layer) if err != nil { log.Printf("Error copying to blob writer: %v", err) return } descriptor, err = writer.Commit(ctx, distribution.Descriptor{ Digest: digester.Digest(), }) if err != nil { log.Printf("Error commiting blob writer: %v", err) return } bar.Finish() return }