自动更新
更新 Drupal 网站是一项复杂、耗时且成本高的任务。表面上看似简单,但要确保更新过程安全可靠,同时让网站所有者和访问者都能放心,是一项颇具挑战的问题。
Drupal 的自动更新服务旨在简化这一过程,并确保更新能够正确、安全地应用。
请注意,自动更新是 Drupal 项目的战略性计划。目前该计划仍在开发中,因此需要注意以下几点:
- 自动更新模块尚未包含在核心中。当前它作为一个独立的扩展模块提供,下载地址为:https://drupal.org/project/automatic_updates。
- 该模块目前处于候选发布(RC)阶段,稳定版预计将很快发布。
- 在第一阶段中,自动更新模块包含通用服务警告(PSA)通知功能和更新准备检查,并可通过手动或 cron 执行站点内更新(in-place updates)。若更新涉及数据库更改,将自动回滚更新。
- 目前模块尚不支持 contrib 模块更新或基于 Composer 的安装。这些功能将在第二阶段(Phase 2)中实现。
自动更新模块的主要特性
公共安全公告(PSA)
Drupal 核心和扩展模块的安全更新公告(PSA)通常不会频繁发布。当发布 PSA 时,网站所有者应检查自己的网站,确认版本是否最新,并确保网站处于可快速更新的健康状态,以便在修复补丁发布后及时更新。
更新准备检查
并非所有网站在任何时候都可以直接更新。准备检查是一种自动检测方法,用于确定网站在新版本发布后是否已准备好执行自动更新。例如:尚未运行数据库更新、使用只读文件系统或磁盘空间不足的网站,将无法进行自动更新。如果您的网站未通过准备检查且 PSA 已发布,请务必先解决阻碍更新的核心问题,以确保网站可以顺利升级。
站点内更新
当 PSA 服务通知 Drupal 网站管理员有更新可用,并且准备检查确认网站已准备就绪时,自动更新服务即可执行更新操作。
特定网站(或代理机构、主机服务商)可以选择在数据库处理方面添加额外操作。例如,在更新前执行数据库备份并上传到 S3,或在更新完成后发送通知邮件。最后再执行数据库更新。
如果您开发自定义操作,请注意:任何依赖更新中可能被修改代码的操作,都必须通过命令行接口执行。否则会触发旧版本代码的执行,这是 PHP 的固有限制。例如,execute_updates 插件会通过 Symfony 控制台命令来处理此类情况。
安装
目前,Drupal 自动更新模块作为扩展模块发布在 Drupal.org 上。经过充分的社区测试后,它将被集成进 Drupal 核心。届时,您只需升级到包含该功能的 Drupal 版本即可使用。
要安装 contrib 版 Automatic Updates 模块,请遵循与其他 Drupal.org 模块相同的安装步骤:
- 重要:通过 tarball 下载模块。目前暂不支持通过 Composer 安装。
- 然后以您偏好的方式启用该模块。
当前此模块暂不适用于基于 Composer 的站点。假定网站是通过归档包方式安装和维护的。此外,目前仅支持更新 Drupal Core。后续版本将逐步支持基于 Composer 的 Drupal 安装。
模块使用方法
人工操作模式
PSA 功能会将来自 Drupal.org 的官方公告直接显示在 Drupal 管理界面中,提示用户即将发布的更新。
准备检查功能将定期运行,以确保网站不存在阻碍更新的问题。
在模块的配置页面,管理员可以手动触发站点内更新。
无人值守模式
若要启用自动更新,只需在模块配置页面中勾选通过 cron 执行更新的选项。更新将仅在网站通过准备检查后自动应用。
扩展自动更新功能
数据库更新可能较为复杂,不同网站所有者可能有不同的更新策略。Drupal 8 的自动更新模块使用插件架构来处理数据库更新,从而提供可扩展的系统。
默认配置为:将网站置于维护模式 → 执行数据库更新 → 退出维护模式。目前尚无用户界面用于修改此行为(计划后续添加)。处理顺序可通过 automatic_updates.settings.yml 中的 config 调整,或在 settings.php 中添加:
$config['automatic_updates.settings']['database_update_handling'] = ['rollback', 'alternative_plugin_id', 'yet_another_plugin'];
这是一个插件 ID 数组。
模块内置的可用插件包括:
- 'execute_updates'
- 'ignore_updates'
- 'maintenance_mode_activate'
- 'maintenance_mode_disactivate'
- 'rollback'
作为网站管理员或服务提供商,您可以编写额外的插件,例如自定义数据库备份插件,以扩展模块功能。
自动更新系统架构
核心特性
公共安全公告(PSA)
公共安全公告通过 Drupal.org 提供的 PSA.json 数据源生成,并通过 drupal_set_message()
显示在管理界面。
准备检查
准备检查系统是可插拔的,允许执行多种验证操作,并在 Drupal 管理界面中显示警告或错误。
站点内更新
站点内更新使用由 Drupal.org 生成的带签名的 “quasi-patches”(伪补丁)。这些补丁通过 libsodium PHP 库 验证(该库从 PHP 5.3 起可用)。验证通过后,系统使用 PHP 文件复制功能应用补丁,即覆盖更新中修改的文件。
测试功能
当前版本的 Automatic Updates 模块允许用户启用测试版 PSA JSON 通道,以便预览 PSA 通知的显示效果。
步骤如下:
1. 通过 Drupal 管理界面或命令行启用 automatic_updates_test 模块:
$ drush pm-enable automatic_updates_test
2. 设置变量以启用测试通道:
$ drush vset automatic_updates_psa_endpoint http://localhost/automatic_updates/test-json
如果您创建了自己的测试通道,可在命令中替换 URL。
恢复为官方 PSA 通道:
1. 执行命令:
$ drush vset automatic_updates_psa_endpoint https://updates.drupal.org/psa.json
2. 禁用 automatic_updates_test 模块:
$ drush pm-disable automatic_updates_test
Drupal.org 基础设施
Drupal 的自动更新功能依赖 Drupal.org 基础设施,并由 Drupal Association 提供支持与资金。
公共安全公告(PSA)通道
Drupal.org 提供 JSON 数据源以供自动更新模块使用。其主通道地址为:https://updates.drupal.org/psa.json;测试通道为:https://updates.drupal.org/psa-this-is-only-a-test.json,用于测试功能。
该通道包含当前所有有效 PSA 的列表,包括以下字段:
- title:公告标题。
- link:完整 PSA 页面 URL。
- project:目标项目名称。
- type:项目类型(核心、模块、主题、发行版等)。
- is_psa:标识该条信息是否为 PSA。
- insecure:当前不安全的项目版本列表。
- pubDate:PSA 发布日期。
例如,如果 Drupal 7 和 8 的 2019 年 5 月 8 日发布公告 PSA-2019-05-07 与 第三方漏洞公告 PSA-2019-09-04 包含在 psa.json 中,其格式如下:
[ { "title": "Drupal 7 and 8 release on May 8th, 2019 - PSA-2019-05-07", "insecure": ["4.7.0-beta3", "8.7.0-rc1", "8.7.0", "8.7.4"], "link": "https://www.drupal.org/psa-2019-05-07", "pubDate": "2019-09-20T22:09:16+00:00", "project": "drupal", "type": "core", "is_psa": "1" }, { "project": "securitydrupalorg", "pubDate": "2019-09-12T21:35:55+00:00", "is_psa": "1", "type": "module", "insecure": [], "title": "Various 3rd Party Vulnerabilities - PSA-2019-09-04", "link": "https://www.drupal.org/psa-2019-09-04" } ]
随后,自动更新模块会解析此通道,并在 Drupal 管理界面中显示结果。其他模块或服务也可使用该通道。
包生成
Drupal.org 的打包系统负责生成项目的 .tar.gz 和 .zip 下载包。在该过程中,它同时更新 Composer 元数据,并为自动更新系统生成 “quasi-patches” 补丁包。
包签名与安全
为确保 “quasi-patch” 包安全且可验证,Drupal.org 使用基于 BSD Signify 的签名架构。
Drupal 社区开发了 PHP 实现版本,托管在 https://github.com/drupal/php-signify。
该库通过对项目文件生成 SHA 哈希,并使用由 Drupal.org 基础设施 HSM 生成的公钥/私钥对进行签名,确保更新包的完整性与安全性。
反馈
若您想对自动更新模块的初始版本提供反馈,请在 Automatic Updates 问题队列中提交反馈或建议。