讲者: Anthony Wang 译者: Hayden 许可证: CC BY-SA 4.0
大家好 今天我来谈一谈"联邦"式的软件 forge
首先 我会讲解 forge 是什么
然后再讲"联邦" (federation) 是什么
forge 就是用来进行代码托管以及协作的网站
比如说 GitHub 就是个好例子 它就是一个 forge
它是个专有的中心化 forge 但也常常拿来托管自由软件项目
现在大约 95% 以上的自由软件都托管在了 GitHub
当然 也有许多替代品 比如说 GitLab, Gitea, Forgejo 等等
刚刚说的所有这些 都是 forge 软件
它们本身不是网站 而是可以下载的服务器软件
把它装上服务器运行 你就有了一个 forge 网站
当然 并非人人都想自己运行 forge 服务器
所以就有了许多网站 比如 Codeberg, Framagit, 以及 KDE 的 GitLab 实例
这些 forge 和 forge 平台有很多
有的是自由软件 比如 Gitea 和 Forgejo 有的则是 GitHub
目前的情况是 它们都成了孤岛
如果我 Forgejo 实例上有个项目, 而别人 GitLab 实例上有个项目
于是 如果我要向别人的项目提交贡献
那我就得在别人的实例上创一个号 走一遍流程
然后才能在他们的 forge 上提交贡献
所以 目前任何这些 forge 之间都没有互通
我也简单说一下为什么用 forge
forge 好处有很多 比如使用简单 工作流基于邮件 访问更加方便等
你应该也知道 Git 本身已经是去中心化的了
但是 Git 只是为了一个目的专门设计的: 那就是充当追踪代码和文件的工具
Git 在那方面做得很好
但它本身不能用来追踪 bug, 提交 PR, 管理 projects 等
比如说 Git 原本开发出来 是为了管理 Linux 内核的源代码
而内核开发者还开了邮件列表用来接收补丁
他们还有 bug 追踪器等工具
所以 单独用 Git 不足以来开发软件
还需要其他工具来实现 bug 追踪 管理补丁 PR 等
而 forge 就提供了这些功能
最后还要提一下 SourceHut 这个 forge 越来越流行了
它也确实在试图处理这个孤岛问题
于是便允许人们通过 SMTP 协议发邮件 来与 SourceHut 上的项目交互
那种方法也有问题 我之后会解释
这个幻灯片的标题可能有点误导...
如果你想和别人分享你的仓库或者代码项目
那你就要通过...
即使 Git 本身是分布式的源代码管理系统
它并不能提供访问权管理能力 你也不能拿它来分享仓库
你要把它放在一个公开的服务器或者网站
其他人才能 clone 你的仓库
而这里列出的项目能做的 就是托管你的 Git 仓库
但和一般的网站不一样 而是基于 P2P 网络之类的
这些项目很有意思 但不是今天谈论的主题
因为它们更多是让你能够用 P2P 的方式来托管 Git 仓库
但并没有 bug 追踪或者 PR 功能 所以它们不是 forge
接下来讲一讲 目前的情况下有什么问题
你可能听过几年前 GitHub 的公告
为了遵守美国法律 GitHub 决定禁止伊朗等国家的开发者的访问
当然 它作为一个专有平台 还有其他许多问题
其他就不谈论了 你可以自己上网搜索 了解为什么 GitHub 不好
今天来谈点更加有趣的
想想自由软件的开发是怎样进行的
这是全球化的大规模开发过程
全球各地的人都在为这些项目做贡献
这个过程是十分去中心化的
这时 没道理强迫大家用一个中心化的平台
相反 我们想给大家更多选择 避免限制在单一服务商
允许大家用自己想用的 forge
而这些 forge 将能够相互通讯
这样我们就能形成一个 全球的去中心化网络来托管代码
要实现这一目标 就需要 "联邦"(federation)
也就是不同服务器之间的通讯
最近你应该听过 Mastodon
它就是一个用 ActivityPub 协议 实现去中心化的社交媒体/微博平台
ActivityPub 是一个非常通用的协议 它基于参与者 (actor) 模型这种理论概念构建
这种模型 由许多的 actor 组成 它们可以是人或者机器人之类的
所有这些人都可以相互发送信息 有收件箱和发件箱 就像邮箱一样
ActivityPub 提供了一些指南
说明了 actor 之间发送什么特定消息 以及 actor 要如何处理这些消息和转发消息等
但总之 这个协议是十分通用的
它设计出来 非常灵活和通用
所以 你用它并不足以构建一个应用程序
你还要自己填补很多东西
比如说 Mastodon 有很多 ActivityPub 扩展
在 ActivityPub 之上进行了很多开发 才实现了一个微博应用
所以 ActivityPub 是十分通用的
需要做很多工作才能实现有用的东西
而我们开发了一个叫 ForgeFed 的项目
它是一个 ActivityPub 协议的扩展
它由两大部分组成
我给你们看看...
有两个部分: vocabulary 和 behavior
这个网站上有 modeling vocabulary 但它们是十分相似的
vocabulary 就像...
比如说这里有一个仓库
我们想让这种通用的数据格式来代表各种 forge 的数据
比如说仓库, issues, 补丁等
如果不同的 forge 都实现 ForgeFed
那我们就需要他们发送的数据 都遵循这种数据格式
比如说 对仓库而言 就有特定的表达方式
它是基于一种标准的 有很多例子可以参考
behavior 的话 就像我们互发了消息 得到了这种通用消息格式
比如说我的 forge 收到了补丁或者 PR 消息
那我的 forge 该干些什么 以及它应该产生什么连带效果
这就是这个协议的 behavior 部分规定的
而我们之所以需要这个协议 是因为 ActivityPub 协议过于通用
我们得规定这些扩展
这样的话 forge 联邦的各种实现 才能相互兼容 相互操作
我还得说说用 SMTP 实现联邦的一些问题
因为这个协议也广泛用来实现联邦
SMTP 有这几大问题
一是 SMTP 邮件受到了几家大公司的独占 比如说 Gmail 和 Microsoft Outlook 等
这是一种寡头垄断 或者说掌控邮件的只有几家公司
而且 自托管邮箱也不容易
我没法在家里的电脑上建一个邮箱服务器 然后用就它来收发邮件
因为邮件一直以来都面临 spam 问题
许多大型的邮箱服务提供商 采取了排斥性极强的反 spam 政策
这导致根本不可能在家里搭建邮箱服务器
而 ForgeFed 实现了服务器之间的透明协作
即使这些服务器运行了不同的 forge 软件
我们要实现的目标就是 如果你要贡献到一个其他网站其他 forge 上的项目
你就应该感觉像在本地 forge 上贡献一样
这里我也有一个小 demo
你可以提 issue, project 开 PR 或者发送补丁
你可以给 issue 等发评论 和不同 forge 上的人创建组织或团队
这些都是可能需要的功能
而最后两点就更加有意思了
值得一提的是 Mastodon 并没有跨站搜索功能
Mastodon 早期设计就是这样的 你不能在你的实例上搜索 然后获得跨站搜索结果
最近有许多人尝试为 Mastodon / 微博平台 / Fediverse 开发跨站搜索
但遭到了人们的反对
因为许多这些全局搜索项目 都无差异地将无数帖子收录了进去
它们并没有筛选 所以很多人都不满意
我们有一个简单的项目 叫 StarChart
不过我们最近没在开发这个项目 因为我们想先把前三项弄好
但是最终我们会开发出一个选择性加入的全局搜索
因为 如果你问许多自由软件开发者 即使 GitHub 是专有的 为什么还要用它
他们常常会说 因为每个人都在用它 我把我项目放上去 其他人就会发现它
毕竟 GitHub 有这种全局搜索功能
你可以输入搜索词 然后它就会返回许多项目 十分有用
人们就会想 如果转用这些联邦的 forge 就会错过这样的机会
但有了跨站搜索 我们应该就能提供这样的机会
最后 我们想实现的是 能够尽可能简单地 把帐号和仓库等 从一个服务器无缝迁移到另一个
因为可能有很多原因让你想迁移
可能你现处的 forge 服务器改动了政策 你不喜欢了
可能是服务器有资金问题
可能他们不想你的身份和这个 forge 有关联
或者可能他们硬件出了问题 服务器不稳定 要关闭了
而 ForgeFed 的一个目的 就是扩展 ActivityPub 让你能够轻松将项目迁移到其他服务器
这仅仅是个开始
我们还有更远大的理想 就是从此发展一整个生态
大家经常用 GitHub 还有另一个原因
那就是 GitHub 拥有巨大的生态 所有网站, app, 工具都与 GitHub 兼容并集成
比如说 如果你想用 GitHub 的 CI 或构建系统
大家已经写了数千个插件 让你能够更轻松地用他们的 CI
而且许多网站都有 GitHub 集成 比如从 GitHub 导入
也有一些东西 制作出来只能与 GitHub 及其 API 兼容
所以他们给自己围上了高墙 多亏了这些只兼容 GitHub 生态的应用
我们相信 有了 ForgeFed 我们可以做出类似的替代品 但是做得更好
由于我们有 ForgeFed 这个开放的协议
任何人或者任何代码协作工具或网站 都可以读 ForgeFed 的 spec, 然后实现它
接着他们的网站或者工具也能添加 ForgeFed 支持
由于他们的工具使用了 这个可以相互操作的 ForgeFed 协议
就不会像 GitHub 一样 你只能受限于那一个 API 下的 forge
在未来 我们会有很多不同的 forge 很多不同的工具 它们都在 ForgeFed 之上
它们都有这种通用的数据格式和协议
所以他们都能够互相通讯和操作
这就是我们总的图景
我想现在可以讲一讲实现
目前 我们在做 ForgeFed 的两个实现
有一个实现是 Vervis 但并不是适合普通用户使用的
它更多是 ForgeFed 开发者测试和实验用的
不过 我们还有第二个实现 就是一个叫 Forgejo 的 forge 软件
这背后的故事可能有点复杂
原本我们是要在 Gitea 实现的 它是一个很流行的自托管式自由软件 forge
但不幸的是 Gitea 被一家盈利性公司收购了
接着一切都乱了套
最后 许多人就一起开了个新的分支 叫 Forgejo
许多... 应该是所有联邦化开发者都去了 Forgejo
要做的事也很多 实现这个有 100 多项任务
任务很重 要在架构上做出很多改变
现在我建立了两个 Forgejo 实例
这里有一个 还有第二个
第二个实例有一个仓库
这两个很容易区分 这个是亮色的 另一个是暗色的
这里有一个 那里也有一个
这个亮色的有一个仓库
而我想做的就是 在这个实例 向另一个实例的仓库提交贡献
我们会让两个 forge 互相通讯
先在这里登录
这个 forge 是完全空白的 我建起来当 demo 的
目前这个联邦功能还没有 UI 因为我们想先把后端写好
不然没有后端 联邦也不能用
它最终的工作方式就是 把要贡献或搜索的项目地址复制一下
这里会有一个输入框 用于全局搜索
位置就在这里 但是还没实现
所以 我先手动进入 URI... API endpoint
现在我们想在自己的实例上查看另一个项目
这是贡献的第一步
这 API endpoint 有一点复杂
我看看还记不记得
当然 这是因为我们还没做好前端
先用一下这个麻烦的方法
但有了 UI 就可以自动完成了
应该没打错吧
好了 可以了
可以看见 我这个帐号的用户名就是 "a"
现在我在我自己的实例上看那个帐号的仓库
我想发个 PR 提交贡献
就像平常一样 我们 fork 它
现在我们发个 PR 过去
看 现在我要发到另一个实例去
点击 Create Pull Request
如果正常的话 就可以在这里看到这个 PR
然后再看看这里 也有了
可以看到改动的文件
成了 这就是这个 demo 实际工作的样子
亮色和暗色的两个 forge 能够互相通讯
所以我就能在这里贡献另一个 forge 的 Hello World
这就是一个简单的 demo 演示了我们能做的许多事情之一
现在我们完成了整个任务列表的 40%
但并不是 100% 完成了才能开始联邦化
但愿 Forgejo 项目能在两个多月之后实现能用的联邦
ForgeFed 协议本身 已经开发大概 5 年了
而这个一个特定的实现 迄今开发了1 年多了
不过尽管 ForgeFed 协议 我们已经开发了很久
但它还不是很完整
这两个项目的 vocabulary 都还没涵盖 现在 forge 能做的所有事情
很多不同的东西都还没做完
而且 还有很多问题是我们要应对或者注意的
第一个问题就是 spam 和管理
因为任何去中心化的网络 都会有许多社会问题
幸运的是 有应对这些问题的范例
而不幸的是 没有一个最好的解决方案能解决 spam 和管理问题
我们也一直在思考这个问题
因为我们得消灭 spam 并建立一套良好的管理系统
这样才能让它更加易用 更加友好
另一个经常出现在联邦系统 (比如说 Mastodon) 的问题是
会有少数几个大型实例 或者协议的一个实现 出现独占的情况
比如对微博平台而言 那就是 Mastodon Fediverse 里的大多数人用的都是它
它会对 spec 的发展方向有主导作用
有意思的是 ActivityPub 的 spec 基本上已经处于休眠期
但如果想建立一个微博应用 你实际上得遵循 Mastodon 的所有扩展
所以 Mastodon 很大程度上影响着社区的发展方向
这可能有很大的问题
而且 Mastodon 也有三四个超大实例
大多数人都在那几个大型实例上
也有可能面临这样的情况 这些实例对整个网络有着很大的权利和影响
并且控制着整个网络的演进方向等
这种情况没有最优解法
但我们相信的是 通过迁移 将一个 forge 上的数据导入另一个 forge
应该能缓解问题的严重性
因为 如果许多人都在一个巨型 forge 实例上
而这个 forge 立下了颇受争议的政策
那如果人们可以轻松迁移数据 就能解决一部分问题
下一点 就是自托管服务器时 一般都会有的问题
大多数人都会感觉不方便
如果你想自托管 Forgejo 那有很多步骤要走
比如说买域名 买服务器 要么是买 VPS 或者用家里的电脑
但如果你要用家里的电脑的话 你就得进入路由器设置 配置端口转发等
做这些很复杂 一点都不简单
不过因为这是个一般性的问题
所以我们 ForgeFed 没有直接强调它
许多项目已经在着手解决了
比如说 有一些项目 能帮用户安装和运行服务器
而不用关心各种细节和项目维护
它们用打隧道的方法 这样的话 就算没公网 IP 也能在自己的设备上轻松托管
另一点值得考虑的问题是
性能以及网络的伸缩性
因为许多自由软件项目的规模都十分庞大
比如说 Gitea 它有成千上万的 issue
好在大多数 issue 最后都关闭了
而且它还有几百位贡献者 几百个 PR
总之 这些项目十分庞大 需要非常注重伸缩性和性能
举例来说 Mastodon 就容易出现问题
我一直举这个类比 是因为它也有相似的情况 它也用 ActivityPub 并且还进行了扩展
假如你在 Mastodon 上发布了一条带链接的嘟文 那这条嘟文就会传播到全世界各地的服务器
然后 为了生成链接预览 所有这些服务器都会去访问这个链接
这样 数千个服务器都会同时向这个网站发送请求
可能这个网站的网络连接不好
于是 这一获取链接预览的行为 就对网站造成了 DDoS 攻击
所以这一点也是需要注意的
我还想指出的是
Forgejo 实现以及 ForgeFed 协议本身
这两个项目都是 NLNet 资助的
NLNet 是一个荷兰的非盈利性组织 为这些自由软件项目提供了资助
所以我们有充足的资金支持 很不错
我想说的就这么多了
现在欢迎大家提问
Q：我对 Fediverse 很感兴趣，关注你的项目也有一段时间了。 我想问的问题，也是 Fediverse 仍然存在的一个问题。 就拿 ForgeFed 或者 Forgejo 当例子。假如我从联邦网络中 众多的实例中，选了一个实例来托管我的项目，怎么才能保证 它的可靠性呢？显然，我在 GitHub 上注册，一个原因就是， 能保证我存的代码能一直在那里。所以，有没有计划能实现， 如果一个实例不可靠了，能够简单地迁移实例，或者有没有 解决这个问题的方法？当涉及到实例的时候，可靠性确实是个 重要的问题。
A：好问题。这就关联到了我刚刚说的，要尽可能简单地迁移。 我们想做的就是，让你能将帐号下的所有仓库，从一个服务器 迁移到另一个服务器。并且，有了这种通用的数据格式，也能 十分轻松地建立镜像。比如说，现在 Forgejo 可以将一个仓库 镜像到另一个仓库。不过，因为镜像是使用 Git 实现的，所以 这只建立了代码的镜像，因为 Git 没有管理 bug 追踪或者 PR。 有了 ForgeFed，它就延伸了 Git 的镜像，从而能够将项目所有 issue 等，同样地镜像过去。所以，有了镜像功能，希望也能够 提高 Forgejo 实例可靠性，就像备份一样。这样，数据就存在 了多个实例上。
Q：这个项目十分不错，意义非凡。我想知道，你有没有联系 Social Web Working Group，告诉他们这个项目？我之所以会 这么问，是因为过去几周，有很多的讨论，除了把 ActivityPub 用在微博平台，还能用在什么地方，以及是要更新 ActivityPub， 还是把它归入 ActivityStreams 里。 所以我想知道，你有没有 联系他们。如果没有的话，推荐你联系一下。
A：我个人还没联系他们。不过我肯定会考虑的。
Q：比起自由软件用例的那个问题，这个问题应该没那么有趣。 总之，所谓“访问控制”，就是说只允许网络中特定的人访问 某些仓库吗？
A：这个问题其实很有意思。在 ForgeFed 协议里，我们尝试用 对象能力（object capability）模型来实现权限管理和访问控制。 我想在 Forgejo 实现里，不会用到这些花样的对象能力等东西。 不过，在协议方面，我们确实在这么做。
Q：你刚刚谈到了跨站搜索。我不知道能不能实现，搜索的时候 也使用到这个基于对象的东西。还是说，我理解错了？
A：跨站搜索实际上是 ForgeFed 之外的独立的项目。我所说的 对象能力模型，就是另一种管理权限等的方法。所以我想这两个 东西应该没什么关联。
Q：也许我完全搞错了，如果我有什么地方弄错了，还请纠正。 你刚刚谈到了，跨站搜索有一个问题，而大家都想要 Mastodon 把它加上去。现在潜在的问题是，只有允许和禁止两个选项。 所以，能不能给对象分配一些属性，这样我就能选择，只有 在搜索这类型的东西的时候，才能看到我的东西？刚刚谈论的 话题，让我感觉和这个问题有点关联。
A：我想我理解了。我其实并没有在开发这个跨站搜索，不过 我觉得这是一个很有意思的探索方向。
Q：似乎 ForgeFed 建立的标准，同时也能用于 Git-SSB 或者 Radicle，从而建立一个能与其他系统同时工作的 P2P 项目； 两者都使用相同的系统、相同的 spec，并且联邦节点上的 forge 能互动，相互操作。你有没有考虑过让它和另一个协议工作？
A：我认为完全是可以的。不过我们主要的关注点是传统的 forge， 也就是服务器上的，而不是 P2P 网络上的。但我认为 ForgeFed 完全有潜力用在 P2P 网络上。
Q：SourceHut 那个基于 SMTP 的标准，是否和 ForgeFed 项目 有任何关联？还是说那只是给一个特定的 forge，用来借 SMTP 自己做各种事情的？
A：我实际上并没有仔细研究过 SourceHut，不过我觉得它应该 确实在实现类似的东西。我想 SourceHut 参与了 ForgeFed 的 早期开发，但那是好几年前了。我并不清楚，因为我是在大约 一年前加入这个项目的。
Q：有一些 forge 软件，比如说 Gerrit，工作方式有些不一样。 相比 fork 并提交 PR，你可以提交补丁然后 cherry-pick。这种 工作流有些不一样。你认为这要怎么和 ForgeFed 工作？
A：这有些复杂。ForgeFed 尽量保持通用，尽量支持所有不同的 工作流。实际上，它并不在乎你用的是什么版本管理系统。 我们的一位 ForgeFed 开发者对 Darcs 版本管理系统很感兴趣。 所以，我认为理论上，所有这些工作流都会受到支持，并且能够 相互操作。但实际上，不同的 forge 都有许多差异。所以， forge 之间的通讯，可能无法像预期一样工作，毕竟不同的 forge 都有不同之处。
Q：我不太熟悉 ActivityPub 之类的东西。你认为能不能这样： 假如有一个联邦化的 forge，你想给它发一个 PR 什么的。 能不能单纯在本地的客户端这么做，向那个 forge 发送请求？
A：我认为理论上可行。但考虑到 ActivityPub 通常的实现方式， 这可能更加困难一些。你应该还需要在其他实现了 ForgeFed 的 forge 上有一个帐号，才能这么做。
Q：你能在 Mastodon 上看 Pixelfed 帖子，也能在 Mastodon 上 看 PeerTube 视频。有没有计划，或者能不能在 Mastodon 上 看 PR，而不对 Mastodon 进行修改？还是说 Mastodon 有一个 类型白名单，导致 PR 这类信息不能在上面显示？
A：我有研究过这个问题。我们想的是，不止是 forge 之间相互 操作，还要 Forgejo 和 Mastodon 之类的相互操作。然而， Mastodon 的源代码里确实有一个类型白名单。ActivityPub 里 有一个 type array 支持，可能会有些用。有了这个，就可以给 这个 activity 指定多个 type。可惜 Mastodon 也不支持 type array。而且，Forgejo 在实现 ForgeFed 时用到的库也不支持 type array。如果能实现，那应该很有帮助，但我不知道有没有 解决方案。所以，我们也得给 Mastodon 贡献一个补丁，这样 才能实现在 Mastodon 上对一个 issue 进行评论，或者看 PR。 不过这是以后的事了。
Q （续）：这个 type array 是这样没错。我在写一个通用的 ActivityPub 只读客户端。它确实不支持 type array，只支持 string 类型的 type。
Q：这个协议是否支持数字签名，来检查某些行为是否为用户所为？
A：基本所有 ActivityPub 实现都有签名机制。ActivityPub 标准 本身是没有签名机制的。是 Mastodon 先有，然后其他的为了 兼容性才加上去的。所以，我们会增加签名机制，从而给 PR 等 签名。
我的演讲到此结束 谢谢大家
Towards Federated Software Forges 讲者: Anthony Wang 译者: Hayden 源视频与中文翻译均以 CC BY-SA 4.0 发布