mirror of
https://github.com/grafana/grafana.git
synced 2026-09-05 04:40:13 -05:00
StoreSplit: move dashboard thumbs into thumbs service (#55800)
* move dashboard thumbs into thumbs service * rename some variables
This commit is contained in:
@@ -45,7 +45,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/comments"
|
"github.com/grafana/grafana/pkg/services/comments"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||||
"github.com/grafana/grafana/pkg/services/correlations"
|
"github.com/grafana/grafana/pkg/services/correlations"
|
||||||
dashboardThumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs"
|
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboardsnapshots"
|
"github.com/grafana/grafana/pkg/services/dashboardsnapshots"
|
||||||
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
||||||
@@ -193,7 +192,7 @@ type HTTPServer struct {
|
|||||||
|
|
||||||
userService user.Service
|
userService user.Service
|
||||||
tempUserService tempUser.Service
|
tempUserService tempUser.Service
|
||||||
dashboardThumbsService dashboardThumbs.Service
|
dashboardThumbsService thumbs.DashboardThumbService
|
||||||
loginAttemptService loginAttempt.Service
|
loginAttemptService loginAttempt.Service
|
||||||
orgService org.Service
|
orgService org.Service
|
||||||
teamService team.Service
|
teamService team.Service
|
||||||
@@ -240,7 +239,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
|||||||
secretsPluginMigrator spm.SecretMigrationProvider, secretsStore secretsKV.SecretsKVStore,
|
secretsPluginMigrator spm.SecretMigrationProvider, secretsStore secretsKV.SecretsKVStore,
|
||||||
publicDashboardsApi *publicdashboardsApi.Api, userService user.Service, tempUserService tempUser.Service,
|
publicDashboardsApi *publicdashboardsApi.Api, userService user.Service, tempUserService tempUser.Service,
|
||||||
loginAttemptService loginAttempt.Service, orgService org.Service, teamService team.Service,
|
loginAttemptService loginAttempt.Service, orgService org.Service, teamService team.Service,
|
||||||
accesscontrolService accesscontrol.Service, dashboardThumbsService dashboardThumbs.Service, navTreeService navtree.Service,
|
accesscontrolService accesscontrol.Service, dashboardThumbsService thumbs.DashboardThumbService, navTreeService navtree.Service,
|
||||||
annotationRepo annotations.Repository, tagService tag.Service, searchv2HTTPService searchV2.SearchHTTPService,
|
annotationRepo annotations.Repository, tagService tag.Service, searchv2HTTPService searchV2.SearchHTTPService,
|
||||||
userAuthService userauth.Service,
|
userAuthService userauth.Service,
|
||||||
) (*HTTPServer, error) {
|
) (*HTTPServer, error) {
|
||||||
|
|||||||
+2
-2
@@ -54,7 +54,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
|
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
|
||||||
"github.com/grafana/grafana/pkg/services/correlations"
|
"github.com/grafana/grafana/pkg/services/correlations"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboard_thumbs/dashboardthumbsimpl"
|
|
||||||
"github.com/grafana/grafana/pkg/services/dashboardimport"
|
"github.com/grafana/grafana/pkg/services/dashboardimport"
|
||||||
dashboardimportservice "github.com/grafana/grafana/pkg/services/dashboardimport/service"
|
dashboardimportservice "github.com/grafana/grafana/pkg/services/dashboardimport/service"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
@@ -132,6 +131,7 @@ import (
|
|||||||
tempuser "github.com/grafana/grafana/pkg/services/temp_user"
|
tempuser "github.com/grafana/grafana/pkg/services/temp_user"
|
||||||
"github.com/grafana/grafana/pkg/services/temp_user/tempuserimpl"
|
"github.com/grafana/grafana/pkg/services/temp_user/tempuserimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/thumbs"
|
"github.com/grafana/grafana/pkg/services/thumbs"
|
||||||
|
"github.com/grafana/grafana/pkg/services/thumbs/dashboardthumbsimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/updatechecker"
|
"github.com/grafana/grafana/pkg/services/updatechecker"
|
||||||
"github.com/grafana/grafana/pkg/services/user/userimpl"
|
"github.com/grafana/grafana/pkg/services/user/userimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/userauth/userauthimpl"
|
"github.com/grafana/grafana/pkg/services/userauth/userauthimpl"
|
||||||
@@ -177,6 +177,7 @@ var wireBasicSet = wire.NewSet(
|
|||||||
hooks.ProvideService,
|
hooks.ProvideService,
|
||||||
kvstore.ProvideService,
|
kvstore.ProvideService,
|
||||||
localcache.ProvideService,
|
localcache.ProvideService,
|
||||||
|
dashboardthumbsimpl.ProvideService,
|
||||||
updatechecker.ProvideGrafanaService,
|
updatechecker.ProvideGrafanaService,
|
||||||
updatechecker.ProvidePluginsService,
|
updatechecker.ProvidePluginsService,
|
||||||
uss.ProvideService,
|
uss.ProvideService,
|
||||||
@@ -345,7 +346,6 @@ var wireBasicSet = wire.NewSet(
|
|||||||
grpcserver.ProvideHealthService,
|
grpcserver.ProvideHealthService,
|
||||||
teamimpl.ProvideService,
|
teamimpl.ProvideService,
|
||||||
tempuserimpl.ProvideService,
|
tempuserimpl.ProvideService,
|
||||||
dashboardthumbsimpl.ProvideService,
|
|
||||||
loginattemptimpl.ProvideService,
|
loginattemptimpl.ProvideService,
|
||||||
userauthimpl.ProvideService,
|
userauthimpl.ProvideService,
|
||||||
secretsMigrations.ProvideDataSourceMigrationService,
|
secretsMigrations.ProvideDataSourceMigrationService,
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
package dashboardthumbsimpl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs"
|
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore/db"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Service struct {
|
|
||||||
store store
|
|
||||||
}
|
|
||||||
|
|
||||||
func ProvideService(
|
|
||||||
db db.DB,
|
|
||||||
) dashboardthumbs.Service {
|
|
||||||
return &Service{
|
|
||||||
store: &xormStore{db: db},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 *dashboardthumbs.SaveDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) {
|
|
||||||
dt, err := s.store.Save(ctx, cmd)
|
|
||||||
return dt, err
|
|
||||||
}
|
|
||||||
|
|
||||||
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 *dashboardthumbs.FindDashboardThumbnailCountCommand) (int64, error) {
|
|
||||||
n, err := s.store.Count(ctx, cmd)
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) {
|
|
||||||
thumbs, err := s.store.FindDashboardsWithStaleThumbnails(ctx, cmd)
|
|
||||||
return thumbs, err
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package dashboardthumbsimpl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs"
|
|
||||||
)
|
|
||||||
|
|
||||||
type store interface {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
package dashboardthumbs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ThumbnailKind string
|
|
||||||
type ThumbnailState string
|
|
||||||
type CrawlerMode string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ThumbnailKindDefault is a small 320x240 preview
|
|
||||||
ThumbnailKindDefault ThumbnailKind = "thumb"
|
|
||||||
|
|
||||||
// unsupported for now
|
|
||||||
// - ThumbnailKindLarge ThumbnailKind = "large"
|
|
||||||
// - ThumbnailKindTall ThumbnailKind = "tall"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ThumbnailStateDefault is the initial state for all thumbnails. Thumbnails in the "default" state will be considered stale,
|
|
||||||
// and thus refreshed by the crawler, if the dashboard version from the time of taking the thumbnail is different from the current dashboard version
|
|
||||||
ThumbnailStateDefault ThumbnailState = "default"
|
|
||||||
|
|
||||||
// ThumbnailStateStale is a manually assigned state. Thumbnails in the "stale" state will be refreshed on the next crawler run
|
|
||||||
ThumbnailStateStale ThumbnailState = "stale"
|
|
||||||
|
|
||||||
// ThumbnailStateLocked is a manually assigned state. Thumbnails in the "locked" state will not be refreshed by the crawler as long as they remain in the "locked" state.
|
|
||||||
ThumbnailStateLocked ThumbnailState = "locked"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s ThumbnailState) IsValid() bool {
|
|
||||||
return s == ThumbnailStateDefault || s == ThumbnailStateStale || s == ThumbnailStateLocked
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ThumbnailState) UnmarshalJSON(data []byte) error {
|
|
||||||
var str string
|
|
||||||
err := json.Unmarshal(data, &str)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*s = ThumbnailState(str)
|
|
||||||
|
|
||||||
if !s.IsValid() {
|
|
||||||
if (*s) != "" {
|
|
||||||
return fmt.Errorf("JSON validation error: invalid thumbnail state value: %s", *s)
|
|
||||||
}
|
|
||||||
|
|
||||||
*s = ThumbnailStateDefault
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsKnownThumbnailKind checks if the value is supported
|
|
||||||
func (p ThumbnailKind) IsKnownThumbnailKind() bool {
|
|
||||||
switch p {
|
|
||||||
case
|
|
||||||
ThumbnailKindDefault:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseThumbnailKind(str string) (ThumbnailKind, error) {
|
|
||||||
switch str {
|
|
||||||
case string(ThumbnailKindDefault):
|
|
||||||
return ThumbnailKindDefault, nil
|
|
||||||
}
|
|
||||||
return ThumbnailKindDefault, errors.New("unknown thumbnail kind " + str)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A DashboardThumbnail includes all metadata for a dashboard thumbnail
|
|
||||||
type DashboardThumbnail struct {
|
|
||||||
Id int64 `json:"id"`
|
|
||||||
DashboardId int64 `json:"dashboardId"`
|
|
||||||
DashboardVersion int `json:"dashboardVersion"`
|
|
||||||
State ThumbnailState `json:"state"`
|
|
||||||
PanelId int64 `json:"panelId,omitempty"`
|
|
||||||
Kind ThumbnailKind `json:"kind"`
|
|
||||||
Theme models.Theme `json:"theme"`
|
|
||||||
Image []byte `json:"image"`
|
|
||||||
MimeType string `json:"mimeType"`
|
|
||||||
Updated time.Time `json:"updated"`
|
|
||||||
DsUIDs string `json:"-" xorm:"ds_uids"`
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Commands
|
|
||||||
//
|
|
||||||
|
|
||||||
// DashboardThumbnailMeta uniquely identifies a thumbnail; a natural key
|
|
||||||
type DashboardThumbnailMeta struct {
|
|
||||||
DashboardUID string
|
|
||||||
OrgId int64
|
|
||||||
PanelID int64
|
|
||||||
Kind ThumbnailKind
|
|
||||||
Theme models.Theme
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetDashboardThumbnailCommand struct {
|
|
||||||
DashboardThumbnailMeta
|
|
||||||
|
|
||||||
Result *DashboardThumbnail
|
|
||||||
}
|
|
||||||
|
|
||||||
const DashboardVersionForManualThumbnailUpload = -1
|
|
||||||
|
|
||||||
type DashboardWithStaleThumbnail struct {
|
|
||||||
Id int64
|
|
||||||
OrgId int64
|
|
||||||
Uid string
|
|
||||||
Version int
|
|
||||||
Slug string
|
|
||||||
}
|
|
||||||
|
|
||||||
type FindDashboardThumbnailCountCommand struct {
|
|
||||||
Result int64
|
|
||||||
}
|
|
||||||
|
|
||||||
type FindDashboardsWithStaleThumbnailsCommand struct {
|
|
||||||
IncludeManuallyUploadedThumbnails bool
|
|
||||||
IncludeThumbnailsWithEmptyDsUIDs bool
|
|
||||||
Theme models.Theme
|
|
||||||
Kind ThumbnailKind
|
|
||||||
Result []*DashboardWithStaleThumbnail
|
|
||||||
}
|
|
||||||
|
|
||||||
type SaveDashboardThumbnailCommand struct {
|
|
||||||
DashboardThumbnailMeta
|
|
||||||
DashboardVersion int
|
|
||||||
Image []byte
|
|
||||||
MimeType string
|
|
||||||
DatasourceUIDs []string
|
|
||||||
|
|
||||||
Result *DashboardThumbnail
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateThumbnailStateCommand struct {
|
|
||||||
State ThumbnailState
|
|
||||||
DashboardThumbnailMeta
|
|
||||||
}
|
|
||||||
@@ -15,7 +15,6 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"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/live"
|
||||||
"github.com/grafana/grafana/pkg/services/rendering"
|
"github.com/grafana/grafana/pkg/services/rendering"
|
||||||
)
|
)
|
||||||
@@ -29,12 +28,12 @@ type simpleCrawler struct {
|
|||||||
glive *live.GrafanaLive
|
glive *live.GrafanaLive
|
||||||
thumbnailRepo thumbnailRepo
|
thumbnailRepo thumbnailRepo
|
||||||
mode CrawlerMode
|
mode CrawlerMode
|
||||||
thumbnailKind dashboardthumbs.ThumbnailKind
|
thumbnailKind ThumbnailKind
|
||||||
auth CrawlerAuth
|
auth CrawlerAuth
|
||||||
opts rendering.Opts
|
opts rendering.Opts
|
||||||
status crawlStatus
|
status crawlStatus
|
||||||
statusMutex sync.RWMutex
|
statusMutex sync.RWMutex
|
||||||
queue []*dashboardthumbs.DashboardWithStaleThumbnail
|
queue []*DashboardWithStaleThumbnail
|
||||||
queueMutex sync.Mutex
|
queueMutex sync.Mutex
|
||||||
log log.Logger
|
log log.Logger
|
||||||
renderingSessionByOrgId map[int64]rendering.Session
|
renderingSessionByOrgId map[int64]rendering.Session
|
||||||
@@ -65,7 +64,7 @@ func newSimpleCrawler(renderService rendering.Service, gl *live.GrafanaLive, rep
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *simpleCrawler) next(ctx context.Context) (*dashboardthumbs.DashboardWithStaleThumbnail, rendering.Session, rendering.AuthOpts, error) {
|
func (r *simpleCrawler) next(ctx context.Context) (*DashboardWithStaleThumbnail, rendering.Session, rendering.AuthOpts, error) {
|
||||||
r.queueMutex.Lock()
|
r.queueMutex.Lock()
|
||||||
defer r.queueMutex.Unlock()
|
defer r.queueMutex.Unlock()
|
||||||
|
|
||||||
@@ -117,13 +116,13 @@ func (r *simpleCrawler) broadcastStatus() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type byOrgId []*dashboardthumbs.DashboardWithStaleThumbnail
|
type byOrgId []*DashboardWithStaleThumbnail
|
||||||
|
|
||||||
func (d byOrgId) Len() int { return len(d) }
|
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) 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 (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 dashboardthumbs.ThumbnailKind) error {
|
func (r *simpleCrawler) Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, thumbnailKind ThumbnailKind) error {
|
||||||
res, err := r.renderService.HasCapability(ctx, rendering.ScalingDownImages)
|
res, err := r.renderService.HasCapability(ctx, rendering.ScalingDownImages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -326,7 +325,7 @@ func (r *simpleCrawler) walk(ctx context.Context, id int) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
thumbnailId, err := r.thumbnailRepo.saveFromFile(ctx, res.FilePath, dashboardthumbs.DashboardThumbnailMeta{
|
thumbnailId, err := r.thumbnailRepo.saveFromFile(ctx, res.FilePath, DashboardThumbnailMeta{
|
||||||
DashboardUID: item.Uid,
|
DashboardUID: item.Uid,
|
||||||
OrgId: item.OrgId,
|
OrgId: item.OrgId,
|
||||||
Theme: r.opts.Theme,
|
Theme: r.opts.Theme,
|
||||||
|
|||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
package dashboardthumbs
|
package thumbs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service interface {
|
type DashboardThumbService interface {
|
||||||
GetThumbnail(ctx context.Context, query *GetDashboardThumbnailCommand) (*DashboardThumbnail, error)
|
GetThumbnail(ctx context.Context, query *GetDashboardThumbnailCommand) (*DashboardThumbnail, error)
|
||||||
SaveThumbnail(ctx context.Context, cmd *SaveDashboardThumbnailCommand) (*DashboardThumbnail, error)
|
SaveThumbnail(ctx context.Context, cmd *SaveDashboardThumbnailCommand) (*DashboardThumbnail, error)
|
||||||
UpdateThumbnailState(ctx context.Context, cmd *UpdateThumbnailStateCommand) error
|
UpdateThumbnailState(ctx context.Context, cmd *UpdateThumbnailStateCommand) error
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package dashboardthumbsimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/sqlstore/db"
|
||||||
|
"github.com/grafana/grafana/pkg/services/thumbs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
store store
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProvideService(db db.DB) thumbs.DashboardThumbService {
|
||||||
|
return &Service{
|
||||||
|
store: &xormStore{db: db},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetThumbnail(ctx context.Context, query *thumbs.GetDashboardThumbnailCommand) (*thumbs.DashboardThumbnail, error) {
|
||||||
|
dt, err := s.store.Get(ctx, query)
|
||||||
|
return dt, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) SaveThumbnail(ctx context.Context, cmd *thumbs.SaveDashboardThumbnailCommand) (*thumbs.DashboardThumbnail, error) {
|
||||||
|
dt, err := s.store.Save(ctx, cmd)
|
||||||
|
return dt, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) UpdateThumbnailState(ctx context.Context, cmd *thumbs.UpdateThumbnailStateCommand) error {
|
||||||
|
err := s.store.UpdateState(ctx, cmd)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) FindThumbnailCount(ctx context.Context, cmd *thumbs.FindDashboardThumbnailCountCommand) (int64, error) {
|
||||||
|
n, err := s.store.Count(ctx, cmd)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *thumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*thumbs.DashboardWithStaleThumbnail, error) {
|
||||||
|
thumbs, err := s.store.FindDashboardsWithStaleThumbnails(ctx, cmd)
|
||||||
|
return thumbs, err
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package dashboardthumbsimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/thumbs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type store interface {
|
||||||
|
Get(ctx context.Context, query *thumbs.GetDashboardThumbnailCommand) (*thumbs.DashboardThumbnail, error)
|
||||||
|
Save(ctx context.Context, cmd *thumbs.SaveDashboardThumbnailCommand) (*thumbs.DashboardThumbnail, error)
|
||||||
|
UpdateState(ctx context.Context, cmd *thumbs.UpdateThumbnailStateCommand) error
|
||||||
|
Count(ctx context.Context, cmd *thumbs.FindDashboardThumbnailCountCommand) (int64, error)
|
||||||
|
FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *thumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*thumbs.DashboardWithStaleThumbnail, error)
|
||||||
|
}
|
||||||
+27
-27
@@ -7,16 +7,16 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs"
|
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
|
"github.com/grafana/grafana/pkg/services/thumbs"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
var theme = models.ThemeDark
|
var theme = models.ThemeDark
|
||||||
var kind = dashboardthumbs.ThumbnailKindDefault
|
var kind = thumbs.ThumbnailKindDefault
|
||||||
|
|
||||||
func TestIntegrationSqlStorage(t *testing.T) {
|
func TestIntegrationSqlStorage(t *testing.T) {
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
@@ -39,7 +39,7 @@ func TestIntegrationSqlStorage(t *testing.T) {
|
|||||||
thumb := getThumbnail(t, store, dash.Uid, dash.OrgId)
|
thumb := getThumbnail(t, store, dash.Uid, dash.OrgId)
|
||||||
|
|
||||||
require.Positive(t, thumb.Id)
|
require.Positive(t, thumb.Id)
|
||||||
require.Equal(t, dashboardthumbs.ThumbnailStateDefault, thumb.State)
|
require.Equal(t, thumbs.ThumbnailStateDefault, thumb.State)
|
||||||
require.Equal(t, dash.Version, thumb.DashboardVersion)
|
require.Equal(t, dash.Version, thumb.DashboardVersion)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ func TestIntegrationSqlStorage(t *testing.T) {
|
|||||||
|
|
||||||
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version)
|
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version)
|
||||||
|
|
||||||
cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{
|
cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ func TestIntegrationSqlStorage(t *testing.T) {
|
|||||||
|
|
||||||
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version)
|
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version)
|
||||||
|
|
||||||
cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{
|
cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
IncludeThumbnailsWithEmptyDsUIDs: true,
|
IncludeThumbnailsWithEmptyDsUIDs: true,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
@@ -93,9 +93,9 @@ func TestIntegrationSqlStorage(t *testing.T) {
|
|||||||
setup()
|
setup()
|
||||||
dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
||||||
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version)
|
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version)
|
||||||
updateThumbnailState(t, store, dash.Uid, dash.OrgId, dashboardthumbs.ThumbnailStateStale)
|
updateThumbnailState(t, store, dash.Uid, dash.OrgId, thumbs.ThumbnailStateStale)
|
||||||
|
|
||||||
cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{
|
cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
}
|
}
|
||||||
@@ -109,10 +109,10 @@ func TestIntegrationSqlStorage(t *testing.T) {
|
|||||||
setup()
|
setup()
|
||||||
dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
||||||
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version)
|
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version)
|
||||||
updateThumbnailState(t, store, dash.Uid, dash.OrgId, dashboardthumbs.ThumbnailStateStale)
|
updateThumbnailState(t, store, dash.Uid, dash.OrgId, thumbs.ThumbnailStateStale)
|
||||||
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version)
|
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version)
|
||||||
|
|
||||||
cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{
|
cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ func TestIntegrationSqlStorage(t *testing.T) {
|
|||||||
setup()
|
setup()
|
||||||
dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
||||||
|
|
||||||
cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{
|
cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ func TestIntegrationSqlStorage(t *testing.T) {
|
|||||||
"tags": "different-tag",
|
"tags": "different-tag",
|
||||||
})
|
})
|
||||||
|
|
||||||
cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{
|
cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
}
|
}
|
||||||
@@ -158,13 +158,13 @@ func TestIntegrationSqlStorage(t *testing.T) {
|
|||||||
setup()
|
setup()
|
||||||
dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
||||||
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version)
|
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dash.Version)
|
||||||
updateThumbnailState(t, store, dash.Uid, dash.OrgId, dashboardthumbs.ThumbnailStateLocked)
|
updateThumbnailState(t, store, dash.Uid, dash.OrgId, thumbs.ThumbnailStateLocked)
|
||||||
|
|
||||||
updateTestDashboard(t, sqlStore, dash, map[string]interface{}{
|
updateTestDashboard(t, sqlStore, dash, map[string]interface{}{
|
||||||
"tags": "different-tag",
|
"tags": "different-tag",
|
||||||
})
|
})
|
||||||
|
|
||||||
cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{
|
cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
}
|
}
|
||||||
@@ -176,13 +176,13 @@ func TestIntegrationSqlStorage(t *testing.T) {
|
|||||||
t.Run("Should not return dashboards with manually uploaded thumbnails by default", func(t *testing.T) {
|
t.Run("Should not return dashboards with manually uploaded thumbnails by default", func(t *testing.T) {
|
||||||
setup()
|
setup()
|
||||||
dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
||||||
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dashboardthumbs.DashboardVersionForManualThumbnailUpload)
|
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, thumbs.DashboardVersionForManualThumbnailUpload)
|
||||||
|
|
||||||
updateTestDashboard(t, sqlStore, dash, map[string]interface{}{
|
updateTestDashboard(t, sqlStore, dash, map[string]interface{}{
|
||||||
"tags": "different-tag",
|
"tags": "different-tag",
|
||||||
})
|
})
|
||||||
|
|
||||||
cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{
|
cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
}
|
}
|
||||||
@@ -194,13 +194,13 @@ func TestIntegrationSqlStorage(t *testing.T) {
|
|||||||
t.Run("Should return dashboards with manually uploaded thumbnails if requested", func(t *testing.T) {
|
t.Run("Should return dashboards with manually uploaded thumbnails if requested", func(t *testing.T) {
|
||||||
setup()
|
setup()
|
||||||
dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
dash := insertTestDashboard(t, sqlStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")
|
||||||
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, dashboardthumbs.DashboardVersionForManualThumbnailUpload)
|
upsertTestDashboardThumbnail(t, store, dash.Uid, dash.OrgId, thumbs.DashboardVersionForManualThumbnailUpload)
|
||||||
|
|
||||||
updateTestDashboard(t, sqlStore, dash, map[string]interface{}{
|
updateTestDashboard(t, sqlStore, dash, map[string]interface{}{
|
||||||
"tags": "different-tag",
|
"tags": "different-tag",
|
||||||
})
|
})
|
||||||
|
|
||||||
cmd := dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{
|
cmd := thumbs.FindDashboardsWithStaleThumbnailsCommand{
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
IncludeManuallyUploadedThumbnails: true,
|
IncludeManuallyUploadedThumbnails: true,
|
||||||
@@ -222,17 +222,17 @@ func TestIntegrationSqlStorage(t *testing.T) {
|
|||||||
"tags": "different-tag",
|
"tags": "different-tag",
|
||||||
})
|
})
|
||||||
|
|
||||||
cmd := dashboardthumbs.FindDashboardThumbnailCountCommand{}
|
cmd := thumbs.FindDashboardThumbnailCountCommand{}
|
||||||
res, err := store.Count(context.Background(), &cmd)
|
res, err := store.Count(context.Background(), &cmd)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, res, int64(2))
|
require.Equal(t, res, int64(2))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func getThumbnail(t *testing.T, store store, dashboardUID string, orgId int64) *dashboardthumbs.DashboardThumbnail {
|
func getThumbnail(t *testing.T, store store, dashboardUID string, orgId int64) *thumbs.DashboardThumbnail {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
cmd := dashboardthumbs.GetDashboardThumbnailCommand{
|
cmd := thumbs.GetDashboardThumbnailCommand{
|
||||||
DashboardThumbnailMeta: dashboardthumbs.DashboardThumbnailMeta{
|
DashboardThumbnailMeta: thumbs.DashboardThumbnailMeta{
|
||||||
DashboardUID: dashboardUID,
|
DashboardUID: dashboardUID,
|
||||||
OrgId: orgId,
|
OrgId: orgId,
|
||||||
PanelID: 0,
|
PanelID: 0,
|
||||||
@@ -246,10 +246,10 @@ func getThumbnail(t *testing.T, store store, dashboardUID string, orgId int64) *
|
|||||||
return thumb
|
return thumb
|
||||||
}
|
}
|
||||||
|
|
||||||
func upsertTestDashboardThumbnail(t *testing.T, store store, dashboardUID string, orgId int64, dashboardVersion int) *dashboardthumbs.DashboardThumbnail {
|
func upsertTestDashboardThumbnail(t *testing.T, store store, dashboardUID string, orgId int64, dashboardVersion int) *thumbs.DashboardThumbnail {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
cmd := dashboardthumbs.SaveDashboardThumbnailCommand{
|
cmd := thumbs.SaveDashboardThumbnailCommand{
|
||||||
DashboardThumbnailMeta: dashboardthumbs.DashboardThumbnailMeta{
|
DashboardThumbnailMeta: thumbs.DashboardThumbnailMeta{
|
||||||
DashboardUID: dashboardUID,
|
DashboardUID: dashboardUID,
|
||||||
OrgId: orgId,
|
OrgId: orgId,
|
||||||
PanelID: 0,
|
PanelID: 0,
|
||||||
@@ -267,10 +267,10 @@ func upsertTestDashboardThumbnail(t *testing.T, store store, dashboardUID string
|
|||||||
return dash
|
return dash
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateThumbnailState(t *testing.T, store store, dashboardUID string, orgId int64, state dashboardthumbs.ThumbnailState) {
|
func updateThumbnailState(t *testing.T, store store, dashboardUID string, orgId int64, state thumbs.ThumbnailState) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
cmd := dashboardthumbs.UpdateThumbnailStateCommand{
|
cmd := thumbs.UpdateThumbnailStateCommand{
|
||||||
DashboardThumbnailMeta: dashboardthumbs.DashboardThumbnailMeta{
|
DashboardThumbnailMeta: thumbs.DashboardThumbnailMeta{
|
||||||
DashboardUID: dashboardUID,
|
DashboardUID: dashboardUID,
|
||||||
OrgId: orgId,
|
OrgId: orgId,
|
||||||
PanelID: 0,
|
PanelID: 0,
|
||||||
+17
-17
@@ -6,17 +6,17 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs"
|
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
"github.com/grafana/grafana/pkg/services/sqlstore/db"
|
"github.com/grafana/grafana/pkg/services/sqlstore/db"
|
||||||
|
"github.com/grafana/grafana/pkg/services/thumbs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type xormStore struct {
|
type xormStore struct {
|
||||||
db db.DB
|
db db.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *xormStore) Get(ctx context.Context, query *dashboardthumbs.GetDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) {
|
func (ss *xormStore) Get(ctx context.Context, query *thumbs.GetDashboardThumbnailCommand) (*thumbs.DashboardThumbnail, error) {
|
||||||
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
result, err := findThumbnailByMeta(sess, query.DashboardThumbnailMeta)
|
result, err := findThumbnailByMeta(sess, query.DashboardThumbnailMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -41,7 +41,7 @@ func marshalDatasourceUids(dsUids []string) (string, error) {
|
|||||||
return string(b), nil
|
return string(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *xormStore) Save(ctx context.Context, cmd *dashboardthumbs.SaveDashboardThumbnailCommand) (*dashboardthumbs.DashboardThumbnail, error) {
|
func (ss *xormStore) Save(ctx context.Context, cmd *thumbs.SaveDashboardThumbnailCommand) (*thumbs.DashboardThumbnail, error) {
|
||||||
err := ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
err := ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
existing, err := findThumbnailByMeta(sess, cmd.DashboardThumbnailMeta)
|
existing, err := findThumbnailByMeta(sess, cmd.DashboardThumbnailMeta)
|
||||||
|
|
||||||
@@ -60,13 +60,13 @@ func (ss *xormStore) Save(ctx context.Context, cmd *dashboardthumbs.SaveDashboar
|
|||||||
existing.Updated = time.Now()
|
existing.Updated = time.Now()
|
||||||
existing.DashboardVersion = cmd.DashboardVersion
|
existing.DashboardVersion = cmd.DashboardVersion
|
||||||
existing.DsUIDs = dsUids
|
existing.DsUIDs = dsUids
|
||||||
existing.State = dashboardthumbs.ThumbnailStateDefault
|
existing.State = thumbs.ThumbnailStateDefault
|
||||||
_, err = sess.ID(existing.Id).Update(existing)
|
_, err = sess.ID(existing.Id).Update(existing)
|
||||||
cmd.Result = existing
|
cmd.Result = existing
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
thumb := &dashboardthumbs.DashboardThumbnail{}
|
thumb := &thumbs.DashboardThumbnail{}
|
||||||
|
|
||||||
dash, err := findDashboardIdByThumbMeta(sess, cmd.DashboardThumbnailMeta)
|
dash, err := findDashboardIdByThumbMeta(sess, cmd.DashboardThumbnailMeta)
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ func (ss *xormStore) Save(ctx context.Context, cmd *dashboardthumbs.SaveDashboar
|
|||||||
thumb.MimeType = cmd.MimeType
|
thumb.MimeType = cmd.MimeType
|
||||||
thumb.DashboardId = dash.Id
|
thumb.DashboardId = dash.Id
|
||||||
thumb.DashboardVersion = cmd.DashboardVersion
|
thumb.DashboardVersion = cmd.DashboardVersion
|
||||||
thumb.State = dashboardthumbs.ThumbnailStateDefault
|
thumb.State = thumbs.ThumbnailStateDefault
|
||||||
thumb.PanelId = cmd.PanelID
|
thumb.PanelId = cmd.PanelID
|
||||||
_, err = sess.Insert(thumb)
|
_, err = sess.Insert(thumb)
|
||||||
cmd.Result = thumb
|
cmd.Result = thumb
|
||||||
@@ -92,7 +92,7 @@ func (ss *xormStore) Save(ctx context.Context, cmd *dashboardthumbs.SaveDashboar
|
|||||||
return cmd.Result, err
|
return cmd.Result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *xormStore) UpdateState(ctx context.Context, cmd *dashboardthumbs.UpdateThumbnailStateCommand) error {
|
func (ss *xormStore) UpdateState(ctx context.Context, cmd *thumbs.UpdateThumbnailStateCommand) error {
|
||||||
err := ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
err := ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
existing, err := findThumbnailByMeta(sess, cmd.DashboardThumbnailMeta)
|
existing, err := findThumbnailByMeta(sess, cmd.DashboardThumbnailMeta)
|
||||||
|
|
||||||
@@ -108,9 +108,9 @@ func (ss *xormStore) UpdateState(ctx context.Context, cmd *dashboardthumbs.Updat
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *xormStore) Count(ctx context.Context, cmd *dashboardthumbs.FindDashboardThumbnailCountCommand) (int64, error) {
|
func (ss *xormStore) Count(ctx context.Context, cmd *thumbs.FindDashboardThumbnailCountCommand) (int64, error) {
|
||||||
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
count, err := sess.Count(&dashboardthumbs.DashboardThumbnail{})
|
count, err := sess.Count(&thumbs.DashboardThumbnail{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ func (ss *xormStore) Count(ctx context.Context, cmd *dashboardthumbs.FindDashboa
|
|||||||
return cmd.Result, err
|
return cmd.Result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) {
|
func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd *thumbs.FindDashboardsWithStaleThumbnailsCommand) ([]*thumbs.DashboardWithStaleThumbnail, error) {
|
||||||
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||||
sess.Table("dashboard")
|
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.Join("LEFT", "dashboard_thumbnail", "dashboard.id = dashboard_thumbnail.dashboard_id AND dashboard_thumbnail.theme = ? AND dashboard_thumbnail.kind = ?", cmd.Theme, cmd.Kind)
|
||||||
@@ -131,7 +131,7 @@ func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd
|
|||||||
query := "(dashboard.version != dashboard_thumbnail.dashboard_version " +
|
query := "(dashboard.version != dashboard_thumbnail.dashboard_version " +
|
||||||
"OR dashboard_thumbnail.state = ? " +
|
"OR dashboard_thumbnail.state = ? " +
|
||||||
"OR dashboard_thumbnail.id IS NULL"
|
"OR dashboard_thumbnail.id IS NULL"
|
||||||
args := []interface{}{dashboardthumbs.ThumbnailStateStale}
|
args := []interface{}{thumbs.ThumbnailStateStale}
|
||||||
|
|
||||||
if cmd.IncludeThumbnailsWithEmptyDsUIDs {
|
if cmd.IncludeThumbnailsWithEmptyDsUIDs {
|
||||||
query += " OR dashboard_thumbnail.ds_uids = ? OR dashboard_thumbnail.ds_uids IS NULL"
|
query += " OR dashboard_thumbnail.ds_uids = ? OR dashboard_thumbnail.ds_uids IS NULL"
|
||||||
@@ -142,10 +142,10 @@ func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd
|
|||||||
if !cmd.IncludeManuallyUploadedThumbnails {
|
if !cmd.IncludeManuallyUploadedThumbnails {
|
||||||
sess.Where("(dashboard_thumbnail.id is not null AND dashboard_thumbnail.dashboard_version != ?) "+
|
sess.Where("(dashboard_thumbnail.id is not null AND dashboard_thumbnail.dashboard_version != ?) "+
|
||||||
"OR dashboard_thumbnail.id is null "+
|
"OR dashboard_thumbnail.id is null "+
|
||||||
"OR dashboard_thumbnail.state = ?", dashboardthumbs.DashboardVersionForManualThumbnailUpload, dashboardthumbs.ThumbnailStateStale)
|
"OR dashboard_thumbnail.state = ?", thumbs.DashboardVersionForManualThumbnailUpload, thumbs.ThumbnailStateStale)
|
||||||
}
|
}
|
||||||
|
|
||||||
sess.Where("(dashboard_thumbnail.id IS NULL OR dashboard_thumbnail.state != ?)", dashboardthumbs.ThumbnailStateLocked)
|
sess.Where("(dashboard_thumbnail.id IS NULL OR dashboard_thumbnail.state != ?)", thumbs.ThumbnailStateLocked)
|
||||||
|
|
||||||
sess.Cols("dashboard.id",
|
sess.Cols("dashboard.id",
|
||||||
"dashboard.uid",
|
"dashboard.uid",
|
||||||
@@ -153,7 +153,7 @@ func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd
|
|||||||
"dashboard.version",
|
"dashboard.version",
|
||||||
"dashboard.slug")
|
"dashboard.slug")
|
||||||
|
|
||||||
var result = make([]*dashboardthumbs.DashboardWithStaleThumbnail, 0)
|
var result = make([]*thumbs.DashboardWithStaleThumbnail, 0)
|
||||||
err := sess.Find(&result)
|
err := sess.Find(&result)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -166,8 +166,8 @@ func (ss *xormStore) FindDashboardsWithStaleThumbnails(ctx context.Context, cmd
|
|||||||
return cmd.Result, err
|
return cmd.Result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func findThumbnailByMeta(sess *sqlstore.DBSession, meta dashboardthumbs.DashboardThumbnailMeta) (*dashboardthumbs.DashboardThumbnail, error) {
|
func findThumbnailByMeta(sess *sqlstore.DBSession, meta thumbs.DashboardThumbnailMeta) (*thumbs.DashboardThumbnail, error) {
|
||||||
result := &dashboardthumbs.DashboardThumbnail{}
|
result := &thumbs.DashboardThumbnail{}
|
||||||
|
|
||||||
sess.Table("dashboard_thumbnail")
|
sess.Table("dashboard_thumbnail")
|
||||||
sess.Join("INNER", "dashboard", "dashboard.id = dashboard_thumbnail.dashboard_id")
|
sess.Join("INNER", "dashboard", "dashboard.id = dashboard_thumbnail.dashboard_id")
|
||||||
@@ -200,7 +200,7 @@ type dash struct {
|
|||||||
Id int64
|
Id int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func findDashboardIdByThumbMeta(sess *sqlstore.DBSession, meta dashboardthumbs.DashboardThumbnailMeta) (*dash, error) {
|
func findDashboardIdByThumbMeta(sess *sqlstore.DBSession, meta thumbs.DashboardThumbnailMeta) (*dash, error) {
|
||||||
result := &dash{}
|
result := &dash{}
|
||||||
|
|
||||||
sess.Table("dashboard").Where("dashboard.uid = ? AND dashboard.org_id = ?", meta.DashboardUID, meta.OrgId).Cols("id")
|
sess.Table("dashboard").Where("dashboard.uid = ? AND dashboard.org_id = ?", meta.DashboardUID, meta.OrgId).Cols("id")
|
||||||
+150
-11
@@ -2,10 +2,12 @@ package thumbs
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type CrawlerMode string
|
type CrawlerMode string
|
||||||
@@ -32,10 +34,10 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type previewRequest struct {
|
type previewRequest struct {
|
||||||
OrgID int64 `json:"orgId"`
|
OrgID int64 `json:"orgId"`
|
||||||
UID string `json:"uid"`
|
UID string `json:"uid"`
|
||||||
Kind dashboardthumbs.ThumbnailKind `json:"kind"`
|
Kind ThumbnailKind `json:"kind"`
|
||||||
Theme models.Theme `json:"theme"`
|
Theme models.Theme `json:"theme"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type crawlCmd struct {
|
type crawlCmd struct {
|
||||||
@@ -63,10 +65,147 @@ type dashboardPreviewsSetupConfig struct {
|
|||||||
ThumbnailsExist bool `json:"thumbnailsExist"`
|
ThumbnailsExist bool `json:"thumbnailsExist"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ThumbnailKind string
|
||||||
|
type ThumbnailState string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ThumbnailKindDefault is a small 320x240 preview
|
||||||
|
ThumbnailKindDefault ThumbnailKind = "thumb"
|
||||||
|
|
||||||
|
// unsupported for now
|
||||||
|
// - ThumbnailKindLarge ThumbnailKind = "large"
|
||||||
|
// - ThumbnailKindTall ThumbnailKind = "tall"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ThumbnailStateDefault is the initial state for all thumbnails. Thumbnails in the "default" state will be considered stale,
|
||||||
|
// and thus refreshed by the crawler, if the dashboard version from the time of taking the thumbnail is different from the current dashboard version
|
||||||
|
ThumbnailStateDefault ThumbnailState = "default"
|
||||||
|
|
||||||
|
// ThumbnailStateStale is a manually assigned state. Thumbnails in the "stale" state will be refreshed on the next crawler run
|
||||||
|
ThumbnailStateStale ThumbnailState = "stale"
|
||||||
|
|
||||||
|
// ThumbnailStateLocked is a manually assigned state. Thumbnails in the "locked" state will not be refreshed by the crawler as long as they remain in the "locked" state.
|
||||||
|
ThumbnailStateLocked ThumbnailState = "locked"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s ThumbnailState) IsValid() bool {
|
||||||
|
return s == ThumbnailStateDefault || s == ThumbnailStateStale || s == ThumbnailStateLocked
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ThumbnailState) UnmarshalJSON(data []byte) error {
|
||||||
|
var str string
|
||||||
|
err := json.Unmarshal(data, &str)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*s = ThumbnailState(str)
|
||||||
|
|
||||||
|
if !s.IsValid() {
|
||||||
|
if (*s) != "" {
|
||||||
|
return fmt.Errorf("JSON validation error: invalid thumbnail state value: %s", *s)
|
||||||
|
}
|
||||||
|
|
||||||
|
*s = ThumbnailStateDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsKnownThumbnailKind checks if the value is supported
|
||||||
|
func (p ThumbnailKind) IsKnownThumbnailKind() bool {
|
||||||
|
switch p {
|
||||||
|
case
|
||||||
|
ThumbnailKindDefault:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseThumbnailKind(str string) (ThumbnailKind, error) {
|
||||||
|
switch str {
|
||||||
|
case string(ThumbnailKindDefault):
|
||||||
|
return ThumbnailKindDefault, nil
|
||||||
|
}
|
||||||
|
return ThumbnailKindDefault, errors.New("unknown thumbnail kind " + str)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A DashboardThumbnail includes all metadata for a dashboard thumbnail
|
||||||
|
type DashboardThumbnail struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
DashboardId int64 `json:"dashboardId"`
|
||||||
|
DashboardVersion int `json:"dashboardVersion"`
|
||||||
|
State ThumbnailState `json:"state"`
|
||||||
|
PanelId int64 `json:"panelId,omitempty"`
|
||||||
|
Kind ThumbnailKind `json:"kind"`
|
||||||
|
Theme models.Theme `json:"theme"`
|
||||||
|
Image []byte `json:"image"`
|
||||||
|
MimeType string `json:"mimeType"`
|
||||||
|
Updated time.Time `json:"updated"`
|
||||||
|
DsUIDs string `json:"-" xorm:"ds_uids"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Commands
|
||||||
|
//
|
||||||
|
|
||||||
|
// DashboardThumbnailMeta uniquely identifies a thumbnail; a natural key
|
||||||
|
type DashboardThumbnailMeta struct {
|
||||||
|
DashboardUID string
|
||||||
|
OrgId int64
|
||||||
|
PanelID int64
|
||||||
|
Kind ThumbnailKind
|
||||||
|
Theme models.Theme
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetDashboardThumbnailCommand struct {
|
||||||
|
DashboardThumbnailMeta
|
||||||
|
|
||||||
|
Result *DashboardThumbnail
|
||||||
|
}
|
||||||
|
|
||||||
|
const DashboardVersionForManualThumbnailUpload = -1
|
||||||
|
|
||||||
|
type DashboardWithStaleThumbnail struct {
|
||||||
|
Id int64
|
||||||
|
OrgId int64
|
||||||
|
Uid string
|
||||||
|
Version int
|
||||||
|
Slug string
|
||||||
|
}
|
||||||
|
|
||||||
|
type FindDashboardThumbnailCountCommand struct {
|
||||||
|
Result int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type FindDashboardsWithStaleThumbnailsCommand struct {
|
||||||
|
IncludeManuallyUploadedThumbnails bool
|
||||||
|
IncludeThumbnailsWithEmptyDsUIDs bool
|
||||||
|
Theme models.Theme
|
||||||
|
Kind ThumbnailKind
|
||||||
|
Result []*DashboardWithStaleThumbnail
|
||||||
|
}
|
||||||
|
|
||||||
|
type SaveDashboardThumbnailCommand struct {
|
||||||
|
DashboardThumbnailMeta
|
||||||
|
DashboardVersion int
|
||||||
|
Image []byte
|
||||||
|
MimeType string
|
||||||
|
DatasourceUIDs []string
|
||||||
|
|
||||||
|
Result *DashboardThumbnail
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateThumbnailStateCommand struct {
|
||||||
|
State ThumbnailState
|
||||||
|
DashboardThumbnailMeta
|
||||||
|
}
|
||||||
|
|
||||||
type dashRenderer interface {
|
type dashRenderer interface {
|
||||||
|
|
||||||
// Run Assumes you have already authenticated as admin.
|
// Run Assumes you have already authenticated as admin.
|
||||||
Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, kind dashboardthumbs.ThumbnailKind) error
|
Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, kind ThumbnailKind) error
|
||||||
|
|
||||||
// Assumes you have already authenticated as admin.
|
// Assumes you have already authenticated as admin.
|
||||||
Stop() (crawlStatus, error)
|
Stop() (crawlStatus, error)
|
||||||
@@ -78,10 +217,10 @@ type dashRenderer interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type thumbnailRepo interface {
|
type thumbnailRepo interface {
|
||||||
updateThumbnailState(ctx context.Context, state dashboardthumbs.ThumbnailState, meta dashboardthumbs.DashboardThumbnailMeta) error
|
updateThumbnailState(ctx context.Context, state ThumbnailState, meta DashboardThumbnailMeta) error
|
||||||
doThumbnailsExist(ctx context.Context) (bool, error)
|
doThumbnailsExist(ctx context.Context) (bool, error)
|
||||||
saveFromFile(ctx context.Context, filePath string, meta dashboardthumbs.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error)
|
saveFromFile(ctx context.Context, filePath string, meta DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error)
|
||||||
saveFromBytes(ctx context.Context, bytes []byte, mimeType string, meta dashboardthumbs.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error)
|
saveFromBytes(ctx context.Context, bytes []byte, mimeType string, meta DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error)
|
||||||
getThumbnail(ctx context.Context, meta dashboardthumbs.DashboardThumbnailMeta) (*dashboardthumbs.DashboardThumbnail, error)
|
getThumbnail(ctx context.Context, meta DashboardThumbnailMeta) (*DashboardThumbnail, error)
|
||||||
findDashboardsWithStaleThumbnails(ctx context.Context, theme models.Theme, thumbnailKind dashboardthumbs.ThumbnailKind) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error)
|
findDashboardsWithStaleThumbnails(ctx context.Context, theme models.Theme, thumbnailKind ThumbnailKind) ([]*DashboardWithStaleThumbnail, error)
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-13
@@ -9,11 +9,10 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs"
|
|
||||||
"github.com/grafana/grafana/pkg/services/searchV2"
|
"github.com/grafana/grafana/pkg/services/searchV2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newThumbnailRepo(thumbsService dashboardthumbs.Service, search searchV2.SearchService) thumbnailRepo {
|
func newThumbnailRepo(thumbsService DashboardThumbService, search searchV2.SearchService) thumbnailRepo {
|
||||||
repo := &sqlThumbnailRepository{
|
repo := &sqlThumbnailRepository{
|
||||||
store: thumbsService,
|
store: thumbsService,
|
||||||
search: search,
|
search: search,
|
||||||
@@ -23,12 +22,12 @@ func newThumbnailRepo(thumbsService dashboardthumbs.Service, search searchV2.Sea
|
|||||||
}
|
}
|
||||||
|
|
||||||
type sqlThumbnailRepository struct {
|
type sqlThumbnailRepository struct {
|
||||||
store dashboardthumbs.Service
|
store DashboardThumbService
|
||||||
search searchV2.SearchService
|
search searchV2.SearchService
|
||||||
log log.Logger
|
log log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *sqlThumbnailRepository) saveFromFile(ctx context.Context, filePath string, meta dashboardthumbs.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) {
|
func (r *sqlThumbnailRepository) saveFromFile(ctx context.Context, filePath string, meta 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
|
// 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
|
// 1. thumbs/service.go, when user uploads a thumbnail
|
||||||
// 2. the rendering service, when image-renderer returns a screenshot
|
// 2. the rendering service, when image-renderer returns a screenshot
|
||||||
@@ -56,8 +55,8 @@ func getMimeType(filePath string) string {
|
|||||||
return "image/png"
|
return "image/png"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *sqlThumbnailRepository) saveFromBytes(ctx context.Context, content []byte, mimeType string, meta dashboardthumbs.DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) {
|
func (r *sqlThumbnailRepository) saveFromBytes(ctx context.Context, content []byte, mimeType string, meta DashboardThumbnailMeta, dashboardVersion int, dsUids []string) (int64, error) {
|
||||||
cmd := &dashboardthumbs.SaveDashboardThumbnailCommand{
|
cmd := &SaveDashboardThumbnailCommand{
|
||||||
DashboardThumbnailMeta: meta,
|
DashboardThumbnailMeta: meta,
|
||||||
Image: content,
|
Image: content,
|
||||||
MimeType: mimeType,
|
MimeType: mimeType,
|
||||||
@@ -74,22 +73,22 @@ func (r *sqlThumbnailRepository) saveFromBytes(ctx context.Context, content []by
|
|||||||
return cmd.Result.Id, nil
|
return cmd.Result.Id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *sqlThumbnailRepository) updateThumbnailState(ctx context.Context, state dashboardthumbs.ThumbnailState, meta dashboardthumbs.DashboardThumbnailMeta) error {
|
func (r *sqlThumbnailRepository) updateThumbnailState(ctx context.Context, state ThumbnailState, meta DashboardThumbnailMeta) error {
|
||||||
return r.store.UpdateThumbnailState(ctx, &dashboardthumbs.UpdateThumbnailStateCommand{
|
return r.store.UpdateThumbnailState(ctx, &UpdateThumbnailStateCommand{
|
||||||
State: state,
|
State: state,
|
||||||
DashboardThumbnailMeta: meta,
|
DashboardThumbnailMeta: meta,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *sqlThumbnailRepository) getThumbnail(ctx context.Context, meta dashboardthumbs.DashboardThumbnailMeta) (*dashboardthumbs.DashboardThumbnail, error) {
|
func (r *sqlThumbnailRepository) getThumbnail(ctx context.Context, meta DashboardThumbnailMeta) (*DashboardThumbnail, error) {
|
||||||
query := &dashboardthumbs.GetDashboardThumbnailCommand{
|
query := &GetDashboardThumbnailCommand{
|
||||||
DashboardThumbnailMeta: meta,
|
DashboardThumbnailMeta: meta,
|
||||||
}
|
}
|
||||||
return r.store.GetThumbnail(ctx, query)
|
return r.store.GetThumbnail(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *sqlThumbnailRepository) findDashboardsWithStaleThumbnails(ctx context.Context, theme models.Theme, kind dashboardthumbs.ThumbnailKind) ([]*dashboardthumbs.DashboardWithStaleThumbnail, error) {
|
func (r *sqlThumbnailRepository) findDashboardsWithStaleThumbnails(ctx context.Context, theme models.Theme, kind ThumbnailKind) ([]*DashboardWithStaleThumbnail, error) {
|
||||||
return r.store.FindDashboardsWithStaleThumbnails(ctx, &dashboardthumbs.FindDashboardsWithStaleThumbnailsCommand{
|
return r.store.FindDashboardsWithStaleThumbnails(ctx, &FindDashboardsWithStaleThumbnailsCommand{
|
||||||
IncludeManuallyUploadedThumbnails: false,
|
IncludeManuallyUploadedThumbnails: false,
|
||||||
IncludeThumbnailsWithEmptyDsUIDs: !r.search.IsDisabled(),
|
IncludeThumbnailsWithEmptyDsUIDs: !r.search.IsDisabled(),
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
@@ -98,7 +97,7 @@ func (r *sqlThumbnailRepository) findDashboardsWithStaleThumbnails(ctx context.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *sqlThumbnailRepository) doThumbnailsExist(ctx context.Context) (bool, error) {
|
func (r *sqlThumbnailRepository) doThumbnailsExist(ctx context.Context) (bool, error) {
|
||||||
cmd := &dashboardthumbs.FindDashboardThumbnailCountCommand{}
|
cmd := &FindDashboardThumbnailCountCommand{}
|
||||||
count, err := r.store.FindThumbnailCount(ctx, cmd)
|
count, err := r.store.FindThumbnailCount(ctx, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.log.Error("Error finding thumbnails", "err", err)
|
r.log.Error("Error finding thumbnails", "err", err)
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
dashboardthumbs "github.com/grafana/grafana/pkg/services/dashboard_thumbs"
|
|
||||||
"github.com/grafana/grafana/pkg/services/datasources/permissions"
|
"github.com/grafana/grafana/pkg/services/datasources/permissions"
|
||||||
"github.com/grafana/grafana/pkg/services/searchV2"
|
"github.com/grafana/grafana/pkg/services/searchV2"
|
||||||
"github.com/segmentio/encoding/json"
|
"github.com/segmentio/encoding/json"
|
||||||
@@ -69,7 +68,7 @@ type crawlerScheduleOptions struct {
|
|||||||
tickerInterval time.Duration
|
tickerInterval time.Duration
|
||||||
maxCrawlDuration time.Duration
|
maxCrawlDuration time.Duration
|
||||||
crawlerMode CrawlerMode
|
crawlerMode CrawlerMode
|
||||||
thumbnailKind dashboardthumbs.ThumbnailKind
|
thumbnailKind ThumbnailKind
|
||||||
themes []models.Theme
|
themes []models.Theme
|
||||||
auth CrawlerAuth
|
auth CrawlerAuth
|
||||||
}
|
}
|
||||||
@@ -77,7 +76,7 @@ type crawlerScheduleOptions struct {
|
|||||||
func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles,
|
func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles,
|
||||||
lockService *serverlock.ServerLockService, renderService rendering.Service,
|
lockService *serverlock.ServerLockService, renderService rendering.Service,
|
||||||
gl *live.GrafanaLive, store *sqlstore.SQLStore, authSetupService CrawlerAuthSetupService,
|
gl *live.GrafanaLive, store *sqlstore.SQLStore, authSetupService CrawlerAuthSetupService,
|
||||||
dashboardService dashboards.DashboardService, dashboardThumbsService dashboardthumbs.Service, searchService searchV2.SearchService,
|
dashboardService dashboards.DashboardService, dashboardThumbsService DashboardThumbService, searchService searchV2.SearchService,
|
||||||
dsPermissionsService permissions.DatasourcePermissionsService, licensing models.Licensing) Service {
|
dsPermissionsService permissions.DatasourcePermissionsService, licensing models.Licensing) Service {
|
||||||
if !features.IsEnabled(featuremgmt.FlagDashboardPreviews) {
|
if !features.IsEnabled(featuremgmt.FlagDashboardPreviews) {
|
||||||
return &dummyService{}
|
return &dummyService{}
|
||||||
@@ -124,7 +123,7 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles,
|
|||||||
crawlInterval: cfg.DashboardPreviews.SchedulerInterval,
|
crawlInterval: cfg.DashboardPreviews.SchedulerInterval,
|
||||||
maxCrawlDuration: cfg.DashboardPreviews.MaxCrawlDuration,
|
maxCrawlDuration: cfg.DashboardPreviews.MaxCrawlDuration,
|
||||||
crawlerMode: CrawlerModeThumbs,
|
crawlerMode: CrawlerModeThumbs,
|
||||||
thumbnailKind: dashboardthumbs.ThumbnailKindDefault,
|
thumbnailKind: ThumbnailKindDefault,
|
||||||
themes: []models.Theme{models.ThemeDark, models.ThemeLight},
|
themes: []models.Theme{models.ThemeDark, models.ThemeLight},
|
||||||
auth: crawlerAuth,
|
auth: crawlerAuth,
|
||||||
},
|
},
|
||||||
@@ -157,7 +156,7 @@ func (hs *thumbService) Enabled() bool {
|
|||||||
func (hs *thumbService) parseImageReq(c *models.ReqContext, checkSave bool) *previewRequest {
|
func (hs *thumbService) parseImageReq(c *models.ReqContext, checkSave bool) *previewRequest {
|
||||||
params := web.Params(c.Req)
|
params := web.Params(c.Req)
|
||||||
|
|
||||||
kind, err := dashboardthumbs.ParseThumbnailKind(params[":kind"])
|
kind, err := ParseThumbnailKind(params[":kind"])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(400, map[string]string{"error": "invalid size"})
|
c.JSON(400, map[string]string{"error": "invalid size"})
|
||||||
return nil
|
return nil
|
||||||
@@ -191,7 +190,7 @@ func (hs *thumbService) parseImageReq(c *models.ReqContext, checkSave bool) *pre
|
|||||||
}
|
}
|
||||||
|
|
||||||
type updateThumbnailStateRequest struct {
|
type updateThumbnailStateRequest struct {
|
||||||
State dashboardthumbs.ThumbnailState `json:"state" binding:"Required"`
|
State ThumbnailState `json:"state" binding:"Required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hs *thumbService) UpdateThumbnailState(c *models.ReqContext) {
|
func (hs *thumbService) UpdateThumbnailState(c *models.ReqContext) {
|
||||||
@@ -209,11 +208,11 @@ func (hs *thumbService) UpdateThumbnailState(c *models.ReqContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = hs.thumbnailRepo.updateThumbnailState(c.Req.Context(), body.State, dashboardthumbs.DashboardThumbnailMeta{
|
err = hs.thumbnailRepo.updateThumbnailState(c.Req.Context(), body.State, DashboardThumbnailMeta{
|
||||||
DashboardUID: req.UID,
|
DashboardUID: req.UID,
|
||||||
OrgId: req.OrgID,
|
OrgId: req.OrgID,
|
||||||
Theme: req.Theme,
|
Theme: req.Theme,
|
||||||
Kind: dashboardthumbs.ThumbnailKindDefault,
|
Kind: ThumbnailKindDefault,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -232,11 +231,11 @@ func (hs *thumbService) GetImage(c *models.ReqContext) {
|
|||||||
return // already returned value
|
return // already returned value
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := hs.thumbnailRepo.getThumbnail(c.Req.Context(), dashboardthumbs.DashboardThumbnailMeta{
|
res, err := hs.thumbnailRepo.getThumbnail(c.Req.Context(), DashboardThumbnailMeta{
|
||||||
DashboardUID: req.UID,
|
DashboardUID: req.UID,
|
||||||
OrgId: req.OrgID,
|
OrgId: req.OrgID,
|
||||||
Theme: req.Theme,
|
Theme: req.Theme,
|
||||||
Kind: dashboardthumbs.ThumbnailKindDefault,
|
Kind: ThumbnailKindDefault,
|
||||||
})
|
})
|
||||||
|
|
||||||
if errors.Is(err, dashboards.ErrDashboardThumbnailNotFound) {
|
if errors.Is(err, dashboards.ErrDashboardThumbnailNotFound) {
|
||||||
@@ -269,7 +268,7 @@ func (hs *thumbService) GetImage(c *models.ReqContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hs *thumbService) hasAccessToPreview(c *models.ReqContext, res *dashboardthumbs.DashboardThumbnail, req *previewRequest) bool {
|
func (hs *thumbService) hasAccessToPreview(c *models.ReqContext, res *DashboardThumbnail, req *previewRequest) bool {
|
||||||
if !hs.licensing.FeatureEnabled("accesscontrol.enforcement") {
|
if !hs.licensing.FeatureEnabled("accesscontrol.enforcement") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -402,12 +401,12 @@ func (hs *thumbService) SetImage(c *models.ReqContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = hs.thumbnailRepo.saveFromBytes(c.Req.Context(), fileBytes, getMimeType(handler.Filename), dashboardthumbs.DashboardThumbnailMeta{
|
_, err = hs.thumbnailRepo.saveFromBytes(c.Req.Context(), fileBytes, getMimeType(handler.Filename), DashboardThumbnailMeta{
|
||||||
DashboardUID: req.UID,
|
DashboardUID: req.UID,
|
||||||
OrgId: req.OrgID,
|
OrgId: req.OrgID,
|
||||||
Theme: req.Theme,
|
Theme: req.Theme,
|
||||||
Kind: req.Kind,
|
Kind: req.Kind,
|
||||||
}, dashboardthumbs.DashboardVersionForManualThumbnailUpload, dsUids)
|
}, DashboardVersionForManualThumbnailUpload, dsUids)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(400, map[string]string{"error": "error saving thumbnail file"})
|
c.JSON(400, map[string]string{"error": "error saving thumbnail file"})
|
||||||
@@ -432,7 +431,7 @@ func (hs *thumbService) StartCrawler(c *models.ReqContext) response.Response {
|
|||||||
cmd.Mode = CrawlerModeThumbs
|
cmd.Mode = CrawlerModeThumbs
|
||||||
}
|
}
|
||||||
|
|
||||||
go hs.runOnDemandCrawl(context.Background(), cmd.Theme, cmd.Mode, dashboardthumbs.ThumbnailKindDefault, rendering.AuthOpts{
|
go hs.runOnDemandCrawl(context.Background(), cmd.Theme, cmd.Mode, ThumbnailKindDefault, rendering.AuthOpts{
|
||||||
OrgID: c.OrgID,
|
OrgID: c.OrgID,
|
||||||
UserID: c.UserID,
|
UserID: c.UserID,
|
||||||
OrgRole: c.OrgRole,
|
OrgRole: c.OrgRole,
|
||||||
@@ -494,7 +493,7 @@ func (hs *thumbService) getDashboardId(c *models.ReqContext, uid string) (int64,
|
|||||||
return query.Result.Id, nil
|
return query.Result.Id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hs *thumbService) runOnDemandCrawl(parentCtx context.Context, theme models.Theme, mode CrawlerMode, kind dashboardthumbs.ThumbnailKind, authOpts rendering.AuthOpts) {
|
func (hs *thumbService) runOnDemandCrawl(parentCtx context.Context, theme models.Theme, mode CrawlerMode, kind ThumbnailKind, authOpts rendering.AuthOpts) {
|
||||||
if !hs.canRunCrawler {
|
if !hs.canRunCrawler {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user