mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 03:11:40 +00:00
Merge pull request #88854 from bart0sh/PR0088-kubeadm-redesign-printAvailableUpgrades
kubeadm: redesign printAvailableUpgrades function
This commit is contained in:
commit
c1fc466cdd
@ -48,6 +48,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&BootstrapToken{},
|
||||
&Images{},
|
||||
&UpgradePlan{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
@ -40,3 +40,20 @@ type Images struct {
|
||||
|
||||
Images []string
|
||||
}
|
||||
|
||||
// ComponentUpgradePlan represents information about upgrade plan for one component
|
||||
type ComponentUpgradePlan struct {
|
||||
Name string
|
||||
CurrentVersion string
|
||||
NewVersion string
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// UpgradePlan represents information about upgrade plan for the output
|
||||
// produced by 'kubeadm upgrade plan'
|
||||
type UpgradePlan struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
Components []ComponentUpgradePlan
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&BootstrapToken{},
|
||||
&Images{},
|
||||
&UpgradePlan{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
@ -40,3 +40,20 @@ type Images struct {
|
||||
|
||||
Images []string `json:"images"`
|
||||
}
|
||||
|
||||
// ComponentUpgradePlan represents information about upgrade plan for one component
|
||||
type ComponentUpgradePlan struct {
|
||||
Name string `json:"name"`
|
||||
CurrentVersion string `json:"currentVersion"`
|
||||
NewVersion string `json:"newVersion"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// UpgradePlan represents information about upgrade plan for the output
|
||||
// produced by 'kubeadm upgrade plan'
|
||||
type UpgradePlan struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
Components []ComponentUpgradePlan `json:"components"`
|
||||
}
|
||||
|
@ -45,6 +45,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*ComponentUpgradePlan)(nil), (*output.ComponentUpgradePlan)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_ComponentUpgradePlan_To_output_ComponentUpgradePlan(a.(*ComponentUpgradePlan), b.(*output.ComponentUpgradePlan), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*output.ComponentUpgradePlan)(nil), (*ComponentUpgradePlan)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_output_ComponentUpgradePlan_To_v1alpha1_ComponentUpgradePlan(a.(*output.ComponentUpgradePlan), b.(*ComponentUpgradePlan), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*Images)(nil), (*output.Images)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_Images_To_output_Images(a.(*Images), b.(*output.Images), scope)
|
||||
}); err != nil {
|
||||
@ -55,6 +65,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*UpgradePlan)(nil), (*output.UpgradePlan)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_UpgradePlan_To_output_UpgradePlan(a.(*UpgradePlan), b.(*output.UpgradePlan), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*output.UpgradePlan)(nil), (*UpgradePlan)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_output_UpgradePlan_To_v1alpha1_UpgradePlan(a.(*output.UpgradePlan), b.(*UpgradePlan), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -78,6 +98,30 @@ func Convert_output_BootstrapToken_To_v1alpha1_BootstrapToken(in *output.Bootstr
|
||||
return autoConvert_output_BootstrapToken_To_v1alpha1_BootstrapToken(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_ComponentUpgradePlan_To_output_ComponentUpgradePlan(in *ComponentUpgradePlan, out *output.ComponentUpgradePlan, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
out.CurrentVersion = in.CurrentVersion
|
||||
out.NewVersion = in.NewVersion
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_ComponentUpgradePlan_To_output_ComponentUpgradePlan is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_ComponentUpgradePlan_To_output_ComponentUpgradePlan(in *ComponentUpgradePlan, out *output.ComponentUpgradePlan, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_ComponentUpgradePlan_To_output_ComponentUpgradePlan(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_output_ComponentUpgradePlan_To_v1alpha1_ComponentUpgradePlan(in *output.ComponentUpgradePlan, out *ComponentUpgradePlan, s conversion.Scope) error {
|
||||
out.Name = in.Name
|
||||
out.CurrentVersion = in.CurrentVersion
|
||||
out.NewVersion = in.NewVersion
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_output_ComponentUpgradePlan_To_v1alpha1_ComponentUpgradePlan is an autogenerated conversion function.
|
||||
func Convert_output_ComponentUpgradePlan_To_v1alpha1_ComponentUpgradePlan(in *output.ComponentUpgradePlan, out *ComponentUpgradePlan, s conversion.Scope) error {
|
||||
return autoConvert_output_ComponentUpgradePlan_To_v1alpha1_ComponentUpgradePlan(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_Images_To_output_Images(in *Images, out *output.Images, s conversion.Scope) error {
|
||||
out.Images = *(*[]string)(unsafe.Pointer(&in.Images))
|
||||
return nil
|
||||
@ -97,3 +141,23 @@ func autoConvert_output_Images_To_v1alpha1_Images(in *output.Images, out *Images
|
||||
func Convert_output_Images_To_v1alpha1_Images(in *output.Images, out *Images, s conversion.Scope) error {
|
||||
return autoConvert_output_Images_To_v1alpha1_Images(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_UpgradePlan_To_output_UpgradePlan(in *UpgradePlan, out *output.UpgradePlan, s conversion.Scope) error {
|
||||
out.Components = *(*[]output.ComponentUpgradePlan)(unsafe.Pointer(&in.Components))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1alpha1_UpgradePlan_To_output_UpgradePlan is an autogenerated conversion function.
|
||||
func Convert_v1alpha1_UpgradePlan_To_output_UpgradePlan(in *UpgradePlan, out *output.UpgradePlan, s conversion.Scope) error {
|
||||
return autoConvert_v1alpha1_UpgradePlan_To_output_UpgradePlan(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_output_UpgradePlan_To_v1alpha1_UpgradePlan(in *output.UpgradePlan, out *UpgradePlan, s conversion.Scope) error {
|
||||
out.Components = *(*[]ComponentUpgradePlan)(unsafe.Pointer(&in.Components))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_output_UpgradePlan_To_v1alpha1_UpgradePlan is an autogenerated conversion function.
|
||||
func Convert_output_UpgradePlan_To_v1alpha1_UpgradePlan(in *output.UpgradePlan, out *UpgradePlan, s conversion.Scope) error {
|
||||
return autoConvert_output_UpgradePlan_To_v1alpha1_UpgradePlan(in, out, s)
|
||||
}
|
||||
|
@ -50,6 +50,22 @@ func (in *BootstrapToken) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ComponentUpgradePlan) DeepCopyInto(out *ComponentUpgradePlan) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentUpgradePlan.
|
||||
func (in *ComponentUpgradePlan) DeepCopy() *ComponentUpgradePlan {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ComponentUpgradePlan)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Images) DeepCopyInto(out *Images) {
|
||||
*out = *in
|
||||
@ -79,3 +95,33 @@ func (in *Images) DeepCopyObject() runtime.Object {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpgradePlan) DeepCopyInto(out *UpgradePlan) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.Components != nil {
|
||||
in, out := &in.Components, &out.Components
|
||||
*out = make([]ComponentUpgradePlan, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpgradePlan.
|
||||
func (in *UpgradePlan) DeepCopy() *UpgradePlan {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpgradePlan)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *UpgradePlan) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
46
cmd/kubeadm/app/apis/output/zz_generated.deepcopy.go
generated
46
cmd/kubeadm/app/apis/output/zz_generated.deepcopy.go
generated
@ -50,6 +50,22 @@ func (in *BootstrapToken) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ComponentUpgradePlan) DeepCopyInto(out *ComponentUpgradePlan) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentUpgradePlan.
|
||||
func (in *ComponentUpgradePlan) DeepCopy() *ComponentUpgradePlan {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ComponentUpgradePlan)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Images) DeepCopyInto(out *Images) {
|
||||
*out = *in
|
||||
@ -79,3 +95,33 @@ func (in *Images) DeepCopyObject() runtime.Object {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpgradePlan) DeepCopyInto(out *UpgradePlan) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.Components != nil {
|
||||
in, out := &in.Components, &out.Components
|
||||
*out = make([]ComponentUpgradePlan, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpgradePlan.
|
||||
func (in *UpgradePlan) DeepCopy() *UpgradePlan {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpgradePlan)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *UpgradePlan) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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 <old-version>:<node-count>. 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 <old-version>:<node-count>. 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
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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-"
|
||||
|
Loading…
Reference in New Issue
Block a user