Comment supprimer correctement un module dans un environnement intermédiaire?

17

Certains modules ont des routines de désinstallation. Ce qui supprime généralement les tables de données pour ce module, les variables de la table de variables et les paramètres régionaux introduits par ce module. Ces routines vivent dans le .installde ce module.

Par conséquent, ils ne peuvent pas être exécutés sans que ce module soit présent. Voici donc nos étapes actuelles. Ma question est: cela peut-il être fait plus simplement et plus efficacement? Dis que je supprime le module foo_bar.

  1. Dans le RCS, préparez une nouvelle version, où:
    • Tous les CSS et les substitutions de thème qui utilisent ou construisent au-dessus de -foo_bar sont supprimés.
    • Tous les css et les substitutions de thème pour les modules en fonction de foo_bar sont supprimés.
  2. Poussez cette version à l'acceptation. Testez la désinstallation (depuis admin / modules) avec une copie très récente de la base de données de production.
  3. Si tout se passe bien, déployez la nouvelle base de code en production et installez foo_bar et ses dépendances là-bas. Cela invoquera la désinstallation dans les différents modules, nettoyant la base de données.
  4. Dans le RCS (git), préparez une nouvelle version où le code est réellement supprimé.
  5. Déployez cela à l'acceptation où nous testons si rien ne dépend accidentellement de cela (certains modules laids ou fonctions de thème incluent des fichiers directement à partir d'autres modules. Notamment CSS, JS ou fichiers image).
  6. Si elle est acceptée, déployez la nouvelle version en production. la production a maintenant une base de données propre et une base de code propre .

Le problème que je ne vois pas comment résoudre, c'est que cela nécessite toujours deux versions. Étant donné que dans Drupal, une version nécessite que le site soit hors ligne, cela signifie deux fois un temps d'arrêt uniquement pour supprimer un module. Cela nécessite également deux procédures de publication qui, dans les environnements d'hébergement professionnels, peuvent être très coûteuses, longues ou frustrantes.

Si nous supprimons le module de la base de code lors de la première itération, nous ne pouvons pas exécuter les hooks de désinstallation, en conservant de nombreuses peluches dans la base de données; pas seulement quelques tableaux, mais surtout des variables et des locales. Si nous ne supprimons pas le module de la base de code, cela signifie que la base de code augmentera avec du code périmé et inutilisé; cela n'entraîne aucune surcharge de performances, mais rend la maintenance du code de plus en plus difficile.

Comment gérez-vous cela?

[modifier: ajout d'une note sur le déploiement étant une procédure difficile, souvent]

berkes
la source
2
Si vous effectuez d'abord les étapes 1 à 6 sur un serveur de transfert, ne pourriez-vous pas ensuite mettre à jour le site en direct vers HEAD ^, effectuer les désinstallations, puis mettre à jour vers HEAD (le tout en une seule séance)?
Andy
Si tous mes projets ont été déployés avec git, alors oui. Mais certains ont besoin de tarballs pour être postés, tandis que d'autres utilisent (seulement!) Ftp et ainsi de suite. Mais regarder git et certains scripts git-hook est certainement une idée très intéressante.
berkes
Pourquoi faut-il exactement supprimer le site?
Letharion
@Letharion: 1) La suppression du site interdit les écritures indésirables dans votre base de données pendant le processus de modification de cette base de données; Drupal n'utilise pas de transactions. 2) Le déploiement d'un nouveau code qui dépend d'un certain état de la base de données (un thème qui nécessite un certain champ cck, par exemple) interrompra votre site entre le déploiement du code et la mise à jour de la base de données.
berkes

Réponses:

7

Faites très attention à ne pas synchroniser votre base de données et votre code; comme vous le mentionnez dans votre question, les modules à désinstaller doivent rester dans la base de code jusqu'à ce que leurs hooks de désinstallation soient exécutés sur la base de données en direct. C'est une limitation de Drupal qu'un seul workflow git pull ne résoudra pas à lui seul.

Je recommanderais qu'au lieu d'essayer d'ajuster votre processus, vous cherchiez plutôt des moyens de réduire le temps d'arrêt requis pour traiter vos mises à jour. Je recommanderais de configurer un environnement de transfert multisite ying / yang pour résoudre ce problème. nb Je n'ai pas utilisé les scripts contenus dans le lien précédent; vous souhaiterez peut-être configurer les choses différemment, en suivant la même idée que vous pouvez échanger vos sites en direct et sur scène pendant le déploiement.

Continuez à suivre la même procédure que celle décrite dans votre question avec les ajustements suivants:

une. Synchronisez de dev à stage (yang) comme d'habitude. Testez en faisant une désinstallation des modules à supprimer suivie d'une suppression de code, etc. remplace et c. retiré, etc. au besoin. Peut-être que seulement deux références sont nécessaires.

b. Une fois les tests terminés et acceptés, restaurez le code sur scène (yang) à l'état en direct (ying).

c. Préparez le site en direct (ying) pour la mise à jour en désactivant la capacité de tout utilisateur à modifier le contenu du système. Une mise à jour SQL de la table d'autorisation se fera généralement ici. À ce stade, les utilisateurs pourront toujours lire le contenu sur le site en direct, mais obtiendront une erreur d'autorisation refusée s'ils tentent de mettre à jour le contenu. (Si vous êtes cool, vous pouvez peut-être modifier le gestionnaire d'autorisation refusée pour imprimer un avis approprié indiquant que la fonction est temporairement indisponible).

ré. Poussez maintenant la base de données live (ying) vers la base de données stage (yang), à l'exclusion de la table des autorisations de la mise à jour.

e. Répétez l'étape a. encore. Si vous avez vos hashtags à portée de main, il devrait être facile de restaurer l'état dans lequel les modules à supprimer existent, d'exécuter les hooks de désinstallation sur la base de données, puis de revenir à l'état du code où vos éléments de l'étape 1 sont fusionnés de retour.

F. Vous êtes maintenant prêt à échanger le ying et le yang. Pour ce faire, ajustez vos directives de configuration Apache. Notez que si vous effectuez une /etc/init.d/apache restart, certaines connexions peuvent être supprimées, mais /etc/init.d/apache reloadpermettront un échange propre.

g. Live est maintenant «yang»; la table des autorisations n'est pas modifiée ici, afin que les utilisateurs puissent créer du contenu. Si vous automatisez les étapes e. et f., le temps indisponible doit être très faible.

h. Repoussez live (yang) sur scène (ying), à la fois le code et la base de données - ou poussez à partir du développeur, si nécessaire. Vous avez maintenant un environnement propre prêt pour votre prochaine itération.

greg_1_anderson
la source
Ying-yang échoue horriblement à l'étape c. Seuls les sites très spécifiques, tels que éditorial-anon-access-only fonctionneront. C'est principalement parce que non seulement les commentaires, les nœuds et autres doivent être désactivés, mais la table de session, le chien de garde, les compteurs, etc. seront mis à jour et écrits. Les temps d'arrêt semblent un effet secondaire malheureux, mais incontournable. Bien que, en effet, pour certains sites, le ying-yang soit un concept très intéressant à utiliser lors du déploiement.
berkes
Bien sûr, tu as raison; cependant, si vous scriptez l'étape finale, la fenêtre d'indisponibilité ou d'informations perdues sera faible. Si vous perdez une entrée de la table de session, l'utilisateur devra se reconnecter. Un compteur pourrait être un peu décalé. Vous pourriez manquer une notification ou deux dans le chien de garde. Si c'est pire qu'une courte période de «ce site est en panne pour maintenance», alors utilisez la solution la plus simple. Si vous le vouliez vraiment , vous pourriez essayer de récupérer les messages du compteur et du chien de garde après l'échange. Cela pourrait être plus compliqué que cela ne valait, sauf si info + disponibilité TRÈS précieuse.
greg_1_anderson
Vous pourriez envisager de suivre les transactions sur le site de transition à l'aide du journal binaire mysql. Voir dev.mysql.com/doc/refman/5.0/en/point-in-time-recovery.html . Je serais réticent à fusionner les choses ensemble, mais vous pourriez garder une trace des messages supplémentaires de compteur / chien de garde hors bande. La manière la plus simple de gérer la table de session serait également de désactiver les connexions pendant la transition.
greg_1_anderson
Votre commentaire m'a amené à une autre solution possible: agréger tous les hook_uninstall pour un module en tant que hook_update_n () s d'un module spécial: uninstall.module. De cette façon, je peux supprimer la base de code lors de la première itération / et / obtenir une désinstallation beaucoup plus rapide dans la version actuelle. Il pourrait s'agir d'un drush-script qui gratte ces informations.
berkes
1
Encore une chose qui vous aidera un peu. Modifiez tout votre code php personnalisé de sorte que toute référence au module à supprimer soit encapsulée if (module_exists('removeme')) { ... }. Déployez ce code. Si vous testez et confirmez que la suppression du module ne rompt plus votre code personnalisé, cela simplifiera votre déploiement. Il est toujours conseillé de faire l'étape de désactivation sur un site qui n'est pas en ligne, mais cela réduira peut-être légèrement votre fenêtre. Je ne pense pas que votre crochet de mise à jour personnalisé rendra plus sûr la désactivation d'un module en direct.
greg_1_anderson