将插件从 Grafana 7.x 版本迁移到 8.x
按照这些说明将 Grafana v7.x.x 插件迁移到 Grafana v8.x.x 中可用的更新的插件系统。根据您的插件,您需要执行以下一个或多个步骤。
请注意 Grafana v8.x.x 中的重大变更(下文有说明)以及升级插件所需的步骤。
已移除对后端插件 v1 的支持
使用新的 Go 版插件 SDK 来运行您的后端插件在 Grafana 8 中。
1. 添加对 grafana-plugin-sdk-go 的依赖
添加对 https://github.com/grafana/grafana-plugin-sdk-go
的依赖。我们推荐使用 Go modules 来管理您的依赖。
2. 更新引导插件的方式
更新您的 main
包,通过新的 Go 版插件 SDK 进行引导。
// before
package main
import (
"github.com/grafana/grafana_plugin_model/go/datasource"
hclog "github.com/hashicorp/go-hclog"
plugin "github.com/hashicorp/go-plugin"
"github.com/myorgid/datasource/pkg/plugin"
)
func main() {
pluginLogger.Debug("Running GRPC server")
ds, err := NewSampleDatasource(pluginLogger);
if err != nil {
pluginLogger.Error("Unable to create plugin");
}
plugin.Serve(&plugin.ServeConfig{
HandshakeConfig: plugin.HandshakeConfig{
ProtocolVersion: 1,
MagicCookieKey: "grafana_plugin_type",
MagicCookieValue: "datasource",
},
Plugins: map[string]plugin.Plugin{
"myorgid-datasource": &datasource.DatasourcePluginImpl{Plugin: ds},
},
GRPCServer: plugin.DefaultGRPCServer,
})
}
// after
package main
import (
"os"
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
"github.com/myorgid/datasource/pkg/plugin"
)
func main() {
log.DefaultLogger.Debug("Running GRPC server")
if err := datasource.Manage("myorgid-datasource", NewSampleDatasource, datasource.ManageOpts{}); err != nil {
log.DefaultLogger.Error(err.Error())
os.Exit(1)
}
}
3. 更新插件包
更新您的 plugin
包,以使用新的 Go 版插件 SDK。
// before
package plugin
import (
"context"
"github.com/grafana/grafana_plugin_model/go/datasource"
"github.com/hashicorp/go-hclog"
)
func NewSampleDatasource(pluginLogger hclog.Logger) (*SampleDatasource, error) {
return &SampleDatasource{
logger: pluginLogger,
}, nil
}
type SampleDatasource struct{
logger hclog.Logger
}
func (d *SampleDatasource) Query(ctx context.Context, tsdbReq *datasource.DatasourceRequest) (*datasource.DatasourceResponse, error) {
d.logger.Info("QueryData called", "request", req)
// logic for querying your datasource.
}
// after
package plugin
import (
"context"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana-plugin-sdk-go/data"
)
func NewSampleDatasource(_ backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
return &SampleDatasource{}, nil
}
type SampleDatasource struct{}
func (d *SampleDatasource) Dispose() {
// Clean up datasource instance resources.
}
func (d *SampleDatasource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
log.DefaultLogger.Info("QueryData called", "request", req)
// logic for querying your datasource.
}
func (d *SampleDatasource) CheckHealth(_ context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
log.DefaultLogger.Info("CheckHealth called", "request", req)
// The main use case for these health checks is the test button on the
// datasource configuration page which allows users to verify that
// a datasource is working as expected.
}
签名并加载后端插件
我们强烈建议您不要在 Grafana 安装中允许未签名插件。通过允许未签名插件,我们无法保证插件的真实性,这可能会损害您的 Grafana 安装的安全性。
要为您的插件签名,请参阅 为插件签名。
您仍然可以通过在 开发模式 下运行您的 Grafana 实例来运行和开发未签名插件。或者,您可以使用 allow_loading_unsigned_plugins
配置设置。
将 react-hook-form 从 v6 更新到 v7
我们将 react-hook-form 从版本 6 升级到了版本 7。为了使您的表单与版本 7 兼容,请参阅 react-hook-form-migration-guide。
更新 plugin.json
定义插件支持哪个 Grafana 版本的属性已被重命名,并且现在它是一个范围,而不是特定的版本。
// before
{
"dependencies": {
"grafanaVersion": "7.5.x",
"plugins": []
}
}
// after
{
"dependencies": {
"grafanaDependency": ">=8.0.0",
"plugins": []
}
}
更新导入以匹配 emotion 11
Grafana 使用 Emotion 库来管理前端样式。我们已更新了 Emotion 包,如果您有自定义样式,这可能会影响您的前端插件。您只需更新 import
语句即可使其在 Grafana 8 中工作。
// before
import { cx, css } from 'emotion';
// after
import { cx, css } from '@emotion/css';
使用仪表盘的应用插件需要更新
为了使侧边导航正常工作 - 定位到 Grafana 8.+
并且通过 addToNav 属性集成到侧边菜单的应用插件,需要调整其 plugin.json
及其所有仪表盘 json 文件,使其具有匹配的 uid
。
plugin.json
{
"id": "plugin-id",
// ...
"includes": [
{
"type": "dashboard",
"name": "(Team) Situation Overview",
"path": "dashboards/example-dashboard.json",
"addToNav": true,
"defaultNav": false,
"uid": "l3KqBxCMz"
}
]
// ...
}
dashboards/example-dashboard.json
{
// ...
"title": "Example Dashboard",
"uid": "l3KqBxCMz",
"version": 1
// ...
}
8.0 弃用项
以下功能在版本 8.0 中已被弃用。
Grafana 主题 v1
在 Grafana 8 中,我们引入了新的改进版主题系统。先前版本的主题系统仍然可用,但已被弃用,并将在 Grafana 的下一个主要版本中移除。
您可以找到关于如何应用 v2 主题的更多详细信息 此处。
如何为函数组件设置样式
useStyles
Hook 是在设置样式时访问主题的首选方式。它提供基本的 memoization 和对主题对象的访问。
// before
import React, { ReactElement } from 'react';
import css from 'emotion';
import { GrafanaTheme } from '@grafana/data';
import { useStyles } from '@grafana/ui';
function Component(): ReactElement | null {
const styles = useStyles(getStyles);
}
const getStyles = (theme: GrafanaTheme) => ({
myStyle: css`
background: ${theme.colors.bodyBg};
display: flex;
`,
});
// after
import React, { ReactElement } from 'react';
import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '@grafana/ui';
function Component(): ReactElement | null {
const theme = useStyles2(getStyles);
}
const getStyles = (theme: GrafanaTheme2) => ({
myStyle: css`
background: ${theme.colors.background.canvas};
display: flex;
`,
});
如何在函数组件中使用主题
此示例展示如何在函数组件中使用主题
// before
import React, { ReactElement } from 'react';
import { useTheme } from '@grafana/ui';
function Component(): ReactElement | null {
const theme = useTheme();
}
// after
import React, { ReactElement } from 'react';
import { useTheme2 } from '@grafana/ui';
function Component(): ReactElement | null {
const theme = useTheme2();
// Your component has access to the theme variables now
}
如何在类组件中使用主题
此示例展示如何在类组件中使用主题
// before
import React from 'react';
import { Themeable, withTheme } from '@grafana/ui';
type Props = {} & Themeable;
class Component extends React.Component<Props> {
render() {
const { theme } = this.props;
// Your component has access to the theme variables now
}
}
export default withTheme(Component);
// after
import React from 'react';
import { Themeable2, withTheme2 } from '@grafana/ui';
type Props = {} & Themeable2;
class Component extends React.Component<Props> {
render() {
const { theme } = this.props;
// Your component has access to the theme variables now
}
}
export default withTheme2(Component);
组件的渐进式迁移
如果您需要在同一上下文中使用已迁移和未迁移的组件,从而需要同时使用 v1 和 v2 主题,则请在 v2
主题上使用 v1
属性。
示例
function Component(): ReactElement | null {
const theme = useTheme2();
return (
<NonMigrated theme={theme.v1}>
<Migrated theme={theme] />
</NonMigrate>
);
};