从 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 主题的更详细信息,请参阅此处。
如何样式化功能组件
useStyles
钩子是访问主题样式时的首选方法。它提供了基本的记忆化以及访问主题对象的功能。
// 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>
);
};