Sergey Sharybin
9dec2d8927
Previous logic was adding an extra indirection level in the paths which consists of 2 first letters of the repository name. Since then the project was scaled down, and we only use it for own needs, so it makes it simpler to simplify the paths. Extra testing is needed, since something might be missing. |
||
---|---|---|
apache | ||
docker | ||
filelocator | ||
httphandler | ||
json_schemas | ||
svnman | ||
ui | ||
.dockerignore | ||
.gitignore | ||
CHANGELOG.md | ||
Dockerfile | ||
go.mod | ||
go.sum | ||
gocheck_test.go | ||
LICENSE.txt | ||
main.go | ||
Makefile | ||
README.md | ||
run_docker.sh | ||
svn-manager.service |
SVN Manager
System requirements
Requirements are:
- Apache 2
- Mod-SVN
The SVNManager needs to be able to gracefully restart Apache after configuration files have been
created. This is done by invoking sudo apache2ctl
(or its equivalent on the OS - for example,
apachectl when running on FreeBSD), and requires that this command can be performed
without having to provide a password. Add the following to /etc/sudoers
to set this up:
Cmnd_Alias GRACEFUL = /usr/sbin/apache2ctl configtest, /usr/sbin/apache2ctl graceful
www-data ALL = NOPASSWD: GRACEFUL
Replace www-data
with the username of the SVNManager, and /usr/sbin/apache2ctl
with the absolute
path of that executable.
SVNManager tests that the command sudo --non-interactive apache2ctl configtest
can be run
successfully at startup. Failing to do so is considered a fatal error and will prevent SVNManager
from starting.
Internal Structure
The HTTP interface is implemented in the httphandler
subpackage. This package is responsible for
interpreting the HTTP request by parsing variables from the URL and JSON sent in the body.
Furthermore, it is responsible for validating these data.
The actual work managing on-disk files and directories is implemented in the svnman
subpackage.
This package assumes the data is vetted as correct by the httphandler
subpackage.
Apache life cycles, at this moment consisting of graceful restarts, is handled by the apache
subpackage.
Building a release
- Install Golang. Make sure you unpack/install in a way that the current user can write to the Golang directory. This makes it possible to cross-compile the standard library without requiring tricks like Docker containers.
- Install
zip
- Install mockgen
- Run
make mocks test
- Tag the version:
git tag v1.3
- Run
make package
Installation
Server preparation
- SVN repositories are to be stored in
/data/svn/repos
; If this changes, remember this and updatesvn-manager.service
in the section below. - Install Apache + mod-svn + subversion:
sudo apt install apache2 libapache2-mod-svn subversion
- Create the SVN repo directory and set permissions:
sudo mkdir -p /data/svn/repos; sudo chown www-data:www-data /data/svn/repos; sudo chmod 2775 /data/svn/repos
- Enable Apache modules:
sudo a2enmod deflate dav dav_svn authz_svn headers proxy proxy_http
- Make a directory for the SVN Apache config:
sudo mkdir /etc/apache2/svn; sudo chown www-data:www-data /etc/apache2/svn; sudo chmod 0775 /etc/apache2/svn
- Create the API passwords file:
sudo htpasswd -B -c /etc/apache2/api-htpasswd someusername
. If the file already exists, drop the-c
argument. - Set the API passwords file permissions:
sudo chown root:www-data /etc/apache2/api-htpasswd; sudo chmod 0640 /etc/apache2/api-htpasswd
- Update
/etc/apache2/sites-available/000-default.conf
:
<VirtualHost *:80>
ServerAdmin your@email.address
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# Work around TLS termination being done by the TransIP HA-IP, and not by this server:
RequestHeader edit Destination ^https: http:
IncludeOptional svn/*.conf
IncludeOptional svn/*/*.conf
<Location /api/>
AuthType Basic
AuthName "Blender Cloud SVN Manager API"
AuthUserFile api-htpasswd
Require valid-user
ProxyPass http://[::1]:8085/api/
ProxyPassReverse http://[::1]:8085/api/
</Location>
<Location /manage/>
AuthType Basic
AuthName "Blender Cloud SVN Manager"
AuthUserFile api-htpasswd
Require valid-user
ProxyPass http://127.0.0.1:8085/manage/
ProxyPassReverse http://127.0.0.1:8085/manage/
</Location>
</VirtualHost>
- Restart Apache:
sudo systemctl restart apache2
- Put a nice message in
/var/www/html/index.html
so that it doesn't show the default Ubuntu "It Works!" page.
Using Docker for local setup
In case you'd like to run an SVN manager without going through the whole setup
listed above, you can use a container described by the Dockerfile
.
To build and run it, use the following command:
./run_docker.sh
This will build an image and start a container running Apache2, and then build and start SVN manager inside this container.
It will have a single API user: admin
with an empty password.
In order to restart just the SVN manager (e.g. after changing the go
modules),
stop the script (the container will remain running), then rebuild and restart SVN manager
using the following:
docker exec --user www-data:www-data -it svn-manager go run main.go -verbose -repo /data/svn/repos
In order to rebuild the image and restart the container (e.g. after changing Apache configuration), stop the script and run it again.
Building and installing SVN-Manager
- In the SVN-Manager's source directory, run
make package
to build the checked-out version. - Copy
dist/svn-manager-v1.0-linux.tar.gz
to the server. The version number may be different, of course. - Become root:
sudo su -
- Extract the tarball to
/opt
, this will create/opt/svn-manager-v1.0
. - Create or update the symlink
cd /opt; rm -f svn-manager; ln -s svn-manager-v1.0 svn-manager
- Grant 'sudo' permissions, by adding this to
/etc/sudoers
(viavisudo
):
Cmnd_Alias GRACEFUL = /usr/sbin/apache2ctl configtest, /usr/sbin/apache2ctl graceful
www-data ALL = NOPASSWD: GRACEFUL
- Install the service:
cp /opt/svn-manager/svn-manager.service /etc/systemd/system/svn-manager.service
- Update the service and set
ExecStart=/opt/svn-manager/svn-manager -verbose -repo /data/svn/repos
- Enable and start the service:
sudo systemctl daemon-reload; sudo systemctl enable svn-manager; sudo systemctl start svn-manager
To see the logs from SVN Manager, use journalctl -u svn-manager
Testing the installation
Run this command to test the installation. It assumes the username and password
have been given access with sudo htpasswd -B /etc/apache2/api-htpasswd apiuser
and password apipassword
.
curl -v -u apiuser:apipassword https://server-address/api/nonexistant
If the Apache part of the installation was correct, and the SVN Manager is running, this should produce a 404 Not Found error (and not a 500 Internal Server).
curl -v -u apiuser:apipassword \
--data '{"repo_id": "one_two_three", "project_id": "59eefa9cf488554678cae036", "creator": "You <you@example.com>"}' \
-H 'Content-Type: application/json' \
https://server-address/api/repo
This should return a 201 Created
response, with a Location: /api/repo/one_two_three
header in there.
curl -v -u apiuser:apipassword \
https://server-address/api/repo/one_two_three
This should return {"repo_id":"one_two_three","access":[]}
, indicating that nobody has access.
curl -v -u apiuser:apipassword \
--data '{"grant": [{"username": "you", "password": "$2y$05$sF.twcpdlcu76/KVgAuCPe.t5UYxDCKREnse74vPNqVYRYfO/9Wz6"}]}' \
-H 'Content-Type: application/json' \
https://server-address/api/repo/one_two_three/access
This should return an empty 200 OK
reponse.
Now you can do an SVN checkout with username 'you' and password 'rock':
svn co https://server-address/repo/one_two_three