跳到主要内容
版本:0.4.x(Latest)

基本介绍

LinaPro的插件配置采用独立作用域设计。每个插件拥有自己的配置文件,不需要把业务配置塞进主框架config.yaml,主框架也不需要为每个插件增加专用配置字段。

插件配置回答"这个插件在当前部署里怎么运行"。它与Manifest交付资源不同:配置允许生产环境覆盖,而Manifest资源更接近插件版本的一部分。关于Manifest资源的管理和读取,参见Manifest交付资源

插件配置的来源有三种,按优先级从高到低:

优先级来源说明
1生产配置根下plugins/<plugin-id>/config.yaml运维侧覆盖当前插件配置
2apps/lina-plugins/<plugin-id>/manifest/config/config.yaml开发期插件默认配置
3动态插件产物中的manifest/config/config.yaml动态插件随发布版本携带的默认配置

manifest/config/config.example.yaml只是配置模板,不是运行时默认值。

配置读取顺序

插件配置服务只读取当前插件作用域内的config.yaml,读取顺序如下:

生产部署配置路径

生产覆盖配置路径不是固定的仓库根路径,而是"生产配置路径"下的插件配置:

工作目录/plugins/<plugin-id>/config.yaml

开发阶段默认配置

本地开发时,插件默认配置直接放在插件源码目录:

apps/lina-plugins/<plugin-id>/manifest/config/config.yaml

这使插件开发者可以把插件自己的默认行为、演示开关、外部服务缺省地址或调度参数放在插件目录内维护。主框架不需要知道每个插件有哪些业务配置项。

动态插件默认配置

动态插件构建为.wasm产物时,构建工具会把manifest/config/config.yaml写入动态artifact。运行时如果没有生产覆盖配置,也没有开发期配置文件,主框架会使用当前有效发布中携带的默认配置快照。

这让动态插件可以随版本携带一份自描述默认配置,同时仍允许生产环境用外部配置覆盖。插件升级后,默认配置也随有效发布版本切换,不会依赖源码目录。

配置模板不参与读取

manifest/config/config.example.yaml只用于展示配置项和示例值,不参与运行时默认值读取。不要把只存在于config.example.yaml中的值当作插件运行时默认配置。

推荐写法是:

manifest/config/config.yaml # 可运行的默认配置
manifest/config/config.example.yaml # 给运维或用户看的配置模板

Services中的配置服务

插件通过registrar.Services()获取插件作用域的主框架服务。与配置相关的服务主要有两个:

服务读取范围典型用途
Plugins().Config()当前插件自己的配置插件业务开关、外部系统地址、超时时间、调度参数
HostConfig()宿主约定配置键工作台基准路径、默认语言、已启用语言等少量公开键

Plugins().Config()只读取当前插件自己的config.yamlHostConfig()读取宿主公开的配置键。两者职责不同,不应混用。

源码插件使用

源码插件通过services.Plugins().Config()services.HostConfig()读取配置:

func registerRoutes(ctx context.Context, registrar pluginhost.HTTPRegistrar) error {
services := registrar.Services()

endpoint, err := services.Plugins().Config().String(ctx, "sync.endpoint", "")
if err != nil {
return err
}

interval, err := services.Plugins().Config().Duration(ctx, "sync.interval", 30*time.Second)
if err != nil {
return err
}

workspaceBase, err := services.HostConfig().String(ctx, "workspace.basePath", "/admin")
if err != nil {
return err
}

_ = endpoint
_ = interval
_ = workspaceBase
return nil
}

动态插件使用

动态插件通过pluginbridgeguest侧能力访问同类服务。动态插件必须先在plugin.yaml中声明授权:

hostServices:
- service: plugins
methods: [config.get]
- service: hostconfig
methods: [get]
resources:
keys:
- workspace.basePath
- i18n.default

plugins.config.get只读取当前插件自己的配置;hostconfig只能读取已授权的宿主配置键。插件不应通过全局g.Cfg()扫描宿主完整配置树,也不应要求用户把插件业务配置写进主框架config.yaml

设计收益

插件和主框架配置解耦

主框架只发布稳定的插件作用域读取服务,不需要为每个插件增加配置结构体。插件新增配置项时,只需要更新自己的config.yamlconfig.example.yaml和读取逻辑。

支持生产环境独立覆盖

生产环境可以在外部配置根下维护plugins/<plugin-id>/config.yaml,避免直接修改插件源码目录。对于容器和多环境部署,这种方式更容易挂载、审计和回滚。

常见误区

误区正确做法
把插件业务配置写入主框架config.yaml写入插件自己的manifest/config/config.yaml,生产环境用生产配置根下的plugins/<plugin-id>/config.yaml覆盖
依赖config.example.yaml提供默认值把真实默认值写入config.yaml,模板只做说明
Manifest()读取config/config.yaml后当作当前运行配置使用Plugins().Config()读取插件运行配置;Manifest()只能拿到原始文件内容
动态插件在plugin.yaml中声明config.get方法插件配置通过plugins服务的config.get方法读取,不是独立的config服务