Commit 759f12a7 authored by Yang Li's avatar Yang Li

Merge remote-tracking branch 'origin/master' into release-1.13

parents 80b400f6 1e50c571
...@@ -31,7 +31,7 @@ const APIServerExtraArgs = "apiserver-extra-args" ...@@ -31,7 +31,7 @@ const APIServerExtraArgs = "apiserver-extra-args"
// CertificatesDir flag sets the path where to save and read the certificates. // CertificatesDir flag sets the path where to save and read the certificates.
const CertificatesDir = "cert-dir" const CertificatesDir = "cert-dir"
// CfgPath flag sets the path to kubeadm config file. WARNING: Usage of a configuration file is experimental. // CfgPath flag sets the path to kubeadm config file.
const CfgPath = "config" const CfgPath = "config"
// ControllerManagerExtraArgs flag sets extra flags to pass to the Controller Manager or override default ones in form of <flagname>=<value>. // ControllerManagerExtraArgs flag sets extra flags to pass to the Controller Manager or override default ones in form of <flagname>=<value>.
......
...@@ -33,7 +33,7 @@ func AddKubeConfigDirFlag(fs *pflag.FlagSet, kubeConfigDir *string) { ...@@ -33,7 +33,7 @@ func AddKubeConfigDirFlag(fs *pflag.FlagSet, kubeConfigDir *string) {
// AddConfigFlag adds the --config flag to the given flagset // AddConfigFlag adds the --config flag to the given flagset
func AddConfigFlag(fs *pflag.FlagSet, cfgPath *string) { func AddConfigFlag(fs *pflag.FlagSet, cfgPath *string) {
fs.StringVar(cfgPath, CfgPath, *cfgPath, "Path to kubeadm config file (WARNING: Usage of a configuration file is experimental).") fs.StringVar(cfgPath, CfgPath, *cfgPath, "Path to a kubeadm configuration file.")
} }
// AddIgnorePreflightErrorsFlag adds the --ignore-preflight-errors flag to the given flagset // AddIgnorePreflightErrorsFlag adds the --ignore-preflight-errors flag to the given flagset
......
...@@ -50,6 +50,7 @@ func NewMarkControlPlanePhase() workflow.Phase { ...@@ -50,6 +50,7 @@ func NewMarkControlPlanePhase() workflow.Phase {
Example: markControlPlaneExample, Example: markControlPlaneExample,
InheritFlags: []string{ InheritFlags: []string{
options.NodeName, options.NodeName,
options.CfgPath,
}, },
Run: runMarkControlPlane, Run: runMarkControlPlane,
} }
......
...@@ -314,11 +314,14 @@ type RuntimeSorter struct { ...@@ -314,11 +314,14 @@ type RuntimeSorter struct {
} }
func (r *RuntimeSorter) Sort() error { func (r *RuntimeSorter) Sort() error {
if len(r.objects) <= 1 { // a list is only considered "sorted" if there are 0 or 1 items in it
// a list is only considered "sorted" if there are 0 or 1 items in it // AND (if 1 item) the item is not a Table object
// AND (if 1 item) the item is not a Table object if len(r.objects) == 0 {
return nil
}
if len(r.objects) == 1 {
_, isTable := r.objects[0].(*metav1beta1.Table) _, isTable := r.objects[0].(*metav1beta1.Table)
if len(r.objects) == 0 || !isTable { if !isTable {
return nil return nil
} }
} }
......
...@@ -561,6 +561,15 @@ func TestRuntimeSorter(t *testing.T) { ...@@ -561,6 +561,15 @@ func TestRuntimeSorter(t *testing.T) {
expectError string expectError string
}{ }{
{ {
name: "ensure sorter works with an empty object list",
field: "metadata.name",
objs: []runtime.Object{},
op: func(sorter *RuntimeSorter, objs []runtime.Object, out io.Writer) error {
return nil
},
expect: "",
},
{
name: "ensure sorter returns original position", name: "ensure sorter returns original position",
field: "metadata.name", field: "metadata.name",
objs: sortTestData(), objs: sortTestData(),
......
...@@ -881,6 +881,19 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() { ...@@ -881,6 +881,19 @@ var _ = SIGDescribe("Cluster size autoscaling [Slow]", func() {
clusterSize = manuallyIncreaseClusterSize(f, originalSizes) clusterSize = manuallyIncreaseClusterSize(f, originalSizes)
} }
// If new nodes are disconnected too soon, they'll be considered not started
// instead of unready, and cluster won't be considered unhealthy.
//
// More precisely, Cluster Autoscaler compares last transition time of
// several readiness conditions to node create time. If it's within
// 2 minutes, it'll assume node is just starting and not unhealthy.
//
// Nodes become ready in less than 1 minute after being created,
// so waiting extra 2 minutes before breaking them (which triggers
// readiness condition transition) should be sufficient, while
// making no assumptions about minimal node startup time.
time.Sleep(2 * time.Minute)
By("Block network connectivity to some nodes to simulate unhealthy cluster") By("Block network connectivity to some nodes to simulate unhealthy cluster")
nodesToBreakCount := int(math.Ceil(math.Max(float64(unhealthyClusterThreshold), 0.5*float64(clusterSize)))) nodesToBreakCount := int(math.Ceil(math.Max(float64(unhealthyClusterThreshold), 0.5*float64(clusterSize))))
nodes, err := f.ClientSet.CoreV1().Nodes().List(metav1.ListOptions{FieldSelector: fields.Set{ nodes, err := f.ClientSet.CoreV1().Nodes().List(metav1.ListOptions{FieldSelector: fields.Set{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment