Skip to content

Add pausing in deploymentconfigs #9086

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api/swagger-spec/oapi-v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -19306,6 +19306,10 @@
"type": "boolean",
"description": "Test ensures that this deployment config will have zero replicas except while a deployment is running. This allows the deployment config to be used as a continuous deployment test - triggering on images, running the deployment, and then succeeding or failing. Post strategy hooks and After actions can be used to integrate successful deployment with an action."
},
"paused": {
"type": "boolean",
"description": "Paused indicates that the deployment config is paused resulting in no new deployments on template changes or changes in the template caused by other triggers."
},
"selector": {
"type": "any",
"description": "Selector is a label query over pods that should match the Replicas count."
Expand Down
9 changes: 9 additions & 0 deletions pkg/cmd/cli/cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ func (o DeployOptions) RunDeploy() error {
// deploy launches a new deployment unless there's already a deployment
// process in progress for config.
func (o DeployOptions) deploy(config *deployapi.DeploymentConfig, out io.Writer) error {
if config.Spec.Paused {
return fmt.Errorf("cannot deploy a paused deployment config")
}
// TODO: This implies that deploymentconfig.status.latestVersion is always synced. Currently,
// that's the case because clients (oc, trigger controllers) are updating the status directly.
// Clients should be acting either on spec or on annotations and status updates should be a
Expand Down Expand Up @@ -244,6 +247,9 @@ func (o DeployOptions) deploy(config *deployapi.DeploymentConfig, out io.Writer)
// the deployment to be retried. An error is returned if the deployment is not
// currently in a failed state.
func (o DeployOptions) retry(config *deployapi.DeploymentConfig, out io.Writer) error {
if config.Spec.Paused {
return fmt.Errorf("cannot retry a paused deployment config")
}
if config.Status.LatestVersion == 0 {
return fmt.Errorf("no deployments found for %s/%s", config.Namespace, config.Name)
}
Expand Down Expand Up @@ -297,6 +303,9 @@ func (o DeployOptions) retry(config *deployapi.DeploymentConfig, out io.Writer)

// cancel cancels any deployment process in progress for config.
func (o DeployOptions) cancel(config *deployapi.DeploymentConfig, out io.Writer) error {
if config.Spec.Paused {
return fmt.Errorf("cannot cancel a paused deployment config")
}
deployments, err := o.kubeClient.ReplicationControllers(config.Namespace).List(kapi.ListOptions{LabelSelector: deployutil.ConfigSelector(config.Name)})
if err != nil {
return err
Expand Down
18 changes: 15 additions & 3 deletions pkg/cmd/cli/cmd/rollback.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func (o *RollbackOptions) Complete(f *clientcmd.Factory, args []string, out io.W
// a rollback.
func (o *RollbackOptions) Validate() error {
if len(o.TargetName) == 0 {
return fmt.Errorf("a deployment or deploymentconfig name is required")
return fmt.Errorf("a deployment or deployment config name is required")
}
if o.DesiredVersion < 0 {
return fmt.Errorf("the to version must be >= 0")
Expand Down Expand Up @@ -187,9 +187,21 @@ func (o *RollbackOptions) Run() error {
var target *kapi.ReplicationController
switch r := obj.(type) {
case *kapi.ReplicationController:
dcName := deployutil.DeploymentConfigNameFor(r)
dc, err := o.oc.DeploymentConfigs(r.Namespace).Get(dcName)
if err != nil {
return err
}
if dc.Spec.Paused {
return fmt.Errorf("cannot rollback a paused deployment config")
}

// A specific deployment was used.
target = r
case *deployapi.DeploymentConfig:
if r.Spec.Paused {
return fmt.Errorf("cannot rollback a paused deployment config")
}
// A deploymentconfig was used. Find the target deployment by the
// specified version, or by a lookup of the last completed deployment if
// no version was supplied.
Expand All @@ -200,7 +212,7 @@ func (o *RollbackOptions) Run() error {
target = deployment
}
if target == nil {
return fmt.Errorf("%s is not a valid deployment or deploymentconfig", o.TargetName)
return fmt.Errorf("%s is not a valid deployment or deployment config", o.TargetName)
}

// Set up the rollback and generate a new rolled back config.
Expand Down Expand Up @@ -297,7 +309,7 @@ func (o *RollbackOptions) findResource(targetName string) (runtime.Object, error
break
}
if obj == nil {
return nil, fmt.Errorf("%s is not a valid deployment or deploymentconfig", targetName)
return nil, fmt.Errorf("%s is not a valid deployment or deployment config", targetName)
}
return obj, nil
}
Expand Down
1 change: 1 addition & 0 deletions pkg/deploy/api/deep_copy_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ func DeepCopy_api_DeploymentConfigSpec(in DeploymentConfigSpec, out *DeploymentC
}
out.Replicas = in.Replicas
out.Test = in.Test
out.Paused = in.Paused
if in.Selector != nil {
in, out := in.Selector, &out.Selector
*out = make(map[string]string)
Expand Down
4 changes: 4 additions & 0 deletions pkg/deploy/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,10 @@ type DeploymentConfigSpec struct {
// or failing. Post strategy hooks and After actions can be used to integrate successful deployment with an action.
Test bool

// Paused indicates that the deployment config is paused resulting in no new deployments on template
// changes or changes in the template caused by other triggers.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it also mean I can't do oc deploy --latest ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the command will succeed but nothing will be deployed until the config is un-paused.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am disallowing oc deploy --latest for paused deployments. Regarding pausing the deployer, as per @smarterclayton's comments, we probably need to give it more thought (and work) so I guess the first version of oc rollout pause will not pause the deployer if there is one running.

Paused bool

// Selector is a label query over pods that should match the Replicas count.
Selector map[string]string

Expand Down
2 changes: 2 additions & 0 deletions pkg/deploy/api/v1/conversion_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ func autoConvert_v1_DeploymentConfigSpec_To_api_DeploymentConfigSpec(in *Deploym
}
out.Replicas = in.Replicas
out.Test = in.Test
out.Paused = in.Paused
if in.Selector != nil {
in, out := &in.Selector, &out.Selector
*out = make(map[string]string, len(*in))
Expand Down Expand Up @@ -437,6 +438,7 @@ func autoConvert_api_DeploymentConfigSpec_To_v1_DeploymentConfigSpec(in *deploy_
}
out.Replicas = in.Replicas
out.Test = in.Test
out.Paused = in.Paused
if in.Selector != nil {
in, out := &in.Selector, &out.Selector
*out = make(map[string]string, len(*in))
Expand Down
1 change: 1 addition & 0 deletions pkg/deploy/api/v1/deep_copy_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ func DeepCopy_v1_DeploymentConfigSpec(in DeploymentConfigSpec, out *DeploymentCo
}
out.Replicas = in.Replicas
out.Test = in.Test
out.Paused = in.Paused
if in.Selector != nil {
in, out := in.Selector, &out.Selector
*out = make(map[string]string)
Expand Down
1 change: 1 addition & 0 deletions pkg/deploy/api/v1/swagger_doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ var map_DeploymentConfigSpec = map[string]string{
"triggers": "Triggers determine how updates to a DeploymentConfig result in new deployments. If no triggers are defined, a new deployment can only occur as a result of an explicit client update to the DeploymentConfig with a new LatestVersion.",
"replicas": "Replicas is the number of desired replicas.",
"test": "Test ensures that this deployment config will have zero replicas except while a deployment is running. This allows the deployment config to be used as a continuous deployment test - triggering on images, running the deployment, and then succeeding or failing. Post strategy hooks and After actions can be used to integrate successful deployment with an action.",
"paused": "Paused indicates that the deployment config is paused resulting in no new deployments on template changes or changes in the template caused by other triggers.",
"selector": "Selector is a label query over pods that should match the Replicas count.",
"template": "Template is the object that describes the pod that will be created if insufficient replicas are detected.",
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/deploy/api/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ type DeploymentConfigSpec struct {
// or failing. Post strategy hooks and After actions can be used to integrate successful deployment with an action.
Test bool `json:"test"`

// Paused indicates that the deployment config is paused resulting in no new deployments on template
// changes or changes in the template caused by other triggers.
Paused bool `json:"paused,omitempty"`

// Selector is a label query over pods that should match the Replicas count.
Selector map[string]string `json:"selector,omitempty"`

Expand Down
4 changes: 4 additions & 0 deletions pkg/deploy/api/v1beta3/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,10 @@ type DeploymentConfigSpec struct {
// or failing. Post strategy hooks and After actions can be used to integrate successful deployment with an action.
Test bool `json:"test"`

// Paused indicates that the deployment config is paused resulting in no new deployments on template
// changes or changes in the template caused by other triggers.
Paused bool `json:"paused,omitempty"`

// Selector is a label query over pods that should match the Replicas count.
Selector map[string]string `json:"selector,omitempty"`

Expand Down
3 changes: 1 addition & 2 deletions pkg/deploy/controller/configchange/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ func (e fatalError) Error() string {

// Handle processes change triggers for config.
func (c *DeploymentConfigChangeController) Handle(config *deployapi.DeploymentConfig) error {
if !deployutil.HasChangeTrigger(config) {
glog.V(5).Infof("Ignoring deployment config %q; no change triggers detected", deployutil.LabelForDeploymentConfig(config))
if !deployutil.HasChangeTrigger(config) || config.Spec.Paused {
return nil
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/deploy/controller/deploymentconfig/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ func (c *DeploymentConfigController) Handle(config *deployapi.DeploymentConfig)
}
return c.reconcileDeployments(existingDeployments, config)
}
// If the config is paused we shouldn't create new deployments for it.
// TODO: Make sure cleanup policy will work for paused configs.
if config.Spec.Paused {
return c.updateStatus(config)
}
// No deployments are running and the latest deployment doesn't exist, so
// create the new deployment.
deployment, err := deployutil.MakeDeployment(config, c.codec)
Expand Down
2 changes: 1 addition & 1 deletion pkg/deploy/controller/imagechange/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (c *ImageChangeController) Handle(stream *imageapi.ImageStream) error {
// be able to work and not try to pull non-existent images from DockerHub.
// Deployments with automatic set to false that have been deployed at least
// once shouldn't have their images updated.
if !params.Automatic && len(params.LastTriggeredImage) > 0 {
if (!params.Automatic || config.Spec.Paused) && len(params.LastTriggeredImage) > 0 {
continue
}

Expand Down
Loading