@@ -21,20 +21,20 @@ package nativeconverter
2121
2222import (
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
567567const LabelUncompressed = "containerd.io/uncompressed"
568568
569+ // GetDiffID gets the diff ID of the layer blob descriptor.
569570func 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
590617func ClearGCLabels (labels map [string ]string , dgst digest.Digest ) {
0 commit comments