builder: enhance driver factory logic when loading drivers

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
pull/1430/head
CrazyMax 2 years ago
parent e7b5ee7518
commit cc01caaecb
No known key found for this signature in database
GPG Key ID: 3248E46B6BB8C7F7

@ -4,10 +4,12 @@ import (
"context" "context"
"os" "os"
"sort" "sort"
"sync"
"github.com/docker/buildx/driver" "github.com/docker/buildx/driver"
"github.com/docker/buildx/store" "github.com/docker/buildx/store"
"github.com/docker/buildx/store/storeutil" "github.com/docker/buildx/store/storeutil"
"github.com/docker/buildx/util/dockerutil"
"github.com/docker/buildx/util/imagetools" "github.com/docker/buildx/util/imagetools"
"github.com/docker/buildx/util/progress" "github.com/docker/buildx/util/progress"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
@ -18,6 +20,7 @@ import (
// Builder represents an active builder object // Builder represents an active builder object
type Builder struct { type Builder struct {
*store.NodeGroup *store.NodeGroup
driverFactory driverFactory
nodes []Node nodes []Node
opts builderOpts opts builderOpts
err error err error
@ -201,6 +204,45 @@ func (b *Builder) Err() error {
return b.err return b.err
} }
type driverFactory struct {
driver.Factory
once sync.Once
}
// Factory returns the driver factory.
func (b *Builder) Factory(ctx context.Context) (_ driver.Factory, err error) {
b.driverFactory.once.Do(func() {
if b.Driver != "" {
b.driverFactory.Factory, err = driver.GetFactory(b.Driver, true)
if err != nil {
return
}
} else {
// empty driver means nodegroup was implicitly created as a default
// driver for a docker context and allows falling back to a
// docker-container driver for older daemon that doesn't support
// buildkit (< 18.06).
ep := b.nodes[0].Endpoint
var dockerapi *dockerutil.ClientAPI
dockerapi, err = dockerutil.NewClientAPI(b.opts.dockerCli, b.nodes[0].Endpoint)
if err != nil {
return
}
// check if endpoint is healthy is needed to determine the driver type.
// if this fails then can't continue with driver selection.
if _, err = dockerapi.Ping(ctx); err != nil {
return
}
b.driverFactory.Factory, err = driver.GetDefaultFactory(ctx, ep, dockerapi, false)
if err != nil {
return
}
b.Driver = b.driverFactory.Factory.Name()
}
})
return b.driverFactory.Factory, err
}
// GetBuilders returns all builders // GetBuilders returns all builders
func GetBuilders(dockerCli command.Cli, txn *store.Txn) ([]*Builder, error) { func GetBuilders(dockerCli command.Cli, txn *store.Txn) ([]*Builder, error) {
storeng, err := txn.List() storeng, err := txn.List()

@ -46,34 +46,10 @@ func (b *Builder) LoadNodes(ctx context.Context, withData bool) (_ []Node, err e
} }
}() }()
// TODO: factory should be lazy and a dedicated method in Builder object factory, err := b.Factory(ctx)
var factory driver.Factory
if b.NodeGroup.Driver != "" {
factory, err = driver.GetFactory(b.NodeGroup.Driver, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else {
// empty driver means nodegroup was implicitly created as a default
// driver for a docker context and allows falling back to a
// docker-container driver for older daemon that doesn't support
// buildkit (< 18.06).
ep := b.NodeGroup.Nodes[0].Endpoint
dockerapi, err := dockerutil.NewClientAPI(b.opts.dockerCli, b.NodeGroup.Nodes[0].Endpoint)
if err != nil {
return nil, err
}
// check if endpoint is healthy is needed to determine the driver type.
// if this fails then can't continue with driver selection.
if _, err = dockerapi.Ping(ctx); err != nil {
return nil, err
}
factory, err = driver.GetDefaultFactory(ctx, ep, dockerapi, false)
if err != nil {
return nil, err
}
b.NodeGroup.Driver = factory.Name()
}
imageopt, err := b.ImageOpt() imageopt, err := b.ImageOpt()
if err != nil { if err != nil {

Loading…
Cancel
Save