Problem starting hypnotoad with systemd script

639 views
Skip to first unread message

Nacho B

unread,
Apr 13, 2015, 7:38:59 AM4/13/15
to mojol...@googlegroups.com
Hello:

I am already in the pre-production stage for a Mojolicious app, so I want to integrate it with systemd in CentOS 7, following the example at https://github.com/kraih/mojo/wiki/Integrating-hypnotoad-with-systemd-and-rsyslog

- My server has two users: developer and tester, for the obvious roles of developing, and local testing, before going to online staging and production.
- The user tester environment is similar to the future online environment
- Each user has it own PerlBrew, with Perl 20

THE PROBLEM:
It works PERFECTLY in the tester environment if I start the app using $hypnotoad scripts/my_app
But it doesn’t work using the systemd script.


MY ASSUMPTIONS:
1.- I execute the script as root
- It will be used in the startup or in a Monit script
- So I need to test it logged as root or with sudo

2.- The service must be executed as the user tester
- I added the line User=tester to the script

3.- The hypnotoad path for ExecStart, ExecStop and ExecReload is different because of PerlBrew, so I edited the script
- Now it is at /home/tester/perl5/perlbrew/perls/perl-5.20.1/bin/hypnotoad


THE RESULTS:
- If I write an absolute path por the app (/home/tester/path-to-the-app), Mojolicious itself complains about it cant’t found it in @INC

- If I write $HOME/path-to-the-app-from-the-user-directory the script runs “fine", even it says that a .pid has been created, BUT it is not true!!!! In the log says that the app exited, and that .pid number does not exists in the running processes list in the server.


Any suggestions? I do not know if something in some log or in the app code can help to understand my problem or if some of my assumptions are wrong


[Some side notes about my developer setup before going online: everything is local: files are copied between developer and tester using Git; the app runs behind a Niginx server; css, jss and templates are served by Nginx; it resolves to a intranet .foo domain configured locally in BIND in a virtual CentOS 7 installed in Parallels for Mac; it uses Mojo::Pg with also a local database] -----> and it all works starting hypnotoad with the command line!! so I think that all hard work is already well done.

Thank you:
Nacho B.

Nacho B

unread,
Apr 13, 2015, 8:08:56 AM4/13/15
to mojol...@googlegroups.com
From the systemd guide at https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/chap-Managing_Services_with_systemd.html I have just read that:

System services do not inherit any context (such as the HOME and PATH environment variables) from the invoking user and their session. Each service runs in a clean execution context.

So my tryout using $HOME is wrong. An absolute path must be used.

But if "each service runs in a clean execution context", how can it use the PerlBrew Perl and find hypnotoad and mojolicious itself?  

Nacho B.


Tekki

unread,
Apr 13, 2015, 9:35:44 AM4/13/15
to mojol...@googlegroups.com
Did you remember to set PERLBREW_ROOT and PERLBREW_HOME and call $PERLBREW_ROOT/perl5/perlbrew/etc/bashrc before you start the application? See here: http://perlbrew.pl/Perlbrew-In-Shell-Scripts.html

Nacho B

unread,
Apr 13, 2015, 12:50:16 PM4/13/15
to mojol...@googlegroups.com
Hi, Tekki:

The system scripts are not shell scripts, so I don't know how to set the variables…

The error log  from syslog says:
Apr 13 18:28:17 foo tiendas_admin: Can't load application from file "/media/psf/w/tiendas/tiendas_admin/script/tiendas_admin": Can't find application class "TiendasAdmin" in @INC. (lib /home/tester/perl5/perlbrew/perls/perl-5.20.1/lib/site_perl/5.20.1/x86_64-linux /home/tester/perl5/perlbrew/perls/perl-5.20.1/lib/site_perl/5.20.1 /home/tester/perl5/perlbrew/perls/perl-5.20.1/lib/5.20.1/x86_64-linux /home/tester/perl5/perlbrew/perls/perl-5.20.1/lib/5.20.1 .)

If I run hypnotoad from the user tester shell, everything runs fine, because those variables are activated when the shell is opened. But how can I do that from user root or when rebooting the system if I am nor executing a bash script?

Thanks:
Nacho B.

Dotan Dimet

unread,
Apr 13, 2015, 1:05:33 PM4/13/15
to mojol...@googlegroups.com
The documentation you linked to mentions an EnvironmentFile variable you can declare in your unit file, saying: "EnvironmentFile points to the location where environment variables for the service are
defined".
Also, there's an example of an "emacs service" which uses a variable called Environment, where you can declare env vars inline.

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sect-Managing_Services_with_systemd-Unit_Files.html

Maybe that can help
--
You received this message because you are subscribed to the Google Groups "Mojolicious" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mojolicious...@googlegroups.com.
To post to this group, send email to mojol...@googlegroups.com.
Visit this group at http://groups.google.com/group/mojolicious.
For more options, visit https://groups.google.com/d/optout.


--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

Tekki

unread,
Apr 14, 2015, 6:03:55 AM4/14/15
to mojol...@googlegroups.com
Obviously not the path to 5.20, but the path to your application (TiendasAdmin.pm) is missing. Try to hard-code it in the startup script. Instead of
use lib "$FindBin::Bin/../lib";
write
use lib "/media/psf/w/tiendas/tiendas_admin/lib";
(I just guess the content of your script and the path.)
If it works define it as an environment variable as it's described in the Redhat link you posted above.

Nacho B

unread,
Apr 14, 2015, 12:47:07 PM4/14/15
to mojol...@googlegroups.com
Thank you!, Tekki,

In the Mojolicious script I have hardcoded the lib path and it works!

The only drawback for now is that the relative paths used inside the App now must be absolute. For example the path lo load the migrations.sql file.

Maybe I can define multiple places for Mojolicious to search, as I used to do with Catalyst and Template Toolkit. If a file isn´t in the main place, it searches in other place, like cascading, or something like this.

Regards:
Nacho B.

Paul Durden

unread,
Apr 14, 2015, 1:19:47 PM4/14/15
to mojol...@googlegroups.com
I stopped using FindBin a few years back after I was bitten by one of its issues.
Instead, I use the following block in my perl scripts (not modules) that I borrowed from some blog or article that I cannot recall...

## Cannot use Find::Bin because script may be invoked as an
## argument to another script, so instead we use __FILE__
use File::Basename qw(dirname fileparse basename);
use File::Spec;
## Add script directory
use lib join('/', File::Spec->splitdir(dirname(__FILE__)));
## Add script directory/lib
use lib join('/', File::Spec->splitdir(dirname(__FILE__)), 'lib');
## Add script directory/../lib
use lib join('/', File::Spec->splitdir(dirname(__FILE__)), '..', 'lib');


This has worked great for me in Linux and Windows.

You might be able to use similar technique to locate your migration files as long as you know their path relative to your main script.

Hope this helps.


--
Reply all
Reply to author
Forward
0 new messages