diff --git a/commands/create.go b/commands/create.go index 7526391d..bada4cac 100644 --- a/commands/create.go +++ b/commands/create.go @@ -1,8 +1,10 @@ package commands import ( + "encoding/csv" "fmt" "os" + "strings" "github.com/docker/buildx/driver" "github.com/docker/buildx/store" @@ -25,6 +27,7 @@ type createOptions struct { use bool flags string configFile string + driverOpts []string // upgrade bool // perform upgrade of the driver } @@ -139,7 +142,11 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error { return err } } - if err := ng.Update(in.nodeName, ep, in.platform, len(args) > 0, in.actionAppend, flags, in.configFile); err != nil { + m, err := csvToMap(in.driverOpts) + if err != nil { + return err + } + if err := ng.Update(in.nodeName, ep, in.platform, len(args) > 0, in.actionAppend, flags, in.configFile, m); err != nil { return err } } @@ -187,6 +194,7 @@ func createCmd(dockerCli command.Cli) *cobra.Command { flags.StringVar(&options.flags, "buildkitd-flags", "", "Flags for buildkitd daemon") flags.StringVar(&options.configFile, "config", "", "BuildKit config file") flags.StringArrayVar(&options.platform, "platform", []string{}, "Fixed platforms for current node") + flags.StringArrayVar(&options.driverOpts, "driver-opt", []string{}, "Options for the driver") flags.BoolVar(&options.actionAppend, "append", false, "Append a node to builder instead of changing it") flags.BoolVar(&options.actionLeave, "leave", false, "Remove a node from builder instead of changing it") @@ -196,3 +204,22 @@ func createCmd(dockerCli command.Cli) *cobra.Command { return cmd } + +func csvToMap(in []string) (map[string]string, error) { + m := make(map[string]string, len(in)) + for _, s := range in { + csvReader := csv.NewReader(strings.NewReader(s)) + fields, err := csvReader.Read() + if err != nil { + return nil, err + } + for _, v := range fields { + p := strings.SplitN(v, "=", 2) + if len(p) != 2 { + return nil, errors.Errorf("invalid value %q, expecting k=v", v) + } + m[p[0]] = p[1] + } + } + return m, nil +} diff --git a/commands/util.go b/commands/util.go index 37956770..be38bbce 100644 --- a/commands/util.go +++ b/commands/util.go @@ -174,7 +174,7 @@ func driversForNodeGroup(ctx context.Context, dockerCli command.Cli, ng *store.N // TODO: replace the following line with dockerclient.WithAPIVersionNegotiation option in clientForEndpoint dockerapi.NegotiateAPIVersion(ctx) - d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, f, dockerapi, n.Flags, n.ConfigFile) + d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, f, dockerapi, n.Flags, n.ConfigFile, n.DriverOpts) if err != nil { di.Err = err return nil @@ -251,7 +251,7 @@ func getDefaultDrivers(ctx context.Context, dockerCli command.Cli) ([]build.Driv return driversForNodeGroup(ctx, dockerCli, ng) } - d, err := driver.GetDriver(ctx, "buildx_buildkit_default", nil, dockerCli.Client(), nil, "") + d, err := driver.GetDriver(ctx, "buildx_buildkit_default", nil, dockerCli.Client(), nil, "", nil) if err != nil { return nil, err } diff --git a/driver/manager.go b/driver/manager.go index ba1bfa7b..8ddf7821 100644 --- a/driver/manager.go +++ b/driver/manager.go @@ -27,7 +27,7 @@ type InitConfig struct { DockerAPI dockerclient.APIClient BuildkitFlags []string ConfigFile string - Meta map[string]interface{} + DriverOpts map[string]string } var drivers map[string]Factory @@ -72,12 +72,13 @@ func GetFactory(name string, instanceRequired bool) Factory { return nil } -func GetDriver(ctx context.Context, name string, f Factory, api dockerclient.APIClient, flags []string, config string) (Driver, error) { +func GetDriver(ctx context.Context, name string, f Factory, api dockerclient.APIClient, flags []string, config string, do map[string]string) (Driver, error) { ic := InitConfig{ DockerAPI: api, Name: name, BuildkitFlags: flags, ConfigFile: config, + DriverOpts: do, } if f == nil { var err error diff --git a/store/nodegroup.go b/store/nodegroup.go index 41743ad6..04f8be82 100644 --- a/store/nodegroup.go +++ b/store/nodegroup.go @@ -21,6 +21,7 @@ type Node struct { Platforms []specs.Platform Flags []string ConfigFile string + DriverOpts map[string]string } func (ng *NodeGroup) Leave(name string) error { @@ -35,7 +36,7 @@ func (ng *NodeGroup) Leave(name string) error { return nil } -func (ng *NodeGroup) Update(name, endpoint string, platforms []string, endpointsSet bool, actionAppend bool, flags []string, configFile string) error { +func (ng *NodeGroup) Update(name, endpoint string, platforms []string, endpointsSet bool, actionAppend bool, flags []string, configFile string, do map[string]string) error { i := ng.findNode(name) if i == -1 && !actionAppend { if len(ng.Nodes) > 0 { @@ -82,6 +83,7 @@ func (ng *NodeGroup) Update(name, endpoint string, platforms []string, endpoints Platforms: pp, ConfigFile: configFile, Flags: flags, + DriverOpts: do, } ng.Nodes = append(ng.Nodes, n) diff --git a/store/nodegroup_test.go b/store/nodegroup_test.go index e7b9325a..cdcfc77d 100644 --- a/store/nodegroup_test.go +++ b/store/nodegroup_test.go @@ -11,16 +11,16 @@ func TestNodeGroupUpdate(t *testing.T) { t.Parallel() ng := &NodeGroup{} - err := ng.Update("foo", "foo0", []string{"linux/amd64"}, true, false, []string{"--debug"}, "") + err := ng.Update("foo", "foo0", []string{"linux/amd64"}, true, false, []string{"--debug"}, "", nil) require.NoError(t, err) - err = ng.Update("foo1", "foo1", []string{"linux/arm64", "linux/arm/v7"}, true, true, nil, "") + err = ng.Update("foo1", "foo1", []string{"linux/arm64", "linux/arm/v7"}, true, true, nil, "", nil) require.NoError(t, err) require.Equal(t, len(ng.Nodes), 2) // update - err = ng.Update("foo", "foo2", []string{"linux/amd64", "linux/arm"}, true, false, nil, "") + err = ng.Update("foo", "foo2", []string{"linux/amd64", "linux/arm"}, true, false, nil, "", nil) require.NoError(t, err) require.Equal(t, len(ng.Nodes), 2) @@ -32,7 +32,7 @@ func TestNodeGroupUpdate(t *testing.T) { require.Equal(t, []string(nil), ng.Nodes[1].Flags) // duplicate endpoint - err = ng.Update("foo1", "foo2", nil, true, false, nil, "") + err = ng.Update("foo1", "foo2", nil, true, false, nil, "", nil) require.Error(t, err) require.Contains(t, err.Error(), "duplicate endpoint")