Skip to content

Commit

Permalink
Enable selecting compression on remote cache export
Browse files Browse the repository at this point in the history
Signed-off-by: Kohei Tokunaga <[email protected]>
  • Loading branch information
ktock committed Feb 28, 2022
1 parent 9ff8e77 commit c29d913
Show file tree
Hide file tree
Showing 6 changed files with 438 additions and 7 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,9 @@ buildctl build ... \
* `mode=max`: export all the layers of all intermediate steps.
* `ref=docker.io/user/image:tag`: reference
* `oci-mediatypes=true|false`: whether to use OCI mediatypes in exported manifests. Since BuildKit `v0.8` defaults to true.
* `compression=[uncompressed,gzip,estargz,zstd]`: choose compression type for layers newly created and cached, gzip is default value. estargz and zstd should be used with `oci-mediatypes=true`.
* `compression-level=[value]`: compression level for gzip, estargz (0-9) and zstd (0-22)
* `force-compression=true`: forcibly apply `compression` option to all layers.

`--import-cache` options:
* `type=registry`
Expand All @@ -380,6 +383,9 @@ The directory layout conforms to OCI Image Spec v1.0.
* `mode=max`: export all the layers of all intermediate steps.
* `dest=path/to/output-dir`: destination directory for cache exporter
* `oci-mediatypes=true|false`: whether to use OCI mediatypes in exported manifests. Since BuildKit `v0.8` defaults to true.
* `compression=[uncompressed,gzip,estargz,zstd]`: choose compression type for layers newly created and cached, gzip is default value. estargz and zstd should be used with `oci-mediatypes=true`.
* `compression-level=[value]`: compression level for gzip, estargz (0-9) and zstd (0-22)
* `force-compression=true`: forcibly apply `compression` option to all layers.

`--import-cache` options:
* `type=local`
Expand Down
19 changes: 17 additions & 2 deletions cache/remotecache/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ type Exporter interface {
Finalize(ctx context.Context) (map[string]string, error)
}

type ExporterConfig interface {
Config() Config
}

type Config struct {
Compression compression.Config
}

const (
// ExportResponseManifestDesc is a key for the map returned from Exporter.Finalize.
// The map value is a JSON string of an OCI desciptor of a manifest.
Expand All @@ -59,11 +67,18 @@ type contentCacheExporter struct {
ingester content.Ingester
oci bool
ref string
comp compression.Config
}

func NewExporter(ingester content.Ingester, ref string, oci bool) Exporter {
func NewExporter(ingester content.Ingester, ref string, oci bool, compressionConfig compression.Config) Exporter {
cc := v1.NewCacheChains()
return &contentCacheExporter{CacheExporterTarget: cc, chains: cc, ingester: ingester, oci: oci, ref: ref}
return &contentCacheExporter{CacheExporterTarget: cc, chains: cc, ingester: ingester, oci: oci, ref: ref, comp: compressionConfig}
}

func (ce *contentCacheExporter) Config() Config {
return Config{
Compression: ce.comp,
}
}

func (ce *contentCacheExporter) Finalize(ctx context.Context) (map[string]string, error) {
Expand Down
41 changes: 40 additions & 1 deletion cache/remotecache/local/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/moby/buildkit/cache/remotecache"
"github.com/moby/buildkit/session"
sessioncontent "github.com/moby/buildkit/session/content"
"github.com/moby/buildkit/util/compression"
digest "github.com/opencontainers/go-digest"
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
Expand All @@ -20,6 +21,9 @@ const (
attrDest = "dest"
attrOCIMediatypes = "oci-mediatypes"
contentStoreIDPrefix = "local:"
attrLayerCompression = "compression"
attrForceCompression = "force-compression"
attrCompressionLevel = "compression-level"
)

// ResolveCacheExporterFunc for "local" cache exporter.
Expand All @@ -29,6 +33,10 @@ func ResolveCacheExporterFunc(sm *session.Manager) remotecache.ResolveCacheExpor
if store == "" {
return nil, errors.New("local cache exporter requires dest")
}
compressionConfig, err := attrsToCompression(attrs)
if err != nil {
return nil, err
}
ociMediatypes := true
if v, ok := attrs[attrOCIMediatypes]; ok {
b, err := strconv.ParseBool(v)
Expand All @@ -42,7 +50,7 @@ func ResolveCacheExporterFunc(sm *session.Manager) remotecache.ResolveCacheExpor
if err != nil {
return nil, err
}
return remotecache.NewExporter(cs, "", ociMediatypes), nil
return remotecache.NewExporter(cs, "", ociMediatypes, *compressionConfig), nil
}
}

Expand Down Expand Up @@ -92,3 +100,34 @@ func getContentStore(ctx context.Context, sm *session.Manager, g session.Group,
}
return sessioncontent.NewCallerStore(caller, storeID), nil
}

func attrsToCompression(attrs map[string]string) (*compression.Config, error) {
compressionType := compression.Default
if v, ok := attrs[attrLayerCompression]; ok {
if c := compression.Parse(v); c != compression.UnknownCompression {
compressionType = c
}
}
compressionConfig := compression.New(compressionType)
if v, ok := attrs[attrForceCompression]; ok {
var force bool
if v == "" {
force = true
} else {
b, err := strconv.ParseBool(v)
if err != nil {
return nil, errors.Wrapf(err, "non-bool value %s specified for %s", v, attrForceCompression)
}
force = b
}
compressionConfig = compressionConfig.SetForce(force)
}
if v, ok := attrs[attrCompressionLevel]; ok {
ii, err := strconv.ParseInt(v, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "non-integer value %s specified for %s", v, attrCompressionLevel)
}
compressionConfig = compressionConfig.SetLevel(int(ii))
}
return &compressionConfig, nil
}
45 changes: 42 additions & 3 deletions cache/remotecache/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/docker/distribution/reference"
"github.com/moby/buildkit/cache/remotecache"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/util/compression"
"github.com/moby/buildkit/util/contentutil"
"github.com/moby/buildkit/util/estargz"
"github.com/moby/buildkit/util/push"
Expand All @@ -32,12 +33,19 @@ func canonicalizeRef(rawRef string) (string, error) {
}

