Unverified Commit 0c99ca7b authored by Cristian Klein's avatar Cristian Klein Committed by Matt Farina
Browse files

fix(tiller): improve handling of corrupted storage


For some reason, many users experince corrupted storage with the
ConfigMaps storage backend. Specifically, several Releases are marked as
DEPLOYED. This patch improved handling of such situations, by taking the latest
DEPLOYED Release. Eventually, the storage will clean itself out, after
the corrupted Releases are deleted due to --history-max.

Closes #6031

Signed-off-by: default avatarCristian Klein <cristian.klein@elastisys.com>
(cherry picked from commit 840e0e27)
No related merge requests found
Showing with 43 additions and 0 deletions
+43 -0
...@@ -136,6 +136,9 @@ func (s *Storage) Deployed(name string) (*rspb.Release, error) { ...@@ -136,6 +136,9 @@ func (s *Storage) Deployed(name string) (*rspb.Release, error) {
return nil, fmt.Errorf("%q %s", name, NoReleasesErr) return nil, fmt.Errorf("%q %s", name, NoReleasesErr)
} }
// Sometimes Tiller's database gets corrupted and multiple releases are DEPLOYED. Take the latest.
relutil.Reverse(ls, relutil.SortByRevision)
return ls[0], err return ls[0], err
} }
......
...@@ -205,6 +205,46 @@ func TestStorageDeployed(t *testing.T) { ...@@ -205,6 +205,46 @@ func TestStorageDeployed(t *testing.T) {
} }
} }
func TestStorageDeployedWithCorruption(t *testing.T) {
storage := Init(driver.NewMemory())
const name = "angry-bird"
const vers = int32(4)
// setup storage with test releases
setup := func() {
// release records (notice odd order and corruption)
rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.Status_SUPERSEDED}.ToRelease()
rls1 := ReleaseTestData{Name: name, Version: 4, Status: rspb.Status_DEPLOYED}.ToRelease()
rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.Status_SUPERSEDED}.ToRelease()
rls3 := ReleaseTestData{Name: name, Version: 2, Status: rspb.Status_DEPLOYED}.ToRelease()
// create the release records in the storage
assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)")
assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)")
assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)")
assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)")
}
setup()
rls, err := storage.Deployed(name)
if err != nil {
t.Fatalf("Failed to query for deployed release: %s\n", err)
}
switch {
case rls == nil:
t.Fatalf("Release is nil")
case rls.Name != name:
t.Fatalf("Expected release name %q, actual %q\n", name, rls.Name)
case rls.Version != vers:
t.Fatalf("Expected release version %d, actual %d\n", vers, rls.Version)
case rls.Info.Status.Code != rspb.Status_DEPLOYED:
t.Fatalf("Expected release status 'DEPLOYED', actual %s\n", rls.Info.Status.Code)
}
}
func TestStorageHistory(t *testing.T) { func TestStorageHistory(t *testing.T) {
storage := Init(driver.NewMemory()) storage := Init(driver.NewMemory())
......
Supports Markdown
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