mirror of https://github.com/docker/cli.git
Merge pull request #2774 from thaJeztah/drop_experimental
Always enable experimental features
This commit is contained in:
commit
6916b427a0
|
@ -101,6 +101,5 @@ func main() {
|
|||
SchemaVersion: "0.1.0",
|
||||
Vendor: "Docker Inc.",
|
||||
Version: "testing",
|
||||
Experimental: os.Getenv("HELLO_EXPERIMENTAL") != "",
|
||||
})
|
||||
}
|
||||
|
|
|
@ -12,10 +12,9 @@ import (
|
|||
)
|
||||
|
||||
type fakeCandidate struct {
|
||||
path string
|
||||
exec bool
|
||||
meta string
|
||||
allowExperimental bool
|
||||
path string
|
||||
exec bool
|
||||
meta string
|
||||
}
|
||||
|
||||
func (c *fakeCandidate) Path() string {
|
||||
|
@ -30,7 +29,7 @@ func (c *fakeCandidate) Metadata() ([]byte, error) {
|
|||
}
|
||||
|
||||
func TestValidateCandidate(t *testing.T) {
|
||||
var (
|
||||
const (
|
||||
goodPluginName = NamePrefix + "goodplugin"
|
||||
|
||||
builtinName = NamePrefix + "builtin"
|
||||
|
@ -70,14 +69,12 @@ func TestValidateCandidate(t *testing.T) {
|
|||
{name: "invalid schemaversion", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "xyzzy"}`}, invalid: `plugin SchemaVersion "xyzzy" is not valid`},
|
||||
{name: "no vendor", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0"}`}, invalid: "plugin metadata does not define a vendor"},
|
||||
{name: "empty vendor", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0", "Vendor": ""}`}, invalid: "plugin metadata does not define a vendor"},
|
||||
{name: "experimental required", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: metaExperimental}, invalid: "requires experimental CLI"},
|
||||
// This one should work
|
||||
{name: "valid", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0", "Vendor": "e2e-testing"}`}},
|
||||
{name: "valid + allowing experimental", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: `{"SchemaVersion": "0.1.0", "Vendor": "e2e-testing"}`, allowExperimental: true}},
|
||||
{name: "experimental + allowing experimental", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: metaExperimental, allowExperimental: true}},
|
||||
{name: "experimental + allowing experimental", c: &fakeCandidate{path: goodPluginPath, exec: true, meta: metaExperimental}},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
p, err := newPlugin(tc.c, fakeroot, tc.c.allowExperimental)
|
||||
p, err := newPlugin(tc.c, fakeroot)
|
||||
if tc.err != "" {
|
||||
assert.ErrorContains(t, err, tc.err)
|
||||
} else if tc.invalid != "" {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package manager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
@ -30,16 +29,6 @@ func (e errPluginNotFound) Error() string {
|
|||
return "Error: No such CLI plugin: " + string(e)
|
||||
}
|
||||
|
||||
type errPluginRequireExperimental string
|
||||
|
||||
// Note: errPluginRequireExperimental implements notFound so that the plugin
|
||||
// is skipped when listing the plugins.
|
||||
func (e errPluginRequireExperimental) NotFound() {}
|
||||
|
||||
func (e errPluginRequireExperimental) Error() string {
|
||||
return fmt.Sprintf("plugin candidate %q: requires experimental CLI", string(e))
|
||||
}
|
||||
|
||||
type notFound interface{ NotFound() }
|
||||
|
||||
// IsNotFound is true if the given error is due to a plugin not being found.
|
||||
|
@ -133,7 +122,7 @@ func ListPlugins(dockerCli command.Cli, rootcmd *cobra.Command) ([]Plugin, error
|
|||
continue
|
||||
}
|
||||
c := &candidate{paths[0]}
|
||||
p, err := newPlugin(c, rootcmd, dockerCli.ClientInfo().HasExperimental)
|
||||
p, err := newPlugin(c, rootcmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -181,19 +170,12 @@ func PluginRunCommand(dockerCli command.Cli, name string, rootcmd *cobra.Command
|
|||
}
|
||||
|
||||
c := &candidate{path: path}
|
||||
plugin, err := newPlugin(c, rootcmd, dockerCli.ClientInfo().HasExperimental)
|
||||
plugin, err := newPlugin(c, rootcmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if plugin.Err != nil {
|
||||
// TODO: why are we not returning plugin.Err?
|
||||
|
||||
err := plugin.Err.(*pluginError).Cause()
|
||||
// if an experimental plugin was invoked directly while experimental mode is off
|
||||
// provide a more useful error message than "not found".
|
||||
if err, ok := err.(errPluginRequireExperimental); ok {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errPluginNotFound(name)
|
||||
}
|
||||
cmd := exec.Command(plugin.Path, args...)
|
||||
|
|
|
@ -23,6 +23,6 @@ type Metadata struct {
|
|||
// URL is a pointer to the plugin's homepage.
|
||||
URL string `json:",omitempty"`
|
||||
// Experimental specifies whether the plugin is experimental.
|
||||
// Experimental plugins are not displayed on non-experimental CLIs.
|
||||
// Deprecated: experimental features are now always enabled in the CLI
|
||||
Experimental bool `json:",omitempty"`
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ type Plugin struct {
|
|||
// non-recoverable error.
|
||||
//
|
||||
// nolint: gocyclo
|
||||
func newPlugin(c Candidate, rootcmd *cobra.Command, allowExperimental bool) (Plugin, error) {
|
||||
func newPlugin(c Candidate, rootcmd *cobra.Command) (Plugin, error) {
|
||||
path := c.Path()
|
||||
if path == "" {
|
||||
return Plugin{}, errors.New("plugin candidate path cannot be empty")
|
||||
|
@ -96,10 +96,6 @@ func newPlugin(c Candidate, rootcmd *cobra.Command, allowExperimental bool) (Plu
|
|||
p.Err = wrapAsPluginError(err, "invalid metadata")
|
||||
return p, nil
|
||||
}
|
||||
if p.Experimental && !allowExperimental {
|
||||
p.Err = &pluginError{errPluginRequireExperimental(p.Name)}
|
||||
return p, nil
|
||||
}
|
||||
if p.Metadata.SchemaVersion != "0.1.0" {
|
||||
p.Err = NewPluginError("plugin SchemaVersion %q is not valid, must be 0.1.0", p.Metadata.SchemaVersion)
|
||||
return p, nil
|
||||
|
|
23
cli/cobra.go
23
cli/cobra.go
|
@ -35,6 +35,7 @@ func setupCommonRootCommand(rootCmd *cobra.Command) (*cliflags.ClientOptions, *p
|
|||
cobra.AddTemplateFunc("vendorAndVersion", vendorAndVersion)
|
||||
cobra.AddTemplateFunc("invalidPluginReason", invalidPluginReason)
|
||||
cobra.AddTemplateFunc("isPlugin", isPlugin)
|
||||
cobra.AddTemplateFunc("isExperimental", isExperimental)
|
||||
cobra.AddTemplateFunc("decoratedName", decoratedName)
|
||||
|
||||
rootCmd.SetUsageTemplate(usageTemplate)
|
||||
|
@ -191,6 +192,19 @@ var helpCommand = &cobra.Command{
|
|||
},
|
||||
}
|
||||
|
||||
func isExperimental(cmd *cobra.Command) bool {
|
||||
if _, ok := cmd.Annotations["experimentalCLI"]; ok {
|
||||
return true
|
||||
}
|
||||
var experimental bool
|
||||
cmd.VisitParents(func(cmd *cobra.Command) {
|
||||
if _, ok := cmd.Annotations["experimentalCLI"]; ok {
|
||||
experimental = true
|
||||
}
|
||||
})
|
||||
return experimental
|
||||
}
|
||||
|
||||
func isPlugin(cmd *cobra.Command) bool {
|
||||
return cmd.Annotations[pluginmanager.CommandAnnotationPlugin] == "true"
|
||||
}
|
||||
|
@ -286,7 +300,16 @@ var usageTemplate = `Usage:
|
|||
{{- if .HasSubCommands}} {{ .CommandPath}}{{- if .HasAvailableFlags}} [OPTIONS]{{end}} COMMAND{{end}}
|
||||
|
||||
{{if ne .Long ""}}{{ .Long | trim }}{{ else }}{{ .Short | trim }}{{end}}
|
||||
{{- if isExperimental .}}
|
||||
|
||||
EXPERIMENTAL:
|
||||
{{.CommandPath}} is an experimental feature.
|
||||
Experimental features provide early access to product functionality. These
|
||||
features may change between releases without warning, or can be removed from a
|
||||
future release. Learn more about experimental features in our documentation:
|
||||
https://docs.docker.com/go/experimental/
|
||||
|
||||
{{- end}}
|
||||
{{- if gt .Aliases 0}}
|
||||
|
||||
Aliases:
|
||||
|
|
|
@ -152,16 +152,6 @@ func (cli *DockerCli) ClientInfo() ClientInfo {
|
|||
}
|
||||
|
||||
func (cli *DockerCli) loadClientInfo() error {
|
||||
var experimentalValue string
|
||||
// Environment variable always overrides configuration
|
||||
if experimentalValue = os.Getenv("DOCKER_CLI_EXPERIMENTAL"); experimentalValue == "" {
|
||||
experimentalValue = cli.ConfigFile().Experimental
|
||||
}
|
||||
hasExperimental, err := isEnabled(experimentalValue)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Experimental field")
|
||||
}
|
||||
|
||||
var v string
|
||||
if cli.client != nil {
|
||||
v = cli.client.ClientVersion()
|
||||
|
@ -170,7 +160,7 @@ func (cli *DockerCli) loadClientInfo() error {
|
|||
}
|
||||
cli.clientInfo = &ClientInfo{
|
||||
DefaultVersion: v,
|
||||
HasExperimental: hasExperimental,
|
||||
HasExperimental: true,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -358,17 +348,6 @@ func resolveDefaultDockerEndpoint(opts *cliflags.CommonOptions) (docker.Endpoint
|
|||
}, nil
|
||||
}
|
||||
|
||||
func isEnabled(value string) (bool, error) {
|
||||
switch value {
|
||||
case "enabled":
|
||||
return true, nil
|
||||
case "", "disabled":
|
||||
return false, nil
|
||||
default:
|
||||
return false, errors.Errorf("%q is not valid, should be either enabled or disabled", value)
|
||||
}
|
||||
}
|
||||
|
||||
func (cli *DockerCli) initializeFromClient() {
|
||||
ctx := context.Background()
|
||||
if strings.HasPrefix(cli.DockerEndpoint().Host, "tcp://") {
|
||||
|
@ -471,6 +450,8 @@ type ServerInfo struct {
|
|||
|
||||
// ClientInfo stores details about the supported features of the client
|
||||
type ClientInfo struct {
|
||||
// Deprecated: experimental CLI features always enabled. This field is kept
|
||||
// for backward-compatibility, and is always "true".
|
||||
HasExperimental bool
|
||||
DefaultVersion string
|
||||
}
|
||||
|
|
|
@ -167,25 +167,24 @@ func TestInitializeFromClient(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// The CLI no longer disables/hides experimental CLI features, however, we need
|
||||
// to verify that existing configuration files do not break
|
||||
func TestExperimentalCLI(t *testing.T) {
|
||||
defaultVersion := "v1.55"
|
||||
|
||||
var testcases = []struct {
|
||||
doc string
|
||||
configfile string
|
||||
expectedExperimentalCLI bool
|
||||
doc string
|
||||
configfile string
|
||||
}{
|
||||
{
|
||||
doc: "default",
|
||||
configfile: `{}`,
|
||||
expectedExperimentalCLI: false,
|
||||
doc: "default",
|
||||
configfile: `{}`,
|
||||
},
|
||||
{
|
||||
doc: "experimental",
|
||||
configfile: `{
|
||||
"experimental": "enabled"
|
||||
}`,
|
||||
expectedExperimentalCLI: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -205,7 +204,8 @@ func TestExperimentalCLI(t *testing.T) {
|
|||
cliconfig.SetDir(dir.Path())
|
||||
err := cli.Initialize(flags.NewClientOptions())
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(testcase.expectedExperimentalCLI, cli.ClientInfo().HasExperimental))
|
||||
// For backward-compatibility, HasExperimental will always be "true"
|
||||
assert.Check(t, is.Equal(true, cli.ClientInfo().HasExperimental))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ func WrapCli(dockerCli command.Cli, opts Options) (*KubeCli, error) {
|
|||
}
|
||||
|
||||
func (c *KubeCli) composeClient() (*Factory, error) {
|
||||
return NewFactory(c.kubeNamespace, c.kubeConfig, c.clientSet, c.ClientInfo().HasExperimental)
|
||||
return NewFactory(c.kubeNamespace, c.kubeConfig, c.clientSet)
|
||||
}
|
||||
|
||||
func (c *KubeCli) checkHostsMatch() error {
|
||||
|
|
|
@ -18,11 +18,10 @@ type Factory struct {
|
|||
coreClientSet corev1.CoreV1Interface
|
||||
appsClientSet appsv1beta2.AppsV1beta2Interface
|
||||
clientSet *kubeclient.Clientset
|
||||
experimental bool
|
||||
}
|
||||
|
||||
// NewFactory creates a kubernetes client factory
|
||||
func NewFactory(namespace string, config *restclient.Config, clientSet *kubeclient.Clientset, experimental bool) (*Factory, error) {
|
||||
func NewFactory(namespace string, config *restclient.Config, clientSet *kubeclient.Clientset) (*Factory, error) {
|
||||
coreClientSet, err := corev1.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -39,7 +38,6 @@ func NewFactory(namespace string, config *restclient.Config, clientSet *kubeclie
|
|||
coreClientSet: coreClientSet,
|
||||
appsClientSet: appsClientSet,
|
||||
clientSet: clientSet,
|
||||
experimental: experimental,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -85,7 +83,7 @@ func (s *Factory) DaemonSets() typesappsv1beta2.DaemonSetInterface {
|
|||
|
||||
// Stacks returns a client for Docker's Stack on Kubernetes
|
||||
func (s *Factory) Stacks(allNamespaces bool) (StackClient, error) {
|
||||
version, err := kubernetes.GetStackAPIVersion(s.clientSet.Discovery(), s.experimental)
|
||||
version, err := kubernetes.GetStackAPIVersion(s.clientSet.Discovery())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@ package system
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"text/tabwriter"
|
||||
"text/template"
|
||||
"time"
|
||||
|
@ -83,7 +83,7 @@ type clientVersion struct {
|
|||
Arch string
|
||||
BuildTime string `json:",omitempty"`
|
||||
Context string
|
||||
Experimental bool
|
||||
Experimental bool `json:",omitempty"` // Deprecated: experimental CLI features always enabled. This field is kept for backward-compatibility, and is always "true"
|
||||
}
|
||||
|
||||
type kubernetesVersion struct {
|
||||
|
@ -157,7 +157,7 @@ func runVersion(dockerCli command.Cli, opts *versionOptions) error {
|
|||
BuildTime: reformatDate(version.BuildTime),
|
||||
Os: runtime.GOOS,
|
||||
Arch: arch(),
|
||||
Experimental: dockerCli.ClientInfo().HasExperimental,
|
||||
Experimental: true,
|
||||
Context: dockerCli.CurrentContext(),
|
||||
},
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ func runVersion(dockerCli command.Cli, opts *versionOptions) error {
|
|||
"Os": sv.Os,
|
||||
"Arch": sv.Arch,
|
||||
"BuildTime": reformatDate(vd.Server.BuildTime),
|
||||
"Experimental": fmt.Sprintf("%t", sv.Experimental),
|
||||
"Experimental": strconv.FormatBool(sv.Experimental),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -274,13 +274,13 @@ func getKubernetesVersion(dockerCli command.Cli, kubeConfig string) *kubernetesV
|
|||
logrus.Debugf("failed to get Kubernetes client: %s", err)
|
||||
return &version
|
||||
}
|
||||
version.StackAPI = getStackVersion(kubeClient, dockerCli.ClientInfo().HasExperimental)
|
||||
version.StackAPI = getStackVersion(kubeClient)
|
||||
version.Kubernetes = getKubernetesServerVersion(kubeClient)
|
||||
return &version
|
||||
}
|
||||
|
||||
func getStackVersion(client *kubernetesClient.Clientset, experimental bool) string {
|
||||
apiVersion, err := kubernetes.GetStackAPIVersion(client, experimental)
|
||||
func getStackVersion(client *kubernetesClient.Clientset) string {
|
||||
apiVersion, err := kubernetes.GetStackAPIVersion(client)
|
||||
if err != nil {
|
||||
logrus.Debugf("failed to get Stack API version: %s", err)
|
||||
return "Unknown"
|
||||
|
|
|
@ -336,12 +336,11 @@ func hideSubcommandIf(subcmd *cobra.Command, condition func(string) bool, annota
|
|||
|
||||
func hideUnsupportedFeatures(cmd *cobra.Command, details versionDetails) error {
|
||||
var (
|
||||
buildKitDisabled = func(_ string) bool { v, _ := command.BuildKitEnabled(details.ServerInfo()); return !v }
|
||||
buildKitEnabled = func(_ string) bool { v, _ := command.BuildKitEnabled(details.ServerInfo()); return v }
|
||||
notExperimental = func(_ string) bool { return !details.ServerInfo().HasExperimental }
|
||||
notExperimentalCLI = func(_ string) bool { return !details.ClientInfo().HasExperimental }
|
||||
notOSType = func(v string) bool { return v != details.ServerInfo().OSType }
|
||||
versionOlderThan = func(v string) bool { return versions.LessThan(details.Client().ClientVersion(), v) }
|
||||
buildKitDisabled = func(_ string) bool { v, _ := command.BuildKitEnabled(details.ServerInfo()); return !v }
|
||||
buildKitEnabled = func(_ string) bool { v, _ := command.BuildKitEnabled(details.ServerInfo()); return v }
|
||||
notExperimental = func(_ string) bool { return !details.ServerInfo().HasExperimental }
|
||||
notOSType = func(v string) bool { return v != details.ServerInfo().OSType }
|
||||
versionOlderThan = func(v string) bool { return versions.LessThan(details.Client().ClientVersion(), v) }
|
||||
)
|
||||
|
||||
cmd.Flags().VisitAll(func(f *pflag.Flag) {
|
||||
|
@ -359,7 +358,6 @@ func hideUnsupportedFeatures(cmd *cobra.Command, details versionDetails) error {
|
|||
hideFlagIf(f, buildKitDisabled, "buildkit")
|
||||
hideFlagIf(f, buildKitEnabled, "no-buildkit")
|
||||
hideFlagIf(f, notExperimental, "experimental")
|
||||
hideFlagIf(f, notExperimentalCLI, "experimentalCLI")
|
||||
hideFlagIf(f, notOSType, "ostype")
|
||||
hideFlagIf(f, versionOlderThan, "version")
|
||||
})
|
||||
|
@ -368,7 +366,6 @@ func hideUnsupportedFeatures(cmd *cobra.Command, details versionDetails) error {
|
|||
hideSubcommandIf(subcmd, buildKitDisabled, "buildkit")
|
||||
hideSubcommandIf(subcmd, buildKitEnabled, "no-buildkit")
|
||||
hideSubcommandIf(subcmd, notExperimental, "experimental")
|
||||
hideSubcommandIf(subcmd, notExperimentalCLI, "experimentalCLI")
|
||||
hideSubcommandIf(subcmd, notOSType, "ostype")
|
||||
hideSubcommandIf(subcmd, versionOlderThan, "version")
|
||||
}
|
||||
|
@ -417,9 +414,6 @@ func areFlagsSupported(cmd *cobra.Command, details versionDetails) error {
|
|||
if _, ok := f.Annotations["experimental"]; ok && !details.ServerInfo().HasExperimental {
|
||||
errs = append(errs, fmt.Sprintf(`"--%s" is only supported on a Docker daemon with experimental features enabled`, f.Name))
|
||||
}
|
||||
if _, ok := f.Annotations["experimentalCLI"]; ok && !details.ClientInfo().HasExperimental {
|
||||
errs = append(errs, fmt.Sprintf(`"--%s" is only supported on a Docker cli with experimental cli features enabled`, f.Name))
|
||||
}
|
||||
// buildkit-specific flags are noop when buildkit is not enabled, so we do not add an error in that case
|
||||
})
|
||||
if len(errs) > 0 {
|
||||
|
@ -441,9 +435,6 @@ func areSubcommandsSupported(cmd *cobra.Command, details versionDetails) error {
|
|||
if _, ok := curr.Annotations["experimental"]; ok && !details.ServerInfo().HasExperimental {
|
||||
return fmt.Errorf("%s is only supported on a Docker daemon with experimental features enabled", cmd.CommandPath())
|
||||
}
|
||||
if _, ok := curr.Annotations["experimentalCLI"]; ok && !details.ClientInfo().HasExperimental {
|
||||
return fmt.Errorf("%s is only supported on a Docker cli with experimental cli features enabled", cmd.CommandPath())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -67,7 +67,6 @@ by the `docker` command line:
|
|||
|
||||
* `DOCKER_API_VERSION` The API version to use (e.g. `1.19`)
|
||||
* `DOCKER_CONFIG` The location of your client configuration files.
|
||||
* `DOCKER_CLI_EXPERIMENTAL` Enable experimental features for the cli (e.g. `enabled` or `disabled`)
|
||||
* `DOCKER_HOST` Daemon socket to connect to.
|
||||
* `DOCKER_STACK_ORCHESTRATOR` Configure the default orchestrator to use when using `docker stack` management commands.
|
||||
* `DOCKER_CONTENT_TRUST` When set Docker uses notary to sign and verify images.
|
||||
|
@ -318,27 +317,8 @@ Following is a sample `config.json` file:
|
|||
### Experimental features
|
||||
|
||||
Experimental features provide early access to future product functionality.
|
||||
These features are intended only for testing and feedback as they may change
|
||||
between releases without warning or can be removed entirely from a future
|
||||
release.
|
||||
|
||||
> Experimental features must not be used in production environments.
|
||||
{: .warning }
|
||||
|
||||
To enable experimental features, edit the `config.json` file and set
|
||||
`experimental` to `enabled`. The example below enables experimental features
|
||||
in a `config.json` file that already enables a debug feature.
|
||||
|
||||
```json
|
||||
{
|
||||
"experimental": "enabled",
|
||||
"debug": true
|
||||
}
|
||||
```
|
||||
|
||||
You can also enable experimental features from the Docker Desktop menu. See the
|
||||
[Docker Desktop Getting Started page](https://docs.docker.com/docker-for-mac#experimental-features)
|
||||
for more information.
|
||||
These features are intended for testing and feedback, and they may change
|
||||
between releases without warning or can be removed from a future release.
|
||||
|
||||
### Notary
|
||||
|
||||
|
|
|
@ -24,18 +24,18 @@ const (
|
|||
)
|
||||
|
||||
// GetStackAPIVersion returns the most appropriate stack API version installed.
|
||||
func GetStackAPIVersion(serverGroups discovery.ServerGroupsInterface, experimental bool) (StackVersion, error) {
|
||||
func GetStackAPIVersion(serverGroups discovery.ServerGroupsInterface) (StackVersion, error) {
|
||||
groups, err := serverGroups.ServerGroups()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return getAPIVersion(groups, experimental)
|
||||
return getAPIVersion(groups)
|
||||
}
|
||||
|
||||
func getAPIVersion(groups *metav1.APIGroupList, experimental bool) (StackVersion, error) {
|
||||
func getAPIVersion(groups *metav1.APIGroupList) (StackVersion, error) {
|
||||
switch {
|
||||
case experimental && findVersion(apiv1alpha3.SchemeGroupVersion, groups.Groups):
|
||||
case findVersion(apiv1alpha3.SchemeGroupVersion, groups.Groups):
|
||||
return StackAPIV1Alpha3, nil
|
||||
case findVersion(apiv1beta2.SchemeGroupVersion, groups.Groups):
|
||||
return StackAPIV1Beta2, nil
|
||||
|
|
|
@ -12,20 +12,18 @@ func TestGetStackAPIVersion(t *testing.T) {
|
|||
var tests = []struct {
|
||||
description string
|
||||
groups *metav1.APIGroupList
|
||||
experimental bool
|
||||
err bool
|
||||
expectedStack StackVersion
|
||||
}{
|
||||
{"no stack api", makeGroups(), false, true, ""},
|
||||
{"v1beta1", makeGroups(groupVersion{"compose.docker.com", []string{"v1beta1"}}), false, false, StackAPIV1Beta1},
|
||||
{"v1beta2", makeGroups(groupVersion{"compose.docker.com", []string{"v1beta2"}}), false, false, StackAPIV1Beta2},
|
||||
{"most recent has precedence", makeGroups(groupVersion{"compose.docker.com", []string{"v1beta1", "v1beta2"}}), false, false, StackAPIV1Beta2},
|
||||
{"most recent has precedence", makeGroups(groupVersion{"compose.docker.com", []string{"v1beta1", "v1beta2", "v1alpha3"}}), false, false, StackAPIV1Beta2},
|
||||
{"most recent has precedence", makeGroups(groupVersion{"compose.docker.com", []string{"v1beta1", "v1beta2", "v1alpha3"}}), true, false, StackAPIV1Alpha3},
|
||||
{"no stack api", makeGroups(), true, ""},
|
||||
{"v1beta1", makeGroups(groupVersion{"compose.docker.com", []string{"v1beta1"}}), false, StackAPIV1Beta1},
|
||||
{"v1beta2", makeGroups(groupVersion{"compose.docker.com", []string{"v1beta2"}}), false, StackAPIV1Beta2},
|
||||
{"most recent has precedence", makeGroups(groupVersion{"compose.docker.com", []string{"v1beta1", "v1beta2"}}), false, StackAPIV1Beta2},
|
||||
{"most recent has precedence", makeGroups(groupVersion{"compose.docker.com", []string{"v1beta1", "v1beta2", "v1alpha3"}}), false, StackAPIV1Alpha3},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
version, err := getAPIVersion(test.groups, test.experimental)
|
||||
version, err := getAPIVersion(test.groups)
|
||||
if test.err {
|
||||
assert.ErrorContains(t, err, "")
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue