cSvn-UI for SVN Repositories

cSvn-UI – is a web interface for Subversion (SVN) Repositories. cSvn CGI script is writen in C and therefore it's fast enough.

12 Commits   0 Branches   2 Tags   |

cSvn-UI for SVN Repositories

cSvn-UI – is a web interface for Subversion (SVN) Repositories. cSvn CGI script is writen in C and therefore it's fast enough.

Table of Contents

Reqired packages

cSvn-ui depends of following libraries: libpcre2-8, librt, libm, libmd4c, libmd4c-html, libmagic, and libxml2.

From the moment when the cSvn package was split into two, so as do not produce unnecessary entities, cSvn-ui depends on the cScm package. Therefore, before installing cSvn-ui, you have to install and configure cScm Configuration Daemon.

To use cSvn-ui 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

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

svn checkout svn://radix.pro/csvn-ui/tags/csvn-ui-0.1.3 csvn-ui-0.1.3

and run the bootstrap script:

cd csvn-ui-0.1.3
./bootstrap

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

Bootstrap Script

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

./bootstrap

I 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:

TARGET_DEST_DIR=/home/developer/prog/trunk-672/dist/.s9xx-glibc/enybox-x2 \
       ./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

./configure --prefix=/usr \
            --with-scriptdir=/var/www/htdocs/csvn

Install on the Build Machine

make
make install

Cross Compilation Example

#!/bin/sh

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

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

PKG_CONFIG=/usr/bin/pkg-config \
PKG_CONFIG_PATH=${TARGET_DEST_DIR}/usr/lib${LIBDIRSUFFIX}/pkgconfig:${TARGET_DEST_DIR}/usr/share/pkgconfig \
PKG_CONFIG_LIBDIR=${TARGET_DEST_DIR}/usr/lib${LIBDIRSUFFIX}/pkgconfig:${TARGET_DEST_DIR}/usr/share/pkgconfig \
STRIP="${TOOLCHAIN_PATH}/${TARGET}-strip" \
CC="${TOOLCHAIN_PATH}/${TARGET}-gcc --sysroot=${TARGET_DEST_DIR}" \
./configure --prefix=/usr
  --build=x86_64-pc-linux-gnu \
  --host=${TARGET} \
  --with-scriptdir=/var/www/htdocs/csvn

make
make install DESTDIR=${TARGET_DEST_DIR}

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

LDFLAGS="-L${TARGET_DEST_DIR}/lib -L${TARGET_DEST_DIR}/usr/lib"
TARGET_INCPATH="-L${TARGET_DEST_DIR}/usr/include"
CFLAGS="${TARGET_INCPATH}"
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-ui CGI script was installed:

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

uWsgi

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

/etc/uwsgi/csvn-ui.ini:

[uwsgi]
master          = true
plugins         = cgi
socket          = /run/uwsgi/%n.sock
uid             = nginx
gid             = nginx
procname-master = uwsgi csvn-ui
processes       = 1
threads         = 2
cgi             = /var/www/htdocs/csvn/csvn-ui.cgi

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

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

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

#!/bin/sh
#
# uWSGI daemon control script.
#

CONF=csvn-ui
BIN=/usr/bin/uwsgi
CONFDIR=/etc/uwsgi
PID=/var/run/$CONF-uwsgi.pid

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

  if [ -s $PID ]; then
    echo "uWSGI for cSvn-ui appears to already be running?"
    exit 1
  fi

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

uwsgi_stop() {
  echo "Shutdown uWSGI for cSvn-ui gracefully..."
  /bin/kill -INT $(cat $PID)
  /bin/rm -f $PID
}

uwsgi_reload() {
  echo "Reloading uWSGI for cSvn-ui configuration..."
  kill -HUP $(cat $PID)
}

uwsgi_restart() {
  uwsgi_stop
  sleep 3
  uwsgi_start
}

case "$1" in
  start)
    uwsgi_start
    ;;
  stop)
    uwsgi_stop
    ;;
  reload)
    uwsgi_reload
    ;;
  restart)
    uwsgi_restart
    ;;
  *)
  echo "usage: `basename $0` {start|stop|reload|restart}"
esac

To run this 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 correspondingly.

/etc/rc.d/rc.M:

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

/etc/rc.d/rc.6:

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

Nginx

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

/etc/nginx/nginx.conf:

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

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

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

#
# cSvn server:
#

    server {
        listen 80;
        server_name csvn.example.org;
        return 301 https://csvn.example.org$request_uri;
    }

    server {
        listen 443 ssl;
        server_name csvn.example.org;
        root /var/www/htdocs/csvn;

        charset UTF-8;

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

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

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

        gzip on;
        gzip_disable "msie6";
        gzip_comp_level 6;
        gzip_min_length 1100;
        gzip_buffers 16 8k;
        gzip_proxied any;
        gzip_types text/plain text/css text/js text/xml text/javascript
                   image/svg+xml image/gif image/jpeg image/png
                   application/json application/x-javascript application/xml application/xml+rss application/javascript
                   font/truetype font/opentype application/font-woff application/font-woff2
                   application/x-font-ttf application/x-font-opentype application/vnd.ms-fontobject application/font-sfnt;


        location ~* ^.+(favicon.ico|robots.txt) {
            root /var/www/htdocs/csvn;
            expires 30d;
        }

        location = /robots.txt {
            allow all;
            log_not_found off;
            access_log off;
        }

        location / {
            try_files $uri @csvn-ui;
        }

        location @csvn-ui {
            gzip off;
            include uwsgi_params;
            uwsgi_modifier1 9;
            uwsgi_pass unix:/run/uwsgi/csvn-ui.sock;
        }
    }

Configuring SVN Repositories

A detailed description of the configuration file format can be found in the csvn-ui.rc(5) manual page:

man 5 csvn-ui.rc

Here we will give an example of a description of the Apache Subversion repository. Please note that the Apache server responds very slowly to HTTP requests.

/**************************
  Apache's SVN repository:
 */
home-page = "https://svn.apache.org/";

section "Subversion" {
  repo 'subversion' {
    owner = "Apache";
    description = "Source repository of the Subversion.";
    checkout-prefix-readonly = 'https://svn.apache.org/repos/asf';
  }
}

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

See Also

cscmd(8)csvn-ui.rc(5)

Copyright and License

© Andrey V. Kosteltsev, 2019 – 2020.
Code and documentation released under the Radix.pro License.