Skip to content

Commit f81ab5a

Browse files
authored
Merge pull request kubernetes#81342 from knight42/fix/kubectl-patch-scale
Refactor `kubectl scale` to patch scale subresource
2 parents 087aafc + 92c4c2e commit f81ab5a

File tree

11 files changed

+215
-109
lines changed

11 files changed

+215
-109
lines changed

staging/src/k8s.io/kubectl/pkg/cmd/rollingupdate/BUILD

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ go_library(
1515
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
1616
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
1717
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
18-
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
1918
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
2019
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
2120
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",

staging/src/k8s.io/kubectl/pkg/cmd/rollingupdate/rolling_updater.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2929
"k8s.io/apimachinery/pkg/labels"
3030
"k8s.io/apimachinery/pkg/runtime"
31-
"k8s.io/apimachinery/pkg/runtime/schema"
3231
"k8s.io/apimachinery/pkg/util/intstr"
3332
"k8s.io/apimachinery/pkg/util/wait"
3433
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
@@ -413,7 +412,7 @@ func (r *RollingUpdater) scaleDown(newRc, oldRc *corev1.ReplicationController, d
413412
// scalerScaleAndWait scales a controller using a Scaler and a real client.
414413
func (r *RollingUpdater) scaleAndWaitWithScaler(rc *corev1.ReplicationController, retry *scale.RetryParams, wait *scale.RetryParams) (*corev1.ReplicationController, error) {
415414
scaler := scale.NewScaler(r.scaleClient)
416-
if err := scaler.Scale(rc.Namespace, rc.Name, uint(valOrZero(rc.Spec.Replicas)), &scale.ScalePrecondition{Size: -1, ResourceVersion: ""}, retry, wait, schema.GroupResource{Resource: "replicationcontrollers"}); err != nil {
415+
if err := scaler.Scale(rc.Namespace, rc.Name, uint(valOrZero(rc.Spec.Replicas)), &scale.ScalePrecondition{Size: -1, ResourceVersion: ""}, retry, wait, corev1.SchemeGroupVersion.WithResource("replicationcontrollers")); err != nil {
417416
return nil, err
418417
}
419418
return r.rcClient.ReplicationControllers(rc.Namespace).Get(rc.Name, metav1.GetOptions{})

staging/src/k8s.io/kubectl/pkg/cmd/scale/scale.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ func (o *ScaleOptions) RunScale() error {
227227
}
228228

229229
mapping := info.ResourceMapping()
230-
if err := o.scaler.Scale(info.Namespace, info.Name, uint(o.Replicas), precondition, retry, waitForReplicas, mapping.Resource.GroupResource()); err != nil {
230+
if err := o.scaler.Scale(info.Namespace, info.Name, uint(o.Replicas), precondition, retry, waitForReplicas, mapping.Resource); err != nil {
231231
return err
232232
}
233233

staging/src/k8s.io/kubectl/pkg/scale/BUILD

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ go_library(
99
deps = [
1010
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
1111
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
12-
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
1312
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
13+
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
1414
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
1515
"//staging/src/k8s.io/client-go/scale:go_default_library",
1616
],
@@ -27,6 +27,7 @@ go_test(
2727
"//staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/v1:go_default_library",
2828
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
2929
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
30+
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
3031
"//staging/src/k8s.io/client-go/scale:go_default_library",
3132
"//staging/src/k8s.io/client-go/scale/fake:go_default_library",
3233
"//staging/src/k8s.io/client-go/testing:go_default_library",

staging/src/k8s.io/kubectl/pkg/scale/scale.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import (
2323

2424
autoscalingv1 "k8s.io/api/autoscaling/v1"
2525
"k8s.io/apimachinery/pkg/api/errors"
26-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2726
"k8s.io/apimachinery/pkg/runtime/schema"
27+
"k8s.io/apimachinery/pkg/types"
2828
"k8s.io/apimachinery/pkg/util/wait"
2929
scaleclient "k8s.io/client-go/scale"
3030
)
@@ -35,10 +35,10 @@ type Scaler interface {
3535
// retries in the event of resource version mismatch (if retry is not nil),
3636
// and optionally waits until the status of the resource matches newSize (if wait is not nil)
3737
// TODO: Make the implementation of this watch-based (#56075) once #31345 is fixed.
38-
Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, wait *RetryParams, gr schema.GroupResource) error
38+
Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, wait *RetryParams, gvr schema.GroupVersionResource) error
3939
// ScaleSimple does a simple one-shot attempt at scaling - not useful on its own, but
4040
// a necessary building block for Scale
41-
ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint, gr schema.GroupResource) (updatedResourceVersion string, err error)
41+
ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint, gvr schema.GroupVersionResource) (updatedResourceVersion string, err error)
4242
}
4343

4444
// NewScaler get a scaler for a given resource
@@ -77,9 +77,9 @@ func NewRetryParams(interval, timeout time.Duration) *RetryParams {
7777
}
7878

7979
// ScaleCondition is a closure around Scale that facilitates retries via util.wait
80-
func ScaleCondition(r Scaler, precondition *ScalePrecondition, namespace, name string, count uint, updatedResourceVersion *string, gr schema.GroupResource) wait.ConditionFunc {
80+
func ScaleCondition(r Scaler, precondition *ScalePrecondition, namespace, name string, count uint, updatedResourceVersion *string, gvr schema.GroupVersionResource) wait.ConditionFunc {
8181
return func() (bool, error) {
82-
rv, err := r.ScaleSimple(namespace, name, precondition, count, gr)
82+
rv, err := r.ScaleSimple(namespace, name, precondition, count, gvr)
8383
if updatedResourceVersion != nil {
8484
*updatedResourceVersion = rv
8585
}
@@ -113,23 +113,25 @@ type genericScaler struct {
113113
var _ Scaler = &genericScaler{}
114114

115115
// ScaleSimple updates a scale of a given resource. It returns the resourceVersion of the scale if the update was successful.
116-
func (s *genericScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint, gr schema.GroupResource) (updatedResourceVersion string, err error) {
117-
scale := &autoscalingv1.Scale{
118-
ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: name},
119-
}
116+
func (s *genericScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint, gvr schema.GroupVersionResource) (updatedResourceVersion string, err error) {
120117
if preconditions != nil {
121-
var err error
122-
scale, err = s.scaleNamespacer.Scales(namespace).Get(gr, name)
118+
scale, err := s.scaleNamespacer.Scales(namespace).Get(gvr.GroupResource(), name)
123119
if err != nil {
124120
return "", err
125121
}
126-
if err := preconditions.validate(scale); err != nil {
122+
if err = preconditions.validate(scale); err != nil {
123+
return "", err
124+
}
125+
scale.Spec.Replicas = int32(newSize)
126+
updatedScale, err := s.scaleNamespacer.Scales(namespace).Update(gvr.GroupResource(), scale)
127+
if err != nil {
127128
return "", err
128129
}
130+
return updatedScale.ResourceVersion, nil
129131
}
130132

131-
scale.Spec.Replicas = int32(newSize)
132-
updatedScale, err := s.scaleNamespacer.Scales(namespace).Update(gr, scale)
133+
patch := []byte(fmt.Sprintf(`{"spec":{"replicas":%d}}`, newSize))
134+
updatedScale, err := s.scaleNamespacer.Scales(namespace).Patch(gvr, name, types.MergePatchType, patch)
133135
if err != nil {
134136
return "", err
135137
}
@@ -138,17 +140,17 @@ func (s *genericScaler) ScaleSimple(namespace, name string, preconditions *Scale
138140

139141
// Scale updates a scale of a given resource to a new size, with optional precondition check (if preconditions is not nil),
140142
// optional retries (if retry is not nil), and then optionally waits for the status to reach desired count.
141-
func (s *genericScaler) Scale(namespace, resourceName string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams, gr schema.GroupResource) error {
143+
func (s *genericScaler) Scale(namespace, resourceName string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams, gvr schema.GroupVersionResource) error {
142144
if retry == nil {
143145
// make it try only once, immediately
144146
retry = &RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
145147
}
146-
cond := ScaleCondition(s, preconditions, namespace, resourceName, newSize, nil, gr)
148+
cond := ScaleCondition(s, preconditions, namespace, resourceName, newSize, nil, gvr)
147149
if err := wait.PollImmediate(retry.Interval, retry.Timeout, cond); err != nil {
148150
return err
149151
}
150152
if waitForReplicas != nil {
151-
return WaitForScaleHasDesiredReplicas(s.scaleNamespacer, gr, resourceName, namespace, newSize, waitForReplicas)
153+
return WaitForScaleHasDesiredReplicas(s.scaleNamespacer, gvr.GroupResource(), resourceName, namespace, newSize, waitForReplicas)
152154
}
153155
return nil
154156
}

0 commit comments

Comments
 (0)