From 34c7a2ff12869730701754a4e67cbf39120b1ced Mon Sep 17 00:00:00 2001 From: Marcos Lilljedahl Date: Tue, 5 Apr 2022 12:28:53 -0300 Subject: [PATCH] Automatically set target platform based on client architecture Set the default platform based on the client's OS and architecture. This function is the same one that buildkit uses (https://github.com/moby/buildkit/blob/master/frontend/dockerfile/builder/build.go#L100-L102) to set the default build target platform Signed-off-by: Marcos Lilljedahl --- client/client.go | 32 ++++++++++++++++++++++++++++++++ plan/plan.go | 2 +- plancontext/context.go | 4 +--- plancontext/platform.go | 25 ++++++++++++------------- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/client/client.go b/client/client.go index 071ea373..7d109113 100644 --- a/client/client.go +++ b/client/client.go @@ -7,12 +7,15 @@ import ( "strings" "sync" + "github.com/containerd/containerd/platforms" "github.com/google/uuid" "go.opentelemetry.io/otel/trace" "golang.org/x/sync/errgroup" "github.com/rs/zerolog/log" + specs "github.com/opencontainers/image-spec/specs-go/v1" + // Cue // buildkit @@ -78,6 +81,15 @@ func (c *Client) Do(ctx context.Context, pctx *plancontext.Context, fn DoFunc) e lg := log.Ctx(ctx) eg, gctx := errgroup.WithContext(ctx) + // if platform is set through plan config, skip detection. + if !pctx.Platform.IsSet() { + p, err := c.detectPlatform(ctx) + if err != nil { + return err + } + pctx.Platform.Set(*p) + } + // Spawn print function events := make(chan *bk.SolveStatus) eg.Go(func() error { @@ -95,6 +107,26 @@ func (c *Client) Do(ctx context.Context, pctx *plancontext.Context, fn DoFunc) e return eg.Wait() } +// detectPlatform will try to automatically Buildkit's target platform. +// If not possible, default platform will be used. +func (c *Client) detectPlatform(ctx context.Context) (*specs.Platform, error) { + w, err := c.c.ListWorkers(ctx) + if err != nil { + return nil, fmt.Errorf("error detecting platform %w", err) + } + + lg := log.Ctx(ctx) + if len(w) > 0 && len(w[0].Platforms) > 0 { + dPlatform := w[0].Platforms[0] + lg.Debug(). + Str("platform", fmt.Sprintf("%s", dPlatform)). + Msg("platform detected automatically") + return &dPlatform, nil + } + defaultPlatform := platforms.DefaultSpec() + return &defaultPlatform, nil +} + func convertCacheOptionEntries(ims []bk.CacheOptionsEntry) []bkgw.CacheOptionsEntry { convertIms := []bkgw.CacheOptionsEntry{} diff --git a/plan/plan.go b/plan/plan.go index dc4cc0df..6414e443 100644 --- a/plan/plan.go +++ b/plan/plan.go @@ -123,7 +123,7 @@ func (p *Plan) configPlatform() error { } // Set platform to context - err = p.context.Platform.Set(platform) + err = p.context.Platform.SetString(platform) if err != nil { return err } diff --git a/plancontext/context.go b/plancontext/context.go index 58f6cb79..618dd915 100644 --- a/plancontext/context.go +++ b/plancontext/context.go @@ -17,9 +17,7 @@ type Context struct { func New() *Context { return &Context{ - Platform: &platformContext{ - platform: defaultPlatform, - }, + Platform: &platformContext{}, FS: &fsContext{ store: make(map[string]*FS), }, diff --git a/plancontext/platform.go b/plancontext/platform.go index 5d12aeab..4ee46b82 100644 --- a/plancontext/platform.go +++ b/plancontext/platform.go @@ -5,28 +5,27 @@ import ( specs "github.com/opencontainers/image-spec/specs-go/v1" ) -var ( - // Default platform. - // FIXME: This should be auto detected using buildkit - defaultPlatform = specs.Platform{ - OS: "linux", - Architecture: "amd64", - } -) - type platformContext struct { - platform specs.Platform + platform *specs.Platform } func (c *platformContext) Get() specs.Platform { - return c.platform + return *c.platform } -func (c *platformContext) Set(platform string) error { +func (c *platformContext) SetString(platform string) error { p, err := platforms.Parse(platform) if err != nil { return err } - c.platform = p + c.platform = &p return nil } + +func (c *platformContext) Set(p specs.Platform) { + c.platform = &p +} + +func (c *platformContext) IsSet() bool { + return c.platform != nil +}