systemd env vars from an executable script - linux

I have the following systemd service file:
[Unit]
Description=My description
[Service]
Type=simple
User=myuser
ExecStart=/path/to/my/start_script.sh
ExecStop=/path/to/my/stop_script.sh
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=30s
[Install]
WantedBy=multi-user.target
My start_script.sh is used to start a java application BUT I need to get some variables from an executable ksh script custom_script.sh.
I tried the following systemd params with no success:
ExecStartPre
EnvironmentFile
Is there a way to make it work?
Thank you in advance heroes.

In order to have the variables from custom_script.sh accessible from your Java process, you'll have to insert them into the environment somehow, in a way that systemd will be pleased with. The docs for the EnvironmentFile= directive say that any line that is not a parameter assignment statement with an = sign will be ignored. So we need to take your script and cook it down so that all we have left are the variables after running it.
What you can do is create an auxiliary "distillery" service that sources your custom_script.sh file and prints every value in the environment to another file called custom_script.env. Then you can provide the "distilled" environment file to the Java process in the EnvironmentFile directive.
So if your original service adds After= and Requires= like this,
[Unit]
Description=My description
After=custom-script-distillery
Requires=custom-script-distillery
[Service]
Type=simple
User=myuser
EnvironmentFile=/path/to/my/custom_script.env
ExecStart=/path/to/my/start_script.sh
ExecStop=/path/to/my/stop_script.sh
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=30s
[Install]
WantedBy=multi-user.target
Then the distillery could look like this:
[Unit]
Description=My service to distill custom_script.sh to an EnvironmentFile
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c 'set -o allexport; source /path/to/my/custom_script.sh; set +o allexport; unset IFS; set | grep -v "^BASH" > /path/to/my/custom_script.env'

Related

Systemd service with multiple execStart and watchdog for each execStart

I would know if it's possible to create service with multiple execStart where I can monitor each execStart with a watchdog such as:
[Unit]
Description="test service"
[Service]
Type=oneshot
ExecStart=/home/program1
ExecStart=/home/program2
WatchdogSec= 2
Restart=on-failure
RestartSec= 1
[Install]
WantedBy=default.target
Or it's better if I use template service for example test#.service with this syntax:
[Unit]
Description="test service %i"
[Service]
ExecStart=/home/%i
WatchdogSec= 2
Restart=on-failure
RestartSec= 1
[Install]
WantedBy=default.target
Thanks in advance.
I found that using the template service is the better solution and covers what I need. Thanks to you all.

How to restart Systemd service only once on-failure?

I have a service that should restart only once when something go wrong.
Here is my service:
[Unit]
Description=Do job on boot
AllowIsolate=yes
StartLimitBurst=1 # or 2
StartLimitIntervalSec=3
[Service]
User=root
Type=idle
ExecStart=/usr/bin/python3 /var/www/flask/initJobs.py
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
But this on failure keep restarting.
systemd version 241.
Tried to add StartLimitAction=none but did not change nothing.
Ok i found, so to restart service only once on failure after 3 second.
[Unit]
Description=Do job on boot
StartLimitBurst=2
StartLimitInterval=11 # StartLimitInterval > RestartSec * StartLimitBurst
#OR
#StartLimitIntervalSec=11
[Service]
User=root
Type=idle
ExecStart=/usr/bin/python3 /var/www/flask/initJobs.py
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
the key here is StartLimitIntervalSec have to be > to RestartSec * StartLimitBurst and StartLimitBurst count the first start.

How to pipe Systemd service standard output from ExecStart to shell, ex. bash?

I have a Systemd service that starts the process of output which I need to execute as a normal Bash script
[Unit]
Description=Example app
[Service]
Type=simple
PIDFile=/var/run/app.pid
Sockets=app.socket
StandardInput=fd:app.socket
#StandardOutput=fd:sh
StandardError=journal
ExecStart=/usr/bin/app -a | sh #
[Install]
WantedBy=default.target
Instead of execution, the output of the application falls into the log.
Tell me how can I solve this problem?
you can't really pipe stuff in ExecStart, but you can do:
ExecStart=/bin/bash -c '/usr/bin/app -a | sh '

Register daemon controllable by start and stop command in Linux

Many system daemon can be started using start/stop command. I was just curious how start/stop works on Linux system. Say I wrote a daemon executable, how should I configure it so that it can be controlled by start/stop in Linux.
I make a daemon in linux (ArchLinux) few years ago, and it works every day perfectly.
There are 2 ways to do this. Short way and long way:
Short Way:
Create a file in /etc/systemd/system/ called for example mydaemon.service :
/etc/systemd/system/mydaemon.service
[Unit]
Description=This is my first daemon! - Fernando Pucci
After=network.target
[Service]
User=root
WorkingDirectory=/root
Type=oneshotmc
RemainAfterExit=yes
ExecStart=/bin/echo -e "Daemon started"
ExecStop=/bin/echo -e "Daemon Stopped"
[Install]
WantedBy=multi-user.target
This service does nothing but show Daemon Started or Stopped. You can change echoes by the sentences you need.
If you need to run some script, try the Long way:
Long way
Create a file in some directory, like root folder or /usr/lib/systemd/scripts called for example
/root/mydaemon.sh
start() {
<your start sentences here
and here>
}
stop() {
<your stop sentences here
and here>
}
case $1 in
start|stop) "$1" ;;
esac
You must to make it runnable (chmod x)
(And you can execute it with start or stop parameter to test it.)
And as second step, create another file in
/usr/lib/systemd/system/mydaemon.service
[Unit]
Description=Second daemon of Fernando Pucci
After=network.target
[Service]
User=root
WorkingDirectory=/root
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c '/root/mydaemon.sh start'
ExecStart=/bin/echo -e "MyDaemon Started"
ExecStop=/bin/bash -c '/root/mydaemon.sh stop'
ExecStop=/bin/echo -e "MyDaemon Stopped"
[Install]
WantedBy=multi-user.target
Starting and Stopping
systemctl start mydaemon
systemctl stop mydaemon
systemctl status mydaemon
systemctl enable mydaemon
systemctl disable mydaemon
You (and someone) can send me a private msg for help about that.

systemctl testing shell scripts

So I am trying arch linux, but I can't really understand how to make autostart scripts and such. I tried this (I know there are better ways to do it but it's just a test):
this is the service:
[Unit]
Description=testing purposes
[Service]
Type=oneshot
ExecStart=/usr/lib/systemd/scripts/font
[Install]
WantedBy=multi-user.target
this is the script:
setfont Lat2-Terminus16
I chmod +x'd the script and stuff so I thought it wouldn't make any problems but it does not work unlike what I expected, so I am clearly doing something wrong. Where is the problem?
EDIT: Solved, I changed the ExecStart line to this:
ExecStart=/bin/sh -c '/usr/bin/setfont Lat2-Terminus16'

Resources