Browse Source

Merge pull request #43657 from thaJeztah/default_builder_version

api: set default "Builder-Version" to "2" (BuildKit) on Linux
Sebastiaan van Stijn 2 years ago
parent
commit
a4ac991d02
4 changed files with 84 additions and 11 deletions
  1. 19 10
      api/server/router/build/build.go
  2. 11 1
      api/swagger.yaml
  3. 12 0
      docs/api/version-history.md
  4. 42 0
      integration/system/ping_test.go

+ 19 - 10
api/server/router/build/build.go

@@ -1,6 +1,8 @@
 package build // import "github.com/docker/docker/api/server/router/build"
 package build // import "github.com/docker/docker/api/server/router/build"
 
 
 import (
 import (
+	"runtime"
+
 	"github.com/docker/docker/api/server/router"
 	"github.com/docker/docker/api/server/router"
 	"github.com/docker/docker/api/types"
 	"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 {
 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
 	return bv
 }
 }

+ 11 - 1
api/swagger.yaml

@@ -8786,7 +8786,17 @@ paths:
               description: "Max API Version the server supports"
               description: "Max API Version the server supports"
             Builder-Version:
             Builder-Version:
               type: "string"
               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:
             Docker-Experimental:
               type: "boolean"
               type: "boolean"
               description: "If the server is running with experimental mode enabled"
               description: "If the server is running with experimental mode enabled"

+ 12 - 0
docs/api/version-history.md

@@ -59,6 +59,18 @@ keywords: "API, Docker, rcli, REST, documentation"
   if they are not set.
   if they are not set.
 * `GET /info` now omits the `KernelMemory` and `KernelMemoryTCP` if they are not
 * `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).
   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
 * `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
   client to detect if Swarm is enabled on the daemon, without having to call
   additional endpoints.
   additional endpoints.

+ 42 - 0
integration/system/ping_test.go

@@ -3,9 +3,13 @@ package system // import "github.com/docker/docker/integration/system"
 import (
 import (
 	"context"
 	"context"
 	"net/http"
 	"net/http"
+	"os"
+	"path/filepath"
+	"runtime"
 	"strings"
 	"strings"
 	"testing"
 	"testing"
 
 
+	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/api/types/versions"
 	"github.com/docker/docker/api/types/versions"
 	"github.com/docker/docker/testutil/daemon"
 	"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 {
 func hdr(res *http.Response, name string) string {
 	val, ok := res.Header[http.CanonicalHeaderKey(name)]
 	val, ok := res.Header[http.CanonicalHeaderKey(name)]
 	if !ok || len(val) == 0 {
 	if !ok || len(val) == 0 {