Daemonize celery with systemd on centos 7 - python-3.x

I'm tying to run celery 4.3.0 as a daemon using systemd but it gave me this error:
It starts workers but stop them quickly. However, I can run a worker manually by typing a command like:
celery -A bin.proj.celery_app worker1
celery.service - Celery Service
Loaded: loaded (/etc/systemd/system/celery.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Fri 2020-04-10 08:39:59 CEST; 35s ago
Process: 19276 ExecStop=/bin/sh -c ${CELERY_BIN} multi stopwait ${CELERYD_NODES} --
pidfile=${CELERYD_PID_FILE} (code=exited, status=0/SUCCESS)
Process: 19245 ExecStart=/bin/sh -c ${CELERY_BIN} multi start ${CELERYD_NODES} -A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} --logfile=${CELERYD_LOG_FILE} ${CELERYD_OPTS} (code=exited, status=0/SUCCESS)
Main PID: 19245 (code=exited, status=0/SUCCESS)
Apr 10 08:39:58 prod1 sh[19276]: > Stopping nodes...
Apr 10 08:39:58 prod1 sh[19276]: > worker1#prod1: TERM -> 19254
Apr 10 08:39:58 prod1 sh[19276]: > worker2#prod1: TERM -> 19264
Apr 10 08:39:58 prod1 sh[19276]: > Waiting for 2 nodes -> 19254, 19264......
Apr 10 08:39:58 prod1 sh[19276]: > worker1#prod1: OK
Apr 10 08:39:58 prod1 sh[19276]: > worker1#prod1: DOWN
Apr 10 08:39:58 prod1 sh[19276]: > Waiting for 2 nodes -> None, None....
Apr 10 08:39:58 prod1 sh[19276]: > worker2#prod1: OK
Apr 10 08:39:58 prod1 sh[19276]: > worker2#prod1: DOWN
Apr 10 08:39:58 prod1 sh[19276]: > Waiting for 1 node -> None...
Here is the celery.service:
[Unit]
Description=Celery Service
After=network.target
[Service]
type=forking
User=ssc
Group=ssc
EnvironmentFile=/etc/conf/celery
WorkingDirectory=/home/ssc/Mr.Robot/
ExecStart=/bin/sh -c '${CELERY_BIN} multi start ${CELERYD_NODES} -A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} --logfile=${CELERYD_LOG_FILE} ${CELERYD_OPTS}'
ExecStop=/bin/sh -c '${CELERY_BIN} multi stopwait ${CELERYD_NODES} --pidfile=${CELERYD_PID_FILE}'
ExecReload=/bin/sh -c '${CELERY_BIN} restart ${CELERYD_NODES} -A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} --logfile=${CELERYD_LOG_FILE} ${CELERYD_OPTS}'
[Install]
WantedBy=multi-user.target
Here is the config file associated:
# Name of nodes to start
# here we have a single node
#CELERYD_NODES="w1"
# or we could have three nodes:
CELERYD_NODES="worker1 worker2 worker3"
# Absolute or relative path to the 'celery' command:
CELERY_BIN="/usr/local/bin/celery"
#CELERY_BIN="/virtualenvs/def/bin/celery"
# App instance to use
# comment out this line if you don't use an app
CELERY_APP="bin.proj.celery_app"
# or fully qualified:
#CELERY_APP="proj.tasks:app"
# How to call manage.py
CELERYD_MULTI="multi"
# Extra command-line arguments to the worker
CELERYD_OPTS="--loglevel=INFO --time-limit=300 --concurrency=3"
# - %n will be replaced with the first part of the nodename.
# - %I will be replaced with the current child process index
# and is important when using the prefork pool to avoid race conditions.
CELERYD_PID_FILE="/var/run/celery/%n.pid"
CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
CELERYD_LOG_LEVEL="INFO"
# you may wish to add these options for Celery Beat
CELERYBEAT_PID_FILE="/var/run/celery/beat.pid"
CELERYBEAT_LOG_FILE="/var/log/celery/beat.log"
And the app file:
import sys,os
sys.path.append(os.getcwd())
from celery import Celery
from bin.proj.utils import create_rotating_log
# initialize logger
global logger
logger = create_rotating_log('./log/activity.log')
# initialize celery
try:
app = Celery('celery_app',
broker="".join(['redis://:pass#localhost:6379/10']),
backend="".join(['redis://:pass#localhost:6379/11']),
include=['bin.proj.tasks'])
#logger.info('Celery session OK')
except Exception as e:
logger.error('Celery session KO')
logger.error(e)
if __name__ == '__main__':
app.start()
The user is 'ssc', this user is not part of root group, and I gave all rights needed to 'ssc' user on the project.
Any help would be much appreciated, I already send too much time on it, thanks

