Score:0

systemd drop-in unit, ExecStartPre as root user, ExecStart as custom user

ru flag

I have a web service running using systemd, this service runs by its own user, and I would like to execute some ExecStartPre commands but running as root user. So more in detail:

i.e /lib/systemd/system/webservice.service

[Unit]
Wants=network-online.target
After=network-online.target

[Service]
EnvironmentFile=/etc/default/web
Group=webuser
Type=simple
Restart=on-failure
WorkingDirectory=/usr/share/web
RuntimeDirectory=web
RuntimeDirectoryMode=0750
ExecStart=/usr/sbin/web --config=/etc/web/config.ini                               

[Install]
WantedBy=multi-user.target

and I would like to have a drop-in service where it fetches from a web-source the config.ini file

i.e /etc/systemd/system/web.service.d/local.conf

[Service]
PermissionsStartOnly=true
RestartSec=5
EnvironmentFile=/etc/environment
ExecStartPre=+/usr/bin/curl http://some.url --output /etc/web/config.ini 
ExecStartPre=+chown web:web /etc/web/config.ini  

The configuration above is not working since my service is freezing during the startup without any message in any log. Is there any way I can make something like that to work?

Andrew Lowther avatar
jp flag
Is the configuration you posted doing what you want? I can't tell if you need help getting this to work if you want to know if there is a cleaner way.
ru flag
You are right, I reformulate my question.
Score:0
jp flag

I think your systemd setup is correct. If the terminal hangs when you start the service then I would suspect the ExecStartPre command is not exiting.

I ran the following commands as root on an Ubuntu 20.04 server to test a similar service setup.

Create a user for the service.

useradd --system myservice

Create a script for the service that logs the user the script is running as and loops.

cat <<'EOF' > /usr/local/bin/myservice.sh
#!/usr/bin/env bash

# first argument is loop count, defaults to infinite
i=${1:--1}
while :; do
  date >> ${RUNTIME_DIRECTORY:-/tmp}/run.log
  whoami >> ${RUNTIME_DIRECTORY:-/tmp}/run.log
  (( --i == 0 )) && break
  sleep ${SLEEP:-60}
done
EOF

Add the service file and the override file.

cat <<EOF > /etc/systemd/system/myservice.service
[Unit]
Description=My Service

[Service]
EnvironmentFile=-/etc/default/myservice
Type=simple
User=myservice
Group=myservice
Restart=on-failure
RuntimeDirectory=myservice
RuntimeDirectoryMode=0750
ExecStart=/bin/bash /usr/local/bin/myservice.sh
EOF

mkdir -p /etc/systemd/system/myservice.service.d/
cat <<EOF > /etc/systemd/system/myservice.service.d/override.conf
[Service]
PermissionsStartOnly=true
ExecStartPre=/bin/bash /usr/local/bin/myservice.sh 1
ExecStartPre=chown myservice.myservice /run/myservice/run.log
EOF

systemctl daemon-reload

Start the service

systemctl start myservice.service

The result is as expected. The run.log file shows the script ran once as root and then continues running as the myservice user until the service is stopped.

root@ubuntu:~# ls -al /run/myservice/
total 4
drwxr-x---  2 myservice myservice   60 Feb 27 18:23 .
drwxr-xr-x 30 root      root      1080 Feb 27 18:23 ..
-rw-r--r--  1 myservice myservice   73 Feb 27 18:23 run.log
root@ubuntu:~# cat /run/myservice/run.log
Sun Feb 27 18:23:14 UTC 2022
root
Sun Feb 27 18:23:14 UTC 2022
myservice
Sun Feb 27 18:24:14 UTC 2022
myservice

I did find that if the ExecStartPre command enters the loop then the terminal appears to hang when the service is started. That could explain why you think your service is freezing. The ExecStartPre command may still be running or may be unable to complete.

Other Notes

  • I found that using either PermissionsStartOnly=true or ExecStartPre=+... had the same effect of running the ExecStartPre script as root.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.