Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions client/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"

"github.com/moby/buildkit/client/buildid"
"github.com/moby/buildkit/frontend/attestations"
gateway "github.com/moby/buildkit/frontend/gateway/client"
"github.com/moby/buildkit/frontend/gateway/grpcclient"
gatewayapi "github.com/moby/buildkit/frontend/gateway/pb"
Expand All @@ -24,7 +23,6 @@ func (c *Client) Build(ctx context.Context, opt SolveOpt, product string, buildF
feOpts := opt.FrontendAttrs

opt.Frontend = ""
opt.FrontendAttrs = attestations.Filter(opt.FrontendAttrs)

if product == "" {
product = apicaps.ExportedProduct
Expand Down
13 changes: 7 additions & 6 deletions client/solve.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,12 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
})
}

frontendAttrs := map[string]string{}
for k, v := range opt.FrontendAttrs {
frontendAttrs[k] = v
}
for k, v := range cacheOpt.frontendAttrs {
if opt.FrontendAttrs == nil {
opt.FrontendAttrs = map[string]string{}
}
opt.FrontendAttrs[k] = v
frontendAttrs[k] = v
}

solveCtx, cancelSolve := context.WithCancel(ctx)
Expand Down Expand Up @@ -254,7 +255,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
ExporterAttrs: ex.Attrs,
Session: s.ID(),
Frontend: opt.Frontend,
FrontendAttrs: opt.FrontendAttrs,
FrontendAttrs: frontendAttrs,
FrontendInputs: frontendInputs,
Cache: cacheOpt.options,
Entitlements: opt.AllowedEntitlements,
Expand All @@ -270,7 +271,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG

