Difference between starting a command using init.d script and service start - linux

I need to understand the difference between starting a command using init.d script and service start.
For example what is the difference between
/etc/init.d/nginx start and service nginx start.

They do the same thing except service runs the script in a controlled environment. From the service(8) man page:
DESCRIPTION
service runs a System V init script in as predictable environment
as possible, removing most environment variables and with current
working directory set to /.
ENVIRONMENT
LANG, TERM
The only environment variables passed to the init scripts.

Furthermore:
Calling /etc/init.d/* scripts directly is deprecated by facts because:
On latest Debian/Ubuntu distro ( and derived ), sysvinit ( which was default init system ) has been replaced by either upstart or systemd. Thus, if one of the service is managed using either an usptart job or systemd unit configuration file, calling /etc/init.d/* will be a NOOP in sense that the script will exit without further information.
Instead, users must use the service command to start/stop/restart services. The service command is a wrapper which will invoke the right script, in as predictable environment as possible, whatever the init system in use ( sysinit, upstart or systemd ).

Related

What should I use from init and systemd to create daemon for my service?

What should be used from init and systemd to create daemon for a service. Heard that init is been removed from linux distributions.
At a minimum, you don't need to change your program. You just need to write a .service file which describes how your daemon works. What's the command line to start it, how do you stop it, etcetera.
You can create a tighter integration, but the .service file remains the first step.

How to trigger a custom script to run whenever a specific systemd service restarts

I wish to know how can I schedule a custom script to run whenever I restart a service.
My use case is that I have to run several commands whenever I restart my Tomcat Service. I want to know if there is a way I can write a script and schedule it to run whenever I restart the Tomcat service.
I have setup the tomcat script as a systemd service. I am using Cent OS 7 x64.
I have been able to achieve this by creating another service and incorporating the Tomcat service's start stop in the new service. The new service acts as a wrapper service which first starts tomcat and then executes the commands that we need to run as soon as tomcat starts.
Then while stopping, it stops tomcat and runs clean up commands.
EDIT: I found another way of doing this on unix & linux stackexchange.
Simply create an new systemd .service file in /etc which includes and overrides part of the one in /lib. For example, create /etc/systemd/system/tomcat.service to contain
.include /lib/systemd/system/tomcat.service
[Service]
ExecStartPre=/home/meuh/myscripttorun some pre args here
ExecStartPost=/home/meuh/myscripttorun some post args here
Any ExecStartPre lines will be executed before the ExecStart line, and similarly any ExecStartPost will run after tomcat has started.

How do I generate upstart and monit configuration files using a common spec or meta-configuration?

I'm deploying a node web application as an upstart service using grunt and monitoring it using monit. However:
My upstart and monit configuration duplicate each other a little bit
Upstart doesn't do variable expansion inside env stanzas
I can't find a way to configure monit dynamically (ala upstart .override files)
My question
This means I'm looking for a grunt plugin or other tool that I can use to generate the uptstart .conf and monit conf.d/ files. Can you please help me find one (or suggest a better way of robustly running my node web app)?
A rather crude solution?
To be honest an underscore template of the upstart and monit files would probably be sufficient, and that's what I'll wrap up into a grunt plugin if there isn't a ready-made solution, but this feels like a problem that other people must have run into as well so I imagine there's a solution out there, I just can't find it.
Detail
A bit more detail to illustrate the three problems. My upstart conf file looks like this:
setuid node
setgid node
# ...
script
mkdir -p /home/node/.my-app
echo $$ > /home/node/.my-app/upstart.pid
/usr/local/bin/node /var/node/my-app/server.js >> /var/node/my-app/logs/console.log 2>&1
end script
# ...
And my monit configuration looks like this:
check process node with pidfile /home/node/.my-app/upstart.pid
start program = "/sbin/start my-app" with timeout 60 seconds
stop program = "/sbin/stop my-app"
if failed host localhost port 17394 protocol http
and request "/monit.html"
then restart
if 3 restarts within 5 cycles then timeout
As you can see, the PID file path and config directory is duplicated across the two (problem 1) and I'd love to parameterise the host, port and request URL in the monit file (problem 3).
For problem 2 (no variable expansion in upstart's env stanza, bug report here) there are a couple of workarounds that work for variables used inside *script blocks, which are interpreted as bash scripts, but they don't seem to work in the conf file itself. I think this makes it impossible to specify the user id the app should run as in a configuration file?
Those techniques I just mentioned:
Method 1: Don't use env - echo the variables in the pre-script to a file and then source it later
Method 2: Duplicate the variable expansion in all the script bodies where it is needed
Method 3: Store the variables in a file and cat them in using command substitution
...or suggest a better way of robustly running my node web app
Use PM2 by Unitech instead.
I run all my node apps using PM2. It works perfectly and is easy to configure. It has built-in functionality for autogenerating of startup script. It gives you logging, monitoring and easy maintenance.
Here is a good article showing off the highlights.
Install
npm install -g pm2
Start app
pm2 start app.js
Show running apps
pm2 list
Make a startup script
pm2 startup [ubuntu|centos|systemd]
More details in the readme on their github page

.Net Window service equivalent in linux?

Can we hook to similar start,stop etc events. Do we have to write them as shell scripts? I know of mono port of .NET.
You are looking for something called an 'init script'. These are scripts that allow you to start or stop a service with a single command, like so:
service httpd restart
service httpd stop
service httpd start
Some Linux distributions do not include the service command, in which case you access init scripts directly by their location, /etc/init.d, like so.
/etc/init.d/mysqld restart
You can program your init script to accept whatever parameters you want (start, stop, restart, etc). Some basic tutorials on writing init scripts to get you started can be found at the following web pages:
http://www.cyberciti.biz/tips/linux-write-sys-v-init-script-to-start-stop-service.html
http://www.linuxquestions.org/questions/programming-9/how-to-write-init-script-376302/
Many times an init script is unnecessary, and you can just go with the simpler option of executing your program in the background and killing it manually. Running an executable on Linux in the background can be done like so:
./some_prog arg1 arg2 &
And killing it is done like this:
kill `pgrep some_prog`
If you are fairly new to Linux, that latter option might be a much easier way to go until you get a handle on init scripts and the general Linux service ecosystem.

Erlang: daemon 'init.d' script fails to start

I have a python script which manages an Erlang daemon. Everything works fine when used through a shell once the system is initialized.
Now, when I included the same script under "/etc/init.d" and with the symlinks properly set in "/etc/rcX.d", the python script still works but my Erlang daemon fails to start and leaves no discernible traces (e.g. crash_dump, dmesg etc.)
I also tried setting the environment variable "HOME" through 'erl -env HOME /root' and still no luck.
Any clues?
To manually run the script the same way the system does, use service daemon start if you have that command, or else try
cd /
env -i LANG="$LANG" PATH="$PATH" TERM="$TERM" /etc/init.d/daemon start
That forces the script to run with a known, minimal environment just like it would at startup.
Thanks for this answer - I was having a devil of a time starting the "Alice" RESTful interface to rabbitmq on startup. The key was using 'env HOME=/root /path/to/alice/startup/script' in my init script.

Resources