diff --git a/cmd/supervisor/main.go b/cmd/supervisor/main.go index 258f8b2..3daf981 100644 --- a/cmd/supervisor/main.go +++ b/cmd/supervisor/main.go @@ -45,7 +45,7 @@ func main() { fatal(err) } - s := &server{lifeboat: lifeboat, stableUpstream: stable, candidate: candidate, client: &http.Client{Timeout: 5 * time.Second}} + s := &server{lifeboat: lifeboat, stableUpstream: stable, candidate: candidate, client: &http.Client{Timeout: 30 * time.Second}} public := http.NewServeMux() public.HandleFunc("GET /healthz", s.health) public.HandleFunc("GET /readyz", s.ready) diff --git a/runtime/supervisor/supervisor.go b/runtime/supervisor/supervisor.go index bf44ca0..2b915fa 100644 --- a/runtime/supervisor/supervisor.go +++ b/runtime/supervisor/supervisor.go @@ -193,6 +193,11 @@ func (l *Lifeboat) PromoteSet() bool { if l.CandidateReleaseSet == nil || l.Current.State != ReleaseHealthy { return false } + if l.StableReleaseSet != nil { + previous := *l.StableReleaseSet + l.RollbackTargetReleaseSet = &previous + l.RollbackTarget = l.LastKnownGood + } set := *l.CandidateReleaseSet l.StableReleaseSet = &set l.LastKnownGoodReleaseSet = &set @@ -202,7 +207,6 @@ func (l *Lifeboat) PromoteSet() bool { l.Current.Set = &set l.Current.LastKnownGood = true l.CandidateReleaseSet = nil - l.RollbackTargetReleaseSet = nil return l.setSetUpstreams(&set, nil) } diff --git a/runtime/supervisor/supervisor_test.go b/runtime/supervisor/supervisor_test.go index f6ca351..eb2b77e 100644 --- a/runtime/supervisor/supervisor_test.go +++ b/runtime/supervisor/supervisor_test.go @@ -139,3 +139,22 @@ func TestPersistentReleaseSetRollbackPreservesWholeLastKnownGood(t *testing.T) { t.Fatalf("state=%+v", state) } } + +func TestReleaseSetPromotionRetainsPreviousStableForRollback(t *testing.T) { + good := testReleaseSet("stable-r1", "r1", "http://web", "http://core", "http://cognitive", "http://research") + candidate := testReleaseSet("candidate-r2", "r2", "http://web-c", "http://core-c", "http://cognitive-c", "http://research-c") + l := supervisor.Lifeboat{} + if !l.EstablishBaselineSet(good) || !l.StartSet(candidate) { + t.Fatal("release set setup failed") + } + observation := supervisor.ReleaseSetObservation{ReleaseID: candidate.ID, Ready: true, Components: map[string]supervisor.ComponentObservation{}} + for name := range candidate.Components { + observation.Components[name] = supervisor.ComponentObservation{Revision: candidate.Revision, Health: true, Ready: true} + } + if !l.RecordSet(observation) || !l.PromoteSet() { + t.Fatal("promotion failed") + } + if l.RollbackTargetReleaseSet == nil || l.RollbackTargetReleaseSet.Revision != "r1" { + t.Fatalf("rollback target=%+v", l.RollbackTargetReleaseSet) + } +}