Skip to content

Commit b33d982

Browse files
committed
nativeconverter.GetDiffID: support unpacked blobs
blobs without `containerd.io/uncompressed` labels were not supported Signed-off-by: Akihiro Suda <[email protected]>
1 parent 835c6e3 commit b33d982

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

nativeconverter/nativeconverter.go

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,20 @@ package nativeconverter
2121

2222
import (
2323
"bytes"
24+
"compress/gzip"
2425
"context"
2526
"encoding/json"
2627
"fmt"
28+
"io"
2729
"strings"
2830
"sync"
2931

3032
"github.com/containerd/containerd"
3133
"github.com/containerd/containerd/content"
32-
"github.com/containerd/containerd/errdefs"
3334
"github.com/containerd/containerd/images"
3435
"github.com/containerd/containerd/platforms"
3536
"github.com/opencontainers/go-digest"
3637
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
37-
"github.com/pkg/errors"
3838
"github.com/sirupsen/logrus"
3939
"golang.org/x/sync/errgroup"
4040
)
@@ -566,9 +566,11 @@ func ConvertDockerMediaTypeToOCI(mt string) string {
566566

567567
const LabelUncompressed = "containerd.io/uncompressed"
568568

569+
// GetDiffID gets the diff ID of the layer blob descriptor.
569570
func GetDiffID(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (digest.Digest, error) {
570571
switch desc.MediaType {
571572
case
573+
// If the layer is already uncompressed, we can just return its digest
572574
images.MediaTypeDockerSchema2Layer,
573575
ocispec.MediaTypeImageLayer,
574576
images.MediaTypeDockerSchema2LayerForeign,
@@ -580,11 +582,36 @@ func GetDiffID(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (
580582
return "", err
581583
}
582584
v, ok := info.Labels[LabelUncompressed]
583-
if !ok {
584-
return "", errors.Wrapf(errdefs.ErrNotFound, "content %s does not have label %q",
585-
desc.Digest.String(), LabelUncompressed)
585+
if ok {
586+
// Fast path: if the image is already unpacked, we can use the label value
587+
return digest.Parse(v)
586588
}
587-
return digest.Parse(v)
589+
// if the image is not unpacked, we may not have the label
590+
ra, err := cs.ReaderAt(ctx, desc)
591+
if err != nil {
592+
return "", err
593+
}
594+
defer ra.Close()
595+
r := content.NewReader(ra)
596+
gzR, err := gzip.NewReader(r)
597+
if err != nil {
598+
return "", err
599+
}
600+
digester := digest.Canonical.Digester()
601+
hashW := digester.Hash()
602+
if _, err := io.Copy(hashW, gzR); err != nil {
603+
return "", err
604+
}
605+
if err := ra.Close(); err != nil {
606+
return "", err
607+
}
608+
digest := digester.Digest()
609+
// memorize the computed value
610+
info.Labels[LabelUncompressed] = digest.String()
611+
if _, err := cs.Update(ctx, info, "labels"); err != nil {
612+
logrus.WithError(err).Warnf("failed to set %s label for %s", LabelUncompressed, desc.Digest)
613+
}
614+
return digest, nil
588615
}
589616

590617
func ClearGCLabels(labels map[string]string, dgst digest.Digest) {

0 commit comments

Comments
 (0)