Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my Erlang boot script work from console but does not work when run from init system (sysvinit, upstart, systemd)?

I have an Erlang boot script that I can launch like this:

/usr/bin/erl -boot /path/to/my-boot-script

It works when run from console, but fails without any error messages when I run it from systemd. The systemd unit file looks like this:

[Unit]
Description=My daemon written in Erlang

[Service]
Type=simple
ExecStart=/usr/bin/erl -boot /path/to/my-boot-script
Restart=always

[Install]
WantedBy=multi-user.target

The log shows that the system boots properly and then terminates abruptly without any kind of error message. What the hell is going on?

like image 985
Shnatsel Avatar asked Jun 03 '16 20:06

Shnatsel


2 Answers

Turns out that you have to pass -noinput parameter to erl. Otherwise it will try to open stdin for reading, fail because there's nothing there and terminate without any kind of error message.

This works:

[Unit]
Description=My daemon written in Erlang

[Service]
Type=simple
ExecStart=/usr/bin/erl -noinput -boot /path/to/my-boot-script
Restart=always

[Install]
WantedBy=multi-user.target
like image 121
Shnatsel Avatar answered Sep 24 '22 16:09

Shnatsel


I have just managed to use the erlang install system with systemd to install a code repository. This procedure is compliant with the erlang documenation about setting up embedded systems. Here is what I learnt:

1) Need to add a path to get to the install tools in erts/examples. Here is an excerpt from my .erlang file for this:

code:add_path(filename:join([os:getenv("ROOTDIR"),"lib/sasl-2.6/examples/ebin"])).

2) do the build as in erlang/doc/system_principles/create_target.html

target_system:create("mysystem").

3) extract the build into a temporary location. For my application it done from erlang with:

target_system:install("code_repository", "/home/tony/Projects/code_repository/release_test").

4) edit the last line of start where it starts run erl and remove the -daemon option and add any erlang runtime parameters required like -sname or -set_cookie. This is outlined in erlang/doc/embedded/embedded_solaris.html#idm45326372314928. Here is the edited line from my system:

$ROOTDIR/bin/run_erl  /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -sname code_repository" 

5) Install to runtime location (don't forget about sys.config)
6) Set up .services file as follows. This file is stored in /etc/systemd/system/code_repository.service:

[Unit]
Description=Tonys Code Repository Daemon

[Service]
Type=simple
WorkingDirectory=/var/opt/code_repository
Environment=HOME=/var/opt/code_repository
ExecStart=/var/opt/code_repository/bin/start
Restart=yes

[Install]
WantedBy=multi-user.target

The removal of the -daemon flag is essential to operate as simple service, as simple services run and do not return unless they fail. The use of run_erl as in this procedure allows erlang tools to attach to the daemon for maintenance..

like image 40
tony wallace Avatar answered Sep 24 '22 16:09

tony wallace