diff --git a/pkg/archive/compression/compression.go b/pkg/archive/compression/compression.go index e5c0a18b9..cba5e477c 100644 --- a/pkg/archive/compression/compression.go +++ b/pkg/archive/compression/compression.go @@ -45,6 +45,8 @@ const ( Gzip // Zstd is zstd compression algorithm. Zstd + // Unknown is used when a plugin handles the algorithm. + Unknown ) const ( @@ -257,6 +259,8 @@ func (compression *Compression) Extension() string { return "gz" case Zstd: return "zst" + case Unknown: + return "unknown" } return "" } diff --git a/plugins/diff/walking/differ.go b/plugins/diff/walking/differ.go index 92080b157..304355213 100644 --- a/plugins/diff/walking/differ.go +++ b/plugins/diff/walking/differ.go @@ -25,6 +25,11 @@ import ( "io" "time" + "github.com/containerd/errdefs" + "github.com/containerd/log" + digest "github.com/opencontainers/go-digest" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/containerd/containerd/v2/core/content" "github.com/containerd/containerd/v2/core/diff" "github.com/containerd/containerd/v2/core/mount" @@ -32,10 +37,6 @@ import ( "github.com/containerd/containerd/v2/pkg/archive/compression" "github.com/containerd/containerd/v2/pkg/epoch" "github.com/containerd/containerd/v2/pkg/labels" - "github.com/containerd/errdefs" - "github.com/containerd/log" - digest "github.com/opencontainers/go-digest" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) type walkingDiff struct { @@ -74,12 +75,12 @@ func (s *walkingDiff) Compare(ctx context.Context, lower, upper []mount.Mount, o writeDiffOpts = append(writeDiffOpts, archive.WithSourceDateEpoch(config.SourceDateEpoch)) } - var isCompressed bool + compressionType := compression.Uncompressed if config.Compressor != nil { if config.MediaType == "" { return emptyDesc, errors.New("media type must be explicitly specified when using custom compressor") } - isCompressed = true + compressionType = compression.Unknown } else { if config.MediaType == "" { config.MediaType = ocispec.MediaTypeImageLayerGzip @@ -88,7 +89,9 @@ func (s *walkingDiff) Compare(ctx context.Context, lower, upper []mount.Mount, o switch config.MediaType { case ocispec.MediaTypeImageLayer: case ocispec.MediaTypeImageLayerGzip: - isCompressed = true + compressionType = compression.Gzip + case ocispec.MediaTypeImageLayerZstd: + compressionType = compression.Zstd default: return emptyDesc, fmt.Errorf("unsupported diff media type: %v: %w", config.MediaType, errdefs.ErrNotImplemented) } @@ -131,7 +134,7 @@ func (s *walkingDiff) Compare(ctx context.Context, lower, upper []mount.Mount, o } } - if isCompressed { + if compressionType != compression.Uncompressed { dgstr := digest.SHA256.Digester() var compressed io.WriteCloser if config.Compressor != nil { @@ -140,7 +143,7 @@ func (s *walkingDiff) Compare(ctx context.Context, lower, upper []mount.Mount, o return fmt.Errorf("failed to get compressed stream: %w", errOpen) } } else { - compressed, errOpen = compression.CompressStream(cw, compression.Gzip) + compressed, errOpen = compression.CompressStream(cw, compressionType) if errOpen != nil { return fmt.Errorf("failed to get compressed stream: %w", errOpen) } diff --git a/plugins/diff/windows/windows.go b/plugins/diff/windows/windows.go index 35bd9efa8..3424615ea 100644 --- a/plugins/diff/windows/windows.go +++ b/plugins/diff/windows/windows.go @@ -28,6 +28,14 @@ import ( "time" "github.com/Microsoft/go-winio" + "github.com/containerd/errdefs" + "github.com/containerd/log" + "github.com/containerd/platforms" + "github.com/containerd/plugin" + "github.com/containerd/plugin/registry" + "github.com/opencontainers/go-digest" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/containerd/containerd/v2/core/content" "github.com/containerd/containerd/v2/core/diff" "github.com/containerd/containerd/v2/core/metadata" @@ -37,13 +45,6 @@ import ( "github.com/containerd/containerd/v2/pkg/epoch" "github.com/containerd/containerd/v2/pkg/labels" "github.com/containerd/containerd/v2/plugins" - "github.com/containerd/errdefs" - "github.com/containerd/log" - "github.com/containerd/platforms" - "github.com/containerd/plugin" - "github.com/containerd/plugin/registry" - "github.com/opencontainers/go-digest" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) func init() { @@ -197,11 +198,13 @@ func (s windowsDiff) Compare(ctx context.Context, lower, upper []mount.Mount, op config.MediaType = ocispec.MediaTypeImageLayerGzip } - var isCompressed bool + compressionType := compression.Uncompressed switch config.MediaType { case ocispec.MediaTypeImageLayer: case ocispec.MediaTypeImageLayerGzip: - isCompressed = true + compressionType = compression.Gzip + case ocispec.MediaTypeImageLayerZstd: + compressionType = compression.Zstd default: return emptyDesc, fmt.Errorf("unsupported diff media type: %v: %w", config.MediaType, errdefs.ErrNotImplemented) } @@ -245,10 +248,10 @@ func (s windowsDiff) Compare(ctx context.Context, lower, upper []mount.Mount, op return emptyDesc, err } - if isCompressed { + if compressionType != compression.Uncompressed { dgstr := digest.SHA256.Digester() var compressed io.WriteCloser - compressed, err = compression.CompressStream(cw, compression.Gzip) + compressed, err = compression.CompressStream(cw, compressionType) if err != nil { return emptyDesc, fmt.Errorf("failed to get compressed stream: %w", err) }