diff --git a/cmd/kubeadm/app/cmd/upgrade/BUILD b/cmd/kubeadm/app/cmd/upgrade/BUILD index eab8937bad0..958b345a937 100644 --- a/cmd/kubeadm/app/cmd/upgrade/BUILD +++ b/cmd/kubeadm/app/cmd/upgrade/BUILD @@ -15,6 +15,7 @@ go_library( deps = [ "//cmd/kubeadm/app/apis/kubeadm:go_default_library", "//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library", + "//cmd/kubeadm/app/apis/output/v1alpha1:go_default_library", "//cmd/kubeadm/app/cmd/options:go_default_library", "//cmd/kubeadm/app/cmd/phases/upgrade/node:go_default_library", "//cmd/kubeadm/app/cmd/phases/workflow:go_default_library", diff --git a/cmd/kubeadm/app/cmd/upgrade/plan.go b/cmd/kubeadm/app/cmd/upgrade/plan.go index a4cb2be73fd..a07d8646a7d 100644 --- a/cmd/kubeadm/app/cmd/upgrade/plan.go +++ b/cmd/kubeadm/app/cmd/upgrade/plan.go @@ -29,6 +29,8 @@ import ( "k8s.io/apimachinery/pkg/util/version" "k8s.io/klog" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" + outputapiv1alpha1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/v1alpha1" + "k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade" etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd" ) @@ -97,131 +99,154 @@ func runPlan(flags *planFlags, userVersion string) error { return errors.Wrap(err, "[upgrade/versions] FATAL") } - // Tell the user which upgrades are available - printAvailableUpgrades(availUpgrades, os.Stdout, isExternalEtcd) + // No upgrades available + if len(availUpgrades) == 0 { + klog.V(1).Infoln("[upgrade/plan] Awesome, you're up-to-date! Enjoy!") + return nil + } + + // Generate and print upgrade plans + for _, up := range availUpgrades { + plan, unstableVersionFlag, err := genUpgradePlan(&up, isExternalEtcd) + if err != nil { + return err + } + + printUpgradePlan(&up, plan, unstableVersionFlag, isExternalEtcd, os.Stdout) + } return nil } -// printAvailableUpgrades prints a UX-friendly overview of what versions are available to upgrade to -// TODO look into columnize or some other formatter when time permits instead of using the tabwriter -func printAvailableUpgrades(upgrades []upgrade.Upgrade, w io.Writer, isExternalEtcd bool) { - - // Return quickly if no upgrades can be made - if len(upgrades) == 0 { - fmt.Fprintln(w, "Awesome, you're up-to-date! Enjoy!") - return +// newComponentUpgradePlan helper creates outputapiv1alpha1.ComponentUpgradePlan object +func newComponentUpgradePlan(name, currentVersion, newVersion string) outputapiv1alpha1.ComponentUpgradePlan { + return outputapiv1alpha1.ComponentUpgradePlan{ + Name: name, + CurrentVersion: currentVersion, + NewVersion: newVersion, } +} + +// TODO There is currently no way to cleanly output upgrades that involve adding, removing, or changing components +// https://github.com/kubernetes/kubeadm/issues/810 was created to track addressing this. +func appendDNSComponent(components []outputapiv1alpha1.ComponentUpgradePlan, up *upgrade.Upgrade, DNSType kubeadmapi.DNSAddOnType, name string) []outputapiv1alpha1.ComponentUpgradePlan { + beforeVersion, afterVersion := "", "" + if up.Before.DNSType == DNSType { + beforeVersion = up.Before.DNSVersion + } + if up.After.DNSType == DNSType { + afterVersion = up.After.DNSVersion + } + + if beforeVersion != "" || afterVersion != "" { + components = append(components, newComponentUpgradePlan(name, beforeVersion, afterVersion)) + } + return components +} + +// genUpgradePlan generates output-friendly upgrade plan out of upgrade.Upgrade structure +func genUpgradePlan(up *upgrade.Upgrade, isExternalEtcd bool) (*outputapiv1alpha1.UpgradePlan, string, error) { + newK8sVersion, err := version.ParseSemantic(up.After.KubeVersion) + if err != nil { + return nil, "", errors.Wrapf(err, "Unable to parse normalized version %q as a semantic version", up.After.KubeVersion) + } + + unstableVersionFlag := "" + if len(newK8sVersion.PreRelease()) != 0 { + if strings.HasPrefix(newK8sVersion.PreRelease(), "rc") { + unstableVersionFlag = " --allow-release-candidate-upgrades" + } else { + unstableVersionFlag = " --allow-experimental-upgrades" + } + } + + components := []outputapiv1alpha1.ComponentUpgradePlan{} + + if isExternalEtcd && up.CanUpgradeEtcd() { + components = append(components, newComponentUpgradePlan(constants.Etcd, up.Before.EtcdVersion, up.After.EtcdVersion)) + } + + if up.CanUpgradeKubelets() { + // The map is of the form :. Here all the keys are put into a slice and sorted + // in order to always get the right order. Then the map value is extracted separately + for _, oldVersion := range sortedSliceFromStringIntMap(up.Before.KubeletVersions) { + nodeCount := up.Before.KubeletVersions[oldVersion] + components = append(components, newComponentUpgradePlan(constants.Kubelet, fmt.Sprintf("%d x %s", nodeCount, oldVersion), up.After.KubeVersion)) + } + } + + components = append(components, newComponentUpgradePlan(constants.KubeAPIServer, up.Before.KubeVersion, up.After.KubeVersion)) + components = append(components, newComponentUpgradePlan(constants.KubeControllerManager, up.Before.KubeVersion, up.After.KubeVersion)) + components = append(components, newComponentUpgradePlan(constants.KubeScheduler, up.Before.KubeVersion, up.After.KubeVersion)) + components = append(components, newComponentUpgradePlan(constants.KubeProxy, up.Before.KubeVersion, up.After.KubeVersion)) + + components = appendDNSComponent(components, up, kubeadmapi.CoreDNS, constants.CoreDNS) + components = appendDNSComponent(components, up, kubeadmapi.KubeDNS, constants.KubeDNS) + + if !isExternalEtcd { + components = append(components, newComponentUpgradePlan(constants.Etcd, up.Before.EtcdVersion, up.After.EtcdVersion)) + } + + return &outputapiv1alpha1.UpgradePlan{Components: components}, unstableVersionFlag, nil +} + +// printUpgradePlan prints a UX-friendly overview of what versions are available to upgrade to +func printUpgradePlan(up *upgrade.Upgrade, plan *outputapiv1alpha1.UpgradePlan, unstableVersionFlag string, isExternalEtcd bool, w io.Writer) { // The tab writer writes to the "real" writer w tabw := tabwriter.NewWriter(w, 10, 4, 3, ' ', 0) - // Loop through the upgrade possibilities and output text to the command line - for _, upgrade := range upgrades { - - newK8sVersion, err := version.ParseSemantic(upgrade.After.KubeVersion) - if err != nil { - fmt.Fprintf(w, "Unable to parse normalized version %q as a semantic version\n", upgrade.After.KubeVersion) - continue - } - - UnstableVersionFlag := "" - if len(newK8sVersion.PreRelease()) != 0 { - if strings.HasPrefix(newK8sVersion.PreRelease(), "rc") { - UnstableVersionFlag = " --allow-release-candidate-upgrades" - } else { - UnstableVersionFlag = " --allow-experimental-upgrades" - } - } - - if isExternalEtcd && upgrade.CanUpgradeEtcd() { - fmt.Fprintln(w, "External components that should be upgraded manually before you upgrade the control plane with 'kubeadm upgrade apply':") - fmt.Fprintln(tabw, "COMPONENT\tCURRENT\tAVAILABLE") - fmt.Fprintf(tabw, "Etcd\t%s\t%s\n", upgrade.Before.EtcdVersion, upgrade.After.EtcdVersion) - - // We should flush the writer here at this stage; as the columns will now be of the right size, adjusted to the above content - tabw.Flush() - fmt.Fprintln(w, "") - } - - if upgrade.CanUpgradeKubelets() { - fmt.Fprintln(w, "Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':") - fmt.Fprintln(tabw, "COMPONENT\tCURRENT\tAVAILABLE") - firstPrinted := false - - // The map is of the form :. Here all the keys are put into a slice and sorted - // in order to always get the right order. Then the map value is extracted separately - for _, oldVersion := range sortedSliceFromStringIntMap(upgrade.Before.KubeletVersions) { - nodeCount := upgrade.Before.KubeletVersions[oldVersion] - if !firstPrinted { - // Output the Kubelet header only on the first version pair - fmt.Fprintf(tabw, "Kubelet\t%d x %s\t%s\n", nodeCount, oldVersion, upgrade.After.KubeVersion) - firstPrinted = true - continue - } - fmt.Fprintf(tabw, "\t%d x %s\t%s\n", nodeCount, oldVersion, upgrade.After.KubeVersion) - } - // We should flush the writer here at this stage; as the columns will now be of the right size, adjusted to the above content - tabw.Flush() - fmt.Fprintln(w, "") - } - - fmt.Fprintf(w, "Upgrade to the latest %s:\n", upgrade.Description) - fmt.Fprintln(w, "") - fmt.Fprintln(tabw, "COMPONENT\tCURRENT\tAVAILABLE") - fmt.Fprintf(tabw, "API Server\t%s\t%s\n", upgrade.Before.KubeVersion, upgrade.After.KubeVersion) - fmt.Fprintf(tabw, "Controller Manager\t%s\t%s\n", upgrade.Before.KubeVersion, upgrade.After.KubeVersion) - fmt.Fprintf(tabw, "Scheduler\t%s\t%s\n", upgrade.Before.KubeVersion, upgrade.After.KubeVersion) - fmt.Fprintf(tabw, "Kube Proxy\t%s\t%s\n", upgrade.Before.KubeVersion, upgrade.After.KubeVersion) - - // TODO There is currently no way to cleanly output upgrades that involve adding, removing, or changing components - // https://github.com/kubernetes/kubeadm/issues/810 was created to track addressing this. - printCoreDNS, printKubeDNS := false, false - coreDNSBeforeVersion, coreDNSAfterVersion, kubeDNSBeforeVersion, kubeDNSAfterVersion := "", "", "", "" - - switch upgrade.Before.DNSType { - case kubeadmapi.CoreDNS: - printCoreDNS = true - coreDNSBeforeVersion = upgrade.Before.DNSVersion - case kubeadmapi.KubeDNS: - printKubeDNS = true - kubeDNSBeforeVersion = upgrade.Before.DNSVersion - } - - switch upgrade.After.DNSType { - case kubeadmapi.CoreDNS: - printCoreDNS = true - coreDNSAfterVersion = upgrade.After.DNSVersion - case kubeadmapi.KubeDNS: - printKubeDNS = true - kubeDNSAfterVersion = upgrade.After.DNSVersion - } - - if printCoreDNS { - fmt.Fprintf(tabw, "CoreDNS\t%s\t%s\n", coreDNSBeforeVersion, coreDNSAfterVersion) - } - if printKubeDNS { - fmt.Fprintf(tabw, "Kube DNS\t%s\t%s\n", kubeDNSBeforeVersion, kubeDNSAfterVersion) - } - - if !isExternalEtcd { - fmt.Fprintf(tabw, "Etcd\t%s\t%s\n", upgrade.Before.EtcdVersion, upgrade.After.EtcdVersion) - } - - // The tabwriter should be flushed at this stage as we have now put in all the required content for this time. This is required for the tabs' size to be correct. + // endOfTable helper function flashes table writer + endOfTable := func() { tabw.Flush() fmt.Fprintln(w, "") - fmt.Fprintln(w, "You can now apply the upgrade by executing the following command:") - fmt.Fprintln(w, "") - fmt.Fprintf(w, "\tkubeadm upgrade apply %s%s\n", upgrade.After.KubeVersion, UnstableVersionFlag) - fmt.Fprintln(w, "") + } - if upgrade.Before.KubeadmVersion != upgrade.After.KubeadmVersion { - fmt.Fprintf(w, "Note: Before you can perform this upgrade, you have to update kubeadm to %s.\n", upgrade.After.KubeadmVersion) - fmt.Fprintln(w, "") + printHeader := true + printManualUpgradeHeader := true + for _, component := range plan.Components { + if isExternalEtcd && component.Name == constants.Etcd { + fmt.Fprintln(w, "External components that should be upgraded manually before you upgrade the control plane with 'kubeadm upgrade apply':") + fmt.Fprintln(tabw, "COMPONENT\tCURRENT\tAVAILABLE") + fmt.Fprintf(tabw, "%s\t%s\t%s\n", component.Name, component.CurrentVersion, component.NewVersion) + // end of external components table + endOfTable() + } else if component.Name == constants.Kubelet { + if printManualUpgradeHeader { + fmt.Fprintln(w, "Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':") + fmt.Fprintln(tabw, "COMPONENT\tCURRENT\tAVAILABLE") + fmt.Fprintf(tabw, "%s\t%s\t%s\n", component.Name, component.CurrentVersion, component.NewVersion) + printManualUpgradeHeader = false + } else { + fmt.Fprintf(tabw, "%s\t%s\t%s\n", "", component.CurrentVersion, component.NewVersion) + } + } else { + if printHeader { + // End of manual upgrades table + endOfTable() + + fmt.Fprintf(w, "Upgrade to the latest %s:\n", up.Description) + fmt.Fprintln(w, "") + fmt.Fprintln(tabw, "COMPONENT\tCURRENT\tAVAILABLE") + printHeader = false + } + fmt.Fprintf(tabw, "%s\t%s\t%s\n", component.Name, component.CurrentVersion, component.NewVersion) } + } + // End of control plane table + endOfTable() - fmt.Fprintln(w, "_____________________________________________________________________") + //fmt.Fprintln(w, "") + fmt.Fprintln(w, "You can now apply the upgrade by executing the following command:") + fmt.Fprintln(w, "") + fmt.Fprintf(w, "\tkubeadm upgrade apply %s%s\n", up.After.KubeVersion, unstableVersionFlag) + fmt.Fprintln(w, "") + + if up.Before.KubeadmVersion != up.After.KubeadmVersion { + fmt.Fprintf(w, "Note: Before you can perform this upgrade, you have to update kubeadm to %s.\n", up.After.KubeadmVersion) fmt.Fprintln(w, "") } + + fmt.Fprintln(w, "_____________________________________________________________________") + fmt.Fprintln(w, "") } // sortedSliceFromStringIntMap returns a slice of the keys in the map sorted alphabetically diff --git a/cmd/kubeadm/app/cmd/upgrade/plan_test.go b/cmd/kubeadm/app/cmd/upgrade/plan_test.go index 7f4c703607f..560e6aa6120 100644 --- a/cmd/kubeadm/app/cmd/upgrade/plan_test.go +++ b/cmd/kubeadm/app/cmd/upgrade/plan_test.go @@ -75,19 +75,6 @@ func TestPrintAvailableUpgrades(t *testing.T) { expectedBytes []byte externalEtcd bool }{ - { - name: "Up to date", - upgrades: []upgrade.Upgrade{}, - expectedBytes: []byte(`Awesome, you're up-to-date! Enjoy! -`), - }, - { - name: "Up to date external etcd", - externalEtcd: true, - upgrades: []upgrade.Upgrade{}, - expectedBytes: []byte(`Awesome, you're up-to-date! Enjoy! -`), - }, { name: "Patch version available", upgrades: []upgrade.Upgrade{ @@ -114,17 +101,17 @@ func TestPrintAvailableUpgrades(t *testing.T) { }, expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE -Kubelet 1 x v1.8.1 v1.8.3 +kubelet 1 x v1.8.1 v1.8.3 Upgrade to the latest version in the v1.8 series: -COMPONENT CURRENT AVAILABLE -API Server v1.8.1 v1.8.3 -Controller Manager v1.8.1 v1.8.3 -Scheduler v1.8.1 v1.8.3 -Kube Proxy v1.8.1 v1.8.3 -Kube DNS 1.14.5 1.14.5 -Etcd 3.0.17 3.0.17 +COMPONENT CURRENT AVAILABLE +kube-apiserver v1.8.1 v1.8.3 +kube-controller-manager v1.8.1 v1.8.3 +kube-scheduler v1.8.1 v1.8.3 +kube-proxy v1.8.1 v1.8.3 +kube-dns 1.14.5 1.14.5 +etcd 3.0.17 3.0.17 You can now apply the upgrade by executing the following command: @@ -162,17 +149,17 @@ _____________________________________________________________________ }, expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE -Kubelet 1 x v1.8.3 v1.9.0 +kubelet 1 x v1.8.3 v1.9.0 Upgrade to the latest stable version: -COMPONENT CURRENT AVAILABLE -API Server v1.8.3 v1.9.0 -Controller Manager v1.8.3 v1.9.0 -Scheduler v1.8.3 v1.9.0 -Kube Proxy v1.8.3 v1.9.0 -Kube DNS 1.14.5 1.14.13 -Etcd 3.0.17 3.1.12 +COMPONENT CURRENT AVAILABLE +kube-apiserver v1.8.3 v1.9.0 +kube-controller-manager v1.8.3 v1.9.0 +kube-scheduler v1.8.3 v1.9.0 +kube-proxy v1.8.3 v1.9.0 +kube-dns 1.14.5 1.14.13 +etcd 3.0.17 3.1.12 You can now apply the upgrade by executing the following command: @@ -228,17 +215,17 @@ _____________________________________________________________________ }, expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE -Kubelet 1 x v1.8.3 v1.8.5 +kubelet 1 x v1.8.3 v1.8.5 Upgrade to the latest version in the v1.8 series: -COMPONENT CURRENT AVAILABLE -API Server v1.8.3 v1.8.5 -Controller Manager v1.8.3 v1.8.5 -Scheduler v1.8.3 v1.8.5 -Kube Proxy v1.8.3 v1.8.5 -Kube DNS 1.14.5 1.14.5 -Etcd 3.0.17 3.0.17 +COMPONENT CURRENT AVAILABLE +kube-apiserver v1.8.3 v1.8.5 +kube-controller-manager v1.8.3 v1.8.5 +kube-scheduler v1.8.3 v1.8.5 +kube-proxy v1.8.3 v1.8.5 +kube-dns 1.14.5 1.14.5 +etcd 3.0.17 3.0.17 You can now apply the upgrade by executing the following command: @@ -248,17 +235,17 @@ _____________________________________________________________________ Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE -Kubelet 1 x v1.8.3 v1.9.0 +kubelet 1 x v1.8.3 v1.9.0 Upgrade to the latest stable version: -COMPONENT CURRENT AVAILABLE -API Server v1.8.3 v1.9.0 -Controller Manager v1.8.3 v1.9.0 -Scheduler v1.8.3 v1.9.0 -Kube Proxy v1.8.3 v1.9.0 -Kube DNS 1.14.5 1.14.13 -Etcd 3.0.17 3.1.12 +COMPONENT CURRENT AVAILABLE +kube-apiserver v1.8.3 v1.9.0 +kube-controller-manager v1.8.3 v1.9.0 +kube-scheduler v1.8.3 v1.9.0 +kube-proxy v1.8.3 v1.9.0 +kube-dns 1.14.5 1.14.13 +etcd 3.0.17 3.1.12 You can now apply the upgrade by executing the following command: @@ -296,17 +283,17 @@ _____________________________________________________________________ }, expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE -Kubelet 1 x v1.8.5 v1.9.0-beta.1 +kubelet 1 x v1.8.5 v1.9.0-beta.1 Upgrade to the latest experimental version: -COMPONENT CURRENT AVAILABLE -API Server v1.8.5 v1.9.0-beta.1 -Controller Manager v1.8.5 v1.9.0-beta.1 -Scheduler v1.8.5 v1.9.0-beta.1 -Kube Proxy v1.8.5 v1.9.0-beta.1 -Kube DNS 1.14.5 1.14.13 -Etcd 3.0.17 3.1.12 +COMPONENT CURRENT AVAILABLE +kube-apiserver v1.8.5 v1.9.0-beta.1 +kube-controller-manager v1.8.5 v1.9.0-beta.1 +kube-scheduler v1.8.5 v1.9.0-beta.1 +kube-proxy v1.8.5 v1.9.0-beta.1 +kube-dns 1.14.5 1.14.13 +etcd 3.0.17 3.1.12 You can now apply the upgrade by executing the following command: @@ -344,17 +331,17 @@ _____________________________________________________________________ }, expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE -Kubelet 1 x v1.8.5 v1.9.0-rc.1 +kubelet 1 x v1.8.5 v1.9.0-rc.1 Upgrade to the latest release candidate version: -COMPONENT CURRENT AVAILABLE -API Server v1.8.5 v1.9.0-rc.1 -Controller Manager v1.8.5 v1.9.0-rc.1 -Scheduler v1.8.5 v1.9.0-rc.1 -Kube Proxy v1.8.5 v1.9.0-rc.1 -Kube DNS 1.14.5 1.14.13 -Etcd 3.0.17 3.1.12 +COMPONENT CURRENT AVAILABLE +kube-apiserver v1.8.5 v1.9.0-rc.1 +kube-controller-manager v1.8.5 v1.9.0-rc.1 +kube-scheduler v1.8.5 v1.9.0-rc.1 +kube-proxy v1.8.5 v1.9.0-rc.1 +kube-dns 1.14.5 1.14.13 +etcd 3.0.17 3.1.12 You can now apply the upgrade by executing the following command: @@ -393,18 +380,18 @@ _____________________________________________________________________ }, expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE -Kubelet 1 x v1.9.2 v1.9.3 +kubelet 1 x v1.9.2 v1.9.3 2 x v1.9.3 v1.9.3 Upgrade to the latest version in the v1.9 series: -COMPONENT CURRENT AVAILABLE -API Server v1.9.2 v1.9.3 -Controller Manager v1.9.2 v1.9.3 -Scheduler v1.9.2 v1.9.3 -Kube Proxy v1.9.2 v1.9.3 -Kube DNS 1.14.5 1.14.8 -Etcd 3.0.17 3.1.12 +COMPONENT CURRENT AVAILABLE +kube-apiserver v1.9.2 v1.9.3 +kube-controller-manager v1.9.2 v1.9.3 +kube-scheduler v1.9.2 v1.9.3 +kube-proxy v1.9.2 v1.9.3 +kube-dns 1.14.5 1.14.8 +etcd 3.0.17 3.1.12 You can now apply the upgrade by executing the following command: @@ -444,20 +431,20 @@ _____________________________________________________________________ externalEtcd: true, expectedBytes: []byte(`External components that should be upgraded manually before you upgrade the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE -Etcd 3.0.17 3.1.12 +etcd 3.0.17 3.1.12 Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE -Kubelet 1 x v1.9.2 v1.9.3 +kubelet 1 x v1.9.2 v1.9.3 Upgrade to the latest version in the v1.9 series: -COMPONENT CURRENT AVAILABLE -API Server v1.9.2 v1.9.3 -Controller Manager v1.9.2 v1.9.3 -Scheduler v1.9.2 v1.9.3 -Kube Proxy v1.9.2 v1.9.3 -Kube DNS 1.14.5 1.14.8 +COMPONENT CURRENT AVAILABLE +kube-apiserver v1.9.2 v1.9.3 +kube-controller-manager v1.9.2 v1.9.3 +kube-scheduler v1.9.2 v1.9.3 +kube-proxy v1.9.2 v1.9.3 +kube-dns 1.14.5 1.14.8 You can now apply the upgrade by executing the following command: @@ -495,18 +482,18 @@ _____________________________________________________________________ }, expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE -Kubelet 1 x v1.10.2 v1.11.0 +kubelet 1 x v1.10.2 v1.11.0 Upgrade to the latest kubedns to coredns: -COMPONENT CURRENT AVAILABLE -API Server v1.10.2 v1.11.0 -Controller Manager v1.10.2 v1.11.0 -Scheduler v1.10.2 v1.11.0 -Kube Proxy v1.10.2 v1.11.0 -CoreDNS 1.0.6 -Kube DNS 1.14.7 -Etcd 3.1.11 3.2.18 +COMPONENT CURRENT AVAILABLE +kube-apiserver v1.10.2 v1.11.0 +kube-controller-manager v1.10.2 v1.11.0 +kube-scheduler v1.10.2 v1.11.0 +kube-proxy v1.10.2 v1.11.0 +CoreDNS 1.0.6 +kube-dns 1.14.7 +etcd 3.1.11 3.2.18 You can now apply the upgrade by executing the following command: @@ -542,17 +529,17 @@ _____________________________________________________________________ }, expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE -Kubelet 1 x v1.10.2 v1.11.0 +kubelet 1 x v1.10.2 v1.11.0 Upgrade to the latest coredns: -COMPONENT CURRENT AVAILABLE -API Server v1.10.2 v1.11.0 -Controller Manager v1.10.2 v1.11.0 -Scheduler v1.10.2 v1.11.0 -Kube Proxy v1.10.2 v1.11.0 -CoreDNS 1.0.5 1.0.6 -Etcd 3.1.11 3.2.18 +COMPONENT CURRENT AVAILABLE +kube-apiserver v1.10.2 v1.11.0 +kube-controller-manager v1.10.2 v1.11.0 +kube-scheduler v1.10.2 v1.11.0 +kube-proxy v1.10.2 v1.11.0 +CoreDNS 1.0.5 1.0.6 +etcd 3.1.11 3.2.18 You can now apply the upgrade by executing the following command: @@ -588,18 +575,18 @@ _____________________________________________________________________ }, expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE -Kubelet 1 x v1.10.2 v1.11.0 +kubelet 1 x v1.10.2 v1.11.0 Upgrade to the latest coredns to kubedns: -COMPONENT CURRENT AVAILABLE -API Server v1.10.2 v1.11.0 -Controller Manager v1.10.2 v1.11.0 -Scheduler v1.10.2 v1.11.0 -Kube Proxy v1.10.2 v1.11.0 -CoreDNS 1.0.6 -Kube DNS 1.14.9 -Etcd 3.1.11 3.2.18 +COMPONENT CURRENT AVAILABLE +kube-apiserver v1.10.2 v1.11.0 +kube-controller-manager v1.10.2 v1.11.0 +kube-scheduler v1.10.2 v1.11.0 +kube-proxy v1.10.2 v1.11.0 +CoreDNS 1.0.6 +kube-dns 1.14.9 +etcd 3.1.11 3.2.18 You can now apply the upgrade by executing the following command: @@ -613,11 +600,18 @@ _____________________________________________________________________ for _, rt := range tests { t.Run(rt.name, func(t *testing.T) { rt.buf = bytes.NewBufferString("") - printAvailableUpgrades(rt.upgrades, rt.buf, rt.externalEtcd) + // Generate and print upgrade plans + for _, up := range rt.upgrades { + plan, unstableVersionFlag, err := genUpgradePlan(&up, rt.externalEtcd) + if err != nil { + t.Errorf("failed genUpgradePlan, err: %+v", err) + } + printUpgradePlan(&up, plan, unstableVersionFlag, rt.externalEtcd, rt.buf) + } actualBytes := rt.buf.Bytes() if !bytes.Equal(actualBytes, rt.expectedBytes) { t.Errorf( - "failed PrintAvailableUpgrades:\n\texpected: %q\n\t actual: %q", + "failed PrintAvailableUpgrades:\n\texpected: %q\n\n\tactual : %q", string(rt.expectedBytes), string(actualBytes), ) diff --git a/cmd/kubeadm/app/constants/constants.go b/cmd/kubeadm/app/constants/constants.go index a309708c119..34508d1d784 100644 --- a/cmd/kubeadm/app/constants/constants.go +++ b/cmd/kubeadm/app/constants/constants.go @@ -279,6 +279,12 @@ const ( KubeProxy = "kube-proxy" // HyperKube defines variable used internally when referring to the hyperkube image HyperKube = "hyperkube" + // CoreDNS defines variable used internally when referring to the CoreDNS component + CoreDNS = "CoreDNS" + // KubeDNS defines variable used internally when referring to the KubeDNS component + KubeDNS = "kube-dns" + // Kubelet defines variable used internally when referring to the Kubelet + Kubelet = "kubelet" // SelfHostingPrefix describes the prefix workloads that are self-hosted by kubeadm has SelfHostingPrefix = "self-hosted-"