DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Understanding Git
  • Keep Your Application Secrets Secret
  • Code Security Remediation: What 50,000 Repositories Reveal About PR Scanning
  • Shrink a Bloated Git Repository and Optimize Pack Files

Trending

  • Introduction to Retrieval Augmented Generation (RAG)
  • What Nobody Tells You About Multimodal Data Pipelines for AI Training
  • Building an Image Classification Pipeline With Apache Camel and Deep Java Library (DJL)
  • Java Backend Development in the Era of Kubernetes and Docker
  1. DZone
  2. Data Engineering
  3. Databases
  4. Modern Web-UI for SVN Repositories

Modern Web-UI for SVN Repositories

Installing and configuring cSvn - a modern web interface written in C for Subversion repositories on your server.

By 
Andrey Kosteltsev user avatar
Andrey Kosteltsev
·
Nov. 25, 20 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
13.0K Views

Join the DZone community and get the full member experience.

Join For Free

cSvn — is a web interface for Subversion repositories. cSvn is based on CGI script written in С.

This article covers installing and configuring cSvn to work using Nginx + uWsgi. Setting up server components is quite simple and practically does not differ from setting up cGit.

cSvn supports Markdown files that are processed on the server side using the md4c library, which has proven itself in the KDE Plasma project. cSvn provides the ability to add site verification codes and scripts from systems such as Google Analytics and Yandex.Metrika for trafic analysis. Users who wonder to receive donations for his projects can create and import custom donation modal dialogs.

Instead of looking at screenshots, it is better to look at the working site to decide on installing cSvn on your own server.

It should be noted that you can browse not only your own repositories, but also configure viewing of third-party resources via HTTPS and SVN protocols.

Reqired Packages

cSvn depends of following libraries: libpcre2, libmd4c, libmd4c-html, libmagic, and libxml2.

To use cSvn a web server must be installed and configured on the system. We recommend the Nginx with uWsgi application server. Of course, Apache Subversion SCM system should be installed too.

Installation

The cSvn package consists of two parts. First of which is a regular Linux daemon that is responsible for parsing the configuration file, and the second is a CGI script that responds to HTTP requests. Both parts of the package are installed simultaneously but are maintained independently of each other.

Download Sources

To obtain sources we have to checkout its from SVN repository:

Shell
 




xxxxxxxxxx
1


 
1
svn checkout svn checkout svn://radix.pro/csvn/tags/csvn-0.1.2 csvn-0.1.2


and run the bootstrap script:

Shell
 




xxxxxxxxxx
1


 
1
cd csvn-0.1.2
2
./bootstrap


Also cSvn source packages are available for download on the Radix.pro FTP-server.

Bootstrap Script

The bootstrap script especially created for Autotools install automation. To install Autotools into the source directory on the build machine (i.e. when build == host) the bootstrap script can be run without arguments.

Shell
 




xxxxxxxxxx
1


 
1
./bootstrap


In this case Autotools will be installed from current root file system.

For the cross environment the --target-dest-dir option allows to install some stuff from development root file system:

Shell
 




xxxxxxxxxx
1


 
1
TARGET_DEST_DIR=/home/developer/prog/trunk-672/dist/.s9xx-glibc/enybox-x2 \
2
    ./bootstrap --target-dest-dir=${TARGET_DEST_DIR}


For example, in this case the aclocal.m4 script will be collected from the
${TARGET_DEST_DIR}/usr/share/aclocal directory.


Configuring Sources

Shell
 




xxxxxxxxxx
1


 
1
./configure --prefix=/usr \
2
            --sysconfdir=/etc \
3
            --with-config=/etc/csvnrc \
4
            --with-controldir=/etc/rc.d \
5
            --with-logrotatedir=/etc/logrotate.d \
6
            --with-scriptdir=/var/www/htdocs/csvn \
7
            --with-homedir=/var/lib/csvn \
8
            --with-logdir=/var/log \
9
            --with-piddir=/var/run



Install on the Build Machine

Shell
 




xxxxxxxxxx
1


 
1
make
2
make install



Cross Compilation Example

Shell
 




xxxxxxxxxx
1
27


 
1
#!/bin/sh
2

          
3
TARGET_DEST_DIR=/home/developer/prog/trunk-672/dist/.s9xx-glibc/enybox-x2
4
TOOLCHAIN_PATH=/opt/toolchains/aarch64-S9XX-linux-glibc/1.1.4/bin
5
TARGET=aarch64-s9xx-linux-gnu
6

          
7
./bootstrap --target-dest-dir=${TARGET_DEST_DIR}
8

          
9
PKG_CONFIG=/usr/bin/pkg-config \
10
PKG_CONFIG_PATH=${TARGET_DEST_DIR}/usr/lib${LIBDIRSUFFIX}/pkgconfig:${TARGET_DEST_DIR}/usr/share/pkgconfig \
11
PKG_CONFIG_LIBDIR=${TARGET_DEST_DIR}/usr/lib${LIBDIRSUFFIX}/pkgconfig:${TARGET_DEST_DIR}/usr/share/pkgconfig \
12
STRIP="${TOOLCHAIN_PATH}/${TARGET}-strip" \
13
CC="${TOOLCHAIN_PATH}/${TARGET}-gcc --sysroot=${TARGET_DEST_DIR}" \
14
./configure --prefix=/usr
15
  --build=x86_64-pc-linux-gnu \
