// DeployWithAcceptor scales down from and then scales up to. If // updateAcceptor is provided and the desired replica count is >1, the first // replica of to is rolled out and validated before performing the full scale // up. // // This is currently only used in conjunction with the rolling update strategy // for initial deployments. func (s *RecreateDeploymentStrategy) DeployWithAcceptor(from *kapi.ReplicationController, to *kapi.ReplicationController, desiredReplicas int, updateAcceptor strat.UpdateAcceptor) error { config, err := deployutil.DecodeDeploymentConfig(to, s.codec) if err != nil { return fmt.Errorf("couldn't decode config from deployment %s: %v", to.Name, err) } params := config.Spec.Strategy.RecreateParams retryParams := kubectl.NewRetryParams(s.retryPeriod, s.retryTimeout) waitParams := kubectl.NewRetryParams(s.retryPeriod, s.retryTimeout) // Execute any pre-hook. if params != nil && params.Pre != nil { if err := s.hookExecutor.Execute(params.Pre, to, "prehook"); err != nil { return fmt.Errorf("Pre hook failed: %s", err) } else { glog.Infof("Pre hook finished") } } // Scale down the from deployment. if from != nil { glog.Infof("Scaling %s down to zero", deployutil.LabelForDeployment(from)) _, err := s.scaleAndWait(from, 0, retryParams, waitParams) if err != nil { return fmt.Errorf("couldn't scale %s to 0: %v", deployutil.LabelForDeployment(from), err) } } // Scale up the to deployment. if desiredReplicas > 0 { // If an UpdateAcceptor is provided, scale up to 1 and validate the replica, // aborting if the replica isn't acceptable. if updateAcceptor != nil { glog.Infof("Scaling %s to 1 before performing acceptance check", deployutil.LabelForDeployment(to)) updatedTo, err := s.scaleAndWait(to, 1, retryParams, waitParams) if err != nil { return fmt.Errorf("couldn't scale %s to 1: %v", deployutil.LabelForDeployment(to), err) } glog.Infof("Performing acceptance check of %s", deployutil.LabelForDeployment(to)) if err := updateAcceptor.Accept(updatedTo); err != nil { return fmt.Errorf("update acceptor rejected %s: %v", deployutil.LabelForDeployment(to), err) } to = updatedTo } // Complete the scale up. if to.Spec.Replicas != desiredReplicas { glog.Infof("Scaling %s to %d", deployutil.LabelForDeployment(to), desiredReplicas) updatedTo, err := s.scaleAndWait(to, desiredReplicas, retryParams, waitParams) if err != nil { return fmt.Errorf("couldn't scale %s to %d: %v", deployutil.LabelForDeployment(to), desiredReplicas, err) } to = updatedTo } } // Execute any post-hook. Errors are logged and ignored. if params != nil && params.Post != nil { if err := s.hookExecutor.Execute(params.Post, to, "posthook"); err != nil { util.HandleError(fmt.Errorf("post hook failed: %s", err)) } else { glog.Infof("Post hook finished") } } glog.Infof("Deployment %s successfully made active", to.Name) return nil }
// DeployWithAcceptor scales down from and then scales up to. If // updateAcceptor is provided and the desired replica count is >1, the first // replica of to is rolled out and validated before performing the full scale // up. // // This is currently only used in conjunction with the rolling update strategy // for initial deployments. func (s *RecreateDeploymentStrategy) DeployWithAcceptor(from *kapi.ReplicationController, to *kapi.ReplicationController, desiredReplicas int, updateAcceptor strat.UpdateAcceptor) error { config, err := deployutil.DecodeDeploymentConfig(to, s.decoder) if err != nil { return fmt.Errorf("couldn't decode config from deployment %s: %v", to.Name, err) } params := config.Spec.Strategy.RecreateParams retryParams := kubectl.NewRetryParams(s.retryPeriod, s.retryTimeout) waitParams := kubectl.NewRetryParams(s.retryPeriod, s.retryTimeout) if updateAcceptor == nil { updateAcceptor = s.getUpdateAcceptor(time.Duration(*params.TimeoutSeconds)*time.Second, config.Spec.MinReadySeconds) } // Execute any pre-hook. if params != nil && params.Pre != nil { if err := s.hookExecutor.Execute(params.Pre, to, deployapi.PreHookPodSuffix, "pre"); err != nil { return fmt.Errorf("pre hook failed: %s", err) } } if s.until == "pre" { return strat.NewConditionReachedErr("pre hook succeeded") } // Record all warnings defer stratutil.RecordConfigWarnings(s.eventClient, from, s.decoder, s.out) defer stratutil.RecordConfigWarnings(s.eventClient, to, s.decoder, s.out) // Scale down the from deployment. if from != nil { fmt.Fprintf(s.out, "--> Scaling %s down to zero\n", from.Name) _, err := s.scaleAndWait(from, 0, retryParams, waitParams) if err != nil { return fmt.Errorf("couldn't scale %s to 0: %v", from.Name, err) } } if s.until == "0%" { return strat.NewConditionReachedErr("Reached 0% (no running pods)") } if params != nil && params.Mid != nil { if err := s.hookExecutor.Execute(params.Mid, to, deployapi.MidHookPodSuffix, "mid"); err != nil { return fmt.Errorf("mid hook failed: %s", err) } } if s.until == "mid" { return strat.NewConditionReachedErr("mid hook succeeded") } accepted := false // Scale up the to deployment. if desiredReplicas > 0 { if from != nil { // Scale up to 1 and validate the replica, // aborting if the replica isn't acceptable. fmt.Fprintf(s.out, "--> Scaling %s to 1 before performing acceptance check\n", to.Name) updatedTo, err := s.scaleAndWait(to, 1, retryParams, waitParams) if err != nil { return fmt.Errorf("couldn't scale %s to 1: %v", to.Name, err) } if err := updateAcceptor.Accept(updatedTo); err != nil { return fmt.Errorf("update acceptor rejected %s: %v", to.Name, err) } accepted = true to = updatedTo if strat.PercentageBetween(s.until, 1, 99) { return strat.NewConditionReachedErr(fmt.Sprintf("Reached %s", s.until)) } } // Complete the scale up. if to.Spec.Replicas != int32(desiredReplicas) { fmt.Fprintf(s.out, "--> Scaling %s to %d\n", to.Name, desiredReplicas) updatedTo, err := s.scaleAndWait(to, desiredReplicas, retryParams, waitParams) if err != nil { return fmt.Errorf("couldn't scale %s to %d: %v", to.Name, desiredReplicas, err) } to = updatedTo } if !accepted { if err := updateAcceptor.Accept(to); err != nil { return fmt.Errorf("update acceptor rejected %s: %v", to.Name, err) } } } if (from == nil && strat.PercentageBetween(s.until, 1, 100)) || (from != nil && s.until == "100%") { return strat.NewConditionReachedErr(fmt.Sprintf("Reached %s", s.until)) } // Execute any post-hook. if params != nil && params.Post != nil { if err := s.hookExecutor.Execute(params.Post, to, deployapi.PostHookPodSuffix, "post"); err != nil { return fmt.Errorf("post hook failed: %s", err) } } return nil }