Use a label to correlate deployments with their deploymentConfig.
This allows efficient query of the deployments for a config without
performance degradation as a factor of increasing non-deployment
controller count in the project.
| ... | ... |
@@ -145,13 +145,11 @@ func (o DeployOptions) RunDeploy() error {
|
| 145 | 145 |
return o.kubeClient.ReplicationControllers(namespace).Get(name) |
| 146 | 146 |
}, |
| 147 | 147 |
ListDeploymentsForConfigFn: func(namespace, configName string) (*kapi.ReplicationControllerList, error) {
|
| 148 |
- rcs, err := o.kubeClient.ReplicationControllers(namespace).List(labels.Everything()) |
|
| 148 |
+ list, err := o.kubeClient.ReplicationControllers(namespace).List(deployutil.ConfigSelector(configName)) |
|
| 149 | 149 |
if err != nil {
|
| 150 | 150 |
return nil, err |
| 151 | 151 |
} |
| 152 |
- return &kapi.ReplicationControllerList{
|
|
| 153 |
- Items: deployutil.ConfigSelector(configName, rcs.Items), |
|
| 154 |
- }, nil |
|
| 152 |
+ return list, nil |
|
| 155 | 153 |
}, |
| 156 | 154 |
|
| 157 | 155 |
UpdateDeploymentConfigFn: func(config *deployapi.DeploymentConfig) (*deployapi.DeploymentConfig, error) {
|
| ... | ... |
@@ -8,7 +8,6 @@ import ( |
| 8 | 8 |
kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api" |
| 9 | 9 |
kclient "github.com/GoogleCloudPlatform/kubernetes/pkg/client" |
| 10 | 10 |
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl" |
| 11 |
- "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" |
|
| 12 | 11 |
"github.com/golang/glog" |
| 13 | 12 |
"github.com/spf13/cobra" |
| 14 | 13 |
|
| ... | ... |
@@ -83,8 +82,8 @@ func NewDeployer(client kclient.Interface) *Deployer {
|
| 83 | 83 |
getDeployment: func(namespace, name string) (*kapi.ReplicationController, error) {
|
| 84 | 84 |
return client.ReplicationControllers(namespace).Get(name) |
| 85 | 85 |
}, |
| 86 |
- getControllers: func(namespace string) (*kapi.ReplicationControllerList, error) {
|
|
| 87 |
- return client.ReplicationControllers(namespace).List(labels.Everything()) |
|
| 86 |
+ getDeployments: func(namespace, configName string) (*kapi.ReplicationControllerList, error) {
|
|
| 87 |
+ return client.ReplicationControllers(namespace).List(deployutil.ConfigSelector(configName)) |
|
| 88 | 88 |
}, |
| 89 | 89 |
scaler: scaler, |
| 90 | 90 |
strategyFor: func(config *deployapi.DeploymentConfig) (strategy.DeploymentStrategy, error) {
|
| ... | ... |
@@ -114,8 +113,8 @@ type Deployer struct {
|
| 114 | 114 |
strategyFor func(config *deployapi.DeploymentConfig) (strategy.DeploymentStrategy, error) |
| 115 | 115 |
// getDeployment finds the named deployment. |
| 116 | 116 |
getDeployment func(namespace, name string) (*kapi.ReplicationController, error) |
| 117 |
- // getControllers finds all controllers in namespace. |
|
| 118 |
- getControllers func(namespace string) (*kapi.ReplicationControllerList, error) |
|
| 117 |
+ // getDeployments finds all deployments associated with a config. |
|
| 118 |
+ getDeployments func(namespace, configName string) (*kapi.ReplicationControllerList, error) |
|
| 119 | 119 |
// scaler is used to scale replication controllers. |
| 120 | 120 |
scaler kubectl.Scaler |
| 121 | 121 |
} |
| ... | ... |
@@ -146,14 +145,14 @@ func (d *Deployer) Deploy(namespace, deploymentName string) error {
|
| 146 | 146 |
return fmt.Errorf("deployment %s has no desired replica count", deployutil.LabelForDeployment(deployment))
|
| 147 | 147 |
} |
| 148 | 148 |
|
| 149 |
- // Find all controllers in order to pick out the deployments. |
|
| 150 |
- controllers, err := d.getControllers(namespace) |
|
| 149 |
+ // Find all deployments for the config. |
|
| 150 |
+ unsortedDeployments, err := d.getDeployments(namespace, config.Name) |
|
| 151 | 151 |
if err != nil {
|
| 152 | 152 |
return fmt.Errorf("couldn't get controllers in namespace %s: %v", namespace, err)
|
| 153 | 153 |
} |
| 154 |
+ deployments := unsortedDeployments.Items |
|
| 154 | 155 |
|
| 155 |
- // Find all deployments sorted by version. |
|
| 156 |
- deployments := deployutil.ConfigSelector(config.Name, controllers.Items) |
|
| 156 |
+ // Sort all the deployments by version. |
|
| 157 | 157 |
sort.Sort(deployutil.DeploymentsByLatestVersionDesc(deployments)) |
| 158 | 158 |
|
| 159 | 159 |
// Find any last completed deployment. |
| ... | ... |
@@ -23,7 +23,7 @@ func TestDeployer_getDeploymentFail(t *testing.T) {
|
| 23 | 23 |
getDeployment: func(namespace, name string) (*kapi.ReplicationController, error) {
|
| 24 | 24 |
return nil, fmt.Errorf("get error")
|
| 25 | 25 |
}, |
| 26 |
- getControllers: func(namespace string) (*kapi.ReplicationControllerList, error) {
|
|
| 26 |
+ getDeployments: func(namespace, configName string) (*kapi.ReplicationControllerList, error) {
|
|
| 27 | 27 |
t.Fatal("unexpected call")
|
| 28 | 28 |
return nil, nil |
| 29 | 29 |
}, |
| ... | ... |
@@ -144,7 +144,7 @@ func TestDeployer_deployScenarios(t *testing.T) {
|
| 144 | 144 |
getDeployment: func(namespace, name string) (*kapi.ReplicationController, error) {
|
| 145 | 145 |
return to, nil |
| 146 | 146 |
}, |
| 147 |
- getControllers: func(namespace string) (*kapi.ReplicationControllerList, error) {
|
|
| 147 |
+ getDeployments: func(namespace, configName string) (*kapi.ReplicationControllerList, error) {
|
|
| 148 | 148 |
list := &kapi.ReplicationControllerList{}
|
| 149 | 149 |
for _, d := range s.deployments {
|
| 150 | 150 |
list.Items = append(list.Items, *d) |
| ... | ... |
@@ -52,12 +52,12 @@ func (factory *DeploymentConfigControllerFactory) Create() controller.RunnableCo |
| 52 | 52 |
return factory.KubeClient.ReplicationControllers(namespace).Create(deployment) |
| 53 | 53 |
}, |
| 54 | 54 |
listDeploymentsForConfigFunc: func(namespace, configName string) (*kapi.ReplicationControllerList, error) {
|
| 55 |
- rcList, err := factory.KubeClient.ReplicationControllers(namespace).List(labels.Everything()) |
|
| 55 |
+ sel := deployutil.ConfigSelector(configName) |
|
| 56 |
+ list, err := factory.KubeClient.ReplicationControllers(namespace).List(sel) |
|
| 56 | 57 |
if err != nil {
|
| 57 | 58 |
return nil, err |
| 58 | 59 |
} |
| 59 |
- rcList.Items = deployutil.ConfigSelector(configName, rcList.Items) |
|
| 60 |
- return rcList, nil |
|
| 60 |
+ return list, nil |
|
| 61 | 61 |
}, |
| 62 | 62 |
updateDeploymentFunc: func(namespace string, deployment *kapi.ReplicationController) (*kapi.ReplicationController, error) {
|
| 63 | 63 |
return factory.KubeClient.ReplicationControllers(namespace).Update(deployment) |
| ... | ... |
@@ -8,7 +8,6 @@ import ( |
| 8 | 8 |
kerrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" |
| 9 | 9 |
kclient "github.com/GoogleCloudPlatform/kubernetes/pkg/client" |
| 10 | 10 |
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl" |
| 11 |
- "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" |
|
| 12 | 11 |
"github.com/golang/glog" |
| 13 | 12 |
|
| 14 | 13 |
"github.com/openshift/origin/pkg/client" |
| ... | ... |
@@ -52,7 +51,7 @@ func (reaper *DeploymentConfigReaper) Stop(namespace, name string, gracePeriod * |
| 52 | 52 |
} |
| 53 | 53 |
|
| 54 | 54 |
// Clean up deployments related to the config. |
| 55 |
- rcList, err := reaper.kc.ReplicationControllers(namespace).List(labels.Everything()) |
|
| 55 |
+ rcList, err := reaper.kc.ReplicationControllers(namespace).List(util.ConfigSelector(name)) |
|
| 56 | 56 |
if err != nil {
|
| 57 | 57 |
return "", err |
| 58 | 58 |
} |
| ... | ... |
@@ -62,7 +61,7 @@ func (reaper *DeploymentConfigReaper) Stop(namespace, name string, gracePeriod * |
| 62 | 62 |
} |
| 63 | 63 |
|
| 64 | 64 |
// If there is neither a config nor any deployments, we can return NotFound. |
| 65 |
- deployments := util.ConfigSelector(name, rcList.Items) |
|
| 65 |
+ deployments := rcList.Items |
|
| 66 | 66 |
if configNotFound && len(deployments) == 0 {
|
| 67 | 67 |
return "", kerrors.NewNotFound("DeploymentConfig", name)
|
| 68 | 68 |
} |
| ... | ... |
@@ -109,15 +109,13 @@ func LabelForDeploymentConfig(config *deployapi.DeploymentConfig) string {
|
| 109 | 109 |
return fmt.Sprintf("%s/%s:%d", config.Namespace, config.Name, config.LatestVersion)
|
| 110 | 110 |
} |
| 111 | 111 |
|
| 112 |
-// ConfigSelector matches all the deployments of the provided DeploymentConfig |
|
| 113 |
-func ConfigSelector(name string, list []api.ReplicationController) []api.ReplicationController {
|
|
| 114 |
- matches := []api.ReplicationController{}
|
|
| 115 |
- for _, rc := range list {
|
|
| 116 |
- if DeploymentConfigNameFor(&rc) == name {
|
|
| 117 |
- matches = append(matches, rc) |
|
| 118 |
- } |
|
| 119 |
- } |
|
| 120 |
- return matches |
|
| 112 |
+// ConfigSelector returns a label Selector which can be used to find all |
|
| 113 |
+// deployments for a DeploymentConfig. |
|
| 114 |
+// |
|
| 115 |
+// TODO: Using the annotation constant for now since the value is correct |
|
| 116 |
+// but we could consider adding a new constant to the public types. |
|
| 117 |
+func ConfigSelector(name string) labels.Selector {
|
|
| 118 |
+ return labels.Set{deployapi.DeploymentConfigAnnotation: name}.AsSelector()
|
|
| 121 | 119 |
} |
| 122 | 120 |
|
| 123 | 121 |
// DecodeDeploymentConfig decodes a DeploymentConfig from controller using codec. An error is returned |
| ... | ... |
@@ -165,6 +163,10 @@ func MakeDeployment(config *deployapi.DeploymentConfig, codec runtime.Codec) (*a |
| 165 | 165 |
for k, v := range config.Labels {
|
| 166 | 166 |
controllerLabels[k] = v |
| 167 | 167 |
} |
| 168 |
+ // Correlate the deployment with the config. |
|
| 169 |
+ // TODO: Using the annotation constant for now since the value is correct |
|
| 170 |
+ // but we could consider adding a new constant to the public types. |
|
| 171 |
+ controllerLabels[deployapi.DeploymentConfigAnnotation] = config.Name |
|
| 168 | 172 |
|
| 169 | 173 |
// Ensure that pods created by this deployment controller can be safely associated back |
| 170 | 174 |
// to the controller, and that multiple deployment controllers for the same config don't |
| ... | ... |
@@ -107,6 +107,10 @@ func TestMakeDeploymentOk(t *testing.T) {
|
| 107 | 107 |
t.Fatalf("expected deployment replicas to be 0")
|
| 108 | 108 |
} |
| 109 | 109 |
|
| 110 |
+ if l, e, a := deployapi.DeploymentConfigAnnotation, config.Name, deployment.Labels[deployapi.DeploymentConfigAnnotation]; e != a {
|
|
| 111 |
+ t.Fatalf("expected label %s=%s, got %s", l, e, a)
|
|
| 112 |
+ } |
|
| 113 |
+ |
|
| 110 | 114 |
if e, a := config.Name, deployment.Spec.Template.Labels[deployapi.DeploymentConfigLabel]; e != a {
|
| 111 | 115 |
t.Fatalf("expected label DeploymentConfigLabel=%s, got %s", e, a)
|
| 112 | 116 |
} |