在 Red Hat Developer Hub 中安装并查看插件


Red Hat Developer Hub 1.7

在 Red Hat Developer Hub 中安装插件

Red Hat Customer Content Services

摘要

管理用户可以安装和配置插件,使其他用户能够使用插件扩展 Red Hat Developer Hub (RHDH)功能。

第 1 章 在 Red Hat Developer Hub 中安装动态插件

动态插件支持基于 backend 插件管理器软件包,它是一个在 app-config.yaml 文件中扫描配置的根目录(dynamicPlugins.rootDirectory )的服务,并动态加载它们。

您可以使用预安装 Red Hat Developer Hub 的动态插件,或者从公共 NPM registry 安装外部动态插件。

您可以将动态插件的配置存储在 Backstage 自定义资源(CR)可引用的 ConfigMap 对象中。

注意

如果 pluginConfig 字段引用环境变量,则必须在 < my_product_secrets > secret 中定义变量。

流程

  1. 在 OpenShift Container Platform Web 控制台中选择 ConfigMaps 选项卡。
  2. Create ConfigMap
  3. Create ConfigMap 页面中,选择 Configure via 中的 YAML view 选项,并根据需要编辑该文件。

    使用 GitHub 动态插件的 ConfigMap 对象示例

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: dynamic-plugins-rhdh
    data:
      dynamic-plugins.yaml: |
        includes:
          - dynamic-plugins.default.yaml
        plugins:
          - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-dynamic'
            disabled: false
            pluginConfig:
              catalog:
                providers:
                  github:
                    organization: "${GITHUB_ORG}"
                    schedule:
                      frequency: { minutes: 1 }
                      timeout: { minutes: 1 }
                      initialDelay: { seconds: 100 }

  4. Create
  5. 进入 Topology 视图。
  6. 点您要使用的 Red Hat Developer Hub 实例的溢出菜单,然后选择 Edit Backstage 以加载 Red Hat Developer Hub 实例的 YAML 视图。

    Operator 安装 2
  7. dynamicPluginsConfigMapName 字段添加到 Backstage CR。例如:

    apiVersion: rhdh.redhat.com/v1alpha3
    kind: Backstage
    metadata:
      name: my-rhdh
    spec:
      application:
    # ...
        dynamicPluginsConfigMapName: dynamic-plugins-rhdh
    # ...
  8. 点击 Save
  9. 返回到 Topology 视图并等待 Red Hat Developer Hub pod 启动。
  10. Open URL 图标以使用 Red Hat Developer Hub 平台以及新的配置更改。

验证

  • 通过在 Red Hat Developer Hub root URL 中附加 /api/dynamic-plugins-info/loaded-plugins 并检查插件列表来确保动态插件配置已被加载:

    插件列表示例

    [
      {
        "name": "backstage-plugin-catalog-backend-module-github-dynamic",
        "version": "0.5.2",
        "platform": "node",
        "role": "backend-plugin-module"
      },
      {
        "name": "backstage-plugin-techdocs",
        "version": "1.10.0",
        "role": "frontend-plugin",
        "platform": "web"
      },
      {
        "name": "backstage-plugin-techdocs-backend-dynamic",
        "version": "1.9.5",
        "platform": "node",
        "role": "backend-plugin"
      },
    ]

1.2. 使用 Helm Chart 安装动态插件

您可以使用 Helm Chart 部署 Developer Hub 实例,它是一个灵活的安装方法。使用 Helm Chart,您可以侧将动态插件加载到 Developer Hub 实例中,而无需重新编译代码或重建容器。

要使用 Helm 在 Developer Hub 中安装动态插件,请在 Helm Chart 中添加以下 global.dynamic 参数:

  • 插件 :用于安装的动态插件列表。默认情况下,列表为空。您可以使用以下字段填充 plugins 列表:

    • 软件包 :您要安装的动态插件软件包的软件包规格。您可以使用软件包进行本地或外部动态插件安装。对于本地安装,请使用包含动态插件的本地文件夹的路径。对于外部安装,请使用公共 NPM 存储库中的软件包规格。
    • 完整性 (外部软件包必需):一个特定于软件包的 < alg>-<digest&gt; 形式的完整性校验和。支持的算法包括 sha256sha384sha512
    • pluginConfig :特定于插件的 app-config.yaml YAML 片段。如需更多信息,请参阅插件配置。
    • disabled :如果设为 true,则禁用动态插件。默认值: false
    • forceDownload :将值设置为 true 以强制重新安装插件,绕过缓存。默认值为 false
    • PullPolicy :与 forceDownload 参数类似,并与其他镜像容器平台一致。对于这个键,您可以使用以下值之一:

      • Always: 这个值比较远程 registry 中的镜像摘要,并下载工件(如果之前下载了插件)。
      • IfNotPresent: 如果工件还没有存在于 dynamic-plugins-root 文件夹中,如果没有检查镜像摘要,则下载工件。

        注意

        pullPolicy 设置也应用于 NPM 下载方法,但 Always 将下载远程工件,而无需摘要检查。现有的 forceDownload 选项仍可以正常工作,但 pullPolicy 选项具有优先权。在以后的 Developer Hub 发行版本中可能会弃用 forceDownload 选项。

  • 包括 :使用相同语法的 YAML 文件列表。
注意

includes 文件中的 plugins 列表与主 Helm 值中的 plugins 列表合并。如果这两个插件列表中都提到了插件软件包,则主 Helm 值中的 plugins 字段会覆盖 includes 文件中的 plugins 字段。默认配置包含 dynamic-plugins.default.yaml 文件,其中包含 Developer Hub 中预安装的所有动态插件,无论是默认启用还是禁用。

1.2.1. 动态插件安装的 Helm Chart 配置示例

以下示例演示了如何为特定类型的动态插件安装配置 Helm Chart。

当外部插件需要特定配置时,配置本地插件和外部插件

global:
  dynamic:
    plugins:
      - package: <alocal package-spec used by npm pack>
      - package: <external package-spec used by npm pack>
        integrity: sha512-<some hash>
        pluginConfig: ...

从包含的文件禁用插件

global:
  dynamic:
    includes:
      - dynamic-plugins.default.yaml
    plugins:
      - package: <some imported plugins listed in dynamic-plugins.default.yaml>
        disabled: true

从包含的文件启用插件

global:
  dynamic:
    includes:
      - dynamic-plugins.default.yaml
    plugins:
      - package: <some imported plugins listed in dynamic-plugins.custom.yaml>
        disabled: false

启用在所含文件中禁用的插件

global:
  dynamic:
    includes:
      - dynamic-plugins.default.yaml
    plugins:
      - package: <some imported plugins listed in dynamic-plugins.custom.yaml>
        disabled: false

1.3. 在 air-gapped 环境中安装动态插件

您可以通过设置自定义 NPM registry,在 air-gapped 环境中安装外部插件。

您可以使用 Helm Chart 为动态插件软件包配置 NPM registry URL 和身份验证信息。对于通过 npm pack 获取的动态插件软件包,您可以使用 .npmrc 文件。

使用 Helm Chart,通过创建 secret 将 .npmrc 文件添加到 NPM registry 中。例如:

apiVersion: v1
kind: Secret
metadata:
  name: <release_name>-dynamic-plugins-npmrc 
1

type: Opaque
stringData:
  .npmrc: |
    registry=<registry-link>
    //<registry-link>:_authToken=<auth-token>
          ...
1
<release_name > 替换为您的 Helm 发行版本名称。此名称是 Kubernetes 集群中每个 chart 安装的唯一标识符。

第 2 章 Red Hat Developer Hub 中的第三方插件

您可以将第三方动态插件集成到 Red Hat Developer Hub 中,以增强其功能,而无需修改其源代码或重建它。要添加这些插件,请将它们导出为派生的软件包。

在导出插件软件包时,您必须确保依赖项被正确捆绑或标记为共享,具体取决于它们与 Developer Hub 环境的关系。

将第三方插件集成到 Developer Hub 中:

  1. 首先,获取插件的源代码。
  2. 将插件导出为动态插件软件包。请参阅 第 2.1 节 “在 Red Hat Developer Hub 中导出第三方插件”
  3. 软件包并发布动态插件。请参阅 第 2.2 节 “将第三方插件打包并发布为动态插件”
  4. 在 Developer Hub 环境中安装插件。请参阅 第 2.3 节 “在 Red Hat Developer Hub 中安装第三方插件”

