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/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -212,6 +211,9 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...Initialize
|
|||
if opts.Debug {
|
||||
debug.Enable()
|
||||
}
|
||||
if opts.Context != "" && len(opts.Hosts) > 0 {
|
||||
return errors.New("conflicting options: either specify --host or --context, not both")
|
||||
}
|
||||
|
||||
cli.loadConfigFile()
|
||||
|
||||
|
@ -222,10 +224,7 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...Initialize
|
|||
return ResolveDefaultContext(opts, cli.contextStoreConfig)
|
||||
},
|
||||
}
|
||||
cli.currentContext, err = resolveContextName(opts, cli.configFile, cli.contextStore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cli.currentContext = resolveContextName(opts, cli.configFile)
|
||||
cli.dockerEndpoint, err = resolveDockerEndpoint(cli.contextStore, cli.currentContext)
|
||||
if err != nil {
|
||||
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
|
||||
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()
|
||||
contextStore := &ContextStoreWithDefault{
|
||||
Store: store.New(config.ContextStoreDir(), storeConfig),
|
||||
|
@ -250,11 +253,7 @@ func NewAPIClientFromFlags(opts *cliflags.ClientOptions, configFile *configfile.
|
|||
return ResolveDefaultContext(opts, storeConfig)
|
||||
},
|
||||
}
|
||||
contextName, err := resolveContextName(opts, configFile, contextStore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
endpoint, err := resolveDockerEndpoint(contextStore, contextName)
|
||||
endpoint, err := resolveDockerEndpoint(contextStore, resolveContextName(opts, configFile))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to resolve docker endpoint")
|
||||
}
|
||||
|
@ -363,11 +362,63 @@ func (cli *DockerCli) ContextStore() store.Store {
|
|||
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 {
|
||||
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
|
||||
func (cli *DockerCli) DockerEndpoint() docker.Endpoint {
|
||||
return cli.dockerEndpoint
|
||||
|
@ -437,40 +488,6 @@ func UserAgent() string {
|
|||
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{
|
||||
store.EndpointTypeGetter(docker.DockerEndpoint, func() interface{} { return &docker.EndpointMeta{} }),
|
||||
}
|
||||
|
|
|
@ -200,7 +200,8 @@ func TestInitializeFromClientHangs(t *testing.T) {
|
|||
|
||||
go func() {
|
||||
cli := &DockerCli{client: apiClient, initTimeout: time.Millisecond}
|
||||
cli.Initialize(flags.NewClientOptions())
|
||||
err := cli.Initialize(flags.NewClientOptions())
|
||||
assert.Check(t, err)
|
||||
close(initializedCh)
|
||||
}()
|
||||
|
||||
|
|
Loading…
Reference in New Issue