让代码协作平台走向联邦化 #

讲者:Anthony Wang
译者:Hayden

译者注:该演讲最初由译者听译并制作视频字幕,之后编辑成本文。你也可以下载源字幕文件(.ass),使用合适的播放器配合原视频观看。

大家好,今天我来谈一谈联邦化的 forge。首先,我会讲解 forge 是什么,然后再讲“联邦化”是什么。

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(不包括 forge) #

尽管 Git 本身是分布式的源代码管理系统,但它并不能提供访问权管理能力,也不能拿它来分享仓库。你要把它放在一个公开的服务器或者网站,其他人才能 clone 你的仓库。

而 Git-SSB、Radicle 这类项目能做的,就是托管你的 Git 仓库。但和一般的网站不一样,而是基于 P2P 网络之类的。

这些项目很有意思,但不是今天谈论的主题,因为它们更多是让你能够用 P2P 的方式来托管 Git 仓库,但并没有 bug 追踪或者 PR 功能,所以它们不是 forge。

目前的问题 #

接下来讲一讲,目前的情况下有什么问题。

你可能听过几年前 GitHub 的公告:为了遵守美国法律,GitHub 决定禁止伊朗等国家的开发者的访问。当然,它作为一个专有平台,还有其他许多问题。其他就不谈论了,你可以自己上网搜索,了解为什么 GitHub 不好。

今天来谈点更加有趣的。想想自由软件的开发是怎样进行的。这是全球化的大规模开发过程,全球各地的人都在为这些项目做贡献。

这个过程是十分去中心化的。这时,就没道理强迫大家用一个中心化的平台了。相反,我们想给大家更多选择,避免限制在单一服务商,允许大家用自己想用的 forge,而这些 forge 将能够相互通讯。这样,我们就能形成一个全球的去中心化网络来托管代码。要实现这一目标,就需要“联邦化”,也就是不同服务器之间的通讯。

ActivityPub 和联邦化 #

最近你应该听过 Mastodon。它就是一个用 ActivityPub 协议实现去中心化的社交媒体/微博平台。

ActivityPub 是一个非常通用的协议。它是基于参与者(actor)模型这种理论概念构建的。这种模型,由许多的 actor 组成,它们可以是人或者机器人之类的。所有这些人都可以相互发送信息,有收件箱和发件箱,就像邮箱一样。

ActivityPub 提供了一些指南,说明了 actor 之间发送什么特定消息,以及 actor 要如何处理这些消息及转发消息等。但总之,这个协议是十分通用的。它设计出来非常灵活和通用,所以,你用它并不足以构建一个应用程序,还要自己填补很多东西。

比如说,Mastodon 有很多 ActivityPub 扩展,在 ActivityPub 之上进行了很多开发,才实现了一个微博应用。所以 ActivityPub 是十分通用的,需要做很多工作才能实现有用的东西。

ForgeFed:ActivityPub 扩展 #

我们开发了一个叫 ForgeFed 的项目,它是一个 ActivityPub 协议的扩展。它由两大部分组成: vocabulary 和 behavior。这个网站上有 modeling vocabulary,但它们是十分相似的。

vocabulary 就像,比如说这里有一个仓库,我们想让这种通用的数据格式来代表各种 forge 的数据(比如说仓库、issue、补丁等)。如果不同的 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 实现 #

现在可以讲一讲实现了。目前,我们在做两个 ForgeFed 实现。

有一个实现是 Vervis,但并不是适合普通用户使用的,它更多是 ForgeFed 开发者测试和实验用的。

不过,我们还有第二个实现,就是一个叫 Forgejo 的 forge 软件。

这背后的故事可能有点复杂。原本我们是要在 Gitea 实现联邦化的,它是一个很流行的自托管式自由软件 forge。但不幸的是 Gitea 被一家盈利性公司收购了,接着一切都乱了套。最后,许多人就一起开了个新的分支,叫 Forgejo。所有联邦化开发者都去了 Forgejo。要做的事也很多,有 100 多项任务。任务很重,要在架构上做出很多改变。

Demo(见原视频) #

现在我建立了两个 Forgejo 实例,这里有一个,还有第二个。第二个实例有一个仓库,这两个很容易区分,这个是亮色的,另一个是暗色的。这里有一个,那里也有一个。

这个亮色的有一个仓库,而我想做的就是,在这个实例,向另一个实例的仓库提交贡献。我们会让两个 forge 互相通讯。

先在这里登录,这个 forge 是完全空白的,我建起来当 demo 的。

目前这个联邦功能还没有 UI,因为我们想先把后端写好,不然没有后端,联邦也不能用。它最终的工作方式就是,把要贡献或搜索的项目地址复制一下,这里会有一个输入框,用于全局搜索。位置就在这里,但是还没实现。所以,我先手动进入 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。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 是一个荷兰的非盈利性组织,为这些自由软件项目提供了资助,所以我们有充足的资金支持。

观众问答 #

Q1:我对 Fediverse 很感兴趣,关注你的项目也有一段时间了。我想问的问题,也是 Fediverse 仍然存在的一个问题。就拿 ForgeFed 或者 Forgejo 当例子。假如我从联邦网络中众多的实例中,选了一个实例来托管我的项目,怎么才能保证它的可靠性呢?显然,我在 GitHub 上注册,一大原因就是,能保证我存的代码能一直在那里。所以,有没有计划能实现,如果一个实例不可靠了,能够简单地迁移实例,或者有没有解决这个问题的方法?当涉及到实例的时候,可靠性确实是个重要的问题。

A1:好问题。这就关联到了我刚刚说的,要尽可能简单地迁移。我们想做的就是,让你能将帐号下的所有仓库,从一个服务器迁移到另一个服务器。并且,有了这种通用的数据格式,也能十分轻松地建立镜像。比如说,现在 Forgejo 可以将一个仓库镜像到另一个仓库。不过,因为镜像是使用 Git 实现的,所以这只建立了代码的镜像,因为 Git 没有管理 bug 追踪或者 PR。有了 ForgeFed,它就延伸了 Git 的镜像,从而能够将项目所有issue 等,同样地镜像过去。所以,有了镜像功能,希望也能够提高 Forgejo 实例可靠性,就像备份一样。这样,数据就存在了多个实例上。

Q2:这个项目十分不错,意义非凡。我想知道,你有没有联系 Social Web Working Group,告诉他们这个项目?我之所以会这么问,是因为过去几周,有很多的讨论,除了把 ActivityPub 用在微博平台,还能用在什么地方,以及是要更新 ActivityPub,还是把它归入 ActivityStreams 里。 所以我想知道,你有没有联系他们。如果没有的话,推荐你联系一下。

A2:我个人还没联系他们。不过我肯定会考虑的。

Q3:比起自由软件用例的那个问题,这个问题应该没那么有趣。不过,所谓“访问控制”,就是说只允许网络中特定的人访问某些仓库吗?

A3:这个问题其实很有意思。在 ForgeFed 协议里,我们尝试用对象能力(object capability)模型来实现权限管理和访问控制。我想在 Forgejo 实现里,不会用到这些花样的对象能力等东西。不过,在协议方面,我们确实在这么做。

Q4:你刚刚谈到了跨站搜索。我不知道能不能实现,搜索的时候也使用到这个基于对象的东西。还是说,我理解错了?

A4:跨站搜索实际上是 ForgeFed 之外的独立的项目。我所说的对象能力模型,就是另一种管理权限等的方法。所以我想这两个东西应该没什么关联。

Q5:也许我完全搞错了,如果我有什么地方弄错了,还请纠正。你刚刚谈到了,跨站搜索有一个问题,而大家都想要 Mastodon 把它加上去。现在潜在的问题是,只有允许和禁止两个选项。所以,能不能给对象分配一些属性,这样我就能选择,只有在搜索这种类型的东西的时候,才能看到我的东西?刚刚谈论的话题,让我感觉和这个问题有点关联。

