Provisioning: Start in "mode5" when nothing exists in legacy (#100862)

This commit is contained in:
Ryan McKinley authored and GitHub committed 2025-02-18 14:27:13 +03:00
1 parent 590e912d60
commit 4069f4cd41
2 files changed
+64 -2

No files matched your search

@@ -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
}
+2 -2
View File
@@ -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")