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/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,
),
}
}

View File

@ -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,12 +23,14 @@ 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,
ProvisionedPlugins: provisionedPlugins,
}
}
@ -34,6 +39,7 @@ type check struct {
PluginRepo repo.Service
PluginPreinstall plugininstaller.Preinstall
ManagedPlugins managedplugins.Manager
ProvisionedPlugins provisionedplugins.Manager
}
func (c *check) ID() string {
@ -58,6 +64,8 @@ func (c *check) Steps() []checks.Step {
PluginRepo: c.PluginRepo,
PluginPreinstall: c.PluginPreinstall,
ManagedPlugins: c.ManagedPlugins,
ProvisionedPlugins: c.ProvisionedPlugins,
log: log.New("advisor.check.plugin.update"),
},
}
}
@ -120,6 +128,9 @@ type updateStep struct {
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)
}

View File

@ -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
}

View File

@ -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)),
)

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
}