mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 09:17:49 +08:00
Implement new driver-opt: default-load
This eases build driver migrations, as it allows aligning the default behavior. See also https://docs.docker.com/build/drivers/ Signed-off-by: Niklas Gehlen <niklas@namespacelabs.com>
This commit is contained in:
parent
5c29e6e26e
commit
ccc314a823
@ -169,6 +169,10 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
|
|||||||
if noMobyDriver != nil && !noDefaultLoad() && noPrintFunc(opt) {
|
if noMobyDriver != nil && !noDefaultLoad() && noPrintFunc(opt) {
|
||||||
var noOutputTargets []string
|
var noOutputTargets []string
|
||||||
for name, opt := range opt {
|
for name, opt := range opt {
|
||||||
|
if noMobyDriver.Features(ctx)[driver.DefaultLoad] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if !opt.Linked && len(opt.Exports) == 0 {
|
if !opt.Linked && len(opt.Exports) == 0 {
|
||||||
noOutputTargets = append(noOutputTargets, name)
|
noOutputTargets = append(noOutputTargets, name)
|
||||||
}
|
}
|
||||||
|
@ -162,10 +162,14 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
|
|||||||
case 1:
|
case 1:
|
||||||
// valid
|
// valid
|
||||||
case 0:
|
case 0:
|
||||||
if nodeDriver.IsMobyDriver() && !noDefaultLoad() {
|
if !noDefaultLoad() {
|
||||||
|
if nodeDriver.IsMobyDriver() {
|
||||||
// backwards compat for docker driver only:
|
// backwards compat for docker driver only:
|
||||||
// this ensures the build results in a docker image.
|
// this ensures the build results in a docker image.
|
||||||
opt.Exports = []client.ExportEntry{{Type: "image", Attrs: map[string]string{}}}
|
opt.Exports = []client.ExportEntry{{Type: "image", Attrs: map[string]string{}}}
|
||||||
|
} else if nodeDriver.Features(ctx)[driver.DefaultLoad] {
|
||||||
|
opt.Exports = []client.ExportEntry{{Type: "docker", Attrs: map[string]string{}}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if err := bopts.LLBCaps.Supports(pb.CapMultipleExporters); err != nil {
|
if err := bopts.LLBCaps.Supports(pb.CapMultipleExporters); err != nil {
|
||||||
|
@ -56,6 +56,7 @@ type Driver struct {
|
|||||||
cgroupParent string
|
cgroupParent string
|
||||||
restartPolicy container.RestartPolicy
|
restartPolicy container.RestartPolicy
|
||||||
env []string
|
env []string
|
||||||
|
defaultLoad bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) IsMobyDriver() bool {
|
func (d *Driver) IsMobyDriver() bool {
|
||||||
@ -423,6 +424,7 @@ func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
|
|||||||
driver.DockerExporter: true,
|
driver.DockerExporter: true,
|
||||||
driver.CacheExport: true,
|
driver.CacheExport: true,
|
||||||
driver.MultiPlatform: true,
|
driver.MultiPlatform: true,
|
||||||
|
driver.DefaultLoad: d.defaultLoad,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +94,11 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
case k == "default-load":
|
||||||
|
d.defaultLoad, err = strconv.ParseBool(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
case strings.HasPrefix(k, "env."):
|
case strings.HasPrefix(k, "env."):
|
||||||
envName := strings.TrimPrefix(k, "env.")
|
envName := strings.TrimPrefix(k, "env.")
|
||||||
if envName == "" {
|
if envName == "" {
|
||||||
|
@ -93,6 +93,7 @@ func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
|
|||||||
driver.DockerExporter: useContainerdSnapshotter,
|
driver.DockerExporter: useContainerdSnapshotter,
|
||||||
driver.CacheExport: useContainerdSnapshotter,
|
driver.CacheExport: useContainerdSnapshotter,
|
||||||
driver.MultiPlatform: useContainerdSnapshotter,
|
driver.MultiPlatform: useContainerdSnapshotter,
|
||||||
|
driver.DefaultLoad: true,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return d.features.list
|
return d.features.list
|
||||||
|
@ -7,3 +7,5 @@ const DockerExporter Feature = "Docker exporter"
|
|||||||
|
|
||||||
const CacheExport Feature = "Cache export"
|
const CacheExport Feature = "Cache export"
|
||||||
const MultiPlatform Feature = "Multi-platform build"
|
const MultiPlatform Feature = "Multi-platform build"
|
||||||
|
|
||||||
|
const DefaultLoad Feature = "Automatically load images to the Docker Engine image store"
|
||||||
|
@ -49,6 +49,7 @@ type Driver struct {
|
|||||||
podClient clientcorev1.PodInterface
|
podClient clientcorev1.PodInterface
|
||||||
configMapClient clientcorev1.ConfigMapInterface
|
configMapClient clientcorev1.ConfigMapInterface
|
||||||
podChooser podchooser.PodChooser
|
podChooser podchooser.PodChooser
|
||||||
|
defaultLoad bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) IsMobyDriver() bool {
|
func (d *Driver) IsMobyDriver() bool {
|
||||||
@ -229,6 +230,7 @@ func (d *Driver) Features(_ context.Context) map[driver.Feature]bool {
|
|||||||
driver.DockerExporter: d.DockerAPI != nil,
|
driver.DockerExporter: d.DockerAPI != nil,
|
||||||
driver.CacheExport: true,
|
driver.CacheExport: true,
|
||||||
driver.MultiPlatform: true, // Untested (needs multiple Driver instances)
|
driver.MultiPlatform: true, // Untested (needs multiple Driver instances)
|
||||||
|
driver.DefaultLoad: d.defaultLoad,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,11 +68,13 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
|
|||||||
clientset: clientset,
|
clientset: clientset,
|
||||||
}
|
}
|
||||||
|
|
||||||
deploymentOpt, loadbalance, namespace, err := f.processDriverOpts(deploymentName, namespace, cfg)
|
deploymentOpt, loadbalance, namespace, defaultLoad, err := f.processDriverOpts(deploymentName, namespace, cfg)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d.defaultLoad = defaultLoad
|
||||||
|
|
||||||
d.deployment, d.configMaps, err = manifest.NewDeployment(deploymentOpt)
|
d.deployment, d.configMaps, err = manifest.NewDeployment(deploymentOpt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -100,7 +102,7 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
|
|||||||
return d, nil
|
return d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg driver.InitConfig) (*manifest.DeploymentOpt, string, string, error) {
|
func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg driver.InitConfig) (*manifest.DeploymentOpt, string, string, bool, error) {
|
||||||
deploymentOpt := &manifest.DeploymentOpt{
|
deploymentOpt := &manifest.DeploymentOpt{
|
||||||
Name: deploymentName,
|
Name: deploymentName,
|
||||||
Image: bkimage.DefaultImage,
|
Image: bkimage.DefaultImage,
|
||||||
@ -111,6 +113,8 @@ func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg
|
|||||||
ConfigFiles: cfg.Files,
|
ConfigFiles: cfg.Files,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultLoad := false
|
||||||
|
|
||||||
deploymentOpt.Qemu.Image = bkimage.QemuImage
|
deploymentOpt.Qemu.Image = bkimage.QemuImage
|
||||||
|
|
||||||
loadbalance := LoadbalanceSticky
|
loadbalance := LoadbalanceSticky
|
||||||
@ -127,7 +131,7 @@ func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg
|
|||||||
case "replicas":
|
case "replicas":
|
||||||
deploymentOpt.Replicas, err = strconv.Atoi(v)
|
deploymentOpt.Replicas, err = strconv.Atoi(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", "", err
|
return nil, "", "", false, err
|
||||||
}
|
}
|
||||||
case "requests.cpu":
|
case "requests.cpu":
|
||||||
deploymentOpt.RequestsCPU = v
|
deploymentOpt.RequestsCPU = v
|
||||||
@ -140,7 +144,7 @@ func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg
|
|||||||
case "rootless":
|
case "rootless":
|
||||||
deploymentOpt.Rootless, err = strconv.ParseBool(v)
|
deploymentOpt.Rootless, err = strconv.ParseBool(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", "", err
|
return nil, "", "", false, err
|
||||||
}
|
}
|
||||||
if _, isImage := cfg.DriverOpts["image"]; !isImage {
|
if _, isImage := cfg.DriverOpts["image"]; !isImage {
|
||||||
deploymentOpt.Image = bkimage.DefaultRootlessImage
|
deploymentOpt.Image = bkimage.DefaultRootlessImage
|
||||||
@ -150,17 +154,17 @@ func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg
|
|||||||
case "nodeselector":
|
case "nodeselector":
|
||||||
deploymentOpt.NodeSelector, err = splitMultiValues(v, ",", "=")
|
deploymentOpt.NodeSelector, err = splitMultiValues(v, ",", "=")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", "", errors.Wrap(err, "cannot parse node selector")
|
return nil, "", "", false, errors.Wrap(err, "cannot parse node selector")
|
||||||
}
|
}
|
||||||
case "annotations":
|
case "annotations":
|
||||||
deploymentOpt.CustomAnnotations, err = splitMultiValues(v, ",", "=")
|
deploymentOpt.CustomAnnotations, err = splitMultiValues(v, ",", "=")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", "", errors.Wrap(err, "cannot parse annotations")
|
return nil, "", "", false, errors.Wrap(err, "cannot parse annotations")
|
||||||
}
|
}
|
||||||
case "labels":
|
case "labels":
|
||||||
deploymentOpt.CustomLabels, err = splitMultiValues(v, ",", "=")
|
deploymentOpt.CustomLabels, err = splitMultiValues(v, ",", "=")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", "", errors.Wrap(err, "cannot parse labels")
|
return nil, "", "", false, errors.Wrap(err, "cannot parse labels")
|
||||||
}
|
}
|
||||||
case "tolerations":
|
case "tolerations":
|
||||||
ts := strings.Split(v, ";")
|
ts := strings.Split(v, ";")
|
||||||
@ -185,12 +189,12 @@ func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg
|
|||||||
case "tolerationSeconds":
|
case "tolerationSeconds":
|
||||||
c, err := strconv.Atoi(kv[1])
|
c, err := strconv.Atoi(kv[1])
|
||||||
if nil != err {
|
if nil != err {
|
||||||
return nil, "", "", err
|
return nil, "", "", false, err
|
||||||
}
|
}
|
||||||
c64 := int64(c)
|
c64 := int64(c)
|
||||||
t.TolerationSeconds = &c64
|
t.TolerationSeconds = &c64
|
||||||
default:
|
default:
|
||||||
return nil, "", "", errors.Errorf("invalid tolaration %q", v)
|
return nil, "", "", false, errors.Errorf("invalid tolaration %q", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,24 +206,29 @@ func (f *factory) processDriverOpts(deploymentName string, namespace string, cfg
|
|||||||
case LoadbalanceSticky:
|
case LoadbalanceSticky:
|
||||||
case LoadbalanceRandom:
|
case LoadbalanceRandom:
|
||||||
default:
|
default:
|
||||||
return nil, "", "", errors.Errorf("invalid loadbalance %q", v)
|
return nil, "", "", false, errors.Errorf("invalid loadbalance %q", v)
|
||||||
}
|
}
|
||||||
loadbalance = v
|
loadbalance = v
|
||||||
case "qemu.install":
|
case "qemu.install":
|
||||||
deploymentOpt.Qemu.Install, err = strconv.ParseBool(v)
|
deploymentOpt.Qemu.Install, err = strconv.ParseBool(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", "", err
|
return nil, "", "", false, err
|
||||||
}
|
}
|
||||||
case "qemu.image":
|
case "qemu.image":
|
||||||
if v != "" {
|
if v != "" {
|
||||||
deploymentOpt.Qemu.Image = v
|
deploymentOpt.Qemu.Image = v
|
||||||
}
|
}
|
||||||
|
case "default-load":
|
||||||
|
defaultLoad, err = strconv.ParseBool(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", "", false, err
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return nil, "", "", errors.Errorf("invalid driver option %s for driver %s", k, DriverName)
|
return nil, "", "", false, errors.Errorf("invalid driver option %s for driver %s", k, DriverName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return deploymentOpt, loadbalance, namespace, nil
|
return deploymentOpt, loadbalance, namespace, defaultLoad, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitMultiValues(in string, itemsep string, kvsep string) (map[string]string, error) {
|
func splitMultiValues(in string, itemsep string, kvsep string) (map[string]string, error) {
|
||||||
|
@ -52,8 +52,9 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
"loadbalance": "random",
|
"loadbalance": "random",
|
||||||
"qemu.install": "true",
|
"qemu.install": "true",
|
||||||
"qemu.image": "qemu:latest",
|
"qemu.image": "qemu:latest",
|
||||||
|
"default-load": "true",
|
||||||
}
|
}
|
||||||
r, loadbalance, ns, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
r, loadbalance, ns, defaultLoad, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
|
|
||||||
nodeSelectors := map[string]string{
|
nodeSelectors := map[string]string{
|
||||||
"selector1": "value1",
|
"selector1": "value1",
|
||||||
@ -102,6 +103,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
require.Equal(t, LoadbalanceRandom, loadbalance)
|
require.Equal(t, LoadbalanceRandom, loadbalance)
|
||||||
require.True(t, r.Qemu.Install)
|
require.True(t, r.Qemu.Install)
|
||||||
require.Equal(t, "qemu:latest", r.Qemu.Image)
|
require.Equal(t, "qemu:latest", r.Qemu.Image)
|
||||||
|
require.True(t, defaultLoad)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -109,7 +111,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
"NoOptions", func(t *testing.T) {
|
"NoOptions", func(t *testing.T) {
|
||||||
cfg.DriverOpts = map[string]string{}
|
cfg.DriverOpts = map[string]string{}
|
||||||
|
|
||||||
r, loadbalance, ns, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
r, loadbalance, ns, defaultLoad, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -128,6 +130,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
require.Equal(t, LoadbalanceSticky, loadbalance)
|
require.Equal(t, LoadbalanceSticky, loadbalance)
|
||||||
require.False(t, r.Qemu.Install)
|
require.False(t, r.Qemu.Install)
|
||||||
require.Equal(t, bkimage.QemuImage, r.Qemu.Image)
|
require.Equal(t, bkimage.QemuImage, r.Qemu.Image)
|
||||||
|
require.False(t, defaultLoad)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -138,7 +141,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
"loadbalance": "sticky",
|
"loadbalance": "sticky",
|
||||||
}
|
}
|
||||||
|
|
||||||
r, loadbalance, ns, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
r, loadbalance, ns, defaultLoad, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -157,6 +160,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
require.Equal(t, LoadbalanceSticky, loadbalance)
|
require.Equal(t, LoadbalanceSticky, loadbalance)
|
||||||
require.False(t, r.Qemu.Install)
|
require.False(t, r.Qemu.Install)
|
||||||
require.Equal(t, bkimage.QemuImage, r.Qemu.Image)
|
require.Equal(t, bkimage.QemuImage, r.Qemu.Image)
|
||||||
|
require.False(t, defaultLoad)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -165,7 +169,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"replicas": "invalid",
|
"replicas": "invalid",
|
||||||
}
|
}
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -175,7 +179,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"rootless": "invalid",
|
"rootless": "invalid",
|
||||||
}
|
}
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -185,7 +189,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"tolerations": "key=foo,value=bar,invalid=foo2",
|
"tolerations": "key=foo,value=bar,invalid=foo2",
|
||||||
}
|
}
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -195,7 +199,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"tolerations": "key=foo,value=bar,tolerationSeconds=invalid",
|
"tolerations": "key=foo,value=bar,tolerationSeconds=invalid",
|
||||||
}
|
}
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -205,7 +209,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"annotations": "key,value",
|
"annotations": "key,value",
|
||||||
}
|
}
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -215,7 +219,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"labels": "key=value=foo",
|
"labels": "key=value=foo",
|
||||||
}
|
}
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -225,7 +229,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"loadbalance": "invalid",
|
"loadbalance": "invalid",
|
||||||
}
|
}
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -235,7 +239,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"qemu.install": "invalid",
|
"qemu.install": "invalid",
|
||||||
}
|
}
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -245,7 +249,7 @@ func TestFactory_processDriverOpts(t *testing.T) {
|
|||||||
cfg.DriverOpts = map[string]string{
|
cfg.DriverOpts = map[string]string{
|
||||||
"invalid": "foo",
|
"invalid": "foo",
|
||||||
}
|
}
|
||||||
_, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
_, _, _, _, err := f.processDriverOpts(cfg.Name, "test", cfg)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -24,6 +24,7 @@ type Driver struct {
|
|||||||
// if you add fields, remember to update docs:
|
// if you add fields, remember to update docs:
|
||||||
// https://github.com/docker/docs/blob/main/content/build/drivers/remote.md
|
// https://github.com/docker/docs/blob/main/content/build/drivers/remote.md
|
||||||
*tlsOpts
|
*tlsOpts
|
||||||
|
defaultLoad bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type tlsOpts struct {
|
type tlsOpts struct {
|
||||||
@ -149,6 +150,7 @@ func (d *Driver) Features(ctx context.Context) map[driver.Feature]bool {
|
|||||||
driver.DockerExporter: true,
|
driver.DockerExporter: true,
|
||||||
driver.CacheExport: true,
|
driver.CacheExport: true,
|
||||||
driver.MultiPlatform: true,
|
driver.MultiPlatform: true,
|
||||||
|
driver.DefaultLoad: d.defaultLoad,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
// import connhelpers for special url schemes
|
// import connhelpers for special url schemes
|
||||||
@ -80,6 +81,12 @@ func (f *factory) New(ctx context.Context, cfg driver.InitConfig) (driver.Driver
|
|||||||
}
|
}
|
||||||
tls.key = v
|
tls.key = v
|
||||||
tlsEnabled = true
|
tlsEnabled = true
|
||||||
|
case "default-load":
|
||||||
|
parsed, err := strconv.ParseBool(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
d.defaultLoad = parsed
|
||||||
default:
|
default:
|
||||||
return nil, errors.Errorf("invalid driver option %s for remote driver", k)
|
return nil, errors.Errorf("invalid driver option %s for remote driver", k)
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ var buildTests = []func(t *testing.T, sb integration.Sandbox){
|
|||||||
testBuildMultiExporters,
|
testBuildMultiExporters,
|
||||||
testBuildLoadPush,
|
testBuildLoadPush,
|
||||||
testBuildSecret,
|
testBuildSecret,
|
||||||
|
testBuildDefaultLoad,
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBuild(t *testing.T, sb integration.Sandbox) {
|
func testBuild(t *testing.T, sb integration.Sandbox) {
|
||||||
@ -750,6 +751,50 @@ COPY --from=build /token /
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testBuildDefaultLoad(t *testing.T, sb integration.Sandbox) {
|
||||||
|
if !isDockerWorker(sb) {
|
||||||
|
t.Skip("only testing with docker workers")
|
||||||
|
}
|
||||||
|
|
||||||
|
tag := "buildx/build:" + identity.NewID()
|
||||||
|
|
||||||
|
var builderName string
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if builderName == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := dockerCmd(sb, withArgs("image", "rm", tag))
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
require.NoError(t, cmd.Run())
|
||||||
|
|
||||||
|
out, err := rmCmd(sb, withArgs(builderName))
|
||||||
|
require.NoError(t, err, out)
|
||||||
|
})
|
||||||
|
|
||||||
|
out, err := createCmd(sb, withArgs(
|
||||||
|
"--driver", "docker-container",
|
||||||
|
"--driver-opt", "default-load=true",
|
||||||
|
))
|
||||||
|
require.NoError(t, err, out)
|
||||||
|
builderName = strings.TrimSpace(out)
|
||||||
|
|
||||||
|
dir := createTestProject(t)
|
||||||
|
|
||||||
|
cmd := buildxCmd(sb, withArgs(
|
||||||
|
"build",
|
||||||
|
fmt.Sprintf("-t=%s", tag),
|
||||||
|
dir,
|
||||||
|
))
|
||||||
|
cmd.Env = append(cmd.Env, "BUILDX_BUILDER="+builderName)
|
||||||
|
outb, err := cmd.CombinedOutput()
|
||||||
|
require.NoError(t, err, string(outb))
|
||||||
|
|
||||||
|
cmd = dockerCmd(sb, withArgs("image", "inspect", tag))
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
require.NoError(t, cmd.Run())
|
||||||
|
}
|
||||||
|
|
||||||
func createTestProject(t *testing.T) string {
|
func createTestProject(t *testing.T) string {
|
||||||
dockerfile := []byte(`
|
dockerfile := []byte(`
|
||||||
FROM busybox:latest AS base
|
FROM busybox:latest AS base
|
||||||
|
@ -64,8 +64,8 @@ func testCreateRestartAlways(t *testing.T, sb integration.Sandbox) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testCreateRemoteContainer(t *testing.T, sb integration.Sandbox) {
|
func testCreateRemoteContainer(t *testing.T, sb integration.Sandbox) {
|
||||||
if sb.Name() != "docker" {
|
if !isDockerWorker(sb) {
|
||||||
t.Skip("skipping test for non-docker workers")
|
t.Skip("only testing with docker workers")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctnBuilderName := "ctn-builder-" + identity.NewID()
|
ctnBuilderName := "ctn-builder-" + identity.NewID()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user