Выполнение «автономного» обновления версии erlang OTP

#erlang #erlang-otp

#erlang #erlang-otp

Вопрос:

Я работаю над проектом, который в значительной степени связан с выпусками OTP и процессом их обновления. Мне удалось выполнить горячие обновления из архива обновления выпуска (tar.gz ) с использованием функций release_handler unpack_release, install_release и make_permanent. Все они вызываются в том самом узле, который обновляется.

Теперь мне приходится иметь дело с ситуацией, когда узел erlang не работает, и я должен выполнить «автономное» обновление. По сути, я хочу распаковать release и обновить определенные файлы, такие как RELEASES и start_erl.data (может быть, еще некоторые?), Чтобы они находились в том же состоянии, что и после горячего обновления. Результатом будет то, что при запуске узла загружается недавно установленная версия erlang. Кроме того, важно то, что я хочу избежать запуска старой версии.

Есть идеи, как сделать это как можно проще и понятнее?

Комментарии:

1. отключение узла — отличный шанс развернуть код с нуля. Что насчет этого? Оставьте Mnesia dir и т.д., Но замените всю структуру сборки / выпуска. Что вы думаете об этом?

2. Да, создание всей структуры с нуля является жизнеспособным решением, но с этим есть одна проблема: мне придется повторно создать RELEASES файл, а функция, ответственная за это ( release_handler:create_RELEASES ), перечисляет только один данный выпуск, и она полностью забывает о старых выпусках. Я хотел бы избежать этой потери информации, потому что я хочу использовать ее для удаления старых выпусков с помощью release_handler . Или, может быть, вы думаете, что я тоже должен попытаться выполнить очистку вручную?

3. да, давайте подумаем .. реальное преимущество, которое вы получаете от всей информации в выпусках, — это возможность отката. Автономный узел — он будет первым с новым кодом или последним? Кроме того, как вы подключаете узлы? Можете ли вы установить его и не присоединяться к кластеру?

4. Ну, система на самом деле не распространяется. Все, о чем я писал, касается одной целевой системы erlang, которую я назвал «узлом», потому что это «встроенный узел», поскольку его генерирует rebar ( rebar create-node ).

Ответ №1:

Запустите узел erlang, чтобы получить оболочку. Имя узла не требуется, просто убедитесь, что вы используете то же самое ~/bin/erl , что и целевой узел. Затем поместите свой пакет выпуска в ~/lib/erlang/releases и распакуйте, как обычно:

 1> application:start(sasl),
1> release_handler:unpack_release("my_release-1.0").
{ok, "1.0"}.
  

Теперь завершите работу, закрыв оболочку:

 2> q().
  

[Не пытайтесь обмануть, используя другое окно здесь! Вы должны выйти.]

Теперь вам нужно отредактировать ~/lib/erlang/releases/RELEASES файл и изменить статус новой версии с unpacked на current :

 [{release,"My Release Package","1.0","5.9.1",
       [{kernel,"2.15.1","/Users/otpuser/lib/erlang/lib/kernel-2.15.1"},
        {stdlib,"1.18.1","/Users/otpuser/lib/erlang/lib/stdlib-1.18.1"},
        {sasl,"2.2.1","/Users/otpuser/lib/erlang/lib/sasl-2.2.1"}, ...],
-     unpacked}].
      current}].
  

Запустите оболочку снова и сделайте ее постоянной:

 1> application:start(sasl),
1> release_handler:make_permanent("1.0").
ok
  

[Примечание: все, что make_permanent/1 нужно сделать, это вставить версию выпуска ( "1.0" ) в ~/lib/erlang/releases/start_erl.data , чтобы вы могли здесь жульничать.]

Обязательно поместите конфигурацию вашей системы в ~/lib/erlang/releases/1.0/sys.config .

Теперь при запуске ~/bin/start название версии будет считываться из start_erl.data и init в ~/lib/erlang/releases/1.0/start.boot будет использоваться сценарий загрузки.