设置更新服务器

本文档的目的是提供有关安装本地服务 Firefox 更新以进行测试的说明。请注意,这些不是有关如何创建或运行生产更新服务器的说明。此更新服务方法旨在诱使 Firefox 执行通常不会执行的操作:反复下载和安装相同的更新。这对于测试很有用,但显然不是生产更新服务器的正确行为。

获取更新 MAR 文件

更新以 MAR 文件的形式提供。获取要使用的 MAR 文件有两种常见方法:下载预构建文件或自行构建。

下载 MAR 文件

预构建的 Nightly MAR 文件可以在 archive.mozilla.org 上的 此处找到。请确保您使用与您的机器配置匹配的文件。例如,如果您想要 2019 年 9 月 17 日的 Nightly MAR 文件,用于 64 位 Windows 机器,您可能需要位于 https://archive.mozilla.org/pub/firefox/nightly/2019/09/2019-09-17-09-36-29-mozilla-central/firefox-71.0a1.en-US.win64.complete.mar 的 MAR 文件。

可以在 此处找到发布版和测试版的预构建 MAR 文件。测试版构建是在版本字符串中带有 b 的构建。找到所需的版本后,MAR 文件将位于 update 目录中。您需要使用标记为 complete 的 MAR 文件,而不是部分 MAR 文件。这是一个可以使用此类 MAR 文件的示例:https://archive.mozilla.org/pub/firefox/releases/69.0b9/update/win64/en-US/firefox-69.0b9.complete.mar

构建 MAR 文件

在本地构建 MAR 文件更为复杂。问题的一部分在于,MAR 文件由 Mozilla 签名,因此您实际上无法自己构建“官方”MAR 文件。这是一项旨在防止任何人提供恶意更新的安全措施。如果您想使用本地构建的 MAR 文件,则正在更新的 Firefox 副本需要构建为允许未签名的 MAR 文件。有关在本地构建 Firefox 的更多信息,请参阅 构建 Firefox。为了使用本地构建的 MAR 文件,您需要将此行放在构建目录根目录下的 mozconfig 文件中(如果不存在,则创建它)

ac_add_options --enable-unverified-updates

否则,Firefox 应以正常方式构建。构建完成后,您可能希望将 Firefox 安装复制到其他位置。如果您在不移动安装的情况下更新安装,则进一步增量构建的尝试将无法正常工作,并且下次构建时需要执行清理操作。要移动安装,首先调用 ./mach package,然后将 <obj dir>/dist/firefox 复制到其他位置。复制的目录将是您的安装目录。

如果您正在运行 Windows 并希望使用 Mozilla 维护服务,则需要执行以下几个额外步骤。首先,需要“安装”维护服务。很可能,已经安装了不同的维护服务,可能位于 C:\Program Files (x86)\Mozilla Maintenance Service\maintenanceservice.exe。将该文件备份到另一个位置,并将其替换为 <obj dir>/dist/bin/maintenanceservice.exe。完成后不要忘记恢复备份。接下来,您需要更改创建的 Firefox 安装目录的权限。该目录及其父目录都应具有阻止当前用户写入的权限。

现在,您已经构建了一个能够使用本地构建的 MAR 文件的 Firefox 版本,是时候构建 MAR 文件了。首先,按照您希望更新后 Firefox 的方式构建它。如果您希望它在更新前后保持相同,则此步骤不是必需的,您可以使用与创建安装相同的构建。然后运行以下命令,适当地替换 <obj dir><MAR output path><version><channel>

$ ./mach package
$ touch "<obj dir>/dist/firefox/precomplete"
$ MAR="<obj dir>/dist/host/bin/mar.exe" MOZ_PRODUCT_VERSION=<version> MAR_CHANNEL_ID=<channel> ./tools/update-packaging/make_full_update.sh <MAR output path> "<obj dir>/dist/firefox"

对于 macOS,您应使用以下命令

$ ./mach package
$ touch "<obj dir>/dist/firefox/Firefox.app/Contents/Resources/precomplete"
$ MAR="<obj dir>/dist/host/bin/mar.exe" MOZ_PRODUCT_VERSION=<version> MAR_CHANNEL_ID=<channel> ./tools/update-packaging/make_full_update.sh <MAR output path> "<obj dir>/dist/firefox/Firefox.app"