16
  --host=${TARGET} \
17
  --sysconfdir=/etc \
18
  --with-config=/etc/csvnrc \
19
  --with-controldir=/etc/rc.d \
20
  --with-logrotatedir=/etc/logrotate.d \
21
  --with-scriptdir=/var/www/htdocs/csvn \
22
  --with-homedir=/var/lib/csvn \
23
  --with-logdir=/var/log \
24
  --with-piddir=/var/run
25

          
26
make
27
make install DESTDIR=${TARGET_DEST_DIR}


Also we can make use of additional variables such as CFLAGS, LDFLAGS:

Shell
 




xxxxxxxxxx
1


 
1
LDFLAGS="-L${TARGET_DEST_DIR}/lib -L${TARGET_DEST_DIR}/usr/lib"
2
TARGET_INCPATH="-L${TARGET_DEST_DIR}/usr/include"
3
CFLAGS="${TARGET_INCPATH}"
4
CPPFLAGS="${TARGET_INCPATH}"



Post Install

The system user, on whose behalf the Nginx server is launched, must have permissions to access the directory in which the cSvn CGI script was installed:

Shell
 




xxxxxxxxxx
1


 
1
chown -R nginx:nginx /var/www/htdocs/csvn


If you configured access to your repositories on behalf system user named svn, then it would be good to grant permissions to svn user to access to the directory /var/lib/csvn/ which is a home of csvnd(8) daemon:

Shell
 




xxxxxxxxxx
1


 
1
chown -R svn:svn /var/lib/csvn


and also run the csvnd daemon on behalf of that svn user.

To run the csvnd daemon on systems with BSD-like initialization such as Slackware we have to add following lines to the /etc/rc.d/rc.M and /etc/rc.d/rc.6 scripts correspondengly:

/etc/rc.d/rc.M:

Shell
 




xxxxxxxxxx
1


 
1
# Start csvnd server:
2
if [ -x /etc/rc.d/rc.csvnd ]; then
3
  /etc/rc.d/rc.csvnd start
4
fi


/etc/rc.d/rc.6:

Shell
 




xxxxxxxxxx
1


 
1
# Stop csvnd server:
2
if [ -x /etc/rc.d/rc.csvnd ]; then
3
  /etc/rc.d/rc.csvnd stop
4
fi


For systems which uses systemd initialization you have to set up your own systemd unit like follow:

/etc/systemd/system/csvnd.service:

Shell
 




xxxxxxxxxx
1
12


 
1
[Unit]
2
Description=The cSvn daemon
3
After=network.target
4

          
5
[Service]
6
PIDFile=/var/run/csvnd.pid
7
ExecStart=/usr/sbin/csvnd --daemonize --inotify --config=/etc/csvnrc
8
ExecReload=/bin/kill -s HUP $MAINPID
9
ExecStop=/bin/kill -s TERM $MAINPID
10

          
11
[Install]
12
WantedBy=multi-user.target



uWsgi

Since we used the --with-scriptdir=/var/www/htdocs/csvn option on configuring stage, the cSvn CGI script installed in the /var/www/htdocs/csvn/ directory. In this case, the /etc/uwsgi/csvn.ini file should look like this:

/etc/uwsgi/csvn.ini:

Shell
 




xxxxxxxxxx
1
10


 
1
[uwsgi]
2
master          = true
3
plugins         = cgi
4
socket          = /run/uwsgi/%n.sock
5
uid             = nginx
6
gid             = nginx
7
procname-master = uwsgi csvn
8
processes       = 1
9
threads         = 2
10
cgi             = /var/www/htdocs/csvn/csvn.cgi


Where /var/www/htdocs/csvn/csvn.cgi is the full name of installed cSvn CGI script.

To run the uWSGI daemon for cSvn backend we can make use following start/stop script:

/ets/rc.d/rc.csvn-uwsgi:

Shell
 