2.1. 在 Red Hat Developer Hub 中导出第三方插件

要在 Red Hat Developer Hub 中使用插件,您可以将插件导出为派生的动态插件软件包。这些软件包包含插件代码和依赖项,可用于将动态插件集成到 Developer Hub 中。

先决条件

  • 已安装 @red-hat-developer-hub/cli 软件包。使用最新版本(@latest 标签)与最新的功能和修复程序兼容。
  • Node.js 和 NPM 已安装并配置。
  • 第三方插件与您的 Red Hat Developer Hub 版本兼容。如需更多信息,请参阅 版本兼容性列表
  • 第三方插件在其根目录中必须具有有效的 package.json 文件,其中包含所有必需的元数据和依赖项。

    后端插件

    为确保与动态插件支持兼容并启用它们的用作动态插件,现有后端插件必须与新的 Backstage 后端系统兼容。此外,这些插件必须使用专用的 CLI 命令重建。

    新的 Backstage 后端系统入口点(使用 createBackendPlugin ()createBackendModule ()创建)必须导出为来自主软件包或 alpha 软件包的默认导出(如果插件实例支持仍使用 alpha API 提供)。这不会对插件实例的标准插件开发指南之上添加任何其他要求。

    动态导出机制标识私有依赖项,并在 package.json 文件中设置 bundleDependencies 字段。此导出机制可确保将动态插件软件包作为自包含的软件包发布,其私有依赖项捆绑在私有 node_modules 文件夹中。

    某些插件依赖项需要在派生的软件包中特定处理,例如:

    • 共享依赖关系 由 RHDH 应用程序提供,并列为 package.json 文件中的 对等依赖项,而不是捆绑在动态插件软件包中。例如,默认情况下,所有 @backstage 范围的软件包都将被共享。

      您可以使用 -shared-package 标志指定共享依赖项,这些依赖项应该由 Red Hat Developer Hub 应用程序提供,而不是捆绑在动态插件软件包中。

      要将 @backstage 软件包视为私有,请使用负前缀(!)。例如,当插件依赖于 @backstage 中的软件包时,该软件包不是由 Red Hat Developer Hub 应用程序提供。

    • 嵌入式依赖项 捆绑到动态插件软件包中,它们的依赖项与顶层相同。默认情况下,嵌入了带有 -node-common 后缀的软件包。

      您可以使用-- embed-package 标志指定其他嵌入的软件包。例如,来自同一工作区中的软件包不遵循默认命名约定。

      以下是使用共享和嵌入式软件包导出动态插件的示例:

      带有共享和嵌入式软件包的动态插件导出示例

      npx @red-hat-developer-hub/cli@latest plugin export --shared-package '!/@backstage/plugin-notifications/' --embed-package @backstage/plugin-notifications-backend

      在上例中:

    • @backstage/plugin-notifications 软件包被视为私有依赖项,并且捆绑在动态插件软件包中,尽管处于 @backstage 范围。
    • @backstage/plugin-notifications-backend 软件包标记为嵌入式依赖项,并捆绑到动态插件软件包中。
    前端插件

    前端插件可以使用 scalprum 进行配置,CLI 可以在导出过程中自动生成。运行以下命令时,生成的默认配置会被记录:

    记录默认配置的命令示例

    npx @red-hat-developer-hub/cli@latest plugin export

    以下是默认 scalprum 配置示例:

    默认 scalprum 配置

    "scalprum": {
      "name": "<package_name>",  // The Webpack container name matches the NPM package name, with "@" replaced by "." and "/" removed.
      "exposedModules": {
        "PluginRoot": "./src/index.ts"  // The default module name is "PluginRoot" and doesn't need explicit specification in the app-config.yaml file.
      }
    }

    您可以在 package.json 文件中添加 scalprum 部分。例如:

    scalprum 自定义示例

    "scalprum": {
      "name": "custom-package-name",
      "exposedModules": {
        "FooModuleName": "./src/foo.ts",
        "BarModuleName": "./src/bar.ts"
        // Define multiple modules here, with each exposed as a separate entry point in the Webpack container.
      }
    }

    动态插件可能需要调整 Developer Hub 需求,如用于挂载点或动态路由的静态 JSX。这些更改是可选的,但可能与静态插件不兼容。

    要包含静态 JSX,请定义一个额外的导出,并将其用作动态插件的 importName。例如:

    静态和动态插件导出示例

    // For a static plugin
    export const EntityTechdocsContent = () => {...}
    
    // For a dynamic plugin
    export const DynamicEntityTechdocsContent = {
      element: EntityTechdocsContent,
      staticJSXContent: (
        <TechDocsAddons>
          <ReportIssue />
        </TechDocsAddons>
      ),
    };

流程

  • 使用 @red-hat-developer-hub/cli 软件包中的 插件 export 命令来导出插件:

    导出第三方插件的命令示例

    npx @red-hat-developer-hub/cli@latest plugin export

    确保在插件的 JavaScript 软件包的根目录中执行上一命令(包含 package.json 文件)。

    生成的派生软件包将位于 dist-dynamic 子文件夹中。导出的软件包名称由原始插件名称组成,并附加了 -dynamic

    警告

    派生的动态插件 JavaScript 软件包不得发布到公共 NPM 注册表。有关更合适的打包选项,请参阅 第 2.2 节 “将第三方插件打包并发布为动态插件”。如果需要发布至 NPM 注册表,请使用私有 registry。

2.2. 将第三方插件打包并发布为动态插件

在导出第三方插件 后,您可以将派生的软件包打包成以下支持的格式之一:

  • 开放容器项目(OCI)镜像(推荐)
  • TGZ 文件
  • JavaScript 软件包

    重要

    导出的动态插件软件包必须仅发布到私有 NPM registry。

2.2.1. 使用动态软件包创建 OCI 镜像

先决条件

流程

  1. 导航到插件的根目录(而不是 dist-dynamic 目录)。
  2. 运行以下命令将插件打包到 OCI 镜像中:

    打包导出的第三方插件的命令示例

    npx @red-hat-developer-hub/cli@latest plugin package --tag quay.io/example/image:v0.0.1

    在上一命令中,--tag 参数指定镜像名称和标签。

  3. 运行以下命令之一将镜像推送(push)到 registry:

    使用 podman 将镜像推送到 registry 的命令示例

    podman push quay.io/example/image:v0.0.1

    使用 docker 将镜像推送到 registry 的命令示例

    docker push quay.io/example/image:v0.0.1

    package-dynamic-plugins 命令的输出提供了插件的路径,可在 dynamic-plugin-config.yaml 文件中使用。

2.2.2. 使用动态软件包创建 TGZ 文件

先决条件

流程

  1. 进入 dist-dynamic 目录。
  2. 运行以下命令来创建 tgz 归档:

    创建 tgz 归档的命令示例

    npm pack

    您可以使用-- json 标志从 npm pack 命令的输出中获取完整性哈希,如下所示:

    获取 tgz 归档的完整性哈希值的命令示例

    npm pack --json | head -n 10

  3. 在 RHDH 实例可访问的 Web 服务器上托管存档,并在 dynamic-plugin-config.yaml 文件中引用其 URL,如下所示:

    dynamic-plugin-config.yaml 文件示例

    plugins:
      - package: https://example.com/backstage-plugin-myplugin-1.0.0.tgz
        integrity: sha512-<hash>

  4. 运行以下命令来打包插件:

    打包动态插件的命令示例

    npm pack --pack-destination ~/test/dynamic-plugins-root/

    提示

    要使用 OpenShift Container Platform 上的 HTTP 服务器创建插件 registry,请运行以下命令:

    在 OpenShift Container Platform 中构建和部署 HTTP 服务器的命令示例

    oc project my-rhdh-project
    oc new-build httpd --name=plugin-registry --binary
    oc start-build plugin-registry --from-dir=dynamic-plugins-root --wait
    oc new-app --image-stream=plugin-registry

  5. 通过编辑 dynamic-plugin-config.yaml 文件,将 RHDH 配置为使用来自 HTTP 服务器的插件:

    在 RHDH 中使用打包插件的示例配置

    plugins:
      - package: http://plugin-registry:8080/backstage-plugin-myplugin-1.9.6.tgz

