mirror of https://github.com/docker/cli.git
Merge pull request #3878 from thaJeztah/current_context_improvements
context: don't validate context when looking up name
This commit is contained in:
commit
2080390f5b
|
@ -28,7 +28,6 @@ import (
|
||||||
"github.com/docker/docker/api/types/registry"
|
"github.com/docker/docker/api/types/registry"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/errdefs"
|
|
||||||
"github.com/docker/go-connections/tlsconfig"
|
"github.com/docker/go-connections/tlsconfig"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -212,6 +211,9 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...Initialize
|
||||||
if opts.Debug {
|
if opts.Debug {
|
||||||
debug.Enable()
|
debug.Enable()
|
||||||
}
|
}
|
||||||
|
if opts.Context != "" && len(opts.Hosts) > 0 {
|
||||||
|
return errors.New("conflicting options: either specify --host or --context, not both")
|
||||||
|
}
|
||||||
|
|
||||||
cli.loadConfigFile()
|
cli.loadConfigFile()
|
||||||
|
|
||||||
|
@ -222,10 +224,7 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...Initialize
|
||||||
return ResolveDefaultContext(opts, cli.contextStoreConfig)
|
return ResolveDefaultContext(opts, cli.contextStoreConfig)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cli.currentContext, err = resolveContextName(opts, cli.configFile, cli.contextStore)
|
cli.currentContext = resolveContextName(opts, cli.configFile)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
cli.dockerEndpoint, err = resolveDockerEndpoint(cli.contextStore, cli.currentContext)
|
cli.dockerEndpoint, err = resolveDockerEndpoint(cli.contextStore, cli.currentContext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "unable to resolve docker endpoint")
|
return errors.Wrap(err, "unable to resolve docker endpoint")
|
||||||
|
@ -243,6 +242,10 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...Initialize
|
||||||
|
|
||||||
// NewAPIClientFromFlags creates a new APIClient from command line flags
|
// NewAPIClientFromFlags creates a new APIClient from command line flags
|
||||||
func NewAPIClientFromFlags(opts *cliflags.ClientOptions, configFile *configfile.ConfigFile) (client.APIClient, error) {
|
func NewAPIClientFromFlags(opts *cliflags.ClientOptions, configFile *configfile.ConfigFile) (client.APIClient, error) {
|
||||||
|
if opts.Context != "" && len(opts.Hosts) > 0 {
|
||||||
|
return nil, errors.New("conflicting options: either specify --host or --context, not both")
|
||||||
|
}
|
||||||
|
|
||||||
storeConfig := DefaultContextStoreConfig()
|
storeConfig := DefaultContextStoreConfig()
|
||||||
contextStore := &ContextStoreWithDefault{
|
contextStore := &ContextStoreWithDefault{
|
||||||
Store: store.New(config.ContextStoreDir(), storeConfig),
|
Store: store.New(config.ContextStoreDir(), storeConfig),
|
||||||
|
@ -250,11 +253,7 @@ func NewAPIClientFromFlags(opts *cliflags.ClientOptions, configFile *configfile.
|
||||||
return ResolveDefaultContext(opts, storeConfig)
|
return ResolveDefaultContext(opts, storeConfig)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
contextName, err := resolveContextName(opts, configFile, contextStore)
|
endpoint, err := resolveDockerEndpoint(contextStore, resolveContextName(opts, configFile))
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
endpoint, err := resolveDockerEndpoint(contextStore, contextName)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "unable to resolve docker endpoint")
|
return nil, errors.Wrap(err, "unable to resolve docker endpoint")
|
||||||
}
|
}
|
||||||
|
@ -363,11 +362,63 @@ func (cli *DockerCli) ContextStore() store.Store {
|
||||||
return cli.contextStore
|
return cli.contextStore
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentContext returns the current context name
|
// CurrentContext returns the current context name, based on flags,
|
||||||
|
// environment variables and the cli configuration file, in the following
|
||||||
|
// order of preference:
|
||||||
|
//
|
||||||
|
// 1. The "--context" command-line option.
|
||||||
|
// 2. The "DOCKER_CONTEXT" environment variable.
|
||||||
|
// 3. The current context as configured through the in "currentContext"
|
||||||
|
// field in the CLI configuration file ("~/.docker/config.json").
|
||||||
|
// 4. If no context is configured, use the "default" context.
|
||||||
|
//
|
||||||
|
// # Fallbacks for backward-compatibility
|
||||||
|
//
|
||||||
|
// To preserve backward-compatibility with the "pre-contexts" behavior,
|
||||||
|
// the "default" context is used if:
|
||||||
|
//
|
||||||
|
// - The "--host" option is set
|
||||||
|
// - The "DOCKER_HOST" ([DefaultContextName]) environment variable is set
|
||||||
|
// to a non-empty value.
|
||||||
|
//
|
||||||
|
// In these cases, the default context is used, which uses the host as
|
||||||
|
// specified in "DOCKER_HOST", and TLS config from flags/env vars.
|
||||||
|
//
|
||||||
|
// Setting both the "--context" and "--host" flags is ambiguous and results
|
||||||
|
// in an error when the cli is started.
|
||||||
|
//
|
||||||
|
// CurrentContext does not validate if the given context exists or if it's
|
||||||
|
// valid; errors may occur when trying to use it.
|
||||||
func (cli *DockerCli) CurrentContext() string {
|
func (cli *DockerCli) CurrentContext() string {
|
||||||
return cli.currentContext
|
return cli.currentContext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurrentContext returns the current context name, based on flags,
|
||||||
|
// environment variables and the cli configuration file. It does not
|
||||||
|
// validate if the given context exists or if it's valid; errors may
|
||||||
|
// occur when trying to use it.
|
||||||
|
//
|
||||||
|
// Refer to [DockerCli.CurrentContext] above for further details.
|
||||||
|
func resolveContextName(opts *cliflags.ClientOptions, config *configfile.ConfigFile) string {
|
||||||
|
if opts != nil && opts.Context != "" {
|
||||||
|
return opts.Context
|
||||||
|
}
|
||||||
|
if opts != nil && len(opts.Hosts) > 0 {
|
||||||
|
return DefaultContextName
|
||||||
|
}
|
||||||
|
if os.Getenv(client.EnvOverrideHost) != "" {
|
||||||
|
return DefaultContextName
|
||||||
|
}
|
||||||
|
if ctxName := os.Getenv("DOCKER_CONTEXT"); ctxName != "" {
|
||||||
|
return ctxName
|
||||||
|
}
|
||||||
|
if config != nil && config.CurrentContext != "" {
|
||||||
|
// We don't validate if this context exists: errors may occur when trying to use it.
|
||||||
|
return config.CurrentContext
|
||||||
|
}
|
||||||
|
return DefaultContextName
|
||||||
|
}
|
||||||
|
|
||||||
// DockerEndpoint returns the current docker endpoint
|
// DockerEndpoint returns the current docker endpoint
|
||||||
func (cli *DockerCli) DockerEndpoint() docker.Endpoint {
|
func (cli *DockerCli) DockerEndpoint() docker.Endpoint {
|
||||||
return cli.dockerEndpoint
|
return cli.dockerEndpoint
|
||||||
|
@ -437,40 +488,6 @@ func UserAgent() string {
|
||||||
return "Docker-Client/" + version.Version + " (" + runtime.GOOS + ")"
|
return "Docker-Client/" + version.Version + " (" + runtime.GOOS + ")"
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolveContextName resolves the current context name with the following rules:
|
|
||||||
// - setting both --context and --host flags is ambiguous
|
|
||||||
// - if --context is set, use this value
|
|
||||||
// - if --host flag or DOCKER_HOST (client.EnvOverrideHost) is set, fallbacks to use the same logic as before context-store was added
|
|
||||||
// for backward compatibility with existing scripts
|
|
||||||
// - if DOCKER_CONTEXT is set, use this value
|
|
||||||
// - if Config file has a globally set "CurrentContext", use this value
|
|
||||||
// - fallbacks to default HOST, uses TLS config from flags/env vars
|
|
||||||
func resolveContextName(opts *cliflags.ClientOptions, config *configfile.ConfigFile, contextstore store.Reader) (string, error) {
|
|
||||||
if opts.Context != "" && len(opts.Hosts) > 0 {
|
|
||||||
return "", errors.New("Conflicting options: either specify --host or --context, not both")
|
|
||||||
}
|
|
||||||
if opts.Context != "" {
|
|
||||||
return opts.Context, nil
|
|
||||||
}
|
|
||||||
if len(opts.Hosts) > 0 {
|
|
||||||
return DefaultContextName, nil
|
|
||||||
}
|
|
||||||
if os.Getenv(client.EnvOverrideHost) != "" {
|
|
||||||
return DefaultContextName, nil
|
|
||||||
}
|
|
||||||
if ctxName := os.Getenv("DOCKER_CONTEXT"); ctxName != "" {
|
|
||||||
return ctxName, nil
|
|
||||||
}
|
|
||||||
if config != nil && config.CurrentContext != "" {
|
|
||||||
_, err := contextstore.GetMetadata(config.CurrentContext)
|
|
||||||
if errdefs.IsNotFound(err) {
|
|
||||||
return "", errors.Errorf("current context %q is not found on the file system, please check your config file at %s", config.CurrentContext, config.Filename)
|
|
||||||
}
|
|
||||||
return config.CurrentContext, err
|
|
||||||
}
|
|
||||||
return DefaultContextName, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultStoreEndpoints = []store.NamedTypeGetter{
|
var defaultStoreEndpoints = []store.NamedTypeGetter{
|
||||||
store.EndpointTypeGetter(docker.DockerEndpoint, func() interface{} { return &docker.EndpointMeta{} }),
|
store.EndpointTypeGetter(docker.DockerEndpoint, func() interface{} { return &docker.EndpointMeta{} }),
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,7 +200,8 @@ func TestInitializeFromClientHangs(t *testing.T) {
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
cli := &DockerCli{client: apiClient, initTimeout: time.Millisecond}
|
cli := &DockerCli{client: apiClient, initTimeout: time.Millisecond}
|
||||||
cli.Initialize(flags.NewClientOptions())
|
err := cli.Initialize(flags.NewClientOptions())
|
||||||
|
assert.Check(t, err)
|
||||||
close(initializedCh)
|
close(initializedCh)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue