diff --git a/apps/advisor/pkg/app/checkregistry/checkregistry.go b/apps/advisor/pkg/app/checkregistry/checkregistry.go index 335b9cc7567..31be8ae936e 100644 --- a/apps/advisor/pkg/app/checkregistry/checkregistry.go +++ b/apps/advisor/pkg/app/checkregistry/checkregistry.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" + "github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins" ) type CheckService interface { @@ -25,11 +26,14 @@ type Service struct { pluginRepo repo.Service pluginPreinstall plugininstaller.Preinstall managedPlugins managedplugins.Manager + provisionedPlugins provisionedplugins.Manager } func ProvideService(datasourceSvc datasources.DataSourceService, pluginStore pluginstore.Store, 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{ datasourceSvc: datasourceSvc, pluginStore: pluginStore, @@ -38,6 +42,7 @@ func ProvideService(datasourceSvc datasources.DataSourceService, pluginStore plu pluginRepo: pluginRepo, pluginPreinstall: pluginPreinstall, managedPlugins: managedPlugins, + provisionedPlugins: provisionedPlugins, } } @@ -54,6 +59,7 @@ func (s *Service) Checks() []checks.Check { s.pluginRepo, s.pluginPreinstall, s.managedPlugins, + s.provisionedPlugins, ), } } diff --git a/apps/advisor/pkg/app/checks/plugincheck/check.go b/apps/advisor/pkg/app/checks/plugincheck/check.go index 45c54d4fdc0..3b08e0c5f6f 100644 --- a/apps/advisor/pkg/app/checks/plugincheck/check.go +++ b/apps/advisor/pkg/app/checks/plugincheck/check.go @@ -4,15 +4,18 @@ import ( "context" "fmt" sysruntime "runtime" + "slices" "github.com/Masterminds/semver/v3" advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" "github.com/grafana/grafana/apps/advisor/pkg/app/checks" "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/services/pluginsintegration/managedplugins" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" + "github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins" ) func New( @@ -20,20 +23,23 @@ func New( pluginRepo repo.Service, pluginPreinstall plugininstaller.Preinstall, managedPlugins managedplugins.Manager, + provisionedPlugins provisionedplugins.Manager, ) checks.Check { return &check{ - PluginStore: pluginStore, - PluginRepo: pluginRepo, - PluginPreinstall: pluginPreinstall, - ManagedPlugins: managedPlugins, + PluginStore: pluginStore, + PluginRepo: pluginRepo, + PluginPreinstall: pluginPreinstall, + ManagedPlugins: managedPlugins, + ProvisionedPlugins: provisionedPlugins, } } type check struct { - PluginStore pluginstore.Store - PluginRepo repo.Service - PluginPreinstall plugininstaller.Preinstall - ManagedPlugins managedplugins.Manager + PluginStore pluginstore.Store + PluginRepo repo.Service + PluginPreinstall plugininstaller.Preinstall + ManagedPlugins managedplugins.Manager + ProvisionedPlugins provisionedplugins.Manager } func (c *check) ID() string { @@ -55,9 +61,11 @@ func (c *check) Steps() []checks.Step { PluginRepo: c.PluginRepo, }, &updateStep{ - PluginRepo: c.PluginRepo, - PluginPreinstall: c.PluginPreinstall, - ManagedPlugins: c.ManagedPlugins, + PluginRepo: c.PluginRepo, + PluginPreinstall: c.PluginPreinstall, + 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 { - PluginRepo repo.Service - PluginPreinstall plugininstaller.Preinstall - ManagedPlugins managedplugins.Manager + PluginRepo repo.Service + PluginPreinstall plugininstaller.Preinstall + ManagedPlugins managedplugins.Manager + ProvisionedPlugins provisionedplugins.Manager + provisionedPlugins []string + log log.Logger } 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 if p.IsCorePlugin() { + s.log.Debug("Skipping core plugin", "plugin", p.ID) return nil, nil } // Skip if it's managed or pinned 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 } @@ -197,3 +216,14 @@ func (s *updateStep) isManaged(ctx context.Context, pluginID string) bool { } 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) +} diff --git a/apps/advisor/pkg/app/checks/plugincheck/check_test.go b/apps/advisor/pkg/app/checks/plugincheck/check_test.go index 13b2a17ea1b..c8cdc965a32 100644 --- a/apps/advisor/pkg/app/checks/plugincheck/check_test.go +++ b/apps/advisor/pkg/app/checks/plugincheck/check_test.go @@ -10,6 +10,7 @@ import ( "github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins" "github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller" "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" + "github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins" "github.com/stretchr/testify/assert" ) @@ -21,6 +22,7 @@ func TestRun(t *testing.T) { pluginArchives map[string]*repo.PluginArchiveInfo pluginPreinstalled []string pluginManaged []string + pluginProvisioned []string expectedFailures []advisor.CheckReportFailure }{ { @@ -131,6 +133,20 @@ func TestRun(t *testing.T) { pluginManaged: []string{"plugin4"}, 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 { @@ -142,7 +158,8 @@ func TestRun(t *testing.T) { } pluginPreinstall := &mockPluginPreinstall{pinned: tt.pluginPreinstalled} 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()) assert.NoError(t, err) @@ -208,3 +225,12 @@ type mockManagedPlugins struct { func (m *mockManagedPlugins) ManagedPlugins(ctx context.Context) []string { return m.managed } + +type mockProvisionedPlugins struct { + provisionedplugins.Manager + provisioned []string +} + +func (m *mockProvisionedPlugins) ProvisionedPlugins(ctx context.Context) ([]string, error) { + return m.provisioned, nil +} diff --git a/pkg/services/pluginsintegration/pluginsintegration.go b/pkg/services/pluginsintegration/pluginsintegration.go index eca6c3be53f..da0319b3d7f 100644 --- a/pkg/services/pluginsintegration/pluginsintegration.go +++ b/pkg/services/pluginsintegration/pluginsintegration.go @@ -53,6 +53,7 @@ import ( "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings" 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/provisionedplugins" "github.com/grafana/grafana/pkg/services/pluginsintegration/renderer" "github.com/grafana/grafana/pkg/services/pluginsintegration/serviceregistration" "github.com/grafana/grafana/pkg/services/rendering" @@ -144,6 +145,8 @@ var WireExtensionSet = wire.NewSet( wire.Bind(new(plugins.Client), new(*backend.MiddlewareHandler)), managedplugins.NewNoop, wire.Bind(new(managedplugins.Manager), new(*managedplugins.Noop)), + provisionedplugins.NewNoop, + wire.Bind(new(provisionedplugins.Manager), new(*provisionedplugins.Noop)), sources.ProvideService, wire.Bind(new(sources.Registry), new(*sources.Service)), ) diff --git a/pkg/services/pluginsintegration/provisionedplugins/provisioned.go b/pkg/services/pluginsintegration/provisionedplugins/provisioned.go new file mode 100644 index 00000000000..c124f6b0203 --- /dev/null +++ b/pkg/services/pluginsintegration/provisionedplugins/provisioned.go @@ -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 +}