2.2.3. 使用动态软件包创建 JavaScript 软件包

警告

派生的动态插件 JavaScript 软件包不得发布到公共 NPM 注册表。如果需要发布至 NPM 注册表,请使用私有 registry。

先决条件

流程

  1. 进入 dist-dynamic 目录。
  2. 运行以下命令,将软件包发布到您的私有 NPM registry:

    将插件软件包发布到 NPM registry 的命令示例

    npm publish --registry <npm_registry_url>

    提示

    在运行 export 命令前,您可以在 package.json 文件中添加以下内容:

    package.json 文件示例

    {
      "publishConfig": {
        "registry": "<npm_registry_url>"
      }
    }

    如果在导出动态插件后修改 publishConfig,请重新运行 plugin export 命令,以确保包含正确的配置。

2.3. 在 Red Hat Developer Hub 中安装第三方插件

您可以在 Red Hat Developer Hub 中安装第三方插件,而无需重建 RHDH 应用程序。

dynamic-plugin-config.yaml 文件的位置取决于部署方法。如需了解更多详细信息,请参阅使用 Red Hat Developer Hub Operator 安装动态插件 和 使用 Helm Chart 安装动态插件

插件在 dynamic-plugin-config.yaml 文件中的 plugins 数组中定义。每个插件以具有以下属性的对象表示:

  • 软件包 :插件的软件包定义,可以是 OCI 镜像、TGZ 文件、JavaScript 软件包或目录路径。
  • disabled :指示插件是启用或禁用的布尔值。
  • 完整性 :软件包的完整性哈希值,TGZ 文件和 JavaScript 软件包是必需的。
  • pluginConfig :插件的配置。对于后端插件,这是可选的;对于 frontend 插件,需要它。pluginConfigapp-config.yaml 文件的片段,任何添加的属性都与 RHDH app-config.yaml 文件合并。
注意

您也可以从另一个目录加载动态插件,但这主要用于开发或测试目的,但不建议在生产环境中使用,除了 RHDH 容器镜像中包含的插件外。如需更多信息,请参阅 第 3 章 启用在 RHDH 容器镜像中添加的插件

2.3.1. 加载打包为 OCI 镜像的插件

先决条件

流程

  1. 要从经过身份验证的 registry 检索插件,请完成以下步骤:

    1. 登录到容器镜像 registry。

      podman login <registry>
    2. 验证登录后创建的 auth.json 文件的内容。

      cat ${XDG_RUNTIME_DIR:-~/.config}/containers/auth.json
    3. 使用以下示例创建 secret 文件:

      oc create secret generic _<secret_name>_ --from-file=auth.json=${XDG_RUNTIME_DIR:-~/.config}/containers/auth.json 
      1
      • 对于基于 Operator 的部署,将 < secret_name> 替换为 dynamic-plugins-registry-auth
      • 对于基于 Helm 的部署,将 < secret_name > 替换为 & lt;Helm_release_name>_-dynamic-plugins-registry-auth
  2. dynamic-plugins.yaml 文件中定义带有 oci:// 前缀的插件:

    oci:// &lt;image_name>:<tag>! &lt;plugin_name>

    dynamic-plugins.yaml 文件中的配置示例

    plugins:
      - disabled: false
        package: oci://quay.io/example/image:v0.0.1!backstage-plugin-myplugin

  3. 要执行完整性检查,请使用镜像摘要来代替 dynamic-plugins.yaml 文件中的标签,如下例所示:

    dynamic-plugins.yaml 文件中的配置示例

    plugins:
      - disabled: false
        package: oci://quay.io/example/image@sha256:28036abec4dffc714394e4ee433f16a59493db8017795049c831be41c02eb5dc!backstage-plugin-myplugin

  4. 要应用更改,请重启 RHDH 应用程序。

2.3.2. 加载打包为 TGZ 文件的插件

先决条件

流程

  1. 使用以下示例在 dynamic-plugins.yaml 文件中指定归档 URL 及其完整性哈希:

    dynamic-plugins.yaml 文件中的配置示例

    plugins:
      - disabled: false
        package: https://example.com/backstage-plugin-myplugin-1.0.0.tgz
        integrity: sha512-9WlbgEdadJNeQxdn1973r5E4kNFvnT9GjLD627GWgrhCaxjCmxqdNW08cj+Bf47mwAtZMt1Ttyo+ZhDRDj9PoA==

  2. 要应用更改,请重启 RHDH 应用程序。

2.3.3. 加载打包为 JavaScript 软件包的插件

先决条件

流程

  1. 运行以下命令以从 NPM registry 获取完整性哈希:

    npm view --registry <registry-link> <npm package>@<version> dist.integrity
  2. dynamic-plugins.yaml 文件中指定软件包名称、版本及其完整性哈希,如下所示:

    dynamic-plugins.yaml 文件中的配置示例

    plugins:
      - disabled: false
        package: @example/backstage-plugin-myplugin@1.0.0
        integrity: sha512-9WlbgEdadJNeQxdn1973r5E4kNFvnT9GjLD627GWgrhCaxjCmxqdNW08cj+Bf47mwAtZMt1Ttyo+ZhDRDj9PoA==

  3. 如果您使用自定义 NPM registry,请使用 registry URL 和身份验证详情创建一个 .npmrc 文件:

    .npmrc 文件示例

    registry=<registry-link>
    //<registry-link>:_authToken=<auth-token>

  4. 使用 OpenShift Container Platform 或 Kubernetes 时:

    • 使用 Helm Chart 通过创建 secret 添加 .npmrc 文件。例如:

      secret 配置示例

      apiVersion: v1
      kind: Secret
      metadata:
        name: <release_name>-dynamic-plugins-npmrc 
      1
      
      type: Opaque
      stringData:
        .npmrc: |
          registry=<registry-link>
          //<registry-link>:_authToken=<auth-token>

      1 1
      <release_name > 替换为您的 Helm 发行版本名称。此名称是 Kubernetes 集群中每个 chart 安装的唯一标识符。
    • 对于 RHDH Helm Chart,使用以下格式命名 secret 进行自动挂载:

      <release_name>-dynamic-plugins-npmrc

  5. 要应用更改,请重启 RHDH 应用程序。

