Image Rendering: Remove PhantomJS support (#23460)
Removes all references and usage of PhantomJS #23375. Remove direct link rendered image e2e smoke test for now. Docker: Fix installing chrome in ubuntu custom docker image. Improve handling of image renderer not available/installed #23593. Add PhantomJS breaking change and upgrading notes. Use grabpl v0.2.10. Closes #13802 Co-authored-by: Kyle Brandt <kyle@grafana.com> Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
This commit is contained in:
co-authored by
Kyle Brandt
Arve Knudsen
Diana Payton
parent
0a1ab60b8c
commit
6e313e7d37
@@ -53,19 +53,25 @@ func (n *notificationService) SendIfNeeded(evalCtx *EvalContext) error {
|
||||
}
|
||||
|
||||
if notifierStates.ShouldUploadImage() {
|
||||
// Create a copy of EvalContext and give it a new, shorter, timeout context to upload the image
|
||||
uploadEvalCtx := *evalCtx
|
||||
timeout := setting.AlertingNotificationTimeout / 2
|
||||
var uploadCtxCancel func()
|
||||
uploadEvalCtx.Ctx, uploadCtxCancel = context.WithTimeout(evalCtx.Ctx, timeout)
|
||||
if n.renderService.IsAvailable() {
|
||||
// Create a copy of EvalContext and give it a new, shorter, timeout context to upload the image
|
||||
uploadEvalCtx := *evalCtx
|
||||
timeout := setting.AlertingNotificationTimeout / 2
|
||||
var uploadCtxCancel func()
|
||||
uploadEvalCtx.Ctx, uploadCtxCancel = context.WithTimeout(evalCtx.Ctx, timeout)
|
||||
|
||||
// Try to upload the image without consuming all the time allocated for EvalContext
|
||||
if err = n.renderAndUploadImage(&uploadEvalCtx, timeout); err != nil {
|
||||
n.log.Error("Failed to render and upload alert panel image.", "ruleId", uploadEvalCtx.Rule.ID, "error", err)
|
||||
// Try to upload the image without consuming all the time allocated for EvalContext
|
||||
if err = n.renderAndUploadImage(&uploadEvalCtx, timeout); err != nil {
|
||||
n.log.Error("Failed to render and upload alert panel image.", "ruleId", uploadEvalCtx.Rule.ID, "error", err)
|
||||
}
|
||||
uploadCtxCancel()
|
||||
evalCtx.ImageOnDiskPath = uploadEvalCtx.ImageOnDiskPath
|
||||
evalCtx.ImagePublicURL = uploadEvalCtx.ImagePublicURL
|
||||
} else {
|
||||
n.log.Warn("Could not render image for alert notification, no image renderer found/installed. " +
|
||||
"For image rendering support please install the grafana-image-renderer plugin. " +
|
||||
"Read more at https://grafana.com/docs/grafana/latest/administration/image_rendering/")
|
||||
}
|
||||
uploadCtxCancel()
|
||||
evalCtx.ImageOnDiskPath = uploadEvalCtx.ImageOnDiskPath
|
||||
evalCtx.ImagePublicURL = uploadEvalCtx.ImagePublicURL
|
||||
}
|
||||
|
||||
return n.sendNotifications(evalCtx, notifierStates)
|
||||
|
||||
@@ -39,6 +39,16 @@ func TestNotificationService(t *testing.T) {
|
||||
require.Truef(t, evalCtx.Ctx.Value(notificationSent{}).(bool), "expected notification to be sent, but wasn't")
|
||||
})
|
||||
|
||||
notificationServiceScenario(t, "Given alert rule with upload image enabled but no renderer available should not render and upload image, but send notification", evalCtx, true, func(scenarioCtx *scenarioContext) {
|
||||
scenarioCtx.rendererAvailable = false
|
||||
err := scenarioCtx.notificationService.SendIfNeeded(evalCtx)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equalf(t, 0, scenarioCtx.renderCount, "expected render to not be called, but it was")
|
||||
require.Equalf(t, 0, scenarioCtx.imageUploadCount, "expected image to not be uploaded, but it was")
|
||||
require.Truef(t, evalCtx.Ctx.Value(notificationSent{}).(bool), "expected notification to be sent, but wasn't")
|
||||
})
|
||||
|
||||
notificationServiceScenario(t, "Given alert rule with upload image disabled should not render and upload image, but send notification", evalCtx, false, func(scenarioCtx *scenarioContext) {
|
||||
err := scenarioCtx.notificationService.SendIfNeeded(evalCtx)
|
||||
require.NoError(t, err)
|
||||
@@ -114,6 +124,7 @@ type scenarioContext struct {
|
||||
renderCount int
|
||||
uploadProvider func(ctx context.Context, path string) (string, error)
|
||||
renderProvider func(ctx context.Context, opts rendering.Opts) (*rendering.RenderResult, error)
|
||||
rendererAvailable bool
|
||||
}
|
||||
|
||||
type scenarioFunc func(c *scenarioContext)
|
||||
@@ -197,7 +208,12 @@ func notificationServiceScenario(t *testing.T, name string, evalCtx *EvalContext
|
||||
return &rendering.RenderResult{FilePath: "image.png"}, nil
|
||||
}
|
||||
|
||||
scenarioCtx.rendererAvailable = true
|
||||
|
||||
renderService := &testRenderService{
|
||||
isAvailableProvider: func() bool {
|
||||
return scenarioCtx.rendererAvailable
|
||||
},
|
||||
renderProvider: func(ctx context.Context, opts rendering.Opts) (*rendering.RenderResult, error) {
|
||||
if scenarioCtx.renderProvider != nil {
|
||||
if _, err := scenarioCtx.renderProvider(ctx, opts); err != nil {
|
||||
@@ -286,10 +302,19 @@ func (n *testNotifier) GetFrequency() time.Duration {
|
||||
var _ Notifier = &testNotifier{}
|
||||
|
||||
type testRenderService struct {
|
||||
isAvailableProvider func() bool
|
||||
renderProvider func(ctx context.Context, opts rendering.Opts) (*rendering.RenderResult, error)
|
||||
renderErrorImageProvider func(error error) (*rendering.RenderResult, error)
|
||||
}
|
||||
|
||||
func (s *testRenderService) IsAvailable() bool {
|
||||
if s.isAvailableProvider != nil {
|
||||
return s.isAvailableProvider()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *testRenderService) Render(ctx context.Context, opts rendering.Opts) (*rendering.RenderResult, error) {
|
||||
if s.renderProvider != nil {
|
||||
return s.renderProvider(ctx, opts)
|
||||
|
||||
Reference in New Issue
Block a user