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"
2016-09-08 13:11:39 -04:00
"github.com/docker/go-connections/tlsconfig"
2020-04-16 05:23:37 -04:00
"github.com/moby/term"
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
)
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
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 ) {
2019-05-16 09:52:37 -04:00
return ResolveDefaultContext ( opts . Common , cli . ConfigFile ( ) , cli . contextStoreConfig , cli . Err ( ) )
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-02-25 08:35:28 -05:00
return ResolveDefaultContext ( opts , configFile , storeConfig , io . Discard )
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
}
2017-12-20 09:04:41 -05:00
func ( cli * DockerCli ) initializeFromClient ( ) {
2020-04-07 18:57:41 -04:00
ctx := context . Background ( )
if strings . HasPrefix ( cli . DockerEndpoint ( ) . Host , "tcp://" ) {
// @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 ( )
ctx , cancel = context . WithTimeout ( ctx , 2 * time . Second )
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 ( ) ,
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
}
if cli . out == nil || cli . in == nil || cli . err == nil {
stdin , stdout , stderr := term . StdStreams ( )
if cli . in == nil {
cli . in = streams . NewIn ( stdin )
}
if cli . out == nil {
cli . out = streams . NewOut ( stdout )
}
if cli . err == nil {
cli . err = stderr
}
}
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-03-24 19:15:14 -04:00
if _ , present := os . LookupEnv ( client . EnvOverrideHost ) ; present {
2019-03-06 09:01:12 -05:00
return DefaultContextName , nil
2018-12-17 05:27:07 -05:00
}
if ctxName , ok := os . LookupEnv ( "DOCKER_CONTEXT" ) ; ok {
return ctxName , nil
}
if config != nil && config . CurrentContext != "" {
2019-04-18 09:12:30 -04:00
_ , err := contextstore . GetMetadata ( config . CurrentContext )
2018-11-09 09:10:41 -05:00
if store . IsErrContextDoesNotExist ( 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
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
)
}