本节介绍将 Todo 插件 集成到 Developer Hub 中的过程。

  1. 获取第三方插件源代码 :克隆 plugins 存储库并导航到 Todo 插件 目录:

    获取第三方插件源代码

    $ git clone https://github.com/backstage/community-plugins
    $ cd community-plugins/workspaces/todo
    $ yarn install

  2. 导出后端和前端插件 : 运行以下命令构建后端插件,调整动态加载的软件包依赖项,并生成自包含的配置模式:

    导出后端插件

    $ cd todo-backend
    $ npx @red-hat-developer-hub/cli@latest plugin export

    导出后端插件命令的输出

    Building main package
      executing     yarn build ✔
    Packing main package to dist-dynamic/package.json
    Customizing main package in dist-dynamic/package.json for dynamic loading
      moving @backstage/backend-common to peerDependencies
      moving @backstage/backend-openapi-utils to peerDependencies
      moving @backstage/backend-plugin-api to peerDependencies
      moving @backstage/catalog-client to peerDependencies
      moving @backstage/catalog-model to peerDependencies
      moving @backstage/config to peerDependencies
      moving @backstage/errors to peerDependencies
      moving @backstage/integration to peerDependencies
      moving @backstage/plugin-catalog-node to peerDependencies
    Installing private dependencies of the main package
       executing     yarn install --no-immutable ✔
    Validating private dependencies
    Validating plugin entry points
    Saving self-contained config schema in /Users/user/Code/community-plugins/workspaces/todo/plugins/todo-backend/dist-dynamic/dist/configSchema.json

    您可以运行以下命令来设置默认动态 UI 配置,创建前端插件资产,并为前端插件生成配置模式:

    导出前端插件

    $ cd ../todo
    $ npx @red-hat-developer-hub/cli@latest plugin export

    导出前端插件命令的输出

    No scalprum config. Using default dynamic UI configuration:
    {
      "name": "backstage-community.plugin-todo",
      "exposedModules": {
        "PluginRoot": "./src/index.ts"
      }
    }
    If you wish to change the defaults, add "scalprum" configuration to plugin "package.json" file, or use the '--scalprum-config' option to specify an external config.
    Packing main package to dist-dynamic/package.json
    Customizing main package in dist-dynamic/package.json for dynamic loading
    Generating dynamic frontend plugin assets in /Users/user/Code/community-plugins/workspaces/todo/plugins/todo/dist-dynamic/dist-scalprum
      263.46 kB  dist-scalprum/static/1417.d5271413.chunk.js
    ...
    ...
    ...
      250 B      dist-scalprum/static/react-syntax-highlighter_languages_highlight_plaintext.0b7d6592.chunk.js
    Saving self-contained config schema in /Users/user/Code/community-plugins/workspaces/todo/plugins/todo/dist-dynamic/dist-scalprum/configSchema.json

  3. 软件包并发布第三方插件 : 运行以下命令进入工作区目录,并打包动态插件以构建 OCI 镜像:

    构建 OCI 镜像

    $ cd ../..
    $ npx @red-hat-developer-hub/cli@latest plugin package --tag quay.io/user/backstage-community-plugin-todo:v0.1.1

    构建 OCI 镜像命令的输出

      executing     podman --version ✔
    Using existing 'dist-dynamic' directory at plugins/todo
    Using existing 'dist-dynamic' directory at plugins/todo-backend
    Copying 'plugins/todo/dist-dynamic' to '/var/folders/5c/67drc33d0018j6qgtzqpcsbw0000gn/T/package-dynamic-pluginsmcP4mU/backstage-community-plugin-todo
    No plugin configuration found at undefined create this file as needed if this plugin requires configuration
    Copying 'plugins/todo-backend/dist-dynamic' to '/var/folders/5c/67drc33d0018j6qgtzqpcsbw0000gn/T/package-dynamic-pluginsmcP4mU/backstage-community-plugin-todo-backend-dynamic
    No plugin configuration found at undefined create this file as needed if this plugin requires configuration
    Writing plugin registry metadata to '/var/folders/5c/67drc33d0018j6qgtzqpcsbw0000gn/T/package-dynamic-pluginsmcP4mU/index.json'
    Creating image using podman
      executing     echo "from scratch
    COPY . .
    " | podman build --annotation com.redhat.rhdh.plugins='[{"backstage-community-plugin-todo":{"name":"@backstage-community/plugin-todo","version":"0.2.40","description":"A Backstage plugin that lets you browse TODO comments in your source code","backstage":{"role":"frontend-plugin","pluginId":"todo","pluginPackages":["@backstage-community/plugin-todo","@backstage-community/plugin-todo-backend"]},"homepage":"https://backstage.io","repository":{"type":"git","url":"https://github.com/backstage/community-plugins","directory":"workspaces/todo/plugins/todo"},"license":"Apache-2.0"}},{"backstage-community-plugin-todo-backend-dynamic":{"name":"@backstage-community/plugin-todo-backend","version":"0.3.19","description":"A Backstage backend plugin that lets you browse TODO comments in your source code","backstage":{"role":"backend-plugin","pluginId":"todo","pluginPackages":["@backstage-community/plugin-todo","@backstage-community/plugin-todo-backend"]},"homepage":"https://backstage.io","repository":{"type":"git","url":"https://github.com/backstage/community-plugins","directory":"workspaces/todo/plugins/todo-backend"},"license":"Apache-2.0"}}]' -t 'quay.io/user/backstage-community-plugin-todo:v0.1.1' -f - .
        ✔
    Successfully built image quay.io/user/backstage-community-plugin-todo:v0.1.1 with following plugins:
      backstage-community-plugin-todo
      backstage-community-plugin-todo-backend-dynamic
    
    Here is an example dynamic-plugins.yaml for these plugins:
    
    plugins:
      - package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo
        disabled: false
      - package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo-backend-dynamic
        disabled: false

    将 OCI 镜像推送到容器 registry:

    $ podman push quay.io/user/backstage-community-plugin-todo:v0.1.1

    推送 OCI image 命令的输出

    Getting image source signatures
    Copying blob sha256:86a372c456ae6a7a305cd464d194aaf03660932efd53691998ab3403f87cacb5
    Copying config sha256:3b7f074856ecfbba95a77fa87cfad341e8a30c7069447de8144aea0edfcb603e
    Writing manifest to image destination

  4. 安装和配置第三方插件:在 dynamic- plugins.yaml 文件中添加以下插件定义:

    dynamic-plugins.yaml 文件中的插件定义

    packages:
     - package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo
       pluginConfig:
         dynamicPlugins:
           frontend:
             backstage-community.plugin-todo:
               mountPoints:
                 - mountPoint: entity.page.todo/cards
                   importName: EntityTodoContent
               entityTabs:
                 - path: /todo
                   title: Todo
                   mountPoint: entity.page.todo
     - package: oci://quay.io/user/backstage-community-plugin-todo:v0.1.1!backstage-community-plugin-todo-backend-dynamic
       disabled: false

第 3 章 启用在 RHDH 容器镜像中添加的插件

在 RHDH 容器镜像中,会预加载一组动态插件来增强功能。但是,由于强制配置要求,大多数插件都被禁用。

您可以在 RHDH 容器镜像中启用和配置插件,包括如何管理默认配置,设置必要的环境变量,并确保应用程序中的插件正常工作。

先决条件

  • 您可以访问 dynamic-plugins.default.yaml 文件,该文件列出所有预加载的插件及其默认配置。
  • 您已部署了 RHDH 应用程序,并可访问 install-dynamic-plugins init 容器的日志。
  • 您有修改插件配置并访问应用程序环境所需的权限。
  • 您已识别并设置插件默认配置引用的必要环境变量。这些环境变量必须在 Helm Chart 或 Operator 配置中定义。

流程

  1. 启动 RHDH 应用程序,并访问 RHDH pod 中 install-dynamic-plugins init 容器的日志。
  2. 识别默认情况下禁用的 红帽支持插件
  3. dynamic-plugins.default.yaml 文件中复制软件包配置。
  4. 打开插件配置文件,并找到您要启用的插件条目。

    插件配置文件的位置因部署方法而异。如需了解更多详细信息,请参阅 Red Hat Developer Hub 中安装和查看插件

  5. disabled 字段修改为 false,并添加软件包名称,如下所示:

    插件配置示例

    plugins:
      - disabled: false
        package: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-dynamic

    有关如何在 Developer Hub 中配置动态插件的更多信息,请参阅配置动态插件

验证

  1. 重启 RHDH 应用程序,并验证插件是否已成功激活和配置。
  2. 验证应用程序日志以确认,并确保插件按预期工作。

第 4 章 Red Hat Developer Hub 中的扩展

重要

这些功能仅用于技术预览。红帽产品服务级别协议(SLA)不支持技术预览功能,且其功能可能并不完善,因此红帽不建议在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

Red Hat Developer Hub (RHDH)包括预装并启用的扩展功能。扩展功能为用户提供了用于浏览和管理可用插件的集中界面

您可以使用扩展来发现扩展 RHDH 功能、简化开发工作流并改进开发人员体验的插件。

4.1. 查看可用插件

您可以在 Extensions 页面中查看 Red Hat Developer Hub 应用程序可用的插件。

流程

  1. 打开 Developer Hub 应用程序,然后点击 Administration > Extensions
  2. 前往 Catalog 选项卡,以查看可用插件和相关信息的列表。

    extensions Catalog

4.2. 查看已安装的插件

使用 Dynamic Plugins Info 前端插件,您可以查看当前安装在 Red Hat Developer Hub 应用程序中的插件。此插件默认是启用的。

流程

  1. 打开 Developer Hub 应用程序,然后点击 Administration > Extensions
  2. 进入 Installed 选项卡,以查看已安装的插件列表和相关信息。

4.3. 搜索并过滤插件

4.3.1. 根据插件名称搜索

您可以使用标头中的搜索栏来根据名称过滤 Extensions 插件卡。例如,如果您在搜索栏中键入 "A",则 Extensions 仅显示了在 Name 字段中包含字母"A"的插件。

带有 Dynatrace 搜索的扩展目录

另外,您还可以将搜索栏与过滤器结合使用,以仅根据名称过滤所选过滤器的插件。例如,您可以应用 Category 过滤器,然后在搜索栏中输入字符,以仅查看名称中包含键入字符的 Openshift 插件。

可用的过滤器如下:

  • 类别
  • 作者
  • 支持类型

