@@ -17,6 +17,7 @@ import (
1717 "github.com/DataDog/rules_oci/go/internal/tarutil"
1818 "github.com/DataDog/rules_oci/go/pkg/layer"
1919 "github.com/DataDog/rules_oci/go/pkg/ociutil"
20+ "github.com/klauspost/compress/zstd"
2021 "github.com/opencontainers/go-digest"
2122 ocispec "github.com/opencontainers/image-spec/specs-go/v1"
2223 "github.com/urfave/cli/v2"
@@ -35,11 +36,32 @@ func CreateLayerCmd(c *cli.Context) error {
3536
3637 digester := digest .SHA256 .Digester ()
3738 wc := ociutil .NewWriterCounter (io .MultiWriter (out , digester .Hash ()))
38- gw := gzip .NewWriter (wc )
39- gw .Name = path .Base (out .Name ())
40- defer gw .Close ()
4139
42- tw := tar .NewWriter (gw )
40+ var compressWriter io.Writer
41+ var compressCloser io.Closer
42+ var mediaType string
43+ switch config .CompressionMethod {
44+ case "gzip" :
45+ gzipWriter := gzip .NewWriter (wc )
46+ gzipWriter .Name = path .Base (out .Name ())
47+ compressWriter = gzipWriter
48+ compressCloser = gzipWriter
49+ mediaType = ocispec .MediaTypeImageLayerGzip
50+ case "zstd" :
51+ zstdWriter , err := zstd .NewWriter (wc ,
52+ zstd .WithEncoderLevel (zstd .SpeedBestCompression ))
53+ if err != nil {
54+ return err
55+ }
56+ compressWriter = zstdWriter
57+ compressCloser = zstdWriter
58+ mediaType = ocispec .MediaTypeImageLayerZstd
59+ default :
60+ return fmt .Errorf ("uknown compress method %s" , config .CompressionMethod )
61+ }
62+ defer compressCloser .Close ()
63+
64+ tw := tar .NewWriter (compressWriter )
4365 defer tw .Close ()
4466
4567 slices .Sort (config .Files )
@@ -139,11 +161,12 @@ func CreateLayerCmd(c *cli.Context) error {
139161 // Need to flush before we count bytes and digest, might as well close since
140162 // it's not needed anymore.
141163 tw .Close ()
142- gw .Close ()
164+ compressCloser .Close ()
165+ out .Close ()
143166
144167 desc := ocispec.Descriptor {
145168 Digest : digester .Digest (),
146- MediaType : ocispec . MediaTypeImageLayerGzip ,
169+ MediaType : mediaType ,
147170 Size : int64 (wc .Count ()),
148171 }
149172
@@ -164,15 +187,16 @@ func CreateLayerCmd(c *cli.Context) error {
164187}
165188
166189type createLayerConfig struct {
167- BazelLabel string `json:"bazel-label" toml:"bazel-label" yaml:"bazel-label"`
168- Descriptor string `json:"outd" toml:"outd" yaml:"outd"`
169- Directory string `json:"dir" toml:"dir" yaml:"dir"`
170- FileMapping map [string ]string `json:"file-map" toml:"file-map" yaml:"file-map"`
171- Files []string `json:"file" toml:"file" yaml:"file"`
172- ModeMapping map [string ]int64 `json:"mode-map" toml:"mode-map" yaml:"mode-map"`
173- OutputLayer string `json:"out" toml:"out" yaml:"out"`
174- OwnerMapping map [string ]string `json:"owner-map" toml:"owner-map" yaml:"owner-map"`
175- SymlinkMapping map [string ]string `json:"symlink" toml:"symlink" yaml:"symlink"`
190+ BazelLabel string `json:"bazel-label" toml:"bazel-label" yaml:"bazel-label"`
191+ Descriptor string `json:"outd" toml:"outd" yaml:"outd"`
192+ Directory string `json:"dir" toml:"dir" yaml:"dir"`
193+ FileMapping map [string ]string `json:"file-map" toml:"file-map" yaml:"file-map"`
194+ Files []string `json:"file" toml:"file" yaml:"file"`
195+ ModeMapping map [string ]int64 `json:"mode-map" toml:"mode-map" yaml:"mode-map"`
196+ OutputLayer string `json:"out" toml:"out" yaml:"out"`
197+ OwnerMapping map [string ]string `json:"owner-map" toml:"owner-map" yaml:"owner-map"`
198+ SymlinkMapping map [string ]string `json:"symlink" toml:"symlink" yaml:"symlink"`
199+ CompressionMethod string `json:"compression-method" toml:"compression-method" yaml:"compression-method"`
176200}
177201
178202func newCreateLayerConfig (c * cli.Context ) (* createLayerConfig , error ) {
@@ -184,16 +208,23 @@ func newCreateLayerConfig(c *cli.Context) (*createLayerConfig, error) {
184208 }
185209 modeMapping [path ] = mode
186210 }
211+
212+ compressionMethod := c .String ("compression-method" )
213+ if compressionMethod == "" {
214+ compressionMethod = "gzip"
215+ }
216+
187217 return & createLayerConfig {
188- BazelLabel : c .String ("bazel-label" ),
189- Descriptor : c .String ("outd" ),
190- Directory : c .String ("dir" ),
191- FileMapping : c .Generic ("file-map" ).(* flagutil.KeyValueFlag ).Map ,
192- Files : c .StringSlice ("file" ),
193- ModeMapping : modeMapping ,
194- OutputLayer : c .String ("out" ),
195- OwnerMapping : c .Generic ("owner-map" ).(* flagutil.KeyValueFlag ).Map ,
196- SymlinkMapping : c .Generic ("symlink" ).(* flagutil.KeyValueFlag ).Map ,
218+ BazelLabel : c .String ("bazel-label" ),
219+ Descriptor : c .String ("outd" ),
220+ Directory : c .String ("dir" ),
221+ FileMapping : c .Generic ("file-map" ).(* flagutil.KeyValueFlag ).Map ,
222+ Files : c .StringSlice ("file" ),
223+ ModeMapping : modeMapping ,
224+ OutputLayer : c .String ("out" ),
225+ OwnerMapping : c .Generic ("owner-map" ).(* flagutil.KeyValueFlag ).Map ,
226+ SymlinkMapping : c .Generic ("symlink" ).(* flagutil.KeyValueFlag ).Map ,
227+ CompressionMethod : compressionMethod ,
197228 }, nil
198229}
199230
0 commit comments