I had a similar issue daemonizing celery and the problem was related on the rights on pidfile and logfile.
The directories /var/run/celery and /var/log/celery should belong to the user running the service, here user scc. The problem is that when running as daemon the output is closed and thus hiding error messages.
If you want to debug the service and find the issue, just run the full command using the 'scc' account. It should tell you about any access right error or anything else.
/bin/sh -c '/usr/local/bin/celery multi start worker1 worker2 worker3 -A bin.proj.celery_app --pidfile=/var/run/celery/%n.pid --logfile=/var/log/celery/%n%I.log --loglevel=INFO --time-limit=300 --concurrency=3'

Related

bash script runs in terminal, but doesn't auto-start with systemd

I'm trying to run a bash script on startup as a systemd service, I'm doing this on a Raspberry Pi 4 with Raspbian Buster Lite.
I'm able to execute the bash script if I run it manually ./hls.sh and I am able to also run the service if I do sudo service tv start but the tv.service does not appear to be able to execute the bash script hls.sh on start. I did give permissions chmod 777 for both the service and the bash file as well.
Any help here would be appreciated, I've been trying to figure this out on and off for a month now.
Edit:
Using the suggestions by Carl, I modified the files. However, it still doesn't work. I noticed also that when Type=oneshot you can't do a Restart=always, and if I do a restorecon -r there's an error that says the command isn't found. Per Carl's suggestion I put everything in /opt I decided not to use the temp file suggestion because I need to have the ffmpeg output go to the same place every time (my understanding is that the other way would randomly generate a folder?).
Edit2: Issue was related to this systemd issue: https://unix.stackexchange.com/questions/209832/debian-systemd-network-online-target-not-working the workaround was simply to do RestartSec=5s under [Service]
Bash Script [Before]
#!/bin/bash
/usr/bin/ffmpeg -reconnect 1 -reconnect_at_eof 1 -reconnect_streamed 1 -reconnect_delay_max 2 -y -nostdin \
-hide_banner -loglevel fatal \
-i http://10.0.0.11:9981/stream/channelnumber/2 \
-vcodec copy -acodec copy -scodec copy -g 60 \
-fflags +genpts -user_agent HLS_delayer \
-metadata service_provider="TimeShift" \
-metadata service_name="TV 1" \
-f hls -hls_flags delete_segments \
-hls_time 60 \
-hls_list_size 480 \
-hls_wrap 481 \
-hls_segment_filename /home/pi/hls/1_%03d.ts /home/pi/hls/1_hls.m3u8
Bash Script [After]
#!/usr/bin/env bash
set -e -o pipefail # return exit code of command with non-zero exit code and stop executing
echo "The solution works!"
/usr/bin/ffmpeg -reconnect 1 -reconnect_at_eof 1 -reconnect_streamed 1 -reconnect_delay_max 2 -y -nostdin \
-hide_banner -loglevel fatal \
-i http://10.0.0.11:9981/stream/channelnumber/2 \
-vcodec copy -acodec copy -scodec copy -g 60 \
-fflags +genpts -user_agent HLS_delayer \
-metadata service_provider="TimeShift" \
-metadata service_name="JSTV 1" \
-f hls -hls_flags delete_segments \
-hls_time 60 \
-hls_list_size 480 \
-hls_wrap 481 \
-hls_segment_filename /opt/hls/tmp/1_%03d.ts /opt/hls/tmp/1_hls.m3u8
Service [Before]
[Unit]
Description=Timeshift TV
After=tvheadend.service
PartOf=tvheadend.service
Restart=always
[Service]
ExecStartPre=/bin/mkdir -p /home/pi/hls/
ExecStart=/home/pi/hls.sh 103 &
ExecStop=/bin/rm -rf /home/pi/hls
[Install]
WantedBy=default.target
Service [After]
[Unit]
Description=Timeshift TV
After=tvheadend.service
PartOf=tvheadend.service
[Service]
WorkingDirectory=/opt/hls
User=nobody
Type=oneshot
ExecStartPre=+/bin/mkdir -p -m777 /opt/hls/tmp
ExecStart=/opt/hls/hls.sh
ExecStopPost=+/bin/rm -rf /opt/hls/tmp
#Restart=always
[Install]
WantedBy=multi-user.target
After a reboot, checking the status via systemctl status [Before]
● tv.service - Timeshift TV
Loaded: loaded (/etc/systemd/system/tv.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Mon 2020-05-18 05:36:40 BST; 45s ago
Process: 465 ExecStartPre=/bin/mkdir -p -m777 /home/pi/hls/ (code=exited, status=0/SUCCESS)
Process: 472 ExecStart=/home/pi/hls.sh 103 & (code=exited, status=1/FAILURE)
Main PID: 472 (code=exited, status=1/FAILURE)
May 18 05:36:39 tv3 systemd[1]: Starting Timeshift TV...
May 18 05:36:39 tv3 systemd[1]: Started Timeshift TV.
May 18 05:36:40 tv3 systemd[1]: tv.service: Main process exited, code=exited, status=1/FAILURE
May 18 05:36:40 tv3 systemd[1]: tv.service: Failed with result 'exit-code'.
After a reboot, checking the status via systemctl status [After]
● tv.service - Timeshift tv
Loaded: loaded (/etc/systemd/system/tv.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Mon 2020-05-18 20:13:39 BST; 15min ago
Process: 464 ExecStartPre=/bin/mkdir -p -m777 /opt/hls/tmp (code=exited, status=0/SUCCESS)
Process: 471 ExecStart=/opt/hls/hls.sh (code=exited, status=1/FAILURE)
Process: 484 ExecStopPost=/bin/rm -rf /opt/hls/tmp (code=exited, status=0/SUCCESS)
Main PID: 471 (code=exited, status=1/FAILURE)
May 18 20:13:38 tv3 systemd[1]: Starting Timeshift tv...
May 18 20:13:38 tv3 hls.sh[471]: The solution works!
May 18 20:13:39 tv3 systemd[1]: tv.service: Main process exited, code=exited, status=1/FAILURE
May 18 20:13:39 tv3 systemd[1]: tv.service: Failed with result 'exit-code'.
May 18 20:13:39 tv3 systemd[1]: Failed to start Timeshift tv.
[After] starting the process manually still works
● tv2.service - Timeshift tv
Loaded: loaded (/etc/systemd/system/tv2.service; enabled; vendor preset: enabled)
Active: activating (start) since Mon 2020-05-18 20:53:13 BST; 17s ago
Process: 865 ExecStartPre=/bin/mkdir -p -m777 /opt/hls/tmp (code=exited, status=0/SUCCESS)
Main PID: 866 (bash)
Tasks: 2 (limit: 4915)
Memory: 15.3M
CGroup: /system.slice/tv2.service
├─866 bash /opt/hls/hls.sh
└─867 /usr/bin/ffmpeg -reconnect 1 -reconnect_at_eof 1 -reconnect_streamed 1 -reconnect_delay_max 2 -y -nostdin -hide_banner -logle
May 18 20:53:13 tv3 systemd[1]: Starting Timeshift tv...
May 18 20:53:13 tv3 hls.sh[866]: The solution works!
pi#tv3:/etc/systemd/system $ cd /opt/hls
pi#tv3:/opt/hls $ ls
hls.sh tmp
pi#tv3:/opt/hls $ cd tmp
pi#tv3:/opt/hls/tmp $ ls
1_000.ts
There are a few issues with this service file. I'll address them below and then show the final solution.
Avoid putting system-level services under the /home directory. While it may work, it is not advised. There are many out-of-scope issues that could occur by doing that. Instead, consider placing the scripts under /opt, /srv, or /usr/local.
When moving the files around in a big way like this, make sure to run restorecon -r on that directory after moving it. This ensures SELinux contexts are reset to their correct values, rather than mixing the new context with the old context. This can help solve permission denied errors when SELinux is in enforcing mode.
The Restart= directive goes under [Service] not [Unit], so that should be moved there or be removed entirely. It's probably innocuous since systemd is sometimes forgiving, but the systemd.service is the one that defines that directive, not systemd.unit.
Change ExecStart= to not have & at the end. Just leave it be and run it as a normal script. Systemd will handle the rest, if properly configured.
Change ExecStop= to ExecStopPost= instead. This will allow systemd to do its normal stop behavior, which is to send a SIGTERM to the script when being asked to stop the service. After the stop has been completed (either gracefully or forcefully), the ExecStopPost= will run. Since it appears you're using it to cleanup after the script ran, that should be changed. If left as is, systemd will remove the directory then wait for the script to exit, which the script will never do since it wasn't told to, so systemd will wait the timeout period before asking the kernel to SIGKILL the script. Definitely not ideal.
A few extra directives under [Service] would solve some of the assumptions about how this service should behave.
WorkingDirectory= — so that it is defined rather than assumed. If left as default, it becomes the home directory of the User, which if also is left default, would be /root. Instead, set it to the location of the script or to /tmp if PrivateTmp=true.
User= — so that the script doesn't run as root which is the default user. I suggest nobody or whichever user you wish to have managing the ffmpeg execution. This prevents giving the script root privileges when it runs, which ffmpeg shouldn't need.
Type= — this is arguably the most important, since the script is being ran as a one-off and will then exit after succeeding; it doesn't daemonize to the background and continue running as the default simple service would. This should be set to oneshot instead so that systemd knows that; it will treat the script exiting (with a status code of 0) as a successful run of the service, and will move on.
PrivateTmp= — In most cases, this should be enabled. Only in rare circumstances should it be disabled. The default behavior is disabled. When enabled, anything the script tries to store in /tmp will actually be transparently stored in a namespaced directory called /tmp/systemd-private-xxxx-servicename.service-xxxxx/, preventing any conflicts with other files in /tmp. If you use this, I would change your ffmpeg to write to /tmp instead of managing a directory next to the script, enabling you to remove ExecStartPre= and ExecStopPost= altogether.
Make sure the ExecStartPre= and ExecStopPost= have a + prepended, that way they run as root instead of the defined User= which might not be root; this may or may not be necessary depending on your expectations with the directory. See systemd.service Table 1. Special executable prefixes for more info.
Change WantedBy=default.target to multi-user.target; it is more likely that this service is supposed to be ran for that target, rather than whatever target happens to get booted as default.
You probably shouldn't make the script chmod 777, I would go with a modest chmod 755 instead. It should only need the read and execute bits (+rx).
So without further adieu, this is the final solution:
Directory Structure: ls -lZ /opt/sfo-61862759
total 8
-rwxr-xr-x. 1 carl users unconfined_u:object_r:usr_t:s0 58 May 18 01:44 sfo-61862759.bash
-rw-r--r--. 1 carl users unconfined_u:object_r:usr_t:s0 316 May 18 01:53 sfo-61862759.service
Shell Script: /opt/sfo-61862759/sfo-61862759.bash
#!/usr/bin/env bash
set -e -o pipefail # return exit code of command with non-zero exit code and stop executing
echo "The solution works!"
# put ffmpeg stuff here and remove the echo if you choose
Service File: /etc/systemd/system/sfo-61862759.service
[Unit]
Description=Stackoverflow Question #61862759 Solution
[Service]
WorkingDirectory=/tmp
User=nobody
Type=oneshot
#ExecStartPre=+/bin/mkdir -p /opt/sfo-61862759/temp
ExecStart=/opt/sfo-61862759/sfo-61862759.bash
#ExecStopPost=+/bin/rm -rf /opt/sfo-61862759/temp
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Systemd Status Output:
01:53 carl#utility.localdomain:/opt/sfo-61862759$ sudo systemctl start sfo-61862759.service
01:54 carl#utility.localdomain:/opt/sfo-61862759$ sudo systemctl status sfo-61862759.service -n 4
● sfo-61862759.service - Stackoverflow Question #61862759 Solution
Loaded: loaded (/opt/sfo-61862759/sfo-61862759.service; linked; vendor preset: disabled)
Active: inactive (dead)
May 18 01:54:02 utility.localdomain systemd[1]: Starting Stackoverflow Question #61862759 Solution...
May 18 01:54:03 utility.localdomain sfo-61862759.bash[459746]: The solution works!
May 18 01:54:03 utility.localdomain systemd[1]: sfo-61862759.service: Succeeded.
May 18 01:54:03 utility.localdomain systemd[1]: Finished Stackoverflow Question #61862759 Solution.

Setting up minecraft server service on usb hard drive problem

I'm trying to set up a minecraft server to play with my friends. It's my first time doing this on linux, so I have a (I believe) small problem. I can't figure out how to set up it on my usb hard drive.
Here's my minecraft.service
GNU nano 2.9.3 minecraft.service
[Unit]
Description=Minecraft Server
After=network.target
[Service]
WorkingDirectory=/media/main/ALL/.minecraft-server
User=minecraft
Restart=always
ExecStart=/usr/bin/screen -DmS mc-%i /usr/bin/java -Xms512M -Xmx3584M -jar -DIReallyKnowWhatIAmDoingISwear spigot*.jar nogui
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "say SERVER SHUTTING DOWN IN 15 SECONDS..."\015'
ExecStop=/bin/sleep 5
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "say SERVER SHUTTING DOWN IN 10 SECONDS..."\015'
ExecStop=/bin/sleep 5
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "say SERVER SHUTTING DOWN IN 5 SECONDS..."\015'
ExecStop=/bin/sleep 5
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "save-all"\015'
ExecStop=/usr/bin/screen -p 0 -S mc-%i -X eval 'stuff "stop"\015'
[Install]
WantedBy=multi-user.target
small edit - I removed -%i, because it's to make multi-server I believe
and here is status of service after start
● minecraft.service - Minecraft Server
Loaded: loaded (/etc/systemd/system/minecraft.service; disabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sat 2019-10-19 11:30:25 CEST; 17min ago
Process: 1462 ExecStart=/usr/bin/screen -DmS mc- /usr/bin/java -Xms512M -Xmx3584M -jar -DIReallyKnowWhatIAmDoingISwear spigot*.jar nogui (code=exited, status=1/FAILURE)
Main PID: 1462 (code=exited, status=1/FAILURE)
Oct 19 11:30:25 ubuntu systemd[1]: minecraft.service: Service hold-off time over, scheduling restart.
Oct 19 11:30:25 ubuntu systemd[1]: minecraft.service: Scheduled restart job, restart counter is at 5.
Oct 19 11:30:25 ubuntu systemd[1]: Stopped Minecraft Server.
Oct 19 11:30:25 ubuntu systemd[1]: minecraft.service: Start request repeated too quickly.
Oct 19 11:30:25 ubuntu systemd[1]: minecraft.service: Failed with result 'exit-code'.
Oct 19 11:30:25 ubuntu systemd[1]: Failed to start Minecraft Server.
user was created by "useradd minecraft" with no password
Distro is Ubuntu Server 18.04.3 LTS
I need it on usb hard drive because I have small sd card. In future I want to replace it with ssd on adpter
Ok. Thank you all for not helping me. After hours I found solution(s).
I re-created user minecraft with --system
Created group minecraft with --system
added user to group
Set home folder of minecraft user to .../.minecraft-server (when i did it on create it throwed error)
This fixed my problem with server not starting at all, but then i cannot attach to screen.
I tried -c with custom config and editing /etc/screenrc (second option totally broke screen, so I needed to reinstall it). Finally i created .screenrc in /.minecraft-server with options multiuser on and added users that can attach.
Now it's working, but I spend about 10 hours straight to fix it...
Creating user and group:
adduser --system minecraft
addgroup --system minecraft
usermod -a -G minecraft minecraft
usermod --home /home_folder minecraft
.screenrc in minecraft's home directory:
multiuser on
addacl root
addacl user1
Finall version of minecraft.service in systemd:
[Unit]
Description=Minecraft Server
After=network.target
[Service]
WorkingDirectory=/media/main/ALL/.minecraft-server
User=minecraft
Group=minecraft
Type=forking
Restart=on-failure
#RestartSec=20 5
ExecStart=/usr/bin/screen -dmS mc /usr/bin/java -Xms512M -Xmx3584M -jar -DIReallyKnowWhatIAmDoingISwear spigot-1.14.4.jar nogui
ExecStop=/usr/bin/screen -p 0 -S mc -X eval 'stuff "say SERVER SHUTTING DOWN IN 15 SECONDS..."\015'
ExecStop=/bin/sleep 5
ExecStop=/usr/bin/screen -p 0 -S mc -X eval 'stuff "say SERVER SHUTTING DOWN IN 10 SECONDS..."\015'
ExecStop=/bin/sleep 5
ExecStop=/usr/bin/screen -p 0 -S mc -X eval 'stuff "say SERVER SHUTTING DOWN IN 5 SECONDS..."\015'
ExecStop=/bin/sleep 5
ExecStop=/usr/bin/screen -p 0 -S mc -X eval 'stuff "save-all"\015'
ExecStop=/usr/bin/screen -p 0 -S mc -X eval 'stuff "stop"\015'
[Install]
WantedBy=multi-user.target
To attach to screen: screen -x minecraft/mc
where minecraft is user, and mc is screen name

How can I access the return code of a service in ExecStop or ExecPostStop?

Is it possible to capture the exit code from a process running on, e.g. ExecStart in a systemd service unit? I want to check, if the process exited okay or if an error occurred.
After reading the systemd.service and systemd.exec docs, I thought $SERVICE_RESULT $EXIT_CODE and / or $EXIT_STATUS might help. But to no avail.
Given this test unit:
[Unit]
Description=Testing Run Order
[Service]
Type=simple
Environment=HELLO=WORLD
ExecStartPre=/bin/echo [StartPre] $MAINPID $SERVICE_RESULT $EXIT_CODE $EXIT_STATUS
ExecStartPost=/bin/echo [StartPost] $MAINPID $SERVICE_RESULT $EXIT_CODE $EXIT_STATUS
ExecStart=/bin/sleep 2
ExecStop=/bin/env
ExecStop=/bin/echo [Stop] $MAINPID $SERVICE_RESULT $EXIT_CODE $EXIT_STATUS
ExecStopPost=/bin/echo [StopPost] $MAINPID $SERVICE_RESULT $EXIT_CODE $EXIT_STATUS
I get the following output:
Aug 30 08:37:26 localhost.localdomain systemd[1]: Starting Testing Run Order...
Aug 30 08:37:26 localhost.localdomain echo[3458]: [StartPre]
Aug 30 08:37:26 localhost.localdomain systemd[1]: Started Testing service metrics.
Aug 30 08:37:26 localhost.localdomain echo[3460]: [StartPost] 3459
Aug 30 08:37:27 localhost.localdomain env[3465]: LANG=en_US.UTF-8
Aug 30 08:37:27 localhost.localdomain env[3465]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Aug 30 08:37:27 localhost.localdomain env[3465]: HELLO=WORLD
Aug 30 08:37:27 localhost.localdomain echo[3467]: [Stop]
Aug 30 08:37:27 localhost.localdomain echo[3469]: [StopPost]
So nothing. I'm currently stuck with systemd 219 (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN) on Centos7.
$EXIT_CODE and $EXIT_STATUS were only added in systemd v232. If you’re stuck with an older version, you’ll have to work around it, perhaps with something like this (untested):
ExitStart=/bin/sh -c '/* normal command goes here */; echo $? > /tmp/my-service.exit'
ExecStopPost=/bin/sh -c 'EXIT_STATUS=$(cat /tmp/my-service.exit); /* rest of command goes here */'
A side note: when you write something like
ExecStop=/bin/echo [Stop] $MAINPID $SERVICE_RESULT $EXIT_CODE $EXIT_STATUS
in your test unit, those variables are substituted by systemd. To check the environment of the actual process, use a shell (as above) or a command like env (as you did for one of the ExecStop lines).
You can actually read ExecMainStatusCode from the command systemctl show your_service --property=ExecMainStatus
For example, if you want to trigger a command depending on the result (graceful stop or hard crash) you could use something like this:
ExecStopPost=/bin/bash -c "if [ $(systemctl show your_service --property=ExecMainStatus) == 'ExecMainStatus=143' ]; then exit; else /bin/bash -c '/usr/local/bin/your_custom_program.sh'; fi"

PID file /usr/local/apache2/logs/httpd.pid not readable (yet?) after start

I installed httpd 2.4.27 in CentOS 7. I configured httpd.service as systemd service. But everytime I got this error PID file /usr/local/apache2/logs/httpd.pid not readable (yet?) after start. when I start or restart httpd.service.
Here is my configuration of httpd.service:
[root#localhost ~]# cat /usr/lib/systemd/system/httpd.service
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)
[Service]
Type=forking
ExecStart=/usr/local/apache2/bin/apachectl -k start
ExecReload=/usr/local/apache2/bin/apachectl -k graceful
ExecStop=/usr/local/apache2/bin/apachectl -k graceful-stop
PIDFile=/usr/local/apache2/logs/httpd.pid
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[root#localhost ~]#
Here is the error info:
[root#localhost ~]# systemctl start httpd.service
[root#localhost ~]# systemctl status httpd.service
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since Fri 2017-09-01 22:30:48 EDT; 1s ago
Docs: man:httpd(8)
man:apachectl(8)
Process: 2173 ExecStart=/usr/local/apache2/bin/apachectl -k start (code=exited, status=0/SUCCESS)
Main PID: 2176 (httpd)
CGroup: /system.slice/httpd.service
├─2176 /usr/local/apache2/bin/httpd -k start
├─2177 /usr/local/apache2/bin/httpd -k start
├─2178 /usr/local/apache2/bin/httpd -k start
└─2179 /usr/local/apache2/bin/httpd -k start
Sep 01 22:30:47 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
Sep 01 22:30:48 localhost.localdomain systemd[1]: PID file /usr/local/apache2/logs/httpd.pid not readable (yet?) after start.
Sep 01 22:30:48 localhost.localdomain systemd[1]: Started The Apache HTTP Server.
[root#localhost ~]#
Here is the permission of httpd.pid file:
[root#localhost ~]# ll /usr/local/apache2/logs/
total 8
-rw-r--r--. 1 root root 0 Sep 1 20:46 access_log
-rw-r--r--. 1 root root 3270 Sep 1 22:30 error_log
-rw-r--r-- 1 root root 5 Sep 1 22:30 httpd.pid
[root#localhost ~]#
I found there was no use to change the permission of httpd.pid file manually, because the file will be removed automatically when service gets stopped. And new httpd.pid file will be generated once service is turned on.
Note: I see some posts saying updating /usr/lib/tmpfiles.d/httpd.conf will work. But I don't have this file since I installed apache from source. I think only 'yum install httpd' has this.
Anyone can help? I just want to have a clean service start with no error or warning. Thanks.
you can set /lib/tmpfiles.d/httpd.conf follow:
d /usr/local/apache2/logs/httpd.pid 700 apache apache
vim /etc/systemd/system/httpd.service
Add parameter of "ExecStartPost" is work,
[Unit]
Description=httpd service
After=syslog.target network.target
[Service]
Type=forking
PIDFile=/usr/local/apache2/logs/httpd.pid
ExecStart=/bin/sh -c '/usr/sbin/apachectl -f /etc/httpd/httpd.conf -k start'
ExecStop=/bin/sh -c '/usr/sbin/apachectl -f /etc/httpd/httpd.conf -k stop'
ExecReload=/bin/sh -c '/usr/sbin/apachectl -f /etc/httpd/httpd.conf -k graceful'
ExecStartPost=/bin/sh -c '/usr/bin/chown apache:apache -R /usr/local/apache2/logs/httpd.pid'
[Install]
WantedBy=multi-user.target

supervisord not including [include] files=/abs/path/to/files/*conf

I have a fresh install of supervisord inside a development vagrant machine. I have rabbitmq setup and receiving messages from my Symfony2 producers. I am attempting to use supervisord to maintain X consumers which are Symfony2 console commands.
The following config works like a dream. My consumers are created and maintained fine.
# /etc/supervisord.conf
# ...
[supervisord]
logfile=/var/log/supervisor/supervisord.log
user=root
[program:rabbitmq-consume-email]
command=/usr/bin/php /another/path/app/console rabbitmq:consumer -w email
numprocs=2
process_name=%(program_name)s-%(process_num)s
But changing it up to the following, does not seem to create any producers, including checking for current consumers on the queues I am consuming from.
# /etc/supervisord.conf
# ...
[supervisord]
logfile=/var/log/supervisor/supervisord.log
user=root
[include]
files = /abs/path/to/more/confs/*.conf
With ...
# /abs/path/to/more/confs/rabbitmq-email.conf
# ...
[program:rabbitmq-consume-email]
command=/usr/bin/php /another/path/app/console rabbitmq:consumer -w email
numprocs=2
process_name=%(program_name)s-%(process_num)s
As you can see from the following, the configuration files all share the same permissions. But even making the included config files 777 (purely out of frustration) I have no progress.
vagrant#box  ~  ls -l /etc/supervisord.conf
-rw-r--r-- 1 root root 391 Dec 3 14:51 /etc/supervisord.conf
vagrant#box  ~  ls -l /abs/path/to/more/confs/
-rw-r--r-- 1 root root 197 Dec 3 15:41 rabbitmq-email.conf
-rw-r--r-- 1 root root 193 Dec 3 15:42 rabbitmq-sms.conf
The log file shows the normal start info (at debug level) and no errors concerning including any files (before and after permission changes.
2015-12-03 16:00:02,225 CRIT Set uid to user 0
2015-12-03 16:00:02,234 DEBG supervisord forked; parent exiting
2015-12-03 16:00:02,235 INFO daemonizing the process
2015-12-03 16:00:02,235 INFO supervisord started with pid 28061
Any suggestions greatly appreciated.

Resources