forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
scale.go
109 lines (96 loc) · 4.35 KB
/
scale.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package scaler
import (
"time"
kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
kclient "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait"
"github.com/openshift/origin/pkg/client"
"github.com/openshift/origin/pkg/deploy/util"
)
// DeploymentConfigScaler is a wrapper for the kubectl Scaler client
type DeploymentConfigScaler struct {
c kubectl.ScalerClient
}
// ScalerFor returns the appropriate Scaler client depending on the provided
// kind of resource (Replication controllers and deploymentConfigs supported)
func ScalerFor(kind string, oc client.Interface, kc kclient.Interface) (kubectl.Scaler, error) {
if kind != "DeploymentConfig" {
return kubectl.ScalerFor(kind, kubectl.NewScalerClient(kc))
}
return &DeploymentConfigScaler{NewScalerClient(oc, kc)}, nil
}
// Scale updates a replication controller created by the DeploymentConfig with the provided namespace/name,
// to a new size, with optional precondition check (if preconditions is not nil),optional retries (if retry
// is not nil), and then optionally waits for it's replica count to reach the new value (if wait is not nil).
func (scaler *DeploymentConfigScaler) Scale(namespace, name string, newSize uint, preconditions *kubectl.ScalePrecondition, retry, waitForReplicas *kubectl.RetryParams) error {
if preconditions == nil {
preconditions = &kubectl.ScalePrecondition{-1, ""}
}
if retry == nil {
// Make it try only once, immediately
retry = &kubectl.RetryParams{Interval: time.Millisecond, Timeout: time.Millisecond}
}
cond := kubectl.ScaleCondition(scaler, preconditions, namespace, name, newSize)
if err := wait.Poll(retry.Interval, retry.Timeout, cond); err != nil {
return err
}
if waitForReplicas != nil {
rc, err := scaler.c.GetReplicationController(namespace, name)
if err != nil {
return err
}
return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout,
scaler.c.ControllerHasDesiredReplicas(rc))
}
return nil
}
// ScaleSimple does a simple one-shot attempt at scaling - not useful on it's own, but
// a necessary building block for Scale
func (scaler *DeploymentConfigScaler) ScaleSimple(namespace, name string, preconditions *kubectl.ScalePrecondition, newSize uint) (string, error) {
const scaled = "scaled"
controller, err := scaler.c.GetReplicationController(namespace, name)
if err != nil {
return "", kubectl.ControllerScaleError{kubectl.ControllerScaleGetFailure, "Unknown", err}
}
if preconditions != nil {
if err := preconditions.Validate(controller); err != nil {
return "", err
}
}
controller.Spec.Replicas = int(newSize)
// TODO: do retry on 409 errors here?
if _, err := scaler.c.UpdateReplicationController(namespace, controller); err != nil {
return "", kubectl.ControllerScaleError{kubectl.ControllerScaleUpdateFailure, controller.ResourceVersion, err}
}
// TODO: do a better job of printing objects here.
return scaled, nil
}
// NewScalerClient returns a new Scaler client bundling both the OpenShift and
// Kubernetes clients
func NewScalerClient(oc client.Interface, kc kclient.Interface) kubectl.ScalerClient {
return &realScalerClient{oc: oc, kc: kc}
}
// realScalerClient is a ScalerClient which uses an OpenShift and a Kube client.
type realScalerClient struct {
oc client.Interface
kc kclient.Interface
}
// GetReplicationController returns the most recent replication controller associated with the deploymentConfig
// with the provided namespace/name combination
func (c *realScalerClient) GetReplicationController(namespace, name string) (*kapi.ReplicationController, error) {
dc, err := c.oc.DeploymentConfigs(namespace).Get(name)
if err != nil {
return nil, err
}
return c.kc.ReplicationControllers(namespace).Get(util.LatestDeploymentNameForConfig(dc))
}
// UpdateReplicationController updates the provided replication controller
func (c *realScalerClient) UpdateReplicationController(namespace string, rc *kapi.ReplicationController) (*kapi.ReplicationController, error) {
return c.kc.ReplicationControllers(namespace).Update(rc)
}
// ControllerHasDesiredReplicas checks whether the provided replication controller has the desired replicas
// number set
func (c *realScalerClient) ControllerHasDesiredReplicas(rc *kapi.ReplicationController) wait.ConditionFunc {
return kclient.ControllerHasDesiredReplicas(c.kc, rc)
}