From 75b80c277faa1cbe6672c5ffb51848776f39ad87 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Wed, 31 Jul 2019 17:25:25 -0700 Subject: [PATCH 1/3] driver: allow setting driver opts Signed-off-by: Tonis Tiigi --- commands/create.go | 29 ++++++++++++++++++++++++++++- commands/util.go | 4 ++-- driver/manager.go | 5 +++-- store/nodegroup.go | 4 +++- store/nodegroup_test.go | 8 ++++---- 5 files changed, 40 insertions(+), 10 deletions(-) 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") From bcc882cbf134cabb4ea5e154bff0aa8e90a5398c Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Wed, 31 Jul 2019 17:42:49 -0700 Subject: [PATCH 2/3] docker-container: allow using host network Signed-off-by: Tonis Tiigi --- driver/docker-container/driver.go | 9 +++++++-- driver/docker-container/factory.go | 14 +++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/driver/docker-container/driver.go b/driver/docker-container/driver.go index 99207f01..ecdd7199 100644 --- a/driver/docker-container/driver.go +++ b/driver/docker-container/driver.go @@ -27,6 +27,7 @@ var buildkitImage = "moby/buildkit:master" // TODO: make this verified and confi type Driver struct { driver.InitConfig factory driver.Factory + netMode string } func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error { @@ -70,9 +71,13 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error { } if err := l.Wrap("creating container "+d.Name, func() error { - _, err := d.DockerAPI.ContainerCreate(ctx, cfg, &container.HostConfig{ + hc := &container.HostConfig{ Privileged: true, - }, &network.NetworkingConfig{}, d.Name) + } + if d.netMode != "" { + hc.NetworkMode = container.NetworkMode(d.netMode) + } + _, err := d.DockerAPI.ContainerCreate(ctx, cfg, hc, &network.NetworkingConfig{}, d.Name) if err != nil { return err } diff --git a/driver/docker-container/factory.go b/driver/docker-container/factory.go index 16b7c15c..37db8268 100644 --- a/driver/docker-container/factory.go +++ b/driver/docker-container/factory.go @@ -37,8 +37,20 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver if cfg.DockerAPI == nil { return nil, errors.Errorf("%s driver requires docker API access", f.Name()) } + d := &Driver{factory: f, InitConfig: cfg} + for k, v := range cfg.DriverOpts { + switch k { + case "network": + d.netMode = v + if v == "host" { + d.InitConfig.BuildkitFlags = append(d.InitConfig.BuildkitFlags, "--allow-insecure-entitlement=network.host") + } + default: + return nil, errors.Errorf("invalid driver option %s for docker-container driver") + } + } - return &Driver{factory: f, InitConfig: cfg}, nil + return d, nil } func (f *factory) AllowsInstances() bool { From afd821010dc8774635dac39c374978ecea901e79 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Wed, 31 Jul 2019 18:19:03 -0700 Subject: [PATCH 3/3] docker-container: allow setting custom buildkit image Signed-off-by: Tonis Tiigi --- driver/docker-container/driver.go | 13 +++++++++---- driver/docker-container/factory.go | 4 +++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/driver/docker-container/driver.go b/driver/docker-container/driver.go index ecdd7199..38be74a4 100644 --- a/driver/docker-container/driver.go +++ b/driver/docker-container/driver.go @@ -22,12 +22,13 @@ import ( "github.com/pkg/errors" ) -var buildkitImage = "moby/buildkit:master" // TODO: make this verified and configuratble +var defaultBuildkitImage = "moby/buildkit:buildx-stable-1" // TODO: make this verified type Driver struct { driver.InitConfig factory driver.Factory netMode string + image string } func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error { @@ -52,8 +53,12 @@ func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error { } func (d *Driver) create(ctx context.Context, l progress.SubLogger) error { - if err := l.Wrap("pulling image "+buildkitImage, func() error { - rc, err := d.DockerAPI.ImageCreate(ctx, buildkitImage, types.ImageCreateOptions{}) + imageName := defaultBuildkitImage + if d.image != "" { + imageName = d.image + } + if err := l.Wrap("pulling image "+imageName, func() error { + rc, err := d.DockerAPI.ImageCreate(ctx, imageName, types.ImageCreateOptions{}) if err != nil { return err } @@ -64,7 +69,7 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error { } cfg := &container.Config{ - Image: buildkitImage, + Image: imageName, } if d.InitConfig.BuildkitFlags != nil { cfg.Cmd = d.InitConfig.BuildkitFlags diff --git a/driver/docker-container/factory.go b/driver/docker-container/factory.go index 37db8268..0b6c7968 100644 --- a/driver/docker-container/factory.go +++ b/driver/docker-container/factory.go @@ -45,8 +45,10 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver if v == "host" { d.InitConfig.BuildkitFlags = append(d.InitConfig.BuildkitFlags, "--allow-insecure-entitlement=network.host") } + case "image": + d.image = v default: - return nil, errors.Errorf("invalid driver option %s for docker-container driver") + return nil, errors.Errorf("invalid driver option %s for docker-container driver", k) } }