4.4. 删除扩展

Red Hat Developer Hub (RHDH)中预装了扩展功能插件,并默认启用。如果要从 RHDH 实例中删除扩展,您可以禁用相关的插件。

流程

  1. 要禁用扩展功能插件,请使用以下内容编辑 dynamic-plugins.yaml

    dynamic-plugins.yaml 片段

    plugins:
      - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-marketplace
        disabled: true
      - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-catalog-backend-module-marketplace-dynamic
        disabled: true
      - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-marketplace-backend-dynamic
        disabled: true

注意

如果您禁用 Extensions 功能插件, 目录和 Installed 选项卡也会被删除。您仍然可以通过点 Administration > Extensions 来查看已安装的插件。

4.5. 使用扩展管理插件

您可以使用 扩展 来安装和配置插件。

警告

使用扩展安装和配置插件仅在开发环境中正常工作。在生产环境中不支持此功能。

在生产环境中,用户会收到不允许插件安装的通知。

extensions restart plugin 1

在开发环境中:

  • 管理员可以使用编辑器中预加载的默认配置来安装插件,或者在安装前修改配置。成功安装后,用户会收到需要重启后端才能完成安装过程。
  • 安装插件后,管理员可以访问插件侧面面板中的 Actions 下拉菜单。可用的操作包括:

    • 编辑在安装过程中使用的配置
    • 禁用或启用插件
    • 执行这些操作后,用户会收到需要重启后端才能使更改生效。

4.5.1. 配置 RBAC 以管理扩展

您可以通过创建或更新和现有的 RBAC 角色来添加扩展权限。有关使用 RBAC 管理基于角色的访问控制的更多信息,请参阅使用 Red Hat Developer Hub Web UI 管理基于角色的访问控制(RBAC)

先决条件

  • 您已启用了 RBAC,在 Developer Hub 中有一个策略管理员角色,并添加了带有权限的插件。

流程

  1. 进入 Developer Hub 中边栏底部的 管理

    此时会出现 RBAC 选项卡,在 Developer Hub 中显示所有创建的角色。

  2. 单击 Create 以创建角色。
  3. 在给定字段中输入角色的用户名和密码(可选),然后单击 Next
  4. Add users and groups 中,选择用户名,然后单击 Next
  5. 添加权限策略 中,从插件下拉菜单中选择 扩展
  6. 展开 Extensions,为 Extensions 插件选择 CreateRead 权限,然后点 Next
  7. 单击 Create 以创建该角色。

    扩展 rbac 角色创建

验证

刷新 RHDH 应用程序时,当您选择插件时,Actions 下拉列表是活跃的。当点 Actions 下拉菜单时,您可以编辑插件配置,并启用或禁用插件。

4.5.2. 配置 RHDH 以使用扩展安装插件

当使用 Extensions UI 安装插件时,您使用的配置会保存到 dynamic-plugins-root 持久性卷中的 dynamic-plugins.extensions.yaml 文件中。这样可确保在重启应用程序时可以使用配置,供您编辑或重新启用插件。

您必须创建一个持久性卷声明(PVC),以确保在重启 RHDH 应用程序时缓存会保留。有关使用动态插件缓存的更多信息,请参阅使用动态插件缓存

先决条件

  • 您已使用名称 dynamic-plugins-root 为动态插件缓存创建一个持久性卷声明(PVC)。
  • 已使用 Helm Chart 或 Operator 安装 Red Hat Developer Hub。
  • 已安装 OpenShift CLI(oc)。

流程

  1. 创建扩展配置文件并将其保存为 dynamic-plugins.extensions.yaml。例如:

    includes:
      - dynamic-plugins.default.yaml
    
    plugins:
      - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-marketplace
        disabled: false
        pluginConfig:
          dynamicPlugins:
            frontend:
              red-hat-developer-hub.backstage-plugin-marketplace:
                appIcons:
                  - name: marketplace
                    importName: MarketplaceIcon
                dynamicRoutes:
                  - path: /extensions/catalog
                    importName: DynamicMarketplacePluginRouter
                mountPoints:
                  - mountPoint: application/provider
                    importName: InstallationContextProvider
                  - mountPoint: internal.plugins/tab
                    importName: DynamicMarketplacePluginContent
                    config:
                      path: marketplace
                      title: Catalog
                      icon: CatalogTabIcon
      - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-marketplace-backend-dynamic
        disabled: false
        pluginConfig:
          extensions:
            installation:
              enabled: true
              saveToSingleFile:
                file: /opt/app-root/src/dynamic-plugins-root/dynamic-plugins.extensions.yaml
  2. 运行以下命令将文件复制到集群中:

    oc get pods -n <your-namespace>
    
    oc cp ./dynamic-plugins.extensions.yaml <your-namespace>/<pod-name>:/opt/app-root/src/dynamic-plugins-root/dynamic-plugins.extensions.yaml
  3. 更新您的 RHDH 应用程序以使用此文件:

    1. 对于基于 operator 的安装:

      1. 更新 Backstage CR,将 NODE_ENV 环境变量更新为 development,如下所示:

        apiVersion: rhdh.redhat.com/v1alpha3
        kind: Backstage
        metadata:
          name: developer-hub
          namespace: rhdh
        spec:
          application:
            dynamicPluginsConfigMapName: dynamic-plugins-rhdh
            extraEnvs:
              envs:
                - name: NODE_ENV
                  value: "development"
              secrets:
                - name: secrets-rhdh
            extraFiles:
              mountPath: /opt/app-root/src
            route:
              enabled: true
          database:
            enableLocalDb: true
      2. 更新您的 dynamic-plugins-rhdh 配置映射使其包含您的扩展配置文件,如下所示:

        kind: ConfigMap
        apiVersion: v1
        metadata:
          name: dynamic-plugins-rhdh
          namespace: rhdh
        data:
         dynamic-plugins.yaml: |
           includes:
             - dynamic-plugins.default.yaml
             - /dynamic-plugins-root/dynamic-plugins.extensions.yaml
           plugins: []
    2. 对于 Helm Chart 安装:

      1. 升级 Helm 发行版本使其包含扩展配置文件,并将 NODE_ENV 环境变量更新为 development

        global:
          auth:
            backend:
              enabled: true
          clusterRouterBase: apps.<clusterName>.com
          dynamic:
            includes:
              - dynamic-plugins.default.yaml
              - /dynamic-plugins-root/dynamic-plugins.extensions.yaml
        upstream:
          backstage:
            extraEnvVars:
              - name: NODE_ENV
                value: development
      2. Upgrade

验证

使用 Extensions UI 启用插件,重启 RHDH 应用程序并刷新 UI 以确认插件是否已启用。

4.5.3. 配置 RHDH Local 以使用扩展安装插件

您可以使用 RHDH Local 来使用扩展来测试安装插件。

先决条件

流程

  1. 更新您的 dynamic-plugins.override.yaml 文件:

    includes:
      - dynamic-plugins.default.yaml
    
    plugins:
      - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-marketplace
        disabled: false
        pluginConfig:
          dynamicPlugins:
            frontend:
              red-hat-developer-hub.backstage-plugin-marketplace:
                appIcons:
                  - name: marketplace
                    importName: MarketplaceIcon
                dynamicRoutes:
                  - path: /extensions/catalog
                    importName: DynamicMarketplacePluginRouter
                mountPoints:
                   - mountPoint: application/provider
                     importName: InstallationContextProvider
                  - mountPoint: internal.plugins/tab
                    importName: DynamicMarketplacePluginContent
                    config:
                      path: marketplace
                      title: Catalog
      - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-marketplace-backend-dynamic
        disabled: false
        pluginConfig:
          extensions:
            installation:
              enabled: true
              saveToSingleFile:
                file: /opt/app-root/src/configs/dynamic-plugins/dynamic-plugins.override.yaml
  2. 更新 compose.yaml 文件:

    rhdh:
      container_name: rhdh
      environment:
        NODE_OPTIONS: "--inspect=0.0.0.0:9229"
        NODE_ENV: "development"

验证

使用 Extensions UI 启用插件,重启 RHDH 应用程序并刷新 UI 以确认插件是否已启用。

4.5.4. 使用扩展安装插件

您可以使用扩展来安装和配置插件。

先决条件

  • 您已将 RHDH 配置为允许来自 扩展 插件安装。
  • 您已将 RBAC 配置为允许当前用户管理插件配置。