对于本地构建,<channel> 可以是 default,而 <version> 可以是 browser/config/version.txt 中的值(或任意大的值,例如 2000.0a1)。

注意:让 make_full_update.sh 脚本接受包含空格的路径可能有点棘手。

提供更新

准备更新文件

首先,创建将从中提供更新的目录并将 MAR 文件放入其中。然后,在其中创建一个名为 update.xml 的文件,其中包含以下内容,将 <mar name><hash><size> 分别替换为 MAR 文件的文件名、其 sha512 哈希值以及其文件大小(以字节为单位)。

<?xml version="1.0" encoding="UTF-8"?>
<updates>
    <update type="minor" displayVersion="2000.0a1" appVersion="2000.0a1" platformVersion="2000.0a1" buildID="21181002100236">
        <patch type="complete" URL="http://127.0.0.1:8000/<mar name>" hashFunction="sha512" hashValue="<hash>" size="<size>"/>
    </update>
</updates>

如果您已下载正在使用的 MAR 文件,则可以在 archive.mozilla.org 上发布版或测试版目录的根目录中名为 SHA512SUMS 的文件中找到 sha512 值(您需要在其中搜索 MAR 文件的文件名,因为它包含该版本中每个文件的 sha512 值),对于 nightly 构建,您会在 MAR 文件旁边的文件中找到一个扩展名为 .checksums 的文件,其中包含该信息(例如,对于位于 https://archive.mozilla.org/pub/firefox/nightly/2019/09/2019-09-17-09-36-29-mozilla-central/firefox-71.0a1.en-US.win64.complete.mar 的 MAR 文件,文件 https://archive.mozilla.org/pub/firefox/nightly/2019/09/2019-09-17-09-36-29-mozilla-central/firefox-71.0a1.en-US.win64.checksums 包含该文件以及该 nightly 版本中所有其他 win64 文件的 sha512 值)。

如果您自己构建了 MAR 文件,则可以通过运行以下命令获取其 sha512 校验和,该命令应在 MozillaBuild 环境中的 Linux、macOS 或 Windows 中工作

shasum --algorithm 512 <filename>

在 Windows 上,您可以通过在文件资源管理器中右键单击 MAR 文件并选择“属性”来获取其确切的文件大小(以字节为单位)。您会在以“大小”开头的行的末尾找到正确的大小(以字节为单位),**而不是**以“磁盘上的大小”开头的行。将此数字粘贴到 XML 文件时,请务必删除逗号。

在 macOS 上,您可以通过运行以下命令获取 MAR 文件的确切大小

stat -f%z <filename>

或者在 Linux 上,相同的命令为

stat --format "%s" <filename>

启动更新服务器

现在,启动一个更新服务器,以便在端口 8000 上提供更新文件。一种简单的方法是使用 Python。请记住在启动服务器之前导航到正确的目录。这是 Python2 命令

$ python -m SimpleHTTPServer 8000

或者,这是 Python3 命令

$ python3 -m http.server 8000

如果您不确定是否已正确启动服务器,请尝试使用 Web 浏览器导航到 http://127.0.0.1:8000/update.xml 并确保您获得了之前创建的 XML 文件。

安装更新

您可能希望首先删除任何挂起的更新,以确保没有先前找到的更新干扰所需更新的安装。您可以使用 Firefox 的浏览器控制台中的此命令来确定更新目录

ChromeUtils.importESModule("resource://gre/modules/FileUtils.sys.mjs").FileUtils.getDir("UpdRootD", []).path

确定更新目录后,关闭 Firefox,浏览到该目录并删除名为 updates 的子目录。

接下来,您需要更改更新 URL 以指向本地 XML 文件。这可以通过企业策略最可靠地完成。策略文件位置取决于您使用的操作系统。
Windows/Linux:<install dir>/distribution/policies.json
macOS:<install dir>/Contents/Resources/distribution/policies.json
如有必要,创建 distribution 目录,并将此内容放入 policies.json
{
  "policies": {
    "AppUpdateURL": "http://127.0.0.1:8000/update.xml"
  }
}

现在您已准备好进行更新!从其安装目录中启动 Firefox 并导航到“更新”部分 about:preferences。您应该会看到它正在将更新下载到更新目录。由于传输完全是本地的,因此应该很快完成,并且会显示“重新启动以更新”按钮。单击它以重新启动并应用更新。