Skip to content

Commit

Permalink
api: set default "Builder-Version" to "2" (BuildKit) on Linux
Browse files Browse the repository at this point in the history
Starting with the 22.06 release, buildx is the default client for
docker build, which uses BuildKit as builder.

This patch changes the default builder version as advertised by
the daemon to "2" (BuildKit), so that pre-22.06 CLIs with BuildKit
support (but no buildx installed) also default to using BuildKit
when interacting with a 22.06 (or up) daemon.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
  • Loading branch information
thaJeztah committed May 29, 2022
1 parent cb01202 commit a58b29d
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 11 deletions.
29 changes: 19 additions & 10 deletions api/server/router/build/build.go
Original file line number Diff line number Diff line change
@@ -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"
)
Expand Down Expand Up @@ -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
}
12 changes: 11 additions & 1 deletion api/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8718,7 +8718,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"
Expand Down
12 changes: 12 additions & 0 deletions docs/api/version-history.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,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.
Expand Down
40 changes: 40 additions & 0 deletions integration/system/ping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -93,6 +97,42 @@ func TestPingSwarmHeader(t *testing.T) {
})
}

func TestPingBuilderHeader(t *testing.T) {
skip.If(t, testEnv.IsRemoteDaemon)

defer setupTest(t)()
d := daemon.New(t)

t.Run("default config", func(t *testing.T) {
d.Start(t)
defer d.Stop(t)

var expected = string(types.BuilderBuildKit)
if runtime.GOOS == "windows" {
expected = string(types.BuilderV1)
}

res, _, err := request.Head("/_ping", request.Host(d.Sock()))
assert.NilError(t, err)
assert.Equal(t, res.StatusCode, http.StatusOK)
assert.Equal(t, hdr(res, "Builder-Version"), 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 = string(types.BuilderV1)
res, _, err := request.Head("/_ping", request.Host(d.Sock()))
assert.NilError(t, err)
assert.Equal(t, res.StatusCode, http.StatusOK)
assert.Equal(t, hdr(res, "Builder-Version"), expected)
})
}

func hdr(res *http.Response, name string) string {
val, ok := res.Header[http.CanonicalHeaderKey(name)]
if !ok || len(val) == 0 {
Expand Down

0 comments on commit a58b29d

Please sign in to comment.