From 70c2a31513e3d237beec8f741674eaa19e8cada9 Mon Sep 17 00:00:00 2001 From: ying-jeanne <74549700+ying-jeanne@users.noreply.github.com> Date: Mon, 26 Sep 2022 12:37:34 +0200 Subject: [PATCH] move models of dashboard thumbs into its package (#55729) --- .../dashboard_thumbs/dashboard_thumbs.go | 12 +- .../dashboardthumbsimpl/dashboard_thumbs.go | 11 +- .../dashboardthumbsimpl/store.go | 222 +----------------- .../dashboardthumbsimpl/store_test.go | 53 +++-- .../dashboardthumbsimpl/xorm_store.go | 217 +++++++++++++++++ .../dashboard_thumbs/model.go} | 10 +- pkg/services/thumbs/crawler.go | 13 +- pkg/services/thumbs/models.go | 21 +- pkg/services/thumbs/repo.go | 20 +- pkg/services/thumbs/service.go | 26 +- 10 files changed, 307 insertions(+), 298 deletions(-) create mode 100644 pkg/services/dashboard_thumbs/dashboardthumbsimpl/xorm_store.go rename pkg/{models/dashboard_thumbs.go => services/dashboard_thumbs/model.go} (95%) diff --git a/pkg/services/dashboard_thumbs/dashboard_thumbs.go b/pkg/services/dashboard_thumbs/dashboard_thumbs.go index b6c3c525ce3..2561f0c3e6a 100644 --- a/pkg/services/dashboard_thumbs/dashboard_thumbs.go +++ b/pkg/services/dashboard_thumbs/dashboard_thumbs.go @@ -2,14 +2,12 @@ package dashboardthumbs import ( "context" - - "github.com/grafana/grafana/pkg/models" ) type Service interface { - GetThumbnail(ctx context.Context, query *models.GetDashboardThumbnailCommand) (*models.DashboardThumbnail, error) - SaveThumbnail(ctx context.Context, cmd *models.SaveDashboardThumbnailCommand) (*models.DashboardThumbnail, error) - UpdateThumbnailState(ctx context.Context, cmd *models.UpdateThumbnailStateCommand) error - FindThumbnailCount(ctx context.Context, cmd *models.FindDashboardThumbnailCountCommand) (int64, error) - FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *models.FindDashboardsWithStaleThumbnailsCommand) ([]*models.DashboardWithStaleThumbnail, error) + GetThumbnail(ctx context.Context, query *GetDashboardThumbnailCommand) (*DashboardThumbnail, error) + SaveThumbnail(ctx context.Context, cmd *SaveDashboardThumbnailCommand) (*DashboardThumbnail, error) + UpdateThumbnailState(ctx context.Context, cmd *UpdateThumbnailStateCommand) error + FindThumbnailCount(ctx context.Context, cmd *FindDashboardThumbnailCountCommand) (int64, error) + FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *FindDashboardsWithStaleThumbnailsCommand) ([]*DashboardWithStaleThumbnail, error) } diff --git a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/dashboard_thumbs.go b/pkg/services/dashboard_thumbs/dashboardthumbsimpl/dashboard_thumbs.go index 7d010381b45..a71116b2136 100644 --- a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/dashboard_thumbs.go +++ b/pkg/services/dashboard_thumbs/dashboardthumbsimpl/dashboard_thumbs.go @@ -3,7 +3,6 @@ package dashboardthumbsimpl import ( "context" - "github.com/grafana/grafana/pkg/models" dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" "github.com/grafana/grafana/pkg/services/sqlstore/db" ) @@ -20,27 +19,27 @@ func ProvideService( } } -func (s *Service) GetThumbnail(ctx context.Context, query *models.GetDashboardThumbnailCommand) (*models.DashboardThumbnail, error) { +func (s *Service) GetThumbnail(ctx context.Context, query *dashboardthumbs.GetDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) { dt, err := s.store.Get(ctx, query) return dt, err } -func (s *Service) SaveThumbnail(ctx context.Context, cmd *models.SaveDashboardThumbnailCommand) (*models.DashboardThumbnail, error) { +func (s *Service) SaveThumbnail(ctx context.Context, cmd *dashboardthumbs.SaveDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) { dt, err := s.store.Save(ctx, cmd) return dt, err } -func (s *Service) UpdateThumbnailState(ctx context.Context, cmd *models.UpdateThumbnailStateCommand) error { +func (s *Service) UpdateThumbnailState(ctx context.Context, cmd *dashboardthumbs.UpdateThumbnailStateCommand) error { err := s.store.UpdateState(ctx, cmd) return err } -func (s *Service) FindThumbnailCount(ctx context.Context, cmd *models.FindDashboardThumbnailCountCommand) (int64, error) { +func (s *Service) FindThumbnailCount(ctx context.Context, cmd *dashboardthumbs.FindDashboardThumbnailCountCommand) (int64, error) { n, err := s.store.Count(ctx, cmd) return n, err } -func (s *Service) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *models.FindDashboardsWithStaleThumbnailsCommand) ([]*models.DashboardWithStaleThumbnail, error) { +func (s *Service) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) { thumbs, err := s.store.FindDashboardsWithStaleThumbnails(ctx, cmd) return thumbs, err } diff --git a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store.go b/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store.go index 754797d008f..23ea9cc2221 100644 --- a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store.go +++ b/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store.go @@ -2,224 +2,14 @@ package dashboardthumbsimpl import ( "context" - "encoding/json" - "errors" - "time" - "github.com/grafana/grafana/pkg/models" - "github.com/grafana/grafana/pkg/services/dashboards" - "github.com/grafana/grafana/pkg/services/sqlstore" - "github.com/grafana/grafana/pkg/services/sqlstore/db" + dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" ) type store interface { - Get(ctx context.Context, query *models.GetDashboardThumbnailCommand) (*models.DashboardThumbnail, error) - Save(ctx context.Context, cmd *models.SaveDashboardThumbnailCommand) (*models.DashboardThumbnail, error) - UpdateState(ctx context.Context, cmd *models.UpdateThumbnailStateCommand) error - Count(ctx context.Context, cmd *models.FindDashboardThumbnailCountCommand) (int64, error) - FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *models.FindDashboardsWithStaleThumbnailsCommand) ([]*models.DashboardWithStaleThumbnail, error) -} - -type xormStore struct { - db db.DB -} - -func (ss *xormStore) Get(ctx context.Context, query *models.GetDashboardThumbnailCommand) (*models.DashboardThumbnail, error) { - err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { - result, err := findThumbnailByMeta(sess, query.DashboardThumbnailMeta) - if err != nil { - return err - } - query.Result = result - return nil - }) - - return query.Result, err -} - -func marshalDatasourceUids(dsUids []string) (string, error) { - if dsUids == nil { - return "", nil - } - - b, err := json.Marshal(dsUids) - if err != nil { - return "", err - } - return string(b), nil -} - -func (ss *xormStore) Save(ctx context.Context, cmd *models.SaveDashboardThumbnailCommand) (*models.DashboardThumbnail, error) { - err := ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error { - existing, err := findThumbnailByMeta(sess, cmd.DashboardThumbnailMeta) - - if err != nil && !errors.Is(err, dashboards.ErrDashboardThumbnailNotFound) { - return err - } - - dsUids, err := marshalDatasourceUids(cmd.DatasourceUIDs) - if err != nil { - return err - } - - if existing != nil { - existing.Image = cmd.Image - existing.MimeType = cmd.MimeType - existing.Updated = time.Now() - existing.DashboardVersion = cmd.DashboardVersion - existing.DsUIDs = dsUids - existing.State = models.ThumbnailStateDefault - _, err = sess.ID(existing.Id).Update(existing) - cmd.Result = existing - return err - } - - thumb := &models.DashboardThumbnail{} - - dash, err := findDashboardIdByThumbMeta(sess, cmd.DashboardThumbnailMeta) - - if err != nil { - return err - } - - thumb.Updated = time.Now() - thumb.Theme = cmd.Theme - thumb.Kind = cmd.Kind - thumb.Image = cmd.Image - thumb.DsUIDs = dsUids - thumb.MimeType = cmd.MimeType - thumb.DashboardId = dash.Id - thumb.DashboardVersion = cmd.DashboardVersion - thumb.State = models.ThumbnailStateDefault - thumb.PanelId = cmd.PanelID - _, err = sess.Insert(thumb) - cmd.Result = thumb - return err - }) - - return cmd.Result, err -} - -func (ss *xormStore) UpdateState(ctx context.Context, cmd *models.UpdateThumbnailStateCommand) error { - err := ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error { - existing, err := findThumbnailByMeta(sess, cmd.DashboardThumbnailMeta) - - if err != nil { - return err - } - - existing.State = cmd.State - _, err = sess.ID(existing.Id).Update(existing) - return err - }) - - return err -} - -func (ss *xormStore) Count(ctx context.Context, cmd *models.FindDashboardThumbnailCountCommand) (int64, error) { - err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { - count, err := sess.Count(&models.DashboardThumbnail{}) - if err != nil { - return err - } - - cmd.Result = count - return nil - }) - - return cmd.Result, err -} - -func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *models.FindDashboardsWithStaleThumbnailsCommand) ([]*models.DashboardWithStaleThumbnail, error) { - err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { - sess.Table("dashboard") - sess.Join("LEFT", "dashboard_thumbnail", "dashboard.id = dashboard_thumbnail.dashboard_id AND dashboard_thumbnail.theme = ? AND dashboard_thumbnail.kind = ?", cmd.Theme, cmd.Kind) - sess.Where("dashboard.is_folder = ?", ss.db.GetDialect().BooleanStr(false)) - - query := "(dashboard.version != dashboard_thumbnail.dashboard_version " + - "OR dashboard_thumbnail.state = ? " + - "OR dashboard_thumbnail.id IS NULL" - args := []interface{}{models.ThumbnailStateStale} - - if cmd.IncludeThumbnailsWithEmptyDsUIDs { - query += " OR dashboard_thumbnail.ds_uids = ? OR dashboard_thumbnail.ds_uids IS NULL" - args = append(args, "") - } - sess.Where(query+")", args...) - - if !cmd.IncludeManuallyUploadedThumbnails { - sess.Where("(dashboard_thumbnail.id is not null AND dashboard_thumbnail.dashboard_version != ?) "+ - "OR dashboard_thumbnail.id is null "+ - "OR dashboard_thumbnail.state = ?", models.DashboardVersionForManualThumbnailUpload, models.ThumbnailStateStale) - } - - sess.Where("(dashboard_thumbnail.id IS NULL OR dashboard_thumbnail.state != ?)", models.ThumbnailStateLocked) - - sess.Cols("dashboard.id", - "dashboard.uid", - "dashboard.org_id", - "dashboard.version", - "dashboard.slug") - - var result = make([]*models.DashboardWithStaleThumbnail, 0) - err := sess.Find(&result) - - if err != nil { - return err - } - cmd.Result = result - return err - }) - - return cmd.Result, err -} - -func findThumbnailByMeta(sess *sqlstore.DBSession, meta models.DashboardThumbnailMeta) (*models.DashboardThumbnail, error) { - result := &models.DashboardThumbnail{} - - sess.Table("dashboard_thumbnail") - sess.Join("INNER", "dashboard", "dashboard.id = dashboard_thumbnail.dashboard_id") - sess.Where("dashboard.uid = ? AND dashboard.org_id = ? AND panel_id = ? AND kind = ? AND theme = ?", meta.DashboardUID, meta.OrgId, meta.PanelID, meta.Kind, meta.Theme) - sess.Cols("dashboard_thumbnail.id", - "dashboard_thumbnail.dashboard_id", - "dashboard_thumbnail.panel_id", - "dashboard_thumbnail.image", - "dashboard_thumbnail.dashboard_version", - "dashboard_thumbnail.state", - "dashboard_thumbnail.kind", - "dashboard_thumbnail.ds_uids", - "dashboard_thumbnail.mime_type", - "dashboard_thumbnail.theme", - "dashboard_thumbnail.updated") - exists, err := sess.Get(result) - - if !exists { - return nil, dashboards.ErrDashboardThumbnailNotFound - } - - if err != nil { - return nil, err - } - - return result, nil -} - -type dash struct { - Id int64 -} - -func findDashboardIdByThumbMeta(sess *sqlstore.DBSession, meta models.DashboardThumbnailMeta) (*dash, error) { - result := &dash{} - - sess.Table("dashboard").Where("dashboard.uid = ? AND dashboard.org_id = ?", meta.DashboardUID, meta.OrgId).Cols("id") - exists, err := sess.Get(result) - - if err != nil { - return nil, err - } - if !exists { - return nil, dashboards.ErrDashboardNotFound - } - - return result, err + Get(ctx context.Context, query *dashboardthumbs.GetDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) + Save(ctx context.Context, cmd *dashboardthumbs.SaveDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) + UpdateState(ctx context.Context, cmd *dashboardthumbs.UpdateThumbnailStateCommand) error + Count(ctx context.Context, cmd *dashboardthumbs.FindDashboardThumbnailCountCommand) (int64, error) + FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) } diff --git a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store_test.go b/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store_test.go index b17d777aca0..d7890b6b4e8 100644 --- a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store_test.go +++ b/pkg/services/dashboard_thumbs/dashboardthumbsimpl/store_test.go @@ -7,6 +7,7 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/models" + dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" "github.com/grafana/grafana/pkg/services/dashboards" dashver "github.com/grafana/grafana/pkg/services/dashboardversion" "github.com/grafana/grafana/pkg/services/sqlstore" @@ -15,7 +16,7 @@ import ( ) var theme = models.ThemeDark -var kind = models.ThumbnailKindDefault +var kind = dashboardthumbs.ThumbnailKindDefault func TestIntegrationSqlStorage(t *testing.T) { if testing.Short() { @@ -38,7 +39,7 @@ func TestIntegrationSqlStorage(t *testing.T) { thumb := getThumbnail(t, store, dash.Uid, dash.OrgId) require.Positive(t, thumb.Id) - require.Equal(t, models.ThumbnailStateDefault, thumb.State) + require.Equal(t, dashboardthumbs.ThumbnailStateDefault, thumb.State) require.Equal(t, dash.Version, thumb.DashboardVersion) }) @@ -62,7 +63,7 @@ func TestIntegrationSqlStorage(t *testing.T) { upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version) - cmd := models.FindDashboardsWithStaleThumbnailsCommand{ + cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -77,7 +78,7 @@ func TestIntegrationSqlStorage(t *testing.T) { upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version) - cmd := models.FindDashboardsWithStaleThumbnailsCommand{ + cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, IncludeThumbnailsWithEmptyDsUIDs: true, Theme: theme, @@ -92,9 +93,9 @@ func TestIntegrationSqlStorage(t *testing.T) { setup() dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version) - updateThumbnailState(t, store, dash.Uid, dash.OrgId, models.ThumbnailStateStale) + updateThumbnailState(t, store, dash.Uid, dash.OrgId, dashboardthumbs.ThumbnailStateStale) - cmd := models.FindDashboardsWithStaleThumbnailsCommand{ + cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -108,10 +109,10 @@ func TestIntegrationSqlStorage(t *testing.T) { setup() dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version) - updateThumbnailState(t, store, dash.Uid, dash.OrgId, models.ThumbnailStateStale) + updateThumbnailState(t, store, dash.Uid, dash.OrgId, dashboardthumbs.ThumbnailStateStale) upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version) - cmd := models.FindDashboardsWithStaleThumbnailsCommand{ + cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -124,7 +125,7 @@ func TestIntegrationSqlStorage(t *testing.T) { setup() dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") - cmd := models.FindDashboardsWithStaleThumbnailsCommand{ + cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -143,7 +144,7 @@ func TestIntegrationSqlStorage(t *testing.T) { "tags": "different-tag", }) - cmd := models.FindDashboardsWithStaleThumbnailsCommand{ + cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -157,13 +158,13 @@ func TestIntegrationSqlStorage(t *testing.T) { setup() dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version) - updateThumbnailState(t, store, dash.Uid, dash.OrgId, models.ThumbnailStateLocked) + updateThumbnailState(t, store, dash.Uid, dash.OrgId, dashboardthumbs.ThumbnailStateLocked) updateTestDashboard(t, sqlStore, dash, map[string]interface{}{ "tags": "different-tag", }) - cmd := models.FindDashboardsWithStaleThumbnailsCommand{ + cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -175,13 +176,13 @@ func TestIntegrationSqlStorage(t *testing.T) { t.Run("Should not return dashboards with manually uploaded thumbnails by default", func(t *testing.T) { setup() dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") - upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, models.DashboardVersionForManualThumbnailUpload) + upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dashboardthumbs.DashboardVersionForManualThumbnailUpload) updateTestDashboard(t, sqlStore, dash, map[string]interface{}{ "tags": "different-tag", }) - cmd := models.FindDashboardsWithStaleThumbnailsCommand{ + cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, } @@ -193,13 +194,13 @@ func TestIntegrationSqlStorage(t *testing.T) { t.Run("Should return dashboards with manually uploaded thumbnails if requested", func(t *testing.T) { setup() dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp") - upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, models.DashboardVersionForManualThumbnailUpload) + upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dashboardthumbs.DashboardVersionForManualThumbnailUpload) updateTestDashboard(t, sqlStore, dash, map[string]interface{}{ "tags": "different-tag", }) - cmd := models.FindDashboardsWithStaleThumbnailsCommand{ + cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ Kind: kind, Theme: theme, IncludeManuallyUploadedThumbnails: true, @@ -221,17 +222,17 @@ func TestIntegrationSqlStorage(t *testing.T) { "tags": "different-tag", }) - cmd := models.FindDashboardThumbnailCountCommand{} + cmd := dashboardthumbs.FindDashboardThumbnailCountCommand{} res, err := store.Count(context.Background(), &cmd) require.NoError(t, err) require.Equal(t, res, int64(2)) }) } -func getThumbnail(t *testing.T, store store, dashboardUID string, orgId int64) *models.DashboardThumbnail { +func getThumbnail(t *testing.T, store store, dashboardUID string, orgId int64) *dashboardthumbs.DashboardThumbnail { t.Helper() - cmd := models.GetDashboardThumbnailCommand{ - DashboardThumbnailMeta: models.DashboardThumbnailMeta{ + cmd := dashboardthumbs.GetDashboardThumbnailCommand{ + DashboardThumbnailMeta: dashboardthumbs.DashboardThumbnailMeta{ DashboardUID: dashboardUID, OrgId: orgId, PanelID: 0, @@ -245,10 +246,10 @@ func getThumbnail(t *testing.T, store store, dashboardUID string, orgId int64) * return thumb } -func upsertTestDashboardThumbnail(t *testing.T, store store, dashboardUID string, orgId int64, dashboardVersion int) *models.DashboardThumbnail { +func upsertTestDashboardThumbnail(t *testing.T, store store, dashboardUID string, orgId int64, dashboardVersion int) *dashboardthumbs.DashboardThumbnail { t.Helper() - cmd := models.SaveDashboardThumbnailCommand{ - DashboardThumbnailMeta: models.DashboardThumbnailMeta{ + cmd := dashboardthumbs.SaveDashboardThumbnailCommand{ + DashboardThumbnailMeta: dashboardthumbs.DashboardThumbnailMeta{ DashboardUID: dashboardUID, OrgId: orgId, PanelID: 0, @@ -266,10 +267,10 @@ func upsertTestDashboardThumbnail(t *testing.T, store store, dashboardUID string return dash } -func updateThumbnailState(t *testing.T, store store, dashboardUID string, orgId int64, state models.ThumbnailState) { +func updateThumbnailState(t *testing.T, store store, dashboardUID string, orgId int64, state dashboardthumbs.ThumbnailState) { t.Helper() - cmd := models.UpdateThumbnailStateCommand{ - DashboardThumbnailMeta: models.DashboardThumbnailMeta{ + cmd := dashboardthumbs.UpdateThumbnailStateCommand{ + DashboardThumbnailMeta: dashboardthumbs.DashboardThumbnailMeta{ DashboardUID: dashboardUID, OrgId: orgId, PanelID: 0, diff --git a/pkg/services/dashboard_thumbs/dashboardthumbsimpl/xorm_store.go b/pkg/services/dashboard_thumbs/dashboardthumbsimpl/xorm_store.go new file mode 100644 index 00000000000..ae1bdd901ee --- /dev/null +++ b/pkg/services/dashboard_thumbs/dashboardthumbsimpl/xorm_store.go @@ -0,0 +1,217 @@ +package dashboardthumbsimpl + +import ( + "context" + "encoding/json" + "errors" + "time" + + dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" + "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/sqlstore" + "github.com/grafana/grafana/pkg/services/sqlstore/db" +) + +type xormStore struct { + db db.DB +} + +func (ss *xormStore) Get(ctx context.Context, query *dashboardthumbs.GetDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) { + err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { + result, err := findThumbnailByMeta(sess, query.DashboardThumbnailMeta) + if err != nil { + return err + } + query.Result = result + return nil + }) + + return query.Result, err +} + +func marshalDatasourceUids(dsUids []string) (string, error) { + if dsUids == nil { + return "", nil + } + + b, err := json.Marshal(dsUids) + if err != nil { + return "", err + } + return string(b), nil +} + +func (ss *xormStore) Save(ctx context.Context, cmd *dashboardthumbs.SaveDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) { + err := ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error { + existing, err := findThumbnailByMeta(sess, cmd.DashboardThumbnailMeta) + + if err != nil && !errors.Is(err, dashboards.ErrDashboardThumbnailNotFound) { + return err + } + + dsUids, err := marshalDatasourceUids(cmd.DatasourceUIDs) + if err != nil { + return err + } + + if existing != nil { + existing.Image = cmd.Image + existing.MimeType = cmd.MimeType + existing.Updated = time.Now() + existing.DashboardVersion = cmd.DashboardVersion + existing.DsUIDs = dsUids + existing.State = dashboardthumbs.ThumbnailStateDefault + _, err = sess.ID(existing.Id).Update(existing) + cmd.Result = existing + return err + } + + thumb := &dashboardthumbs.DashboardThumbnail{} + + dash, err := findDashboardIdByThumbMeta(sess, cmd.DashboardThumbnailMeta) + + if err != nil { + return err + } + + thumb.Updated = time.Now() + thumb.Theme = cmd.Theme + thumb.Kind = cmd.Kind + thumb.Image = cmd.Image + thumb.DsUIDs = dsUids + thumb.MimeType = cmd.MimeType + thumb.DashboardId = dash.Id + thumb.DashboardVersion = cmd.DashboardVersion + thumb.State = dashboardthumbs.ThumbnailStateDefault + thumb.PanelId = cmd.PanelID + _, err = sess.Insert(thumb) + cmd.Result = thumb + return err + }) + + return cmd.Result, err +} + +func (ss *xormStore) UpdateState(ctx context.Context, cmd *dashboardthumbs.UpdateThumbnailStateCommand) error { + err := ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error { + existing, err := findThumbnailByMeta(sess, cmd.DashboardThumbnailMeta) + + if err != nil { + return err + } + + existing.State = cmd.State + _, err = sess.ID(existing.Id).Update(existing) + return err + }) + + return err +} + +func (ss *xormStore) Count(ctx context.Context, cmd *dashboardthumbs.FindDashboardThumbnailCountCommand) (int64, error) { + err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { + count, err := sess.Count(&dashboardthumbs.DashboardThumbnail{}) + if err != nil { + return err + } + + cmd.Result = count + return nil + }) + + return cmd.Result, err +} + +func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) { + err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error { + sess.Table("dashboard") + sess.Join("LEFT", "dashboard_thumbnail", "dashboard.id = dashboard_thumbnail.dashboard_id AND dashboard_thumbnail.theme = ? AND dashboard_thumbnail.kind = ?", cmd.Theme, cmd.Kind) + sess.Where("dashboard.is_folder = ?", ss.db.GetDialect().BooleanStr(false)) + + query := "(dashboard.version != dashboard_thumbnail.dashboard_version " + + "OR dashboard_thumbnail.state = ? " + + "OR dashboard_thumbnail.id IS NULL" + args := []interface{}{dashboardthumbs.ThumbnailStateStale} + + if cmd.IncludeThumbnailsWithEmptyDsUIDs { + query += " OR dashboard_thumbnail.ds_uids = ? OR dashboard_thumbnail.ds_uids IS NULL" + args = append(args, "") + } + sess.Where(query+")", args...) + + if !cmd.IncludeManuallyUploadedThumbnails { + sess.Where("(dashboard_thumbnail.id is not null AND dashboard_thumbnail.dashboard_version != ?) "+ + "OR dashboard_thumbnail.id is null "+ + "OR dashboard_thumbnail.state = ?", dashboardthumbs.DashboardVersionForManualThumbnailUpload, dashboardthumbs.ThumbnailStateStale) + } + + sess.Where("(dashboard_thumbnail.id IS NULL OR dashboard_thumbnail.state != ?)", dashboardthumbs.ThumbnailStateLocked) + + sess.Cols("dashboard.id", + "dashboard.uid", + "dashboard.org_id", + "dashboard.version", + "dashboard.slug") + + var result = make([]*dashboardthumbs.DashboardWithStaleThumbnail, 0) + err := sess.Find(&result) + + if err != nil { + return err + } + cmd.Result = result + return err + }) + + return cmd.Result, err +} + +func findThumbnailByMeta(sess *sqlstore.DBSession, meta dashboardthumbs.DashboardThumbnailMeta) (*dashboardthumbs.DashboardThumbnail, error) { + result := &dashboardthumbs.DashboardThumbnail{} + + sess.Table("dashboard_thumbnail") + sess.Join("INNER", "dashboard", "dashboard.id = dashboard_thumbnail.dashboard_id") + sess.Where("dashboard.uid = ? AND dashboard.org_id = ? AND panel_id = ? AND kind = ? AND theme = ?", meta.DashboardUID, meta.OrgId, meta.PanelID, meta.Kind, meta.Theme) + sess.Cols("dashboard_thumbnail.id", + "dashboard_thumbnail.dashboard_id", + "dashboard_thumbnail.panel_id", + "dashboard_thumbnail.image", + "dashboard_thumbnail.dashboard_version", + "dashboard_thumbnail.state", + "dashboard_thumbnail.kind", + "dashboard_thumbnail.ds_uids", + "dashboard_thumbnail.mime_type", + "dashboard_thumbnail.theme", + "dashboard_thumbnail.updated") + exists, err := sess.Get(result) + + if !exists { + return nil, dashboards.ErrDashboardThumbnailNotFound + } + + if err != nil { + return nil, err + } + + return result, nil +} + +type dash struct { + Id int64 +} + +func findDashboardIdByThumbMeta(sess *sqlstore.DBSession, meta dashboardthumbs.DashboardThumbnailMeta) (*dash, error) { + result := &dash{} + + sess.Table("dashboard").Where("dashboard.uid = ? AND dashboard.org_id = ?", meta.DashboardUID, meta.OrgId).Cols("id") + exists, err := sess.Get(result) + + if err != nil { + return nil, err + } + if !exists { + return nil, dashboards.ErrDashboardNotFound + } + + return result, err +} diff --git a/pkg/models/dashboard_thumbs.go b/pkg/services/dashboard_thumbs/model.go similarity index 95% rename from pkg/models/dashboard_thumbs.go rename to pkg/services/dashboard_thumbs/model.go index 0d1b8a8cdd0..3ee310880ba 100644 --- a/pkg/models/dashboard_thumbs.go +++ b/pkg/services/dashboard_thumbs/model.go @@ -1,10 +1,12 @@ -package models +package dashboardthumbs import ( "encoding/json" "errors" "fmt" "time" + + "github.com/grafana/grafana/pkg/models" ) type ThumbnailKind string @@ -82,7 +84,7 @@ type DashboardThumbnail struct { State ThumbnailState `json:"state"` PanelId int64 `json:"panelId,omitempty"` Kind ThumbnailKind `json:"kind"` - Theme Theme `json:"theme"` + Theme models.Theme `json:"theme"` Image []byte `json:"image"` MimeType string `json:"mimeType"` Updated time.Time `json:"updated"` @@ -99,7 +101,7 @@ type DashboardThumbnailMeta struct { OrgId int64 PanelID int64 Kind ThumbnailKind - Theme Theme + Theme models.Theme } type GetDashboardThumbnailCommand struct { @@ -125,7 +127,7 @@ type FindDashboardThumbnailCountCommand struct { type FindDashboardsWithStaleThumbnailsCommand struct { IncludeManuallyUploadedThumbnails bool IncludeThumbnailsWithEmptyDsUIDs bool - Theme Theme + Theme models.Theme Kind ThumbnailKind Result []*DashboardWithStaleThumbnail } diff --git a/pkg/services/thumbs/crawler.go b/pkg/services/thumbs/crawler.go index 1269d616365..e941dc96ce9 100644 --- a/pkg/services/thumbs/crawler.go +++ b/pkg/services/thumbs/crawler.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" + dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" "github.com/grafana/grafana/pkg/services/live" "github.com/grafana/grafana/pkg/services/rendering" ) @@ -28,12 +29,12 @@ type simpleCrawler struct { glive *live.GrafanaLive thumbnailRepo thumbnailRepo mode CrawlerMode - thumbnailKind models.ThumbnailKind + thumbnailKind dashboardthumbs.ThumbnailKind auth CrawlerAuth opts rendering.Opts status crawlStatus statusMutex sync.RWMutex - queue []*models.DashboardWithStaleThumbnail + queue []*dashboardthumbs.DashboardWithStaleThumbnail queueMutex sync.Mutex log log.Logger renderingSessionByOrgId map[int64]rendering.Session @@ -64,7 +65,7 @@ func newSimpleCrawler(renderService rendering.Service, gl *live.GrafanaLive, rep return c } -func (r *simpleCrawler) next(ctx context.Context) (*models.DashboardWithStaleThumbnail, rendering.Session, rendering.AuthOpts, error) { +func (r *simpleCrawler) next(ctx context.Context) (*dashboardthumbs.DashboardWithStaleThumbnail, rendering.Session, rendering.AuthOpts, error) { r.queueMutex.Lock() defer r.queueMutex.Unlock() @@ -116,13 +117,13 @@ func (r *simpleCrawler) broadcastStatus() { } } -type byOrgId []*models.DashboardWithStaleThumbnail +type byOrgId []*dashboardthumbs.DashboardWithStaleThumbnail func (d byOrgId) Len() int { return len(d) } func (d byOrgId) Less(i, j int) bool { return d[i].OrgId > d[j].OrgId } func (d byOrgId) Swap(i, j int) { d[i], d[j] = d[j], d[i] } -func (r *simpleCrawler) Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, thumbnailKind models.ThumbnailKind) error { +func (r *simpleCrawler) Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, thumbnailKind dashboardthumbs.ThumbnailKind) error { res, err := r.renderService.HasCapability(ctx, rendering.ScalingDownImages) if err != nil { return err @@ -325,7 +326,7 @@ func (r *simpleCrawler) walk(ctx context.Context, id int) { } }() - thumbnailId, err := r.thumbnailRepo.saveFromFile(ctx, res.FilePath, models.DashboardThumbnailMeta{ + thumbnailId, err := r.thumbnailRepo.saveFromFile(ctx, res.FilePath, dashboardthumbs.DashboardThumbnailMeta{ DashboardUID: item.Uid, OrgId: item.OrgId, Theme: r.opts.Theme, diff --git a/pkg/services/thumbs/models.go b/pkg/services/thumbs/models.go index 7ab47e7a9d3..d8df1fe8ef8 100644 --- a/pkg/services/thumbs/models.go +++ b/pkg/services/thumbs/models.go @@ -5,6 +5,7 @@ import ( "time" "github.com/grafana/grafana/pkg/models" + dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs" ) type CrawlerMode string @@ -31,10 +32,10 @@ const ( ) type previewRequest struct { - OrgID int64 `json:"orgId"` - UID string `json:"uid"` - Kind models.ThumbnailKind `json:"kind"` - Theme models.Theme `json:"theme"` + OrgID int64 `json:"orgId"` + UID string `json:"uid"` + Kind dashboardthumbs.ThumbnailKind `json:"kind"` + Theme models.Theme `json:"theme"` } type crawlCmd struct { @@ -65,7 +66,7 @@ type dashboardPreviewsSetupConfig struct { type dashRenderer interface { // Run Assumes you have already authenticated as admin. - Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, kind models.ThumbnailKind) error + Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, kind dashboardthumbs.ThumbnailKind) error // Assumes you have already authenticated as admin. Stop() (crawlStatus, error) @@ -77,10 +78,10 @@ type dashRenderer interface { } type thumbnailRepo interface { - updateThumbnailState(ctx context.Context, state models.ThumbnailState, meta models.DashboardThumbnailMeta) error + updateThumbnailState(ctx context.Context, state dashboardthumbs.ThumbnailState, meta dashboardthumbs.DashboardThumbnailMeta) error doThumbnailsExist(ctx context.Context) (bool, error) - saveFromFile(ctx context.Context, filePath string, meta models.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) - saveFromBytes(ctx context.Context, bytes []byte, mimeType string, meta models.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) - getThumbnail(ctx context.Context, meta models.DashboardThumbnailMeta) (*models.DashboardThumbnail, error) - findDashboardsWithStaleThumbnails(ctx context.Context, theme models.Theme, thumbnailKind models.ThumbnailKind) ([]*models.DashboardWithStaleThumbnail, error) + saveFromFile(ctx context.Context, filePath string, meta dashboardthumbs.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) + saveFromBytes(ctx context.Context, bytes []byte, mimeType string, meta dashboardthumbs.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) + getThumbnail(ctx context.Context, meta dashboardthumbs.DashboardThumbnailMeta) (*dashboardthumbs.DashboardThumbnail, error) + findDashboardsWithStaleThumbnails(ctx context.Context, theme models.Theme, thumbnailKind dashboardthumbs.ThumbnailKind) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) } diff --git a/pkg/services/thumbs/repo.go b/pkg/services/thumbs/repo.go index 8011abf414f..4d0f6f94697 100644 --- a/pkg/services/thumbs/repo.go +++ b/pkg/services/thumbs/repo.go @@ -28,7 +28,7 @@ type sqlThumbnailRepository struct { log log.Logger } -func (r *sqlThumbnailRepository) saveFromFile(ctx context.Context, filePath string, meta models.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) { +func (r *sqlThumbnailRepository) saveFromFile(ctx context.Context, filePath string, meta dashboardthumbs.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) { // the filePath variable is never set by the user. it refers to a temporary file created either in // 1. thumbs/service.go, when user uploads a thumbnail // 2. the rendering service, when image-renderer returns a screenshot @@ -56,8 +56,8 @@ func getMimeType(filePath string) string { return "image/png" } -func (r *sqlThumbnailRepository) saveFromBytes(ctx context.Context, content []byte, mimeType string, meta models.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) { - cmd := &models.SaveDashboardThumbnailCommand{ +func (r *sqlThumbnailRepository) saveFromBytes(ctx context.Context, content []byte, mimeType string, meta dashboardthumbs.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) { + cmd := &dashboardthumbs.SaveDashboardThumbnailCommand{ DashboardThumbnailMeta: meta, Image: content, MimeType: mimeType, @@ -74,22 +74,22 @@ func (r *sqlThumbnailRepository) saveFromBytes(ctx context.Context, content []by return cmd.Result.Id, nil } -func (r *sqlThumbnailRepository) updateThumbnailState(ctx context.Context, state models.ThumbnailState, meta models.DashboardThumbnailMeta) error { - return r.store.UpdateThumbnailState(ctx, &models.UpdateThumbnailStateCommand{ +func (r *sqlThumbnailRepository) updateThumbnailState(ctx context.Context, state dashboardthumbs.ThumbnailState, meta dashboardthumbs.DashboardThumbnailMeta) error { + return r.store.UpdateThumbnailState(ctx, &dashboardthumbs.UpdateThumbnailStateCommand{ State: state, DashboardThumbnailMeta: meta, }) } -func (r *sqlThumbnailRepository) getThumbnail(ctx context.Context, meta models.DashboardThumbnailMeta) (*models.DashboardThumbnail, error) { - query := &models.GetDashboardThumbnailCommand{ +func (r *sqlThumbnailRepository) getThumbnail(ctx context.Context, meta dashboardthumbs.DashboardThumbnailMeta) (*dashboardthumbs.DashboardThumbnail, error) { + query := &dashboardthumbs.GetDashboardThumbnailCommand{ DashboardThumbnailMeta: meta, } return r.store.GetThumbnail(ctx, query) } -func (r *sqlThumbnailRepository) findDashboardsWithStaleThumbnails(ctx context.Context, theme models.Theme, kind models.ThumbnailKind) ([]*models.DashboardWithStaleThumbnail, error) { - return r.store.FindDashboardsWithStaleThumbnails(ctx, &models.FindDashboardsWithStaleThumbnailsCommand{ +func (r *sqlThumbnailRepository) findDashboardsWithStaleThumbnails(ctx context.Context, theme models.Theme, kind dashboardthumbs.ThumbnailKind) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) { + return r.store.FindDashboardsWithStaleThumbnails(ctx, &dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{ IncludeManuallyUploadedThumbnails: false, IncludeThumbnailsWithEmptyDsUIDs: !r.search.IsDisabled(), Theme: theme, @@ -98,7 +98,7 @@ func (r *sqlThumbnailRepository) findDashboardsWithStaleThumbnails(ctx context.C } func (r *sqlThumbnailRepository) doThumbnailsExist(ctx context.Context) (bool, error) { - cmd := &models.FindDashboardThumbnailCountCommand{} + cmd := &dashboardthumbs.FindDashboardThumbnailCountCommand{} count, err := r.store.FindThumbnailCount(ctx, cmd) if err != nil { r.log.Error("Error finding thumbnails", "err", err) diff --git a/pkg/services/thumbs/service.go b/pkg/services/thumbs/service.go index 56741c5baed..8d520e81513 100644 --- a/pkg/services/thumbs/service.go +++ b/pkg/services/thumbs/service.go @@ -69,7 +69,7 @@ type crawlerScheduleOptions struct { tickerInterval time.Duration maxCrawlDuration time.Duration crawlerMode CrawlerMode - thumbnailKind models.ThumbnailKind + thumbnailKind dashboardthumbs.ThumbnailKind themes []models.Theme auth CrawlerAuth } @@ -124,7 +124,7 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, crawlInterval: cfg.DashboardPreviews.SchedulerInterval, maxCrawlDuration: cfg.DashboardPreviews.MaxCrawlDuration, crawlerMode: CrawlerModeThumbs, - thumbnailKind: models.ThumbnailKindDefault, + thumbnailKind: dashboardthumbs.ThumbnailKindDefault, themes: []models.Theme{models.ThemeDark, models.ThemeLight}, auth: crawlerAuth, }, @@ -157,7 +157,7 @@ func (hs *thumbService) Enabled() bool { func (hs *thumbService) parseImageReq(c *models.ReqContext, checkSave bool) *previewRequest { params := web.Params(c.Req) - kind, err := models.ParseThumbnailKind(params[":kind"]) + kind, err := dashboardthumbs.ParseThumbnailKind(params[":kind"]) if err != nil { c.JSON(400, map[string]string{"error": "invalid size"}) return nil @@ -191,7 +191,7 @@ func (hs *thumbService) parseImageReq(c *models.ReqContext, checkSave bool) *pre } type updateThumbnailStateRequest struct { - State models.ThumbnailState `json:"state" binding:"Required"` + State dashboardthumbs.ThumbnailState `json:"state" binding:"Required"` } func (hs *thumbService) UpdateThumbnailState(c *models.ReqContext) { @@ -209,11 +209,11 @@ func (hs *thumbService) UpdateThumbnailState(c *models.ReqContext) { return } - err = hs.thumbnailRepo.updateThumbnailState(c.Req.Context(), body.State, models.DashboardThumbnailMeta{ + err = hs.thumbnailRepo.updateThumbnailState(c.Req.Context(), body.State, dashboardthumbs.DashboardThumbnailMeta{ DashboardUID: req.UID, OrgId: req.OrgID, Theme: req.Theme, - Kind: models.ThumbnailKindDefault, + Kind: dashboardthumbs.ThumbnailKindDefault, }) if err != nil { @@ -232,11 +232,11 @@ func (hs *thumbService) GetImage(c *models.ReqContext) { return // already returned value } - res, err := hs.thumbnailRepo.getThumbnail(c.Req.Context(), models.DashboardThumbnailMeta{ + res, err := hs.thumbnailRepo.getThumbnail(c.Req.Context(), dashboardthumbs.DashboardThumbnailMeta{ DashboardUID: req.UID, OrgId: req.OrgID, Theme: req.Theme, - Kind: models.ThumbnailKindDefault, + Kind: dashboardthumbs.ThumbnailKindDefault, }) if errors.Is(err, dashboards.ErrDashboardThumbnailNotFound) { @@ -269,7 +269,7 @@ func (hs *thumbService) GetImage(c *models.ReqContext) { } } -func (hs *thumbService) hasAccessToPreview(c *models.ReqContext, res *models.DashboardThumbnail, req *previewRequest) bool { +func (hs *thumbService) hasAccessToPreview(c *models.ReqContext, res *dashboardthumbs.DashboardThumbnail, req *previewRequest) bool { if !hs.licensing.FeatureEnabled("accesscontrol.enforcement") { return true } @@ -402,12 +402,12 @@ func (hs *thumbService) SetImage(c *models.ReqContext) { return } - _, err = hs.thumbnailRepo.saveFromBytes(c.Req.Context(), fileBytes, getMimeType(handler.Filename), models.DashboardThumbnailMeta{ + _, err = hs.thumbnailRepo.saveFromBytes(c.Req.Context(), fileBytes, getMimeType(handler.Filename), dashboardthumbs.DashboardThumbnailMeta{ DashboardUID: req.UID, OrgId: req.OrgID, Theme: req.Theme, Kind: req.Kind, - }, models.DashboardVersionForManualThumbnailUpload, dsUids) + }, dashboardthumbs.DashboardVersionForManualThumbnailUpload, dsUids) if err != nil { c.JSON(400, map[string]string{"error": "error saving thumbnail file"}) @@ -432,7 +432,7 @@ func (hs *thumbService) StartCrawler(c *models.ReqContext) response.Response { cmd.Mode = CrawlerModeThumbs } - go hs.runOnDemandCrawl(context.Background(), cmd.Theme, cmd.Mode, models.ThumbnailKindDefault, rendering.AuthOpts{ + go hs.runOnDemandCrawl(context.Background(), cmd.Theme, cmd.Mode, dashboardthumbs.ThumbnailKindDefault, rendering.AuthOpts{ OrgID: c.OrgID, UserID: c.UserID, OrgRole: c.OrgRole, @@ -494,7 +494,7 @@ func (hs *thumbService) getDashboardId(c *models.ReqContext, uid string) (int64, return query.Result.Id, nil } -func (hs *thumbService) runOnDemandCrawl(parentCtx context.Context, theme models.Theme, mode CrawlerMode, kind models.ThumbnailKind, authOpts rendering.AuthOpts) { +func (hs *thumbService) runOnDemandCrawl(parentCtx context.Context, theme models.Theme, mode CrawlerMode, kind dashboardthumbs.ThumbnailKind, authOpts rendering.AuthOpts) { if !hs.canRunCrawler { return }