xxxxxxxxxx
1
64


 
1
#!/bin/sh
2
#
3
# uWSGI daemon control script.
4
#
5

          
6
CONF=csvn
7
BIN=/usr/bin/uwsgi
8
CONFDIR=/etc/uwsgi
9
PID=/var/run/$CONF-uwsgi.pid
10

          
11
uwsgi_start() {
12
  # Sanity checks.
13
  if [ ! -r $CONFDIR/csvn.ini ]; then # no config files, exit:
14
    echo "There are config files in $CONFDIR directory. Abort."
15
    exit 1
16
  fi
17

          
18
  if [ -s $PID ]; then
19
    echo "uWSGI for cSvn appears to already be running?"
20
    exit 1
21
  fi
22

          
23
  echo "Starting uWSGI for cSvn server daemon..."
24
  if [ -x $BIN ]; then
25
    /bin/mkdir -p /run/uwsgi
26
    /bin/chown nginx:nginx /run/uwsgi
27
    /bin/chmod 0755 /run/uwsgi
28
    $BIN --thunder-lock --pidfile $PID --daemonize /var/log/csvn-uwsgi.log --ini $CONFDIR/$CONF.ini
29
  fi
30
}
31

          
32
uwsgi_stop() {
33
  echo "Shutdown uWSGI for cSvn gracefully..."
34
  /bin/kill -INT $(cat $PID)
35
  /bin/rm -f $PID
36
}
37

          
38
uwsgi_reload() {
39
  echo "Reloading uWSGI for cSvn configuration..."
40
  kill -HUP $(cat $PID)
41
}
42

          
43
uwsgi_restart() {
44
  uwsgi_stop
45
  sleep 3
46
  uwsgi_start
47
}
48

          
49
case "$1" in
50
  start)
51
    uwsgi_start
52
    ;;
53
  stop)
54
    uwsgi_stop
55
    ;;
56
  reload)
57
    uwsgi_reload
58
    ;;
59
  restart)
60
    uwsgi_restart
61
    ;;
62
  *)
63
  echo "usage: `basename $0` {start|stop|reload|restart}"
64
esac


To run this daemon on systems with BSD-like initialization such as Slackware we have to add the following lines to the /etc/rc.d/rc.M and /etc/rc.d/rc.6 scripts correspondingly.

/etc/rc.d/rc.M:

Shell
 




xxxxxxxxxx
1


 
1
# Start uWSGI for cSvn server:
2
if [ -x /etc/rc.d/rc.csvn-uwsgi ]; then
3
  /etc/rc.d/rc.csvn-uwsgi start
4
fi


/etc/rc.d/rc.6:

Shell
 




xxxxxxxxxx
1


 
1
# Stop uWSGI for cSvn server:
2
if [ -x /etc/rc.d/rc.csvn-uwsgi ]; then
3
  /etc/rc.d/rc.csvn-uwsgi stop
4
fi



Nginx

First of all, we have to add a virtual server to the main Nginx config file:

/etc/nginx/nginx.conf:

Nginx
 




xxxxxxxxxx
1


 
1
include /etc/nginx/vhosts/csvn.example.org.conf;


The following configuration used uWsgi and will serve cSvn on a subdomain like csvn.example.org:

/etc/nginx/vhosts/csvn.example.org.conf:

Nginx
 




xxxxxxxxxx
1
105


 
1
#
2
# cSvn server:
3
#
4

          
5
    server {
6
        listen 80;
7
        server_name csvn.example.org;
8
        return 301 https://csvn.example.org$request_uri;
9
    }
10

          
11
    server {
12
        listen 443 ssl;
13
        server_name csvn.example.org;
14
        root /var/www/htdocs/csvn;
15

          
16
        charset UTF-8;
17

          
18
        #
19
        # see:
20
        #   https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security ,
21
        #   https://raymii.org/s/tutorials/HTTP_Strict_Transport_Security_for_Apache_NGINX_and_Lighttpd.html
22
        #
23
        # see also: http://classically.me/blogs/how-clear-hsts-settings-major-browsers
24
        # and do not include includeSubdomains; parameter into line:
25
        #
26
        add_header Strict-Transport-Security "max-age=63072000; preload";
27

          
28
        error_log /var/log/nginx/csvn.example.org-error.log;
29
        access_log /var/log/nginx/csvn.example.org-access.log;
30

          
31
        keepalive_timeout        60;
32
        ssl_certificate          /etc/letsencrypt/live/csvn.example.org/fullchain.pem;
33
        ssl_certificate_key      /etc/letsencrypt/live/csvn.example.org/privkey.pem;
34
        ssl_trusted_certificate  /etc/letsencrypt/live/csvn.example.org/chain.pem;
35
        ssl_protocols            SSLv3 TLSv1 TLSv1.1 TLSv1.2;
36
        ssl_ciphers              "RC4:HIGH:!aNULL:!MD5:!kEDH";
37

          
38
        gzip on;
39
        gzip_disable "msie6";
40
        gzip_comp_level 6;
41
        gzip_min_length 1100;
42
        gzip_buffers 16 8k;
43
        gzip_proxied any;
44
        gzip_types text/plain text/css text/js text/xml text/javascript
45
                   image/svg+xml image/gif image/jpeg image/png
46
                   application/json application/x-javascript application/xml application/xml+rss application/javascript
47
                   font/truetype font/opentype application/font-woff application/font-woff2
48
                   application/x-font-ttf application/x-font-opentype application/vnd.ms-fontobject application/font-sfnt;
49

          
50
        #
51
        # Serve static content with nginx
52
        #
53

          
54
        #
55
        # Rewrite rules for versioning CSS + JS thtouh filemtime directive
56
        #
57
        location ~* ^.+.(css|js)$ {
58
            rewrite ^(.+).(d+).(css|js)$ $1.$3 last;
59

          
60
            expires 31536000s;
61

          
62
            access_log off;
63
            log_not_found off;
64

          
65
            add_header Pragma public;
66
            add_header Cache-Control "max-age=31536000, public";
67
        }
68

          
69
        #
70
        # Caching of static files
71
        #
72
        location ~* .(eot|gif|gz|gzip|ico|jpg|jpeg|otf|pdf|png|svg|svgz|swf|tar|t?gz|woff|zip)$ {
73
            expires 31536000s;
74

          
75
            access_log off;
76
            log_not_found off;
77

          
78
            add_header Pragma public;
79
            add_header Cache-Control "max-age=31536000, public";
80
        }
81

          
82
        location ~ ^/favicon.ico$ {
83
            root /u3/nginx/vhosts/csvn;
84
            access_log off;
85
            log_not_found off;
86
            expires 30d;
87
        }
88

          
89
        location = /robots.txt {
90
            allow all;
91
            log_not_found off;
92
            access_log off;
93
        }
94

          
95
        location / {
96
            try_files $uri @csvn;
97
        }
98

          
99
        location @csvn {
100
            gzip off;
101
            include uwsgi_params;
102
            uwsgi_modifier1 9;
103
            uwsgi_pass unix:/run/uwsgi/csvn.sock;
104
        }
105
    }



Configuring SVN Repositories

A detailed description of the configuration file format can be found in the csvnrc(5) manual page.

Here we will give a working example of a description of the cSvn repository which can be used as a template for your configurations.

/etc/csvnrc:

Nginx
 




x
40


 
1
svn-utc-offset = +0300;
2

          
3
checkout-prefix-readonly = 'svn://radix.pro';
4
checkout-prefix          = 'svn+ssh://[email protected]';
5

          
6
branches = 'branches';
7
trunk    = 'trunk';
8
tags     = 'tags';
9

          
10
snapshots = 'tar.xz';
11

          
12
css = '/.csvn/css/csvn.css';
13
logo = '/.csvn/pixmaps/csvn-banner-280x280.png';
14
logo-alt = "Radix.pro";
15
logo-link = "https://radix.pro";
16
main-menu-logo = '/.csvn/pixmaps/logo/SVN-logo-white-744x744.svg';
17
favicon-path = '/.csvn/pixmaps/favicon';
18
syntax-highlight-css = '_csvn.css';
19
header = '/.csvn/html/header.html';
20
footer = '/.csvn/html/footer.html';
21
page-size = 200;
22

          
23
owner = "Andrey V.Kosteltsev";
24
author = "Andrey V.Kosteltsev";
25
title = "Radix.pro SVN Repositories";
26
description = "Subversion repositories hosted at radix.pro (St.-Petersburg)";
27
keywords = "cSvn repositories";
28
copyright = "© Andrey V. Kosteltsev, 2019 – 2020.";
29
copyright-notice = "Where any material of this site is being reproduced, published or issued to others the reference to the source is obligatory.";
30

          
31
home-page = "https://radix.pro/";
32

          
33
section "Tools" {
34
  repo 'csvn' {
35
    owner = "Andrey V.Kosteltsev";
36
    title = "cSvn CGI Script";
37
    description = "cSvn CGI Script – is a web frontend for Subversion™ Repositories";
38
    home-page = "https://radix.pro/";
39
  }
40
}


To access your own repositories, we recommend the svn+ssh protocol.


Final Settings

Files needed to work on web-client side are placed in the /var/www/htdocs/csvn/.csvn/ directory. By editing the HTML header file /.csvn/html/header.html and cSvn config file /etc/csvnrc user can change favicon.ico, change the theme of syntax highlighting, choose images for his repositories, define keywords for search engines such as Google, and also bunch of the other settings.

Additional information about support of analysis services and custom donation dialogues you can find on csvnrc(5) page.

Enjoy.

Repository (version control) shell

Opinions expressed by DZone contributors are their own.

Related

  • Understanding Git
  • Keep Your Application Secrets Secret
  • Code Security Remediation: What 50,000 Repositories Reveal About PR Scanning
  • Shrink a Bloated Git Repository and Optimize Pack Files

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook