Commit 5a5a44ec authored by Adam Reese's avatar Adam Reese

feat(*): add rollback to a release version

closes #1244
parent becc1200
...@@ -183,7 +183,6 @@ message UpdateReleaseRequest { ...@@ -183,7 +183,6 @@ message UpdateReleaseRequest {
hapi.chart.Config values = 3; hapi.chart.Config values = 3;
// dry_run, if true, will run through the release logic, but neither create // dry_run, if true, will run through the release logic, but neither create
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;
} }
...@@ -200,6 +199,8 @@ message RollbackReleaseRequest { ...@@ -200,6 +199,8 @@ message RollbackReleaseRequest {
bool dry_run = 2; bool dry_run = 2;
// DisableHooks causes the server to skip running any hooks for the rollback // DisableHooks causes the server to skip running any hooks for the rollback
bool disable_hooks = 3; bool disable_hooks = 3;
// Version is the version of the release to deploy.
int32 version = 4;
} }
// RollbackReleaseResponse is the response to an update request. // RollbackReleaseResponse is the response to an update request.
......
...@@ -26,12 +26,13 @@ import ( ...@@ -26,12 +26,13 @@ import (
) )
const rollbackDesc = ` const rollbackDesc = `
This command rolls back a release to the previous version. This command rolls back a release to the previous revision.
The argument of the rollback command is the name of a release. The argument of the rollback command is the name of a release.
` `
type rollbackCmd struct { type rollbackCmd struct {
name string name string
version int32
dryRun bool dryRun bool
disableHooks bool disableHooks bool
out io.Writer out io.Writer
...@@ -46,7 +47,7 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command { ...@@ -46,7 +47,7 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "rollback [RELEASE]", Use: "rollback [RELEASE]",
Short: "roll back a release to the previous version", Short: "roll back a release to a previous revision",
Long: rollbackDesc, Long: rollbackDesc,
PersistentPreRunE: setupConnection, PersistentPreRunE: setupConnection,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
...@@ -60,13 +61,19 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command { ...@@ -60,13 +61,19 @@ func newRollbackCmd(c helm.Interface, out io.Writer) *cobra.Command {
} }
f := cmd.Flags() f := cmd.Flags()
f.Int32Var(&rollback.version, "revision", 0, "revision to deploy")
f.BoolVar(&rollback.dryRun, "dry-run", false, "simulate a rollback") f.BoolVar(&rollback.dryRun, "dry-run", false, "simulate a rollback")
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
} }
func (r *rollbackCmd) run() error { func (r *rollbackCmd) run() error {
_, err := r.client.RollbackRelease(r.name, helm.RollbackDryRun(r.dryRun), helm.RollbackDisableHooks(r.disableHooks)) _, err := r.client.RollbackRelease(
r.name,
helm.RollbackDryRun(r.dryRun),
helm.RollbackDisableHooks(r.disableHooks),
helm.RollbackVersion(r.version),
)
if err != nil { if err != nil {
return prettyError(err) return prettyError(err)
} }
......
...@@ -29,7 +29,12 @@ func TestRollbackCmd(t *testing.T) { ...@@ -29,7 +29,12 @@ func TestRollbackCmd(t *testing.T) {
{ {
name: "rollback a release", name: "rollback a release",
args: []string{"funny-honey"}, args: []string{"funny-honey"},
resp: nil, flags: []string{"revision", "1"},
expected: "Rollback was a success! Happy Helming!",
},
{
name: "rollback a release without version",
args: []string{"funny-honey"},
expected: "Rollback was a success! Happy Helming!", expected: "Rollback was a success! Happy Helming!",
}, },
} }
......
...@@ -461,7 +461,17 @@ func (s *releaseServer) prepareRollback(req *services.RollbackReleaseRequest) (* ...@@ -461,7 +461,17 @@ func (s *releaseServer) prepareRollback(req *services.RollbackReleaseRequest) (*
return nil, nil, err return nil, nil, err
} }
previousRelease, err := s.env.Releases.Get(req.Name, currentRelease.Version-1) v := req.Version
if v == 0 {
v = currentRelease.Version - 1
}
if v < 1 {
return nil, nil, errors.New("cannot rollback to version < 1")
}
log.Printf("rolling back %s to version %d", req.Name, v)
previousRelease, err := s.env.Releases.Get(req.Name, v)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
......
...@@ -664,6 +664,27 @@ func TestRollbackReleaseNoHooks(t *testing.T) { ...@@ -664,6 +664,27 @@ func TestRollbackReleaseNoHooks(t *testing.T) {
} }
} }
func TestRollbackWithReleaseVersion(t *testing.T) {
c := helm.NewContext()
rs := rsFixture()
rel := releaseStub()
rs.env.Releases.Create(rel)
upgradedRel := upgradeReleaseVersion(rel)
rs.env.Releases.Update(rel)
rs.env.Releases.Create(upgradedRel)
req := &services.RollbackReleaseRequest{
Name: rel.Name,
DisableHooks: true,
Version: 1,
}
_, err := rs.RollbackRelease(c, req)
if err != nil {
t.Fatalf("Failed rollback: %s", err)
}
}
func TestRollbackRelease(t *testing.T) { func TestRollbackRelease(t *testing.T) {
c := helm.NewContext() c := helm.NewContext()
rs := rsFixture() rs := rsFixture()
......
...@@ -196,6 +196,13 @@ func RollbackDryRun(dry bool) RollbackOption { ...@@ -196,6 +196,13 @@ func RollbackDryRun(dry bool) RollbackOption {
} }
} }
// RollbackVersion sets the version of the release to deploy.
func RollbackVersion(ver int32) RollbackOption {
return func(opts *options) {
opts.rollbackReq.Version = ver
}
}
// UpgradeDisableHooks will disable hooks for an upgrade operation. // UpgradeDisableHooks will disable hooks for an upgrade operation.
func UpgradeDisableHooks(disable bool) UpdateOption { func UpgradeDisableHooks(disable bool) UpdateOption {
return func(opts *options) { return func(opts *options) {
...@@ -333,7 +340,7 @@ func (o *options) rpcRollbackRelease(rlsName string, rlc rls.ReleaseServiceClien ...@@ -333,7 +340,7 @@ func (o *options) rpcRollbackRelease(rlsName string, rlc rls.ReleaseServiceClien
o.rollbackReq.DryRun = o.dryRun o.rollbackReq.DryRun = o.dryRun
o.rollbackReq.Name = rlsName o.rollbackReq.Name = rlsName
return rlc.RollbackRelease(context.TODO(), &o.rollbackReq) return rlc.RollbackRelease(NewContext(), &o.rollbackReq)
} }
// Executes tiller.GetReleaseStatus RPC. // Executes tiller.GetReleaseStatus RPC.
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment