From ae24077d2c17d5d42c844910229b742ec66b81b9 Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Mon, 22 May 2017 13:24:45 -0700 Subject: [PATCH] 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 --- content/helpers.go | 15 +++++++++++++-- remotes/handlers.go | 13 ++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/content/helpers.go b/content/helpers.go index 859de7095..3610c844f 100644 --- a/content/helpers.go +++ b/content/helpers.go @@ -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) } } diff --git a/remotes/handlers.go b/remotes/handlers.go index ec9551172..b4818863a 100644 --- a/remotes/handlers.go +++ b/remotes/handlers.go @@ -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) }