Преглед на файлове

Merge pull request #37692 from AntaresS/live-reload-buildkit

allow features option live reloading
Tibor Vass преди 6 години
родител
ревизия
8af91768c7

+ 25 - 6
api/server/router/build/build.go

@@ -7,15 +7,19 @@ import (
 
 
 // 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
-	daemon         experimentalProvider
-	routes         []router.Route
-	builderVersion types.BuilderVersion
+	backend  Backend
+	daemon   experimentalProvider
+	routes   []router.Route
+	features *map[string]bool
 }
 }
 
 
 // NewRouter initializes a new build router
 // NewRouter initializes a new build router
-func NewRouter(b Backend, d experimentalProvider, bv types.BuilderVersion) router.Router {
-	r := &buildRouter{backend: b, daemon: d, builderVersion: bv}
+func NewRouter(b Backend, d experimentalProvider, features *map[string]bool) router.Router {
+	r := &buildRouter{
+		backend:  b,
+		daemon:   d,
+		features: features,
+	}
 	r.initRoutes()
 	r.initRoutes()
 	return r
 	return r
 }
 }
@@ -32,3 +36,18 @@ func (r *buildRouter) initRoutes() {
 		router.NewPostRoute("/build/cancel", r.postCancel),
 		router.NewPostRoute("/build/cancel", r.postCancel),
 	}
 	}
 }
 }
+
+// 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.
+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
+		}
+	}
+	return bv
+}

+ 2 - 1
api/server/router/build/build_routes.go

@@ -230,8 +230,9 @@ 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"))
 	}
 	}
 
 
+	builderVersion := BuilderVersion(*br.features)
 	// check if the builder feature has been enabled from daemon as well.
 	// check if the builder feature has been enabled from daemon as well.
-	if buildOptions.Version == types.BuilderBuildKit && br.builderVersion != "" && br.builderVersion != types.BuilderBuildKit {
+	if buildOptions.Version == types.BuilderBuildKit && builderVersion != "" && builderVersion != types.BuilderBuildKit {
 		return errdefs.InvalidParameter(errors.New("buildkit is not enabled on daemon"))
 		return errdefs.InvalidParameter(errors.New("buildkit is not enabled on daemon"))
 	}
 	}
 
 

+ 13 - 14
api/server/router/system/system.go

@@ -2,30 +2,29 @@ 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"
+	"github.com/docker/docker/builder/builder-next"
 	"github.com/docker/docker/builder/fscache"
 	"github.com/docker/docker/builder/fscache"
 )
 )
 
 
 // systemRouter provides information about the Docker system overall.
 // systemRouter provides information about the Docker system overall.
 // It gathers information about host, daemon and container events.
 // It gathers information about host, daemon and container events.
 type systemRouter struct {
 type systemRouter struct {
-	backend        Backend
-	cluster        ClusterBackend
-	routes         []router.Route
-	fscache        *fscache.FSCache // legacy
-	builder        *buildkit.Builder
-	builderVersion types.BuilderVersion
+	backend  Backend
+	cluster  ClusterBackend
+	routes   []router.Route
+	fscache  *fscache.FSCache // legacy
+	builder  *buildkit.Builder
+	features *map[string]bool
 }
 }
 
 
 // NewRouter initializes a new system router
 // NewRouter initializes a new system router