流程

  1. 导航到 Extensions
  2. 选择要安装的插件。
  3. Install 按钮。

    extensions 安装插件 1

    此时会显示代码编辑器,显示插件默认配置。

  4. 如果需要,更新插件配置。

    extensions 安装插件 2
  5. Install
  6. 要查看需要重启的插件,请点警报消息中的 View plugins

    扩展安装插件 3
  7. 重启您的 RHDH 应用程序。

验证

  1. 重启 RHDH 应用程序后,导航到 Extensions
  2. 选择已安装的插件。
  3. 此时会显示 Actions 按钮。

4.5.5. 使用扩展启用和禁用插件

先决条件

  • 您已将 RHDH 配置为允许来自 扩展 插件安装。
  • 您已配置了 RBAC,以允许当前用户访问插件配置。

流程

  1. 导航到 Extensions
  2. 选择要启用或禁用的插件。
  3. 点 Enable/Disable slider。

    extensions 启用插件 1
  4. 要查看需要重启的插件,请点警报消息中的 View plugins

    扩展安装插件 3
  5. 重启您的 RHDH 应用程序。

验证

  1. 重启 RHDH 应用程序后,导航到 Extensions
  2. 选择已安装的插件。
  3. Enable/Disable 滑块已更新。

第 5 章 插件故障排除

5.1. 启用插件后,RHDH pod 无法启动

流程

  1. 检查 RHDH pod 日志,以识别插件是否需要特定的环境变量或额外的配置,例如:

    Plugin '<PLUGIN_NAME>' threw an error during startup, waiting for X other plugins to finish before shutting down the process. Plugin '<PLUGIN_NAME>' startup failed; caused by Error: Missing required config value at '<concretePluginRequiredVariable.name>' in 'app-config.local.yaml' type="initialization"
  2. 通过检查 dynamic-plugins.default.yaml 文件来验证所需的配置,该文件列出了每个插件所需的环境变量。每个插件的变量格式为 ${PLUGIN_VARIABLE_NAME}
  3. 如果缺少所需的环境变量,请使用 secret 设置环境变量。例如:

    kind: Secret
    apiVersion: v1
    metadata:
      name: rhdh-secrets
      labels:
        backstage.io/kubernetes-id: developer-hub
    data:
      PLUGIN_VARIABLE_NAME: 'dummy-value'
    type: Opaque
  4. 挂载 secret:

    1. 如果使用 Operator 部署 RHDH,请更新 Backstage CR,如下所示:

      spec:
        application:
          extraEnvs:
            secrets:
              - name: rhdh-secrets
    2. 如果使用 Helm Chart 部署 RHDH,请在 Helm Chart 值中的 upstream.backstage 键中,输入 Developer Hub rhdh-secrets secret 的名称作为 extraEnvVarsSecrets 字段的值。例如:

      upstream:
        backstage:
          extraEnvVarsSecrets:
            - rhdh-secrets

第 6 章 前端插件

您可以配置前端插件来自定义图标,在挂载点上集成组件,并提供或替换实用程序 API。

6.1. 扩展内部图标目录

您可以使用内部目录获取使用边栏导航菜单配置的路由的图标。

流程

  • 使用 appIcons 配置,在插件的菜单项中使用的内部图标目录中添加自定义图标,如下例所示:
# dynamic-plugins-config.yaml
plugins:
  - plugin: <plugin_path_or_url>
    disabled: false
    pluginConfig:
      dynamicPlugins:
        frontend:
          my-plugin:  # The plugin package name
            appIcons:
              - name: fooIcon # The icon catalog name
                # (Optional): The set of assets to access within the plugin. If not specified, the system uses the `PluginRoot` module.
                module: CustomModule
                # (Optional): The actual component name to be rendered as a standalone page. If not specified, the system uses the `default` export.
                importName: FooIcon
注意

dynamicPlugins.frontend 中的 package_name 键必须与插件的 package.json 中的 scalprum.name 值匹配。这样可确保您的动态插件在运行时正确加载。

6.2. 为新插件页面定义动态路由

流程

  1. 通过指定一个唯一 路径 来定义每个路由,如果需要,则指定 importName (如果它 与默认 导出不同)。
  2. 通过配置 dynamicRoutes,在动态插件中公开其他路由,如下例所示:

    # dynamic-plugins-config.yaml
    plugins:
      - plugin: <plugin_path_or_url>
        disabled: false
        pluginConfig:
          dynamicPlugins:
            frontend:
              my-plugin: # The plugin package name
                dynamicRoutes:
                    # The unique path in the application. The path cannot override existing routes except the `/` home route.
                  - path: /my-plugin
                    # (Optional): The set of assets to access within the plugin. If not specified, the system uses the `PluginRoot` module.
                    module: CustomModule
                    # (Optional): The component name as a standalone page. If not specified, the system uses the `default` export.
                    importName: FooPluginPage
                    # Allows you to extend the main sidebar navigation and point to a new route.
                    menuItem:
                      icon: fooIcon
                      text: Foo Plugin Page
                      enabled: false
                    config: # (Optional): Passes `props` to a custom sidebar item
                      props: ...

    menuItem 接受以下属性:

    • 文本 :显示给用户的标签。
    • 图标 : Backstage system 图标名称。
    • Enabled: 可选:允许用户在侧边栏设置为 false 时从侧边栏中删除 menuItem。
    • importName :指定导出的 SidebarItem 组件的可选名称。

      要配置自定义 SidebarItem 以增强通知徽标等体验,请确保组件接受以下属性:

export type MySidebarItemProps = {
  to: string; // supplied by the sidebar during rendering, this will be the path configured for the dynamicRoute
};

指定自定义 SidebarItem 组件示例:

# dynamic-plugins-config.yaml
plugins:
  - plugin: <plugin_path_or_url>
    disabled: false
    pluginConfig:
      dynamicPlugins:
        frontend:
          my-dynamic-plugin-package-name:
            dynamicRoutes:
              - importName: CustomPage
                menuItem:
                  config:
                    props:
                      text: Click Me!
                  importName: SimpleSidebarItem
                path: /custom_page

6.3. 在侧边栏导航中自定义菜单项

您可以使用菜单项配置在主侧边栏导航中自定义插件菜单项的顺序和父子关系,如下例所示:

# dynamic-plugins-config.yaml
plugins:
  - plugin: <plugin_path_or_url>
    disabled: false
    pluginConfig:
      dynamicPlugins:
        frontend:
          my-plugin: # The plugin package name
            menuItems:
              # The unique name in the main sidebar navigation (for example, either a standalone menu item or a parent menu item)
              <menu_item_name>:
                # (Optional): The icon for the menu item, which refers to a Backstage system icon
                icon: fooIcon
                # (Optional): The display title of the menu item
                title: Foo Plugin Page
                # (Optional): The order in which menu items appear. The default priority is `0`.
                priority: 10
                # (Optional): Defines the parent menu item to nest the current item under
                parent: favorites
                # (Optional): Allows you to remove a `menuItem` from the sidebar when it is set to `false`
                enabled: false

处理复杂路径:

  • 对于类似 path: /my-plugin 的简单路径,menu_item_name 应为 my-plugin
  • 对于 /metrics/users/info 等复杂路径,menu_item_name 应该以点表示法表示完整路径(如 metrics.users.info)。
  • 忽略路径中的结尾和前导斜杠,如下所示:

    • 对于 path: /docsmenu_item_namedocs
    • 对于 path: /metrics/usersmenu_item_namemetrics.users
注意

Red Hat Developer Hub 支持最多 3 级嵌套菜单项。

6.4. 绑定到现有插件

您可以绑定到现有插件及其路由,并声明来自动态插件的新目标,如以下 routeBindings 配置中所示:

# dynamic-plugins-config.yaml
plugins:
  - plugin: <plugin_path_or_url>
    disabled: false
    pluginConfig:
      dynamicPlugins:
        frontend:
          my-plugin: # The plugin package name
            routeBindings:
              targets: # A new bind target
                  # (Optional): Defaults to importName. Explicit name of the plugin that exposes the bind target.
                - name: barPlugin
                  # (Required): Explicit import name that reference a BackstagePlugin<{}> implementation.
                  importName: barPlugin
                  # # (Optional): Same as key in `scalprum.exposedModules` key in the `package.json` file of the plugin.
                  module: CustomModule
              bindings:
                - bindTarget: "barPlugin.externalRoutes" # (Required): One of the supported or imported bind targets
                  bindMap: #  A required map of route bindings similar to `bind` function options
                    headerLink: "fooPlugin.routes.root"

要配置 routeBindings,请完成以下步骤:

  1. 使用 routeBindings.targets 定义新目标。将所需的 importName 设置为 BackstagePlugin<{}> 实现。
  2. 通过将 bindTarget 设置为要绑定到的目标名称,使用 routeBindings.bindings 字段来声明路由绑定。这是一个动态或静态目标,例如:

    • catalogPlugin.externalRoutes
    • catalogImportPlugin.externalRoutes
    • techdocsPlugin.externalRoutes
    • scaffolderPlugin.externalRoutes

      您可以使用挂载点扩展现有页面,它们是应用中预定义的标识符。

6.5. 使用挂载点

挂载点是定义的标识符,可在 Red Hat Developer Hub 之间提供。您可以使用这些点来扩展带有额外内容的现有页面。

6.5.1. 自定义实体页面

您可以扩展目录组件和其他视图。

可用的挂载点包括:

Expand
表 6.1. 输入参数
挂载点描述即使没有启用插件,也可见

admin.page.plugins

管理插件页面

admin.page.rbac

管理 RBAC 页面

entity.context.menu

目录实体上下文菜单

所有实体的 YES

entity.page.overview

目录实体概览页面

所有实体的 YES

entity.page.topology

目录实体 拓扑 标签页

entity.page.issues

目录实体 问题 标签页

entity.page.pull-requests

目录实体 Pull Requests 选项卡

entity.page.ci

目录实体 CI 选项卡

entity.page.cd

目录实体 CD 标签页

entity.page.kubernetes

目录实体 Kubernetes 标签页

entity.page.image-registry

Catalog entity Image Registry 标签页

entity.page.monitoring

目录实体 监控 标签页

entity.page.lighthouse

目录实体 Lighthouse 选项卡

entity.page.api

目录实体 API 标签页

YES 用于 kind: Componentspec.type: 'service'

entity.page.dependencies

目录实体 依赖项 标签页

YES 用于类型 实体:组件

entity.page.docs

目录实体 文档 标签页

适用于满足 TechDocsAvailable的实体的 YES

entity.page.definition

目录实体 定义 标签页

YES 用于 种类的实体:Api

entity.page.diagram

目录实体 选项卡

适用于类型实体的 YES:系统

search.page.types

搜索结果类型

YES,默认目录搜索类型可用

search.page.filters

搜索过滤器

YES、默认目录类型和生命周期过滤器可见

search.page.results

搜索结果内容

YES,存在默认目录搜索

注意

在目录内挂载点,如 entity.page. 呈现为标签页,只有在至少有一个插件贡献它们时或可以呈现静态内容时才可见。

每个 entity.page. 挂载点都包含以下变体:

  • 用于创建 React 上下文的 /context 类型
  • 常规 React 组件的 /cards 类型

以下是挂载点的整体配置结构的示例:

# dynamic-plugins-config.yaml
plugins:
  - plugin: <plugin_path_or_url>
    disabled: false
    pluginConfig:
      dynamicPlugins:
        frontend:
          my-plugin: # The plugin package name
            mountPoints: # (Optional): Uses existing mount points
              - mountPoint: <mountPointName>/[cards|context]
                module: CustomModule
                importName: FooPluginPage
                config: # (Optional): Allows you to pass additional configuration to the component
                  layout: {} # Used only in `/cards` type which renders visible content
                  # Use only in `/cards` type which renders visible content. `if` is passed to `<EntitySwitch.Case if={<here>}`.
                  if:
                    allOf|anyOf|oneOf:
                      - isMyPluginAvailable
                      - isKind: component
                      - isType: service
                      - hasAnnotation: annotationKey
                  props: {} # Useful when you are passing additional data to the component

可用的条件包括:

  • All Of: 必须满足所有条件
  • anyOf: 必须至少满足一个条件
  • oneOf: 只满足一个条件

条件为:

  • isKind: 接受字符串或带有实体类型的字符串列表。例如,isKind: component 仅为 kind: Component 实体呈现组件。
  • isType: 接受字符串或带有实体类型的字符串列表。例如 ,isType: 服务 仅对 spec.type: 'service' 实体呈现组件。
  • hasAnnotation: 接受字符串或带有注解键的字符串列表。例如 ,withAnnotation: my-annotation 只适用于定义了 metadata.annotations['my-annotation'] 的实体的组件。
  • 从插件 模块 导入的条件:必须是从插件中的同一 模块 导出的函数名称。例如,是MyPluginAvailable,只有在 isMyPluginAvailable 功能返回 true 时才会呈现组件。函数必须具有以下签名: (e: Entity) select boolean.

实体页面支持向页面右上角的上下文菜单添加更多项目。导出的组件是一个对话框打包程序组件,接受 打开 的布尔值属性和 onClose 事件处理器属性,如下例所示:

export type SimpleDialogProps = {
  open: boolean;
  onClose: () => void;
};

您可以使用挂载点的 props 配置条目来配置上下文菜单条目。titleicon 属性设置菜单项的文本和图标。您可以使用通过动态插件添加的任何系统图标或图标。以下是一个配置示例:

# dynamic-plugins-config.yaml
plugins:
  - plugin: <plugin_path_or_url>
    disabled: false
    pluginConfig:
      dynamicPlugins:
        frontend:
          my-dynamic-plugin-package:
            appIcons:
              - name: dialogIcon
                importName: DialogIcon
            mountPoints:
              - mountPoint: entity.context.menu
                importName: SimpleDialog
                config:
                  props:
                    title: Open Simple Dialog
                    icon: dialogIcon

6.5.2. 添加应用程序标头

您可以通过在 app-config.yaml 文件中指定配置来自定义全局标头,如下例所示:

# app-config.yaml
dynamicPlugins:
  frontend:
    my-plugin:  # The plugin package name
      mountPoints:
        - mountPoint: application/header # Adds the header as a global header
          importName: <header_component> # Specifies the component exported by the global header plugin
          config:
            position: above-main-content # Supported values: (`above-main-content`| above-sidebar`)
注意

要在不同位置配置多个全局标头,请在 mountPoints 字段中添加条目。

6.5.3. 添加应用程序监听程序

您可以使用 application/listener 挂载点添加应用程序监听程序,如下例所示:

# app-config.yaml
dynamicPlugins:
  frontend:
    my-plugin: # The plugin package name
      mountPoints:
        - mountPoint: application/listener
          importName: <exported listener component>
注意

您可以通过在 mountPoints 字段中添加条目来配置多个应用程序监听程序。

6.5.4. 添加应用程序供应商

您可以使用 application/provider 挂载点添加应用程序供应商。您可以使用挂载点来配置上下文供应商,如下例所示:

# app-config.yaml
dynamicPlugins:
  frontend:
    my-plugin: # The plugin package name
      dynamicRoutes:
        - path: /<route>
          importName: Component # The component to load on the route
      mountPoints:
        - mountPoint: application/provider
          importName: <exported provider component>
注意
  1. 您可以通过在 mountPoints 字段中添加条目来配置多个应用提供程序。
  2. dynamicPlugins.frontend 下的 package_name 键必须与插件的 package.json 文件中的 scalprum.name 值匹配。这样可确保您的动态插件在运行时正确加载。

6.6. 自定义和扩展实体标签页

您可以使用 entityTabs 配置自定义和扩展一组标签页,如下所示:

# dynamic-plugins-config.yaml
plugins:
  - plugin: <plugin_path_or_url>
    disabled: false
    pluginConfig:
      dynamicPlugins:
        frontend:
          my-plugin: # The plugin package name
            entityTabs:
              # Specify a new tab
              - path: /new-path
                title: My New Tab
                mountPoint: entity.page.my-new-tab
              # Change an existing tab's title or mount point
              - path: /
                title: General
                mountPoint: entity.page.overview
                # Specify the sub-path route in the catalog where this tab is available
              - path: "/pr"
                title: "Changed Pull/Merge Requests" # Specify the title you want to display
                priority: 1
                # The base mount point name available on the tab. This name expands to create two mount points per tab, with` /context` and with `/cards`
                mountPoint: "entity.page.pull-requests"
              - path: "/"
                title: "Changed Overview"
                mountPoint: "entity.page.overview"
                # Specify the order of tabs. The tabs with higher priority values appear first
                priority: -6

