| ... | ... |
@@ -211,6 +211,9 @@ func (o DeployOptions) RunDeploy() error {
|
| 211 | 211 |
// deploy launches a new deployment unless there's already a deployment |
| 212 | 212 |
// process in progress for config. |
| 213 | 213 |
func (o DeployOptions) deploy(config *deployapi.DeploymentConfig, out io.Writer) error {
|
| 214 |
+ if config.Spec.Paused {
|
|
| 215 |
+ return fmt.Errorf("cannot deploy a paused deployment config")
|
|
| 216 |
+ } |
|
| 214 | 217 |
// TODO: This implies that deploymentconfig.status.latestVersion is always synced. Currently, |
| 215 | 218 |
// that's the case because clients (oc, trigger controllers) are updating the status directly. |
| 216 | 219 |
// Clients should be acting either on spec or on annotations and status updates should be a |
| ... | ... |
@@ -244,6 +247,9 @@ func (o DeployOptions) deploy(config *deployapi.DeploymentConfig, out io.Writer) |
| 244 | 244 |
// the deployment to be retried. An error is returned if the deployment is not |
| 245 | 245 |
// currently in a failed state. |
| 246 | 246 |
func (o DeployOptions) retry(config *deployapi.DeploymentConfig, out io.Writer) error {
|
| 247 |
+ if config.Spec.Paused {
|
|
| 248 |
+ return fmt.Errorf("cannot retry a paused deployment config")
|
|
| 249 |
+ } |
|
| 247 | 250 |
if config.Status.LatestVersion == 0 {
|
| 248 | 251 |
return fmt.Errorf("no deployments found for %s/%s", config.Namespace, config.Name)
|
| 249 | 252 |
} |
| ... | ... |
@@ -297,6 +303,9 @@ func (o DeployOptions) retry(config *deployapi.DeploymentConfig, out io.Writer) |
| 297 | 297 |
|
| 298 | 298 |
// cancel cancels any deployment process in progress for config. |
| 299 | 299 |
func (o DeployOptions) cancel(config *deployapi.DeploymentConfig, out io.Writer) error {
|
| 300 |
+ if config.Spec.Paused {
|
|
| 301 |
+ return fmt.Errorf("cannot cancel a paused deployment config")
|
|
| 302 |
+ } |
|
| 300 | 303 |
deployments, err := o.kubeClient.ReplicationControllers(config.Namespace).List(kapi.ListOptions{LabelSelector: deployutil.ConfigSelector(config.Name)})
|
| 301 | 304 |
if err != nil {
|
| 302 | 305 |
return err |
| ... | ... |
@@ -150,7 +150,7 @@ func (o *RollbackOptions) Complete(f *clientcmd.Factory, args []string, out io.W |
| 150 | 150 |
// a rollback. |
| 151 | 151 |
func (o *RollbackOptions) Validate() error {
|
| 152 | 152 |
if len(o.TargetName) == 0 {
|
| 153 |
- return fmt.Errorf("a deployment or deploymentconfig name is required")
|
|
| 153 |
+ return fmt.Errorf("a deployment or deployment config name is required")
|
|
| 154 | 154 |
} |
| 155 | 155 |
if o.DesiredVersion < 0 {
|
| 156 | 156 |
return fmt.Errorf("the to version must be >= 0")
|
| ... | ... |
@@ -187,9 +187,21 @@ func (o *RollbackOptions) Run() error {
|
| 187 | 187 |
var target *kapi.ReplicationController |
| 188 | 188 |
switch r := obj.(type) {
|
| 189 | 189 |
case *kapi.ReplicationController: |
| 190 |
+ dcName := deployutil.DeploymentConfigNameFor(r) |
|
| 191 |
+ dc, err := o.oc.DeploymentConfigs(r.Namespace).Get(dcName) |
|
| 192 |
+ if err != nil {
|
|
| 193 |
+ return err |
|
| 194 |
+ } |
|
| 195 |
+ if dc.Spec.Paused {
|
|
| 196 |
+ return fmt.Errorf("cannot rollback a paused deployment config")
|
|
| 197 |
+ } |
|
| 198 |
+ |
|
| 190 | 199 |
// A specific deployment was used. |
| 191 | 200 |
target = r |
| 192 | 201 |
case *deployapi.DeploymentConfig: |
| 202 |
+ if r.Spec.Paused {
|
|
| 203 |
+ return fmt.Errorf("cannot rollback a paused deployment config")
|
|
| 204 |
+ } |
|
| 193 | 205 |
// A deploymentconfig was used. Find the target deployment by the |
| 194 | 206 |
// specified version, or by a lookup of the last completed deployment if |
| 195 | 207 |
// no version was supplied. |
| ... | ... |
@@ -200,7 +212,7 @@ func (o *RollbackOptions) Run() error {
|
| 200 | 200 |
target = deployment |
| 201 | 201 |
} |
| 202 | 202 |
if target == nil {
|
| 203 |
- return fmt.Errorf("%s is not a valid deployment or deploymentconfig", o.TargetName)
|
|
| 203 |
+ return fmt.Errorf("%s is not a valid deployment or deployment config", o.TargetName)
|
|
| 204 | 204 |
} |
| 205 | 205 |
|
| 206 | 206 |
// Set up the rollback and generate a new rolled back config. |
| ... | ... |
@@ -297,7 +309,7 @@ func (o *RollbackOptions) findResource(targetName string) (runtime.Object, error |
| 297 | 297 |
break |
| 298 | 298 |
} |
| 299 | 299 |
if obj == nil {
|
| 300 |
- return nil, fmt.Errorf("%s is not a valid deployment or deploymentconfig", targetName)
|
|
| 300 |
+ return nil, fmt.Errorf("%s is not a valid deployment or deployment config", targetName)
|
|
| 301 | 301 |
} |
| 302 | 302 |
return obj, nil |
| 303 | 303 |
} |
| ... | ... |
@@ -311,6 +311,10 @@ type DeploymentConfigSpec struct {
|
| 311 | 311 |
// or failing. Post strategy hooks and After actions can be used to integrate successful deployment with an action. |
| 312 | 312 |
Test bool |
| 313 | 313 |
|
| 314 |
+ // Paused indicates that the deployment config is paused resulting in no new deployments on template |
|
| 315 |
+ // changes or changes in the template caused by other triggers. |
|
| 316 |
+ Paused bool |
|
| 317 |
+ |
|
| 314 | 318 |
// Selector is a label query over pods that should match the Replicas count. |
| 315 | 319 |
Selector map[string]string |
| 316 | 320 |
|
| ... | ... |
@@ -268,6 +268,10 @@ type DeploymentConfigSpec struct {
|
| 268 | 268 |
// or failing. Post strategy hooks and After actions can be used to integrate successful deployment with an action. |
| 269 | 269 |
Test bool `json:"test"` |
| 270 | 270 |
|
| 271 |
+ // Paused indicates that the deployment config is paused resulting in no new deployments on template |
|
| 272 |
+ // changes or changes in the template caused by other triggers. |
|
| 273 |
+ Paused bool `json:"paused,omitempty"` |
|
| 274 |
+ |
|
| 271 | 275 |
// Selector is a label query over pods that should match the Replicas count. |
| 272 | 276 |
Selector map[string]string `json:"selector,omitempty"` |
| 273 | 277 |
|
| ... | ... |
@@ -284,6 +284,10 @@ type DeploymentConfigSpec struct {
|
| 284 | 284 |
// or failing. Post strategy hooks and After actions can be used to integrate successful deployment with an action. |
| 285 | 285 |
Test bool `json:"test"` |
| 286 | 286 |
|
| 287 |
+ // Paused indicates that the deployment config is paused resulting in no new deployments on template |
|
| 288 |
+ // changes or changes in the template caused by other triggers. |
|
| 289 |
+ Paused bool `json:"paused,omitempty"` |
|
| 290 |
+ |
|
| 287 | 291 |
// Selector is a label query over pods that should match the Replicas count. |
| 288 | 292 |
Selector map[string]string `json:"selector,omitempty"` |
| 289 | 293 |
|
| ... | ... |
@@ -35,8 +35,7 @@ func (e fatalError) Error() string {
|
| 35 | 35 |
|
| 36 | 36 |
// Handle processes change triggers for config. |
| 37 | 37 |
func (c *DeploymentConfigChangeController) Handle(config *deployapi.DeploymentConfig) error {
|
| 38 |
- if !deployutil.HasChangeTrigger(config) {
|
|
| 39 |
- glog.V(5).Infof("Ignoring deployment config %q; no change triggers detected", deployutil.LabelForDeploymentConfig(config))
|
|
| 38 |
+ if !deployutil.HasChangeTrigger(config) || config.Spec.Paused {
|
|
| 40 | 39 |
return nil |
| 41 | 40 |
} |
| 42 | 41 |
|
| ... | ... |
@@ -119,6 +119,11 @@ func (c *DeploymentConfigController) Handle(config *deployapi.DeploymentConfig) |
| 119 | 119 |
} |
| 120 | 120 |
return c.reconcileDeployments(existingDeployments, config) |
| 121 | 121 |
} |
| 122 |
+ // If the config is paused we shouldn't create new deployments for it. |
|
| 123 |
+ // TODO: Make sure cleanup policy will work for paused configs. |
|
| 124 |
+ if config.Spec.Paused {
|
|
| 125 |
+ return c.updateStatus(config) |
|
| 126 |
+ } |
|
| 122 | 127 |
// No deployments are running and the latest deployment doesn't exist, so |
| 123 | 128 |
// create the new deployment. |
| 124 | 129 |
deployment, err := deployutil.MakeDeployment(config, c.codec) |
| ... | ... |
@@ -54,7 +54,7 @@ func (c *ImageChangeController) Handle(stream *imageapi.ImageStream) error {
|
| 54 | 54 |
// be able to work and not try to pull non-existent images from DockerHub. |
| 55 | 55 |
// Deployments with automatic set to false that have been deployed at least |
| 56 | 56 |
// once shouldn't have their images updated. |
| 57 |
- if !params.Automatic && len(params.LastTriggeredImage) > 0 {
|
|
| 57 |
+ if (!params.Automatic || config.Spec.Paused) && len(params.LastTriggeredImage) > 0 {
|
|
| 58 | 58 |
continue |
| 59 | 59 |
} |
| 60 | 60 |
|