2014-12-10 21:48:48 +00:00
/ *
Copyright 2014 Google Inc . All rights reserved .
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 (
"fmt"
"io"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
2015-02-05 00:14:48 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
2014-12-10 21:48:48 +00:00
"github.com/spf13/cobra"
)
const (
2015-02-20 21:28:43 +00:00
updatePeriod = "1m0s"
timeout = "5m0s"
pollInterval = "3s"
rollingupdate_long = ` Perform a rolling update of the given ReplicationController .
2014-12-10 21:48:48 +00:00
2015-02-03 17:59:21 +00:00
Replaces the specified controller with new controller , updating one pod at a time to use the
2014-12-10 21:48:48 +00:00
new PodTemplate . The new - controller . json must specify the same namespace as the
2015-02-20 21:28:43 +00:00
existing controller and overwrite at least one ( common ) label in its replicaSelector . `
rollingupdate_example = ` // Update pods of frontend-v1 using new controller data in frontend-v2.json.
$ kubectl rollingupdate frontend - v1 - f frontend - v2 . json
2014-12-10 21:48:48 +00:00
2015-02-20 21:28:43 +00:00
// Update pods of frontend-v1 using JSON data passed into stdin.
$ cat frontend - v2 . json | kubectl rollingupdate frontend - v1 - f - `
)
2015-02-03 17:59:21 +00:00
2015-02-20 21:28:43 +00:00
func ( f * Factory ) NewCmdRollingUpdate ( out io . Writer ) * cobra . Command {
cmd := & cobra . Command {
Use : "rollingupdate <old-controller-name> -f <new-controller.json>" ,
Short : "Perform a rolling update of the given ReplicationController." ,
Long : rollingupdate_long ,
Example : rollingupdate_example ,
2014-12-10 21:48:48 +00:00
Run : func ( cmd * cobra . Command , args [ ] string ) {
2015-02-05 00:14:48 +00:00
filename := util . GetFlagString ( cmd , "filename" )
2014-12-10 21:48:48 +00:00
if len ( filename ) == 0 {
usageError ( cmd , "Must specify filename for new controller" )
}
2015-02-05 00:14:48 +00:00
period := util . GetFlagDuration ( cmd , "update-period" )
interval := util . GetFlagDuration ( cmd , "poll-interval" )
timeout := util . GetFlagDuration ( cmd , "timeout" )
2014-12-10 21:48:48 +00:00
if len ( args ) != 1 {
usageError ( cmd , "Must specify the controller to update" )
}
oldName := args [ 0 ]
schema , err := f . Validator ( cmd )
2015-03-04 00:24:29 +00:00
util . CheckErr ( err )
2015-01-02 18:08:37 +00:00
clientConfig , err := f . ClientConfig ( cmd )
2015-03-04 00:24:29 +00:00
util . CheckErr ( err )
2015-01-02 18:08:37 +00:00
cmdApiVersion := clientConfig . Version
2014-12-31 23:35:52 +00:00
mapper , typer := f . Object ( cmd )
2015-02-21 23:22:07 +00:00
// TODO: use resource.Builder instead
2015-02-05 00:14:48 +00:00
mapping , namespace , newName , data := util . ResourceFromFile ( filename , typer , mapper , schema , cmdApiVersion )
2014-12-10 21:48:48 +00:00
if mapping . Kind != "ReplicationController" {
usageError ( cmd , "%s does not specify a valid ReplicationController" , filename )
}
2015-01-15 22:33:45 +00:00
if oldName == newName {
usageError ( cmd , "%s cannot have the same name as the existing ReplicationController %s" ,
filename , oldName )
}
2015-01-02 18:08:37 +00:00
cmdNamespace , err := f . DefaultNamespace ( cmd )
2015-03-04 00:24:29 +00:00
util . CheckErr ( err )
2015-02-21 23:22:07 +00:00
// TODO: use resource.Builder instead
2015-02-05 00:14:48 +00:00
err = util . CompareNamespace ( cmdNamespace , namespace )
2015-03-04 00:24:29 +00:00
util . CheckErr ( err )
2014-12-10 21:48:48 +00:00
2014-12-28 05:27:52 +00:00
client , err := f . Client ( cmd )
2015-03-04 00:24:29 +00:00
util . CheckErr ( err )
2015-01-08 13:40:02 +00:00
2014-12-10 21:48:48 +00:00
obj , err := mapping . Codec . Decode ( data )
2015-03-04 00:24:29 +00:00
util . CheckErr ( err )
2014-12-10 21:48:48 +00:00
newRc := obj . ( * api . ReplicationController )
2015-02-21 08:00:00 +00:00
updater := kubectl . NewRollingUpdater ( cmdNamespace , client )
2014-12-10 21:48:48 +00:00
// fetch rc
2015-02-21 08:00:00 +00:00
oldRc , err := client . ReplicationControllers ( cmdNamespace ) . Get ( oldName )
2015-03-04 00:24:29 +00:00
util . CheckErr ( err )
2014-12-10 21:48:48 +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 {
usageError ( cmd , "%s must specify a matching key with non-equal value in Selector for %s" ,
filename , oldName )
}
// TODO: handle resizes during rolling update
if newRc . Spec . Replicas == 0 {
newRc . Spec . Replicas = oldRc . Spec . Replicas
}
err = updater . Update ( out , oldRc , newRc , period , interval , timeout )
2015-03-04 00:24:29 +00:00
util . CheckErr ( err )
2014-12-10 21:48:48 +00:00
fmt . Fprintf ( out , "%s\n" , newName )
} ,
}
cmd . Flags ( ) . String ( "update-period" , updatePeriod , ` Time to wait between updating pods. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". ` )
cmd . Flags ( ) . String ( "poll-interval" , pollInterval , ` Time delay between polling controller status after update. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". ` )
cmd . Flags ( ) . String ( "timeout" , timeout , ` Max time to wait for a controller to update before giving up. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". ` )
2015-02-03 17:59:21 +00:00
cmd . Flags ( ) . StringP ( "filename" , "f" , "" , "Filename or URL to file to use to create the new controller." )
2014-12-10 21:48:48 +00:00
return cmd
}