我的 openEuler 社区参与之旅
openEuler 是什么?
openEuler 是一个开源、免费的 Linux 发行版平台,将通过开放的社区形式与全球的开发者共同构建一个开放、多元和架构包容的软件生态体系。同时,openEuler 也是一个创新的平台,鼓励任何人在该平台上提出新想法、开拓新思路、实践新方案。
安装界面:
openEuler 的官方网站: https://openeuler.org/
repo 下载地址: https://repo.openeuler.org
文档手册:https://openeuler.org/zh/docs/20.03_LTS/docs/Releasenotes/release_notes.html
openEuler 版本怎么规划?
说明:
有创新版本和 LTS(Long term support)版本两条线的版本。
遵循 Upstream First 原则,软件带包直接来源于原生社区,并反哺原生社区。
master 分支即为当前最新版本开发分支,一旦发布创新版本或 LTS 版本,
openEuler 创新版本(非 LTS)openEuler LTS 版本版本定位构筑开发者生态,新特性活跃,版本演进快支持合作伙伴构筑商业发行版发布周期 0.5 年 2 年维护周期 0.5 年 4 年 or more 质量标准低,对标 fedora 质量要求中,对标 centos 质量要求关键工作**新特性、**bugfix、CVE、升级选型等**有限特性、**bugfix、CVE 对应分支当前无,下一个版本 openEuler-20.09 最新分支 openEuler-20.03LTS
openEuler 版本如何构建?
openEuler 构建模型:
版本如何构建:
说明:
名字说明备注码云 openuler Group 这个组织下存放的都是由 openEuler 社区发起的原生项目,相当于一个一个的上游社区。例如 isula、atune 项目。https://gitee.com/openeuler码云 src-openeuler Group 这里存放的是以 rpm 源码形式的代码。每个仓库源码都可以直接构建 rpm 二进制。https://gitee.com/src-openeulerOBSopen build service,opensuse 发布的一套开源构建系统,类似于 koji、yacto 等。https://build.openeuler.orghttps://openbuildservice.orgjenkinsCI/CD,持续集成平台,主要用于门禁任务、版本构建任务调度等http://114.116.250.98/repo用于归档发布的交付件及 yum 软件源。https://repo.openeuler.org/
openEuler 版本里有啥软件?
最直观的方式是访问 openEuler 官方 repo,看看发布件。
发布件构建工具 Repo****归档地址 ISO:Dvd ISO 、Debuginfo ISOEverything ISOSource ISOmkdvdiso(待开源)、 kiwihttp://repo.openeuler.org/openEuler-20.03-LTS/ISOQcow2镜像 CreateImage(待开源)http://repo.openeuler.org/openEuler-20.03-LTS/docker_img容器镜像 kiwihttp://repo.openeuler.org/openEuler-20.03-LTS/virtual_machine_imgLiveCD ? …
另外一种方式,就是访问 openEuler OBS 上的构建工程,可以知道每个版本里包含哪些软件,当前的构建状态是啥样的。
版本 OBS 工程说明约束地址 master 主干 openEuler:Factory(新包引入)新软件加入,首先引入到 openEuler 软件工场,master 分支代码构建 rpm,不会集成到 iso 或 repo 中https://build.openeuler.org/project/show/openEuler:Factory openEuler:Mainline 主线工程,master 分支代码里面涉及的包都会随着 openEuler 的版本发布https://build.openeuler.org/project/show/openEuler:MainlineLTS版本 openEuler:20.03:LTSLTS 版本构建工程,openeuler-20.03-LTS 分支代码 https://build.openeuler.org/project/show/openEuler:20.03:LTS20.09版本(未拉分支)--- ---
软件是如何管理的?
openeuler 源码仓库管理:
openEuler 所有代码托管在 gitee.com
有 openeuler、src-openeuler 两个 group
都是源码化、配置化管理
groupopeneulersrc-openeuler 定位代码仓、原生社区软件包仓、制品仓内容 openEuler 发起的原生项目 spec rpm 格式归档的软件包仓库 URLhttps://gitee.com/openeulerhttps://gitee.com/src-openeuler仓库数量 50+2500+代码管理源码树 src rpm 格式关系是 src-openeuler 的上游社区
当前 openEuler 软件的管理是以 sig 组来承载,所有的软件唯一的归属于某个 sig。通过sigs.yaml文件,你可以查询到该软件属于哪个 sig,并通过sigs专有归档目你可以查询对应的 maintainer。只有对应的 maintainer 才有对应仓库代码合入权限。
openeuler/community 仓库下,以下三个文件比较重要:
sig/sigs.yaml 管理和维护各 sig 下维护的软件包,划分 sig 管理的软件包范围。
repository/openeuler.yaml openeuler 下维护的软件包仓库信息。
repository/src-openeuler.yaml src-openeuler 下维护的软件包仓库信息。
通过修改这几个文件,来新增、删除软件包仓库,来给相应的软件包划分 sig,从而实现 sig 的 owner 对软件包的权限管理。
了解 openEuler SIGs
SIG 就是 Special Interest Group 的缩写,openEuler 社区按照不同的 SIG 来组织,以便于更好的管理和改善工作流程。
SIG 组和 SIG 的邮件列表是开放的,欢迎任何人和团体加入并参与贡献。
SIG 都是针对特定的一个或多个技术主题而成立的。SIG 内的成员推动交付成果输出,并争取让交付成果成为 openEuler 社区发行的一部分。
SIG 的核心成员主导 SIG 的治理。请查看SIG的角色说明。您可以在贡献的同时积累经验和提升影响力。
每一个 SIG 在 Gitee 上都会拥有一个或多个项目,这些项目会拥有一个或多个 Repository。SIG 的交付成果会保存在这些 Repository 内。
可以在 SIG 对应的 Repository 内提交 Issue、针对特定问题参与讨论,提交和解决问题,参与评审等。
您也可以通过邮件列表、IRC 或视频会议和 SIG 内的成员进行交流。
openEuler SIG 维护策略
根据所有软件所涉及领域和方向,openEuler 已经垂直的划分了很多基础的 SIG。
每个独立软件要归属到唯一 SIG 里,SIG 的 maintainer 管理该 SIG 涉及的软件包,并定期审视。
SIG 之间要避免正交、耦合,粒度要合理,管理的软件仓规模避免太大。
新成立 SIG 时,应提前了解当前 openEuler 是否已经存在相同或类似的 SIG。
新 SIG 申请时,应考虑和其他 SIG 沟通,将该 SIG 领域涉及软件一并接管过来。
SIG 的成立、运营、废弃受 TC 委员会监管。
openEuler 社区开发全景?
上图是 openEuler 社区开发指引图。
说明:
软件包管理按照软件包所处的时间点分为:
、
、
。
每个阶段的输入是圆框绿底,如
。
所有的开发和维护动作是由 issue 触发。issue 可分为需求、问题、CVE 等类型。
。
所有修改和操作通过 PR 来发起。
全景图中,每个动作都可能涉及规范或指导。将在后面以表格的方式整理呈现。
全景图中涉及的规范:
阶段动作规范或指导引入
指导:《如何申请 SIG》 --待输出--
规范:《软件包引入和退出要求》指导:《openEuler 加包指导》 --待输出--
规范:《软件包打包规范》开发 &维护
规范:《软件包升级选型规范》 --待输出--
指导:《软件包打包规范》
规范:《软件包打包规范》指导:《如何提交 PR、发起检视及合入验证》 --待输出--
规范:《openEuler漏洞处理流程》规范:《openEuler漏洞严重性评估》指导:《如何申请CVE、漏洞上报》
规范:《openEuler 软件包随版本发布规范》 --待输出--指导:《如何将软件包加入 openEuler 发布版本》--待输出--
规范:《安全漏洞处理和发布流程》退出
规范:《软件包引入和退出要求》
如果参与 openEuler 社区贡献?
第一步,开源并不意味者随心所欲,签署 CLA:“贡献者许可协议”是第一步,阅读并遵守 openEuler 社区的行为守则;
第二步,从了解、安装、使用、测试 openEuler 开始,积极反馈问题和建议,相关的文档和手册,以及相关的资讯可以帮助你更加深入的了解 openEuler。
第三步,开发者熟悉社区的开发流程后——《贡献者指南》,可以基于自己感兴趣的项目和软件,在码云上 openEuler 对应的项目提交自己的贡献。
了解 gitee 工作流
准备工作
Fork 仓库
克隆到本地
拉分支
修改验证提交
推送到码云
创建 PR
关注代码审查意见
更新 PR
建议:
相关的修改,单独拉分支来修改提交,并创建 PR。如果可以,一次 commit 一个分支。
当 PR 合入后,可以强制同步最新代码到个人仓库。
不要在 master 上提交代码,当 PR 未 merge 时,强制同步会失败。
开发者可以在 openEuler 社区做些什么?
包括但不限于:
提交一些需求,并尽可能实现它
提交一个 bug 并修复它
上报漏洞及漏洞处理
提出一些建议,包括不限于网站改进、文档改进、流程规范改进、体验提升等。
为社区添加新的软件
发起社区新项目
结合前面的开发者全景图,可以分解成以下动作:
1、创建 issue,提交需求 &问题 &建议
提出问题:如果您发现并想向社区上报问题或缺陷,问题提交的方式就是创建一个 Issue。您只要将问题以 Issue 的方式提交到该项目 Repository 的 Issue 列表内,并查看Issue提交指南以获取更多的信息。提交问题时,请尽量遵守问题提交准则。
提出建议:如果您想对 SIG 领域内贡献出自己的意见或建议,也可以通过提交 Issue 的方式分享给大家。大家可以在该 Issue 上充分的交流和讨论。为了吸引更广泛的注意,您也可以把 Issue 的链接附在邮件内,通过邮件列表发送给所有人。
提出需求:如果你希望某个特性或是技术在 openEuler 上落地,可以提交需求类 issue,清晰完整的描述有助于团队成员理解,并被更快的接受和排入开发计划。
2、提交 PR,修复一个问题(bug、cve、新特性)
当你提交一个 PR 的时候,就意味您已经开始给社区贡献代码了。请参考openEuler社区PR提交指导 与 码云PR提交流程。
注意事项:
openEuler 只接受 PR 的形式来提交代码,不允许直接向 openEuler 下的仓库直接 push 代码。
首先,要找到修复问题对应的仓库,以src-openEuler/mock为例,点击 fork 按钮,复制仓库代码到个人名下。
将代码 git clone 到本地,如果你的修改不涉及二进制源码软件包的变化,将所修改的代码做成一个 patch,因为仓库是以 rpm 源码包的格式组织的。
每个 PR 都会触发 openEuler 门禁的检查,包括不定命名、代码规范、代码构建。门禁的结果会稍后回显在评论中,存在失败的检查项要及时修正。
通过门禁中的 openeuler-rpm-build 的链接,你可以逐层找到这次提交构建的临时 rpm 二进制。后续会将生成的二进制直接回显到评论里。
代码 reviewers 可以针对提交给出自己意见,当他认可你的提交时,会
/lgtm
来给出 ok 的意见。仓库的 maintainers 有合入的权限,
/approve
的评论会触发 robot 自动合入,如果存在冲突,你需要提前解决冲突。针对别人给出的检视意见。如果涉及修改代码,可以使用
git commit --amend; git push -f
来在同一个 PR 更新 PR。
检视代码:
openEuler 是一个开放的社区,我们希望所有参与社区的人都能成为活跃的检视者。可以参考社区成员,该文档描述了不同贡献者的角色职责。
对于贡献者,为了使您的提交更容易被接受,您需要:
遵循 SIG 组的编码约定,如果有的话
准备完善的提交信息
如果一次提交的代码量较大,建议将大型的内容分解成一系列逻辑上较小的内容,分别进行提交会更便于检视者理解您的想法
使用适当的 SIG 组和监视者标签去标记 PR:社区机器人会发送给您消息,以方便您更好的完成整个 PR 的过程
对于检视者,强烈建议本着行为准则,超越自我,相互尊重和促进协作。《补丁审核的柔和艺术》一文中提出了一系列检视的重点,说明代码检视的活动也希望能够促进新的贡献者积极参与,而不会使贡献者一开始就被细微的错误淹没,所以检视的时候,可以重点关注包括:
贡献背后的想法是否合理
贡献的架构是否正确
贡献是否完善
注意:如果您的 PR 请求没有引起足够的关注,可以在 SIG 的邮件列表或dev@openeuler.org求助。
这里是一个可供参考的示例。
3、创建兴趣小组
找到您感兴趣的 SIG 或项目
找到您感兴趣的 SIG 组,可以帮助您在正确的地方提出问题,并得到更快的社区响应。
方式一:如果您不了解有哪些 SIG 或项目,您可以查看SIG列表,它包含当前 openEuler 社区成立的所有 SIG 团队的清单。您可以通过该列表快速的定位到您感兴趣的领域所对应 SIG 团队。同时还会向您提供该 SIG 团队的如下信息:SIG 下的项目,以及项目的 Repository 地址 SIG 内的交流方式,包括邮件列表、IRC 或视频会议等 Maintainer 的联系方式
方式二:如果您知道感兴趣的项目名称,可以在 openEuler 的 Repository 列表下进行模糊搜索,从而快速定位到对应项目的首页地址。通常情况下,在该项目首页地址的
README.md
文件中,可以找到该项目所属的 SIG 信息、交流方式、成员和联系方式等。
如果上述两种方式都定位不到您感兴趣的 SIG,您可以向community@openeuler.org发求助邮件。建议您在邮件列表内用“【开发过程疑问】”作为标题,在内容中写出你寻找的 SIG 或项目的特征,我们会为您提供帮助。
确定好你要创建小组后,可以按照模板创建一个新的 sig 目录,并提交 PR 到 community仓库,并在 TC 例会上申请议题(订阅 tc@openeuler.org,并关注议题收集的邮件),经过大家一致同意后,合入 PR,就代表 sig 创立成功。
这里是一个 PR 提交创立 sig-golang 的具体例子,包括 sig 的 raodmap、职责、管理的仓库(也许是从别的 sig 中移交过来)、联系方式和 maintainer 等信息。
4、贡献软件包
当前发现 openEuler 社区缺少你需要的软件时,你可以尝试动手为社区贡献软件包。这里不再赘述 OS 是如何由 linux 软件包组成的,以及如何制作一个 rpm 包。这里着重讲解贡献软件包的流程。
首先,要明确贡献的软件包的功能,遵循openEuler软件包引入和退出原则。
再者,由于软件唯一的归属于一个 sig,你需要查看当前是否有合适的 sig 承载,如果没有,需要你按照步骤 3 申请成立一个新的 sig。
然后,你可以通过提交 PR 的方式,在对应的 sig 下添加软件仓库。可参考这个提交,一旦审核通过,后台会自动为你在对应的 src-openeuler group 下创建同名仓库,并在Factory工程中去创建同名 package 开始构建,由于默认仓库里只有 readme,并不会进行真正的构建,而是 exclude 状态。
接着你可以按照 2 的操作提交一个 PR,来上传可以构建的代码。一旦合入,Factory 工程便会触发构建。
软件打包符合打包规范,请参考如何打包。
该工程下所有软件包成功的构建结果,归档在:
openEuler OBS 使用
这两片文章帮助你了解 obs 的基本使用。如何使用 openEuler OBS - (一)介绍 和如何使用 openEuler OBS - (二)与gitee的联动
什么是 obs?
OBS 是 Open Build Service 的简写(官方网址:https://openbuildservice.org/),
原本是作为发行版 openSUSE 专用的 rpm 打包的平台,后续扩展为面向多发行版、多架构、多格式的打包发布平台。
与 koji 的不同
管理范围
与 koji 只管理包(包括源码包与二进制包)仓库不同,OBS 同时管理着源码与包两个仓库。koji 是从一个包编译完成后开始接手,根据包的 NVR(Name-Version-Release)确定包的位置,在编译验证后入库保存。而 OBS 是从源码阶段开始管理,它拥有自己的包版本标记与 changelog 日志。OBS 可以像 git 一样保存源码的历史版本,对源码进行分支管理。并生成各版本的二进制包与源码包。
换句话说,OBS 可以同时实现 koji 和 git 的功能。 > OBS 接受源码的格式与 git 普遍的保存格式并不相同,所以 OBS 无法完全取代 git。
适用格式
OBS 可以生成 rpm、deb 等格式的包,而 koji 只适用于 rpm 格式。
支持 Rest API
方便测试框架、构建工程调用。
如何配置 obs
安装 osc
osc 是 OBS 的命令行程序,您可以在这里 ,选择自己的系统版本,添加软件源到自身包管理器中。
这里以 Fedora30 为例:
添加软件源
将文件http://download.opensuse.org/repositories/openSUSE:/Tools/Fedora_30/openSUSE:Tools.repo
另存到/etc/yum.repo.d/中。 > 需要 root 权限。
安装 osc
执行 dnf install osc
命令安装 osc。
配置 openEuler 的 OBS
有很多方法可以将 osc 链接至 openEuler 外网的 OBS:
最基础的方法为在每次执行
osc
命令时添加参数:-A http://openeuler-build.huawei.com/
使用 alias:
alias iosc="osc -A http://openeuler-build.huawei.com/"
修改位于
home
目录下的 osc 配置文件:vi ~/.oscrc
,并写入以下内容:
注册 OBS 账号
打开 http://openeuler-build.huawei.com/,点击右上角“Sign Up”,注册自己喜欢的帐号。
注册完成后,重新回到上面网址。点击右上角的“Login”,用新账户登录。系统会在注册时自动创建一个以“home:用户名”为格式命名的 Home Project。
后续需要邮箱向 infra@openEuler.org 申请。
OSC 命令
osc help 是帮助指南。类似 git 命令。
List Existing Content on the Server
Checkout Content
Update a Working Ddirectory
Upload Changed Content
Check the Commit Log
Show the status (which files have been changed locally)
If an update cannot be merged automatically, a file is in 'C' (conflict) state, and conflicts are marked with special lines. After manually resolving the problem, use osc resolved *FILE*
.
Mark files to be Added or Removed on the Next Checkin
Add all New Files in Local Copy and Removes all Disappeared files
Generate a diff to view the changes
Show the Build Results of the Package
Show the Log File of a Package
(you need to be inside a package directory)
在本地机器上构建
以 abuild 用户进入 chroot 环境,方便调试
如何创建自己的工程,package
配置 Project
两种方法:网页操作、命令行操作
网页操作:
在 obs 主页点击右上角
依次进入 Home Project -> Repositories -> Add from a Distribution 。
按上图所示填写基础配置,并在 Name 栏填写喜欢的名字。
在选择后后退至 Repositories 界面,可以看到如下图所示的环境:
第一个为编辑按钮,可以选择当前发行版编译架构
第二个为添加按钮,可在发行版标准环境上额外添加单独的包(例如其他私人编译的依赖包)
第三个为下载,点击后转到当前环境的仓库
第四个为删除
命令行操作:
执行命令: osc meta prj -e [project名]
,会看到类似如下文本:
其中, 1. repository 标签为仓库标签, 可添加此项添加编译时的基础环境 2. Path 标签为可用包路径标签, 需手动添加发行版包路径。如需要额外依赖, 也可以单独添加。 3. Arch 标签为编译架构, 可同时添加多个。
例如:
新建包
进入 Project 目录: cd [project名]
新建 Package: osc mkpac [package名]
进入 Package 目录并将下载源码以【tar 包、所有 patch、spec 文件、其他 source 文件】格式放置:
向新创建的 package 中添加以上文件: osc add *
将更改上传至服务器: osc commit
在这里可以注明本次上传的简短介绍,用:wq
保存并退出
之后就可以在网页上等待编译并查看结果了。
查看包状态与下载包
您可以在 Project 与 Package 主页右侧看到当前编译状态
finished
表示在某个系统平台执行编译链接、安装检查的过程结束succeeded
状态为编译成功failed
为编译失败,您可以点击查看日志
您可以点击编译平台 -> Go to download repository 到达编译仓库,获得此 Project 的 repo 源与所有编译成功的 package。
更新包
进入 project 文件夹: cd [project名]
更新本地代码为最新代码: osc up
进入 package 目录,使用 osc add
命令将新文件添加到 package,修改 spec 文件后使用osc commit
命令上传新版本。
_service 的使用,与码云的联动
分为两部分:
利用 Source Services(下称源服务)直接获取 git 源码并编译成包
利用 webhook 使源服务在 git 仓库 push 时触发,从而实现 OBS 始终跟进 git 仓库最新版本源码的效果
利用源服务直接获取 git 源码并编译成包
Source Services 相关
Source Services 是用于以可靠方式验证,生成或修改源的工具。它们被设计为最小的工具,并且可以按照经典 UNIX 设计的强大思想进行组合。
源服务就像是系统中的函数,我们可以通过运行脚本调用它;而脚本就是 Package 中的_service 文件。
创建使用源服务的 Package
通过命令行工具或者网页新建一个空的 Package
进入 Package 目录并创建_service:网页端点击 Add file ,点击 Choose a file,并选择本地建好的_service 文件。命令行则在 Package 目录中新建_service 文件并上传之服务器。
准备编辑_service 文件
编辑_service 文件
最基础的_service 文件将会如下所示:
最外层为标记,在
内则为一个个函数,而
则为``函数的参数。
为了实现“利用源服务直接获取 git 源码并编译成包”这个目标,
我们的_service 应该类似于这样(以下格式请根据具体情况选择合适的顺序):
下面将对所需的服务逐一进行介绍:
第一个服务:tar_scm
tar_scm 会将链接 url 中的仓库下载下来并打包为 tar 文件,文件包命名格式为:
[Name]-[Version].[commit_timestamp].tar
其中,[commit_timestamp]为 commit 十六进制时间戳。
可选参数:
filename 定义打包后文件的 Name,默认为 git 仓库名。
versionprefix 定以打包后文件的 Version 格式,默认为当前十进制时间戳。
在 OBS 官方服务器中, tar_scm 服务由于在空间利用率上表现不佳, 已被 obs_scm、tar 服务取代,但 openEuler 的外网 OBS 暂时还不支持 obs_scm,所以这里选择 tar_scm 。
详见:链接
第二个服务:extract_file
extract_file 可以从 tar 包中提取文件, 具体需要提取什么文件取决于 git 仓库中的文件格式。
一般来说我们可以将打包需要的内容分为四大类:
源码 : 参与编译过程的文件
spec 文件 : 指导如何打包的规范文件
patch 文件 : 修改源码的差异文件
源文件 : 不参与编译但需要打包的文件
对于 git 仓库来说,一般会将所有文件放到仓库的根目录。
此时我们需要将 spec 文件、patch 文件、源文件提取出来, 源码则留在 tar 包中等待之后的服务将其压缩打包。
对于 OBS 仓库来说,为了方便 OBS 系统使用,人们已经对源码进行压缩打包。
此时我们需要将所有文件提取出来并省略之后的压缩打包环节。
参数:
archive 定义提取来源文件格式
files 定义提取文件类型 注意:存在一个顶层目录,其名称未知,因此文件名应以 “*/” 开头
第三个服务:recompress
recompress 会对指定文件进行压缩
参数:
compression 压缩格式,可选:none、gz、bz2、xz
file 压缩内容
第四个服务:set_version
会将 spec 文件中的 Version 替换为 obs_scm 时的
spec 文件中可以以
格式定位源码包。
等待编译完成
由于使用源服务获取源码,所以编译时需要额外过程与时间。
当状态显示为 blocked 时, 表明源服务正在运行。当源服务运行完毕时会正常开始打包过程。
我的参考案例:链接
Source Services 在实际场景中的应用
在oVirt-SIG组中,我们应用了源服务实现代码由 git 到 OBS 的同步。
首先,我们在 git 仓库中以:**spec 文件、patch 文件、 源码 tar 包 的格式上传并管理源码。
在 OBS 系统中建立对应包并以一下格式定义_service 文件:
由于我们已经很好的在 git 仓库中设置了存储格式, 此时我们只需将所有文件下载并提取即可。
在这之后,OBS 系统会帮助我们完成编译与打包的环节。
利用 webhook 使源服务在 git 仓库 push 时触发
在写此文时,OBS 系统还不支持 gitee 格式的 webhook,所以以下内容为使用 github 仓库实现。
obs 可以创建令牌(token),当令牌被触发时,OBS 会运行源服务。
将网址与令牌添加到 git 仓库的 webhook 列表中,就可以在 git 仓库中实现触发源服务,进而更新 OBS 中的包版本。
具体步骤:
创建专属包的 OBS Token(OBS 令牌):
命令将生成仅对 Project/Package 生效的 token。
使用命令
osc token
可以查看当前生效的令牌列表。使用命令
osc token --delete
可以删除令牌
打开 git 仓库网址(以 github 为例):
打开仓库 -> Setting -> Webhooks
点击左上方的 Add webhook 。
在 Payload URL 中以:
为格式填入。
在 Secret 中填入令牌秘匙,按需求选择 trigger 类型, 保证 Webhook 为 Active 状态。
之后点击 Add webhook 即成功实现。
可尝试触发 trigger 以验证成果。
----------------------------------------------------------------------------------------
添加小助手 openEuler,加入 openEuler 交流群
更多内容,敬请关注 openEuler 公众号
评论