7

subversion package in debian jessie does not include a systemd service file. what is the simplest solution for automatic start. i try

[Unit]
Description=Subversion protocol daemon
After=syslog.target network.target

[Service]
Type=forking
#EnvironmentFile=/etc/conf.d/svnserve
#ExecStart=/usr/bin/svnserve --daemon $SVNSERVE_ARGS
ExecStart=/usr/bin/svnserve -d -r /svnFolder/repositories
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target
Alias=svnserve.service

it is an adaptation of https://bbs.archlinux.org/viewtopic.php?id=190127 but i have put the arguments directly for svnserve directly here.

what can be improved?

user855443
  • 2,596
  • 3
  • 25
  • 37
  • I'm voting to close this question as off-topic because it's off topic for SO as it does not directly relate to programming. The Unix and Linux StackExchange site would be a better fit. – Mark Stosberg Jul 05 '16 at 13:07
  • systemd files are largely the same between all distributions that are based on systemd. Have you looked at equivalent files from Arch Linux, Fedora or Ubuntu for inspiration? – Mark Stosberg Jul 05 '16 at 13:08
  • What is the problem with your current solution? It doesn't work? What error does it produce? – Marki555 Jul 14 '16 at 10:46

5 Answers5

35

Here is a proposal to setup svnserve service "the-Debian-way" running with a dedicated svn service account with proper logging. According to FHS, repositories should be stored in /srv/:

mkdir -p /srv/svn/repos; chown svn /srv/svn/repos

First, the service configuration for systemd /etc/systemd/system/svnserve.service:

[Unit]
Description=Subversion protocol daemon
After=syslog.target network.target

[Service]
Type=forking
RuntimeDirectory=svnserve
PIDFile=/run/svnserve/svnserve.pid
EnvironmentFile=/etc/default/svnserve
ExecStart=/usr/bin/svnserve $DAEMON_ARGS
User=svn
Group=svn
KillMode=control-group
Restart=on-failure

[Install]
WantedBy=multi-user.target

Second, the service startup options at /etc/default/svnserve:

# svnserve options
DAEMON_ARGS="--daemon --pid-file /run/svnserve/svnserve.pid --root /srv/svn/repos --log-file /var/log/svnserve/svnserve.log"

To work properly, the folder for log files must be created with proper ownership and run location for pid file too:

mkdir /var/log/svnserve; chown svn /var/log/svnserve
mkdir -p /run/svnserve; chown svn /run/svnserve

To end with log rotation configuration /etc/logrotate.d/svnserve:

/var/log/svnserve/*.log {
    daily
    missingok
    rotate 14
    compress
    notifempty
    create 640 svn adm
    sharedscripts
    postrotate
            if /bin/systemctl status svnserve > /dev/null ; then \
                /bin/systemctl restart svnserve > /dev/null; \
            fi;
    endscript
}

Hope this helps.

Yves Martin
  • 10,217
  • 2
  • 38
  • 77
  • 1
    @Yves Martin Thanks for this solution. I recently used a variation of this solution and had a few comments. First off, in `/etc/default/svnserve`, the arg flag for the log file should be `--log-file`, not `--log`. Also, while creating the log directory only needs to be done once, `/var/run` is not guaranteed to persist. It would be better to use the [`RuntimeDirectory=`](http://0pointer.de/public/systemd-man/systemd.exec.html#RuntimeDirectory=) directive. In Ubuntu, `/var/run` is a symlink to `/run`. – Grexis Feb 06 '17 at 08:08
  • @Grexis Many thanks for your improvements. This service setup looks great now. I learned yet another feature of `systemd` and fix my FHS about `/run`. Thank you – Yves Martin Feb 08 '17 at 10:57
  • Won't this break outstanding svn connections during the logrotation? That is, if I'm in the middle of an svn operation, say, a long checkout on an automated builder, won't the "restart" interrupt and thus break my svn connection and thus my build? – K Richard Pixley Mar 17 '17 at 17:30
  • Good question. As far as I know, `svnserve` forks for each request and waits for child to stop before exiting... so I think there is no chance to cancel an in-progress operation – Yves Martin Mar 17 '17 at 18:02
  • I reverted `KillMode` to default `control-group` or else child processes are left running. `ExecReload` does not have expected effect, process is simply killed. – Yves Martin Jun 20 '17 at 10:48
  • It seems `sudo mkdir -p /srv/svn/repos` is necessay before editing `/etc/default/svnserve` if there is no this dir, `/srv/svn/repos`. – Zhilong Jia Jan 21 '19 at 14:39
  • I'd like to draw attention to an answer below by @Matt Hovey that suggests removing the alias line. I too find that having this line prevents the systemctl enable command from working (on Ubuntu 20.04). – EricS May 28 '20 at 19:47
  • The combination of `User=...` + `PIDFile=/run/...` wasn't working for me (on RHEL7), because user `svn` can't write to `/run/...`. Even with a `svn` user owned subdirectory, the subdirectory was getting wiped out. I got this to work by ditching the PID file and using `GuessMainPID=true`. – Possum Aug 06 '20 at 21:01
  • RHEL cleans /run at boot, whereas Debian does not. It may be interesting to find a portable way to write non-root PID file from systemd service. – Yves Martin Sep 14 '20 at 09:33
2

Update: My answer below has been obsoleted. These improvements and others have been incorporated into Yves Martin's excellent solution.

I have two improvements: it's generally recommended not to run such things as root. Create a user for this, for example 'svn'. It is also recommended to explicitly specify a PID file when using forking. My svnserve.service looks much like yours except I add the lines:

User=svn
Group=svn
PIDFile=/usr/local/svn/svnserve.pid
ExecStart=/usr/bin/svnserve  -d -r /usr/local/svn/repos --pid-file /usr/local/svn/svnserve.pid
EricS
  • 569
  • 1
  • 3
  • 15
  • A PID FILE is looks like a good idea as does the separate user. thank you! – user855443 Oct 30 '16 at 08:41
  • I've changed this to put the pid file in a directory fully managed by the svn user rather than /var/run/svnserve. /var/run was temporary on the system I was using. Perhaps it would be better to have a startup script create and permission /var/run/svnserve but I chose not to deal with it. Perhaps someone else can improve this. – EricS Nov 11 '16 at 01:54
  • @EricS I had the same issue. The [`RuntimeDirectory=`](http://0pointer.de/public/systemd-man/systemd.exec.html#RuntimeDirectory=) directive is perfect for this, and there is [`tmpfiles.d`](http://0pointer.de/public/systemd-man/tmpfiles.d.html) for anything more complicated. – Grexis Feb 06 '17 at 08:12
1

One comment on Yves Martin's excellent answer above (I don't have the rep points to comment yet):

When trying to enable the service to start on boot, I'd get an error:

$ sudo systemctl enable svnserve.service
Failed to execute operation: Invalid argument

After doing some research I found you apparently cannot set an alias to the same name as the service. Deleting the Alias line from the [Install] section of the svnserve.service solved the issue:

[Unit]
Description=Subversion protocol daemon
After=syslog.target network.target

[Service]
Type=forking
RuntimeDirectory=svnserve
PIDFile=/run/svnserve/svnserve.pid
EnvironmentFile=/etc/default/svnserve
ExecStart=/usr/bin/svnserve $DAEMON_ARGS
User=svn
Group=svn
KillMode=control-group
Restart=on-failure

[Install]
WantedBy=multi-user.target
Matt Hovey
  • 85
  • 5
  • I find this to be true also, on Ubuntu 20.04. I get a different error from enable though: "Failed to enable unit: File /etc/systemd/system/svnserve.service already exists." Thanks for this! – EricS May 28 '20 at 19:48
0

(I'd make this a comment on @Yves Martin's answer, but this is a new account and I'm not allowed to comment. :-P )

With SELinux, this solution doesn't allow for an autostart of the daemon. I made a few changes to make it happy. The svnserve daemon does not have open rights in the /var/log tree. Placing the log in the svn account's domain resolves a security whine.

In /etc/systemd/system/svnserve.service:

ExecStart=/usr/bin/svnserve --daemon \
  --pid-file /var/run/svnserve/svnserve.pid \
  --root /project/svn/repos \
  --log-file /project/svn/log/svnserve.log

In /etc/logrotate.d/svnserve:

/project/svn/log/*.log {  # path changed
...
  create 644 svn svn   # corrected group and made world-readable
...

Finally, make the svn repos and log directory have the correct ownership and security type:

sudo mkdir /project/svn
sudo chmod 755 /project/svn
sudo mkdir /project/svn/repos /project/svn/log
sudo chown -R svn:svn /project/svn
sudo semanage fcontext --add --type svnserve_content_t "/project/svn(/.*)?"
sudo restorecon -Rv /project/svn

(Obviously, change /project/svn to wherever you have decided to put your repo structure. /var/svn is common and the rules already exist for that directory tree, making the last couple lines above unnecessary.)

S. Narum
  • 1
  • 2
0

Please consider this replacement of xinet -> systemd: (This was mostly gleaned from http://0pointer.de/blog/projects/inetd.html

You would need to create two files:

svnserve.socket

[Unit]
Description=SVN Socket for Per-Connection Servers

[Socket]
ListenStream=3690
Accept=yes

[Install]
WantedBy=sockets.target

and svnserve@.service

[Unit]
Description=SVN Per-Connection Server

[Service]
User=svn
Group=svn
ExecStart=-/usr/bin/svnserve -i -r /srv/repositories/svn/repositories
StandardInput=socket

Copy both files to /etc/systemd/system/

then

systemctl enable svnserve.socket
systemctl start svnserve.socket
systemctl status svnserve.socket
vkersten
  • 131
  • 1
  • 5