上周,一个名为 mimemagic 的 Ruby 库因开源许可证不兼容的问题导致 50 万 + 项目陷入混乱。
上周三,shared-mime-info 软件库的维护者 Bastien Nocera 给 Ruby 库 mimemagic 的维护者 Daniel Mendler 发送了消息:“你之前交付的 mimemagic 库采用了我的代码,使用了不兼容的软件许可证。”
shared-mime-info 库是在 GPLv2 许可证下授权的 ,而 mimemagic 是在 MIT 许可证下授权的,事实上这两种开源许可确实是不兼容的。Nocera 在 GitHub 的 Issues 上发帖:“使用 GPL 文件作为源文件,会使整个代码库都变成衍生代码,并且全部代码都应遵循 GPL 许可,所以如果有人在纯 MIT 代码库中或者是闭源应用程序中使用了 GPL 代码,应该及时纠正这个问题。”
得知此事之后,Mendler 先是向 Nocera 表示了感谢,并将最新的 0.4.0 和 0.3.6 版本移到 GPLv2 下,并从包注册表 RubyGems.org 上撤销了之前发布的版本,将 mimemagic GitHub 代码库存档。
虽然补救动作比较及时,但 Ruby on Rails 由于依赖 mimemeagic 0.3.5 仍然受到了影响。同时,还有 172 个其它软件包、共 577148 个不同的软件仓库也受到了影响。当然,并不是所有项目都会立即受到影响,但是任何试图从 RubyGems.org 获取 mimemagic 已撤销版本的构建过程都会失败,除非之前就已经实现了依赖缓存。
如何解决?
面对已经发生的开源许可不兼容的问题,我们应该如何解决呢?开源许可顾问 Paul Berg 表示:“这件事对于 Rails 造成了很大的影响。目前,有很多应用程序都是使用 Rails 开发的,由于 Rails 之前采用的是较为宽松的开源许可 MIT,所以这些应用程序自然不可能遵守 GPL 的条款。如果,我们将 Rails 改为采用 GPL 许可,那么成千上万的团队都可能要做出调整,这是不切实际的,我们必须寻找其它的办法。”
Ruby on Rails 团队讨论了很多解决方案,例如使用替代产品,比如 2-clause BSD 授权的 libmagic 或实现一个 mime 数据库的 Ruby 版本,但这些方法的工作量很大。
上周四,mimemagic 发布了 0.4.1 版本,删除了 GPL 覆盖的代码,恢复了 MIT 许可,用户现在必须自己提供 mime 类型数据库。对于 0.3.6 和 0.4.0 版本的撤销,许多人感到遗憾。
上周五,Rails 团队经过讨论最终决定将 mimemagic 换成另一个名为 Marcel 的库。Rails 5.2.5、6.0.3.6 和 6.1.3.1 发布了带有 ActiveStorage 服务的修订版,用 Marcel 1.0.0 取代了它的 mimemagic 依赖。
Basecamp 的开发人员 George Claghorn 在发布新版本的博客文章中解释说:“在 1.0.0 之前,根据 MIT 许可证的条款发行的 Marcel(和 Rails 一样)间接依赖在不兼容的 GNU 通用公共许可证下发布的 mime 类型数据。而 Marcel 1.0.0 则是直接打包从 Apache Tika 改编的 mime 类型数据,这些数据是在许可且兼容的 Apache 许可证 2.0 下发布的。”
要做到这一点需要费一些功夫。Marcel 本质上是 mimemagic 的包装,因此它的某些部分必须经过修改才能被 MIT 许可。现在,Marcel 的 mime 签名数据表(称为魔术数字签名)来自 Apache Tika,因此不需要遵循 GPLv2。
后记:开源许可的兼容性
目前经过 Open Source Initiative(OSI)认证的开源许可证共有 80 余种。中国信通院云计算与大数据研究所开源运营主管郭雪将这些开源许可证根据使用条件的不同,分为了四类:开放性开源许可证、弱传染型开源许可证、传染型开源许可证和强传染型许可证。
开放性开源许可证是最基本的类型,用户可以修改代码后闭源。常见的许可证包括:MIT、BSD、Apache 等;
弱传染型开源许可证是指如果一个软件包含该协议下部分代码,完全发布时某些部分必须适用该许可证,其它部分可在其它写协议下发布。常见的许可证包括:LGPL、MPL、EPL 等。
弱传染型开源许可证明确修改版本必须以同一许可证发布,如果一个软件包含该协议下的代码,完全发布时必须作为整体适用该协议。常见的许可证为 GPL;
强传染型许可证在传染型许可证要求的基础上,还要求使用开源软件提供云服务时也必须提供源代码。常见的许可证为 AGPL。
当一个开源软件使用了一个许可证,而你想把它的代码整合到你发布的开源项目中时,我们应该如何判断两个许可证的兼容性呢?大家可以参考信通院发布的这张图: