扩展生态系统:工作和工具
扩展生态系统:工作和工具
本文档概述了理想化的 Postgres 扩展生态系统。
为什么?
过去一年,人们对 Postgres 扩展分发的兴趣激增。许多人特别指出了在查找和安装扩展方面遇到的挑战。
PGXN,于 2011 年发布,旨在成为社区的规范注册表,但目前仅索引了 350 个发行版,而这些发行版是开发者主动发布的 --- 可能只有所有 [已知扩展][extension-gist] 中的三分之一。
此外,PGXN 分发源代码包,要求开发人员下载、编译、安装和测试它们。二进制打包程序和云提供商已在其注册表中添加了有限数量的扩展,例如 apt.postgresql.org、yum.postgresql.org 等,但 PGXN 以及 pgxn 客户端 均未提供与这些工具的集成。
由于这些挑战,近几个月出现了许多新的参与者,它们都旨在成为扩展的记录来源,并专注于发现和易于安装。其中包括 dbdev、trunk、pgxman、pgpm。它们也存在局限性,例如操作系统和平台可用性有限,尤其是添加扩展的手动流程,进一步限制了包含性。甚至没有一个能达到 PGXN 提供的数量。
这些挑战以及探索新解决方案的兴趣和精力表明,现在是时候重新审视 PostgreSQL 扩展生态系统的整体理念了:要解决 待办事项、指定完成这些工作的 工具,并概述更广泛的 Postgres 社区设计和构建这些工具的计划。
🎬 让我们开始吧。
待办事项
西奥多·莱维特引用了 一句名言
"去年,卖出了 100 万把 1/4 英寸的钻头",利奥·麦吉维纳曾经说过,"不是因为人们想要 1/4 英寸的钻头,而是因为他们想要 1/4 英寸的孔。"
人们不是购买产品;他们购买的是对益处的期望。
今天,最常被引用的描述支撑着 工作完成理论,感谢克莱顿·克里斯坦森,我们牢记这一点,以思考理想化的 Postgres 扩展生态系统的“工作”——不参考现有的 Postgres 解决方案。但是,我们从其他项目和社区中引用了一些工作的例子,既是为了澄清待办事项,也是为了参考可以借鉴的现有技术。
那么,理想的 Postgres 扩展生态系统需要完成哪些工作呢?
权威性
工作:成为所有 Postgres 扩展的官方规范记录来源
开发人员需要知道一个可靠地发布和查找所有公开可用的 Postgres 扩展的地方。它不能是子集,而必须是全面的,被社区认定为默认,并在 Postgres 文档中包含。
典范
- The Go Module Index indexes Go package that it automatically discovers
- crates.io indexes Rust crates published to it
- PAUSE indexes Perl modules uploaded to it
- RubyGems indexes Ruby Gems published to it
- PyPI indexes Python distributions uploaded to it
益处
工作:期望扩展开发人员在生态系统中开发和发布他们的扩展。
扩展开发人员希望他们的扩展成为生态系统的一部分,获得参与的所有优势和特权,而无需过度努力。
发布扩展应尽可能简单。理想情况下,它只需要维护一个元数据文件并将版本发布到 权威索引。
典范
- Go Package Discovery 自动发现和索引
go.mod
-configured packages - 已注册的 crates.io 开发人员发布由 Cargo Manifest File 定义的 Rust 扩展 通过
cargo
CLI - 已注册的 NPM 开发人员发布由
package.json
文件定义的 NPM 项目 通过npm publish
命令 - 已注册的 PAUSE 开发人员发布由 CPAN Meta Spec 文件定义的 Perl 模块 通过
cpan-upload
CLI 或 Web API
集成
工作:让开发人员轻松开始编写和发布扩展。
扩展开发人员需要出色的工具来简化创建、维护、测试和分发扩展的过程。这些工具应该很好地集成到扩展生态系统中,并使开发人员能够轻松上手,并在整个扩展开发生命周期中轻松遵循最佳实践:从开始开发、管理依赖项和其他元数据、测试它到发布它。
典范
可发现性
工作:让扩展易于查找和理解
如果没有人能找到,那么成为可用扩展的规范索引就没有用。需要有一个众所周知的网站,人们可以在那里找到扩展,了解它们的用途,区分它们,并阅读它们的文档。理想情况下,大多数人使用集成搜索而不是搜索引擎,但扩展页面也应该在搜索引擎结果中排名前列。
典范
信息丰富
工作:让扩展文档保持一致、标准化和全面
扩展的使用便利性取决于其文档的可用性。因此,提供组织良好、标准化且可访问的文档非常重要——并且开发人员能够方便地为其扩展包编写文档。理想情况下,开发工具鼓励在扩展中包含文档。使用标准化文档,可以轻松地以多种格式发布文档,特别是在规范的 发现 网站上。
典范
可编程性
工作:提供稳定、易于使用且全面的 API,下游开发人员可以使用这些 API 来构建其他工具和产品
提供出色的、有良好文档的、直观的 Web API,允许任何人在此索引上构建有用的工具和服务。以下工作需要它,但富有创造力的编码人员会以我们意想不到的方式发明和 混搭 API。Web API 使得在生态系统内和生态系统外都能实现富有想象力的解决方案。一些示例 API
- 最新版本提要
- 扩展元数据
- 全文搜索
- 向注册服务发送事件 Webhook
典范
可安装性
工作:为各种平台提供自动二进制打包
用户必须能够尽可能轻松地安装所有索引的扩展。理想情况下,独立服务会使用 索引 API 来接收新版本发布的通知,并自动为尽可能多的操作系统、操作系统版本、体系结构 (arm64、amd64 等) 和 PostgreSQL 版本构建二进制包。
一些支持或启用从核心注册表构建和分发扩展的示例存储库
- 社区打包:apt.postgresql.org、yum.postgresql.org
- 二进制打包:Homebrew、Chocolatey 等
- 供应商打包和分发:pgxman、dbdev、pgpm、trunk
典范:❓❓
可信赖
工作:验证扩展并防止供应链漏洞
提供工具和功能,通过确保 规范注册表 索引的扩展已通过验证,来自可信赖的来源,并且不太可能成为 供应链攻击 的载体,从而获得和保持用户信任。这意味着某种形式的作者验证(例如,为来自知名来源的项目加徽章)、校验和、公钥签名,以及可能的静态代码分析。
典范
可管理性
工作:提供直观、强大的界面用于安装和管理扩展
提供应用程序来管理一个或多个 Postgres 集群中的扩展。至少提供一个命令行界面,用于管理本地安装的 Postgres 的扩展——正如目前安装包所必需的那样,例如。8
用户需要以单一、一致的方式轻松管理其 Postgres 扩展。扩展管理器应了解已安装的扩展、可用的扩展、依赖关系图和已知的漏洞;允许搜索(通过API);当然,还应安装或升级扩展。
典范
工具
工具满足要做的事情。或者更确切地说,是工具的类别,因为一些工具可能部署为一个定义明确的服务,而另一些工具则表示一种服务或工具类型,可以由多个字面应用程序实现(其中许多应用程序我们还没有想出来!)。
核心注册表
作业
核心注册表是索引 Postgres 扩展的单一规范服务(理想情况下,将替换像这样的黑客行为)。它提供了用于获取完整索引、单个扩展元数据、发布通知等的 API。
达到那一点的一些要求
- 一个由社区定义和维护的元数据标准,以支持扩展的索引、构建和安装。内容可能包括,除其他事项外
- PGXN 元数据
- 控制文件元数据
- 二进制依赖项(配置、构建、测试和运行时)
- 未打包的依赖项(Python 包、Perl 模块、Ruby 宝石、Java JAR 等)
- 平台要求(操作系统、体系结构)
- 冲突
- 必需的配置(例如,“必须在
shared_preload
中”,“需要重新启动”等) - 新元数据,例如,TLE 启用,扩展类型 等。
- pgxman buildkit、
trunk.toml
和其他注册表开创的其他有用元数据
- 一个版本控制标准,例如SemVer,用于识别新发布的版本并以有意义的顺序对其进行适当索引
- 一个扩展注册和托管模式;需要考虑的选项:3
- 策划和所有权:始终使用开发人员提供的分发元数据,但考虑为不提供元数据的扩展生成默认元数据。但允许扩展所有者在他们后来添加它时将其覆盖。
受信任的注册客户端提供元数据,并可以使用索引用于其他用例,例如
- 增加下载次数
- 发现站点 中其他链接的 URI 模板(例如,二进制下载)
- 注册一个 Webhook 以接收新发布或其他事件的通知
从概念上讲,核心注册表是一个单一服务,但实际上它可能包含多个服务。以下是一些示例:5
- 扩展发现
- 事件通知(Webhook 排队和调度)
- 用户管理4(注册、权限)
- 发布管理(索引、命名空间)
- 供稿服务
- 总和服务(可审计的校验和数据库,go 命令将使用它来验证模块)
现有技术
API 服务
作业
一个提供索引和搜索站点 的所有 Web API 的服务(实际上,搜索站点本身应该是一个围绕此 API 的薄包装器)。这将是开发人员使用 Postgres 扩展数据构建服务和混搭的规范可编程 资源。它还可以提供一个 API 来获取从扩展文档渲染的干净 HTML。
所有版本的扩展都将通过 API 存在并可查询。
随着时间的推移,它将扩展以支持其他功能,例如
- 从受信任的第三方收集指标:下载次数、测试、构建、安装成功和失败等。
- 存储库元数据(星标、提交次数、最后更新等)
- 版本比较(差异)
- 用户评论和/或评价
- 分类/标记/捆绑
现有技术
搜索站点
作业
一个网站,在API 上提供一个引人入胜的界面,提供有效的搜索、分类、文档的标准化呈现以及指向其他资源的链接。提供扩展主页,通常在通过第三方搜索引擎搜索扩展名称时,在最前几条结果中链接。6
该网站很可能是功能最丰富的服务;随着时间的推移,可以将许多功能添加到API 中,并在此处呈现,例如详细的元数据、版本历史记录、用户评价、用户提供的文档、捆绑等。
所需功能
- 搜索引擎索引(Google、Duck Duck Go、Kari 等)
- 类似于pkg.go.dev 和crates.io 的全文搜索
- 发布主页
- 用户主页
- 格式精美的扩展文档
- 扩展分类
- 用户反馈和评价
- 有关下载次数、使用情况、访问次数最多的扩展、构建/测试/安装失败、漏洞等的指标。
- 用户管理 UX(注册、用户资料)
- 发布管理 UX(所有权、权限、存档)
现有技术
打包
作业
从核心注册表 中消费的下游服务,以自动下载和验证源代码,然后构建和签署二进制发行版。初始目标包括apt.postgresql.org、yum.postgresql.org 以及 Tembo 所需的打包。
在短期内,可以像今天一样手动管理此类服务:一个经过策划的扩展列表,包含手动编辑的规范(RPM 规范文件、Apt 文件、Homebrew Bottles、Chocolatey 包 等)。
但要努力实现理想的最终状态,社区打包存储库支持所有主要平台、操作系统、PostgreSQL 以及所有主要版本,这些版本都是从发布时由核心注册表 提供的扩展元数据中自动构建的。流程如下
- 开发人员将版本化的扩展源文件和元数据发布到核心注册表,该注册表会通知受信任的下游服务
- 这些受信任的服务安装在元数据中记录的依赖项,然后下载、验证、构建、测试、签名并上传到apt.postgresql.org、yum.postgresql.org、Trunk、pgxman 等。
一个补充服务提供一个 API 来表示每个发布版本和二进制打包分发,允许客户端查询特定操作系统、体系结构和 Postgres 集群的适当打包存储库(以及要编译成非打包 PostgreSQL 集群的源代码分发)。
名称映射服务
作业
自动打包可能需要某种规范的名称映射服务,因此扩展作者只需要说,libxml2
,自动打包系统就可以找出在每个操作系统和版本上安装什么东西才能满足该规范名称。
现有技术
- ❓❓
安装
作业
一个 SDK 和 CLI,以及可能的其他使用API 和打包服务 来快速轻松地在支持的平台、体系结构和 Postgres 版本上验证和安装扩展的界面。还应支持源代码安装(也许借鉴打包服务的技术)。
理想情况下,它应该实现为一个 SDK,以便可以为各种环境提供薄包装器:一个 CLI、一个本机 Mac 或 Windows 应用程序、一个 Web 应用程序等。
- 用于构建用于从打包服务下载和验证二进制文件(或从规范索引下载源代码并进行编译)以及安装1 的 SDK 的各种操作系统(和体系结构)和 Postgres 版本
- 支持的操作系统(Linux、MacOS、Windows、*BSD)和体系结构(amd64、arm64、i386 等)的 CLI,具有可扩展的体系结构,可以集成开发功能 并允许第三方快速添加功能
- 本机应用程序还是 Web 应用程序?
- 特定 Postgres 集群的扩展目录,因此安装程序/扩展2 管理器知道安装了什么
现有技术
发展
作业
一个 SDK 和 CLI 以及使用API 来管理扩展开发生命周期的界面,从启动扩展、管理依赖项和其他元数据、对其进行测试以及将其发布到核心注册表。
理想情况下,一个 SDK 和 CLI,它通过添加适当的子命令来补充或更好地扩展管理 CLI。功能
- 初始化新的扩展项目,为基本文件、元数据和社区推荐的项目组织提供脚手架。
- 用于编辑元数据、最终格式化和 lint 源文件和文档、添加新文件(用于升级、测试等)以及运行测试的命令。
- 用于捆绑、签名和发布版本的命令。
- 持续集成工具,用于在多个平台、操作系统和 Postgres 版本上启用测试。
- 用于捆绑和发布扩展的持续部署工具。
现有技术
其他工具想法
集思广益其他工具想法,由任何有兴趣的人开发。
测试
一个从核心索引中消费的下游服务,自动在所有主要平台、操作系统、PostgreSQL 以及所有主要版本上测试扩展。可能是打包理想最终状态的一部分,因为有很多重叠?为每个扩展7 提供一个矩阵作为数据,也许还有一个链接自搜索站点 的网页。Perl 示例。
工具
编辑器插件或语言服务器,以支持扩展自动完成。
认证验证
一项类似于测试 的服务,但侧重于其他质量指标,例如构建、测试和安装成功和失败;静态代码分析警告和错误;漏洞、易受攻击的依赖项、编码错误等。将问题报告回API 服务 以显示在网站 扩展主页上。
问题
鉴于过去在构建扩展 Postgres 分发服务和工具方面付出的努力,更不用说一些项目的雄心壮志了。
- 在理想的扩展生态系统中,PGXN 的作用是什么?
- 其他扩展注册表的作用是什么?
- 标准元数据的格式应该是什么,现有元数据(控制文件、PGXN
META.json
、Trunk.toml
、pgxmanextension.yaml
、pgrxCargo.toml
)将如何处理? - 身份记录的来源应该是什么?PostgreSQL 社区帐户 可能是理想的选择
- 我们是否希望像Go 包发现 一样自动发现和索引扩展?如果不是,我们如何才能使参与尽可能简单?包括元数据管理、身份和认证、发布和权限。
- 自动发现也会引发命名空间的问题。我们如何将发现的扩展(例如`github.com/theory/pg-semver`)与 Postgres 扩展命名约定关联起来?如果我们只允许使用名称的最后一部分,如何处理命名冲突?
- 对于新组件,我们应该使用哪种语言?交给每个贡献者最擅长的语言?建立一些社区标准来提高可信度,吸引开发人员,或简化部署?
- 谁来做什么,如何最好地协作?我们是否应该确定核心注册表并从那里开始?还是其他方法?
一旦我们对这些问题(以及肯定还有其他问题!)有了答案或朝着明确答案的方向前进,我们就可以开始制定项目计划。
脚注
1
是否需要考虑权限?
2
与 Postgres 核心配置集成,还是创建单独的事物?
3
这确实是需要做出的关键决定。Go 风格的自动发现非常酷,可以确保全面索引,而无需开发人员注册或源代码存储的开销。另一方面,它需要 Go 包式的`$host/$user/$package`命名空间,以避免托管服务之间的命名冲突。另一方面,它直接允许使用替代和私有的源代码分发。但请参阅对crates.io 为什么不使用 GitHub 作为注册表的解释。
4
我们还需要考虑身份验证和身份管理。我们是否信任相关的 OAuth2 提供商,例如GitHub和BitBucket?或者我们是否需要使用postgresql.org 帐户?
5
受到Go 注册表服务(以及其他服务)的启发。
6
这将是一个有趣的挑战,因为我们不想过度优化 SEO(这很糟糕,而且通常是错误的),但需要一些方法来让结果在搜索结果中排名更高。也许最好将其托管在 PostgreSQL.org 上,并联系搜索引擎公司?
7
几年前,有人实现了这个功能!该服务从 PGXN 获取数据,并在 Postgres 版本和操作系统的矩阵上测试扩展,并生成一份非常好的报告。我原本打算与他们合作将其标准化,将其托管在 PGXN 子域上,并从 PGXN 的每个页面链接到它,但一直没有完成,项目也停滞了。我会尝试将其挖出来,看看我们是否可以将其作为基础进行构建。
8
提供一些扩展捆绑方法会很有趣,这样就可以在 CI/CD 管道中构建一个捆绑包,而无需在生产主机上安装 CLI。但另一方面,许多人会通过 Docker 构建或类似模式来完成此操作。