Skip to content

Commit

Permalink
Merge pull request #5798 from nanikjava/f-fix-2570
Browse files Browse the repository at this point in the history
Make Kubernetes version sticky for a cluster instead of auto-upgrading
  • Loading branch information
tstromberg authored Dec 9, 2019
2 parents 92b646d + f680d1b commit a6c749f
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 9 deletions.
26 changes: 19 additions & 7 deletions cmd/minikube/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func initMinikubeFlags() {

// initKubernetesFlags inits the commandline flags for kubernetes related options
func initKubernetesFlags() {
startCmd.Flags().String(kubernetesVersion, constants.DefaultKubernetesVersion, "The kubernetes version that the minikube VM will use (ex: v1.2.3)")
startCmd.Flags().String(kubernetesVersion, "", "The kubernetes version that the minikube VM will use (ex: v1.2.3)")
startCmd.Flags().Var(&extraOptions, "extra-config",
`A set of key=value pairs that describe configuration that may be passed to different components.
The key should be '.' separated, and the first part before the dot is the component to apply the configuration to.
Expand Down Expand Up @@ -1120,15 +1120,20 @@ func tryRegistry(r command.Runner) {

// getKubernetesVersion ensures that the requested version is reasonable
func getKubernetesVersion(old *cfg.MachineConfig) (string, bool) {
rawVersion := viper.GetString(kubernetesVersion)
paramVersion := viper.GetString(kubernetesVersion)
isUpgrade := false
if rawVersion == "" {
rawVersion = constants.DefaultKubernetesVersion

if paramVersion == "" { // if the user did not specify any version then ...
if old != nil { // .. use the old version from config
paramVersion = old.KubernetesConfig.KubernetesVersion
} else { // .. otherwise use the default version
paramVersion = constants.DefaultKubernetesVersion
}
}

nvs, err := semver.Make(strings.TrimPrefix(rawVersion, version.VersionPrefix))
nvs, err := semver.Make(strings.TrimPrefix(paramVersion, version.VersionPrefix))
if err != nil {
exit.WithCodeT(exit.Data, `Unable to parse "{{.kubernetes_version}}": {{.error}}`, out.V{"kubernetes_version": rawVersion, "error": err})
exit.WithCodeT(exit.Data, `Unable to parse "{{.kubernetes_version}}": {{.error}}`, out.V{"kubernetes_version": paramVersion, "error": err})
}
nv := version.VersionPrefix + nvs.String()

Expand All @@ -1140,6 +1145,10 @@ func getKubernetesVersion(old *cfg.MachineConfig) (string, bool) {
if err != nil {
exit.WithCodeT(exit.Data, "Unable to parse oldest Kubernetes version from constants: {{.error}}", out.V{"error": err})
}
defaultVersion, err := semver.Make(strings.TrimPrefix(constants.DefaultKubernetesVersion, version.VersionPrefix))
if err != nil {
exit.WithCodeT(exit.Data, "Unable to parse default Kubernetes version from constants: {{.error}}", out.V{"error": err})
}

if nvs.LT(oldestVersion) {
out.WarningT("Specified Kubernetes version {{.specified}} is less than the oldest supported version: {{.oldest}}", out.V{"specified": nvs, "oldest": constants.OldestKubernetesVersion})
Expand Down Expand Up @@ -1168,8 +1177,11 @@ func getKubernetesVersion(old *cfg.MachineConfig) (string, bool) {
* Reuse the existing cluster with Kubernetes v{{.old}} or newer: Run "minikube start {{.profile}} --kubernetes-version={{.old}}"`, out.V{"new": nvs, "old": ovs, "profile": profileArg})

}
if defaultVersion.GT(nvs) {
out.T(out.ThumbsUp, "Kubernetes {{.new}} is now available. If you would like to upgrade, specify: --kubernetes-version={{.new}}", out.V{"new": defaultVersion})
}

if nvs.GT(ovs) {
out.T(out.ThumbsUp, "Upgrading from Kubernetes {{.old}} to {{.new}}", out.V{"old": ovs, "new": nvs})
isUpgrade = true
}
return nv, isUpgrade
Expand Down
55 changes: 55 additions & 0 deletions cmd/minikube/cmd/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,64 @@ import (

"github.com/spf13/cobra"
"github.com/spf13/viper"
cfg "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
)

func TestGetKuberneterVersion(t *testing.T) {
var tests = []struct {
description string
expectedVersion string
paramVersion string
upgrade bool
cfg *cfg.MachineConfig
}{
{
description: "kubernetes-version not given, no config",
expectedVersion: constants.DefaultKubernetesVersion,
paramVersion: "",
upgrade: false,
},
{
description: "kubernetes-version not given, config available",
expectedVersion: "v1.15.0",
paramVersion: "",
upgrade: false,
cfg: &cfg.MachineConfig{KubernetesConfig: cfg.KubernetesConfig{KubernetesVersion: "v1.15.0"}},
},
{
description: "kubernetes-version given, no config",
expectedVersion: "v1.15.0",
paramVersion: "v1.15.0",
upgrade: false,
},
{
description: "kubernetes-version given, config available",
expectedVersion: "v1.16.0",
paramVersion: "v1.16.0",
upgrade: true,
cfg: &cfg.MachineConfig{KubernetesConfig: cfg.KubernetesConfig{KubernetesVersion: "v1.15.0"}},
},
}

for _, test := range tests {
t.Run(test.description, func(t *testing.T) {
viper.SetDefault(kubernetesVersion, test.paramVersion)
version, upgrade := getKubernetesVersion(test.cfg)

// check whether we are getting the expected version
if version != test.expectedVersion {
t.Fatalf("test failed because the expected version %s is not returned", test.expectedVersion)
}

// check whether the upgrade flag is correct
if test.upgrade != upgrade {
t.Fatalf("test failed expected upgrade is %t", test.upgrade)
}
})
}
}

func TestGenerateCfgFromFlagsHTTPProxyHandling(t *testing.T) {
viper.SetDefault(memory, defaultMemorySize)
viper.SetDefault(humanReadableDiskSize, defaultDiskSize)
Expand Down
36 changes: 34 additions & 2 deletions test/integration/version_upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package integration

import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"os"
Expand All @@ -28,6 +29,7 @@ import (
"time"

"github.com/docker/machine/libmachine/state"

"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/util/retry"

Expand Down Expand Up @@ -66,13 +68,13 @@ func TestVersionUpgrade(t *testing.T) {

args := append([]string{"start", "-p", profile, fmt.Sprintf("--kubernetes-version=%s", constants.OldestKubernetesVersion), "--alsologtostderr", "-v=1"}, StartArgs()...)
rr := &RunResult{}
releaseStart := func() error {
r := func() error {
rr, err = Run(t, exec.CommandContext(ctx, tf.Name(), args...))
return err
}

// Retry to allow flakiness for the previous release
if err := retry.Expo(releaseStart, 1*time.Second, 30*time.Minute, 3); err != nil {
if err := retry.Expo(r, 1*time.Second, 30*time.Minute, 3); err != nil {
t.Fatalf("release start failed: %v", err)
}

Expand All @@ -96,4 +98,34 @@ func TestVersionUpgrade(t *testing.T) {
if err != nil {
t.Errorf("%s failed: %v", rr.Args, err)
}

s, err := Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "version", "--output=json"))
if err != nil {
t.Fatalf("error running kubectl: %v", err)
}
cv := struct {
ServerVersion struct {
GitVersion string `json:"gitVersion"`
} `json:"serverVersion"`
}{}
err = json.Unmarshal(s.Stdout.Bytes(), &cv)

if err != nil {
t.Fatalf("error traversing json output: %v", err)
}

if cv.ServerVersion.GitVersion != constants.NewestKubernetesVersion {
t.Fatalf("expected server version %s is not the same with latest version %s", cv.ServerVersion.GitVersion, constants.NewestKubernetesVersion)
}

args = append([]string{"start", "-p", profile, fmt.Sprintf("--kubernetes-version=%s", constants.OldestKubernetesVersion), "--alsologtostderr", "-v=1"}, StartArgs()...)
rr = &RunResult{}
r = func() error {
rr, err = Run(t, exec.CommandContext(ctx, tf.Name(), args...))
return err
}

if err := retry.Expo(r, 1*time.Second, 30*time.Minute, 3); err == nil {
t.Fatalf("downgrading kubernetes should not be allowed: %v", err)
}
}

0 comments on commit a6c749f

Please sign in to comment.