将插件从 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 模块 来管理您的依赖项。
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 迁移指南。
更新 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 主题的更多详细信息 here。
如何为函数组件设置样式
useStyles
hook 是在设置样式时访问主题的首选方法。它提供基本的记忆功能和对主题对象的访问
// 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>
);
};