You are not logged in.

#1 2012-07-31 09:12:07

Revelation60
Member
From: The Netherlands
Registered: 2009-03-19
Posts: 158
Website

Systemd: writing complicated service file

I am trying to write a service file for sabnzbd, the package I am maintaining. In the old init script of sabnzbd a lot of bash code is executed and I can't seem to find a systemd example file that does something like this. I want to include a configuration file and use its variables, because my ExecStart should be:

su - "${SABNZBD_USER}" -c "python2 ${SABNZBD_DIR}/SABnzbd.py ${SABNZBD_ARGS}" -s /bin/sh

and my ExecStop should be

curl -f "${SABNZBD_PROTOCOL}://${SABNZBD_USPW}${SABNZBD_IP}:${SABNZBD_PORT}/sabnzbd/api?mode=shutdown&apikey=${SABNZBD_KEY}" &> /dev/null


I also want to check if sabnzbd actually closed. So, how do I do all these bash things in a service file?

Offline

#2 2012-07-31 09:14:36

Shark
Member
From: /dev/zero
Registered: 2011-02-28
Posts: 686

Re: Systemd: writing complicated service file

I just installed systemd few days ago so i wouldn't know exactly but "man systemd.service" is quite informative.
Check this too:
http://patrakov.blogspot.com/2011/01/wr … files.html

Last edited by Shark (2012-07-31 09:17:30)


If you have built castles in the air, your work need not be lost; that is where they should be. Now put foundations under them.
Henry David Thoreau

Registered Linux User: #559057

Offline

#3 2012-07-31 10:07:04

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: Systemd: writing complicated service file

ExecStart etc. can take multiple lines, these must be ; separated, with spaces round the ;.

ExecStart=cmd1 ; cmd2 ; \
                  cmd3

Remember, you can also write a script to start/stop the service and simply call that from the unit file. You'll need to get the type right though.
That's what netcfg does, so if you have that installed, check that one out.

As well as man systemd.service, man systemd.unit is useful too.

@Shark - thanks for that blog link, that's useful.


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#4 2012-08-01 08:37:34

Revelation60
Member
From: The Netherlands
Registered: 2009-03-19
Posts: 158
Website

Re: Systemd: writing complicated service file

It seems that

[Service]
User=${SABNZBD_USER}

is invalid, because I get an error:  Failed at step USER spawning /bin/sh: No such process

Getting variables from the environment does work for ExecStart, ExecStop, etc. but not for User and Group. Is this a bug?

Last edited by Revelation60 (2012-08-01 08:38:01)

Offline

#5 2012-08-01 11:55:15

debdj
Member
Registered: 2012-01-19
Posts: 163

Re: Systemd: writing complicated service file

Revelation60 wrote:

It seems that

[Service]
User=${SABNZBD_USER}

is invalid, because I get an error:  Failed at step USER spawning /bin/sh: No such process

I think you should initialize the variables in a separate conf file like you said earlier.
Like, this is my network service file:

[Unit]  
Description=Network Connectivity        
Wants=network.target    
Before=network.target
        
[Service]       
Type=oneshot    
RemainAfterExit=yes     
EnvironmentFile=/etc/conf.d/city_network
ExecStart=/sbin/ip link set dev ${interface} up
ExecStart=/sbin/ip addr add ${address}/${netmask} broadcast ${broadcast} dev ${interface}
ExecStart=/sbin/ip route add default via ${gateway}
ExecStart=/sbin/mii-tool -F 10BaseT-HD eth0
ExecStop=/sbin/ip addr flush dev ${interface}   
ExecStop=/sbin/ip link set dev ${interface} down
        
[Install]       
WantedBy=multi-user.target

while /etc/conf.d/city_network contains the network parameters.

And besides, systemd.service(5) and systemd.unit(5) clarifies most(if not all) things.

Last edited by debdj (2012-08-01 11:58:17)

Offline

#6 2012-08-01 12:06:34

Revelation60
Member
From: The Netherlands
Registered: 2009-03-19
Posts: 158
Website

Re: Systemd: writing complicated service file

Like I said, that works fine for ExecStart. Try setting User=${somevar} and it won't do the parsing. The same goes for Group and PIDFile.

Offline

#7 2012-08-01 12:32:25

65kid
Member
From: Germany
Registered: 2011-01-26
Posts: 663

Re: Systemd: writing complicated service file

Revelation60 wrote:

Like I said, that works fine for ExecStart. Try setting User=${somevar} and it won't do the parsing. The same goes for Group and PIDFile.

I had a similiar situation with my transmission service file. Using variables indeed only works for ExecStart/Stop (maybe a few others). No idea if this simply hasn't been implemented or if there is a good reason they didn't do this for User= etc as well.

My suggestion: Use a hardcoded User= and create that user when installing the package (to make sure it works out of the box).
Whoever wants to change that user can copy the service file to /etc and edit User= or just do an ".include ..." and override User= (see https://wiki.archlinux.org/index.php/Sy … it_file.3F ).

Offline

#8 2012-08-01 13:02:42

Revelation60
Member
From: The Netherlands
Registered: 2009-03-19
Posts: 158
Website

Re: Systemd: writing complicated service file

Whoever wants to change that user can copy the service file to /etc and edit User= or just do an ".include ..." and override User=

That's a pretty nice way to deal with this smile

Still, maybe a bug report/feature request somewhere is a good thing to do.

Last edited by Revelation60 (2012-08-01 13:02:55)

Offline

#9 2012-08-01 14:35:45

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: Systemd: writing complicated service file

I've not tried this, but this is another alternative.

If you name your service file:

myservice@.service

and then, enable it by doing:

ln -s /usr/lib/systemd/system/myservice@.service /etc/systemd/sytem/multi-user.target.wants/myservice@user.service

Then you can set the user with:

User=%I

See http://www.freedesktop.org/software/sys … .unit.html

That way a user can change the user associated with the service, merely by changing the symlink.

Edit: meant to say, it looks like netcfg makes use of this process, as there's a netcfg@.service file. I'm not sure how it gets set up though.


Also, you can use systemctl to enable a service just for a specified user:

# systemctl --user me enable myservice.service

And I think then using %u instead of %I will give you the user - though you probably don't have to specify User in this case, it might be useful for config paths, etc.

Last edited by skanky (2012-08-01 14:37:16)


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

Board footer

Powered by FluxBB