Avoid fetch call to registry when blob already exists
Open up content store writer with expected digest before opening up the fetch call to the registry. Add Copy method to content store helpers to allow content copy to take advantage of seeking helper code. Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
parent
a7f5c20b0f
commit
ae24077d2c
@ -41,6 +41,17 @@ func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, size i
|
||||
}
|
||||
defer cw.Close()
|
||||
|
||||
return Copy(cw, r, size, expected)
|
||||
}
|
||||
|
||||
// Copy copies data with the expected digest from the reader into the
|
||||
// provided content store writer.
|
||||
//
|
||||
// This is useful when the digest and size are known beforehand. When
|
||||
// the size or digest is unknown, these values may be empty.
|
||||
//
|
||||
// Copy is buffered, so no need to wrap reader in buffered io.
|
||||
func Copy(cw Writer, r io.Reader, size int64, expected digest.Digest) error {
|
||||
ws, err := cw.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -50,7 +61,7 @@ func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, size i
|
||||
r, err = seekReader(r, ws.Offset, size)
|
||||
if err != nil {
|
||||
if !isUnseekable(err) {
|
||||
return errors.Wrapf(err, "unabled to resume write to %v", ref)
|
||||
return errors.Wrapf(err, "unabled to resume write to %v", ws.Ref)
|
||||
}
|
||||
|
||||
// reader is unseekable, try to move the writer back to the start.
|
||||
@ -69,7 +80,7 @@ func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, size i
|
||||
|
||||
if err := cw.Commit(size, expected); err != nil {
|
||||
if !IsExists(err) {
|
||||
return errors.Wrapf(err, "failed commit on ref %q", ref)
|
||||
return errors.Wrapf(err, "failed commit on ref %q", ws.Ref)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,11 +56,22 @@ func FetchHandler(ingester content.Ingester, fetcher Fetcher) images.HandlerFunc
|
||||
func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc ocispec.Descriptor) error {
|
||||
log.G(ctx).Debug("fetch")
|
||||
ref := MakeRefKey(ctx, desc)
|
||||
|
||||
cw, err := ingester.Writer(ctx, ref, desc.Size, desc.Digest)
|
||||
if err != nil {
|
||||
if !content.IsExists(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
defer cw.Close()
|
||||
|
||||
rc, err := fetcher.Fetch(ctx, desc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
return content.WriteBlob(ctx, ingester, ref, rc, desc.Size, desc.Digest)
|
||||
return content.Copy(cw, rc, desc.Size, desc.Digest)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user