mirror of https://github.com/k3s-io/k3s
Merge pull request #69301 from neolit123/kubeadm-version-stable
kubeadm: handle stable-1 as the default versionpull/58/head
commit
77742ea94c
|
@ -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,12 +91,14 @@ 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())
|
||||
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
|
||||
}
|
||||
glog.Infof("falling back to the local client version: %s", body)
|
||||
}
|
||||
// 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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue