Advisor: Skip plugin check for provisioned plugins (#101782)

This commit is contained in:
Andres Martinez Gotor
2025-03-13 15:04:08 +01:00
committed by GitHub
parent 772432e025
commit a9634f9b12
5 changed files with 100 additions and 16 deletions

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
) )
type CheckService interface { type CheckService interface {
@ -25,11 +26,14 @@ type Service struct {
pluginRepo repo.Service pluginRepo repo.Service
pluginPreinstall plugininstaller.Preinstall pluginPreinstall plugininstaller.Preinstall
managedPlugins managedplugins.Manager managedPlugins managedplugins.Manager
provisionedPlugins provisionedplugins.Manager
} }
func ProvideService(datasourceSvc datasources.DataSourceService, pluginStore pluginstore.Store, func ProvideService(datasourceSvc datasources.DataSourceService, pluginStore pluginstore.Store,
pluginContextProvider *plugincontext.Provider, pluginClient plugins.Client, pluginContextProvider *plugincontext.Provider, pluginClient plugins.Client,
pluginRepo repo.Service, pluginPreinstall plugininstaller.Preinstall, managedPlugins managedplugins.Manager) *Service { pluginRepo repo.Service, pluginPreinstall plugininstaller.Preinstall, managedPlugins managedplugins.Manager,
provisionedPlugins provisionedplugins.Manager,
) *Service {
return &Service{ return &Service{
datasourceSvc: datasourceSvc, datasourceSvc: datasourceSvc,
pluginStore: pluginStore, pluginStore: pluginStore,
@ -38,6 +42,7 @@ func ProvideService(datasourceSvc datasources.DataSourceService, pluginStore plu
pluginRepo: pluginRepo, pluginRepo: pluginRepo,
pluginPreinstall: pluginPreinstall, pluginPreinstall: pluginPreinstall,
managedPlugins: managedPlugins, managedPlugins: managedPlugins,
provisionedPlugins: provisionedPlugins,
} }
} }
@ -54,6 +59,7 @@ func (s *Service) Checks() []checks.Check {
s.pluginRepo, s.pluginRepo,
s.pluginPreinstall, s.pluginPreinstall,
s.managedPlugins, s.managedPlugins,
s.provisionedPlugins,
), ),
} }
} }

View File

@ -4,15 +4,18 @@ import (
"context" "context"
"fmt" "fmt"
sysruntime "runtime" sysruntime "runtime"
"slices"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
"github.com/grafana/grafana/apps/advisor/pkg/app/checks" "github.com/grafana/grafana/apps/advisor/pkg/app/checks"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/services" "github.com/grafana/grafana/pkg/cmd/grafana-cli/services"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins/repo" "github.com/grafana/grafana/pkg/plugins/repo"
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins" "github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
) )
func New( func New(
@ -20,20 +23,23 @@ func New(
pluginRepo repo.Service, pluginRepo repo.Service,
pluginPreinstall plugininstaller.Preinstall, pluginPreinstall plugininstaller.Preinstall,
managedPlugins managedplugins.Manager, managedPlugins managedplugins.Manager,
provisionedPlugins provisionedplugins.Manager,
) checks.Check { ) checks.Check {
return &check{ return &check{
PluginStore: pluginStore, PluginStore: pluginStore,
PluginRepo: pluginRepo, PluginRepo: pluginRepo,
PluginPreinstall: pluginPreinstall, PluginPreinstall: pluginPreinstall,
ManagedPlugins: managedPlugins, ManagedPlugins: managedPlugins,
ProvisionedPlugins: provisionedPlugins,
} }
} }
type check struct { type check struct {
PluginStore pluginstore.Store PluginStore pluginstore.Store
PluginRepo repo.Service PluginRepo repo.Service
PluginPreinstall plugininstaller.Preinstall PluginPreinstall plugininstaller.Preinstall
ManagedPlugins managedplugins.Manager ManagedPlugins managedplugins.Manager
ProvisionedPlugins provisionedplugins.Manager
} }
func (c *check) ID() string { func (c *check) ID() string {
@ -55,9 +61,11 @@ func (c *check) Steps() []checks.Step {
PluginRepo: c.PluginRepo, PluginRepo: c.PluginRepo,
}, },
&updateStep{ &updateStep{
PluginRepo: c.PluginRepo, PluginRepo: c.PluginRepo,
PluginPreinstall: c.PluginPreinstall, PluginPreinstall: c.PluginPreinstall,
ManagedPlugins: c.ManagedPlugins, ManagedPlugins: c.ManagedPlugins,
ProvisionedPlugins: c.ProvisionedPlugins,
log: log.New("advisor.check.plugin.update"),
}, },
} }
} }
@ -117,9 +125,12 @@ func (s *deprecationStep) Run(ctx context.Context, _ *advisor.CheckSpec, it any)
} }
type updateStep struct { type updateStep struct {
PluginRepo repo.Service PluginRepo repo.Service
PluginPreinstall plugininstaller.Preinstall PluginPreinstall plugininstaller.Preinstall
ManagedPlugins managedplugins.Manager ManagedPlugins managedplugins.Manager
ProvisionedPlugins provisionedplugins.Manager
provisionedPlugins []string
log log.Logger
} }
func (s *updateStep) Title() string { func (s *updateStep) Title() string {
@ -146,11 +157,19 @@ func (s *updateStep) Run(ctx context.Context, _ *advisor.CheckSpec, i any) (*adv
// Skip if it's a core plugin // Skip if it's a core plugin
if p.IsCorePlugin() { if p.IsCorePlugin() {
s.log.Debug("Skipping core plugin", "plugin", p.ID)
return nil, nil return nil, nil
} }
// Skip if it's managed or pinned // Skip if it's managed or pinned
if s.isManaged(ctx, p.ID) || s.PluginPreinstall.IsPinned(p.ID) { if s.isManaged(ctx, p.ID) || s.PluginPreinstall.IsPinned(p.ID) {
s.log.Debug("Skipping managed or pinned plugin", "plugin", p.ID)
return nil, nil
}
// Skip if it's provisioned
if s.isProvisioned(ctx, p.ID) {
s.log.Debug("Skipping provisioned plugin", "plugin", p.ID)
return nil, nil return nil, nil
} }
@ -197,3 +216,14 @@ func (s *updateStep) isManaged(ctx context.Context, pluginID string) bool {
} }
return false return false
} }
func (s *updateStep) isProvisioned(ctx context.Context, pluginID string) bool {
if s.provisionedPlugins == nil {
var err error
s.provisionedPlugins, err = s.ProvisionedPlugins.ProvisionedPlugins(ctx)
if err != nil {
return false
}
}
return slices.Contains(s.provisionedPlugins, pluginID)
}

View File

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins" "github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -21,6 +22,7 @@ func TestRun(t *testing.T) {
pluginArchives map[string]*repo.PluginArchiveInfo pluginArchives map[string]*repo.PluginArchiveInfo
pluginPreinstalled []string pluginPreinstalled []string
pluginManaged []string pluginManaged []string
pluginProvisioned []string
expectedFailures []advisor.CheckReportFailure expectedFailures []advisor.CheckReportFailure
}{ }{
{ {
@ -131,6 +133,20 @@ func TestRun(t *testing.T) {
pluginManaged: []string{"plugin4"}, pluginManaged: []string{"plugin4"},
expectedFailures: []advisor.CheckReportFailure{}, expectedFailures: []advisor.CheckReportFailure{},
}, },
{
name: "Provisioned plugin",
plugins: []pluginstore.Plugin{
{JSONData: plugins.JSONData{ID: "plugin5", Info: plugins.Info{Version: "1.0.0"}}},
},
pluginInfo: map[string]*repo.PluginInfo{
"plugin5": {Status: "active"},
},
pluginArchives: map[string]*repo.PluginArchiveInfo{
"plugin5": {Version: "1.1.0"},
},
pluginProvisioned: []string{"plugin5"},
expectedFailures: []advisor.CheckReportFailure{},
},
} }
for _, tt := range tests { for _, tt := range tests {
@ -142,7 +158,8 @@ func TestRun(t *testing.T) {
} }
pluginPreinstall := &mockPluginPreinstall{pinned: tt.pluginPreinstalled} pluginPreinstall := &mockPluginPreinstall{pinned: tt.pluginPreinstalled}
managedPlugins := &mockManagedPlugins{managed: tt.pluginManaged} managedPlugins := &mockManagedPlugins{managed: tt.pluginManaged}
check := New(pluginStore, pluginRepo, pluginPreinstall, managedPlugins) provisionedPlugins := &mockProvisionedPlugins{provisioned: tt.pluginProvisioned}
check := New(pluginStore, pluginRepo, pluginPreinstall, managedPlugins, provisionedPlugins)
items, err := check.Items(context.Background()) items, err := check.Items(context.Background())
assert.NoError(t, err) assert.NoError(t, err)
@ -208,3 +225,12 @@ type mockManagedPlugins struct {
func (m *mockManagedPlugins) ManagedPlugins(ctx context.Context) []string { func (m *mockManagedPlugins) ManagedPlugins(ctx context.Context) []string {
return m.managed return m.managed
} }
type mockProvisionedPlugins struct {
provisionedplugins.Manager
provisioned []string
}
func (m *mockProvisionedPlugins) ProvisionedPlugins(ctx context.Context) ([]string, error) {
return m.provisioned, nil
}

View File

@ -53,6 +53,7 @@ import (
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
pluginSettings "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings/service" pluginSettings "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings/service"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
"github.com/grafana/grafana/pkg/services/pluginsintegration/renderer" "github.com/grafana/grafana/pkg/services/pluginsintegration/renderer"
"github.com/grafana/grafana/pkg/services/pluginsintegration/serviceregistration" "github.com/grafana/grafana/pkg/services/pluginsintegration/serviceregistration"
"github.com/grafana/grafana/pkg/services/rendering" "github.com/grafana/grafana/pkg/services/rendering"
@ -144,6 +145,8 @@ var WireExtensionSet = wire.NewSet(
wire.Bind(new(plugins.Client), new(*backend.MiddlewareHandler)), wire.Bind(new(plugins.Client), new(*backend.MiddlewareHandler)),
managedplugins.NewNoop, managedplugins.NewNoop,
wire.Bind(new(managedplugins.Manager), new(*managedplugins.Noop)), wire.Bind(new(managedplugins.Manager), new(*managedplugins.Noop)),
provisionedplugins.NewNoop,
wire.Bind(new(provisionedplugins.Manager), new(*provisionedplugins.Noop)),
sources.ProvideService, sources.ProvideService,
wire.Bind(new(sources.Registry), new(*sources.Service)), wire.Bind(new(sources.Registry), new(*sources.Service)),
) )

View File

@ -0,0 +1,19 @@
package provisionedplugins
import "context"
type Manager interface {
ProvisionedPlugins(ctx context.Context) ([]string, error)
}
var _ Manager = (*Noop)(nil)
type Noop struct{}
func NewNoop() *Noop {
return &Noop{}
}
func (s *Noop) ProvisionedPlugins(_ context.Context) ([]string, error) {
return []string{}, nil
}