2014-12-10 21:48:48 +00:00
/ *
2016-06-03 00:25:58 +00:00
Copyright 2014 The Kubernetes Authors .
2014-12-10 21:48:48 +00:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package cmd
import (
2015-04-23 23:27:19 +00:00
"bytes"
2014-12-10 21:48:48 +00:00
"fmt"
2015-08-05 14:21:47 +00:00
"time"
2014-12-10 21:48:48 +00:00
2015-05-13 13:16:24 +00:00
"github.com/golang/glog"
2015-08-05 22:05:17 +00:00
"github.com/spf13/cobra"
2016-09-08 14:24:02 +00:00
2017-06-22 18:24:23 +00:00
"k8s.io/api/core/v1"
2017-01-13 17:48:50 +00:00
"k8s.io/apimachinery/pkg/api/errors"
2017-01-11 14:09:48 +00:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
2017-01-27 20:42:17 +00:00
"k8s.io/apimachinery/pkg/util/intstr"
2018-04-24 04:40:35 +00:00
scaleclient "k8s.io/client-go/scale"
2017-10-16 11:41:50 +00:00
"k8s.io/kubernetes/pkg/api/legacyscheme"
2017-11-08 22:34:54 +00:00
api "k8s.io/kubernetes/pkg/apis/core"
2018-04-24 04:40:35 +00:00
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/kubectl"
2016-10-07 22:24:42 +00:00
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
2015-08-05 22:03:47 +00:00
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
2018-04-24 04:40:35 +00:00
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/kubectl/resource"
2017-05-19 21:33:08 +00:00
"k8s.io/kubernetes/pkg/kubectl/util"
2017-07-07 04:04:11 +00:00
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
2018-04-24 04:40:35 +00:00
"k8s.io/kubernetes/pkg/kubectl/validation"
"k8s.io/kubernetes/pkg/printers"
2014-12-10 21:48:48 +00:00
)
2016-05-20 17:49:56 +00:00
var (
2017-02-16 03:47:00 +00:00
rollingUpdateLong = templates . LongDesc ( i18n . T ( `
2016-05-20 17:49:56 +00:00
Perform a rolling update of the given ReplicationController .
2014-12-10 21:48:48 +00:00
2016-05-20 17:49:56 +00:00
Replaces the specified replication controller with a new replication controller by updating one pod at a time to use the
new PodTemplate . The new - controller . json must specify the same namespace as the
2016-05-18 14:27:37 +00:00
existing replication controller and overwrite at least one ( common ) label in its replicaSelector .
2017-03-15 03:49:10 +00:00
! [ Workflow ] ( http : //kubernetes.io/images/docs/kubectl_rollingupdate.svg)`))
2016-10-07 22:24:42 +00:00
2017-02-16 03:47:00 +00:00
rollingUpdateExample = templates . Examples ( i18n . T ( `
2016-05-20 17:49:56 +00:00
# Update pods of frontend - v1 using new replication controller data in frontend - v2 . json .
kubectl rolling - update frontend - v1 - f frontend - v2 . json
2014-12-10 21:48:48 +00:00
2016-05-20 17:49:56 +00:00
# Update pods of frontend - v1 using JSON data passed into stdin .
cat frontend - v2 . json | kubectl rolling - update frontend - v1 - f -
2015-04-23 23:27:19 +00:00
2016-05-20 17:49:56 +00:00
# Update the pods of frontend - v1 to frontend - v2 by just changing the image , and switching the
# name of the replication controller .
kubectl rolling - update frontend - v1 frontend - v2 -- image = image : v2
2015-04-23 23:27:19 +00:00
2016-05-20 17:49:56 +00:00
# Update the pods of frontend by just changing the image , and keeping the old name .
kubectl rolling - update frontend -- image = image : v2
2015-11-11 21:29:54 +00:00
2016-05-20 17:49:56 +00:00
# Abort and reverse an existing rollout in progress ( from frontend - v1 to frontend - v2 ) .
2017-03-15 03:49:10 +00:00
kubectl rolling - update frontend - v1 frontend - v2 -- rollback ` ) )
2015-02-20 21:28:43 +00:00
)
2015-02-03 17:59:21 +00:00
2015-08-05 14:21:47 +00:00
var (
updatePeriod , _ = time . ParseDuration ( "1m0s" )
timeout , _ = time . ParseDuration ( "5m0s" )
pollInterval , _ = time . ParseDuration ( "3s" )
)
2018-04-24 04:40:35 +00:00
type RollingUpdateOptions struct {
FilenameOptions * resource . FilenameOptions
OldName string
KeepOldName bool
DeploymentKey string
Image string
Container string
PullPolicy string
Rollback bool
Period time . Duration
Timeout time . Duration
Interval time . Duration
DryRun bool
OutputFormat string
Namespace string
EnforceNamespace bool
ScaleClient scaleclient . ScalesGetter
ClientSet internalclientset . Interface
Builder * resource . Builder
ShouldValidate bool
Validator func ( bool ) ( validation . Schema , error )
FindNewName func ( * api . ReplicationController ) string
PrintFlags * printers . PrintFlags
ToPrinter func ( string ) ( printers . ResourcePrinterFunc , error )
genericclioptions . IOStreams
}
func NewRollingUpdateOptions ( streams genericclioptions . IOStreams ) * RollingUpdateOptions {
return & RollingUpdateOptions {
PrintFlags : printers . NewPrintFlags ( "rolling updated" ) ,
FilenameOptions : & resource . FilenameOptions { } ,
DeploymentKey : "deployment" ,
Timeout : timeout ,
Interval : pollInterval ,
Period : updatePeriod ,
IOStreams : streams ,
}
}
func NewCmdRollingUpdate ( f cmdutil . Factory , ioStreams genericclioptions . IOStreams ) * cobra . Command {
o := NewRollingUpdateOptions ( ioStreams )
2015-08-14 18:46:43 +00:00
2015-02-20 21:28:43 +00:00
cmd := & cobra . Command {
2017-10-11 06:26:02 +00:00
Use : "rolling-update OLD_CONTROLLER_NAME ([NEW_CONTROLLER_NAME] --image=NEW_CONTAINER_IMAGE | -f NEW_CONTROLLER_SPEC)" ,
DisableFlagsInUseLine : true ,
2018-03-16 16:20:14 +00:00
Short : "Perform a rolling update. This command is deprecated, use rollout instead." ,
Long : rollingUpdateLong ,
Example : rollingUpdateExample ,
Deprecated : ` use "rollout" instead ` ,
Hidden : true ,
2014-12-10 21:48:48 +00:00
Run : func ( cmd * cobra . Command , args [ ] string ) {
2018-04-24 04:40:35 +00:00
cmdutil . CheckErr ( o . Complete ( f , cmd , args ) )
cmdutil . CheckErr ( o . Validate ( cmd , args ) )
cmdutil . CheckErr ( o . Run ( ) )
2015-03-09 22:08:16 +00:00
} ,
}
2018-04-24 04:40:35 +00:00
o . PrintFlags . AddFlags ( cmd )
cmd . Flags ( ) . DurationVar ( & o . Period , "update-period" , o . Period , ` Time to wait between updating pods. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". ` )
cmd . Flags ( ) . DurationVar ( & o . Interval , "poll-interval" , o . Interval , ` Time delay between polling for replication controller status after the update. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". ` )
cmd . Flags ( ) . DurationVar ( & o . Timeout , "timeout" , o . Timeout , ` Max time to wait for a replication controller to update before giving up. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". ` )
2015-03-29 03:39:19 +00:00
usage := "Filename or URL to file to use to create the new replication controller."
2018-04-24 04:40:35 +00:00
kubectl . AddJsonFilenameFlag ( cmd , & o . FilenameOptions . Filenames , usage )
cmd . Flags ( ) . StringVar ( & o . Image , "image" , o . Image , i18n . T ( "Image to use for upgrading the replication controller. Must be distinct from the existing image (either new image or new image tag). Can not be used with --filename/-f" ) )
cmd . Flags ( ) . StringVar ( & o . DeploymentKey , "deployment-label-key" , o . DeploymentKey , i18n . T ( "The key to use to differentiate between two different controllers, default 'deployment'. Only relevant when --image is specified, ignored otherwise" ) )
cmd . Flags ( ) . StringVar ( & o . Container , "container" , o . Container , i18n . T ( "Container name which will have its image upgraded. Only relevant when --image is specified, ignored otherwise. Required when using --image on a multi-container pod" ) )
cmd . Flags ( ) . StringVar ( & o . PullPolicy , "image-pull-policy" , o . PullPolicy , i18n . T ( "Explicit policy for when to pull container images. Required when --image is same as existing image, ignored otherwise." ) )
cmd . Flags ( ) . BoolVar ( & o . Rollback , "rollback" , o . Rollback , "If true, this is a request to abort an existing rollout that is partially rolled out. It effectively reverses current and next and runs a rollout" )
2016-05-11 00:26:39 +00:00
cmdutil . AddDryRunFlag ( cmd )
2015-09-10 21:58:09 +00:00
cmdutil . AddValidateFlags ( cmd )
2016-03-10 01:27:19 +00:00
2015-03-09 22:08:16 +00:00
return cmd
}
2015-01-02 18:08:37 +00:00
2015-09-25 02:55:03 +00:00
func validateArguments ( cmd * cobra . Command , filenames , args [ ] string ) error {
deploymentKey := cmdutil . GetFlagString ( cmd , "deployment-label-key" )
image := cmdutil . GetFlagString ( cmd , "image" )
rollback := cmdutil . GetFlagBool ( cmd , "rollback" )
2015-04-23 23:27:19 +00:00
2016-08-29 07:11:01 +00:00
errors := [ ] error { }
2015-04-23 23:27:19 +00:00
if len ( deploymentKey ) == 0 {
2017-06-14 21:14:42 +00:00
errors = append ( errors , cmdutil . UsageErrorf ( cmd , "--deployment-label-key can not be empty" ) )
2015-04-23 23:27:19 +00:00
}
2015-03-29 03:39:19 +00:00
if len ( filenames ) > 1 {
2017-06-14 21:14:42 +00:00
errors = append ( errors , cmdutil . UsageErrorf ( cmd , "May only specify a single filename for new controller" ) )
2015-03-29 03:39:19 +00:00
}
2015-09-25 02:55:03 +00:00
if ! rollback {
if len ( filenames ) == 0 && len ( image ) == 0 {
2017-06-14 21:14:42 +00:00
errors = append ( errors , cmdutil . UsageErrorf ( cmd , "Must specify --filename or --image for new controller" ) )
2016-08-29 07:11:01 +00:00
} else if len ( filenames ) != 0 && len ( image ) != 0 {
2017-06-14 21:14:42 +00:00
errors = append ( errors , cmdutil . UsageErrorf ( cmd , "--filename and --image can not both be specified" ) )
2015-09-25 02:55:03 +00:00
}
} else {
if len ( filenames ) != 0 || len ( image ) != 0 {
2017-06-14 21:14:42 +00:00
errors = append ( errors , cmdutil . UsageErrorf ( cmd , "Don't specify --filename or --image on rollback" ) )
2015-09-25 02:55:03 +00:00
}
2015-04-23 23:27:19 +00:00
}
2015-09-25 02:55:03 +00:00
2015-04-23 23:27:19 +00:00
if len ( args ) < 1 {
2017-06-14 21:14:42 +00:00
errors = append ( errors , cmdutil . UsageErrorf ( cmd , "Must specify the controller to update" ) )
2015-04-23 23:27:19 +00:00
}
2016-08-29 07:11:01 +00:00
return utilerrors . NewAggregate ( errors )
2015-04-23 23:27:19 +00:00
}
2018-04-24 04:40:35 +00:00
func ( o * RollingUpdateOptions ) Complete ( f cmdutil . Factory , cmd * cobra . Command , args [ ] string ) error {
o . OldName = args [ 0 ]
o . DryRun = cmdutil . GetDryRunFlag ( cmd )
o . OutputFormat = cmdutil . GetFlagString ( cmd , "output" )
o . KeepOldName = len ( args ) == 1
o . ShouldValidate = cmdutil . GetFlagBool ( cmd , "validate" )
o . Validator = f . Validator
o . FindNewName = func ( obj * api . ReplicationController ) string {
return findNewName ( args , obj )
2015-03-09 22:08:16 +00:00
}
2015-09-25 02:55:03 +00:00
2018-04-24 04:40:35 +00:00
var err error
o . Namespace , o . EnforceNamespace , err = f . DefaultNamespace ( )
if err != nil {
return err
2015-09-25 02:55:03 +00:00
}
2018-04-24 04:40:35 +00:00
o . ScaleClient , err = f . ScaleClient ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2015-01-08 13:40:02 +00:00
2018-04-24 04:40:35 +00:00
o . ClientSet , err = f . ClientSet ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2018-04-24 04:40:35 +00:00
o . Builder = f . NewBuilder ( )
o . ToPrinter = func ( operation string ) ( printers . ResourcePrinterFunc , error ) {
o . PrintFlags . NamePrintFlags . Operation = operation
if o . DryRun {
o . PrintFlags . Complete ( "%s (dry run)" )
}
printer , err := o . PrintFlags . ToPrinter ( )
if err != nil {
return nil , err
}
return printer . PrintObj , nil
}
return nil
}
func ( o * RollingUpdateOptions ) Validate ( cmd * cobra . Command , args [ ] string ) error {
return validateArguments ( cmd , o . FilenameOptions . Filenames , args )
}
func ( o * RollingUpdateOptions ) Run ( ) error {
filename := ""
if len ( o . FilenameOptions . Filenames ) > 0 {
filename = o . FilenameOptions . Filenames [ 0 ]
}
coreClient := o . ClientSet . Core ( )
2015-04-23 23:27:19 +00:00
2015-05-01 07:31:01 +00:00
var newRc * api . ReplicationController
2015-04-23 23:27:19 +00:00
// fetch rc
2018-04-24 04:40:35 +00:00
oldRc , err := coreClient . ReplicationControllers ( o . Namespace ) . Get ( o . OldName , metav1 . GetOptions { } )
2015-04-23 23:27:19 +00:00
if err != nil {
2018-04-24 04:40:35 +00:00
if ! errors . IsNotFound ( err ) || len ( o . Image ) == 0 || ! o . KeepOldName {
2015-05-01 07:31:01 +00:00
return err
}
// We're in the middle of a rename, look for an RC with a source annotation of oldName
2018-04-24 04:40:35 +00:00
newRc , err := kubectl . FindSourceController ( coreClient , o . Namespace , o . OldName )
2015-05-01 07:31:01 +00:00
if err != nil {
return err
}
2018-04-24 04:40:35 +00:00
return kubectl . Rename ( coreClient , newRc , o . OldName )
2015-04-23 23:27:19 +00:00
}
2015-06-23 01:56:53 +00:00
var replicasDefaulted bool
2015-04-23 23:27:19 +00:00
2015-04-23 23:27:19 +00:00
if len ( filename ) != 0 {
2018-04-24 04:40:35 +00:00
schema , err := o . Validator ( o . ShouldValidate )
2015-05-07 20:53:43 +00:00
if err != nil {
return err
}
2015-06-26 20:49:34 +00:00
2018-04-24 04:40:35 +00:00
request := o . Builder .
2017-11-17 22:21:25 +00:00
Unstructured ( ) .
2015-05-07 20:53:43 +00:00
Schema ( schema ) .
2018-04-24 04:40:35 +00:00
NamespaceParam ( o . Namespace ) . DefaultNamespace ( ) .
FilenameParam ( o . EnforceNamespace , & resource . FilenameOptions { Recursive : false , Filenames : [ ] string { filename } } ) .
2017-11-17 22:21:25 +00:00
Flatten ( ) .
2015-06-23 01:56:53 +00:00
Do ( )
2017-11-17 22:21:25 +00:00
infos , err := request . Infos ( )
2015-04-23 23:27:19 +00:00
if err != nil {
return err
}
2017-11-17 22:21:25 +00:00
// Handle filename input from stdin.
if len ( infos ) > 1 {
2018-04-24 04:40:35 +00:00
return fmt . Errorf ( "%s specifies multiple items" , filename )
2015-05-22 16:44:00 +00:00
}
2017-11-17 22:21:25 +00:00
if len ( infos ) == 0 {
2018-04-24 04:40:35 +00:00
return fmt . Errorf ( "please make sure %s exists and is not empty" , filename )
2015-04-23 23:27:19 +00:00
}
2017-11-17 22:21:25 +00:00
2018-04-26 15:21:41 +00:00
uncastVersionedObj , err := legacyscheme . Scheme . ConvertToVersion ( infos [ 0 ] . Object , v1 . SchemeGroupVersion )
if err != nil {
2018-04-30 18:55:15 +00:00
glog . V ( 4 ) . Infof ( "Object %T is not a ReplicationController" , infos [ 0 ] . Object )
return fmt . Errorf ( "%s contains a %v not a ReplicationController" , filename , infos [ 0 ] . Object . GetObjectKind ( ) . GroupVersionKind ( ) )
2018-04-26 15:21:41 +00:00
}
switch t := uncastVersionedObj . ( type ) {
2017-11-17 22:21:25 +00:00
case * v1 . ReplicationController :
replicasDefaulted = t . Spec . Replicas == nil
2018-04-24 22:31:41 +00:00
// previous code ignored the error. Seem like it's very unlikely to fail, so ok for now.
2018-04-26 15:21:41 +00:00
uncastObj , err := legacyscheme . Scheme . ConvertToVersion ( uncastVersionedObj , api . SchemeGroupVersion )
2018-04-24 22:31:41 +00:00
if err == nil {
newRc , _ = uncastObj . ( * api . ReplicationController )
}
2017-11-17 22:21:25 +00:00
}
if newRc == nil {
glog . V ( 4 ) . Infof ( "Object %T is not a ReplicationController" , infos [ 0 ] . Object )
2018-04-24 04:40:35 +00:00
return fmt . Errorf ( "%s contains a %v not a ReplicationController" , filename , infos [ 0 ] . Object . GetObjectKind ( ) . GroupVersionKind ( ) )
2015-06-23 01:56:53 +00:00
}
2015-04-23 23:27:19 +00:00
}
2017-11-17 22:21:25 +00:00
2015-04-29 22:06:42 +00:00
// If the --image option is specified, we need to create a new rc with at least one different selector
2016-04-21 22:20:32 +00:00
// than the old rc. This selector is the hash of the rc, with a suffix to provide uniqueness for
// same-image updates.
2018-04-24 04:40:35 +00:00
if len ( o . Image ) != 0 {
2017-10-16 11:41:50 +00:00
codec := legacyscheme . Codecs . LegacyCodec ( v1 . SchemeGroupVersion )
2018-04-24 04:40:35 +00:00
newName := o . FindNewName ( oldRc )
if newRc , err = kubectl . LoadExistingNextReplicationController ( coreClient , o . Namespace , newName ) ; err != nil {
2015-05-01 07:31:01 +00:00
return err
2015-04-28 00:10:39 +00:00
}
2015-05-01 07:31:01 +00:00
if newRc != nil {
2018-04-24 04:40:35 +00:00
if inProgressImage := newRc . Spec . Template . Spec . Containers [ 0 ] . Image ; inProgressImage != o . Image {
return fmt . Errorf ( "Found existing in-progress update to image (%s).\nEither continue in-progress update with --image=%s or rollback with --rollback" , inProgressImage , inProgressImage )
2015-10-19 23:59:02 +00:00
}
2018-04-24 04:40:35 +00:00
fmt . Fprintf ( o . Out , "Found existing update in progress (%s), resuming.\n" , newRc . Name )
2015-05-01 07:31:01 +00:00
} else {
2016-04-21 22:20:32 +00:00
config := & kubectl . NewControllerConfig {
2018-04-24 04:40:35 +00:00
Namespace : o . Namespace ,
OldName : o . OldName ,
2016-04-21 22:20:32 +00:00
NewName : newName ,
2018-04-24 04:40:35 +00:00
Image : o . Image ,
Container : o . Container ,
DeploymentKey : o . DeploymentKey ,
2016-04-21 22:20:32 +00:00
}
2018-04-24 04:40:35 +00:00
if oldRc . Spec . Template . Spec . Containers [ 0 ] . Image == o . Image {
if len ( o . PullPolicy ) == 0 {
return fmt . Errorf ( "--image-pull-policy (Always|Never|IfNotPresent) must be provided when --image is the same as existing container image" )
2016-04-21 22:20:32 +00:00
}
2018-04-24 04:40:35 +00:00
config . PullPolicy = api . PullPolicy ( o . PullPolicy )
2015-10-19 23:59:02 +00:00
}
2016-09-08 14:24:02 +00:00
newRc , err = kubectl . CreateNewControllerFromCurrentController ( coreClient , codec , config )
2015-04-28 00:10:39 +00:00
if err != nil {
2015-04-23 23:27:19 +00:00
return err
}
2015-05-01 07:31:01 +00:00
}
// Update the existing replication controller with pointers to the 'next' controller
// and adding the <deploymentKey> label if necessary to distinguish it from the 'next' controller.
2017-05-19 21:33:08 +00:00
oldHash , err := util . HashObject ( oldRc , codec )
2015-05-01 07:31:01 +00:00
if err != nil {
return err
}
2016-04-21 22:20:32 +00:00
// If new image is same as old, the hash may not be distinct, so add a suffix.
oldHash += "-orig"
2018-04-24 04:40:35 +00:00
oldRc , err = kubectl . UpdateExistingReplicationController ( coreClient , coreClient , oldRc , o . Namespace , newRc . Name , o . DeploymentKey , oldHash , o . Out )
2015-05-01 07:31:01 +00:00
if err != nil {
return err
2015-04-23 23:27:19 +00:00
}
2015-03-09 22:08:16 +00:00
}
2015-09-25 02:55:03 +00:00
2018-04-24 04:40:35 +00:00
if o . Rollback {
newName := o . FindNewName ( oldRc )
if newRc , err = kubectl . LoadExistingNextReplicationController ( coreClient , o . Namespace , newName ) ; err != nil {
2015-09-25 02:55:03 +00:00
return err
}
if newRc == nil {
2018-04-24 04:40:35 +00:00
return fmt . Errorf ( "Could not find %s to rollback.\n" , newName )
2015-09-25 02:55:03 +00:00
}
}
2018-04-24 04:40:35 +00:00
if o . OldName == newRc . Name {
return fmt . Errorf ( "%s cannot have the same name as the existing ReplicationController %s" ,
filename , o . OldName )
2015-03-09 22:08:16 +00:00
}
2014-12-10 21:48:48 +00:00
2018-04-24 04:40:35 +00:00
updater := kubectl . NewRollingUpdater ( newRc . Namespace , coreClient , coreClient , o . ScaleClient )
2015-03-09 22:08:16 +00:00
2015-04-29 22:06:42 +00:00
// To successfully pull off a rolling update the new and old rc have to differ
// by at least one selector. Every new pod should have the selector and every
// old pod should not have the selector.
2015-03-09 22:08:16 +00:00
var hasLabel bool
for key , oldValue := range oldRc . Spec . Selector {
if newValue , ok := newRc . Spec . Selector [ key ] ; ok && newValue != oldValue {
hasLabel = true
break
}
}
if ! hasLabel {
2018-04-24 04:40:35 +00:00
return fmt . Errorf ( "%s must specify a matching key with non-equal value in Selector for %s" ,
filename , o . OldName )
2015-03-09 22:08:16 +00:00
}
2015-05-21 21:10:25 +00:00
// TODO: handle scales during rolling update
2015-06-23 01:56:53 +00:00
if replicasDefaulted {
2015-03-09 22:08:16 +00:00
newRc . Spec . Replicas = oldRc . Spec . Replicas
}
2018-04-24 04:40:35 +00:00
if o . DryRun {
2015-04-23 23:27:19 +00:00
oldRcData := & bytes . Buffer { }
newRcData := & bytes . Buffer { }
2018-04-24 04:40:35 +00:00
if o . OutputFormat == "" {
2015-09-01 13:35:27 +00:00
oldRcData . WriteString ( oldRc . Name )
newRcData . WriteString ( newRc . Name )
} else {
2018-04-24 04:40:35 +00:00
printer , err := o . ToPrinter ( "rolling updated" )
if err != nil {
2015-09-01 13:35:27 +00:00
return err
}
2018-04-24 04:40:35 +00:00
if err := printer . PrintObj ( oldRc , oldRcData ) ; err != nil {
return err
}
if err := printer . PrintObj ( newRc , newRcData ) ; err != nil {
2015-09-01 13:35:27 +00:00
return err
}
2015-04-23 23:27:19 +00:00
}
2018-04-24 04:40:35 +00:00
fmt . Fprintf ( o . Out , "Rolling from:\n%s\nTo:\n%s\n" , string ( oldRcData . Bytes ( ) ) , string ( newRcData . Bytes ( ) ) )
2015-04-23 23:27:19 +00:00
return nil
}
2015-04-23 23:27:19 +00:00
updateCleanupPolicy := kubectl . DeleteRollingUpdateCleanupPolicy
2018-04-24 04:40:35 +00:00
if o . KeepOldName {
2015-04-23 23:27:19 +00:00
updateCleanupPolicy = kubectl . RenameRollingUpdateCleanupPolicy
}
2015-04-30 17:28:36 +00:00
config := & kubectl . RollingUpdaterConfig {
2018-04-24 04:40:35 +00:00
Out : o . Out ,
2015-06-18 20:29:28 +00:00
OldRc : oldRc ,
NewRc : newRc ,
2018-04-24 04:40:35 +00:00
UpdatePeriod : o . Period ,
Interval : o . Interval ,
2015-06-18 20:29:28 +00:00
Timeout : timeout ,
CleanupPolicy : updateCleanupPolicy ,
2016-03-02 02:44:59 +00:00
MaxUnavailable : intstr . FromInt ( 0 ) ,
2015-11-10 06:28:45 +00:00
MaxSurge : intstr . FromInt ( 1 ) ,
2015-04-30 17:28:36 +00:00
}
2018-04-24 04:40:35 +00:00
if o . Rollback {
2015-09-28 18:52:01 +00:00
err = kubectl . AbortRollingUpdate ( config )
if err != nil {
return err
}
2016-09-08 14:24:02 +00:00
coreClient . ReplicationControllers ( config . NewRc . Namespace ) . Update ( config . NewRc )
2015-04-30 17:28:36 +00:00
}
err = updater . Update ( config )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2015-09-01 13:35:27 +00:00
message := "rolling updated"
2018-04-24 04:40:35 +00:00
if o . KeepOldName {
newRc . Name = o . OldName
2015-04-23 23:27:19 +00:00
} else {
2015-09-01 13:35:27 +00:00
message = fmt . Sprintf ( "rolling updated to %q" , newRc . Name )
}
2018-04-24 04:40:35 +00:00
newRc , err = coreClient . ReplicationControllers ( o . Namespace ) . Get ( newRc . Name , metav1 . GetOptions { } )
2015-09-01 13:35:27 +00:00
if err != nil {
return err
}
2018-04-24 04:40:35 +00:00
printer , err := o . ToPrinter ( message )
if err != nil {
return err
2015-09-01 13:35:27 +00:00
}
2018-04-24 04:40:35 +00:00
return printer . PrintObj ( newRc , o . Out )
2014-12-10 21:48:48 +00:00
}
2015-04-23 23:27:19 +00:00
2015-05-01 07:31:01 +00:00
func findNewName ( args [ ] string , oldRc * api . ReplicationController ) string {
if len ( args ) >= 2 {
return args [ 1 ]
2015-04-23 23:27:19 +00:00
}
2015-05-01 07:31:01 +00:00
if oldRc != nil {
newName , _ := kubectl . GetNextControllerAnnotation ( oldRc )
return newName
2015-04-23 23:27:19 +00:00
}
2015-05-01 07:31:01 +00:00
return ""
2015-04-23 23:27:19 +00:00
}