您可以配置动态前端插件,以目标由 entityTab 配置公开的挂载点。以下是以默认顺序路由的默认目录实体路由:

Expand
表 6.2. 输入参数
Route标题挂载点实体 Kind

/

概述

entity.page.overview

任意

/topology

Topology

entity.page.topology

任意

/issues

问题

entity.page.issues

任意

/pr

CPull/Merge Requests

entity.page.pull-requests

任意

/ci

CI

entity.page.ci`

VAny

/cd

CD

entity.page.cd

任意

/kubernetes

Kubernetes

entity.page.kubernetes

任意

/image-registry

镜像 Registry

entity.page.image-registry

任意

/monitoring

监控

entity.page.monitoring

任意

/lighthouse

lighthouse

entity.page.lighthouse

任意

/api

Api

entity.page.api

kind: Service 或 kind: Component

/dependencies

依赖项

entity.page.dependencies

kind: Component

/docs

文档

entity.page.docs

任意

/definition

定义

entity.page.definition

kind: API

/system

图表

entity.page.diagram

kind: System

注意

Catalog 中的挂载点(如 'entity.page ""' )呈现为标签页,只有在至少有一个插件贡献它们时或可以呈现静态内容时才可见。

6.7. 使用自定义 SignInPage 组件

在 Red Hat Developer Hub (RHDH)中,SignInPage 组件管理应用程序的身份验证流。此组件将一个或多个身份验证供应商连接到登录过程。默认情况下,Developer Hub 使用静态 SignInPage,它支持所有内置身份验证供应商。

当您配置自定义 SignInPage 时:

  • 系统从动态插件加载指定的 importName 组件。
  • 组件返回一个配置的 SignInPage,它连接所需的身份验证供应商工厂。
  • 一次只为应用程序指定一个 signInPage
dynamicPlugins:
  frontend:
    my-plugin: # The plugin package name
      signInPage:
        importName: CustomSignInPage
注意

dynamicPlugins.frontend 中指定的 package_name 必须与插件的 package.json 文件中的 scalprum.name 值匹配,以确保在运行时正确加载动态插件。

module 字段是可选的,允许指定必须在动态插件中访问哪些资产集合。默认情况下,系统使用 PluginRoot 模块。

6.8. 提供自定义 Scaffolder 字段扩展

Red Hat Developer Hub (RHDH)中的 Scaffolder 组件允许用户通过指导向导使用模板创建软件组件。您可以使用 scaffolderFieldExtensions 配置将自定义表单字段作为动态插件提供来扩展 Scaffolder 的功能。

自定义字段扩展允许您添加在构建过程中捕获特定域数据的专用表单字段,如环境选择器、输入验证或存储库检查。

当您配置自定义 scaffolder 字段扩展时:

  • 动态插件使用 createScaffolderFieldExtension 来公开字段扩展组件。
  • 每个字段扩展都需要一个唯一的 importName 才能注册。
  • 您可以通过在配置中列出每个字段来注册多个字段扩展。
dynamicPlugins:
  frontend:
    my-plugin: # The plugin package name
      scaffolderFieldExtensions:
        - importName: MyNewFieldExtension # References the exported scaffolder field extension component from your plugin
注意

module 字段是可选的,指定插件中要访问哪些资产集。默认情况下,系统使用 PluginRoot 模块,与软件包的 package.json 文件中的 scalprum.exposedModules 键一致。

6.9. 提供额外的实用程序 API

如果动态插件导出由 createPlugin 返回的插件对象,则会将其提供给 createApp API。插件导出的所有 API 因子应用程序自动注册并可用。

当动态插件只包含 API 工厂时,您可以在 dynamicPlugins.frontend 配置中添加一个条目,如下例所示:

# app-config.yaml
dynamicPlugins:
  frontend:
    my-dynamic-plugin-package-with-api-factories: {}

但是,当动态插件没有导出插件对象时,明确配置必须使用 apiFactories 配置注册的每个 API 工厂,如下例所示:

# app-config.yaml
dynamicPlugins:
  frontend:
    my-plugin: # The plugin package name
      apiFactories:
        # (Optional): Specify the import name that references a `AnyApiFactory<{}>` implementation. (Defaults to `default` export)
        - importName: BarApi
          # (Optional): An argument which specifies the assets you want to access within the plugin. If not provided, the default module named `PluginRoot` is used
          module: CustomModule

通过指定相同的 API ref ID,Developer Hub 应用程序 shell 初始化的 API 工厂会被动态插件提供的 API 工厂覆盖。动态插件可以将 AnyApiFactory<{} > 导出为某些特定用例的 cater,如下例所示:

export const customScmAuthApiFactory = createApiFactory({
  api: scmAuthApiRef,
  deps: { githubAuthApi: githubAuthApiRef },
  factory: ({ githubAuthApi }) =>
    ScmAuth.merge(
      ScmAuth.forGithub(githubAuthApi, { host: "github.someinstance.com" }),
      ScmAuth.forGithub(githubAuthApi, {
        host: "github.someotherinstance.com",
      }),
    ),
});

Developer Hub 默认为默认 ScmAuth API 工厂的对应配置,如下例所示:

dynamicPlugins:
  frontend:
    my-plugin:  # The plugin package name
      apiFactories:
        - importName: customScmAuthApiFactory

6.10. 添加自定义身份验证供应商设置

您可以从动态插件安装新的身份验证供应商,该供应商可以添加额外的配置支持,或添加新的身份验证供应商。这些提供程序在身份验证提供程序选项卡下的用户设置部分中列出。

您可以使用 providerSettings 配置从动态插件为身份验证供应商添加条目,如下例所示:

dynamicPlugins:
  frontend:
    my-plugin: # The plugin package name
      providerSettings:
        # The title for the authentication provider shown above the user's profile image if available
        - title: My Custom Auth Provider
          # The description of the authentication provider
          description: Sign in using My Custom Auth Provider
          # The ID of the authentication provider as provided to the `createApiRef` API call.
          provider: core.auth.my-custom-auth-provider
注意

供应商查找身份验证提供程序 对应的 API 工厂,以连接提供商的 Sign In/Sign Out 按钮。

6.11. 提供自定义 TechDocs 附加功能

如果插件提供多个附加组件,每个 wagonAddon 条目都指定了与附加组件对应的唯一 importName。前端插件使用 HEKETI Addons 配置公开 TechDocs addon 组件,如下例所示:

dynamicPlugins:
  frontend:
    my-plugin: # The plugin package name
      techdocsAddons:
        - importName: ExampleAddon # The exported Addon component
          config:
            props: ... # (Optional): React props to pass to the addon

6.12. 自定义 Red Hat Developer Hub 主题

您可以从带有各种配置的动态插件自定义 Developer Hub,如下例所示:

import { lightTheme } from './lightTheme';
import { darkTheme } from './darkTheme';
import { UnifiedThemeProvider } from '@backstage/theme';
export const lightThemeProvider = ({ children }: { children: ReactNode }) => (
  <UnifiedThemeProvider theme={lightTheme} children={children} />
);
export const darkThemeProvider = ({ children }: { children: ReactNode }) => (
  <UnifiedThemeProvider theme={darkTheme} children={children} />
);

有关创建自定义主题的更多信息,请参阅 创建自定义主题

您可以使用 themes 配置声明主题,如下例所示:

dynamicPlugins:
  frontend:
    my-plugin: # The plugin package name
      themes:
          #  are `light` or `dark`. Using 'light' overrides the app-provided light theme
        - id: light
          title: Light
          variant: light
          icon: someIconReference
          importName: lightThemeProvider
          # The theme name displayed to the user on the *Settings* page. Using 'dark' overrides the app-provided dark theme
        - id: dark
          title: Dark
          variant: dark
          icon: someIconReference # A string reference to a system or app icon
          # The name of the exported theme provider function, the function signature should match `({ children }: { children: ReactNode }): React.JSX.Element`
          importName: darkThemeProvider

法律通告

Copyright © 2025 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

关于红帽文档

Legal Notice

Theme

© 2026 Red Hat
返回顶部