#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
будет использоваться сценарий загрузки.