2
#!/bin/sh

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON="/usr/local/bin/redis-server"
PIDFILE="/var/run/redis/redis_7128.pid"
RUNDIR="/var/run/redis"
REDIS_USER="redis"
DAEMON_ARGS="/etc/redis/redis_7128.conf"
REDISPORT="7128"

case "$1" in
  start)
        echo -n "Starting $DAEMON: "
        touch $PIDFILE
        chown redis:redis $PIDFILE
        chmod 755 $RUNDIR

        if [ -n "$ULIMIT" ]
        then
                ulimit -n $ULIMIT
        fi

        if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid $REDIS_USER:$REDIS_USER --exec $DAEMON -- $DAEMON_ARGS
        then
                echo "$NAME."
        else
                echo "failed"
        fi
        ;;
  stop)
        echo -n "Stopping $DESC: "
        if start-stop-daemon --stop --retry forever/TERM/1 --quiet --oknodo --pidfile $PIDFILE --exec $DAEMON
        then
                echo "$NAME."
        else
                echo "failed"
        fi
        rm -f $PIDFILE
        sleep 1
        ;;

  restart|force-reload)
        ${0} stop
        ${0} start
        ;;

  status)
        echo -n "$DESC is "
        if start-stop-daemon --stop --quiet --signal 0 --name ${NAME} --pidfile ${PIDFILE}
        then
                echo "running"
        else
                echo "not running"
                exit 1
        fi
        ;;

  *)
        echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload|status}" >&2
        exit 1
        ;;
esac

exit 0

I have the above script written for init.d, I want to port it to systemd.

I tried writing my own, and saved it at /etc/systemd/system/redis.service but the variables are not expanding

[Unit]
Description=My Redis Service

[Service]
Type=forking
#User=redis
Restart=on-failure
RemainAfterExit=yes
EnvironmentFile=/etc/systemd/system/redisenv
ExecStart=start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid $REDIS_USER:$REDIS_USER --exec $DAEMON -- $DAEMON_ARGS
ExecStart=echo -n "Starting $DAEMON: "
ExecStart=touch $PIDFILE
ExecStart=chown redis:redis $PIDFILE
ExecStart=chmod 755 $RUNDIR
ExecStart=if [ -n "$ULIMIT" ];then ulimit -n $ULIMIT ;fi  
ExecStart=if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid $REDIS_USER:$REDIS_USER --exec $DAEMON -- $DAEMON_ARGS ;then echo "$NAME." ; else echo "failed"; fi  

ExecStop=start-stop-daemon --stop --retry forever/TERM/1 --quiet --oknodo --pidfile $PIDFILE --exec $DAEMON

[Install]
WantedBy=multi-user.target

And the EnvironmentFile that I wrote for it while porting, I saved it at /etc/systemd/system/redisenv

SECRET=pGNqduRFkB4K9C2vijOmUDa2kPtUhArN
ANOTHER_SECRET=JP8YLOc2bsNlrGuD6LVTq7L36obpjzxd
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/bin/redis-server
PIDFILE=/var/run/redis/redis_6382.pid
RUNDIR=/var/run/redis
REDIS_USER=redis
DAEMON_ARGS=/etc/redis/redis_6382.conf
REDISPORT=6382

After that I did

sudo chmod 777 /etc/systemd/system/redis.service
sudo chmod 777 /etc/systemd/system/redisenv
sudo systemctl daemon-reload
sudo systemctl start redis-service

but it returns

Failed to start redis.service: Unit redis.service is not loaded properly: Invalid argument. 
See system logs and 'systemctl status redis.service' for details.

and sudo systemctl status redis.service returns

● redis.service - My Redis Service                                                                                                                                                                                                                                            
   Loaded: error (Reason: Invalid argument)                                                                                                                                                                                                                                   
   Active: inactive (dead)

Aug 14 19:11:31 squid2 systemd[1]: [/etc/systemd/system/redis.service:16] Executable path is not absolute, ignoring: if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid $REDIS_USER:$REDIS_USER --exec $DAEMON -- $DAEMON_ARGS ;then echo "$NAME." ; 
Aug 14 19:11:31 squid2 systemd[1]: redis.service: Service lacks both ExecStart= and ExecStop= setting. Refusing.
Aug 14 19:11:37 squid2 systemd[1]: [/etc/systemd/system/redis.service:10] Executable path is not absolute, ignoring: start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid $REDIS_USER:$REDIS_USER --exec $DAEMON -- $DAEMON_ARGS
Aug 14 19:11:37 squid2 systemd[1]: [/etc/systemd/system/redis.service:11] Executable path is not absolute, ignoring: echo -n "Starting $DAEMON: "
Aug 14 19:11:37 squid2 systemd[1]: [/etc/systemd/system/redis.service:12] Executable path is not absolute, ignoring: touch $PIDFILE
Aug 14 19:11:37 squid2 systemd[1]: [/etc/systemd/system/redis.service:13] Executable path is not absolute, ignoring: chown redis:redis $PIDFILE
Aug 14 19:11:37 squid2 systemd[1]: [/etc/systemd/system/redis.service:14] Executable path is not absolute, ignoring: chmod 755 $RUNDIR
Aug 14 19:11:37 squid2 systemd[1]: [/etc/systemd/system/redis.service:15] Executable path is not absolute, ignoring: if [ -n "$ULIMIT" ];then ulimit -n $ULIMIT ;fi
Aug 14 19:11:37 squid2 systemd[1]: [/etc/systemd/system/redis.service:16] Executable path is not absolute, ignoring: if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid $REDIS_USER:$REDIS_USER --exec $DAEMON -- $DAEMON_ARGS ;then echo "$NAME." ; 
Aug 14 19:11:37 squid2 systemd[1]: redis.service: Service lacks both ExecStart= and ExecStop= setting. Refusing.

Any help in porting the init.d script to systemd ??

The first that problem that I can see is that the script the variables are not variable expansion is not occuring

  • The chmod 777 /etc/systemd/system/* is a very bad idea. The ExecStart is not for shell commands. – RalfFriedl Aug 14 '18 at 18:45
2

Welcome to Unix StackExchange.

I recommend starting with one of the systemd unit files for Redis that have have already been created and shared?

The attempt at a direct translation is making it harder than it needs to be because systemd has built-in support for many of the features which were coded in bash before:

  • User= directive sets the user that it runs as
  • start-stop-daemon is not needed
  • Explicit Pidfile management is not needed.
  • systemd already sets a sane PATH variable, so you don't need to.
  • systemd has a lot of options to control resources, so calling ulimit is not needed. See man systemd.resource-control for all your options.

For all those reasons, the example redis.service files you'll find online on are rather short.

Systemd supports environment variable substitution only in limited cases. man systemd.service covers the details when you search for "environment variable substition" in the docs.

  • Why don't we need start-stop-daemon? Does systemd automatically detect if a daemon is running or not and gives error if it's already running? – John Dickery Aug 14 '18 at 14:21
  • 3
    As the linked article indicates, systemd doesn't need the program to daemonize as it takes care of all that itself (using a cgroup container), so it can actually do a better job of tracking the program if you don't daemonize it! The only time that you need to use Type=forking is if the server handles requests by forking, like Samba does. – ErikF Aug 14 '18 at 16:06
  • @JohnDickery Managing daemons is one of the major features of systemd. So yes, it tracks the status of what's running and offers a status command to check the status of any running command. – Mark Stosberg Aug 15 '18 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.