add optional fields in daemon.json to enable buildkit
Signed-off-by: Anda Xu <anda.xu@docker.com>
This commit is contained in:
parent
14d5569f19
commit
2be17666b4
10 changed files with 71 additions and 33 deletions
|
@ -1,17 +1,21 @@
|
||||||
package build // import "github.com/docker/docker/api/server/router/build"
|
package build // import "github.com/docker/docker/api/server/router/build"
|
||||||
|
|
||||||
import "github.com/docker/docker/api/server/router"
|
import (
|
||||||
|
"github.com/docker/docker/api/server/router"
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
|
)
|
||||||
|
|
||||||
// buildRouter is a router to talk with the build controller
|
// buildRouter is a router to talk with the build controller
|
||||||
type buildRouter struct {
|
type buildRouter struct {
|
||||||
backend Backend
|
backend Backend
|
||||||
daemon experimentalProvider
|
daemon experimentalProvider
|
||||||
routes []router.Route
|
routes []router.Route
|
||||||
|
builderVersion types.BuilderVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRouter initializes a new build router
|
// NewRouter initializes a new build router
|
||||||
func NewRouter(b Backend, d experimentalProvider) router.Router {
|
func NewRouter(b Backend, d experimentalProvider, bv types.BuilderVersion) router.Router {
|
||||||
r := &buildRouter{backend: b, daemon: d}
|
r := &buildRouter{backend: b, daemon: d, builderVersion: bv}
|
||||||
r.initRoutes()
|
r.initRoutes()
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,8 +230,10 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
|
||||||
return errdefs.InvalidParameter(errors.New("squash is only supported with experimental mode"))
|
return errdefs.InvalidParameter(errors.New("squash is only supported with experimental mode"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if buildOptions.Version == types.BuilderBuildKit && !br.daemon.HasExperimental() {
|
// check if the builder feature has been enabled from daemon as well.
|
||||||
return errdefs.InvalidParameter(errors.New("buildkit is only supported with experimental mode"))
|
if buildOptions.Version == types.BuilderBuildKit &&
|
||||||
|
(br.builderVersion != types.BuilderBuildKit || !br.daemon.HasExperimental()) {
|
||||||
|
return errdefs.InvalidParameter(errors.New("buildkit is not enabled on daemon"))
|
||||||
}
|
}
|
||||||
|
|
||||||
out := io.Writer(output)
|
out := io.Writer(output)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package system // import "github.com/docker/docker/api/server/router/system"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/docker/docker/api/server/router"
|
"github.com/docker/docker/api/server/router"
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
buildkit "github.com/docker/docker/builder/builder-next"
|
buildkit "github.com/docker/docker/builder/builder-next"
|
||||||
"github.com/docker/docker/builder/fscache"
|
"github.com/docker/docker/builder/fscache"
|
||||||
)
|
)
|
||||||
|
@ -14,20 +15,22 @@ type systemRouter struct {
|
||||||
routes []router.Route
|
routes []router.Route
|
||||||
fscache *fscache.FSCache // legacy
|
fscache *fscache.FSCache // legacy
|
||||||
builder *buildkit.Builder
|
builder *buildkit.Builder
|
||||||
|
builderVersion types.BuilderVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRouter initializes a new system router
|
// NewRouter initializes a new system router
|
||||||
func NewRouter(b Backend, c ClusterBackend, fscache *fscache.FSCache, builder *buildkit.Builder) router.Router {
|
func NewRouter(b Backend, c ClusterBackend, fscache *fscache.FSCache, builder *buildkit.Builder, bv types.BuilderVersion) router.Router {
|
||||||
r := &systemRouter{
|
r := &systemRouter{
|
||||||
backend: b,
|
backend: b,
|
||||||
cluster: c,
|
cluster: c,
|
||||||
fscache: fscache,
|
fscache: fscache,
|
||||||
builder: builder,
|
builder: builder,
|
||||||
|
builderVersion: bv,
|
||||||
}
|
}
|
||||||
|
|
||||||
r.routes = []router.Route{
|
r.routes = []router.Route{
|
||||||
router.NewOptionsRoute("/{anyroute:.*}", optionsHandler),
|
router.NewOptionsRoute("/{anyroute:.*}", optionsHandler),
|
||||||
router.NewGetRoute("/_ping", pingHandler),
|
router.NewGetRoute("/_ping", r.pingHandler),
|
||||||
router.NewGetRoute("/events", r.getEvents, router.WithCancel),
|
router.NewGetRoute("/events", r.getEvents, router.WithCancel),
|
||||||
router.NewGetRoute("/info", r.getInfo),
|
router.NewGetRoute("/info", r.getInfo),
|
||||||
router.NewGetRoute("/version", r.getVersion),
|
router.NewGetRoute("/version", r.getVersion),
|
||||||
|
|
|
@ -25,7 +25,10 @@ func optionsHandler(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func pingHandler(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func (s *systemRouter) pingHandler(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
|
if bv := s.builderVersion; bv != "" {
|
||||||
|
w.Header().Set("Builder-Version", string(bv))
|
||||||
|
}
|
||||||
_, err := w.Write([]byte{'O', 'K'})
|
_, err := w.Write([]byte{'O', 'K'})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -6972,6 +6972,9 @@ paths:
|
||||||
API-Version:
|
API-Version:
|
||||||
type: "string"
|
type: "string"
|
||||||
description: "Max API Version the server supports"
|
description: "Max API Version the server supports"
|
||||||
|
BuildKit-Version:
|
||||||
|
type: "string"
|
||||||
|
description: "Default version of docker image builder"
|
||||||
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"
|
||||||
|
|
|
@ -105,6 +105,7 @@ type Ping struct {
|
||||||
APIVersion string
|
APIVersion string
|
||||||
OSType string
|
OSType string
|
||||||
Experimental bool
|
Experimental bool
|
||||||
|
BuilderVersion BuilderVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComponentVersion describes the version information for a specific component.
|
// ComponentVersion describes the version information for a specific component.
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ping pings the server and returns the value of the "Docker-Experimental", "OS-Type" & "API-Version" headers
|
// Ping pings the server and returns the value of the "Docker-Experimental", "Builder-Version", "OS-Type" & "API-Version" headers
|
||||||
func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||||
var ping types.Ping
|
var ping types.Ping
|
||||||
req, err := cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil)
|
req, err := cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil)
|
||||||
|
@ -27,6 +27,9 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||||
ping.Experimental = true
|
ping.Experimental = true
|
||||||
}
|
}
|
||||||
ping.OSType = serverResp.header.Get("OSType")
|
ping.OSType = serverResp.header.Get("OSType")
|
||||||
|
if bv := serverResp.header.Get("Builder-Version"); bv != "" {
|
||||||
|
ping.BuilderVersion = types.BuilderVersion(bv)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ping, cli.checkResponseErr(serverResp)
|
return ping, cli.checkResponseErr(serverResp)
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,6 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
|
||||||
|
|
||||||
flags.StringVar(&conf.SwarmDefaultAdvertiseAddr, "swarm-default-advertise-addr", "", "Set default address or interface for swarm advertised address")
|
flags.StringVar(&conf.SwarmDefaultAdvertiseAddr, "swarm-default-advertise-addr", "", "Set default address or interface for swarm advertised address")
|
||||||
flags.BoolVar(&conf.Experimental, "experimental", false, "Enable experimental features")
|
flags.BoolVar(&conf.Experimental, "experimental", false, "Enable experimental features")
|
||||||
|
|
||||||
flags.StringVar(&conf.MetricsAddress, "metrics-addr", "", "Set default address and port to serve the metrics api on")
|
flags.StringVar(&conf.MetricsAddress, "metrics-addr", "", "Set default address and port to serve the metrics api on")
|
||||||
|
|
||||||
flags.Var(opts.NewNamedListOptsRef("node-generic-resources", &conf.NodeGenericResources, opts.ValidateSingleGenericResource), "node-generic-resource", "Advertise user-defined resource")
|
flags.Var(opts.NewNamedListOptsRef("node-generic-resources", &conf.NodeGenericResources, opts.ValidateSingleGenericResource), "node-generic-resource", "Advertise user-defined resource")
|
||||||
|
|
|
@ -27,6 +27,7 @@ import (
|
||||||
swarmrouter "github.com/docker/docker/api/server/router/swarm"
|
swarmrouter "github.com/docker/docker/api/server/router/swarm"
|
||||||
systemrouter "github.com/docker/docker/api/server/router/system"
|
systemrouter "github.com/docker/docker/api/server/router/system"
|
||||||
"github.com/docker/docker/api/server/router/volume"
|
"github.com/docker/docker/api/server/router/volume"
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
buildkit "github.com/docker/docker/builder/builder-next"
|
buildkit "github.com/docker/docker/builder/builder-next"
|
||||||
"github.com/docker/docker/builder/dockerfile"
|
"github.com/docker/docker/builder/dockerfile"
|
||||||
"github.com/docker/docker/builder/fscache"
|
"github.com/docker/docker/builder/fscache"
|
||||||
|
@ -253,6 +254,7 @@ type routerOptions struct {
|
||||||
buildBackend *buildbackend.Backend
|
buildBackend *buildbackend.Backend
|
||||||
buildCache *fscache.FSCache // legacy
|
buildCache *fscache.FSCache // legacy
|
||||||
buildkit *buildkit.Builder
|
buildkit *buildkit.Builder
|
||||||
|
builderVersion types.BuilderVersion
|
||||||
daemon *daemon.Daemon
|
daemon *daemon.Daemon
|
||||||
api *apiserver.Server
|
api *apiserver.Server
|
||||||
cluster *cluster.Cluster
|
cluster *cluster.Cluster
|
||||||
|
@ -283,8 +285,7 @@ func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptio
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return opts, err
|
return opts, err
|
||||||
}
|
}
|
||||||
|
bk, err := buildkit.New(buildkit.Opt{
|
||||||
buildkit, err := buildkit.New(buildkit.Opt{
|
|
||||||
SessionManager: sm,
|
SessionManager: sm,
|
||||||
Root: filepath.Join(config.Root, "buildkit"),
|
Root: filepath.Join(config.Root, "buildkit"),
|
||||||
Dist: daemon.DistributionServices(),
|
Dist: daemon.DistributionServices(),
|
||||||
|
@ -293,16 +294,24 @@ func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptio
|
||||||
return opts, err
|
return opts, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bb, err := buildbackend.NewBackend(daemon.ImageService(), manager, buildCache, buildkit)
|
bb, err := buildbackend.NewBackend(daemon.ImageService(), manager, buildCache, bk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return opts, errors.Wrap(err, "failed to create buildmanager")
|
return opts, errors.Wrap(err, "failed to create buildmanager")
|
||||||
}
|
}
|
||||||
|
var bv types.BuilderVersion
|
||||||
|
if v, ok := config.Features["buildkit"]; ok {
|
||||||
|
if v {
|
||||||
|
bv = types.BuilderBuildKit
|
||||||
|
} else {
|
||||||
|
bv = types.BuilderV1
|
||||||
|
}
|
||||||
|
}
|
||||||
return routerOptions{
|
return routerOptions{
|
||||||
sessionManager: sm,
|
sessionManager: sm,
|
||||||
buildBackend: bb,
|
buildBackend: bb,
|
||||||
buildCache: buildCache,
|
buildCache: buildCache,
|
||||||
buildkit: buildkit,
|
buildkit: bk,
|
||||||
|
builderVersion: bv,
|
||||||
daemon: daemon,
|
daemon: daemon,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -476,9 +485,9 @@ func initRouter(opts routerOptions) {
|
||||||
checkpointrouter.NewRouter(opts.daemon, decoder),
|
checkpointrouter.NewRouter(opts.daemon, decoder),
|
||||||
container.NewRouter(opts.daemon, decoder),
|
container.NewRouter(opts.daemon, decoder),
|
||||||
image.NewRouter(opts.daemon.ImageService()),
|
image.NewRouter(opts.daemon.ImageService()),
|
||||||
systemrouter.NewRouter(opts.daemon, opts.cluster, opts.buildCache, opts.buildkit),
|
systemrouter.NewRouter(opts.daemon, opts.cluster, opts.buildCache, opts.buildkit, opts.builderVersion),
|
||||||
volume.NewRouter(opts.daemon.VolumesService()),
|
volume.NewRouter(opts.daemon.VolumesService()),
|
||||||
build.NewRouter(opts.buildBackend, opts.daemon),
|
build.NewRouter(opts.buildBackend, opts.daemon, opts.builderVersion),
|
||||||
sessionrouter.NewRouter(opts.sessionManager),
|
sessionrouter.NewRouter(opts.sessionManager),
|
||||||
swarmrouter.NewRouter(opts.cluster),
|
swarmrouter.NewRouter(opts.cluster),
|
||||||
pluginrouter.NewRouter(opts.daemon.PluginManager()),
|
pluginrouter.NewRouter(opts.daemon.PluginManager()),
|
||||||
|
|
|
@ -56,6 +56,13 @@ var flatOptions = map[string]bool{
|
||||||
"default-ulimits": true,
|
"default-ulimits": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skipValidateOptions contains configuration keys
|
||||||
|
// that will be skipped from findConfigurationConflicts
|
||||||
|
// for unknown flag validation.
|
||||||
|
var skipValidateOptions = map[string]bool{
|
||||||
|
"features": true,
|
||||||
|
}
|
||||||
|
|
||||||
// LogConfig represents the default log configuration.
|
// LogConfig represents the default log configuration.
|
||||||
// It includes json tags to deserialize configuration from a file
|
// It includes json tags to deserialize configuration from a file
|
||||||
// using the same names that the flags in the command line use.
|
// using the same names that the flags in the command line use.
|
||||||
|
@ -203,6 +210,10 @@ type CommonConfig struct {
|
||||||
// should be configured with the CRI plugin enabled. This allows using
|
// should be configured with the CRI plugin enabled. This allows using
|
||||||
// Docker's containerd instance directly with a Kubernetes kubelet.
|
// Docker's containerd instance directly with a Kubernetes kubelet.
|
||||||
CriContainerd bool `json:"cri-containerd,omitempty"`
|
CriContainerd bool `json:"cri-containerd,omitempty"`
|
||||||
|
|
||||||
|
// Features contains a list of feature key value pairs indicating what features are enabled or disabled.
|
||||||
|
// If a certain feature doesn't appear in this list then it's unset (i.e. neither true nor false).
|
||||||
|
Features map[string]bool `json:"features,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValueSet returns true if a configuration value
|
// IsValueSet returns true if a configuration value
|
||||||
|
@ -444,7 +455,7 @@ func findConfigurationConflicts(config map[string]interface{}, flags *pflag.Flag
|
||||||
// 1. Search keys from the file that we don't recognize as flags.
|
// 1. Search keys from the file that we don't recognize as flags.
|
||||||
unknownKeys := make(map[string]interface{})
|
unknownKeys := make(map[string]interface{})
|
||||||
for key, value := range config {
|
for key, value := range config {
|
||||||
if flag := flags.Lookup(key); flag == nil {
|
if flag := flags.Lookup(key); flag == nil && !skipValidateOptions[key] {
|
||||||
unknownKeys[key] = value
|
unknownKeys[key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue