如何在分阶段环境中正确删除模块?


17

一些模块具有取消安装例程。通常会删除该模块的数据库表,变量表中的变量以及该模块引入的语言环境。这些例程位于该.install模块的中。

因此,如果没有该模块,则无法运行它们。所以这是我们当前的步骤。我的问题是:这可以更简单,更有效地完成吗?说我删除foo_bar模块。

  1. 在RCS中,准备一个新版本,其中:
    • 删除了在foo_bar之上使用或构建的所有css和主题覆盖。
    • 取决于foo_bar的模块的所有css和theme-overrides均被删除。
  2. 将该发布推送到接受状态。(使用admin / modules)使用生产数据库的最新副本测试取消安装。
  3. 如果一切顺利,则将新的代码库部署到生产环境中,然后在其中释放foo_bar及其依赖项。这将在各个模块中调用卸载,以清理数据库。
  4. 在RCS(git)中,准备一个新发行版,其中的代码实际上已被删除。
  5. 将其部署到接受测试的地方,以便我们测试是否意外地依赖于此(一些丑陋的模块或主题功能直接包含来自其他模块的文件。最著名的是CSS,JS或图像文件)。
  6. 如果接受,则将新版本部署到生产中。生产现在有一个干净的数据库和一个干净的代码库

我看不到如何解决的问题是,这总是需要两个版本。由于在Drupal中,一个发行版要求站点处于离线状态,这意味着两次停机仅删除一个模块。它还需要两个发布过程,在专业托管环境中,这可能是非常昂贵,费时或令人沮丧的。

如果在第一次迭代中从代码库中删除模块,则无法运行卸载钩子,从而在数据库中保留了很多皮棉;不仅是几个表,而且大多数是变量和语言环境。如果我们不从代码库中删除模块,这意味着代码库将随着陈旧的未使用代码一起增长;这不会产生性能开销,但是会使维护代码越来越难。

您如何处理?

[编辑:经常添加关于部署过程很困难的说明]


2
如果您首先在登台服务器上执行步骤1-6,您是否不能将实时站点更新为HEAD ^,卸载后再更新为HEAD(一次就座)?
安迪

如果我所有的项目都是git部署的,那么可以。但是有些需要使用tarball邮寄,而有些则使用(仅!)ftp等。但是研究git和一些git-hook-scripts当然是一个非常有趣的想法。
berkes 2012年

为什么确切要求拆除该站点?
Letharion

@Letharion:1)关闭站点,以防止在更改数据库的过程中对数据库进行不必要的写入;Drupal不使用事务。2)部署依赖于某些数据库状态(例如,需要特定cck字段的主题)的新代码将在推出代码和更新数据库之间的时间中断您的站点。
berkes 2012年

Answers:


7

在保持数据库和代码同步方面要非常小心;正如您在问题中提到的,要卸载的模块需要保留在代码库中,直到它们的卸载挂钩在实时数据库上运行。这是Drupal的局限性,仅靠git pull工作流程是无法解决的。

我建议您不要尝试调整流程,而应该寻找减少处理更新所需停机时间的方法。我建议设置ying / yang多站点暂存环境以解决此问题。我没有使用前面链接中包含的脚本;您可能希望按照与在部署期间可以交换直播站点和登台站点的相同想法进行不同的设置。

继续按照您在问题中概述的相同步骤进行以下调整:

一种。像往常一样,从开发人员同步到阶段(yang)。通过卸载要删除的模块,然后删除代码等进行测试。Git工作流程注释:创建标签或注释代码不同状态的哈希值:卸载前所有模块就位,代码模块已删除,您的覆盖&c。根据需要删除等。也许只需要两个参考。

b。测试完成并被接受后,将舞台(阳)上的代码恢复为活动(莹)状态。

C。通过禁止任何用户更改系统上的内容的能力来准备实时(应收)网站以进行更新。权限表的sql更新通常将在此处执行。此时,用户仍然可以在实时站点上阅读内容,但是如果他们尝试更新内容,则会收到权限被拒绝的错误。(如果您很酷,也许可以更改权限拒绝处理程序,以打印相应的通知,告知该功能暂时不可用)。

d。现在,将活动(ying)数据库推回舞台(yang)数据库,从更新中排除权限表。

e。重复步骤a。再次。如果方便使用#标签,则应该很容易地恢复到要删除的模块存在的状态,在数据库上运行卸载钩子,然后前进到代码状态,其中合并了步骤1中的项目早在。

F。现在您可以交换阴和阳了。通过调整Apache配置指令来执行此操作。请注意,如果您执行/etc/init.d/apache restart,则可能会删除某些连接,但/etc/init.d/apache reload允许进行干净交换。

G。现在的生活是“阳”;权限表在此处未修改,因此用户可以创建内容。如果自动执行步骤e。f。无法使用的时间应该非常短。

H。将实时代码和数据库推回阶段(ying)–或根据需要从开发者推入。现在,您已经为下一次迭代准备了一个干净的环境。


颖阳在步骤c上严重失败。只有非常特定的网站(例如仅限编辑驱动的匿名访问)才可以使用。这主要是因为不仅必须禁用注释,节点等,而且还将更新会话表,看门狗,计数器等并将其写入。停机似乎是不幸的,但却是不可避免的副作用。但是,实际上,对于某些站点,部署部署时应使用“ ying-yang”这个非常有趣的概念。
berkes 2012年

你当然是对的。但是,如果您编写最后一步的脚本,则停机时间或丢失信息的时间将很短。如果您丢失了会话表中的条目,则用户将不得不再次登录。计数器可能会关闭一点。您可能会错过一个或两个看门狗通知。如果这比短暂的“该站点已停止维护”情况还差,那么请务必使用更简单的解决方案。如果确实需要,可以尝试在交换后恢复计数器和看门狗消息。除非信息+正常运行时间非常有价值,否则这可能比其价值还要复杂。
greg_1_anderson

您可能考虑使用mysql二进制日志跟踪过渡站点上的事务。参见dev.mysql.com/doc/refman/5.0/en/point-in-time-recovery.html。我不愿意将事情合并在一起,但是您可以跟踪带外的其他计数器/看门狗消息。处理会话表的最简单方法是在过渡期间也禁用登录。
greg_1_anderson

您的评论使我想到了另一个可能的解决方案:将模块的所有hook_uninstall汇总为专用模块(uninstalled.module)的hook_update_n()。这样,我可以在第一次迭代中删除代码库,并且//可以在实际发行版中更快地取消安装。可能是提取此信息的草稿脚本。
berkes 2012年

1
还有一点会有所帮助。更改所有自定义php代码,以使对要删除的模块的任何引用都包含在中if (module_exists('removeme')) { ... }。部署该代码。如果您测试并确认删除模块不再破坏您的自定义代码,则将简化您的部署。仍然建议在非活动站点上执行禁用步骤,但这可能会稍微缩小您的窗口。我认为您的自定义更新挂钩不会使实时模块禁用更加安全。
greg_1_anderson 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.