remotes: add FetcherByDigest for fetching blobs without foreknown descriptors

Fetching blobs without foreknown descriptors is useful for using a registry as a general-purpose CAS.

Related: `oras blob fetch` (ORAS v0.15.0)

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
Akihiro Suda
2022-10-01 10:28:55 +09:00
parent c21d1baa88
commit dfd6a3aa6e
3 changed files with 135 additions and 2 deletions

View File

@@ -591,6 +591,28 @@ func testFetch(ctx context.Context, f remotes.Fetcher, desc ocispec.Descriptor)
return fmt.Errorf("content mismatch: %s != %s", dgstr.Digest(), desc.Digest)
}
fByDigest, ok := f.(remotes.FetcherByDigest)
if !ok {
return fmt.Errorf("fetcher %T does not implement FetcherByDigest", f)
}
r2, desc2, err := fByDigest.FetchByDigest(ctx, desc.Digest)
if err != nil {
return fmt.Errorf("FetcherByDigest: faild to fetch %v: %w", desc.Digest, err)
}
if desc2.Size != desc.Size {
r2b, err := io.ReadAll(r2)
if err != nil {
return fmt.Errorf("FetcherByDigest: size mismatch: %d != %d (content: %v)", desc2.Size, desc.Size, err)
}
return fmt.Errorf("FetcherByDigest: size mismatch: %d != %d (content: %q)", desc2.Size, desc.Size, string(r2b))
}
dgstr2 := desc.Digest.Algorithm().Digester()
if _, err = io.Copy(dgstr2.Hash(), r2); err != nil {
return fmt.Errorf("FetcherByDigest: faild to copy: %w", err)
}
if dgstr2.Digest() != desc.Digest {
return fmt.Errorf("FetcherByDigest: content mismatch: %s != %s", dgstr2.Digest(), desc.Digest)
}
return nil
}