Skip to content

Commit 9bf9041

Browse files
committed
Warn if incompatible kubectl version is in use
Fixes: kubernetes#3329 Modification is done inside start.go where additional checking on the version returned via the kubectl CLI is checked. Running 'kubectl version --output=json' will return both client and server information.
1 parent 0a67493 commit 9bf9041

File tree

1 file changed

+57
-4
lines changed

1 file changed

+57
-4
lines changed

cmd/minikube/cmd/start.go

+57-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package cmd
1818

1919
import (
20+
"encoding/json"
2021
"fmt"
2122
"net"
2223
"net/url"
@@ -130,6 +131,17 @@ var (
130131
extraOptions cfg.ExtraOptionSlice
131132
)
132133

134+
type kubectlversion struct {
135+
CVersion ClientVersion `json:"clientVersion"`
136+
SVersion ClientVersion `json:"serverVersion"`
137+
}
138+
139+
type ClientVersion struct {
140+
Major string `json:"major"`
141+
Minor string `json:"minor"`
142+
GitVersion string `json:"gitVersion"`
143+
}
144+
133145
func init() {
134146
initMinikubeFlags()
135147
initKubernetesFlags()
@@ -477,16 +489,57 @@ func showVersionInfo(k8sVersion string, cr cruntime.Manager) {
477489
}
478490
}
479491

492+
/**
493+
Function to check for kubectl. The checking is to compare
494+
the version reported by both the client and server. It is
495+
that kubectl will be of the same version or 1 lower than
496+
the kubernetes version.
497+
*/
480498
func showKubectlConnectInfo(kcs *kubeconfig.Settings) {
499+
var output []byte
500+
clientVersion := kubectlversion{}
501+
serverVersion := kubectlversion{}
502+
503+
path, err := exec.LookPath("kubectl")
504+
505+
if err != nil {
506+
out.T(out.Tip, "For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/")
507+
} else {
508+
glog.Infof("Kubectl found at the following location %s. Let's execute and get the result", path)
509+
output, err = exec.Command(path, "version", "--output=json").Output()
510+
511+
// ...once we get something back do some version checking
512+
if err == nil {
513+
glog.Infof("Received output from kubectl %s", output)
514+
515+
// unmarshal both the {client}
516+
clientjsonErr := json.Unmarshal(output, &clientVersion)
517+
518+
// ....... and {server} json
519+
serverjsonErr := json.Unmarshal(output, &serverVersion)
520+
521+
if (clientjsonErr != nil) || (serverjsonErr != nil) {
522+
glog.Infof("There was an error processing the json output")
523+
} else {
524+
// obtain the minor version for both
525+
serverMinor, _ := strconv.Atoi(serverVersion.SVersion.Minor)
526+
clientMinor, _ := strconv.Atoi(serverVersion.CVersion.Minor)
527+
528+
if clientMinor < serverMinor {
529+
out.T(out.Tip, "The version of kubectl {{.kubectl}} installed is incompatible with your Kubernetes {{.kubernetes}} deployment. Please upgrade/downgrade as necessary, or use minikube kubectlto connect to your cluster",
530+
out.V{"kubectl": clientVersion.CVersion.GitVersion, "kubernetes": serverVersion.SVersion.GitVersion})
531+
}
532+
}
533+
} else {
534+
out.T(out.Tip, "For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/")
535+
}
536+
}
537+
481538
if kcs.KeepContext {
482539
out.T(out.Kubectl, "To connect to this cluster, use: kubectl --context={{.name}}", out.V{"name": kcs.ClusterName})
483540
} else {
484541
out.T(out.Ready, `Done! kubectl is now configured to use "{{.name}}"`, out.V{"name": cfg.GetMachineName()})
485542
}
486-
_, err := exec.LookPath("kubectl")
487-
if err != nil {
488-
out.T(out.Tip, "For best results, install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl/")
489-
}
490543
}
491544

492545
func selectDriver(oldConfig *cfg.Config) string {

0 commit comments

Comments
 (0)