2016-09-08 13:11:39 -04:00
package command
import (
2018-05-03 21:02:44 -04:00
"context"
2016-09-08 13:11:39 -04:00
"io"
"os"
2017-06-15 14:41:54 -04:00
"path/filepath"
2016-09-08 13:11:39 -04:00
"runtime"
2022-02-24 11:57:47 -05:00
"strconv"
2020-04-07 18:57:41 -04:00
"strings"
"time"
2016-09-08 13:11:39 -04:00
2017-06-15 14:41:54 -04:00
"github.com/docker/cli/cli/config"
2017-04-17 18:07:56 -04:00
"github.com/docker/cli/cli/config/configfile"
2018-12-17 05:27:07 -05:00
dcontext "github.com/docker/cli/cli/context"
"github.com/docker/cli/cli/context/docker"
"github.com/docker/cli/cli/context/store"
2018-12-10 09:41:22 -05:00
"github.com/docker/cli/cli/debug"
2017-04-17 18:07:56 -04:00
cliflags "github.com/docker/cli/cli/flags"
2017-06-15 14:41:54 -04:00
manifeststore "github.com/docker/cli/cli/manifest/store"
registryclient "github.com/docker/cli/cli/registry/client"
2019-01-28 08:52:58 -05:00
"github.com/docker/cli/cli/streams"
2017-09-12 12:39:13 -04:00
"github.com/docker/cli/cli/trust"
2019-01-08 10:03:51 -05:00
"github.com/docker/cli/cli/version"
2017-05-15 08:45:19 -04:00
dopts "github.com/docker/cli/opts"
2019-09-20 11:13:26 -04:00
"github.com/docker/docker/api"
2017-06-15 14:41:54 -04:00
"github.com/docker/docker/api/types"
2022-03-29 04:41:43 -04:00
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
2017-05-08 13:51:30 -04:00
"github.com/docker/docker/client"
2022-09-28 16:18:51 -04:00
"github.com/docker/docker/errdefs"
2016-09-08 13:11:39 -04:00
"github.com/docker/go-connections/tlsconfig"
2017-03-27 21:21:59 -04:00
"github.com/pkg/errors"
2016-11-17 13:54:10 -05:00
"github.com/spf13/cobra"
2017-10-30 12:21:41 -04:00
notaryclient "github.com/theupdateframework/notary/client"
2016-09-08 13:11:39 -04:00
)
2022-06-06 12:23:53 -04:00
const defaultInitTimeout = 2 * time . Second
2016-08-29 14:45:29 -04:00
// Streams is an interface which exposes the standard input and output streams
type Streams interface {
2019-01-28 08:52:58 -05:00
In ( ) * streams . In
Out ( ) * streams . Out
2016-08-29 14:45:29 -04:00
Err ( ) io . Writer
}
2016-12-25 16:23:35 -05:00
// Cli represents the docker command line client.
type Cli interface {
Client ( ) client . APIClient
2019-01-28 08:52:58 -05:00
Out ( ) * streams . Out
2016-12-25 16:23:35 -05:00
Err ( ) io . Writer
2019-01-28 08:52:58 -05:00
In ( ) * streams . In
SetIn ( in * streams . In )
Apply ( ops ... DockerCliOption ) error
2016-11-07 00:54:40 -05:00
ConfigFile ( ) * configfile . ConfigFile
2017-06-27 10:31:38 -04:00
ServerInfo ( ) ServerInfo
2017-09-12 12:39:13 -04:00
NotaryClient ( imgRefAndAuth trust . ImageRefAndAuth , actions [ ] string ) ( notaryclient . Repository , error )
2017-12-05 09:41:03 -05:00
DefaultVersion ( ) string
2017-06-15 14:41:54 -04:00
ManifestStore ( ) manifeststore . Store
RegistryClient ( bool ) registryclient . RegistryClient
2018-03-08 14:56:56 -05:00
ContentTrustEnabled ( ) bool
2022-02-24 11:57:47 -05:00
BuildKitEnabled ( ) ( bool , error )
2018-12-17 05:27:07 -05:00
ContextStore ( ) store . Store
CurrentContext ( ) string
2018-11-09 09:10:41 -05:00
DockerEndpoint ( ) docker . Endpoint
2016-12-25 16:23:35 -05:00
}
// DockerCli is an instance the docker command line client.
2016-09-08 13:11:39 -04:00
// Instances of the client can be returned from NewDockerCli.
type DockerCli struct {
2019-11-28 10:54:51 -05:00
configFile * configfile . ConfigFile
in * streams . In
out * streams . Out
err io . Writer
client client . APIClient
serverInfo ServerInfo
contentTrust bool
contextStore store . Store
currentContext string
dockerEndpoint docker . Endpoint
contextStoreConfig store . Config
2022-06-06 12:23:53 -04:00
initTimeout time . Duration
2016-10-06 10:09:54 -04:00
}
2021-06-15 07:03:01 -04:00
// DefaultVersion returns api.defaultVersion.
2016-11-02 20:43:32 -04:00
func ( cli * DockerCli ) DefaultVersion ( ) string {
2021-06-15 07:03:01 -04:00
return api . DefaultVersion
2016-09-08 13:11:39 -04:00
}
// Client returns the APIClient
func ( cli * DockerCli ) Client ( ) client . APIClient {
return cli . client
}
// Out returns the writer used for stdout
2019-01-28 08:52:58 -05:00
func ( cli * DockerCli ) Out ( ) * streams . Out {
2016-09-08 13:11:39 -04:00
return cli . out
}
// Err returns the writer used for stderr
func ( cli * DockerCli ) Err ( ) io . Writer {
return cli . err
}
2017-03-30 20:21:14 -04:00
// SetIn sets the reader used for stdin
2019-01-28 08:52:58 -05:00
func ( cli * DockerCli ) SetIn ( in * streams . In ) {
2017-03-30 20:21:14 -04:00
cli . in = in
}
2016-09-08 13:11:39 -04:00
// In returns the reader used for stdin
2019-01-28 08:52:58 -05:00
func ( cli * DockerCli ) In ( ) * streams . In {
2016-09-08 13:11:39 -04:00
return cli . in
}
2016-11-17 13:54:10 -05:00
// ShowHelp shows the command help.
2017-05-03 17:58:52 -04:00
func ShowHelp ( err io . Writer ) func ( * cobra . Command , [ ] string ) error {
return func ( cmd * cobra . Command , args [ ] string ) error {
2020-05-07 08:25:59 -04:00
cmd . SetOut ( err )
2017-05-03 17:58:52 -04:00
cmd . HelpFunc ( ) ( cmd , args )
return nil
}
2016-11-17 13:54:10 -05:00
}
2016-09-08 13:11:39 -04:00
// ConfigFile returns the ConfigFile
func ( cli * DockerCli ) ConfigFile ( ) * configfile . ConfigFile {
2019-09-20 11:13:26 -04:00
if cli . configFile == nil {
cli . loadConfigFile ( )
}
2016-09-08 13:11:39 -04:00
return cli . configFile
}
2019-09-20 11:13:26 -04:00
func ( cli * DockerCli ) loadConfigFile ( ) {
2022-03-04 07:24:28 -05:00
cli . configFile = config . LoadDefaultConfigFile ( cli . err )
2019-09-20 11:13:26 -04:00
}
2017-03-14 17:53:29 -04:00
// ServerInfo returns the server version details for the host this client is
// connected to
func ( cli * DockerCli ) ServerInfo ( ) ServerInfo {
2022-03-29 04:41:43 -04:00
// TODO(thaJeztah) make ServerInfo() lazily load the info (ping only when needed)
2017-12-20 09:04:41 -05:00
return cli . serverInfo
}
2018-03-14 12:36:23 -04:00
// ContentTrustEnabled returns whether content trust has been enabled by an
2018-03-08 14:56:56 -05:00
// environment variable.
func ( cli * DockerCli ) ContentTrustEnabled ( ) bool {
return cli . contentTrust
2018-03-08 08:35:17 -05:00
}
2022-02-24 11:57:47 -05:00
// BuildKitEnabled returns buildkit is enabled or not.
func ( cli * DockerCli ) BuildKitEnabled ( ) ( bool , error ) {
// use DOCKER_BUILDKIT env var value if set
if v , ok := os . LookupEnv ( "DOCKER_BUILDKIT" ) ; ok {
enabled , err := strconv . ParseBool ( v )
if err != nil {
return false , errors . Wrap ( err , "DOCKER_BUILDKIT environment variable expects boolean value" )
}
return enabled , nil
}
// if a builder alias is defined, we are using BuildKit
aliasMap := cli . ConfigFile ( ) . Aliases
if _ , ok := aliasMap [ "builder" ] ; ok {
return true , nil
}
// otherwise, assume BuildKit is enabled but
// not if wcow reported from server side
return cli . ServerInfo ( ) . OSType != "windows" , nil
}
2017-06-15 14:41:54 -04:00
// ManifestStore returns a store for local manifests
func ( cli * DockerCli ) ManifestStore ( ) manifeststore . Store {
// TODO: support override default location from config file
return manifeststore . NewStore ( filepath . Join ( config . Dir ( ) , "manifests" ) )
}
// RegistryClient returns a client for communicating with a Docker distribution
// registry
func ( cli * DockerCli ) RegistryClient ( allowInsecure bool ) registryclient . RegistryClient {
2022-03-29 04:41:43 -04:00
resolver := func ( ctx context . Context , index * registry . IndexInfo ) types . AuthConfig {
2017-06-15 14:41:54 -04:00
return ResolveAuthConfig ( ctx , cli , index )
}
return registryclient . NewRegistryClient ( resolver , UserAgent ( ) , allowInsecure )
}
2019-01-31 12:50:58 -05:00
// InitializeOpt is the type of the functional options passed to DockerCli.Initialize
type InitializeOpt func ( dockerCli * DockerCli ) error
// WithInitializeClient is passed to DockerCli.Initialize by callers who wish to set a particular API Client for use by the CLI.
func WithInitializeClient ( makeClient func ( dockerCli * DockerCli ) ( client . APIClient , error ) ) InitializeOpt {
return func ( dockerCli * DockerCli ) error {
var err error
dockerCli . client , err = makeClient ( dockerCli )
return err
}
}
2016-09-08 13:11:39 -04:00
// Initialize the dockerCli runs initialization that must happen after command
// line flags are parsed.
2019-01-31 12:50:58 -05:00
func ( cli * DockerCli ) Initialize ( opts * cliflags . ClientOptions , ops ... InitializeOpt ) error {
var err error
for _ , o := range ops {
if err := o ( cli ) ; err != nil {
return err
}
}
2018-12-10 09:41:22 -05:00
cliflags . SetLogLevel ( opts . Common . LogLevel )
if opts . ConfigDir != "" {
2022-03-04 07:24:28 -05:00
config . SetDir ( opts . ConfigDir )
2018-12-10 09:41:22 -05:00
}
if opts . Common . Debug {
debug . Enable ( )
}
2019-09-20 11:13:26 -04:00
cli . loadConfigFile ( )
2019-01-31 12:50:58 -05:00
2022-03-04 07:24:28 -05:00
baseContextStore := store . New ( config . ContextStoreDir ( ) , cli . contextStoreConfig )
2019-03-06 09:01:12 -05:00
cli . contextStore = & ContextStoreWithDefault {
2019-05-14 11:22:39 -04:00
Store : baseContextStore ,
2019-03-06 09:01:12 -05:00
Resolver : func ( ) ( * DefaultContext , error ) {
2022-03-03 12:47:36 -05:00
return ResolveDefaultContext ( opts . Common , cli . contextStoreConfig )
2019-03-06 09:01:12 -05:00
} ,
}
2019-02-25 11:35:53 -05:00
cli . currentContext , err = resolveContextName ( opts . Common , cli . configFile , cli . contextStore )
if err != nil {
return err
}
2019-03-06 09:01:12 -05:00
cli . dockerEndpoint , err = resolveDockerEndpoint ( cli . contextStore , cli . currentContext )
2019-02-26 10:08:26 -05:00
if err != nil {
return errors . Wrap ( err , "unable to resolve docker endpoint" )
}
2019-02-25 11:35:53 -05:00
2019-01-31 12:50:58 -05:00
if cli . client == nil {
2019-02-26 10:08:26 -05:00
cli . client , err = newAPIClientFromEndpoint ( cli . dockerEndpoint , cli . configFile )
2019-01-31 12:50:58 -05:00
if err != nil {
return err
2017-02-25 15:17:23 -05:00
}
2016-09-08 13:11:39 -04:00
}
2020-05-19 12:37:24 -04:00
cli . initializeFromClient ( )
2017-09-20 16:13:03 -04:00
return nil
}
2017-02-25 15:17:23 -05:00
2018-12-17 05:27:07 -05:00
// NewAPIClientFromFlags creates a new APIClient from command line flags
func NewAPIClientFromFlags ( opts * cliflags . CommonOptions , configFile * configfile . ConfigFile ) ( client . APIClient , error ) {
2019-05-16 09:52:37 -04:00
storeConfig := DefaultContextStoreConfig ( )
2021-03-03 06:07:01 -05:00
contextStore := & ContextStoreWithDefault {
2022-03-04 07:24:28 -05:00
Store : store . New ( config . ContextStoreDir ( ) , storeConfig ) ,
2019-03-06 09:01:12 -05:00
Resolver : func ( ) ( * DefaultContext , error ) {
2022-03-03 12:47:36 -05:00
return ResolveDefaultContext ( opts , storeConfig )
2019-03-06 09:01:12 -05:00
} ,
}
2021-03-03 06:07:01 -05:00
contextName , err := resolveContextName ( opts , configFile , contextStore )
2018-12-17 05:27:07 -05:00
if err != nil {
return nil , err
}
2021-03-03 06:07:01 -05:00
endpoint , err := resolveDockerEndpoint ( contextStore , contextName )
2018-12-17 05:27:07 -05:00
if err != nil {
return nil , errors . Wrap ( err , "unable to resolve docker endpoint" )
}
return newAPIClientFromEndpoint ( endpoint , configFile )
}
func newAPIClientFromEndpoint ( ep docker . Endpoint , configFile * configfile . ConfigFile ) ( client . APIClient , error ) {
clientOpts , err := ep . ClientOpts ( )
if err != nil {
return nil , err
}
2020-09-29 11:01:55 -04:00
customHeaders := make ( map [ string ] string , len ( configFile . HTTPHeaders ) )
for k , v := range configFile . HTTPHeaders {
customHeaders [ k ] = v
2018-12-17 05:27:07 -05:00
}
customHeaders [ "User-Agent" ] = UserAgent ( )
clientOpts = append ( clientOpts , client . WithHTTPHeaders ( customHeaders ) )
return client . NewClientWithOpts ( clientOpts ... )
}
2019-04-15 06:03:03 -04:00
func resolveDockerEndpoint ( s store . Reader , contextName string ) ( docker . Endpoint , error ) {
2019-04-18 09:12:30 -04:00
ctxMeta , err := s . GetMetadata ( contextName )
2019-03-06 09:01:12 -05:00
if err != nil {
return docker . Endpoint { } , err
2018-12-17 05:27:07 -05:00
}
2019-03-06 09:01:12 -05:00
epMeta , err := docker . EndpointFromContext ( ctxMeta )
if err != nil {
return docker . Endpoint { } , err
}
return docker . WithTLSData ( s , contextName , epMeta )
}
// Resolve the Docker endpoint for the default context (based on config, env vars and CLI flags)
func resolveDefaultDockerEndpoint ( opts * cliflags . CommonOptions ) ( docker . Endpoint , error ) {
2018-12-17 05:27:07 -05:00
host , err := getServerHost ( opts . Hosts , opts . TLSOptions )
if err != nil {
return docker . Endpoint { } , err
}
var (
skipTLSVerify bool
tlsData * dcontext . TLSData
)
if opts . TLSOptions != nil {
skipTLSVerify = opts . TLSOptions . InsecureSkipVerify
tlsData , err = dcontext . TLSDataFromFiles ( opts . TLSOptions . CAFile , opts . TLSOptions . CertFile , opts . TLSOptions . KeyFile )
if err != nil {
return docker . Endpoint { } , err
}
}
return docker . Endpoint {
EndpointMeta : docker . EndpointMeta {
2018-11-09 09:10:41 -05:00
Host : host ,
SkipTLSVerify : skipTLSVerify ,
2018-12-17 05:27:07 -05:00
} ,
TLSData : tlsData ,
} , nil
}
2022-06-06 12:23:53 -04:00
func ( cli * DockerCli ) getInitTimeout ( ) time . Duration {
if cli . initTimeout != 0 {
return cli . initTimeout
}
return defaultInitTimeout
}
2017-12-20 09:04:41 -05:00
func ( cli * DockerCli ) initializeFromClient ( ) {
2020-04-07 18:57:41 -04:00
ctx := context . Background ( )
2022-06-06 12:23:53 -04:00
if ! strings . HasPrefix ( cli . DockerEndpoint ( ) . Host , "ssh://" ) {
2020-04-07 18:57:41 -04:00
// @FIXME context.WithTimeout doesn't work with connhelper / ssh connections
// time="2020-04-10T10:16:26Z" level=warning msg="commandConn.CloseWrite: commandconn: failed to wait: signal: killed"
var cancel func ( )
2022-06-06 12:23:53 -04:00
ctx , cancel = context . WithTimeout ( ctx , cli . getInitTimeout ( ) )
2020-04-07 18:57:41 -04:00
defer cancel ( )
}
ping , err := cli . client . Ping ( ctx )
2017-09-20 16:13:03 -04:00
if err != nil {
2017-06-14 16:25:24 -04:00
// Default to true if we fail to connect to daemon
2017-12-20 09:04:41 -05:00
cli . serverInfo = ServerInfo { HasExperimental : true }
2017-09-20 16:13:03 -04:00
if ping . APIVersion != "" {
cli . client . NegotiateAPIVersionPing ( ping )
}
return
2016-11-02 20:43:32 -04:00
}
2017-03-14 17:53:29 -04:00
2017-12-20 09:04:41 -05:00
cli . serverInfo = ServerInfo {
2017-09-20 16:13:03 -04:00
HasExperimental : ping . Experimental ,
OSType : ping . OSType ,
2018-08-06 17:17:03 -04:00
BuildkitVersion : ping . BuilderVersion ,
2022-03-29 04:41:43 -04:00
SwarmStatus : ping . SwarmStatus ,
2017-09-20 16:13:03 -04:00
}
cli . client . NegotiateAPIVersionPing ( ping )
}
2017-09-12 12:39:13 -04:00
// NotaryClient provides a Notary Repository to interact with signed metadata for an image
func ( cli * DockerCli ) NotaryClient ( imgRefAndAuth trust . ImageRefAndAuth , actions [ ] string ) ( notaryclient . Repository , error ) {
return trust . GetNotaryRepository ( cli . In ( ) , cli . Out ( ) , UserAgent ( ) , imgRefAndAuth . RepoInfo ( ) , imgRefAndAuth . AuthConfig ( ) , actions ... )
}
2018-12-17 05:27:07 -05:00
// ContextStore returns the ContextStore
func ( cli * DockerCli ) ContextStore ( ) store . Store {
return cli . contextStore
}
// CurrentContext returns the current context name
func ( cli * DockerCli ) CurrentContext ( ) string {
return cli . currentContext
}
2018-11-09 09:10:41 -05:00
// DockerEndpoint returns the current docker endpoint
func ( cli * DockerCli ) DockerEndpoint ( ) docker . Endpoint {
return cli . dockerEndpoint
}
2019-01-28 08:52:58 -05:00
// Apply all the operation on the cli
func ( cli * DockerCli ) Apply ( ops ... DockerCliOption ) error {
for _ , op := range ops {
if err := op ( cli ) ; err != nil {
return err
}
}
return nil
}
2017-03-14 17:53:29 -04:00
// ServerInfo stores details about the supported features and platform of the
// server
type ServerInfo struct {
HasExperimental bool
OSType string
2018-08-06 17:17:03 -04:00
BuildkitVersion types . BuilderVersion
2022-03-29 04:41:43 -04:00
// SwarmStatus provides information about the current swarm status of the
// engine, obtained from the "Swarm" header in the API response.
//
// It can be a nil struct if the API version does not provide this header
// in the ping response, or if an error occurred, in which case the client
// should use other ways to get the current swarm status, such as the /swarm
// endpoint.
SwarmStatus * swarm . Status
2017-03-14 17:53:29 -04:00
}
2019-01-28 08:52:58 -05:00
// NewDockerCli returns a DockerCli instance with all operators applied on it.
2019-11-28 10:54:51 -05:00
// It applies by default the standard streams, and the content trust from
// environment.
2019-01-28 08:52:58 -05:00
func NewDockerCli ( ops ... DockerCliOption ) ( * DockerCli , error ) {
defaultOps := [ ] DockerCliOption {
WithContentTrustFromEnv ( ) ,
2021-03-03 06:09:20 -05:00
WithDefaultContextStoreConfig ( ) ,
cli/command: NewDockerCli(): use WithStandardStreams()
`NewDockerCli` was configuring the standard streams using local code; this patch
instead uses the available `WithStandardStreams()` option to do the same.
There is slight difference in the order of events;
Previously, user-provided options would be applied first, after which NewDockerCli
would check if any of "in", "out", or "err" were nil, and if so set them to the
default stream (or writer) for that output.
The new code unconditionally sets the defaults _before_ applying user-provided
options. In practive, howver, this makes no difference; the fields set are not
exported, and the only functions updating them are `WithStandardStreams`,
`WithInputStream`, and `WithCombinedStream`, neither of which checks the old
value (so always overrides).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-08-31 11:10:53 -04:00
WithStandardStreams ( ) ,
2019-01-28 08:52:58 -05:00
}
ops = append ( defaultOps , ops ... )
2021-03-03 06:09:20 -05:00
cli := & DockerCli { }
2019-01-28 08:52:58 -05:00
if err := cli . Apply ( ops ... ) ; err != nil {
return nil , err
}
return cli , nil
2016-09-08 13:11:39 -04:00
}
2018-10-11 22:30:49 -04:00
func getServerHost ( hosts [ ] string , tlsOptions * tlsconfig . Options ) ( string , error ) {
2017-10-12 11:44:03 -04:00
var host string
2016-09-08 13:11:39 -04:00
switch len ( hosts ) {
case 0 :
2022-03-24 19:15:14 -04:00
host = os . Getenv ( client . EnvOverrideHost )
2016-09-08 13:11:39 -04:00
case 1 :
host = hosts [ 0 ]
default :
return "" , errors . New ( "Please specify only one -H" )
}
2018-10-11 22:30:49 -04:00
return dopts . ParseHost ( tlsOptions != nil , host )
2016-09-08 13:11:39 -04:00
}
2016-08-29 14:45:29 -04:00
// UserAgent returns the user agent string used for making API requests
func UserAgent ( ) string {
2019-01-08 10:03:51 -05:00
return "Docker-Client/" + version . Version + " (" + runtime . GOOS + ")"
2016-09-08 13:11:39 -04:00
}
2018-12-17 05:27:07 -05:00
// 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
2022-03-24 19:15:14 -04:00
// - if --host flag or DOCKER_HOST (client.EnvOverrideHost) is set, fallbacks to use the same logic as before context-store was added
2018-12-17 05:27:07 -05:00
// 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
2019-04-15 06:03:03 -04:00
func resolveContextName ( opts * cliflags . CommonOptions , config * configfile . ConfigFile , contextstore store . Reader ) ( string , error ) {
2018-12-17 05:27:07 -05:00
if opts . Context != "" && len ( opts . Hosts ) > 0 {
2018-11-09 09:10:41 -05:00
return "" , errors . New ( "Conflicting options: either specify --host or --context, not both" )
2018-12-17 05:27:07 -05:00
}
if opts . Context != "" {
return opts . Context , nil
}
if len ( opts . Hosts ) > 0 {
2019-03-06 09:01:12 -05:00
return DefaultContextName , nil
2018-12-17 05:27:07 -05:00
}
2022-06-07 17:56:11 -04:00
if os . Getenv ( client . EnvOverrideHost ) != "" {
2019-03-06 09:01:12 -05:00
return DefaultContextName , nil
2018-12-17 05:27:07 -05:00
}
2022-07-14 14:21:20 -04:00
if ctxName := os . Getenv ( "DOCKER_CONTEXT" ) ; ctxName != "" {
2018-12-17 05:27:07 -05:00
return ctxName , nil
}
if config != nil && config . CurrentContext != "" {
2019-04-18 09:12:30 -04:00
_ , err := contextstore . GetMetadata ( config . CurrentContext )
2022-09-28 16:18:51 -04:00
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 )
2018-11-09 09:10:41 -05:00
}
return config . CurrentContext , err
2018-12-17 05:27:07 -05:00
}
2019-03-06 09:01:12 -05:00
return DefaultContextName , nil
2018-12-17 05:27:07 -05:00
}
2019-01-21 03:37:20 -05:00
2019-05-16 09:10:57 -04:00
var defaultStoreEndpoints = [ ] store . NamedTypeGetter {
store . EndpointTypeGetter ( docker . DockerEndpoint , func ( ) interface { } { return & docker . EndpointMeta { } } ) ,
}
// RegisterDefaultStoreEndpoints registers a new named endpoint
// metadata type with the default context store config, so that
// endpoint will be supported by stores using the config returned by
// DefaultContextStoreConfig.
func RegisterDefaultStoreEndpoints ( ep ... store . NamedTypeGetter ) {
defaultStoreEndpoints = append ( defaultStoreEndpoints , ep ... )
}
2019-05-16 09:52:37 -04:00
// DefaultContextStoreConfig returns a new store.Config with the default set of endpoints configured.
func DefaultContextStoreConfig ( ) store . Config {
2019-01-21 03:37:20 -05:00
return store . NewConfig (
func ( ) interface { } { return & DockerContext { } } ,
2019-05-16 09:10:57 -04:00
defaultStoreEndpoints ... ,
2019-01-21 03:37:20 -05:00
)
}