@@ -33,9 +33,6 @@ import (
3333 "github.com/theupdateframework/notary/passphrase"
3434)
3535
36- // ContextDockerHost is the reported context when DOCKER_HOST env var or -H flag is set
37- const ContextDockerHost = "<DOCKER_HOST>"
38-
3936// Streams is an interface which exposes the standard input and output streams
4037type Streams interface {
4138 In () * InStream
@@ -62,6 +59,7 @@ type Cli interface {
6259 ContextStore () store.Store
6360 CurrentContext () string
6461 StackOrchestrator (flagValue string ) (Orchestrator , error )
62+ DockerEndpoint () docker.Endpoint
6563}
6664
6765// DockerCli is an instance the docker command line client.
@@ -78,6 +76,7 @@ type DockerCli struct {
7876 newContainerizeClient func (string ) (clitypes.ContainerizedClient , error )
7977 contextStore store.Store
8078 currentContext string
79+ dockerEndpoint docker.Endpoint
8180}
8281
8382var storeConfig = store .NewConfig (
@@ -182,14 +181,15 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions) error {
182181 cli .configFile = cliconfig .LoadDefaultConfigFile (cli .err )
183182 var err error
184183 cli .contextStore = store .New (cliconfig .ContextStoreDir (), storeConfig )
185- cli .currentContext , err = resolveContextName (opts .Common , cli .configFile )
184+ cli .currentContext , err = resolveContextName (opts .Common , cli .configFile , cli . contextStore )
186185 if err != nil {
187186 return err
188187 }
189188 endpoint , err := resolveDockerEndpoint (cli .contextStore , cli .currentContext , opts .Common )
190189 if err != nil {
191190 return errors .Wrap (err , "unable to resolve docker endpoint" )
192191 }
192+ cli .dockerEndpoint = endpoint
193193
194194 cli .client , err = newAPIClientFromEndpoint (endpoint , cli .configFile )
195195 if tlsconfig .IsErrEncryptedKey (err ) {
@@ -223,7 +223,7 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions) error {
223223// NewAPIClientFromFlags creates a new APIClient from command line flags
224224func NewAPIClientFromFlags (opts * cliflags.CommonOptions , configFile * configfile.ConfigFile ) (client.APIClient , error ) {
225225 store := store .New (cliconfig .ContextStoreDir (), storeConfig )
226- contextName , err := resolveContextName (opts , configFile )
226+ contextName , err := resolveContextName (opts , configFile , store )
227227 if err != nil {
228228 return nil , err
229229 }
@@ -249,7 +249,7 @@ func newAPIClientFromEndpoint(ep docker.Endpoint, configFile *configfile.ConfigF
249249}
250250
251251func resolveDockerEndpoint (s store.Store , contextName string , opts * cliflags.CommonOptions ) (docker.Endpoint , error ) {
252- if contextName != ContextDockerHost {
252+ if contextName != "" {
253253 ctxMeta , err := s .GetContextMetadata (contextName )
254254 if err != nil {
255255 return docker.Endpoint {}, err
@@ -258,7 +258,7 @@ func resolveDockerEndpoint(s store.Store, contextName string, opts *cliflags.Com
258258 if err != nil {
259259 return docker.Endpoint {}, err
260260 }
261- return epMeta .WithTLSData (s , contextName )
261+ return docker .WithTLSData (s , contextName , epMeta )
262262 }
263263 host , err := getServerHost (opts .Hosts , opts .TLSOptions )
264264 if err != nil {
@@ -280,10 +280,8 @@ func resolveDockerEndpoint(s store.Store, contextName string, opts *cliflags.Com
280280
281281 return docker.Endpoint {
282282 EndpointMeta : docker.EndpointMeta {
283- EndpointMetaBase : dcontext.EndpointMetaBase {
284- Host : host ,
285- SkipTLSVerify : skipTLSVerify ,
286- },
283+ Host : host ,
284+ SkipTLSVerify : skipTLSVerify ,
287285 },
288286 TLSData : tlsData ,
289287 }, nil
@@ -367,15 +365,16 @@ func (cli *DockerCli) StackOrchestrator(flagValue string) (Orchestrator, error)
367365 if currentContext == "" {
368366 currentContext = configFile .CurrentContext
369367 }
370- if currentContext == "" {
371- currentContext = ContextDockerHost
372- }
373- if currentContext != ContextDockerHost {
368+ if currentContext != "" {
374369 contextstore := cli .contextStore
375370 if contextstore == nil {
376371 contextstore = store .New (cliconfig .ContextStoreDir (), storeConfig )
377372 }
378373 ctxRaw , err := contextstore .GetContextMetadata (currentContext )
374+ if store .IsErrContextDoesNotExist (err ) {
375+ // case where the currentContext has been removed (CLI behavior is to fallback to using DOCKER_HOST based resolution)
376+ return GetStackOrchestrator (flagValue , "" , configFile .StackOrchestrator , cli .Err ())
377+ }
379378 if err != nil {
380379 return "" , err
381380 }
@@ -389,6 +388,11 @@ func (cli *DockerCli) StackOrchestrator(flagValue string) (Orchestrator, error)
389388 return GetStackOrchestrator (flagValue , ctxOrchestrator , configFile .StackOrchestrator , cli .Err ())
390389}
391390
391+ // DockerEndpoint returns the current docker endpoint
392+ func (cli * DockerCli ) DockerEndpoint () docker.Endpoint {
393+ return cli .dockerEndpoint
394+ }
395+
392396// ServerInfo stores details about the supported features and platform of the
393397// server
394398type ServerInfo struct {
@@ -435,24 +439,28 @@ func UserAgent() string {
435439// - if DOCKER_CONTEXT is set, use this value
436440// - if Config file has a globally set "CurrentContext", use this value
437441// - fallbacks to default HOST, uses TLS config from flags/env vars
438- func resolveContextName (opts * cliflags.CommonOptions , config * configfile.ConfigFile ) (string , error ) {
442+ func resolveContextName (opts * cliflags.CommonOptions , config * configfile.ConfigFile , contextstore store. Store ) (string , error ) {
439443 if opts .Context != "" && len (opts .Hosts ) > 0 {
440- return "" , errors .New ("Conflicting options: either specify --host or --context, not bot " )
444+ return "" , errors .New ("Conflicting options: either specify --host or --context, not both " )
441445 }
442446 if opts .Context != "" {
443447 return opts .Context , nil
444448 }
445449 if len (opts .Hosts ) > 0 {
446- return ContextDockerHost , nil
450+ return "" , nil
447451 }
448452 if _ , present := os .LookupEnv ("DOCKER_HOST" ); present {
449- return ContextDockerHost , nil
453+ return "" , nil
450454 }
451455 if ctxName , ok := os .LookupEnv ("DOCKER_CONTEXT" ); ok {
452456 return ctxName , nil
453457 }
454458 if config != nil && config .CurrentContext != "" {
455- return config .CurrentContext , nil
459+ _ , err := contextstore .GetContextMetadata (config .CurrentContext )
460+ if store .IsErrContextDoesNotExist (err ) {
461+ return "" , errors .Errorf ("Current context %q is not found on the file system, please check your config file at %s" , config .CurrentContext , config .Filename )
462+ }
463+ return config .CurrentContext , err
456464 }
457- return ContextDockerHost , nil
465+ return "" , nil
458466}
0 commit comments