Alerting: Fix migration that is brittle to version downgrades (#78976)

This commit is contained in:
Matthew Jacobson 2023-12-01 15:18:41 -05:00 committed by GitHub
parent b42d652106
commit 6644e5e676
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,6 +2,7 @@ package ualert
import ( import (
"fmt" "fmt"
"time"
"xorm.io/xorm" "xorm.io/xorm"
@ -30,6 +31,11 @@ const (
// detect transitions between Legacy and UnifiedAlerting by comparing to the desired type in the configuration. // detect transitions between Legacy and UnifiedAlerting by comparing to the desired type in the configuration.
func CreateOrgMigratedKVStoreEntries(mg *migrator.Migrator) { func CreateOrgMigratedKVStoreEntries(mg *migrator.Migrator) {
mg.AddMigration("copy kvstore migration status to each org", &createOrgMigratedKVStoreEntries{}) mg.AddMigration("copy kvstore migration status to each org", &createOrgMigratedKVStoreEntries{})
// Adds back the entry for orgId=0 if it doesn't exist. This is not strictly necessary, but
// helps to cover some issues with createOrgMigratedKVStoreEntries if a grafana instance on UA is downgraded to before
// the split for org-specific migrated statuses.
mg.AddMigration("add back entry for orgid=0 migrated status", &addBackAnyOrgMigratedEntry{})
} }
type createOrgMigratedKVStoreEntries struct { type createOrgMigratedKVStoreEntries struct {
@ -100,3 +106,56 @@ func (c createOrgMigratedKVStoreEntries) Exec(sess *xorm.Session, mg *migrator.M
return nil return nil
} }
type addBackAnyOrgMigratedEntry struct {
migrator.MigrationBase
}
func (c addBackAnyOrgMigratedEntry) SQL(migrator.Dialect) string {
return codeMigration
}
func (c addBackAnyOrgMigratedEntry) Exec(sess *xorm.Session, mg *migrator.Migrator) error {
var anyOrg int64 = 0
migratedEntries := make([]kvStoreV1Entry, 0)
cond := kvStoreV1Entry{
Namespace: &KVNamespace,
Key: &migratedKey,
}
err := sess.Table("kv_store").Find(&migratedEntries, &cond)
if err != nil {
return err
}
if len(migratedEntries) == 0 {
mg.Logger.Debug("No migrated orgs in kvstore, nothing to set")
return nil
}
migratedStatus := "false"
for _, migrated := range migratedEntries {
if migrated.OrgID != nil && *migrated.OrgID == anyOrg {
mg.Logger.Debug("Already have migrated status for orgid=0, nothing to set")
return nil
}
// All org entries should have the same value. If, somehow, they don't, we set it to true if any orgs are migrated.
// This is because assuming an org is migrated when it isn't is less bad as force_migration check exists.
if migrated.Value == "true" {
migratedStatus = "true"
}
}
now := time.Now()
if _, err := sess.Table("kv_store").Insert(&kvStoreV1Entry{
OrgID: &anyOrg,
Namespace: &KVNamespace,
Key: &migratedKey,
Value: migratedStatus,
Created: now,
Updated: now,
}); err != nil {
mg.Logger.Error("failed to insert orgid=0 migrated status in kvstore", "err", err)
return err
}
return nil
}