const (
attrRef = "ref"
attrOCIMediatypes = "oci-mediatypes"
attrRef = "ref"
attrOCIMediatypes = "oci-mediatypes"
attrLayerCompression = "compression"
attrForceCompression = "force-compression"
attrCompressionLevel = "compression-level"
)

func ResolveCacheExporterFunc(sm *session.Manager, hosts docker.RegistryHosts) remotecache.ResolveCacheExporterFunc {
return func(ctx context.Context, g session.Group, attrs map[string]string) (remotecache.Exporter, error) {
compressionConfig, err := attrsToCompression(attrs)
if err != nil {
return nil, err
}
ref, err := canonicalizeRef(attrs[attrRef])
if err != nil {
return nil, err
Expand All @@ -55,7 +63,7 @@ func ResolveCacheExporterFunc(sm *session.Manager, hosts docker.RegistryHosts) r
if err != nil {
return nil, err
}
return remotecache.NewExporter(contentutil.FromPusher(pusher), ref, ociMediatypes), nil
return remotecache.NewExporter(contentutil.FromPusher(pusher), ref, ociMediatypes, *compressionConfig), nil
}
}

Expand Down Expand Up @@ -121,3 +129,34 @@ func (dsl *withDistributionSourceLabel) SnapshotLabels(descs []ocispecs.Descript
}
return labels
}

func attrsToCompression(attrs map[string]string) (*compression.Config, error) {
compressionType := compression.Default
if v, ok := attrs[attrLayerCompression]; ok {
if c := compression.Parse(v); c != compression.UnknownCompression {
compressionType = c
}
}
compressionConfig := compression.New(compressionType)
if v, ok := attrs[attrForceCompression]; ok {
var force bool
if v == "" {
force = true
} else {
b, err := strconv.ParseBool(v)
if err != nil {
return nil, errors.Wrapf(err, "non-bool value %s specified for %s", v, attrForceCompression)
}
force = b
}
compressionConfig = compressionConfig.SetForce(force)
}
if v, ok := attrs[attrCompressionLevel]; ok {
ii, err := strconv.ParseInt(v, 10, 64)
if err != nil {
return nil, errors.Wrapf(err, "non-integer value %s specified for %s", v, attrCompressionLevel)
}
compressionConfig = compressionConfig.SetLevel(int(ii))
}
return &compressionConfig, nil
}
Loading

0 comments on commit c29d913

Please sign in to comment.