diff --git a/api/server/router/build/build.go b/api/server/router/build/build.go index 8ad89ac2b7..75ae8f0ada 100644 --- a/api/server/router/build/build.go +++ b/api/server/router/build/build.go @@ -1,6 +1,8 @@ package build // import "github.com/docker/docker/api/server/router/build" import ( + "runtime" + "github.com/docker/docker/api/server/router" "github.com/docker/docker/api/types" ) @@ -37,17 +39,24 @@ func (r *buildRouter) initRoutes() { } } -// BuilderVersion derives the default docker builder version from the config -// Note: it is valid to have BuilderVersion unset which means it is up to the -// client to choose which builder to use. +// BuilderVersion derives the default docker builder version from the config. +// +// The default on Linux is version "2" (BuildKit), but the daemon can be +// configured to recommend version "1" (classic Builder). Windows does not +// yet support BuildKit for native Windows images, and uses "1" (classic builder) +// as a default. +// +// This value is only a recommendation as advertised by the daemon, and it is +// up to the client to choose which builder to use. func BuilderVersion(features map[string]bool) types.BuilderVersion { - var bv types.BuilderVersion - if v, ok := features["buildkit"]; ok { - if v { - bv = types.BuilderBuildKit - } else { - bv = types.BuilderV1 - } + // TODO(thaJeztah) move the default to daemon/config + if runtime.GOOS == "windows" { + return types.BuilderV1 + } + + bv := types.BuilderBuildKit + if v, ok := features["buildkit"]; ok && !v { + bv = types.BuilderV1 } return bv } diff --git a/api/swagger.yaml b/api/swagger.yaml index a53130a92a..181c80a418 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -8786,7 +8786,17 @@ paths: description: "Max API Version the server supports" Builder-Version: type: "string" - description: "Default version of docker image builder" + description: | + Default version of docker image builder + + The default on Linux is version "2" (BuildKit), but the daemon + can be configured to recommend version "1" (classic Builder). + Windows does not yet support BuildKit for native Windows images, + and uses "1" (classic builder) as a default. + + This value is a recommendation as advertised by the daemon, and + it is up to the client to choose which builder to use. + default: "2" Docker-Experimental: type: "boolean" description: "If the server is running with experimental mode enabled" diff --git a/docs/api/version-history.md b/docs/api/version-history.md index 36482c5479..fb1db32f9c 100644 --- a/docs/api/version-history.md +++ b/docs/api/version-history.md @@ -59,6 +59,18 @@ keywords: "API, Docker, rcli, REST, documentation" if they are not set. * `GET /info` now omits the `KernelMemory` and `KernelMemoryTCP` if they are not supported by the host or host's configuration (if cgroups v2 are in use). +* `GET /_ping` and `HEAD /_ping` now return `Builder-Version` by default. + This header contains the default builder to use, and is a recommendation as + advertised by the daemon. However, it is up to the client to choose which builder + to use. + + The default value on Linux is version "2" (BuildKit), but the daemon can be + configured to recommend version "1" (classic Builder). Windows does not yet + support BuildKit for native Windows images, and uses "1" (classic builder) as + a default. + + This change is not versioned, and affects all API versions if the daemon has + this patch. * `GET /_ping` and `HEAD /_ping` now return a `Swarm` header, which allows a client to detect if Swarm is enabled on the daemon, without having to call additional endpoints. diff --git a/integration/system/ping_test.go b/integration/system/ping_test.go index 6de5f535f1..239049e094 100644 --- a/integration/system/ping_test.go +++ b/integration/system/ping_test.go @@ -3,9 +3,13 @@ package system // import "github.com/docker/docker/integration/system" import ( "context" "net/http" + "os" + "path/filepath" + "runtime" "strings" "testing" + "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/versions" "github.com/docker/docker/testutil/daemon" @@ -93,6 +97,44 @@ func TestPingSwarmHeader(t *testing.T) { }) } +func TestPingBuilderHeader(t *testing.T) { + skip.If(t, testEnv.IsRemoteDaemon) + skip.If(t, testEnv.DaemonInfo.OSType == "windows", "cannot spin up additional daemons on windows") + + defer setupTest(t)() + d := daemon.New(t) + client := d.NewClientT(t) + defer client.Close() + ctx := context.TODO() + + t.Run("default config", func(t *testing.T) { + d.Start(t) + defer d.Stop(t) + + var expected = types.BuilderBuildKit + if runtime.GOOS == "windows" { + expected = types.BuilderV1 + } + + p, err := client.Ping(ctx) + assert.NilError(t, err) + assert.Equal(t, p.BuilderVersion, expected) + }) + + t.Run("buildkit disabled", func(t *testing.T) { + cfg := filepath.Join(d.RootDir(), "daemon.json") + err := os.WriteFile(cfg, []byte(`{"features": { "buildkit": false }}`), 0644) + assert.NilError(t, err) + d.Start(t, "--config-file", cfg) + defer d.Stop(t) + + var expected = types.BuilderV1 + p, err := client.Ping(ctx) + assert.NilError(t, err) + assert.Equal(t, p.BuilderVersion, expected) + }) +} + func hdr(res *http.Response, name string) string { val, ok := res.Header[http.CanonicalHeaderKey(name)] if !ok || len(val) == 0 {