diff --git a/command/bundlefile/bundlefile.go b/command/bundlefile/bundlefile.go index 75c2d07433..7fd1e4f6c4 100644 --- a/command/bundlefile/bundlefile.go +++ b/command/bundlefile/bundlefile.go @@ -1,5 +1,3 @@ -// +build experimental - package bundlefile import ( diff --git a/command/bundlefile/bundlefile_test.go b/command/bundlefile/bundlefile_test.go index 1ff8235ff8..c343410df3 100644 --- a/command/bundlefile/bundlefile_test.go +++ b/command/bundlefile/bundlefile_test.go @@ -1,5 +1,3 @@ -// +build experimental - package bundlefile import ( diff --git a/command/checkpoint/cmd.go b/command/checkpoint/cmd.go index 7c3950bba8..84084ab716 100644 --- a/command/checkpoint/cmd.go +++ b/command/checkpoint/cmd.go @@ -1,13 +1,27 @@ -// +build !experimental - package checkpoint import ( + "fmt" + + "github.com/docker/docker/cli" "github.com/docker/docker/cli/command" "github.com/spf13/cobra" ) // NewCheckpointCommand returns the `checkpoint` subcommand (only in experimental) func NewCheckpointCommand(dockerCli *command.DockerCli) *cobra.Command { - return &cobra.Command{} + cmd := &cobra.Command{ + Use: "checkpoint", + Short: "Manage checkpoints", + Args: cli.NoArgs, + Run: func(cmd *cobra.Command, args []string) { + fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) + }, + } + cmd.AddCommand( + newCreateCommand(dockerCli), + newListCommand(dockerCli), + newRemoveCommand(dockerCli), + ) + return cmd } diff --git a/command/checkpoint/cmd_experimental.go b/command/checkpoint/cmd_experimental.go deleted file mode 100644 index 3c89545778..0000000000 --- a/command/checkpoint/cmd_experimental.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build experimental - -package checkpoint - -import ( - "fmt" - - "github.com/spf13/cobra" - - "github.com/docker/docker/cli" - "github.com/docker/docker/cli/command" -) - -// NewCheckpointCommand returns the `checkpoint` subcommand (only in experimental) -func NewCheckpointCommand(dockerCli *command.DockerCli) *cobra.Command { - cmd := &cobra.Command{ - Use: "checkpoint", - Short: "Manage checkpoints", - Args: cli.NoArgs, - Run: func(cmd *cobra.Command, args []string) { - fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) - }, - } - cmd.AddCommand( - newCreateCommand(dockerCli), - newListCommand(dockerCli), - newRemoveCommand(dockerCli), - ) - return cmd -} diff --git a/command/checkpoint/create.go b/command/checkpoint/create.go index f214574556..d369718119 100644 --- a/command/checkpoint/create.go +++ b/command/checkpoint/create.go @@ -1,5 +1,3 @@ -// +build experimental - package checkpoint import ( diff --git a/command/checkpoint/list.go b/command/checkpoint/list.go index 6d22531d45..7ba035890b 100644 --- a/command/checkpoint/list.go +++ b/command/checkpoint/list.go @@ -1,5 +1,3 @@ -// +build experimental - package checkpoint import ( diff --git a/command/checkpoint/remove.go b/command/checkpoint/remove.go index 6605c5e472..82ce62312b 100644 --- a/command/checkpoint/remove.go +++ b/command/checkpoint/remove.go @@ -1,5 +1,3 @@ -// +build experimental - package checkpoint import ( diff --git a/command/cli.go b/command/cli.go index 9ca28765cc..be82ecf6f3 100644 --- a/command/cli.go +++ b/command/cli.go @@ -19,6 +19,7 @@ import ( dopts "github.com/docker/docker/opts" "github.com/docker/go-connections/sockets" "github.com/docker/go-connections/tlsconfig" + "golang.org/x/net/context" ) // Streams is an interface which exposes the standard input and output streams @@ -31,12 +32,27 @@ type Streams interface { // DockerCli represents the docker command line client. // Instances of the client can be returned from NewDockerCli. type DockerCli struct { - configFile *configfile.ConfigFile - in *InStream - out *OutStream - err io.Writer - keyFile string - client client.APIClient + configFile *configfile.ConfigFile + in *InStream + out *OutStream + err io.Writer + keyFile string + client client.APIClient + hasExperimental *bool +} + +// HasExperimental returns true if experimental features are accessible +func (cli *DockerCli) HasExperimental() bool { + if cli.hasExperimental == nil { + if cli.client == nil { + cli.Initialize(cliflags.NewClientOptions()) + } + enabled := false + cli.hasExperimental = &enabled + enabled, _ = cli.client.Ping(context.Background()) + } + + return *cli.hasExperimental } // Client returns the APIClient diff --git a/command/commands/commands.go b/command/commands/commands.go index 6d0deb1d90..425f90ba7d 100644 --- a/command/commands/commands.go +++ b/command/commands/commands.go @@ -24,8 +24,6 @@ func AddCommands(cmd *cobra.Command, dockerCli *command.DockerCli) { cmd.AddCommand( node.NewNodeCommand(dockerCli), service.NewServiceCommand(dockerCli), - stack.NewStackCommand(dockerCli), - stack.NewTopLevelDeployCommand(dockerCli), swarm.NewSwarmCommand(dockerCli), container.NewContainerCommand(dockerCli), image.NewImageCommand(dockerCli), @@ -72,9 +70,17 @@ func AddCommands(cmd *cobra.Command, dockerCli *command.DockerCli) { hide(image.NewSaveCommand(dockerCli)), hide(image.NewTagCommand(dockerCli)), hide(system.NewInspectCommand(dockerCli)), - checkpoint.NewCheckpointCommand(dockerCli), - plugin.NewPluginCommand(dockerCli), ) + + if dockerCli.HasExperimental() { + cmd.AddCommand( + stack.NewStackCommand(dockerCli), + stack.NewTopLevelDeployCommand(dockerCli), + checkpoint.NewCheckpointCommand(dockerCli), + plugin.NewPluginCommand(dockerCli), + ) + } + } func hide(cmd *cobra.Command) *cobra.Command { diff --git a/command/container/start.go b/command/container/start.go index 4c31f9bf97..8693b3a550 100644 --- a/command/container/start.go +++ b/command/container/start.go @@ -44,7 +44,9 @@ func NewStartCommand(dockerCli *command.DockerCli) *cobra.Command { flags.BoolVarP(&opts.openStdin, "interactive", "i", false, "Attach container's STDIN") flags.StringVar(&opts.detachKeys, "detach-keys", "", "Override the key sequence for detaching a container") - addExperimentalStartFlags(flags, &opts) + if dockerCli.HasExperimental() { + flags.StringVar(&opts.checkpoint, "checkpoint", "", "Restore from this checkpoint") + } return cmd } diff --git a/command/container/start_utils.go b/command/container/start_utils.go deleted file mode 100644 index 689d742f06..0000000000 --- a/command/container/start_utils.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build !experimental - -package container - -import "github.com/spf13/pflag" - -func addExperimentalStartFlags(flags *pflag.FlagSet, opts *startOptions) { -} diff --git a/command/container/start_utils_experimental.go b/command/container/start_utils_experimental.go deleted file mode 100644 index 43c64f431c..0000000000 --- a/command/container/start_utils_experimental.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build experimental - -package container - -import "github.com/spf13/pflag" - -func addExperimentalStartFlags(flags *pflag.FlagSet, opts *startOptions) { - flags.StringVar(&opts.checkpoint, "checkpoint", "", "Restore from this checkpoint") -} diff --git a/command/plugin/cmd.go b/command/plugin/cmd.go index 10074218dd..80fa61cb1c 100644 --- a/command/plugin/cmd.go +++ b/command/plugin/cmd.go @@ -1,13 +1,33 @@ -// +build !experimental - package plugin import ( + "fmt" + + "github.com/docker/docker/cli" "github.com/docker/docker/cli/command" "github.com/spf13/cobra" ) // NewPluginCommand returns a cobra command for `plugin` subcommands func NewPluginCommand(dockerCli *command.DockerCli) *cobra.Command { - return &cobra.Command{} + cmd := &cobra.Command{ + Use: "plugin", + Short: "Manage plugins", + Args: cli.NoArgs, + Run: func(cmd *cobra.Command, args []string) { + fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) + }, + } + + cmd.AddCommand( + newDisableCommand(dockerCli), + newEnableCommand(dockerCli), + newInspectCommand(dockerCli), + newInstallCommand(dockerCli), + newListCommand(dockerCli), + newRemoveCommand(dockerCli), + newSetCommand(dockerCli), + newPushCommand(dockerCli), + ) + return cmd } diff --git a/command/plugin/cmd_experimental.go b/command/plugin/cmd_experimental.go deleted file mode 100644 index 8bb3416097..0000000000 --- a/command/plugin/cmd_experimental.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build experimental - -package plugin - -import ( - "fmt" - - "github.com/docker/docker/cli" - "github.com/docker/docker/cli/command" - "github.com/spf13/cobra" -) - -// NewPluginCommand returns a cobra command for `plugin` subcommands -func NewPluginCommand(dockerCli *command.DockerCli) *cobra.Command { - cmd := &cobra.Command{ - Use: "plugin", - Short: "Manage plugins", - Args: cli.NoArgs, - Run: func(cmd *cobra.Command, args []string) { - fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) - }, - } - - cmd.AddCommand( - newDisableCommand(dockerCli), - newEnableCommand(dockerCli), - newInspectCommand(dockerCli), - newInstallCommand(dockerCli), - newListCommand(dockerCli), - newRemoveCommand(dockerCli), - newSetCommand(dockerCli), - newPushCommand(dockerCli), - ) - return cmd -} diff --git a/command/plugin/disable.go b/command/plugin/disable.go index 3b5c69a018..9089a3cf68 100644 --- a/command/plugin/disable.go +++ b/command/plugin/disable.go @@ -1,5 +1,3 @@ -// +build experimental - package plugin import ( diff --git a/command/plugin/enable.go b/command/plugin/enable.go index cfc3580f43..0fd8f469dd 100644 --- a/command/plugin/enable.go +++ b/command/plugin/enable.go @@ -1,5 +1,3 @@ -// +build experimental - package plugin import ( diff --git a/command/plugin/inspect.go b/command/plugin/inspect.go index e5059629e5..13c7fa72d8 100644 --- a/command/plugin/inspect.go +++ b/command/plugin/inspect.go @@ -1,5 +1,3 @@ -// +build experimental - package plugin import ( diff --git a/command/plugin/install.go b/command/plugin/install.go index e90e8d1224..3989a35ce6 100644 --- a/command/plugin/install.go +++ b/command/plugin/install.go @@ -1,5 +1,3 @@ -// +build experimental - package plugin import ( diff --git a/command/plugin/list.go b/command/plugin/list.go index b8f5e5e08a..9d4b46d120 100644 --- a/command/plugin/list.go +++ b/command/plugin/list.go @@ -1,5 +1,3 @@ -// +build experimental - package plugin import ( diff --git a/command/plugin/push.go b/command/plugin/push.go index 360830902e..4e176bea3e 100644 --- a/command/plugin/push.go +++ b/command/plugin/push.go @@ -1,5 +1,3 @@ -// +build experimental - package plugin import ( diff --git a/command/plugin/remove.go b/command/plugin/remove.go index 4222690a4f..7a51dce06d 100644 --- a/command/plugin/remove.go +++ b/command/plugin/remove.go @@ -1,5 +1,3 @@ -// +build experimental - package plugin import ( diff --git a/command/plugin/set.go b/command/plugin/set.go index f2d3b082c6..e58ea63bc0 100644 --- a/command/plugin/set.go +++ b/command/plugin/set.go @@ -1,5 +1,3 @@ -// +build experimental - package plugin import ( diff --git a/command/stack/cmd.go b/command/stack/cmd.go index 51cb2d1bcf..49fcedf209 100644 --- a/command/stack/cmd.go +++ b/command/stack/cmd.go @@ -1,18 +1,38 @@ -// +build !experimental - package stack import ( + "fmt" + + "github.com/docker/docker/cli" "github.com/docker/docker/cli/command" "github.com/spf13/cobra" ) -// NewStackCommand returns no command +// NewStackCommand returns a cobra command for `stack` subcommands func NewStackCommand(dockerCli *command.DockerCli) *cobra.Command { - return &cobra.Command{} + cmd := &cobra.Command{ + Use: "stack", + Short: "Manage Docker stacks", + Args: cli.NoArgs, + Run: func(cmd *cobra.Command, args []string) { + fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) + }, + } + cmd.AddCommand( + newConfigCommand(dockerCli), + newDeployCommand(dockerCli), + newListCommand(dockerCli), + newRemoveCommand(dockerCli), + newServicesCommand(dockerCli), + newPsCommand(dockerCli), + ) + return cmd } -// NewTopLevelDeployCommand returns no command +// NewTopLevelDeployCommand returns a command for `docker deploy` func NewTopLevelDeployCommand(dockerCli *command.DockerCli) *cobra.Command { - return &cobra.Command{} + cmd := newDeployCommand(dockerCli) + // Remove the aliases at the top level + cmd.Aliases = []string{} + return cmd } diff --git a/command/stack/cmd_experimental.go b/command/stack/cmd_experimental.go deleted file mode 100644 index b32d925330..0000000000 --- a/command/stack/cmd_experimental.go +++ /dev/null @@ -1,40 +0,0 @@ -// +build experimental - -package stack - -import ( - "fmt" - - "github.com/docker/docker/cli" - "github.com/docker/docker/cli/command" - "github.com/spf13/cobra" -) - -// NewStackCommand returns a cobra command for `stack` subcommands -func NewStackCommand(dockerCli *command.DockerCli) *cobra.Command { - cmd := &cobra.Command{ - Use: "stack", - Short: "Manage Docker stacks", - Args: cli.NoArgs, - Run: func(cmd *cobra.Command, args []string) { - fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString()) - }, - } - cmd.AddCommand( - newConfigCommand(dockerCli), - newDeployCommand(dockerCli), - newListCommand(dockerCli), - newRemoveCommand(dockerCli), - newServicesCommand(dockerCli), - newPsCommand(dockerCli), - ) - return cmd -} - -// NewTopLevelDeployCommand returns a command for `docker deploy` -func NewTopLevelDeployCommand(dockerCli *command.DockerCli) *cobra.Command { - cmd := newDeployCommand(dockerCli) - // Remove the aliases at the top level - cmd.Aliases = []string{} - return cmd -} diff --git a/command/stack/common.go b/command/stack/common.go index 2afdb5147d..3e3a35faac 100644 --- a/command/stack/common.go +++ b/command/stack/common.go @@ -1,5 +1,3 @@ -// +build experimental - package stack import ( diff --git a/command/stack/config.go b/command/stack/config.go index bdcf7d4835..56e554a86e 100644 --- a/command/stack/config.go +++ b/command/stack/config.go @@ -1,5 +1,3 @@ -// +build experimental - package stack import ( diff --git a/command/stack/deploy.go b/command/stack/deploy.go index bf31dd7753..fcf55fb7d2 100644 --- a/command/stack/deploy.go +++ b/command/stack/deploy.go @@ -1,5 +1,3 @@ -// +build experimental - package stack import ( diff --git a/command/stack/list.go b/command/stack/list.go index 9fe626d96d..5d87cecb5f 100644 --- a/command/stack/list.go +++ b/command/stack/list.go @@ -1,5 +1,3 @@ -// +build experimental - package stack import ( diff --git a/command/stack/opts.go b/command/stack/opts.go index eef4d0e45b..5f2d8b5d0a 100644 --- a/command/stack/opts.go +++ b/command/stack/opts.go @@ -1,5 +1,3 @@ -// +build experimental - package stack import ( diff --git a/command/stack/ps.go b/command/stack/ps.go index c4683b68a0..2fff3de1fa 100644 --- a/command/stack/ps.go +++ b/command/stack/ps.go @@ -1,5 +1,3 @@ -// +build experimental - package stack import ( diff --git a/command/stack/remove.go b/command/stack/remove.go index 6ab005d71d..8137903d47 100644 --- a/command/stack/remove.go +++ b/command/stack/remove.go @@ -1,5 +1,3 @@ -// +build experimental - package stack import ( diff --git a/command/stack/services.go b/command/stack/services.go index 60f52c30c7..50b50179de 100644 --- a/command/stack/services.go +++ b/command/stack/services.go @@ -1,5 +1,3 @@ -// +build experimental - package stack import ( diff --git a/command/system/info.go b/command/system/info.go index fb5ea17d7b..0f94373d35 100644 --- a/command/system/info.go +++ b/command/system/info.go @@ -225,7 +225,7 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error { } } - ioutils.FprintfIfTrue(dockerCli.Out(), "Experimental: %v\n", info.ExperimentalBuild) + fmt.Fprintf(dockerCli.Out(), "Experimental: %v\n", info.ExperimentalBuild) if info.ClusterStore != "" { fmt.Fprintf(dockerCli.Out(), "Cluster Store: %s\n", info.ClusterStore) } diff --git a/command/system/version.go b/command/system/version.go index 7959bf564f..0b484cb3b9 100644 --- a/command/system/version.go +++ b/command/system/version.go @@ -10,7 +10,6 @@ import ( "github.com/docker/docker/cli" "github.com/docker/docker/cli/command" "github.com/docker/docker/dockerversion" - "github.com/docker/docker/utils" "github.com/docker/docker/utils/templates" "github.com/spf13/cobra" ) @@ -21,8 +20,7 @@ var versionTemplate = `Client: Go version: {{.Client.GoVersion}} Git commit: {{.Client.GitCommit}} Built: {{.Client.BuildTime}} - OS/Arch: {{.Client.Os}}/{{.Client.Arch}}{{if .Client.Experimental}} - Experimental: {{.Client.Experimental}}{{end}}{{if .ServerOK}} + OS/Arch: {{.Client.Os}}/{{.Client.Arch}}{{if .ServerOK}} Server: Version: {{.Server.Version}} @@ -30,8 +28,8 @@ Server: Go version: {{.Server.GoVersion}} Git commit: {{.Server.GitCommit}} Built: {{.Server.BuildTime}} - OS/Arch: {{.Server.Os}}/{{.Server.Arch}}{{if .Server.Experimental}} - Experimental: {{.Server.Experimental}}{{end}}{{end}}` + OS/Arch: {{.Server.Os}}/{{.Server.Arch}} + Experimental: {{.Server.Experimental}}{{end}}` type versionOptions struct { format string @@ -73,14 +71,13 @@ func runVersion(dockerCli *command.DockerCli, opts *versionOptions) error { vd := types.VersionResponse{ Client: &types.Version{ - Version: dockerversion.Version, - APIVersion: dockerCli.Client().ClientVersion(), - GoVersion: runtime.Version(), - GitCommit: dockerversion.GitCommit, - BuildTime: dockerversion.BuildTime, - Os: runtime.GOOS, - Arch: runtime.GOARCH, - Experimental: utils.ExperimentalBuild(), + Version: dockerversion.Version, + APIVersion: dockerCli.Client().ClientVersion(), + GoVersion: runtime.Version(), + GitCommit: dockerversion.GitCommit, + BuildTime: dockerversion.BuildTime, + Os: runtime.GOOS, + Arch: runtime.GOARCH, }, }