Как правильно удалить модуль в поэтапной среде?

17

Некоторые модули имеют процедуры деинсталляции. Которые обычно удаляют таблицы базы данных для этого модуля, переменные из таблицы переменных и локали, представленные этим модулем. Эти процедуры живут в этом .installмодуле.

Следовательно, они не могут быть запущены без присутствия этого модуля. Итак, вот наши текущие шаги. У меня вопрос: можно ли сделать это проще и эффективнее? Скажем, я удаляю модуль foo_bar.

  1. В RCS подготовьте новый выпуск, где:
    • Все переопределения css и theme, которые используют или строят поверх foo_bar, удаляются.
    • Все CSS и переопределения тем для модулей в зависимости от foo_bar удаляются.
  2. Нажмите этот релиз для принятия. Протестируйте деинсталляцию (от admin / modules) с самой последней копией производственной базы данных.
  3. Если все идет хорошо, разверните новую кодовую базу в производство и деинсталлируйте foo_bar и его зависимости там. Это вызовет деинсталляцию в различных модулях, очистку базы данных.
  4. В RCS (git) подготовьте новый выпуск, в котором код фактически удален.
  5. Разверните его для принятия, где мы тестируем, если от этого ничего не зависит случайно (некоторые уродливые модули или функции темы включают файлы непосредственно из других модулей. Наиболее значимыми являются CSS, JS или файлы изображений).
  6. Если принято, разверните новый выпуск в производство. У продукции теперь есть чистая база данных и чистая кодовая база .

Проблема, которую я не вижу, как решить, состоит в том, что это всегда требует двух выпусков. Так как в Drupal релиз требует, чтобы сайт был в автономном режиме, это означает два раза простоя только для удаления одного модуля. Это также требует двух процедур выпуска, которые в профессиональных средах хостинга могут быть очень дорогими, трудоемкими или разочаровывающими.

Если мы удалим модуль из кодовой базы в первой итерации, мы не сможем запустить ловушки удаления, сохраняя много ворса в базе данных; не только несколько таблиц, но в основном переменные и локали. Если мы не удаляем модуль из кодовой базы, это означает, что кодовая база будет расти с устаревшим, неиспользуемым кодом; это не приводит к снижению производительности, но усложняет поддержание кода.

Как вы справляетесь с этим?

[edit: добавлено примечание о том, что развертывание является сложной процедурой, часто]

Беркеш
источник
2
Если вы сначала выполните шаги 1 - 6 на промежуточном сервере, не могли бы вы затем обновить действующий сайт до HEAD ^, выполнить деинсталляцию, а затем обновить до HEAD (все за один присест)?
Энди
Если бы все мои проекты были развернуты git, то да. Но некоторым нужны тарболы для отправки по почте, в то время как другие используют (только!) Ftp и так далее. Но изучение git и некоторых скриптов git-hook, безусловно, очень интересная идея.
Беркес
Почему именно это нужно, чтобы закрыть сайт?
Летарион
@Letharion: 1) отключение сайта запрещает нежелательные записи в вашу базу данных во время процесса изменения этой базы данных; Drupal не использует транзакции. 2) Развертывание нового кода, который зависит от определенного состояния базы данных (тема, которая требует определенного поля cck, например), сломает ваш сайт во время между развертыванием кода и обновлением базы данных.
Беркес

Ответы:

7

Будьте очень осторожны с синхронизацией базы данных и кода; как вы упоминаете в своем вопросе, модули, которые нужно удалить, должны оставаться в базе кода, пока их ловушки удаления не будут запущены в действующей базе данных. Это ограничение Drupal, которое не может решить только рабочий процесс git pull.

Я бы порекомендовал вместо того, чтобы пытаться настроить свой процесс, вместо этого вы должны искать способы сократить время простоя, необходимое для обработки ваших обновлений. Я бы порекомендовал настроить многосайтовую промежуточную среду ying / yang для решения этой проблемы. nb Я не использовал скрипты, содержащиеся в предыдущей ссылке; Возможно, вы захотите настроить все по-другому, следуя той же идее, что вы можете поменять свои живые и сценические сайты во время развертывания.

Продолжайте следовать той же процедуре, которую вы изложили в своем вопросе, со следующими изменениями:

а. Синхронизируйте от dev до stage (yang) как обычно. Протестируйте, выполнив деинсталляцию удаляемых модулей с последующим удалением кода и т. Д. Git workflow notes: создайте тег или запишите хэш-код различных состояний вашего кода: все модули на месте перед удалением, модули кода удалены, ваш переопределяет & c. удалены и т. д. по мере необходимости. Возможно, нужны только две ссылки.

б. Когда тестирование завершено и принято, восстановите код на сцене (ян) в состояние live (ин).

с. Подготовьте действующий (ин) сайт к обновлению, отключив возможность любого пользователя изменять контент в системе. Обновление sql для таблицы разрешений обычно выполняется здесь. На этом этапе пользователи по-прежнему смогут читать контент на действующем сайте, но получат ошибку об отказе в разрешении, если они попытаются обновить контент. (Если вы крутой, возможно, вы могли бы изменить обработчик, которому отказано в разрешении, чтобы напечатать соответствующее уведомление о том, что функция временно недоступна).

д. Теперь переместите действующую (ying) базу данных обратно в базу данных stage (yang), исключая таблицу разрешений из обновления.

е. Повторите шаг а. опять таки. Если у вас есть удобные хэштеги, должно быть легко восстановить состояние, в котором существуют удаляемые модули, запустить перехватчики удаления в базе данных, а затем перейти обратно к состоянию кода, в котором ваши элементы из шага 1 объединены. обратно в.

е. Теперь вы готовы поменять инь и янь. Сделайте это, скорректировав свои директивы конфигурации Apache. Обратите внимание, что если вы сделаете /etc/init.d/apache restart, некоторые соединения могут быть сброшены, но /etc/init.d/apache reloadэто позволит выполнить чистый обмен.

грамм. Жить теперь "Ян"; таблица разрешений здесь не изменяется, поэтому пользователи могут создавать контент. Если вы автоматизируете шаги e. и е. время недоступно должно быть очень низким.

час Нажмите live (yang) обратно на сцену (ying), и код, и базу данных - или нажмите dev, если это необходимо. Теперь у вас есть чистая среда, готовая к следующей итерации.

greg_1_anderson
источник
Инь-янь ужасно терпит неудачу на шаге c. Работать будут только очень специфические сайты, такие как редакторские права - только для доступа. Это происходит главным образом потому, что не только комментарии, узлы и тому подобное должны быть отключены, но таблица сеансов, сторожевой таймер, счетчики и т. Д. Будут обновляться и записываться в них. Простои кажутся неудачным, но неизбежным побочным эффектом. Хотя, действительно, для определенных сайтов ying-yang - очень интересная концепция для развертывания.
Беркес
Конечно, вы правы; однако, если вы запишете последний шаг, окно простоя или потерянной информации будет низким. Если вы потеряете запись из таблицы сеансов, пользователю придется снова войти в систему. Счетчик может быть выключен немного. Вы можете пропустить уведомление или два в сторожевой таймер. Если это хуже, чем короткий период «этот сайт закрыт на техническое обслуживание», тогда непременно используйте более простое решение. Если вы действительно хотите, вы можете попытаться восстановить счетчик и сторожевые сообщения после обмена. Это может быть сложнее, чем оно того стоило, если информация + время работы ОЧЕНЬ ценно.
greg_1_anderson
Вы могли бы рассмотреть отслеживание транзакций на сайте перехода, используя двоичный журнал mysql. См. Dev.mysql.com/doc/refman/5.0/en/point-in-time-recovery.html . Я не хотел бы просто объединять вещи, но вы могли бы отслеживать дополнительные сообщения счетчика / сторожевого таймера вне группы. Самый простой способ справиться с таблицей сеансов - отключить вход в систему во время перехода.
greg_1_anderson
Ваш комментарий привел меня к возможному другому решению: объединить все hook_uninstall для модуля как hook_update_n () модуля специального назначения: uninstall.module. Таким образом, я могу удалить кодовую базу в первой итерации / и / получить намного более быструю деинсталляцию в реальном выпуске. Может быть, сценарий drush, который очищает эту информацию.
Беркес
1
Еще одна вещь, которая немного поможет. Измените весь свой пользовательский php-код так, чтобы любая ссылка на модуль, который будет удален, была включена if (module_exists('removeme')) { ... }. Разверните этот код. Если вы протестируете и подтвердите, что удаление модуля больше не нарушает ваш пользовательский код, это упростит ваше развертывание. По-прежнему целесообразно выполнить шаг отключения на сайте, который не является активным, но, возможно, это немного сузит ваше окно. Я не думаю, что ваш пользовательский хук обновления сделает безопасным отключение живого модуля.
greg_1_anderson