cSvn — это web-интерфейс к Subversion-репозиториям. Основу cSvn представляет CGI-скрипт написанный на языке С.
В мае 2020 года был опубликован релиз очередной версии Apache Subversion 1.14.0. В свете этого события, был создан новый, современный web-интерфейс для просмотра Subversion-репозиториев на любых устройствах. Это весьма позитивная новость для тех, кто использует централизованные системы версионного контроля по тому, что до вчерашнего дня существовал лишь один достойный web-UI (WebSVN), написанный на PHP и, к сожалению, отстающий от современных требований.
В данной статье рассматривается установка и настройка cSvn для работы с использованием Nginx + uWsgi. Настройка серверных компонентов достаточно проста и практически не отличается от настройки cGit.
На стороне клиента работает элементарный JavaScript составляющий не более 350 строк и таблица стилей размером 24K в распакованном виде. Markdown-тексты обрабатываются на стороне сервера с помощью библиотеки md4c, которая успешно зарекомендовала себя в проекте KDE Plasma.
Вместо screenshot-ов, лучше посмотреть на работающий cSvn-сервер.
Стоит заметить, что с помощью cSvn можно просматривать не только собственные репозитории, но и настроить просмотр сторонних ресурсов по протоколам HTTPS и SVN.
Требования к системе
cSvn использует библиотеки libpcre2, md4c, libmagic, входящую в состав пакета File и libxml2. На сервере должны быть установлены: HTTP-сервер Nginx, сервер uWsgi и, разумеется Apache Subversion.
Инсталляция продуктов
cSvn пакет состоит из двух частей. Первая представляет собой обычный Linux демон, который отвечает за разбор конфигурационного файла /etc/csvnrc. Вторая – непосредственно является CGI-скриптом, отвечающим на HTTP-запросы клиента. Обе части устанавливаются одновременно.
Исходные тексты
Получить исходный пакет cSvn можно двумя способами: загрузить с FTP-сервера или с помощью Subversion:
svn checkout svn://radix.pro/csvn/trunk csvn
Если использован второй способ, то перед сборкой пакета необходимо приготовить исходные тексты для их последующего конфигурирования. Для этого нужно воспользоваться скриптом bootstrap:
cd csvn
./bootstarp
который установит Autotools средства, соберет коллекцию aclocal.m4 и создаст configure скрипт.
Сборка пакета
Сборка и установка cSvn ни чем не отличается от любых других продуктов, использующих средства Autoconf, Automake:
./configure --prefix=/usr --sysconfdir=/etc --with-config=/etc/csvnrc --with-controldir=/etc/rc.d --with-logrotatedir=/etc/logrotate.d --with-scriptdir=/var/www/htdocs/csvn --with-homedir=/var/lib/csvn --with-logdir=/var/log --with-piddir=/var/run
make
make install
Здесь, параметр --with-scriptdir определяет место установки CGI-скрипта и связанных с ним файлов, необходимых для работы сервера cSvn. Далее, в описании настроек сервера Nginx, мы будем использовать именно этот каталог. Разумеется, пользователи могут настроить работу cSvn и виртуального HTTP сервера относительно любого другоро каталога.
Права доступа
После инсталляции пакета cSvn необходимо отдать права на каталог /var/www/htdocs/csvn пользователю, от имени которого работает Nginx:
chown -R nginx:nginx /var/www/htdocs/csvn
Subversion репозитории
Перед первым запуском сервера cSvn необходимо создать конфигурационный файл /etc/csvnrc, в котором должны быть определены все обязательные переменные и описан хотя бы один репозиторий.
На странице руководства csvnrc(5) приведен рабочий файл конфигурации сервера:
/etc/csvnrc:
svn-utc-offset = +0300;
checkout-prefix-readonly = 'svn://radix.pro';
checkout-prefix = 'svn+ssh://svn@radix.pro';
branches = 'branches';
trunk = 'trunk';
tags = 'tags';
snapshots = 'tar.xz';
css = '/.csvn/css/csvn.css';
logo = '/.csvn/pixmaps/csvn-banner-280x280.png';
logo-alt = "Radix.pro";
logo-link = "https://radix.pro";
main-menu-logo = '/.csvn/pixmaps/logo/SVN-logo-white-744x744.svg';
favicon-path = '/.csvn/pixmaps/favicon';
syntax-highlight-css = '_csvn.css';
header = '/.csvn/html/header.html';
footer = '/.csvn/html/footer.html';
page-size = 200;
owner = "Andrey V.Kosteltsev";
author = "Andrey V.Kosteltsev";
title = "Radix.pro SVN Repositories";
description = "Subversion repositories hosted at radix.pro (St.-Petersburg)";
keywords = "cSvn repositories";
copyright = "© Andrey V. Kosteltsev, 2019 – 2020.";
copyright-notice = "Where any material of this site is being reproduced, published or issued to others the reference to the source is obligatory.";
home-page = "https://radix.pro/";
section "Tools" {
repo 'csvn' {
owner = "Andrey V.Kosteltsev";
title = "cSvn CGI Script";
description = "cSvn CGI Script – is a web frontend for Subversion™ Repositories";
home-page = "https://radix.pro/";
}
}
Его можно использовать как начальный шаблон.
После создания конфигурационного файла /etc/csvnrc можно проверить работу csvnd(8) демона.
В случае работы на системе с BSD-like инициализацией, для запуска csvnd(8) демона достаточно выполнить команду
/etc/rc.d/rc.csvnd start
Для систем использующих systemd, необходимо воспользоваться утилитой systemctl:
systemctl enable csvnd.service
systemctl start csvnd.service
При сборке и установке исходного пакета cSvn, устанавливается start/stop-скрипт /etc/rc.d/rc.csvnd. Если же речь идет о системах использующих systemd, то для установки cSvn лучше использовать бинарный RPM или pacman пакет, поскольку в таких пакетах файл /etc/rc.d/rc.csvnd заменяется на Systemd Unit,
/usr/lib/systemd/system/csvnd.service:
[Unit]
Description=The cSvn daemon
After=network.target
[Service]
PIDFile=/var/run/csvnd.pid
ExecStart=/usr/sbin/csvnd --daemonize --inotify --config=/etc/csvnrc
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
устанавливаемый в каталог /usr/lib/systemd/system.
Если для используемой вами системы еще не создан пакет cSvn, то вы его можете приготовить самостоятельно, по инструкциям, приведенным к каталоге doc/build-packages.
Если же вы не хотите создавать пакет для вашей системы, то вы можете просто поместить файл csvnd.service в каталог /usr/lib/systemd/system/ и выполнить запуск демона самостоятельно.
После запуска csvnd(8) демона надо убедиться в существовании файла /dev/shm/csvn.bcf и, в случае его отсутствия посмотреть на ошибки приведенные в /var/log/csvnd.log файле.
Настройка uWsgi
Поскольку на этапе конфигурирования мы выбрали для инсталляции cSvn CGI-скрипта каталог /var/www/htdocs/csvn/, файл /etc/uwsgi/csvn.ini должен ваглядеть следующим образом:
/etc/uwsgi/csvn.ini:
[uwsgi]
master = true
plugins = cgi
socket = /run/uwsgi/%n.sock
uid = nginx
gid = nginx
procname-master = uwsgi csvn
processes = 1
threads = 2
cgi = /var/www/htdocs/csvn/csvn.cgi
Здесь переменная cgi устанавливает полное имя CGI-скрипта cSvn.
Для запуска uWsgi демона на системах с BSD-like инициализацией, такой как Slackware, необходимо создать start/stop скрипт следующего вида:
/ets/rc.d/rc.csvn-uwsgi:
#!/bin/sh
#
# uWSGI daemon control script.
#
CONF=csvn
BIN=/usr/bin/uwsgi
CONFDIR=/etc/uwsgi
PID=/var/run/$CONF-uwsgi.pid
uwsgi_start() {
# Sanity checks.
if [ ! -r $CONFDIR/csvn.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 appears to already be running?"
exit 1
fi
echo "Starting uWSGI for cSvn 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-uwsgi.log --ini $CONFDIR/$CONF.ini
fi
}
uwsgi_stop() {
echo "Shutdown uWSGI for cSvn gracefully..."
/bin/kill -INT $(cat $PID)
/bin/rm -f $PID
}
uwsgi_reload() {
echo "Reloading uWSGI for cSvn 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
Дать ему права на выполнение
chmod a+x /ets/rc.d/rc.csvn-uwsgi
и добавить следующие строчки в файлы /etc/rc.d/rc.M, /etc/rc.d/rc.6, соответственно:
/etc/rc.d/rc.M:
# Start uWSGI for cSvn server:
if [ -x /etc/rc.d/rc.csvn-uwsgi ]; then
/etc/rc.d/rc.csvn-uwsgi start
fi
/etc/rc.d/rc.6:
# Stop uWSGI for cSvn server:
if [ -x /etc/rc.d/rc.csvn-uwsgi ]; then
/etc/rc.d/rc.csvn-uwsgi stop
fi
Настройка Nginx
Конфигурационный файл, для выбранного нами каталога установки и домена 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;
#
# Serve static content with nginx
#
#
# Rewrite rules for versioning CSS + JS thtouh filemtime directive
#
location ~* ^.+.(css|js)$ {
rewrite ^(.+).(d+).(css|js)$ $1.$3 last;
expires 31536000s;
access_log off;
log_not_found off;
add_header Pragma public;
add_header Cache-Control "max-age=31536000, public";
}
#
# Caching of static files
#
location ~* .(eot|gif|gz|gzip|ico|jpg|jpeg|otf|pdf|png|svg|svgz|swf|tar|t?gz|woff|zip)$ {
expires 31536000s;
access_log off;
log_not_found off;
add_header Pragma public;
add_header Cache-Control "max-age=31536000, public";
}
location ~ ^/favicon.ico$ {
root /u3/nginx/vhosts/csvn;
access_log off;
log_not_found off;
expires 30d;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location / {
try_files $uri @csvn;
}
location @csvn {
gzip off;
include uwsgi_params;
uwsgi_modifier1 9;
uwsgi_pass unix:/run/uwsgi/csvn.sock;
}
}
После создания файла /etc/nginx/vhosts/csvn.example.org.conf его необходимо включить в основной конфигурационный файл Nginx:
/etc/nginx/nginx.conf:
include /etc/nginx/vhosts/csvn.example.org.conf;
После запуска uWsgi и Nginx можно заняться настройкой репозториев используя руководство csvnrc(5).
Заключительная настройка
Все необходимые файлы для работы на стороне web-клиента находятся в каталоге /var/www/htdocs/csvn/.csvn/. Редактируя файл /.csvn/html/header.html и меняя значения переменных в файле /etc/csvnrc, пользователь может сменить favicon.ico, поменять тему подсветки синтаксиса, выбрать изображения для собственных репозиториев, задать ключевые слова для поисковых систем, а также выполнить множество других настроек своего сервера.
Внешний вид интерфейса определяется единственным CSS-файлом и поэтому, пользователь может поменять тему web-интерфейса так, как ему будет необходимо.
Посмотреть на рабочую копию cSvn сервера можно здесь.
vabka
SVN-ом ещё кто-то пользуется?
Almatyn
Я пользуюсь, надеюсь в этом нет ничего плохого.
sshikov
Плохого в этом нет вообще ничего. Ну разве что у SVN есть определенные ограничения, но вас они вполне могут не касаться. Скажем в мою бытность в Дойче банке у нас SVN хостилась где-то непойми где, судя по пингу — достаточно далеко, так что всякие операции типа merge релизной ветки куда-то в trunk могли проходить часами. На git такого скорее всего не будет, потому что он распределенный. Но вожможно будет что-то другое.
rcl Автор
Разумеется!