A5:我想我理解了。我其实并没有在开发这个跨站搜索,不过我觉得这是一个很有意思的探索方向。

Q6:似乎 ForgeFed 建立的标准,同时也能用于 Git-SSB 或者 Radicle,从而建立一个能与其他系统同时工作的 P2P 项目;两者都使用相同的系统、相同的 spec,并且联邦节点上的 forge能互动,相互操作。你有没有考虑过让它和另一个协议工作?

A6:我认为完全是可以的。不过我们主要的关注点是传统的 forge,也就是服务器上的,而不是 P2P 网络上的。但我认为 ForgeFed 完全有潜力用在 P2P 网络上。

Q7:SourceHut 那个基于 SMTP 的标准,是否和 ForgeFed 项目有任何关联?还是说那只是给一个特定的 forge,用来借 SMTP 自己做各种事情的?

A7:我实际上并没有仔细研究过 SourceHut,不过我觉得它应该确实在实现类似的东西。我想 SourceHut 参与了 ForgeFed 的早期开发,但那是好几年前了。我并不清楚,因为我是在大约一年前加入这个项目的。

Q8:有一些 forge 软件,比如说 Gerrit,工作方式有些不一样。相比 fork 并提交 PR,你可以提交补丁然后 cherry-pick。这种工作流有些不一样。你认为这要怎么和 ForgeFed 工作?

A8:这有些复杂。ForgeFed 尽量保持通用,尽量支持所有不同的工作流。实际上,它并不知道你用的是什么版本管理系统。我们的一位 ForgeFed 开发者对 Darcs 版本管理系统很感兴趣。所以,我认为理论上,所有这些工作流都会受到支持,并且能够相互操作。但实际上,不同的 forge 都有许多差异。所以,forge 之间的通讯,可能无法像预期一样工作,毕竟不同的 forge 都有不同之处。

Q9:我不太熟悉 ActivityPub 之类的东西。你认为能不能这样:假如有一个联邦化的 forge,你想给它发一个 PR 什么的。能不能单纯在本地的客户端这么做,向那个 forge 发送请求?

A9:我认为理论上可行。但考虑到 ActivityPub 通常的实现方式,这可能更加困难一些。你应该还需要在其他实现了 ForgeFed 的 forge 上有一个帐号,才能这么做。

Q10:在 Mastodon 上可以看 Pixelfed 帖子,也可以看 PeerTube 视频。有没有计划,或者能不能在 Mastodon 上看 PR,而不对 Mastodon 进行修改?还是说 Mastodon 有一个类型白名单,导致 PR 这类信息不能在上面显示?

A10:我有研究过这个问题。我们想的是,不止是 forge 之间相互操作,还要 Forgejo 和 Mastodon 之类的相互操作。然而,Mastodon 的源代码里确实有一个类型白名单。ActivityPub 里有一个 type array 支持,可能会有些用。有了这个,就可以给这个 activity 指定多个 type。可惜 Mastodon 也不支持 type array。而且,Forgejo 在实现 ForgeFed 时用到的库也不支持 type array。如果能实现,那应该很有帮助,但我不知道有没有解决方案。所以,我们也得给 Mastodon 贡献一个补丁,这样才能实现在 Mastodon 上对一个 issue 进行评论,或者看 PR。不过这是以后的事了。

Q10(续):这个 type array 是这样没错。我在写一个通用的 ActivityPub 只读客户端。它确实不支持 type array,只支持 string 类型的 type。

Q11:这个协议是否支持数字签名,来检查某些行为是否为用户所为?

A11:基本所有 ActivityPub 实现都有签名机制。ActivityPub 标准本身是没有签名机制的。是 Mastodon 先有,然后其他的为了兼容性才加上去的。所以,我们会增加签名机制,从而给 PR 等签名。


Copyright (C) Anthony Wang 2023
Copyright (C) Hayden 2023-2024

本页面以 CC BY-SA 4.0 许可。