Merge pull request #69301 from neolit123/kubeadm-version-stable

kubeadm: handle stable-1 as the default version
pull/58/head
k8s-ci-robot 2018-10-10 12:01:18 -07:00 committed by GitHub
commit 77742ea94c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 111 additions and 5 deletions

View File

@ -78,6 +78,10 @@ func KubernetesReleaseVersion(version string) (string, error) {
// kubeReleaseLabelRegex matches labels such as: latest, latest-1, latest-1.10
if kubeReleaseLabelRegex.MatchString(versionLabel) {
var clientVersion string
// Try to obtain a client version.
clientVersion, _ = kubeadmVersion(pkgversion.Get().String())
// Fetch version from the internet.
url := fmt.Sprintf("%s/%s.txt", bucketURL, versionLabel)
body, err := fetchFromURL(url, getReleaseVersionTimeout)
if err != nil {
@ -87,11 +91,13 @@ func KubernetesReleaseVersion(version string) (string, error) {
}
// Handle air-gapped environments by falling back to the client version.
glog.Infof("could not fetch a Kubernetes version from the internet: %v", err)
body, err = kubeadmVersion(pkgversion.Get().String())
if err != nil {
return "", err
}
glog.Infof("falling back to the local client version: %s", body)
glog.Infof("falling back to the local client version: %s", clientVersion)
return KubernetesReleaseVersion(clientVersion)
}
// both the client and the remote version are obtained; validate them and pick a stable version
body, err = validateStableVersion(body, clientVersion)
if err != nil {
return "", err
}
// Re-validate received version and return.
return KubernetesReleaseVersion(body)
@ -204,3 +210,31 @@ func kubeadmVersion(info string) (string, error) {
vStr := fmt.Sprintf("v%d.%d.%d%s", v.Major(), v.Minor(), patch, pre)
return vStr, nil
}
// Validate if the remote version is one Minor release newer than the client version.
// This is done to conform with "stable-X" and only allow remote versions from
// the same Patch level release.
func validateStableVersion(remoteVersion, clientVersion string) (string, error) {
if clientVersion == "" {
glog.Infof("could not obtain client version; using remote version: %s", remoteVersion)
return remoteVersion, nil
}
verRemote, err := versionutil.ParseGeneric(remoteVersion)
if err != nil {
return "", fmt.Errorf("remote version error: %v", err)
}
verClient, err := versionutil.ParseGeneric(clientVersion)
if err != nil {
return "", fmt.Errorf("client version error: %v", err)
}
// If the remote Major version is bigger or if the Major versions are the same,
// but the remote Minor is bigger use the client version release. This handles Major bumps too.
if verClient.Major() < verRemote.Major() ||
(verClient.Major() == verRemote.Major()) && verClient.Minor() < verRemote.Minor() {
estimatedRelease := fmt.Sprintf("stable-%d.%d", verClient.Major(), verClient.Minor())
glog.Infof("remote version is much newer: %s; falling back to: %s", remoteVersion, estimatedRelease)
return estimatedRelease, nil
}
return remoteVersion, nil
}

View File

@ -380,3 +380,75 @@ func TestKubeadmVersion(t *testing.T) {
})
}
}
func TestValidateStableVersion(t *testing.T) {
type T struct {
name string
remoteVersion string
clientVersion string
output string
expectedError bool
}
cases := []T{
{
name: "valid: remote version is newer; return stable label [1]",
remoteVersion: "v1.12.0",
clientVersion: "v1.11.0",
output: "stable-1.11",
},
{
name: "valid: remote version is newer; return stable label [2]",
remoteVersion: "v2.0.0",
clientVersion: "v1.11.0",
output: "stable-1.11",
},
{
name: "valid: remote version is newer; return stable label [3]",
remoteVersion: "v2.1.5",
clientVersion: "v1.11.5",
output: "stable-1.11",
},
{
name: "valid: return the remote version as it is part of the same release",
remoteVersion: "v1.11.5",
clientVersion: "v1.11.0",
output: "v1.11.5",
},
{
name: "valid: return the same version",
remoteVersion: "v1.11.0",
clientVersion: "v1.11.0",
output: "v1.11.0",
},
{
name: "valid: client version is empty; use remote version",
remoteVersion: "v1.12.1",
clientVersion: "",
output: "v1.12.1",
},
{
name: "invalid: error parsing the remote version",
remoteVersion: "invalid-version",
clientVersion: "v1.12.0",
expectedError: true,
},
{
name: "invalid: error parsing the client version",
remoteVersion: "v1.12.0",
clientVersion: "invalid-version",
expectedError: true,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
output, err := validateStableVersion(tc.remoteVersion, tc.clientVersion)
if (err != nil) != tc.expectedError {
t.Fatalf("expected error: %v, got: %v", tc.expectedError, err != nil)
}
if output != tc.output {
t.Fatalf("expected output: %s, got: %s", tc.output, output)
}
})
}
}