From de5beb06b314eb4950c5a0de8183dfadb325fc8b Mon Sep 17 00:00:00 2001 From: Blake Mizerany Date: Fri, 24 May 2024 08:40:40 -0700 Subject: [PATCH] server: skip blob verification for already verified blobs --- server/download.go | 12 ++++++------ server/images.go | 20 ++++++++++++-------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/server/download.go b/server/download.go index 937b6754..d93cd3b4 100644 --- a/server/download.go +++ b/server/download.go @@ -340,17 +340,17 @@ type downloadOpts struct { } // downloadBlob downloads a blob from the registry and stores it in the blobs directory -func downloadBlob(ctx context.Context, opts downloadOpts) error { +func downloadBlob(ctx context.Context, opts downloadOpts) (cacheHit bool, _ error) { fp, err := GetBlobsPath(opts.digest) if err != nil { - return err + return false, err } fi, err := os.Stat(fp) switch { case errors.Is(err, os.ErrNotExist): case err != nil: - return err + return false, err default: opts.fn(api.ProgressResponse{ Status: fmt.Sprintf("pulling %s", opts.digest[7:19]), @@ -359,7 +359,7 @@ func downloadBlob(ctx context.Context, opts downloadOpts) error { Completed: fi.Size(), }) - return nil + return true, nil } data, ok := blobDownloadManager.LoadOrStore(opts.digest, &blobDownload{Name: fp, Digest: opts.digest}) @@ -369,12 +369,12 @@ func downloadBlob(ctx context.Context, opts downloadOpts) error { requestURL = requestURL.JoinPath("v2", opts.mp.GetNamespaceRepository(), "blobs", opts.digest) if err := download.Prepare(ctx, requestURL, opts.regOpts); err != nil { blobDownloadManager.Delete(opts.digest) - return err + return false, err } //nolint:contextcheck go download.Run(context.Background(), requestURL, opts.regOpts) } - return download.Wait(ctx, opts.fn) + return false, download.Wait(ctx, opts.fn) } diff --git a/server/images.go b/server/images.go index c0fdec59..529f7b6a 100644 --- a/server/images.go +++ b/server/images.go @@ -853,23 +853,27 @@ func PullModel(ctx context.Context, name string, regOpts *registryOptions, fn fu layers = append(layers, manifest.Layers...) layers = append(layers, manifest.Config) + skipVerify := make(map[string]bool) for _, layer := range layers { - if err := downloadBlob( - ctx, - downloadOpts{ - mp: mp, - digest: layer.Digest, - regOpts: regOpts, - fn: fn, - }); err != nil { + cacheHit, err := downloadBlob(ctx, downloadOpts{ + mp: mp, + digest: layer.Digest, + regOpts: regOpts, + fn: fn, + }) + if err != nil { return err } + skipVerify[layer.Digest] = cacheHit delete(deleteMap, layer.Digest) } delete(deleteMap, manifest.Config.Digest) fn(api.ProgressResponse{Status: "verifying sha256 digest"}) for _, layer := range layers { + if skipVerify[layer.Digest] { + continue + } if err := verifyBlob(layer.Digest); err != nil { if errors.Is(err, errDigestMismatch) { // something went wrong, delete the blob