diff --git a/pkg/registry/apis/provisioning/register.go b/pkg/registry/apis/provisioning/register.go index 17be0330198..2ca48276be1 100644 --- a/pkg/registry/apis/provisioning/register.go +++ b/pkg/registry/apis/provisioning/register.go @@ -25,7 +25,10 @@ import ( "k8s.io/kube-openapi/pkg/spec3" "k8s.io/kube-openapi/pkg/validation/spec" + "github.com/grafana/grafana-app-sdk/logging" "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/grafana/grafana/pkg/apis/dashboard" + folders "github.com/grafana/grafana/pkg/apis/folder/v0alpha1" provisioning "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1" grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic" clientset "github.com/grafana/grafana/pkg/generated/clientset/versioned" @@ -463,6 +466,12 @@ func (b *APIBuilder) GetPostStartHooks() (map[string]genericapiserver.PostStartH return err } + // When starting with an empty instance -- swith to "mode 4+" + err = b.tryRunningOnlyUnifiedStorage() + if err != nil { + return err + } + // Informer with resync interval used for health check and reconciliation sharedInformerFactory := informers.NewSharedInformerFactory(c, 10*time.Second) repoInformer := sharedInformerFactory.Provisioning().V0alpha1().Repositories() @@ -814,3 +823,56 @@ func (b *APIBuilder) encryptSecrets(ctx context.Context, repo *provisioning.Repo } return nil } + +// FIXME: This logic does not belong in provisioning! (but required for now) +// When starting an empty instance, we shift so that we never reference legacy storage +// This should run somewhere else at startup by default (dual writer? dashboards?) +func (b *APIBuilder) tryRunningOnlyUnifiedStorage() error { + ctx := context.Background() + if !dualwrite.IsReadingLegacyDashboardsAndFolders(ctx, b.storageStatus) { + return nil + } + + // Count how many things exist + rsp, err := b.legacyMigrator.Migrate(ctx, legacy.MigrateOptions{ + Namespace: "default", // FIXME! this works for single org, but need to check multi-org + Resources: []schema.GroupResource{{ + Group: dashboard.GROUP, Resource: dashboard.DASHBOARD_RESOURCE, + }, { + Group: folders.GROUP, Resource: folders.RESOURCE, + }}, + OnlyCount: true, + }) + if err != nil { + return fmt.Errorf("error getting legacy count %w", err) + } + for _, stats := range rsp.Summary { + if stats.Count > 0 { + return nil // something exists we can not just switch + } + } + + logger := logging.DefaultLogger.With("logger", "provisioning startup") + mode5 := func(gr schema.GroupResource) error { + status, _ := b.storageStatus.Status(ctx, gr) + if !status.ReadUnified { + status.ReadUnified = true + status.WriteLegacy = false + status.WriteUnified = true + status.Runtime = false + status.Migrated = time.Now().UnixMilli() + _, err = b.storageStatus.Update(ctx, status) + logger.Info("set unified storage access", "group", gr.Group, "resource", gr.Resource) + return err + } + return nil // already reading unified + } + + if err = mode5(dashboard.DashboardResourceInfo.GroupResource()); err != nil { + return err + } + if err = mode5(folders.FolderResourceInfo.GroupResource()); err != nil { + return err + } + return nil +} diff --git a/pkg/storage/legacysql/dualwrite/service.go b/pkg/storage/legacysql/dualwrite/service.go index 563a14aa6b6..3fe8698bba3 100644 --- a/pkg/storage/legacysql/dualwrite/service.go +++ b/pkg/storage/legacysql/dualwrite/service.go @@ -88,7 +88,7 @@ func (m *service) StartMigration(ctx context.Context, gr schema.GroupResource, k return v, fmt.Errorf("already migrated") } if key != v.UpdateKey { - return v, fmt.Errorf("key mismatch") + return v, fmt.Errorf("migration key mismatch") } if v.Migrating > 0 { return v, fmt.Errorf("migration in progress") @@ -120,7 +120,7 @@ func (m *service) Update(ctx context.Context, status StorageStatus) (StorageStat return v, fmt.Errorf("no running status") } if status.UpdateKey != v.UpdateKey { - return v, fmt.Errorf("key mismatch") + return v, fmt.Errorf("key mismatch (resource: %s, expected:%d, received: %d)", v.Resource, v.UpdateKey, status.UpdateKey) } if status.Migrating > 0 { return v, fmt.Errorf("update can not change migrating status")