Provisioning: Fix regression when dashboardProvisioner is accessed before being initialised (#85011)

* Provisioning: Fix regression when dashboardProvisioner is accessed before being initialized

* Set dashboard provisioner in the provider
This commit is contained in:
Sofia Papagiannaki 2024-03-26 12:32:56 +02:00 committed by GitHub
parent d039a0a485
commit 5ebf2d08f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 15 deletions

View File

@ -322,8 +322,9 @@ func (a *dashboardSqlAccess) scanRow(rows *sql.Rows) (*dashboardRow, error) {
if origin_name.Valid { if origin_name.Valid {
ts := time.Unix(origin_ts.Int64, 0) ts := time.Unix(origin_ts.Int64, 0)
resolvedPath := a.provisioning.GetDashboardProvisionerResolvedPath(origin_name.String)
originPath, err := filepath.Rel( originPath, err := filepath.Rel(
a.provisioning.GetDashboardProvisionerResolvedPath(origin_name.String), resolvedPath,
origin_path.String, origin_path.String,
) )
if err != nil { if err != nil {

View File

@ -74,9 +74,25 @@ func ProvideService(
orgService: orgService, orgService: orgService,
folderService: folderService, folderService: folderService,
} }
err := s.setDashboardProvisioner()
if err != nil {
return nil, fmt.Errorf("%v: %w", "Failed to create provisioner", err)
}
return s, nil return s, nil
} }
func (ps *ProvisioningServiceImpl) setDashboardProvisioner() error {
dashboardPath := filepath.Join(ps.Cfg.ProvisioningPath, "dashboards")
dashProvisioner, err := ps.newDashboardProvisioner(context.Background(), dashboardPath, ps.dashboardProvisioningService, ps.orgService, ps.dashboardService, ps.folderService)
if err != nil {
return fmt.Errorf("%v: %w", "Failed to create provisioner", err)
}
ps.dashboardProvisioner = dashProvisioner
return nil
}
type ProvisioningService interface { type ProvisioningService interface {
registry.BackgroundService registry.BackgroundService
RunInitProvisioners(ctx context.Context) error RunInitProvisioners(ctx context.Context) error
@ -110,6 +126,7 @@ func newProvisioningServiceImpl(
newDashboardProvisioner: newDashboardProvisioner, newDashboardProvisioner: newDashboardProvisioner,
provisionDatasources: provisionDatasources, provisionDatasources: provisionDatasources,
provisionPlugins: provisionPlugins, provisionPlugins: provisionPlugins,
Cfg: setting.NewCfg(),
} }
} }
@ -215,25 +232,18 @@ func (ps *ProvisioningServiceImpl) ProvisionPlugins(ctx context.Context) error {
} }
func (ps *ProvisioningServiceImpl) ProvisionDashboards(ctx context.Context) error { func (ps *ProvisioningServiceImpl) ProvisionDashboards(ctx context.Context) error {
dashboardPath := filepath.Join(ps.Cfg.ProvisioningPath, "dashboards")
dashProvisioner, err := ps.newDashboardProvisioner(ctx, dashboardPath, ps.dashboardProvisioningService, ps.orgService, ps.dashboardService, ps.folderService)
if err != nil {
return fmt.Errorf("%v: %w", "Failed to create provisioner", err)
}
ps.mutex.Lock() ps.mutex.Lock()
defer ps.mutex.Unlock() defer ps.mutex.Unlock()
ps.cancelPolling() ps.cancelPolling()
dashProvisioner.CleanUpOrphanedDashboards(ctx) ps.dashboardProvisioner.CleanUpOrphanedDashboards(ctx)
err = dashProvisioner.Provision(ctx) err := ps.dashboardProvisioner.Provision(ctx)
if err != nil { if err != nil {
// If we fail to provision with the new provisioner, the mutex will unlock and the polling will restart with the // If we fail to provision with the new provisioner, the mutex will unlock and the polling will restart with the
// old provisioner as we did not switch them yet. // old provisioner as we did not switch them yet.
return fmt.Errorf("%v: %w", "Failed to provision dashboards", err) return fmt.Errorf("%v: %w", "Failed to provision dashboards", err)
} }
ps.dashboardProvisioner = dashProvisioner
return nil return nil
} }

View File

@ -7,18 +7,18 @@ import (
"time" "time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
dashboardstore "github.com/grafana/grafana/pkg/services/dashboards" dashboardstore "github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/provisioning/dashboards" "github.com/grafana/grafana/pkg/services/provisioning/dashboards"
"github.com/grafana/grafana/pkg/services/provisioning/utils" "github.com/grafana/grafana/pkg/services/provisioning/utils"
"github.com/grafana/grafana/pkg/setting"
) )
func TestProvisioningServiceImpl(t *testing.T) { func TestProvisioningServiceImpl(t *testing.T) {
t.Run("Restart dashboard provisioning and stop service", func(t *testing.T) { t.Run("Restart dashboard provisioning and stop service", func(t *testing.T) {
serviceTest := setup() serviceTest := setup(t)
err := serviceTest.service.ProvisionDashboards(context.Background()) err := serviceTest.service.ProvisionDashboards(context.Background())
assert.Nil(t, err) assert.Nil(t, err)
serviceTest.startService() serviceTest.startService()
@ -45,7 +45,7 @@ func TestProvisioningServiceImpl(t *testing.T) {
}) })
t.Run("Failed reloading does not stop polling with old provisioned", func(t *testing.T) { t.Run("Failed reloading does not stop polling with old provisioned", func(t *testing.T) {
serviceTest := setup() serviceTest := setup(t)
err := serviceTest.service.ProvisionDashboards(context.Background()) err := serviceTest.service.ProvisionDashboards(context.Background())
assert.Nil(t, err) assert.Nil(t, err)
serviceTest.startService() serviceTest.startService()
@ -83,7 +83,7 @@ type serviceTestStruct struct {
service *ProvisioningServiceImpl service *ProvisioningServiceImpl
} }
func setup() *serviceTestStruct { func setup(t *testing.T) *serviceTestStruct {
serviceTest := &serviceTestStruct{} serviceTest := &serviceTestStruct{}
serviceTest.waitTimeout = time.Second serviceTest.waitTimeout = time.Second
@ -102,7 +102,8 @@ func setup() *serviceTestStruct {
nil, nil,
nil, nil,
) )
serviceTest.service.Cfg = setting.NewCfg() err := serviceTest.service.setDashboardProvisioner()
require.NoError(t, err)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
serviceTest.cancel = cancel serviceTest.cancel = cancel