if runGateway != nil {
eg.Go(func() error {
err := runGateway(ref, s, opt.FrontendAttrs)
err := runGateway(ref, s, frontendAttrs)
if err == nil {
return nil
}
Expand Down
15 changes: 13 additions & 2 deletions control/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
controlgateway "github.com/moby/buildkit/control/gateway"
"github.com/moby/buildkit/exporter"
"github.com/moby/buildkit/exporter/util/epoch"
"github.com/moby/buildkit/exporter/util/multiplatform"
"github.com/moby/buildkit/frontend"
"github.com/moby/buildkit/frontend/attestations"
"github.com/moby/buildkit/session"
Expand Down Expand Up @@ -295,12 +296,22 @@ func (c *Controller) Solve(ctx context.Context, req *controlapi.SolveRequest) (*
}

// if SOURCE_DATE_EPOCH is set, enable it for the exporter
if epochVal, ok := req.FrontendAttrs["build-arg:SOURCE_DATE_EPOCH"]; ok {
if v, ok := epoch.ParseBuildArgs(req.FrontendAttrs); ok {
if _, ok := req.ExporterAttrs[epoch.KeySourceDateEpoch]; !ok {
if req.ExporterAttrs == nil {
req.ExporterAttrs = make(map[string]string)
}
req.ExporterAttrs[epoch.KeySourceDateEpoch] = epochVal
req.ExporterAttrs[epoch.KeySourceDateEpoch] = v
}
}

// if multi-platform is set, enable it for the exporter
if v, ok := multiplatform.ParseBuildArgs(req.FrontendAttrs); ok {
if _, ok := req.ExporterAttrs[multiplatform.KeyMultiPlatform]; !ok {
if req.ExporterAttrs == nil {
req.ExporterAttrs = make(map[string]string)
}
req.ExporterAttrs[multiplatform.KeyMultiPlatform] = v
}
}

Expand Down
9 changes: 8 additions & 1 deletion exporter/containerimage/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

cacheconfig "github.com/moby/buildkit/cache/config"
"github.com/moby/buildkit/exporter/util/epoch"
"github.com/moby/buildkit/exporter/util/multiplatform"
"github.com/moby/buildkit/util/compression"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -34,6 +35,7 @@ type ImageCommitOpts struct {
BuildInfoAttrs bool
Annotations AnnotationsGroup
Epoch *time.Time
MultiPlatform *bool
}

func (c *ImageCommitOpts) Load(opt map[string]string) (map[string]string, error) {
Expand All @@ -45,7 +47,12 @@ func (c *ImageCommitOpts) Load(opt map[string]string) (map[string]string, error)
}
opt = toStringMap(optb)

c.Epoch, opt, err = epoch.ParseAttr(opt)
c.Epoch, opt, err = epoch.ParseExporterAttrs(opt)
if err != nil {
return nil, err
}

c.MultiPlatform, opt, err = multiplatform.ParseExporterAttrs(opt)
if err != nil {
return nil, err
}
Expand Down
33 changes: 30 additions & 3 deletions exporter/containerimage/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,20 @@ func (ic *ImageWriter) Commit(ctx context.Context, inp *exporter.Source, session
return nil, errors.Errorf("unable to export multiple refs, missing platforms mapping")
}

multiPlatform := len(inp.Refs) > 0

var p exptypes.Platforms
if ok && len(platformsBytes) > 0 {
if err := json.Unmarshal(platformsBytes, &p); err != nil {
return nil, errors.Wrapf(err, "failed to parse platforms passed to exporter")
}
if len(p.Platforms) > 1 {
multiPlatform = true
}
}

if opts.MultiPlatform != nil {
multiPlatform = *opts.MultiPlatform
}

if opts.Epoch == nil {
Expand All @@ -92,8 +101,26 @@ func (ic *ImageWriter) Commit(ctx context.Context, inp *exporter.Source, session
}
}

if len(inp.Refs) == 0 {
remotes, err := ic.exportLayers(ctx, opts.RefCfg, session.NewGroup(sessionID), inp.Ref)
if !multiPlatform {
if len(p.Platforms) > 1 {
return nil, errors.Errorf("cannot export multiple platforms without multi-platform enabled")
}

var ref cache.ImmutableRef
if inp.Ref != nil {
ref = inp.Ref
} else if len(p.Platforms) > 0 {
p := p.Platforms[0]
if _, ok := inp.Attestations[p.ID]; ok {
return nil, errors.Errorf("cannot export attestations without multi-platform enabled")
}
ref = inp.Refs[p.ID]
} else if len(inp.Refs) == 1 {
for _, ref = range inp.Refs {
}
}

remotes, err := ic.exportLayers(ctx, opts.RefCfg, session.NewGroup(sessionID), ref)
if err != nil {
return nil, err
}
Expand All @@ -112,7 +139,7 @@ func (ic *ImageWriter) Commit(ctx context.Context, inp *exporter.Source, session
return nil, errors.Errorf("index annotations not supported for single platform export")
}

mfstDesc, configDesc, err := ic.commitDistributionManifest(ctx, opts, inp.Ref, inp.Metadata[exptypes.ExporterImageConfigKey], &remotes[0], annotations, inp.Metadata[exptypes.ExporterInlineCache], dtbi, opts.Epoch, session.NewGroup(sessionID))
mfstDesc, configDesc, err := ic.commitDistributionManifest(ctx, opts, ref, inp.Metadata[exptypes.ExporterImageConfigKey], &remotes[0], annotations, inp.Metadata[exptypes.ExporterInlineCache], dtbi, opts.Epoch, session.NewGroup(sessionID))
if err != nil {
return nil, err
}
Expand Down
24 changes: 21 additions & 3 deletions exporter/local/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/moby/buildkit/exporter"
"github.com/moby/buildkit/exporter/containerimage/exptypes"
"github.com/moby/buildkit/exporter/util/epoch"
"github.com/moby/buildkit/exporter/util/multiplatform"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/filesync"
"github.com/moby/buildkit/solver/result"
Expand Down Expand Up @@ -41,15 +42,21 @@ func New(opt Opt) (exporter.Exporter, error) {
}

func (e *localExporter) Resolve(ctx context.Context, opt map[string]string) (exporter.ExporterInstance, error) {
tm, _, err := epoch.ParseAttr(opt)
tm, _, err := epoch.ParseExporterAttrs(opt)
if err != nil {
return nil, err
}

multiPlatform, _, err := multiplatform.ParseExporterAttrs(opt)
if err != nil {
return nil, err
}

i := &localExporterInstance{
localExporter: e,
opts: CreateFSOpts{
Epoch: tm,
Epoch: tm,
MultiPlatform: multiPlatform,
},
}

Expand Down Expand Up @@ -93,6 +100,8 @@ func (e *localExporterInstance) Export(ctx context.Context, inp *exporter.Source
return nil, err
}

isMap := len(inp.Refs) > 0

platformsBytes, ok := inp.Metadata[exptypes.ExporterPlatformsKey]
if len(inp.Refs) > 0 && !ok {
return nil, errors.Errorf("unable to export multiple refs, missing platforms mapping")
Expand All @@ -103,8 +112,17 @@ func (e *localExporterInstance) Export(ctx context.Context, inp *exporter.Source
if err := json.Unmarshal(platformsBytes, &p); err != nil {
return nil, errors.Wrapf(err, "failed to parse platforms passed to exporter")
}
if len(p.Platforms) > 1 {
isMap = true
}
}

if e.opts.MultiPlatform != nil {
isMap = *e.opts.MultiPlatform
}
if !isMap && len(p.Platforms) > 1 {
return nil, errors.Errorf("unable to export multiple platforms without map")
}
isMap := len(p.Platforms) > 1

now := time.Now().Truncate(time.Second)

Expand Down
1 change: 1 addition & 0 deletions exporter/local/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
type CreateFSOpts struct {
Epoch *time.Time
AttestationPrefix string
MultiPlatform *bool
}

func CreateFS(ctx context.Context, sessionID string, k string, ref cache.ImmutableRef, refs map[string]cache.ImmutableRef, attestations []result.Attestation, defaultTime time.Time, opt CreateFSOpts) (fsutil.FS, func() error, error) {
Expand Down
22 changes: 20 additions & 2 deletions exporter/tar/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/moby/buildkit/exporter/containerimage/exptypes"
"github.com/moby/buildkit/exporter/local"
"github.com/moby/buildkit/exporter/util/epoch"
"github.com/moby/buildkit/exporter/util/multiplatform"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/filesync"
"github.com/moby/buildkit/solver/result"
Expand Down Expand Up @@ -48,12 +49,18 @@ func New(opt Opt) (exporter.Exporter, error) {
func (e *localExporter) Resolve(ctx context.Context, opt map[string]string) (exporter.ExporterInstance, error) {
li := &localExporterInstance{localExporter: e}

tm, _, err := epoch.ParseAttr(opt)
tm, opt, err := epoch.ParseExporterAttrs(opt)
if err != nil {
return nil, err
}
li.opts.Epoch = tm

multiPlatform, opt, err := multiplatform.ParseExporterAttrs(opt)
if err != nil {
return nil, err
}
li.opts.MultiPlatform = multiPlatform

for k, v := range opt {
switch k {
case preferNondistLayersKey:
Expand Down Expand Up @@ -126,6 +133,8 @@ func (e *localExporterInstance) Export(ctx context.Context, inp *exporter.Source
}, nil
}

isMap := len(inp.Refs) > 0

platformsBytes, ok := inp.Metadata[exptypes.ExporterPlatformsKey]
if len(inp.Refs) > 0 && !ok {
return nil, errors.Errorf("unable to export multiple refs, missing platforms mapping")
Expand All @@ -136,8 +145,17 @@ func (e *localExporterInstance) Export(ctx context.Context, inp *exporter.Source
if err := json.Unmarshal(platformsBytes, &p); err != nil {
return nil, errors.Wrapf(err, "failed to parse platforms passed to exporter")
}
if len(p.Platforms) > 1 {
isMap = true
}
}

if e.opts.MultiPlatform != nil {
isMap = *e.opts.MultiPlatform
}
if !isMap && len(p.Platforms) > 1 {
return nil, errors.Errorf("unable to export multiple platforms without map")
}
isMap := len(p.Platforms) > 1

var fs fsutil.FS

Expand Down
9 changes: 8 additions & 1 deletion exporter/util/epoch/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@ import (
)

const (
frontendSourceDateEpochArg = "build-arg:SOURCE_DATE_EPOCH"

KeySourceDateEpoch = "source-date-epoch"
)

func ParseAttr(opt map[string]string) (*time.Time, map[string]string, error) {
func ParseBuildArgs(opt map[string]string) (string, bool) {
v, ok := opt[frontendSourceDateEpochArg]
return v, ok
}

func ParseExporterAttrs(opt map[string]string) (*time.Time, map[string]string, error) {
rest := make(map[string]string, len(opt))

var tm *time.Time
Expand Down
45 changes: 45 additions & 0 deletions exporter/util/multiplatform/parse.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package multiplatform

import (
"strconv"

"github.com/pkg/errors"
)

const (
frontendMultiPlatform = "multi-platform"
frontendMultiPlatformArg = "build-arg:BUILDKIT_MULTI_PLATFORM"

KeyMultiPlatform = "multi-platform"
)

func ParseBuildArgs(opt map[string]string) (string, bool) {
if v, ok := opt[frontendMultiPlatform]; ok {
return v, true
}
if v, ok := opt[frontendMultiPlatformArg]; ok {
return v, true
}
return "", false
}

func ParseExporterAttrs(opt map[string]string) (*bool, map[string]string, error) {
rest := make(map[string]string, len(opt))

var multiPlatform *bool

for k, v := range opt {
switch k {
case KeyMultiPlatform:
b, err := strconv.ParseBool(v)
if err != nil {
return nil, nil, errors.Errorf("invalid boolean value %s", v)
}
multiPlatform = &b
default:
rest[k] = v
}
}

return multiPlatform, rest, nil
}
2 changes: 1 addition & 1 deletion frontend/dockerfile/builder/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ func Build(ctx context.Context, c client.Client) (_ *client.Result, err error) {
return nil, errors.Errorf("invalid boolean value %s", v)
}
if !b && exportMap {
return nil, errors.Errorf("returning multiple target plaforms is not allowed")
return nil, errors.Errorf("returning multiple target platforms is not allowed")
}
exportMap = b
}
Expand Down