Introducing flag for restarting pods during release upgrade/rollback

* Added pod restart for ReplicaSet
 * Added --restart flag for helm CLI for upgrade/rollback commands
 * By default, restart is false
reviewable/pr1648/r2
Nikolay Mahotkin 8 years ago
parent b5f7d90baf
commit 045b158c3d

@ -188,6 +188,8 @@ message UpdateReleaseRequest {
bool dry_run = 4; bool dry_run = 4;
// DisableHooks causes the server to skip running any hooks for the upgrade. // DisableHooks causes the server to skip running any hooks for the upgrade.
bool disable_hooks = 5; bool disable_hooks = 5;
// Performs pods restart for resources if applicable
bool restart = 6;
} }
// UpdateReleaseResponse is the response to an update request. // UpdateReleaseResponse is the response to an update request.
@ -204,6 +206,8 @@ message RollbackReleaseRequest {
bool disable_hooks = 3; bool disable_hooks = 3;
// Version is the version of the release to deploy. // Version is the version of the release to deploy.
int32 version = 4; int32 version = 4;
// Performs pods restart for resources if applicable
bool restart = 5;
} }
// RollbackReleaseResponse is the response to an update request. // RollbackReleaseResponse is the response to an update request.

@ -35,6 +35,7 @@ type rollbackCmd struct {
name string name string
revision int32 revision int32
dryRun bool dryRun bool
restart bool
disableHooks bool disableHooks bool
out io.Writer out io.Writer
client helm.Interface client helm.Interface
@ -71,6 +72,7 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
f := cmd.Flags() f := cmd.Flags()
f.BoolVar(&rollback.dryRun, "dry-run", false, "simulate a rollback") f.BoolVar(&rollback.dryRun, "dry-run", false, "simulate a rollback")
f.BoolVar(&rollback.restart, "restart", false, "performs pods restart for the resource if applicable")
f.BoolVar(&rollback.disableHooks, "no-hooks", false, "prevent hooks from running during rollback") f.BoolVar(&rollback.disableHooks, "no-hooks", false, "prevent hooks from running during rollback")
return cmd return cmd
@ -80,6 +82,7 @@ func (r *rollbackCmd) run() error {
_, err := r.client.RollbackRelease( _, err := r.client.RollbackRelease(
r.name, r.name,
helm.RollbackDryRun(r.dryRun), helm.RollbackDryRun(r.dryRun),
helm.RollbackRestart(r.restart),
helm.RollbackDisableHooks(r.disableHooks), helm.RollbackDisableHooks(r.disableHooks),
helm.RollbackVersion(r.revision), helm.RollbackVersion(r.revision),
) )

@ -48,6 +48,7 @@ type upgradeCmd struct {
out io.Writer out io.Writer
client helm.Interface client helm.Interface
dryRun bool dryRun bool
restart bool
disableHooks bool disableHooks bool
valuesFile string valuesFile string
values string values string
@ -86,6 +87,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
f := cmd.Flags() f := cmd.Flags()
f.StringVarP(&upgrade.valuesFile, "values", "f", "", "path to a values YAML file") f.StringVarP(&upgrade.valuesFile, "values", "f", "", "path to a values YAML file")
f.BoolVar(&upgrade.dryRun, "dry-run", false, "simulate an upgrade") f.BoolVar(&upgrade.dryRun, "dry-run", false, "simulate an upgrade")
f.BoolVar(&upgrade.restart, "restart", false, "performs pods restart for the resource if applicable")
f.StringVar(&upgrade.values, "set", "", "set values on the command line. Separate values with commas: key1=val1,key2=val2") f.StringVar(&upgrade.values, "set", "", "set values on the command line. Separate values with commas: key1=val1,key2=val2")
f.BoolVar(&upgrade.disableHooks, "disable-hooks", false, "disable pre/post upgrade hooks. DEPRECATED. Use no-hooks") f.BoolVar(&upgrade.disableHooks, "disable-hooks", false, "disable pre/post upgrade hooks. DEPRECATED. Use no-hooks")
f.BoolVar(&upgrade.disableHooks, "no-hooks", false, "disable pre/post upgrade hooks") f.BoolVar(&upgrade.disableHooks, "no-hooks", false, "disable pre/post upgrade hooks")
@ -143,6 +145,7 @@ func (u *upgradeCmd) run() error {
chartPath, chartPath,
helm.UpdateValueOverrides(rawVals), helm.UpdateValueOverrides(rawVals),
helm.UpgradeDryRun(u.dryRun), helm.UpgradeDryRun(u.dryRun),
helm.UpgradeRestart(u.restart),
helm.UpgradeDisableHooks(u.disableHooks)) helm.UpgradeDisableHooks(u.disableHooks))
if err != nil { if err != nil {
return fmt.Errorf("UPGRADE FAILED: %v", prettyError(err)) return fmt.Errorf("UPGRADE FAILED: %v", prettyError(err))

@ -133,6 +133,7 @@ func (h *Client) UpdateRelease(rlsName string, chstr string, opts ...UpdateOptio
req.DryRun = h.opts.dryRun req.DryRun = h.opts.dryRun
req.Name = rlsName req.Name = rlsName
req.DisableHooks = h.opts.disableHooks req.DisableHooks = h.opts.disableHooks
req.Restart = h.opts.restart
ctx := NewContext() ctx := NewContext()
if h.opts.before != nil { if h.opts.before != nil {

@ -40,6 +40,8 @@ type options struct {
dryRun bool dryRun bool
// if set, re-use an existing name // if set, re-use an existing name
reuseName bool reuseName bool
//
restart bool
// if set, skip running hooks // if set, skip running hooks
disableHooks bool disableHooks bool
// name of release // name of release
@ -212,6 +214,13 @@ func RollbackDryRun(dry bool) RollbackOption {
} }
} }
// RollbackDryRun will (if true) execute a rollback as a dry run.
func RollbackRestart(restart bool) RollbackOption {
return func(opts *options) {
opts.restart = restart
}
}
// RollbackVersion sets the version of the release to deploy. // RollbackVersion sets the version of the release to deploy.
func RollbackVersion(ver int32) RollbackOption { func RollbackVersion(ver int32) RollbackOption {
return func(opts *options) { return func(opts *options) {
@ -233,6 +242,13 @@ func UpgradeDryRun(dry bool) UpdateOption {
} }
} }
// UpgradeDryRun will (if true) execute an upgrade as a dry run.
func UpgradeRestart(restart bool) UpdateOption {
return func(opts *options) {
opts.restart = restart
}
}
// ContentOption allows setting optional attributes when // ContentOption allows setting optional attributes when
// performing a GetReleaseContent tiller rpc. // performing a GetReleaseContent tiller rpc.
type ContentOption func(*options) type ContentOption func(*options)

@ -180,7 +180,7 @@ func (c *Client) Get(namespace string, reader io.Reader) (string, error) {
// not present in the target configuration // not present in the target configuration
// //
// Namespace will set the namespaces // Namespace will set the namespaces
func (c *Client) Update(namespace string, currentReader, targetReader io.Reader) error { func (c *Client) Update(namespace string, currentReader, targetReader io.Reader, restart bool) error {
currentInfos, err := c.newBuilder(namespace, currentReader).Do().Infos() currentInfos, err := c.newBuilder(namespace, currentReader).Do().Infos()
if err != nil { if err != nil {
return fmt.Errorf("failed decoding reader into objects: %s", err) return fmt.Errorf("failed decoding reader into objects: %s", err)
@ -221,7 +221,7 @@ func (c *Client) Update(namespace string, currentReader, targetReader io.Reader)
return err return err
} }
if err := updateResource(c, info, currentObj); err != nil { if err := updateResource(c, info, currentObj, restart); err != nil {
if alreadyExistErr, ok := err.(ErrAlreadyExists); ok { if alreadyExistErr, ok := err.(ErrAlreadyExists); ok {
log.Printf(alreadyExistErr.errorMsg) log.Printf(alreadyExistErr.errorMsg)
} else { } else {
@ -317,7 +317,7 @@ func deleteResource(info *resource.Info) error {
return resource.NewHelper(info.Client, info.Mapping).Delete(info.Namespace, info.Name) return resource.NewHelper(info.Client, info.Mapping).Delete(info.Namespace, info.Name)
} }
func updateResource(c *Client, target *resource.Info, currentObj runtime.Object) error { func updateResource(c *Client, target *resource.Info, currentObj runtime.Object, restart bool) error {
encoder := api.Codecs.LegacyCodec(registered.EnabledVersions()...) encoder := api.Codecs.LegacyCodec(registered.EnabledVersions()...)
originalSerialization, err := runtime.Encode(encoder, currentObj) originalSerialization, err := runtime.Encode(encoder, currentObj)
@ -357,10 +357,11 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object)
return err return err
} }
kind := target.Mapping.GroupVersionKind.Kind if restart {
kind := target.Mapping.GroupVersionKind.Kind
client, _ := c.Client() client, _ := c.Client()
switch kind { switch kind {
case "ReplicationController": case "ReplicationController":
rc := currentObj.(*v1.ReplicationController) rc := currentObj.(*v1.ReplicationController)
err = restartPods(client, target.Namespace, rc.Spec.Selector) err = restartPods(client, target.Namespace, rc.Spec.Selector)
@ -370,7 +371,11 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object)
case "PetSet": case "PetSet":
petSet := currentObj.(*v1alpha1.PetSet) petSet := currentObj.(*v1alpha1.PetSet)
err = restartPods(client, target.Namespace, petSet.Spec.Selector.MatchLabels) err = restartPods(client, target.Namespace, petSet.Spec.Selector.MatchLabels)
} case "ReplicaSet":
replicaSet := currentObj.(*v1beta1.ReplicaSet)
err = restartPods(client, target.Namespace, replicaSet.Spec.Selector.MatchLabels)
}
}
return err return err
} }

@ -246,6 +246,8 @@ type UpdateReleaseRequest struct {
DryRun bool `protobuf:"varint,4,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"` DryRun bool `protobuf:"varint,4,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"`
// DisableHooks causes the server to skip running any hooks for the upgrade. // DisableHooks causes the server to skip running any hooks for the upgrade.
DisableHooks bool `protobuf:"varint,5,opt,name=disable_hooks,json=disableHooks" json:"disable_hooks,omitempty"` DisableHooks bool `protobuf:"varint,5,opt,name=disable_hooks,json=disableHooks" json:"disable_hooks,omitempty"`
// Performs pods restart for resources if applicable
Restart bool `protobuf:"varint,6,opt,name=restart,json=restart" json:"restart,omitempty"`
} }
func (m *UpdateReleaseRequest) Reset() { *m = UpdateReleaseRequest{} } func (m *UpdateReleaseRequest) Reset() { *m = UpdateReleaseRequest{} }
@ -293,6 +295,8 @@ type RollbackReleaseRequest struct {
DisableHooks bool `protobuf:"varint,3,opt,name=disable_hooks,json=disableHooks" json:"disable_hooks,omitempty"` DisableHooks bool `protobuf:"varint,3,opt,name=disable_hooks,json=disableHooks" json:"disable_hooks,omitempty"`
// Version is the version of the release to deploy. // Version is the version of the release to deploy.
Version int32 `protobuf:"varint,4,opt,name=version" json:"version,omitempty"` Version int32 `protobuf:"varint,4,opt,name=version" json:"version,omitempty"`
// Performs pods restart for resources if applicable
Restart bool `protobuf:"varint,5,opt,name=restart,json=restart" json:"restart,omitempty"`
} }
func (m *RollbackReleaseRequest) Reset() { *m = RollbackReleaseRequest{} } func (m *RollbackReleaseRequest) Reset() { *m = RollbackReleaseRequest{} }

@ -133,7 +133,7 @@ type KubeClient interface {
// //
// reader must contain a YAML stream (one or more YAML documents separated // reader must contain a YAML stream (one or more YAML documents separated
// by "\n---\n"). // by "\n---\n").
Update(namespace string, originalReader, modifiedReader io.Reader) error Update(namespace string, originalReader, modifiedReader io.Reader, restart bool) error
// APIClient gets a raw API client for Kubernetes. // APIClient gets a raw API client for Kubernetes.
APIClient() (unversioned.Interface, error) APIClient() (unversioned.Interface, error)

@ -331,7 +331,7 @@ func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.R
} }
} }
if err := s.performKubeUpdate(originalRelease, updatedRelease); err != nil { if err := s.performKubeUpdate(originalRelease, updatedRelease, req.Restart); err != nil {
log.Printf("warning: Release Upgrade %q failed: %s", updatedRelease.Name, err) log.Printf("warning: Release Upgrade %q failed: %s", updatedRelease.Name, err)
originalRelease.Info.Status.Code = release.Status_SUPERSEDED originalRelease.Info.Status.Code = release.Status_SUPERSEDED
updatedRelease.Info.Status.Code = release.Status_FAILED updatedRelease.Info.Status.Code = release.Status_FAILED
@ -463,7 +463,7 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R
} }
} }
if err := s.performKubeUpdate(currentRelease, targetRelease); err != nil { if err := s.performKubeUpdate(currentRelease, targetRelease, req.Restart); err != nil {
log.Printf("warning: Release Rollback %q failed: %s", targetRelease.Name, err) log.Printf("warning: Release Rollback %q failed: %s", targetRelease.Name, err)
currentRelease.Info.Status.Code = release.Status_SUPERSEDED currentRelease.Info.Status.Code = release.Status_SUPERSEDED
targetRelease.Info.Status.Code = release.Status_FAILED targetRelease.Info.Status.Code = release.Status_FAILED
@ -487,11 +487,11 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R
return res, nil return res, nil
} }
func (s *ReleaseServer) performKubeUpdate(currentRelease, targetRelease *release.Release) error { func (s *ReleaseServer) performKubeUpdate(currentRelease, targetRelease *release.Release, restart bool) error {
kubeCli := s.env.KubeClient kubeCli := s.env.KubeClient
current := bytes.NewBufferString(currentRelease.Manifest) current := bytes.NewBufferString(currentRelease.Manifest)
target := bytes.NewBufferString(targetRelease.Manifest) target := bytes.NewBufferString(targetRelease.Manifest)
return kubeCli.Update(targetRelease.Namespace, current, target) return kubeCli.Update(targetRelease.Namespace, current, target, restart)
} }
// prepareRollback finds the previous release and prepares a new release object with // prepareRollback finds the previous release and prepares a new release object with
@ -820,7 +820,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
// so as to append to the old release's history // so as to append to the old release's history
r.Version = old.Version + 1 r.Version = old.Version + 1
if err := s.performKubeUpdate(old, r); err != nil { if err := s.performKubeUpdate(old, r, false); err != nil {
log.Printf("warning: Release replace %q failed: %s", r.Name, err) log.Printf("warning: Release replace %q failed: %s", r.Name, err)
old.Info.Status.Code = release.Status_SUPERSEDED old.Info.Status.Code = release.Status_SUPERSEDED
r.Info.Status.Code = release.Status_FAILED r.Info.Status.Code = release.Status_FAILED

Loading…
Cancel
Save