Erlang, rebar3 и установка сервиса под Windows

    Как заставить Erlang релиз работать как сервис под Windows. Оставим за кадром вопрос зачем это делать. Просто иногда это нужно. Так что сосредоточимся на КАК. Что-бы было еще сложнее поставим себе задачу делать это с помощью wixtoolset.


    Эта заметка некая шпаргалка самому себе. Хотя я очень надеюсь что никогда не пригодится. Поехали.


    Представим себе что файлы мы как-то поставили и ран-тайм с собой принесли. Запуск апликации в виде консоли срабатывает и теперь надо оформить запуск приложения в виде сервиса. Если есть проблемы уже на этом этапе — пишите мне, я там как-раз топтался.


    Итак, Тут нас ждут несколько веселых подводных камней. Мы как-бы можем запустить скрипт ИМЯ-АПЛИКАЦИИ.cmd install. И это даже сработает. Но есть 2 недостатка — вскакивает черный экран и сервис не удаляется при удалении апликации.


    Так что перейдем к тому чего будет нехватать:


    1) Файл erl.ini в директории erts-НОМЕР\bin. Его содержимое после установки содержит пути машины где релиз собирали. Его содержимое надо менять. И в путях надо ставить двойные слеши.
    2) Запускается сервис с помощью файла erlsrv.exe. Это часть рантайма, тут все хорошо. Надо не забыть взять его с собой.
    3) erlsrv.exe расчитывает найти файл start.boot по адресу releases\VERSION. А его там нет. И надо скопировать его


    <DirectoryRef Id="_VERSION">
            <Component Id="CopyBootFile" Guid="{GUID}">
                <CopyFile Id="start.boot" FileId="APPNAME.boot" 
                            DestinationDirectory="_VERSION" 
                            DestinationName="start.boot" />
            </Component>
    </DirectoryRef>

    4) erlsrv.exe хранит параметры сервиса в регистре. И их надо дописать самим.


    Теперь примеры


    Например нашу чудо апликацию зовут erlang_service. Пишем в регистр:


    <RegistryKey Root="HKLM"
                    Key="Software\Ericsson\Erlang\ErlSrv\1.1\erlang_service" >
                    <RegistryValue Type="expandable" Name="Args" Value="-setcookie MY_COOKIE ++ -rootdir &quot;[ProgramFiles64Folder]ErlangService&quot;" />
                    <RegistryValue Type="string" Name="Comment" Value="Erlang node service" />
                    <RegistryValue Type="integer" Name="DebugType" Value="0" />
                    <RegistryValue Type="multiString" Name="Env" Value="" />
                    <RegistryValue Type="string" Name="InternalServiceName" Value="erlang_service" />
                    <RegistryValue Type="expandable" Name="Machine" Value="[ROOT]erts-9.2\bin\start_erl.exe" />
                    <RegistryValue Type="string" Name="Name" Value="" />
                    <RegistryValue Type="integer" Name="OnFail" Value="0" />
                    <RegistryValue Type="integer" Name="Priority" Value="32" />
                    <RegistryValue Type="string" Name="SName" Value="erlang_service" />
                    <RegistryValue Type="string" Name="StopAction" Value="init:stop()." />
                    <RegistryValue Type="expandable" Name="WorkDir" Value="[ROOT]" />
                </RegistryKey>

    Тут у нас так:


    --rootdir — место где установлена апликация. Именно так. Если взять например [ROOT] — id самой директории, то ничего не будет работать, так как в конце будет слеш. А оно его сбивает с толку.
    InternalServiceName Value="erlang_service" — под таким именем будем ставить сервис.
    SName — это erlang short name
    [ROOT] — ID директории в которой лежат наши файлы.


    ну и сам сервис:


    <ServiceInstall Id="ErlangService" Type="ownProcess" Vital="yes"
        Start="auto" Account="LocalSystem" ErrorControl="normal" Name="erlang_service"
        DisplayName="ErlangService" Description="erlang_service-[ProductVersion]"
        Interactive="no"  >
        <ServiceDependency Id="LanmanWorkstation" />
    
        <util:ServiceConfig
            FirstFailureActionType="restart"
            SecondFailureActionType="restart"
            ThirdFailureActionType="none"
            ResetPeriodInDays="1"/>
    
    </ServiceInstall>
    
    <ServiceControl Id="ErlangServiceControl" Start="install"
        Stop="uninstall" Remove="uninstall" Name="erlang_service" Wait="yes" />

    В результате имеем сервис который автоматически ставится, останавливается и корректно удаляется.


    Все.

    Поделиться публикацией

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

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

    Самое читаемое