mirror of
https://github.com/grafana/grafana.git
synced 2026-03-13 15:29:48 +08:00
Rendering: Remove deprecated plugin support (#118809)
This commit is contained in:
@@ -124,7 +124,7 @@ docker run -d -p 3000:3000 --name=grafana \
|
||||
|
||||
## Build a custom Grafana Docker image
|
||||
|
||||
In the Grafana GitHub repository, the `packaging/docker/custom/` folder includes a `Dockerfile` that you can use to build a custom Grafana image. The `Dockerfile` accepts `GRAFANA_VERSION`, `GF_INSTALL_PLUGINS`, and `GF_INSTALL_IMAGE_RENDERER_PLUGIN` as build arguments.
|
||||
In the Grafana GitHub repository, the `packaging/docker/custom/` folder includes a `Dockerfile` that you can use to build a custom Grafana image. The `Dockerfile` accepts `GRAFANA_VERSION` and `GF_INSTALL_PLUGINS` as build arguments.
|
||||
|
||||
The `GRAFANA_VERSION` build argument must be a valid `grafana/grafana` Docker image tag. By default, Grafana builds an Alpine-based image. To build an Ubuntu-based image, append `-ubuntu` to the `GRAFANA_VERSION` build argument.
|
||||
|
||||
@@ -145,30 +145,6 @@ docker build \
|
||||
docker run -d -p 3000:3000 --name=grafana grafana-custom
|
||||
```
|
||||
|
||||
### Build Grafana with the Image Renderer plugin pre-installed
|
||||
|
||||
> **Note:** This feature is experimental.
|
||||
|
||||
Currently, the Grafana Image Renderer plugin requires dependencies that are not available in the Grafana Docker image (see [GitHub Issue#301](https://github.com/grafana/grafana-image-renderer/issues/301) for more details). However, you can create a customized Docker image using the `GF_INSTALL_IMAGE_RENDERER_PLUGIN` build argument as a solution. This will install the necessary dependencies for the Grafana Image Renderer plugin to run.
|
||||
|
||||
Example:
|
||||
|
||||
The following example shows how to build a customized Grafana Docker image that includes the Image Renderer plugin.
|
||||
|
||||
```bash
|
||||
# go to the folder
|
||||
cd packaging/docker/custom
|
||||
|
||||
# running the build command
|
||||
docker build \
|
||||
--build-arg "GRAFANA_VERSION=latest" \
|
||||
--build-arg "GF_INSTALL_IMAGE_RENDERER_PLUGIN=true" \
|
||||
-t grafana-custom .
|
||||
|
||||
# running the docker run command
|
||||
docker run -d -p 3000:3000 --name=grafana grafana-custom
|
||||
```
|
||||
|
||||
### Build a Grafana Docker image with pre-installed plugins
|
||||
|
||||
If you run multiple Grafana installations with the same plugins, you can save time by building a customized image that includes plugins available on the [Grafana Plugin download page](/grafana/plugins). When you build a customized image, Grafana doesn't have to install the plugins each time it starts, making the startup process more efficient.
|
||||
|
||||
@@ -2,8 +2,6 @@ ARG GRAFANA_VERSION="latest"
|
||||
|
||||
FROM grafana/grafana:${GRAFANA_VERSION}
|
||||
|
||||
ARG GF_INSTALL_IMAGE_RENDERER_PLUGIN="false"
|
||||
|
||||
ARG GF_GID="0"
|
||||
|
||||
ENV GF_PATHS_PLUGINS="/var/lib/grafana-plugins"
|
||||
@@ -12,39 +10,10 @@ ENV GF_PLUGIN_RENDERING_CHROME_BIN="/usr/bin/chrome"
|
||||
USER root
|
||||
|
||||
RUN mkdir -p "$GF_PATHS_PLUGINS" && \
|
||||
chown -R grafana:${GF_GID} "$GF_PATHS_PLUGINS" && \
|
||||
if [ $GF_INSTALL_IMAGE_RENDERER_PLUGIN = "true" ]; then \
|
||||
if grep -i -q alpine /etc/issue; then \
|
||||
apk add --no-cache udev ttf-opensans chromium && \
|
||||
ln -s /usr/bin/chromium-browser "$GF_PLUGIN_RENDERING_CHROME_BIN"; \
|
||||
else \
|
||||
cd /tmp && \
|
||||
curl -sLO https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \
|
||||
DEBIAN_FRONTEND=noninteractive && \
|
||||
apt-get update -q && \
|
||||
apt-get install -q -y ./google-chrome-stable_current_amd64.deb && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
rm ./google-chrome-stable_current_amd64.deb && \
|
||||
ln -s /usr/bin/google-chrome "$GF_PLUGIN_RENDERING_CHROME_BIN"; \
|
||||
fi \
|
||||
fi
|
||||
chown -R grafana:${GF_GID} "$GF_PATHS_PLUGINS"
|
||||
|
||||
USER grafana
|
||||
|
||||
RUN if [ $GF_INSTALL_IMAGE_RENDERER_PLUGIN = "true" ]; then \
|
||||
if grep -i -q alpine /etc/issue; then \
|
||||
grafana-cli \
|
||||
--pluginsDir "$GF_PATHS_PLUGINS" \
|
||||
--pluginUrl https://github.com/grafana/grafana-image-renderer/releases/latest/download/plugin-alpine-x64-no-chromium.zip \
|
||||
plugins install grafana-image-renderer; \
|
||||
else \
|
||||
grafana-cli \
|
||||
--pluginsDir "$GF_PATHS_PLUGINS" \
|
||||
--pluginUrl https://github.com/grafana/grafana-image-renderer/releases/latest/download/plugin-linux-x64-glibc-no-chromium.zip \
|
||||
plugins install grafana-image-renderer; \
|
||||
fi \
|
||||
fi
|
||||
|
||||
ARG GF_INSTALL_PLUGINS=""
|
||||
|
||||
RUN if [ ! -z "${GF_INSTALL_PLUGINS}" ]; then \
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
package rendering
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/pluginextensionv2"
|
||||
)
|
||||
|
||||
func (rs *RenderingService) renderViaPlugin(ctx context.Context, renderType RenderType, renderKey string, opts Opts) (*RenderResult, error) {
|
||||
logger := rs.log.FromContext(ctx)
|
||||
|
||||
// gives plugin some additional time to timeout and return possible errors.
|
||||
ctx, cancel := context.WithTimeout(ctx, getRequestTimeout(opts.TimeoutOpts))
|
||||
defer cancel()
|
||||
|
||||
filePath, err := rs.getNewFilePath(renderType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
headers := map[string]*pluginextensionv2.StringList{}
|
||||
|
||||
for k, values := range opts.Headers {
|
||||
headers[k] = &pluginextensionv2.StringList{
|
||||
Values: values,
|
||||
}
|
||||
}
|
||||
|
||||
req := &pluginextensionv2.RenderRequest{
|
||||
Url: rs.getGrafanaCallbackURL(opts.Path),
|
||||
Width: int32(opts.Width),
|
||||
Height: int32(opts.Height),
|
||||
DeviceScaleFactor: float32(opts.DeviceScaleFactor),
|
||||
FilePath: filePath,
|
||||
Timeout: int32(opts.Timeout.Seconds()),
|
||||
RenderKey: renderKey,
|
||||
Timezone: isoTimeOffsetToPosixTz(opts.Timezone),
|
||||
Domain: rs.domain,
|
||||
Headers: headers,
|
||||
AuthToken: rs.Cfg.RendererAuthToken,
|
||||
Encoding: string(renderType),
|
||||
}
|
||||
logger.Debug("Calling renderer plugin", "req", req)
|
||||
|
||||
rc, err := rs.plugin.Client()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rsp, err := rc.Render(ctx, req)
|
||||
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
||||
logger.Error("Rendering timed out")
|
||||
return nil, ErrTimeout
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rsp.Error != "" {
|
||||
return nil, fmt.Errorf("rendering failed: %s", rsp.Error)
|
||||
}
|
||||
|
||||
return &RenderResult{FilePath: filePath}, err
|
||||
}
|
||||
|
||||
func (rs *RenderingService) renderCSVViaPlugin(ctx context.Context, renderKey string, opts CSVOpts) (*RenderCSVResult, error) {
|
||||
logger := rs.log.FromContext(ctx)
|
||||
|
||||
// gives plugin some additional time to timeout and return possible errors.
|
||||
ctx, cancel := context.WithTimeout(ctx, getRequestTimeout(opts.TimeoutOpts))
|
||||
defer cancel()
|
||||
|
||||
filePath, err := rs.getNewFilePath(RenderCSV)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
headers := map[string]*pluginextensionv2.StringList{}
|
||||
for k, values := range opts.Headers {
|
||||
headers[k] = &pluginextensionv2.StringList{
|
||||
Values: values,
|
||||
}
|
||||
}
|
||||
|
||||
req := &pluginextensionv2.RenderCSVRequest{
|
||||
Url: rs.getGrafanaCallbackURL(opts.Path),
|
||||
FilePath: filePath,
|
||||
RenderKey: renderKey,
|
||||
Domain: rs.domain,
|
||||
Timeout: int32(opts.Timeout.Seconds()),
|
||||
Timezone: isoTimeOffsetToPosixTz(opts.Timezone),
|
||||
Headers: headers,
|
||||
AuthToken: rs.Cfg.RendererAuthToken,
|
||||
}
|
||||
logger.Debug("Calling renderer plugin", "req", req)
|
||||
|
||||
rc, err := rs.plugin.Client()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rsp, err := rc.RenderCSV(ctx, req)
|
||||
if err != nil {
|
||||
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
||||
logger.Error("Rendering timed out")
|
||||
return nil, ErrTimeout
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if rsp.Error != "" {
|
||||
return nil, fmt.Errorf("rendering failed: %s", rsp.Error)
|
||||
}
|
||||
|
||||
return &RenderCSVResult{FilePath: filePath, FileName: rsp.FileName}, nil
|
||||
}
|
||||
@@ -34,7 +34,6 @@ var _ Service = (*RenderingService)(nil)
|
||||
|
||||
type RenderingService struct {
|
||||
log log.Logger
|
||||
plugin Plugin
|
||||
renderAction renderFunc
|
||||
renderCSVAction renderCSVFunc
|
||||
domain string
|
||||
@@ -42,7 +41,6 @@ type RenderingService struct {
|
||||
version string
|
||||
versionMutex sync.RWMutex
|
||||
capabilities []Capability
|
||||
pluginAvailable bool
|
||||
rendererCallbackURL string
|
||||
netClient *http.Client
|
||||
|
||||
@@ -126,8 +124,6 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, remot
|
||||
}
|
||||
}
|
||||
|
||||
_, exists := rm.Renderer(context.Background())
|
||||
|
||||
netTransport := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
@@ -176,7 +172,6 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, remot
|
||||
RendererPluginManager: rm,
|
||||
log: logger,
|
||||
domain: domain,
|
||||
pluginAvailable: exists,
|
||||
rendererCallbackURL: rendererCallbackURL,
|
||||
netClient: netClient,
|
||||
}
|
||||
@@ -219,20 +214,6 @@ func (rs *RenderingService) Run(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
if rp, exists := rs.RendererPluginManager.Renderer(ctx); exists {
|
||||
rs.log = rs.log.New("renderer", "plugin")
|
||||
rs.plugin = rp
|
||||
if err := rs.plugin.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
rs.version = rp.Version()
|
||||
rs.renderAction = rs.renderViaPlugin
|
||||
rs.renderCSVAction = rs.renderCSVViaPlugin
|
||||
<-ctx.Done()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
rs.log.Debug("No image renderer found/installed. " +
|
||||
"For image rendering support please use the Grafana Image Renderer remote rendering service. " +
|
||||
"Read more at https://grafana.com/docs/grafana/latest/administration/image_rendering/")
|
||||
@@ -246,7 +227,7 @@ func (rs *RenderingService) remoteAvailable() bool {
|
||||
}
|
||||
|
||||
func (rs *RenderingService) IsAvailable(ctx context.Context) bool {
|
||||
return rs.remoteAvailable() || rs.pluginAvailable
|
||||
return rs.remoteAvailable()
|
||||
}
|
||||
|
||||
func (rs *RenderingService) Version() string {
|
||||
|
||||
Reference in New Issue
Block a user