-func NewRouter(b Backend, c ClusterBackend, fscache *fscache.FSCache, builder *buildkit.Builder, bv types.BuilderVersion) router.Router {
+func NewRouter(b Backend, c ClusterBackend, fscache *fscache.FSCache, builder *buildkit.Builder, features *map[string]bool) router.Router {
 	r := &systemRouter{
 	r := &systemRouter{
-		backend:        b,
-		cluster:        c,
-		fscache:        fscache,
-		builder:        builder,
-		builderVersion: bv,
+		backend:  b,
+		cluster:  c,
+		fscache:  fscache,
+		builder:  builder,
+		features: features,
 	}
 	}
 
 
 	r.routes = []router.Route{
 	r.routes = []router.Route{

+ 3 - 1
api/server/router/system/system_routes.go

@@ -8,6 +8,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/api/server/httputils"
+	"github.com/docker/docker/api/server/router/build"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/events"
 	"github.com/docker/docker/api/types/events"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/filters"
@@ -26,7 +27,8 @@ func optionsHandler(ctx context.Context, w http.ResponseWriter, r *http.Request,
 }
 }
 
 
 func (s *systemRouter) 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 != "" {
+	builderVersion := build.BuilderVersion(*s.features)
+	if bv := builderVersion; bv != "" {
 		w.Header().Set("Builder-Version", string(bv))
 		w.Header().Set("Builder-Version", string(bv))
 	}
 	}
 	_, err := w.Write([]byte{'O', 'K'})
 	_, err := w.Write([]byte{'O', 'K'})

+ 4 - 13
cmd/dockerd/daemon.go

@@ -27,7 +27,6 @@ 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,8 +252,8 @@ type routerOptions struct {
 	sessionManager *session.Manager
 	sessionManager *session.Manager
 	buildBackend   *buildbackend.Backend
 	buildBackend   *buildbackend.Backend
 	buildCache     *fscache.FSCache // legacy
 	buildCache     *fscache.FSCache // legacy
+	features       *map[string]bool
 	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
@@ -300,20 +299,12 @@ func newRouterOptions(config *config.Config, daemon *daemon.Daemon) (routerOptio
 	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:       bk,
 		buildkit:       bk,
-		builderVersion: bv,
+		features:       daemon.Features(),
 		daemon:         daemon,
 		daemon:         daemon,
 	}, nil
 	}, nil
 }
 }
@@ -487,9 +478,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, opts.builderVersion),
+		systemrouter.NewRouter(opts.daemon, opts.cluster, opts.buildCache, opts.buildkit, opts.features),
 		volume.NewRouter(opts.daemon.VolumesService()),
 		volume.NewRouter(opts.daemon.VolumesService()),
-		build.NewRouter(opts.buildBackend, opts.daemon, opts.builderVersion),
+		build.NewRouter(opts.buildBackend, opts.daemon, opts.features),
 		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()),

+ 5 - 0
daemon/daemon.go

@@ -136,6 +136,11 @@ func (daemon *Daemon) HasExperimental() bool {
 	return daemon.configStore != nil && daemon.configStore.Experimental
 	return daemon.configStore != nil && daemon.configStore.Experimental
 }
 }
 
 
+// Features returns the features map from configStore
+func (daemon *Daemon) Features() *map[string]bool {
+	return &daemon.configStore.Features
+}
+
 func (daemon *Daemon) restore() error {
 func (daemon *Daemon) restore() error {
 	containers := make(map[string]*container.Container)
 	containers := make(map[string]*container.Container)
 
 

+ 11 - 0
daemon/reload.go

@@ -45,6 +45,7 @@ func (daemon *Daemon) Reload(conf *config.Config) (err error) {
 	daemon.reloadDebug(conf, attributes)
 	daemon.reloadDebug(conf, attributes)
 	daemon.reloadMaxConcurrentDownloadsAndUploads(conf, attributes)
 	daemon.reloadMaxConcurrentDownloadsAndUploads(conf, attributes)
 	daemon.reloadShutdownTimeout(conf, attributes)
 	daemon.reloadShutdownTimeout(conf, attributes)
+	daemon.reloadFeatures(conf, attributes)
 
 
 	if err := daemon.reloadClusterDiscovery(conf, attributes); err != nil {
 	if err := daemon.reloadClusterDiscovery(conf, attributes); err != nil {
 		return err
 		return err
@@ -322,3 +323,13 @@ func (daemon *Daemon) reloadNetworkDiagnosticPort(conf *config.Config, attribute
 
 
 	return nil
 	return nil
 }
 }
+
+// reloadFeatures updates configuration with enabled/disabled features
+func (daemon *Daemon) reloadFeatures(conf *config.Config, attributes map[string]string) {
+	// update corresponding configuration
+	// note that we allow features option to be entirely unset
+	daemon.configStore.Features = conf.Features
+
+	// prepare reload event attributes with updatable configurations
+	attributes["features"] = fmt.Sprintf("%v", daemon.configStore.Features)
+}