@@ -22,6 +22,7 @@ import (
2222
2323 "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
2424 "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
25+ "github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait"
2526)
2627
2728// ResizePrecondition describes a condition that must be true for the resize to take place
@@ -33,23 +34,46 @@ type ResizePrecondition struct {
3334 ResourceVersion string
3435}
3536
37+ // A PreconditionError is returned when a replication controller fails to match
38+ // the resize preconditions passed to kubectl.
3639type PreconditionError struct {
3740 Precondition string
3841 ExpectedValue string
3942 ActualValue string
4043}
4144
42- func (pe * PreconditionError ) Error () string {
45+ func (pe PreconditionError ) Error () string {
4346 return fmt .Sprintf ("Expected %s to be %s, was %s" , pe .Precondition , pe .ExpectedValue , pe .ActualValue )
4447}
4548
49+ type ControllerResizeErrorType int
50+
51+ const (
52+ ControllerResizeGetFailure ControllerResizeErrorType = iota
53+ ControllerResizeUpdateFailure
54+ )
55+
56+ // A ControllerResizeError is returned when a the resize request passes
57+ // preconditions but fails to actually resize the controller.
58+ type ControllerResizeError struct {
59+ FailureType ControllerResizeErrorType
60+ ResourceVersion string
61+ ActualError error
62+ }
63+
64+ func (c ControllerResizeError ) Error () string {
65+ return fmt .Sprintf (
66+ "Resizing the controller failed with: %s; Current resource version %s" ,
67+ c .ActualError , c .ResourceVersion )
68+ }
69+
4670// Validate ensures that the preconditions match. Returns nil if they are valid, an error otherwise
4771func (precondition * ResizePrecondition ) Validate (controller * api.ReplicationController ) error {
4872 if precondition .Size != - 1 && controller .Spec .Replicas != precondition .Size {
49- return & PreconditionError {"replicas" , strconv .Itoa (precondition .Size ), strconv .Itoa (controller .Spec .Replicas )}
73+ return PreconditionError {"replicas" , strconv .Itoa (precondition .Size ), strconv .Itoa (controller .Spec .Replicas )}
5074 }
5175 if precondition .ResourceVersion != "" && controller .ResourceVersion != precondition .ResourceVersion {
52- return & PreconditionError {"resource version" , precondition .ResourceVersion , controller .ResourceVersion }
76+ return PreconditionError {"resource version" , precondition .ResourceVersion , controller .ResourceVersion }
5377 }
5478 return nil
5579}
@@ -70,11 +94,27 @@ type ReplicationControllerResizer struct {
7094 client.Interface
7195}
7296
97+ // ResizeCondition is a closure around Resize that facilitates retries via util.wait
98+ func ResizeCondition (r Resizer , precondition * ResizePrecondition , namespace , name string , count uint ) wait.ConditionFunc {
99+ return func () (bool , error ) {
100+ _ , err := r .Resize (namespace , name , precondition , count )
101+ switch e , _ := err .(ControllerResizeError ); err .(type ) {
102+ case nil :
103+ return true , nil
104+ case ControllerResizeError :
105+ if e .FailureType == ControllerResizeUpdateFailure {
106+ return false , nil
107+ }
108+ }
109+ return false , err
110+ }
111+ }
112+
73113func (resize * ReplicationControllerResizer ) Resize (namespace , name string , preconditions * ResizePrecondition , newSize uint ) (string , error ) {
74114 rc := resize .ReplicationControllers (namespace )
75115 controller , err := rc .Get (name )
76116 if err != nil {
77- return "" , err
117+ return "" , ControllerResizeError { ControllerResizeGetFailure , "Unknown" , err }
78118 }
79119
80120 if preconditions != nil {
@@ -86,7 +126,7 @@ func (resize *ReplicationControllerResizer) Resize(namespace, name string, preco
86126 controller .Spec .Replicas = int (newSize )
87127 // TODO: do retry on 409 errors here?
88128 if _ , err := rc .Update (controller ); err != nil {
89- return "" , err
129+ return "" , ControllerResizeError { ControllerResizeUpdateFailure , controller . ResourceVersion , err }
90130 }
91131 // TODO: do a better job of printing objects here.
92132 return "resized" , nil
0 commit comments