diff --git a/cli/command/formatter/stack.go b/cli/command/formatter/stack.go index 66b876d11b..965eaf60d5 100644 --- a/cli/command/formatter/stack.go +++ b/cli/command/formatter/stack.go @@ -5,10 +5,14 @@ import ( ) const ( - defaultStackTableFormat = "table {{.Name}}\t{{.Services}}\t{{.Orchestrator}}" + // KubernetesStackTableFormat is the default Kubernetes stack format + KubernetesStackTableFormat = "table {{.Name}}\t{{.Services}}\t{{.Orchestrator}}\t{{.Namespace}}" + // SwarmStackTableFormat is the default Swarm stack format + SwarmStackTableFormat = "table {{.Name}}\t{{.Services}}\t{{.Orchestrator}}" stackServicesHeader = "SERVICES" stackOrchestrastorHeader = "ORCHESTRATOR" + stackNamespaceHeader = "NAMESPACE" ) // Stack contains deployed stack information. @@ -17,17 +21,10 @@ type Stack struct { Name string // Services is the number of the services Services int - // Orchestratort is the platform on which the stack is deployed + // Orchestrator is the platform where the stack is deployed Orchestrator string -} - -// NewStackFormat returns a format for use with a stack Context -func NewStackFormat(source string) Format { - switch source { - case TableFormatKey: - return defaultStackTableFormat - } - return Format(source) + // Namespace is the Kubernetes namespace assigned to the stack + Namespace string } // StackWrite writes formatted stacks using the Context @@ -54,6 +51,7 @@ func newStackContext() *stackContext { "Name": nameHeader, "Services": stackServicesHeader, "Orchestrator": stackOrchestrastorHeader, + "Namespace": stackNamespaceHeader, } return &stackCtx } @@ -73,3 +71,7 @@ func (s *stackContext) Services() string { func (s *stackContext) Orchestrator() string { return s.s.Orchestrator } + +func (s *stackContext) Namespace() string { + return s.s.Namespace +} diff --git a/cli/command/formatter/stack_test.go b/cli/command/formatter/stack_test.go index 743be49dfc..27ca17e5a6 100644 --- a/cli/command/formatter/stack_test.go +++ b/cli/command/formatter/stack_test.go @@ -26,14 +26,22 @@ func TestStackContextWrite(t *testing.T) { }, // Table format { - Context{Format: NewStackFormat("table")}, + Context{Format: Format(SwarmStackTableFormat)}, `NAME SERVICES ORCHESTRATOR baz 2 orchestrator1 bar 1 orchestrator2 `, }, + // Kubernetes table format adds Namespace column { - Context{Format: NewStackFormat("table {{.Name}}")}, + Context{Format: Format(KubernetesStackTableFormat)}, + `NAME SERVICES ORCHESTRATOR NAMESPACE +baz 2 orchestrator1 namespace1 +bar 1 orchestrator2 namespace2 +`, + }, + { + Context{Format: Format("table {{.Name}}")}, `NAME baz bar @@ -41,7 +49,7 @@ bar }, // Custom Format { - Context{Format: NewStackFormat("{{.Name}}")}, + Context{Format: Format("{{.Name}}")}, `baz bar `, @@ -49,8 +57,8 @@ bar } stacks := []*Stack{ - {Name: "baz", Services: 2, Orchestrator: "orchestrator1"}, - {Name: "bar", Services: 1, Orchestrator: "orchestrator2"}, + {Name: "baz", Services: 2, Orchestrator: "orchestrator1", Namespace: "namespace1"}, + {Name: "bar", Services: 1, Orchestrator: "orchestrator2", Namespace: "namespace2"}, } for _, testcase := range cases { out := bytes.NewBufferString("") diff --git a/cli/command/stack/cmd.go b/cli/command/stack/cmd.go index 463532e972..5fe0795836 100644 --- a/cli/command/stack/cmd.go +++ b/cli/command/stack/cmd.go @@ -27,7 +27,7 @@ func NewStackCommand(dockerCli command.Cli) *cobra.Command { newServicesCommand(dockerCli), ) flags := cmd.PersistentFlags() - flags.String("namespace", "default", "Kubernetes namespace to use") + flags.String("namespace", "", "Kubernetes namespace to use") flags.SetAnnotation("namespace", "kubernetes", nil) flags.SetAnnotation("namespace", "experimentalCLI", nil) flags.String("kubeconfig", "", "Kubernetes config file") diff --git a/cli/command/stack/kubernetes/cli.go b/cli/command/stack/kubernetes/cli.go index 27064ba087..9749a41e91 100644 --- a/cli/command/stack/kubernetes/cli.go +++ b/cli/command/stack/kubernetes/cli.go @@ -1,13 +1,8 @@ package kubernetes import ( - "os" - "path/filepath" - "github.com/docker/cli/cli/command" "github.com/docker/cli/kubernetes" - "github.com/docker/docker/pkg/homedir" - "github.com/pkg/errors" flag "github.com/spf13/pflag" kubeclient "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" @@ -43,21 +38,20 @@ func NewOptions(flags *flag.FlagSet) Options { func WrapCli(dockerCli command.Cli, opts Options) (*KubeCli, error) { var err error cli := &KubeCli{ - Cli: dockerCli, - kubeNamespace: "default", + Cli: dockerCli, } - if opts.Namespace != "" { - cli.kubeNamespace = opts.Namespace - } - kubeConfig := opts.Config - if kubeConfig == "" { - if config := os.Getenv("KUBECONFIG"); config != "" { - kubeConfig = config - } else { - kubeConfig = filepath.Join(homedir.Get(), ".kube/config") + clientConfig := kubernetes.NewKubernetesConfig(opts.Config) + + cli.kubeNamespace = opts.Namespace + if opts.Namespace == "" { + configNamespace, _, err := clientConfig.Namespace() + if err != nil { + return nil, err } + cli.kubeNamespace = configNamespace } - config, err := kubernetes.NewKubernetesConfig(kubeConfig) + + config, err := clientConfig.ClientConfig() if err != nil { return nil, err } @@ -73,21 +67,5 @@ func WrapCli(dockerCli command.Cli, opts Options) (*KubeCli, error) { } func (c *KubeCli) composeClient() (*Factory, error) { - return NewFactory(c.kubeNamespace, c.kubeConfig) -} - -func (c *KubeCli) stacks() (stackClient, error) { - version, err := kubernetes.GetStackAPIVersion(c.clientSet) - if err != nil { - return nil, err - } - - switch version { - case kubernetes.StackAPIV1Beta1: - return newStackV1Beta1(c.kubeConfig, c.kubeNamespace) - case kubernetes.StackAPIV1Beta2: - return newStackV1Beta2(c.kubeConfig, c.kubeNamespace) - default: - return nil, errors.Errorf("no supported Stack API version") - } + return NewFactory(c.kubeNamespace, c.kubeConfig, c.clientSet) } diff --git a/cli/command/stack/kubernetes/client.go b/cli/command/stack/kubernetes/client.go index a44bf44590..76361e6492 100644 --- a/cli/command/stack/kubernetes/client.go +++ b/cli/command/stack/kubernetes/client.go @@ -1,6 +1,10 @@ package kubernetes import ( + "github.com/docker/cli/kubernetes" + "github.com/pkg/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kubeclient "k8s.io/client-go/kubernetes" appsv1beta2 "k8s.io/client-go/kubernetes/typed/apps/v1beta2" typesappsv1beta2 "k8s.io/client-go/kubernetes/typed/apps/v1beta2" corev1 "k8s.io/client-go/kubernetes/typed/core/v1" @@ -13,10 +17,11 @@ type Factory struct { config *restclient.Config coreClientSet *corev1.CoreV1Client appsClientSet *appsv1beta2.AppsV1beta2Client + clientSet *kubeclient.Clientset } // NewFactory creates a kubernetes client factory -func NewFactory(namespace string, config *restclient.Config) (*Factory, error) { +func NewFactory(namespace string, config *restclient.Config, clientSet *kubeclient.Clientset) (*Factory, error) { coreClientSet, err := corev1.NewForConfig(config) if err != nil { return nil, err @@ -32,6 +37,7 @@ func NewFactory(namespace string, config *restclient.Config) (*Factory, error) { config: config, coreClientSet: coreClientSet, appsClientSet: appsClientSet, + clientSet: clientSet, }, nil } @@ -65,7 +71,28 @@ func (s *Factory) ReplicationControllers() corev1.ReplicationControllerInterface return s.coreClientSet.ReplicationControllers(s.namespace) } -// ReplicaSets return a client for kubernetes replace sets +// ReplicaSets returns a client for kubernetes replace sets func (s *Factory) ReplicaSets() typesappsv1beta2.ReplicaSetInterface { return s.appsClientSet.ReplicaSets(s.namespace) } + +// Stacks returns a client for Docker's Stack on Kubernetes +func (s *Factory) Stacks(allNamespaces bool) (StackClient, error) { + version, err := kubernetes.GetStackAPIVersion(s.clientSet) + if err != nil { + return nil, err + } + namespace := s.namespace + if allNamespaces { + namespace = metav1.NamespaceAll + } + + switch version { + case kubernetes.StackAPIV1Beta1: + return newStackV1Beta1(s.config, namespace) + case kubernetes.StackAPIV1Beta2: + return newStackV1Beta2(s.config, namespace) + default: + return nil, errors.Errorf("no supported Stack API version") + } +} diff --git a/cli/command/stack/kubernetes/convert.go b/cli/command/stack/kubernetes/convert.go index fbddacc4e8..aa63daf276 100644 --- a/cli/command/stack/kubernetes/convert.go +++ b/cli/command/stack/kubernetes/convert.go @@ -37,6 +37,7 @@ func stackFromV1beta1(in *v1beta1.Stack) (stack, error) { } return stack{ name: in.ObjectMeta.Name, + namespace: in.ObjectMeta.Namespace, composeFile: in.Spec.ComposeFile, spec: fromComposeConfig(ioutil.Discard, cfg), }, nil @@ -55,8 +56,9 @@ func stackToV1beta1(s stack) *v1beta1.Stack { func stackFromV1beta2(in *v1beta2.Stack) stack { return stack{ - name: in.ObjectMeta.Name, - spec: in.Spec, + name: in.ObjectMeta.Name, + namespace: in.ObjectMeta.Namespace, + spec: in.Spec, } } diff --git a/cli/command/stack/kubernetes/deploy.go b/cli/command/stack/kubernetes/deploy.go index b708b9f4e6..48030a60f4 100644 --- a/cli/command/stack/kubernetes/deploy.go +++ b/cli/command/stack/kubernetes/deploy.go @@ -17,11 +17,11 @@ func RunDeploy(dockerCli *KubeCli, opts options.Deploy) error { } // Initialize clients - stacks, err := dockerCli.stacks() + composeClient, err := dockerCli.composeClient() if err != nil { return err } - composeClient, err := dockerCli.composeClient() + stacks, err := composeClient.Stacks(false) if err != nil { return err } diff --git a/cli/command/stack/kubernetes/list.go b/cli/command/stack/kubernetes/list.go index d513872a6d..cc4b3ef981 100644 --- a/cli/command/stack/kubernetes/list.go +++ b/cli/command/stack/kubernetes/list.go @@ -11,17 +11,17 @@ import ( // RunList is the kubernetes implementation of docker stack ls func RunList(dockerCli *KubeCli, opts options.List) error { - stacks, err := getStacks(dockerCli) + stacks, err := getStacks(dockerCli, opts.AllNamespaces) if err != nil { return err } format := opts.Format - if len(format) == 0 { - format = formatter.TableFormatKey + if format == "" || format == formatter.TableFormatKey { + format = formatter.KubernetesStackTableFormat } stackCtx := formatter.Context{ Output: dockerCli.Out(), - Format: formatter.NewStackFormat(format), + Format: formatter.Format(format), } sort.Sort(byName(stacks)) return formatter.StackWrite(stackCtx, stacks) @@ -33,12 +33,15 @@ func (n byName) Len() int { return len(n) } func (n byName) Swap(i, j int) { n[i], n[j] = n[j], n[i] } func (n byName) Less(i, j int) bool { return sortorder.NaturalLess(n[i].Name, n[j].Name) } -func getStacks(kubeCli *KubeCli) ([]*formatter.Stack, error) { - stackSvc, err := kubeCli.stacks() +func getStacks(kubeCli *KubeCli, allNamespaces bool) ([]*formatter.Stack, error) { + composeClient, err := kubeCli.composeClient() + if err != nil { + return nil, err + } + stackSvc, err := composeClient.Stacks(allNamespaces) if err != nil { return nil, err } - stacks, err := stackSvc.List(metav1.ListOptions{}) if err != nil { return nil, err @@ -49,6 +52,7 @@ func getStacks(kubeCli *KubeCli) ([]*formatter.Stack, error) { Name: stack.name, Services: len(stack.getServices()), Orchestrator: "Kubernetes", + Namespace: stack.namespace, }) } return formattedStacks, nil diff --git a/cli/command/stack/kubernetes/ps.go b/cli/command/stack/kubernetes/ps.go index 60fdb32e5d..ded56db19d 100644 --- a/cli/command/stack/kubernetes/ps.go +++ b/cli/command/stack/kubernetes/ps.go @@ -25,7 +25,7 @@ func RunPS(dockerCli *KubeCli, options options.PS) error { if err != nil { return err } - stacks, err := dockerCli.stacks() + stacks, err := client.Stacks(false) if err != nil { return err } diff --git a/cli/command/stack/kubernetes/remove.go b/cli/command/stack/kubernetes/remove.go index bf3654a7a4..af68db7f30 100644 --- a/cli/command/stack/kubernetes/remove.go +++ b/cli/command/stack/kubernetes/remove.go @@ -8,7 +8,11 @@ import ( // RunRemove is the kubernetes implementation of docker stack remove func RunRemove(dockerCli *KubeCli, opts options.Remove) error { - stacks, err := dockerCli.stacks() + composeClient, err := dockerCli.composeClient() + if err != nil { + return err + } + stacks, err := composeClient.Stacks(false) if err != nil { return err } diff --git a/cli/command/stack/kubernetes/services.go b/cli/command/stack/kubernetes/services.go index 1c98c4fd6c..b1a4a5f42f 100644 --- a/cli/command/stack/kubernetes/services.go +++ b/cli/command/stack/kubernetes/services.go @@ -16,7 +16,7 @@ func RunServices(dockerCli *KubeCli, opts options.Services) error { if err != nil { return nil } - stacks, err := dockerCli.stacks() + stacks, err := client.Stacks(false) if err != nil { return err } diff --git a/cli/command/stack/kubernetes/stack.go b/cli/command/stack/kubernetes/stack.go index 76cf07aa20..dedae3707f 100644 --- a/cli/command/stack/kubernetes/stack.go +++ b/cli/command/stack/kubernetes/stack.go @@ -15,6 +15,7 @@ import ( // stack is the main type used by stack commands so they remain independent from kubernetes compose component version. type stack struct { name string + namespace string composeFile string spec *v1beta2.StackSpec } diff --git a/cli/command/stack/kubernetes/stackclient.go b/cli/command/stack/kubernetes/stackclient.go index 686023a03b..763650f15b 100644 --- a/cli/command/stack/kubernetes/stackclient.go +++ b/cli/command/stack/kubernetes/stackclient.go @@ -14,8 +14,8 @@ import ( "k8s.io/client-go/rest" ) -// stackClient talks to a kubernetes compose component. -type stackClient interface { +// StackClient talks to a kubernetes compose component. +type StackClient interface { CreateOrUpdate(s stack) error Delete(name string) error Get(name string) (stack, error) @@ -29,7 +29,7 @@ type stackV1Beta1 struct { stacks composev1beta1.StackInterface } -func newStackV1Beta1(config *rest.Config, namespace string) (stackClient, error) { +func newStackV1Beta1(config *rest.Config, namespace string) (StackClient, error) { client, err := composev1beta1.NewForConfig(config) if err != nil { return nil, err @@ -122,7 +122,7 @@ type stackV1Beta2 struct { stacks composev1beta2.StackInterface } -func newStackV1Beta2(config *rest.Config, namespace string) (stackClient, error) { +func newStackV1Beta2(config *rest.Config, namespace string) (StackClient, error) { client, err := composev1beta2.NewForConfig(config) if err != nil { return nil, err diff --git a/cli/command/stack/list.go b/cli/command/stack/list.go index b153a8b2f6..fc96fd6791 100644 --- a/cli/command/stack/list.go +++ b/cli/command/stack/list.go @@ -31,5 +31,7 @@ func newListCommand(dockerCli command.Cli) *cobra.Command { flags := cmd.Flags() flags.StringVar(&opts.Format, "format", "", "Pretty-print stacks using a Go template") + flags.BoolVarP(&opts.AllNamespaces, "all-namespaces", "", false, "List stacks among all Kubernetes namespaces") + flags.SetAnnotation("all-namespaces", "kubernetes", nil) return cmd } diff --git a/cli/command/stack/options/opts.go b/cli/command/stack/options/opts.go index 8c8a1acf26..f620fe54a9 100644 --- a/cli/command/stack/options/opts.go +++ b/cli/command/stack/options/opts.go @@ -14,7 +14,8 @@ type Deploy struct { // List holds docker stack ls options type List struct { - Format string + Format string + AllNamespaces bool } // PS holds docker stack ps options diff --git a/cli/command/stack/swarm/list.go b/cli/command/stack/swarm/list.go index c9fcc8ffc5..b80e4ab8c5 100644 --- a/cli/command/stack/swarm/list.go +++ b/cli/command/stack/swarm/list.go @@ -24,12 +24,12 @@ func RunList(dockerCli command.Cli, opts options.List) error { return err } format := opts.Format - if len(format) == 0 { - format = formatter.TableFormatKey + if format == "" || format == formatter.TableFormatKey { + format = formatter.SwarmStackTableFormat } stackCtx := formatter.Context{ Output: dockerCli.Out(), - Format: formatter.NewStackFormat(format), + Format: formatter.Format(format), } sort.Sort(byName(stacks)) return formatter.StackWrite(stackCtx, stacks) diff --git a/cli/command/system/version.go b/cli/command/system/version.go index c8e3654cbd..e925843b3d 100644 --- a/cli/command/system/version.go +++ b/cli/command/system/version.go @@ -228,7 +228,8 @@ func getKubernetesVersion(dockerCli command.Cli, kubeConfig string) *kubernetesV Kubernetes: "Unknown", StackAPI: "Unknown", } - config, err := kubernetes.NewKubernetesConfig(kubeConfig) + clientConfig := kubernetes.NewKubernetesConfig(kubeConfig) + config, err := clientConfig.ClientConfig() if err != nil { logrus.Debugf("failed to get Kubernetes configuration: %s", err) return &version diff --git a/docs/reference/commandline/stack_ls.md b/docs/reference/commandline/stack_ls.md index 7205bc8acb..6613577e64 100644 --- a/docs/reference/commandline/stack_ls.md +++ b/docs/reference/commandline/stack_ls.md @@ -55,6 +55,7 @@ Valid placeholders for the Go template are listed below: | `.Name` | Stack name | | `.Services` | Number of services | | `.Orchestrator` | Orchestrator name | +| `.Namespace` | Namespace | When using the `--format` option, the `stack ls` command either outputs the data exactly as the template declares or, when using the diff --git a/kubernetes/client/clientset/clientset.go b/kubernetes/client/clientset/clientset.go index 01af87898e..b9cea6bb14 100644 --- a/kubernetes/client/clientset/clientset.go +++ b/kubernetes/client/clientset/clientset.go @@ -3,10 +3,10 @@ package clientset import ( composev1beta1 "github.com/docker/cli/kubernetes/client/clientset/typed/compose/v1beta1" composev1beta2 "github.com/docker/cli/kubernetes/client/clientset/typed/compose/v1beta2" - glog "github.com/golang/glog" - discovery "k8s.io/client-go/discovery" - rest "k8s.io/client-go/rest" - flowcontrol "k8s.io/client-go/util/flowcontrol" + "github.com/golang/glog" + "k8s.io/client-go/discovery" + "k8s.io/client-go/rest" + "k8s.io/client-go/util/flowcontrol" ) // Interface defines the methods a compose kube client should have diff --git a/kubernetes/client/clientset/scheme/register.go b/kubernetes/client/clientset/scheme/register.go index 9298122bb1..ffd6e4f009 100644 --- a/kubernetes/client/clientset/scheme/register.go +++ b/kubernetes/client/clientset/scheme/register.go @@ -3,10 +3,10 @@ package scheme import ( composev1beta1 "github.com/docker/cli/kubernetes/compose/v1beta1" composev1beta2 "github.com/docker/cli/kubernetes/compose/v1beta2" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - schema "k8s.io/apimachinery/pkg/runtime/schema" - serializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" ) // Variables required for registration diff --git a/kubernetes/client/clientset/typed/compose/v1beta1/compose_client.go b/kubernetes/client/clientset/typed/compose/v1beta1/compose_client.go index 57e836f8d5..4039d4de13 100644 --- a/kubernetes/client/clientset/typed/compose/v1beta1/compose_client.go +++ b/kubernetes/client/clientset/typed/compose/v1beta1/compose_client.go @@ -2,9 +2,9 @@ package v1beta1 import ( "github.com/docker/cli/kubernetes/client/clientset/scheme" - v1beta1 "github.com/docker/cli/kubernetes/compose/v1beta1" - serializer "k8s.io/apimachinery/pkg/runtime/serializer" - rest "k8s.io/client-go/rest" + "github.com/docker/cli/kubernetes/compose/v1beta1" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/client-go/rest" ) // ComposeV1beta1Interface defines the methods a compose v1beta1 client has diff --git a/kubernetes/client/clientset/typed/compose/v1beta1/stack.go b/kubernetes/client/clientset/typed/compose/v1beta1/stack.go index c3f13811fd..1fbe53f813 100644 --- a/kubernetes/client/clientset/typed/compose/v1beta1/stack.go +++ b/kubernetes/client/clientset/typed/compose/v1beta1/stack.go @@ -1,12 +1,12 @@ package v1beta1 import ( - scheme "github.com/docker/cli/kubernetes/client/clientset/scheme" - v1beta1 "github.com/docker/cli/kubernetes/compose/v1beta1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" + "github.com/docker/cli/kubernetes/client/clientset/scheme" + "github.com/docker/cli/kubernetes/compose/v1beta1" + "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/rest" ) // StacksGetter has a method to return a StackInterface. diff --git a/kubernetes/client/clientset/typed/compose/v1beta2/compose_client.go b/kubernetes/client/clientset/typed/compose/v1beta2/compose_client.go index cbb6fa59a8..34bee389c5 100644 --- a/kubernetes/client/clientset/typed/compose/v1beta2/compose_client.go +++ b/kubernetes/client/clientset/typed/compose/v1beta2/compose_client.go @@ -2,9 +2,9 @@ package v1beta2 import ( "github.com/docker/cli/kubernetes/client/clientset/scheme" - v1beta2 "github.com/docker/cli/kubernetes/compose/v1beta2" - serializer "k8s.io/apimachinery/pkg/runtime/serializer" - rest "k8s.io/client-go/rest" + "github.com/docker/cli/kubernetes/compose/v1beta2" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/client-go/rest" ) // ComposeV1beta2Interface defines the methods a compose v1beta2 client has diff --git a/kubernetes/client/clientset/typed/compose/v1beta2/stack.go b/kubernetes/client/clientset/typed/compose/v1beta2/stack.go index 84ac41e6da..6937b4bfba 100644 --- a/kubernetes/client/clientset/typed/compose/v1beta2/stack.go +++ b/kubernetes/client/clientset/typed/compose/v1beta2/stack.go @@ -1,12 +1,12 @@ package v1beta2 import ( - scheme "github.com/docker/cli/kubernetes/client/clientset/scheme" - v1beta2 "github.com/docker/cli/kubernetes/compose/v1beta2" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" + "github.com/docker/cli/kubernetes/client/clientset/scheme" + "github.com/docker/cli/kubernetes/compose/v1beta2" + "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/rest" ) // StacksGetter has a method to return a StackInterface. diff --git a/kubernetes/config.go b/kubernetes/config.go index 3a9fdfc6dc..287a6a6bf0 100644 --- a/kubernetes/config.go +++ b/kubernetes/config.go @@ -5,14 +5,13 @@ import ( "path/filepath" "github.com/docker/docker/pkg/homedir" - restclient "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" ) -// NewKubernetesConfig resolves the path to the desired Kubernetes configuration file, depending -// environment variable and command line flag. -func NewKubernetesConfig(configFlag string) (*restclient.Config, error) { - kubeConfig := configFlag +// NewKubernetesConfig resolves the path to the desired Kubernetes configuration file based on +// the KUBECONFIG environment variable and command line flags. +func NewKubernetesConfig(configPath string) clientcmd.ClientConfig { + kubeConfig := configPath if kubeConfig == "" { if config := os.Getenv("KUBECONFIG"); config != "" { kubeConfig = config @@ -20,5 +19,8 @@ func NewKubernetesConfig(configFlag string) (*restclient.Config, error) { kubeConfig = filepath.Join(homedir.Get(), ".kube/config") } } - return clientcmd.BuildConfigFromFlags("", kubeConfig) + + return clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeConfig}, + &clientcmd.ConfigOverrides{}) }